code wiki / (root) / nx_gguf_fixture_tiny.nx

nx_gguf_fixture_tiny.nx source

↩ module page · 297 lines · 11526 B

1// nx_gguf_fixture_tiny.nx -- reusable tiny-Llama GGUF fixture builder. 2// 3// Encapsulates the ~150 lines of byte-by-byte synthetic GGUF 4// construction that test smokes for nx_llm_run_v2 and the v2 LLM 5// actor adapters currently duplicate. V1 builds the canonical 6// n_layers=1, hidden=2, head=2, vocab=4, ffn=4 shape with all-zero 7// F32 weights -- the same fixture nx_llm_run_v2_test.nx ships -- 8// plus the BPE vocab (4 single-byte tokens 'a' 'b' 'c' 'd'), PRNG, 9// model spec, and a vocab-id-to-byte map for autoregressive smokes 10// to roll the previous token's bytes into the next prompt. 11// 12// One call -> entire test fixture ready to feed nx_llm_generate_one_v2 13// or any actor adapter that wraps it. Closes the combined-autoreg- 14// over-real-transformer smoke gap documented in 15// nx_actor_role_llm_v2_autoreg_test.nx. 16// 17// Honest scope: V1 is a SINGLE-shape fixture -- there are no knobs. 18// Future V2 will add a builder-pattern (caller-set hidden_dim / 19// vocab_size / n_layers). V1 keeps the API surface tiny. 20 21import "nx_syscalls.nx" 22import "nx_tier.nx" 23import "nx_le.nx" 24import "nx_gguf.nx" 25import "nx_gguf_load.nx" 26import "nx_bpe.nx" 27import "nx_model_spec.nx" 28import "nx_prng.nx" 29const NX_MAGIC_4096: i64 = 4096 30 31// ===== Sealed enum: NxGftVerdict ================================== 32 33const NX_GFT_OK: nx_int = 0 34const NX_GFT_ERR_PARSE: nx_int = 1 35const NX_GFT_ERR_SPEC_INVALID: nx_int = 2 36const NX_GFT_ERR_BPE_BUILD: nx_int = 3 37const NX_GFT_ERR_NULL: nx_int = 4 38const NX_GFT_N: nx_int = 5 39 40func nx_gft_v_is_valid(v: nx_int) -> nx_int { 41 if v < 0 { return 0 } 42 if v >= NX_GFT_N { return 0 } 43 return 1 44} 45 46// ===== Struct: NxGgufFixtureBundle ================================ 47 48struct NxGgufFixtureBundle { 49 gguf_buf: *u8, 50 hdr: *NxGgufHeader, 51 spec: *NxModelSpec, 52 bpe: *NxBpeVocab, 53 prng_state: *i64, 54 vocab_byte_map: *u8, 55 vocab_size: nx_int, 56 hidden_dim: nx_int, 57 head_dim: nx_int, 58 n_layers: nx_int, 59 ffn_dim: nx_int, 60 n_heads: nx_int, 61 max_seq_len: nx_int, 62 verdict: nx_int, 63} 64 65const NX_GFT_BUNDLE_BYTES: nx_int = 112 // 14 fields * 8 66 67// ===== Internal fixture builders (mirror nx_llm_run_v2_test layout) ===== 68 69func _gft_write_ti(buf: *u8, off: i64, 70 name: *u8, name_len: i64, 71 n_dims: i64, dim_0: i64, dim_1: i64, 72 ggml_type: i64, data_offset: i64) -> i64 { 73 nx_le_write_u64(buf, off, name_len) 74 var o: i64 = off + 8 75 var i: i64 = 0 76 while i < name_len { buf[o + i] = name[i]; i = i + 1 } 77 o = o + name_len 78 nx_le_write_u32(buf, o, n_dims); o = o + 4 79 nx_le_write_u64(buf, o, dim_0); o = o + 8 80 if n_dims >= 2 { nx_le_write_u64(buf, o, dim_1); o = o + 8 } 81 nx_le_write_u32(buf, o, ggml_type); o = o + 4 82 nx_le_write_u64(buf, o, data_offset); o = o + 8 83 return o 84} 85 86func _gft_mk_blk_name(suffix: *u8, suffix_len: nx_int, out: *u8) -> nx_int { 87 out[0]=0x62; out[1]=0x6c; out[2]=0x6b; out[3]=0x2e 88 out[4]=0x30; out[5]=0x2e 89 var i: nx_int = 0 90 while i < suffix_len { out[6 + i] = suffix[i]; i = i + 1 } 91 return 6 + suffix_len 92} 93 94// ===== Public: nx_gft_build_tiny_llama ============================= 95// 96// Allocates an NxGgufFixtureBundle and fills in every field. Returns 97// the bundle pointer on success; bundle.verdict carries the NX_GFT_* 98// result. Caller owns the bundle and the substructures (the 99// fixture's lifetime is the bundle's lifetime; sys_munmap is queued 100// per conductor Phase E). 101 102func nx_gft_build_tiny_llama(prng_seed: i64) -> *NxGgufFixtureBundle { 103 let raw: *u8 = sys_mmap(NX_GFT_BUNDLE_BYTES) 104 let b: *NxGgufFixtureBundle = raw as *NxGgufFixtureBundle 105 b.vocab_size = 4 106 b.hidden_dim = 2 107 b.head_dim = 2 108 b.n_layers = 1 109 b.ffn_dim = 4 110 b.n_heads = 1 111 b.max_seq_len = 8 112 b.verdict = NX_GFT_OK 113 114 // ===== Build 12-tensor GGUF byte buffer ===== 115 let buf: *u8 = sys_mmap(NX_MAGIC_4096) 116 buf[0]=0x47; buf[1]=0x47; buf[2]=0x55; buf[3]=0x46 117 buf[4]=3 118 nx_le_write_u64(buf, 8, 12) 119 nx_le_write_u64(buf, 16, 0) 120 b.gguf_buf = buf 121 122 // Top-level tensor names 123 let n_te: *u8 = sys_mmap(17) 124 n_te[0]=0x74; n_te[1]=0x6f; n_te[2]=0x6b; n_te[3]=0x65 125 n_te[4]=0x6e; n_te[5]=0x5f; n_te[6]=0x65; n_te[7]=0x6d 126 n_te[8]=0x62; n_te[9]=0x64; n_te[10]=0x2e; n_te[11]=0x77 127 n_te[12]=0x65; n_te[13]=0x69; n_te[14]=0x67; n_te[15]=0x68 128 n_te[16]=0x74 129 130 let n_on: *u8 = sys_mmap(18) 131 n_on[0]=0x6f; n_on[1]=0x75; n_on[2]=0x74; n_on[3]=0x70 132 n_on[4]=0x75; n_on[5]=0x74; n_on[6]=0x5f; n_on[7]=0x6e 133 n_on[8]=0x6f; n_on[9]=0x72; n_on[10]=0x6d; n_on[11]=0x2e 134 n_on[12]=0x77; n_on[13]=0x65; n_on[14]=0x69; n_on[15]=0x67 135 n_on[16]=0x68; n_on[17]=0x74 136 137 let n_ow: *u8 = sys_mmap(13) 138 n_ow[0]=0x6f; n_ow[1]=0x75; n_ow[2]=0x74; n_ow[3]=0x70 139 n_ow[4]=0x75; n_ow[5]=0x74; n_ow[6]=0x2e; n_ow[7]=0x77 140 n_ow[8]=0x65; n_ow[9]=0x69; n_ow[10]=0x67; n_ow[11]=0x68 141 n_ow[12]=0x74 142 143 // Per-layer tensor suffixes 144 let s_an: *u8 = sys_mmap(16) 145 s_an[0]=0x61; s_an[1]=0x74; s_an[2]=0x74; s_an[3]=0x6e 146 s_an[4]=0x5f; s_an[5]=0x6e; s_an[6]=0x6f; s_an[7]=0x72 147 s_an[8]=0x6d; s_an[9]=0x2e; s_an[10]=0x77; s_an[11]=0x65 148 s_an[12]=0x69; s_an[13]=0x67; s_an[14]=0x68; s_an[15]=0x74 149 150 let s_q: *u8 = sys_mmap(13) 151 s_q[0]=0x61; s_q[1]=0x74; s_q[2]=0x74; s_q[3]=0x6e 152 s_q[4]=0x5f; s_q[5]=0x71; s_q[6]=0x2e; s_q[7]=0x77 153 s_q[8]=0x65; s_q[9]=0x69; s_q[10]=0x67; s_q[11]=0x68; s_q[12]=0x74 154 155 let s_k: *u8 = sys_mmap(13) 156 s_k[0]=0x61; s_k[1]=0x74; s_k[2]=0x74; s_k[3]=0x6e 157 s_k[4]=0x5f; s_k[5]=0x6b; s_k[6]=0x2e; s_k[7]=0x77 158 s_k[8]=0x65; s_k[9]=0x69; s_k[10]=0x67; s_k[11]=0x68; s_k[12]=0x74 159 160 let s_v: *u8 = sys_mmap(13) 161 s_v[0]=0x61; s_v[1]=0x74; s_v[2]=0x74; s_v[3]=0x6e 162 s_v[4]=0x5f; s_v[5]=0x76; s_v[6]=0x2e; s_v[7]=0x77 163 s_v[8]=0x65; s_v[9]=0x69; s_v[10]=0x67; s_v[11]=0x68; s_v[12]=0x74 164 165 let s_o: *u8 = sys_mmap(18) 166 s_o[0]=0x61; s_o[1]=0x74; s_o[2]=0x74; s_o[3]=0x6e 167 s_o[4]=0x5f; s_o[5]=0x6f; s_o[6]=0x75; s_o[7]=0x74 168 s_o[8]=0x70; s_o[9]=0x75; s_o[10]=0x74; s_o[11]=0x2e 169 s_o[12]=0x77; s_o[13]=0x65; s_o[14]=0x69; s_o[15]=0x67 170 s_o[16]=0x68; s_o[17]=0x74 171 172 let s_fn: *u8 = sys_mmap(15) 173 s_fn[0]=0x66; s_fn[1]=0x66; s_fn[2]=0x6e; s_fn[3]=0x5f 174 s_fn[4]=0x6e; s_fn[5]=0x6f; s_fn[6]=0x72; s_fn[7]=0x6d 175 s_fn[8]=0x2e; s_fn[9]=0x77; s_fn[10]=0x65; s_fn[11]=0x69 176 s_fn[12]=0x67; s_fn[13]=0x68; s_fn[14]=0x74 177 178 let s_fg: *u8 = sys_mmap(15) 179 s_fg[0]=0x66; s_fg[1]=0x66; s_fg[2]=0x6e; s_fg[3]=0x5f 180 s_fg[4]=0x67; s_fg[5]=0x61; s_fg[6]=0x74; s_fg[7]=0x65 181 s_fg[8]=0x2e; s_fg[9]=0x77; s_fg[10]=0x65; s_fg[11]=0x69 182 s_fg[12]=0x67; s_fg[13]=0x68; s_fg[14]=0x74 183 184 let s_fu: *u8 = sys_mmap(13) 185 s_fu[0]=0x66; s_fu[1]=0x66; s_fu[2]=0x6e; s_fu[3]=0x5f 186 s_fu[4]=0x75; s_fu[5]=0x70; s_fu[6]=0x2e; s_fu[7]=0x77 187 s_fu[8]=0x65; s_fu[9]=0x69; s_fu[10]=0x67; s_fu[11]=0x68; s_fu[12]=0x74 188 189 let s_fd: *u8 = sys_mmap(15) 190 s_fd[0]=0x66; s_fd[1]=0x66; s_fd[2]=0x6e; s_fd[3]=0x5f 191 s_fd[4]=0x64; s_fd[5]=0x6f; s_fd[6]=0x77; s_fd[7]=0x6e 192 s_fd[8]=0x2e; s_fd[9]=0x77; s_fd[10]=0x65; s_fd[11]=0x69 193 s_fd[12]=0x67; s_fd[13]=0x68; s_fd[14]=0x74 194 195 let n_an: *u8 = sys_mmap(32); let l_an: nx_int = _gft_mk_blk_name(s_an, 16, n_an) 196 let n_q: *u8 = sys_mmap(32); let l_q: nx_int = _gft_mk_blk_name(s_q, 13, n_q) 197 let n_k: *u8 = sys_mmap(32); let l_k: nx_int = _gft_mk_blk_name(s_k, 13, n_k) 198 let n_v: *u8 = sys_mmap(32); let l_v: nx_int = _gft_mk_blk_name(s_v, 13, n_v) 199 let n_o: *u8 = sys_mmap(32); let l_o: nx_int = _gft_mk_blk_name(s_o, 18, n_o) 200 let n_fn: *u8 = sys_mmap(32); let l_fn: nx_int = _gft_mk_blk_name(s_fn, 15, n_fn) 201 let n_fg: *u8 = sys_mmap(32); let l_fg: nx_int = _gft_mk_blk_name(s_fg, 15, n_fg) 202 let n_fu: *u8 = sys_mmap(32); let l_fu: nx_int = _gft_mk_blk_name(s_fu, 13, n_fu) 203 let n_fd: *u8 = sys_mmap(32); let l_fd: nx_int = _gft_mk_blk_name(s_fd, 15, n_fd) 204 205 var p: i64 = 24 206 p = _gft_write_ti(buf, p, n_te, 17, 2, 4, 2, NX_GGML_TYPE_F32, 0) 207 p = _gft_write_ti(buf, p, n_on, 18, 1, 2, 1, NX_GGML_TYPE_F32, 32) 208 p = _gft_write_ti(buf, p, n_ow, 13, 2, 2, 4, NX_GGML_TYPE_F32, 40) 209 p = _gft_write_ti(buf, p, n_an, l_an, 1, 2, 1, NX_GGML_TYPE_F32, 72) 210 p = _gft_write_ti(buf, p, n_q, l_q, 2, 2, 2, NX_GGML_TYPE_F32, 80) 211 p = _gft_write_ti(buf, p, n_k, l_k, 2, 2, 2, NX_GGML_TYPE_F32, 96) 212 p = _gft_write_ti(buf, p, n_v, l_v, 2, 2, 2, NX_GGML_TYPE_F32, 112) 213 p = _gft_write_ti(buf, p, n_o, l_o, 2, 2, 2, NX_GGML_TYPE_F32, 128) 214 p = _gft_write_ti(buf, p, n_fn, l_fn, 1, 2, 1, NX_GGML_TYPE_F32, 144) 215 p = _gft_write_ti(buf, p, n_fg, l_fg, 2, 2, 4, NX_GGML_TYPE_F32, 152) 216 p = _gft_write_ti(buf, p, n_fu, l_fu, 2, 2, 4, NX_GGML_TYPE_F32, 184) 217 p = _gft_write_ti(buf, p, n_fd, l_fd, 2, 4, 2, NX_GGML_TYPE_F32, 216) 218 219 let data_off: i64 = (p + 31) / 32 * 32 220 var zi: nx_int = 0 221 while zi < 248 { buf[data_off + zi] = 0; zi = zi + 1 } 222 223 // ===== Parse the header ===== 224 let hdr: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader 225 if nx_gguf_parse(buf, NX_MAGIC_4096, hdr) != NX_GGUF_OK { 226 b.verdict = NX_GFT_ERR_PARSE 227 return b 228 } 229 b.hdr = hdr 230 231 // ===== Model spec ===== 232 let spec: *NxModelSpec = nx_model_spec_new() 233 spec.n_layers = 1 234 spec.hidden_dim = 2 235 spec.n_heads = 1 236 spec.head_dim = 2 237 spec.n_kv_heads = 1 238 spec.ffn_dim = 4 239 spec.vocab_size = 4 240 spec.max_seq_len = 8 241 if nx_model_spec_validate(spec) != NX_MS_OK { 242 b.verdict = NX_GFT_ERR_SPEC_INVALID 243 return b 244 } 245 b.spec = spec 246 247 // ===== BPE vocab (4 single-byte tokens) + vocab-id-to-byte map ===== 248 let bpe: *NxBpeVocab = nx_bpe_vocab_new(256, 16, 8) 249 let ba: *u8 = sys_mmap(1); ba[0] = 0x61 250 let bb: *u8 = sys_mmap(1); bb[0] = 0x62 251 let bc: *u8 = sys_mmap(1); bc[0] = 0x63 252 let bd: *u8 = sys_mmap(1); bd[0] = 0x64 253 nx_bpe_add_token(bpe, ba, 1) 254 nx_bpe_add_token(bpe, bb, 1) 255 nx_bpe_add_token(bpe, bc, 1) 256 nx_bpe_add_token(bpe, bd, 1) 257 b.bpe = bpe 258 259 let vocab_map: *u8 = sys_mmap(4) 260 vocab_map[0] = 0x61 261 vocab_map[1] = 0x62 262 vocab_map[2] = 0x63 263 vocab_map[3] = 0x64 264 b.vocab_byte_map = vocab_map 265 266 // ===== PRNG ===== 267 let prng: *i64 = sys_mmap(8) as *i64 268 nx_prng_init(prng, prng_seed) 269 b.prng_state = prng 270 271 return b 272} 273 274// ===== Accessors / queries ======================================== 275 276func nx_gft_verdict(b: *NxGgufFixtureBundle) -> nx_int { 277 if (b as i64) == 0 { return NX_GFT_ERR_NULL } 278 return b.verdict 279} 280 281func nx_gft_vocab_byte(b: *NxGgufFixtureBundle, token_id: nx_int) -> nx_int { 282 if (b as i64) == 0 { return -1 } 283 if token_id < 0 { return -1 } 284 if token_id >= b.vocab_size { return -1 } 285 return b.vocab_byte_map[token_id] as nx_int 286} 287 288func nx_gft_is_built(b: *NxGgufFixtureBundle) -> nx_int { 289 if (b as i64) == 0 { return 0 } 290 if b.verdict != NX_GFT_OK { return 0 } 291 if (b.gguf_buf as i64) == 0 { return 0 } 292 if (b.hdr as i64) == 0 { return 0 } 293 if (b.spec as i64) == 0 { return 0 } 294 if (b.bpe as i64) == 0 { return 0 } 295 if (b.prng_state as i64) == 0 { return 0 } 296 return 1 297}