code wiki / (root) / nx_nofloat_arch.nx

nx_nofloat_arch.nx source

↩ module page · 74 lines · 4724 B

1// nx_nofloat_arch.nx -- ARCH-CONFIGURABLE inference: read a model's dims from GGUF METADATA instead of 2// hardcoding Qwen2.5-0.5B. The no-float forward (nx_nofloat_llm) is ALREADY cfg-parameterized -- only the 3// gate/serve main()s hardcode ne/n_layers/heads/ffn. This reader fills those from the metadata KVs that 4// llama.cpp's convert writes (`<arch>.embedding_length`, `.block_count`, `.attention.head_count`, 5// `.attention.head_count_kv`, `.feed_forward_length`), so ANY Qwen2/Llama-schema gguf runs -- the real 6// 0.5B AND a small from-scratch model (closing the sovereign train->serve loop). Pure funcs, no main. 7// license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_le.nx" 10import "nx_gguf.nx" 11import "nx_gguf_meta.nx" 12import "nx_nofloat_llm.nx" // isqrt for the attention scale 13 14// cfg layout the reader fills (i64): [0]=D(embedding) [1]=n_layers [2]=n_heads [3]=n_kv [4]=head_dim 15// [5]=q_dim(=D) [6]=kv_dim(=head_dim*n_kv) [7]=ffn [8]=scale_q16(=65536/sqrt(head_dim)) [9]=rope_base [10]=ok 16func nac_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 17// build "<prefix bytes><suffix cstr>" into out; return length. 18func nac_key(prefix: *u8, plen: i64, suffix: *u8, out: *u8) -> i64 { 19 var i: i64=0; while i<plen { out[i]=prefix[i]; i=i+1 } 20 var j: i64=0; while suffix[j]!=(0 as u8) { out[plen+j]=suffix[j]; j=j+1 } 21 return plen+j 22} 23func nac_u32(buf: *u8, len: i64, hdr: *NxGgufHeader, prefix: *u8, plen: i64, suffix: *u8) -> i64 { 24 let key: *u8=sys_mmap(160); let kl: i64=nac_key(prefix, plen, suffix, key) 25 let voff: *i64=sys_mmap(8) as *i64; let vty: *i64=sys_mmap(8) as *i64 26 if nx_gguf_meta_find(buf, len, hdr, key, kl, voff, vty)==NX_GMETA_OK { return nx_gguf_meta_read_u32(buf, voff[0]) } 27 return 0-1 28} 29// read an f32 metadata value, truncated to an integer (for rope base etc.); returns dflt if absent. 30func nac_f32_int(buf: *u8, len: i64, hdr: *NxGgufHeader, prefix: *u8, plen: i64, suffix: *u8, dflt: i64) -> i64 { 31 let key: *u8=sys_mmap(160); let kl: i64=nac_key(prefix, plen, suffix, key) 32 let voff: *i64=sys_mmap(8) as *i64; let vty: *i64=sys_mmap(8) as *i64 33 if nx_gguf_meta_find(buf, len, hdr, key, kl, voff, vty)==NX_GMETA_OK { 34 let q16: i64 = f32_to_q16(nx_le_read_u32(buf, voff[0])) // f32 bits -> Q16 (nx_nofloat_llm decoder) 35 return q16 >> 16 36 } 37 return dflt 38} 39// read the whole config from metadata. returns 0 ok, -1 missing keys. `arch_out` (>=32B) gets the arch string. 40func nac_read_config(buf: *u8, len: i64, hdr: *NxGgufHeader, cfg: *i64, arch_out: *u8) -> i64 { 41 cfg[10]=0 42 // general.architecture -> the key prefix (e.g. "qwen2") 43 let voff: *i64=sys_mmap(8) as *i64; let vty: *i64=sys_mmap(8) as *i64 44 let ka: *u8="general.architecture" as *u8 45 if nx_gguf_meta_find(buf, len, hdr, ka, 20, voff, vty)!=NX_GMETA_OK { return 0-1 } 46 let alen: i64=nx_gguf_meta_read_string_len(buf, voff[0]); let ap: *u8=nx_gguf_meta_read_string_ptr(buf, voff[0]) 47 if alen<1 { return 0-1 } 48 if alen>30 { return 0-1 } 49 var i: i64=0; while i<alen { arch_out[i]=ap[i]; i=i+1 } arch_out[alen]=0 as u8 50 let D: i64=nac_u32(buf, len, hdr, ap, alen, ".embedding_length" as *u8) 51 let NL: i64=nac_u32(buf, len, hdr, ap, alen, ".block_count" as *u8) 52 let NH: i64=nac_u32(buf, len, hdr, ap, alen, ".attention.head_count" as *u8) 53 let NKV: i64=nac_u32(buf, len, hdr, ap, alen, ".attention.head_count_kv" as *u8) 54 let FF: i64=nac_u32(buf, len, hdr, ap, alen, ".feed_forward_length" as *u8) 55 if D<1 { return 0-1 } 56 if NL<1 { return 0-1 } 57 if NH<1 { return 0-1 } 58 if NKV<1 { return 0-1 } 59 if FF<1 { return 0-1 } 60 let hd: i64=D/NH 61 cfg[0]=D; cfg[1]=NL; cfg[2]=NH; cfg[3]=NKV; cfg[4]=hd; cfg[5]=D; cfg[6]=hd*NKV; cfg[7]=FF 62 // EXACT attention scale in Q16 = 1/sqrt(hd) (debt-eaten 2026-07-15): sqrt(hd) in Q16 = isqrt(hd<<32); 63 // scale = 2^32 / that. IDENTITY-PRESERVING at hd=64 (isqrt(64<<32)=524288, 2^32/524288 = 8192 = the old 64 // 65536/isqrt(64)); CORRECT at hd=128 (old 65536/11=5957 was ~2.8% high; new = 5792). Every future 65 // non-perfect-square head_dim now gets the true scale instead of the isqrt-floor approximation. 66 let sqhd: i64 = isqrt(hd << 32); if sqhd < 1 { return 0-1 } 67 cfg[8] = 4294967296 / sqhd 68 // rope base FROM THE MODEL (debt-eaten): <arch>.rope.freq_base (f32); default 1e6 (Qwen2) if absent. 69 // OLMoE/Llama carry 1e4/5e5 -- the hardcoded 1e6 would have garbled their attention. 70 cfg[9] = nac_f32_int(buf, len, hdr, ap, alen, ".rope.freq_base" as *u8, 1000000) 71 cfg[11] = fx_ln_int(cfg[9]) // ln(base) in Q16 -> rope_freqs_base (rope now base-correct for any model) 72 cfg[10]=1 73 return 0 74}