code wiki / (root) / nx_tok_probe.nx

nx_tok_probe.nx source

↩ module page · 94 lines · 3645 B

1// nx_tok_probe.nx -- tokenizer-parity DIAGNOSTIC: dump the exact token ids 2// (and each id's decoded string) that nx_bpe_encode_bytelevel produces for an 3// arithmetic prompt vs a known-good word prompt. Loads GGUF vocab ONLY (no 4// weights) -- fast. Answers mechanically whether digits are being merged 5// (Qwen2.5 pre-tokenizer splits every digit into its OWN token; a merged 6// "47" would be a context the model never saw in arithmetic). 7// expect_exit: 0 8 9import "nx_syscalls.nx" 10import "nx_tier.nx" 11import "nx_le.nx" 12import "nx_strconv.nx" 13import "nx_bpe.nx" 14import "nx_gguf.nx" 15import "nx_gguf_load.nx" 16import "nx_f32_bpe_load.nx" 17import "nx_reasoning.nx" 18 19func tp_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 20func tp_wn(v: i64) -> i64 { 21 let dec: *u8 = sys_mmap(32) 22 var m: i64 = v 23 if m < 0 { tp_w("-" as *u8); m = 0 - m } 24 let nd: i64 = nx_strconv_format_i64(m, dec) 25 sys_write(1, dec, nd) 26 return 0 27} 28func tp_wtext(b: *u8, n: i64) -> i64 { 29 let t: *u8 = sys_mmap(n + 1) 30 var i: i64 = 0 31 while i < n { 32 var c: i64 = b[i] as i64 33 if c < 32 { c = 46 } 34 t[i] = c as u8 35 i = i + 1 36 } 37 sys_write(1, t, n) 38 return 0 39} 40 41func tp_dump(v: *NxBpeVocab, label: *u8, text: *u8, n: nx_int) -> i64 { 42 tp_w(label); tp_w(" [" as *u8); tp_wtext(text, n as i64); tp_w("] -> " as *u8) 43 let toks: *i64 = sys_mmap((n + 4) * 8) as *i64 44 let nt: nx_int = nx_bpe_encode_bytelevel(v, text, n, toks) 45 tp_w("n_tokens=" as *u8); tp_wn(nt as i64); tp_w("\n" as *u8) 46 var i: nx_int = 0 47 let one: *i64 = sys_mmap(8) as *i64 48 let ob: *u8 = sys_mmap(64) 49 while i < nt { 50 one[0] = toks[i] 51 let nb: nx_int = nx_bpe_decode_bytelevel(v, one, 1, ob) 52 tp_w(" id=" as *u8); tp_wn(toks[i]) 53 tp_w(" str=[" as *u8) 54 var sn: i64 = nb as i64 55 if sn < 0 { sn = 0 } 56 tp_wtext(ob, sn) 57 tp_w("]\n" as *u8) 58 i = i + 1 59 } 60 return 0 61} 62 63func main() -> i64 { 64 let path: *u8 = sys_mmap(64) 65 path[0]=0x2F as u8; path[1]=0x74 as u8; path[2]=0x6D as u8; path[3]=0x70 as u8 66 path[4]=0x2F as u8; path[5]=0x6E as u8; path[6]=0x78 as u8; path[7]=0x5F as u8 67 path[8]=0x72 as u8; path[9]=0x65 as u8; path[10]=0x61 as u8; path[11]=0x6C as u8 68 path[12]=0x5F as u8; path[13]=0x6D as u8; path[14]=0x6F as u8; path[15]=0x64 as u8 69 path[16]=0x65 as u8; path[17]=0x6C as u8; path[18]=0x2E as u8 70 path[19]=0x67 as u8; path[20]=0x67 as u8; path[21]=0x75 as u8; path[22]=0x66 as u8 71 path[23]=0 as u8 72 let len_out: *i64 = sys_mmap(8) as *i64 73 let buf: *u8 = sys_read_file(path, len_out) 74 if buf == (0 as *u8) { return 10 } 75 let hdr: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader 76 if nx_gguf_parse(buf, len_out[0], hdr) != NX_GGUF_OK { return 20 } 77 let vocab: *NxBpeVocab = nx_bpe_vocab_new(8388608, 524288, 262144) 78 let nt: *i64 = sys_mmap(8) as *i64 79 let nm: *i64 = sys_mmap(8) as *i64 80 let out_err: *i64 = sys_mmap(8) as *i64 81 if nx_f32_bpe_load_from_gguf(buf, len_out[0], hdr, vocab, nt, nm, out_err) != NX_FBL_OK { return 50 } 82 83 let p1: *u8 = sys_mmap(64) 84 let n1: nx_int = nx_reason_build_arith_prompt(p1, 47, 0, 38) 85 tp_dump(vocab, "ARITH" as *u8, p1, n1) 86 87 let p2: *u8 = sys_mmap(64) 88 p2[0]=0x54 as u8; p2[1]=0x68 as u8; p2[2]=0x65 as u8; p2[3]=0x20 as u8 // "The " 89 p2[4]=0x63 as u8; p2[5]=0x61 as u8; p2[6]=0x70 as u8; p2[7]=0x69 as u8 // "capi" 90 p2[8]=0x74 as u8; p2[9]=0x61 as u8; p2[10]=0x6C as u8 // "tal" 91 tp_dump(vocab, "WORDS" as *u8, p2, 11) 92 93 return 0 94}