nx_f32_llm_bench_test.nx source
↩ module page · 177 lines · 7122 B
1// nx_f32_llm_bench_test.nx -- parked LIVE-FIRE perf harness for real Qwen2.5.
2//
3// Reads /tmp/nx_real_model.gguf, loads dims + weights + vocab, runs
4// nx_f32_llm_run_v2 with a fixed prompt + 32 new tokens, captures
5// wall-clock via sys_now_ms, and writes a TSV row to
6// /tmp/nx_f32_llm_bench.tsv with: prompt_n / max_new / n_emitted /
7// elapsed_ms / tokens_per_sec_milli (= tokens * 1000000 / elapsed_us).
8//
9// Substrate-honest scope:
10// * This is the HARNESS, not a perf result. No claim is made
11// about Nishi tokens/sec until this smoke runs PASS on the real
12// file and produces measured numbers.
13// * No comparison to llama.cpp is made here. A paired bench
14// against llama.cpp on the same Q4_K bytes on the same hardware
15// would be a separate brick. Per
16// feedback-no-strawman-perf-comparisons: NO inflated claims.
17//
18// Smoke wrapper skips gracefully when the file is absent.
19
20import "nx_syscalls.nx"
21import "nx_tier.nx"
22import "nx_le.nx"
23import "nx_strconv.nx"
24import "nx_bpe.nx"
25import "nx_gguf.nx"
26import "nx_gguf_load.nx"
27import "nx_gguf_meta.nx"
28import "nx_f32_kv_cache.nx"
29import "nx_f32_lazy_weight.nx"
30import "nx_f32_llama_block.nx"
31import "nx_f32_llama_block_v4.nx"
32import "nx_f32_llama_stack_v4.nx"
33import "nx_f32_llama_layer_lazy_load.nx"
34import "nx_f32_llm.nx"
35import "nx_f32_llm_v4.nx"
36import "nx_f32_llm_read_dims.nx"
37import "nx_f32_bpe_load.nx"
38import "nx_f32_llm_special_tokens.nx"
39import "nx_f32_sampler.nx"
40import "nx_f32_llm_run_v2.nx"
41import "nx_f32_llm_run_v3.nx"
42
43func _emit_kv(fd: i64, key: *u8, key_len: nx_int, value: i64) -> i64 {
44 let line: *u8 = sys_mmap(128)
45 var lo: i64 = 0
46 var ki: nx_int = 0
47 while ki < key_len { line[lo] = key[ki]; lo = lo + 1; ki = ki + 1 }
48 line[lo] = 0x09 as u8; lo = lo + 1 // tab
49 let dec: *u8 = sys_mmap(32)
50 let n_dec: i64 = nx_strconv_format_i64(value, dec)
51 var k: i64 = 0
52 while k < n_dec { line[lo] = dec[k]; lo = lo + 1; k = k + 1 }
53 line[lo] = 0x0A as u8; lo = lo + 1 // newline
54 return sys_write(fd, line, lo)
55}
56
57func main() -> i64 {
58 // Path: /tmp/nx_real_model.gguf
59 let path: *u8 = sys_mmap(64)
60 path[0]=0x2F as u8; path[1]=0x74 as u8; path[2]=0x6D as u8; path[3]=0x70 as u8
61 path[4]=0x2F as u8; path[5]=0x6E as u8; path[6]=0x78 as u8; path[7]=0x5F as u8
62 path[8]=0x72 as u8; path[9]=0x65 as u8; path[10]=0x61 as u8; path[11]=0x6C as u8
63 path[12]=0x5F as u8; path[13]=0x6D as u8; path[14]=0x6F as u8; path[15]=0x64 as u8
64 path[16]=0x65 as u8; path[17]=0x6C as u8; path[18]=0x2E as u8
65 path[19]=0x67 as u8; path[20]=0x67 as u8; path[21]=0x75 as u8; path[22]=0x66 as u8
66 path[23]=0 as u8
67
68 let len_out: *i64 = sys_mmap(8) as *i64
69 let buf: *u8 = sys_read_file(path, len_out)
70 if buf == (0 as *u8) { return 10 }
71
72 let hdr: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader
73 if nx_gguf_parse(buf, len_out[0], hdr) != NX_GGUF_OK { return 20 }
74
75 let model: *NxF32LlamaModel = nx_f32_llama_model_alloc()
76 let out_err: *i64 = sys_mmap(8) as *i64
77 if nx_f32_llm_read_dims_from_gguf(buf, len_out[0], hdr, model, out_err) != NX_FLD_OK {
78 return 30
79 }
80 if nx_f32_llm_load_weights_v4_from_gguf(buf, hdr, model, out_err) != NX_FLV4_OK {
81 return 40
82 }
83
84 let vocab: *NxBpeVocab = nx_bpe_vocab_new(8388608, 524288, 262144)
85 let nt: *i64 = sys_mmap(8) as *i64
86 let nm: *i64 = sys_mmap(8) as *i64
87 if nx_f32_bpe_load_from_gguf(buf, len_out[0], hdr, vocab, nt, nm, out_err) != NX_FBL_OK {
88 return 50
89 }
90
91 let eos: nx_int = nx_f32_llm_read_eos(buf, len_out[0], hdr)
92
93 let cache: *NxF32KVCache = nx_f32_kv_cache_alloc(
94 model.n_layers, model.n_kv_heads, 256, model.head_dim)
95
96 let cfg: *NxF32SamplerCfg = nx_f32_sampler_cfg_alloc()
97 // Greedy / no penalty / no top-k / no top-p -- pure argmax for
98 // reproducibility. Bench measures the FORWARD path cost, not
99 // sampling variation.
100
101 let prompt: *u8 = sys_mmap(8)
102 prompt[0]=0x48 as u8; prompt[1]=0x69 as u8 // "Hi"
103
104 let out_buf: *u8 = sys_mmap(256)
105 let max_new: nx_int = 32
106
107 let prng: *i64 = sys_mmap(8) as *i64
108 prng[0] = 1
109
110 let eps: i64 = 0x322BCC77
111 let attn_scale: i64 = 0x3F3504F3
112 let rope_base: i64 = 0x4548F000
113
114 let t0: i64 = sys_now_ms()
115 let n_emit: nx_int = nx_f32_llm_run_v3(
116 model, vocab, cache, prompt, 2, max_new, cfg,
117 eps, attn_scale, rope_base, 1,
118 prng, eos, out_buf, 256)
119 let t1: i64 = sys_now_ms()
120 if n_emit < 0 { return 60 }
121
122 let elapsed_ms: i64 = t1 - t0
123 var tok_per_sec_milli: i64 = 0
124 if elapsed_ms > 0 {
125 tok_per_sec_milli = (max_new as i64) * 1000000 / elapsed_ms
126 }
127
128 // Write TSV row to /tmp/nx_f32_llm_bench.tsv
129 let tsv_path: *u8 = sys_mmap(64)
130 tsv_path[0]=0x2F as u8; tsv_path[1]=0x74 as u8; tsv_path[2]=0x6D as u8; tsv_path[3]=0x70 as u8
131 tsv_path[4]=0x2F as u8
132 tsv_path[5]=0x6E as u8; tsv_path[6]=0x78 as u8; tsv_path[7]=0x5F as u8
133 tsv_path[8]=0x66 as u8; tsv_path[9]=0x33 as u8; tsv_path[10]=0x32 as u8; tsv_path[11]=0x5F as u8
134 tsv_path[12]=0x6C as u8; tsv_path[13]=0x6C as u8; tsv_path[14]=0x6D as u8; tsv_path[15]=0x5F as u8
135 tsv_path[16]=0x62 as u8; tsv_path[17]=0x65 as u8; tsv_path[18]=0x6E as u8; tsv_path[19]=0x63 as u8
136 tsv_path[20]=0x68 as u8; tsv_path[21]=0x2E as u8
137 tsv_path[22]=0x74 as u8; tsv_path[23]=0x73 as u8; tsv_path[24]=0x76 as u8
138 tsv_path[25]=0 as u8
139
140 let fd: i64 = sys_openat_wr(tsv_path, 0x1A4)
141 if fd < 0 { return 70 }
142
143 let k_prn: *u8 = sys_mmap(8)
144 k_prn[0]=0x70 as u8; k_prn[1]=0x72 as u8; k_prn[2]=0x6F as u8; k_prn[3]=0x6D as u8
145 k_prn[4]=0x70 as u8; k_prn[5]=0x74 as u8; k_prn[6]=0x5F as u8; k_prn[7]=0x6E as u8
146 _emit_kv(fd, k_prn, 8, 2 as i64)
147
148 let k_mxn: *u8 = sys_mmap(7)
149 k_mxn[0]=0x6D as u8; k_mxn[1]=0x61 as u8; k_mxn[2]=0x78 as u8; k_mxn[3]=0x5F as u8
150 k_mxn[4]=0x6E as u8; k_mxn[5]=0x65 as u8; k_mxn[6]=0x77 as u8
151 _emit_kv(fd, k_mxn, 7, max_new as i64)
152
153 let k_emi: *u8 = sys_mmap(9)
154 k_emi[0]=0x6E as u8; k_emi[1]=0x5F as u8; k_emi[2]=0x65 as u8; k_emi[3]=0x6D as u8
155 k_emi[4]=0x69 as u8; k_emi[5]=0x74 as u8; k_emi[6]=0x74 as u8; k_emi[7]=0x65 as u8
156 k_emi[8]=0x64 as u8
157 _emit_kv(fd, k_emi, 9, n_emit as i64)
158
159 let k_elp: *u8 = sys_mmap(10)
160 k_elp[0]=0x65 as u8; k_elp[1]=0x6C as u8; k_elp[2]=0x61 as u8; k_elp[3]=0x70 as u8
161 k_elp[4]=0x73 as u8; k_elp[5]=0x65 as u8; k_elp[6]=0x64 as u8; k_elp[7]=0x5F as u8
162 k_elp[8]=0x6D as u8; k_elp[9]=0x73 as u8
163 _emit_kv(fd, k_elp, 10, elapsed_ms)
164
165 let k_tps: *u8 = sys_mmap(19)
166 k_tps[0]=0x74 as u8; k_tps[1]=0x6F as u8; k_tps[2]=0x6B as u8; k_tps[3]=0x5F as u8
167 k_tps[4]=0x70 as u8; k_tps[5]=0x65 as u8; k_tps[6]=0x72 as u8; k_tps[7]=0x5F as u8
168 k_tps[8]=0x73 as u8; k_tps[9]=0x65 as u8; k_tps[10]=0x63 as u8; k_tps[11]=0x5F as u8
169 k_tps[12]=0x6D as u8; k_tps[13]=0x69 as u8; k_tps[14]=0x6C as u8; k_tps[15]=0x6C as u8
170 k_tps[16]=0x69 as u8
171 k_tps[17]=0x6F as u8; k_tps[18]=0x6E as u8
172 _emit_kv(fd, k_tps, 19, tok_per_sec_milli)
173
174 sys_close(fd)
175
176 return 0
177}