code wiki / _hdl_build / nx_nofloat_sample_gate.nx

nx_nofloat_sample_gate.nx source

↩ module page · 121 lines · 7727 B

1// nx_nofloat_sample_gate.nx -- TEMPERATURE SAMPLING decode in pure integer Q16 (CAP-NF-SAMPLE). Real LLMs 2// GENERATE by sampling from the softmax distribution (with a temperature), not just greedy argmax. The no-float 3// stack had only argmax; this adds a CORRECT fixed-point sampler: a deterministic LCG PRNG + softmax-with- 4// temperature (scale logits by 1/T, max-subtract, fxexp, normalize) + inverse-CDF pick. All integer -> the 5// sampling is REPRODUCIBLE given a seed (the no-float determinism exceed: same seed+weights -> same text, which 6// float/GPU sampling cannot guarantee bit-for-bit). 7// 8// T1 LOW temperature concentrates on the argmax (>= 90% of draws) -- approaches greedy as T->0. 9// T2 at temperature=1 the EMPIRICAL sample frequencies match softmax(logits) (a CORRECT sampler, measured). 10// T3 REPRODUCIBLE: two runs with the same seed produce byte-identical samples (no-float determinism). 11// T4 HIGH temperature is measurably MORE UNIFORM than low (argmax-frequency drops) -- temperature has teeth. 12// 13// Evidence -> knowledge/status/nofloat_sample.log. Sovereign: nx_nofloat_autograd (nfa_fxexp/nfa_qmul) + nx_syscalls. 14// expect_exit: 0 license_tier: ORIGINAL 15import "nx_nofloat_autograd.nx" 16import "nx_syscalls.nx" 17import "nx_gate_emit_lib.nx" 18import "nx_gate_verdict.nx" 19const Q16: i64 = 65536 20 21 22func g_abs(v: i64) -> i64 { if v<0 { return 0-v } return v } 23func s_ws(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 24func s_wn(fd: i64, v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(fd,"-" as *u8,1);m=0-m} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(fd,b,k); return 0 } 25 26// deterministic LCG -> u in [0, Q16). state updated in place. (glibc constants; >>15 takes high bits.) 27func lcg(st: *i64) -> i64 { st[0] = (st[0]*1103515245 + 12345) & 2147483647; return (st[0] >> 15) & 65535 } 28// out = softmax(logits * invtemp) in Q16 (invtemp = 1/T, Q16). max-subtract for stability; nfa_fxexp(arg<=0). 29func softmax_temp(logits: *i64, n: i64, invtemp: i64, out: *i64) -> i64 { 30 var i: i64=0 31 while i<n { out[i] = nfa_qmul(logits[i], invtemp); i=i+1 } 32 var mx: i64=out[0]; i=1 33 while i<n { if out[i]>mx { mx=out[i] } i=i+1 } 34 var sum: i64=0; i=0 35 while i<n { let e: i64=nfa_fxexp(out[i]-mx); out[i]=e; sum=sum+e; i=i+1 } 36 if sum<=0 { sum=1 } 37 i=0 38 while i<n { out[i]=(out[i]<<16)/sum; i=i+1 } 39 return 0 40} 41// inverse-CDF sample: pick first i with cumulative prob > u. probs Q16 (~sum Q16), u in [0,Q16). 42func sample_idx(probs: *i64, n: i64, u: i64) -> i64 { 43 var c: i64=0; var i: i64=0 44 while i<n { c=c+probs[i]; if u<c { return i } i=i+1 } 45 return n-1 46} 47func argmax_of(probs: *i64, n: i64) -> i64 { var b: i64=0; var bv: i64=probs[0]; var i: i64=1; while i<n { if probs[i]>bv { bv=probs[i]; b=i } i=i+1 } return b } 48 49func main() -> i64 { 50 g_puts("nx_nofloat_sample gate (TEMPERATURE sampling decode in pure integer Q16 -- MEASURED)\n" as *u8) 51 var pass: i64=0; var total: i64=0 52 let n: i64=4 53 let logits: *i64 = sys_mmap(n*8) as *i64 54 logits[0]=32768; logits[1]=65536; logits[2]=131072; logits[3]=0 // [0.5, 1.0, 2.0, 0.0]; argmax=class 2 55 let probs: *i64 = sys_mmap(n*8) as *i64 56 let cnt: *i64 = sys_mmap(n*8) as *i64 57 let st: *i64 = sys_mmap(8) as *i64 58 59 // ---- T1: low temperature (invtemp=8.0) concentrates on argmax ---- 60 softmax_temp(logits, n, 8*Q16, probs) 61 let am: i64 = argmax_of(probs, n) 62 st[0]=12345 63 var draws: i64=4000; var hitArg: i64=0; var d: i64=0 64 while d<draws { let u: i64=lcg(st); let s: i64=sample_idx(probs,n,u); if s==am { hitArg=hitArg+1 } d=d+1 } 65 g_puts(" [measure] low-temp(T=1/8): argmax=class " as *u8); g_pn(am); g_puts(", argmax-draws=" as *u8); g_pn(hitArg); g_puts("/" as *u8); g_pn(draws); g_puts("\n" as *u8) 66 var t1: i64=0; if hitArg*100 >= draws*90 { t1=1 } 67 pass=pass+g_check("T1: low temperature concentrates on argmax (>= 90% of draws)" as *u8, t1); total=total+1 68 69 // ---- T2: temperature=1 empirical frequencies match softmax(logits) ---- 70 softmax_temp(logits, n, Q16, probs) 71 var z: i64=0; while z<n { cnt[z]=0; z=z+1 } 72 st[0]=999 73 draws=8000; d=0 74 while d<draws { let u: i64=lcg(st); let s: i64=sample_idx(probs,n,u); cnt[s]=cnt[s]+1; d=d+1 } 75 var t2: i64=1; var worst: i64=0; var i: i64=0 76 while i<n { 77 let emp: i64=(cnt[i]<<16)/draws // empirical freq in Q16 78 let df: i64=g_abs(emp-probs[i]) 79 if df>worst { worst=df } 80 if df > 4915 { t2=0 } // tolerance 0.075 (4915/65536) 81 g_puts(" class " as *u8); g_pn(i); g_puts(": softmax=" as *u8); g_pn((probs[i]*1000)>>16); g_puts("/1000 empirical=" as *u8); g_pn((emp*1000)>>16); g_puts("/1000\n" as *u8) 82 i=i+1 83 } 84 g_puts(" [measure] worst |empirical-softmax| = " as *u8); g_pn((worst*1000)>>16); g_puts("/1000 (tol=75/1000)\n" as *u8) 85 pass=pass+g_check("T2: temperature=1 empirical frequencies MATCH softmax(logits) (correct sampler)" as *u8, t2); total=total+1 86 87 // ---- T3: reproducible (same seed -> identical sample sequence) ---- 88 softmax_temp(logits, n, Q16, probs) 89 let seqA: *i64 = sys_mmap(64*8) as *i64; let seqB: *i64 = sys_mmap(64*8) as *i64 90 st[0]=2026; var k: i64=0; while k<64 { seqA[k]=sample_idx(probs,n,lcg(st)); k=k+1 } 91 st[0]=2026; k=0; while k<64 { seqB[k]=sample_idx(probs,n,lcg(st)); k=k+1 } 92 var t3: i64=1; k=0; while k<64 { if seqA[k]!=seqB[k] { t3=0 } k=k+1 } 93 pass=pass+g_check("T3: reproducible -- same seed gives byte-identical samples (no-float determinism)" as *u8, t3); total=total+1 94 95 // ---- T4: high temperature is more uniform than low (argmax-frequency drops) ---- 96 softmax_temp(logits, n, 16384, probs) // invtemp=0.25 -> T=4 (flatter) 97 let amH: i64 = argmax_of(probs, n) 98 st[0]=777; draws=4000; var hitH: i64=0; d=0 99 while d<draws { if sample_idx(probs,n,lcg(st))==amH { hitH=hitH+1 } d=d+1 } 100 g_puts(" [measure] high-temp(T=4): argmax-draws=" as *u8); g_pn(hitH); g_puts("/" as *u8); g_pn(draws); g_puts(" vs low-temp " as *u8); g_pn(hitArg); g_puts("/" as *u8); g_pn(4000); g_puts("\n" as *u8) 101 var t4: i64=0; if hitH < hitArg { t4=1 } // high temp picks argmax LESS often = more uniform 102 pass=pass+g_check("T4: high temperature is MORE UNIFORM than low (argmax-frequency drops) -- teeth" as *u8, t4); total=total+1 103 104 var okall: i64=0; if pass==total { okall=1 } 105 let logf: i64 = sys_openat_append("knowledge/status/nofloat_sample.log" as *u8, 420) 106 if logf >= 0 { 107 s_ws(logf,"NOFLOATSAMPLE T1_lowtemp=" as *u8); s_wn(logf,t1); s_ws(logf," T2_distmatch=" as *u8); s_wn(logf,t2); s_ws(logf," T3_repro=" as *u8); s_wn(logf,t3); s_ws(logf," T4_temp_teeth=" as *u8); s_wn(logf,t4) 108 if okall==1 { s_ws(logf," verdict=GREEN\n" as *u8) } else { s_ws(logf," verdict=RED\n" as *u8) } 109 sys_close(logf) 110 } 111 g_puts("---- nofloat_sample gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 112 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 113 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 114 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 115 let ctr__dry: *i64 = gv_ctr() 116 ctr__dry[0] = pass 117 ctr__dry[1] = total 118 let rc__dry: i64 = gv_verdict("NOFLOAT-SAMPLE-GATE" as *u8, ctr__dry, "a correct temperature sampler in pure integer Q16; reproducible decode)" as *u8) 119 sys_exit(rc__dry) 120 return rc__dry 121}