nx_nofloat_speed_bench.nx source
↩ module page · 64 lines · 3748 B
1// nx_nofloat_speed_bench.nx -- honest tok/s baseline for the no-float Qwen serve (the inference-speed arc's
2// "measure before you optimize" foundation). nsv_generate already self-times (meta[1]=gen_tokens,
3// meta[3]=ms_per_token); this drives it with a fixed prompt + max_new and prints prompt-tokens, gen-tokens,
4// ms/tok, and tok/s for BOTH i32-lossless (mode 0) and i8-fast (mode 1) so the real number + the i8 speed
5// delta are on the record (memory had conflicting 3.2 vs 14.9 tok/s). Low-risk: reads the model, no serve edits.
6// usage: nx_nofloat_speed_bench [model.gguf] [max_new] Sovereign: nx_nofloat_serve_core. license_tier: ORIGINAL
7import "nx_syscalls.nx"
8import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
9import "nx_nofloat_serve_core.nx"
10
11const SB_MODEL: *u8 = "/home/elderwesto/nx_stage/nx_real_model.gguf"
12
13func sb_puts(s: *u8) -> i64 { var n: i64=0; while s[n] != (0 as u8) { n=n+1 } sys_write(1, s, n); return 0 }
14// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
15// per call and never freed it. At page granularity that is 4096B leaked PER CALL -- the
16// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff. A BENCH is the worst home for
17// it: its purpose is millions of iterations. nxi_* is MSB-first and allocates NOTHING.
18func sb_putn(v: i64) -> i64 { nxi_out(v); return 0 }
19func sb_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){ n=n+1 } return n }
20func sb_int(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 } return v }
21
22func sb_run(mode: i64, label: *u8, maxnew: i64, pr: *u8, out: *u8, meta: *i64, gp: *i64) -> i64 {
23 let plen: i64 = sb_slen(pr)
24 gp[0]=pr as i64; gp[1]=plen; gp[2]=maxnew; gp[3]=mode; gp[4]=out as i64; gp[5]=4096
25 gp[6]=meta as i64; gp[7]=0-1; gp[8]=0; gp[9]=0; gp[10]=0; gp[11]=0; gp[12]=0
26 let tl: i64 = nsv_generate(gp)
27 sb_puts(" " as *u8); sb_puts(label)
28 if tl < 0 { sb_puts(" FAILED err=" as *u8); sb_putn(meta[5]); sb_puts("\n" as *u8); return 0 }
29 let ptok: i64 = meta[0]
30 let gtok: i64 = meta[1]
31 let mspt: i64 = meta[3]
32 sb_puts(" prompt_tokens=" as *u8); sb_putn(ptok)
33 sb_puts(" gen_tokens=" as *u8); sb_putn(gtok)
34 sb_puts(" ms/tok=" as *u8); sb_putn(mspt)
35 sb_puts(" tok/s=" as *u8)
36 if mspt > 0 { sb_putn(1000 / mspt) } else { sb_puts("inf" as *u8) }
37 sb_puts("\n" as *u8)
38 return 0
39}
40
41func main(argc: i64, argv: *i64) -> i64 {
42 var model: *u8 = SB_MODEL
43 if argc >= 2 { model = argv[1] as *u8 }
44 var maxnew: i64 = 48
45 if argc >= 3 { let m: i64 = sb_int(argv[2] as *u8); if m > 0 { maxnew = m } }
46
47 sb_puts("=== nx_nofloat_speed_bench: honest tok/s baseline for the no-float Qwen serve ===\n" as *u8)
48 let rc: i64 = nsv_init(model)
49 if rc != 0 { sb_puts("MODEL INIT FAILED rc=" as *u8); sb_putn(rc); sb_puts("\n" as *u8); return 1 }
50 sb_puts("model ready; max_new=" as *u8); sb_putn(maxnew); sb_puts(" (greedy)\n\n" as *u8)
51
52 let pr: *u8 = "Question: What is the Stanford Question Answering Dataset and what does it measure? Answer:" as *u8
53 let out: *u8 = sys_mmap(4096)
54 let meta: *i64 = sys_mmap(8*8) as *i64
55 let gp: *i64 = sys_mmap(16*8) as *i64
56
57 sb_puts("-- run 1 (warm-up, i32) --\n" as *u8)
58 sb_run(0, "i32-warmup " as *u8, maxnew, pr, out, meta, gp) // first run pays cold-cache; report the 2nd
59 sb_puts("-- measured --\n" as *u8)
60 sb_run(0, "i32-lossless" as *u8, maxnew, pr, out, meta, gp)
61 sb_run(1, "i8-fast " as *u8, maxnew, pr, out, meta, gp)
62 sb_puts("\n(tok/s = 1000/ms-per-token, as self-reported by nsv_generate; i8 delta = the fast-path speedup)\n" as *u8)
63 return 0
64}