nx_f32_llm_embed_diag_test.nx source
↩ module page · 95 lines · 3359 B
1// nx_f32_llm_embed_diag_test.nx -- check Q5_0-dequanted embed values
2// on real Qwen2.5. Reports the max absolute value (as f32 bit pattern
3// truncated to lower 8 bits via exit code).
4//
5// Token embeddings in well-trained models are typically in [-1, 1].
6// Huge values (>10) would indicate dequant is wrong.
7
8import "nx_syscalls.nx"
9import "nx_tier.nx"
10import "nx_gguf.nx"
11import "nx_gguf_load.nx"
12import "nx_f32.nx"
13import "nx_f32_lazy_weight.nx"
14import "nx_f32_llama_block.nx"
15import "nx_f32_llama_block_v4.nx"
16import "nx_f32_llama_layer_lazy_load.nx"
17import "nx_f32_llm.nx"
18import "nx_f32_llm_v4.nx"
19import "nx_f32_llm_read_dims.nx"
20
21func main() -> i64 {
22 let path: *u8 = sys_mmap(64)
23 path[0]=0x2F as u8; path[1]=0x74 as u8; path[2]=0x6D as u8; path[3]=0x70 as u8
24 path[4]=0x2F as u8; path[5]=0x6E as u8; path[6]=0x78 as u8; path[7]=0x5F as u8
25 path[8]=0x72 as u8; path[9]=0x65 as u8; path[10]=0x61 as u8; path[11]=0x6C as u8
26 path[12]=0x5F as u8; path[13]=0x6D as u8; path[14]=0x6F as u8; path[15]=0x64 as u8
27 path[16]=0x65 as u8; path[17]=0x6C as u8; path[18]=0x2E as u8
28 path[19]=0x67 as u8; path[20]=0x67 as u8; path[21]=0x75 as u8; path[22]=0x66 as u8
29 path[23]=0 as u8
30
31 let len_out: *i64 = sys_mmap(8) as *i64
32 let buf: *u8 = sys_read_file(path, len_out)
33 if buf == (0 as *u8) { return 10 }
34
35 let hdr: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader
36 if nx_gguf_parse(buf, len_out[0], hdr) != NX_GGUF_OK { return 20 }
37
38 let model: *NxF32LlamaModel = nx_f32_llama_model_alloc()
39 let out_err: *i64 = sys_mmap(8) as *i64
40 if nx_f32_llm_read_dims_from_gguf(buf, len_out[0], hdr, model, out_err) != NX_FLD_OK {
41 return 30
42 }
43 if nx_f32_llm_load_weights_v4_from_gguf(buf, hdr, model, out_err) != NX_FLV4_OK {
44 return 40
45 }
46
47 // Find max abs value among first 1000 embed values.
48 // Compare against threshold: if max abs > 10.0, dequant is wrong.
49 // 10.0 in f32 = 0x41200000. Compare absolute value < 0x41200000?
50 let thresh: i64 = 0x41200000 // 10.0
51 var n_huge: nx_int = 0
52 var n_nan: nx_int = 0
53 var n_inf: nx_int = 0
54 var n_zero: nx_int = 0
55 var i: nx_int = 0
56 while i < 1000 {
57 let v: i64 = model.embed_weights[i]
58 let abs_v: i64 = v & 0x7FFFFFFF
59 let exp_field: i64 = (v >> 23) & 0xFF
60 let mant: i64 = v & 0x7FFFFF
61 if exp_field == 0xFF {
62 if mant != 0 { n_nan = n_nan + 1 }
63 if mant == 0 { n_inf = n_inf + 1 }
64 }
65 if v == 0 { n_zero = n_zero + 1 }
66 if abs_v > thresh {
67 if exp_field != 0xFF { n_huge = n_huge + 1 }
68 }
69 i = i + 1
70 }
71
72 // Encode diagnostics in exit code:
73 // 0 = clean (all in [-10, 10])
74 // 100 + ratio = n_huge > 0
75 // 110 + ratio = n_nan > 0 in embed (Q5_0 dequant broken)
76 // 120 + ratio = n_inf > 0
77 // 130 = all-zero (lazy binder didn't load)
78 if n_nan > 0 {
79 var r: nx_int = n_nan / 10
80 if r > 9 { r = 9 }
81 return (110 + r) as i64
82 }
83 if n_inf > 0 {
84 var r: nx_int = n_inf / 10
85 if r > 9 { r = 9 }
86 return (120 + r) as i64
87 }
88 if n_huge > 0 {
89 var r: nx_int = n_huge / 10
90 if r > 9 { r = 9 }
91 return (100 + r) as i64
92 }
93 if n_zero >= 1000 { return 130 }
94 return 0
95}