code wiki / _hdl_build / nx_nofloat_grammar_gate.nx

nx_nofloat_grammar_gate.nx source

↩ module page · 150 lines · 9303 B

1// nx_nofloat_grammar_gate.nx -- CAP-NF-GRAMMAR: the AFFORDABLE "landing" step the sovereign researcher 2// identified (knowledge/research/2026-06-23-nofloat-affordable-land-roadmap.md, R1, grounded in TinyStories 3// arXiv 2305.07759 + Textbooks arXiv 2306.11644: a tiny model is COHERENT iff the DOMAIN is constrained). 4// Instead of memorizing one fixed sentence, the model learns a small GRAMMAR and GENERATES coherent NOVEL 5// sentences. Grammar: a stream of [ARTICLE, NOUN, VERB] triples. Vocab 8: articles {the=0,a=1}, nouns 6// {cat=2,dog=3,bird=4}, verbs {ran=5,sat=6,ate=7}. EVERY training stream is fresh-random members -> the model 7// cannot memorize sentences; it must learn the CATEGORY GRAMMAR (article->noun->verb->article ...). 8// T1 GENERATES coherent grammar: from a seed, free argmax-decode produces a stream whose every token is in 9// the grammatically-correct category for its position (>= 90%, vs ~33% chance) = coherent NOVEL generation. 10// T2 learned the grammar on HELD-OUT streams: teacher-forced next-token category accuracy >= 90% (>> chance). 11// Pure integer Q16, attention-only block, 3 clm_fwd sites in separate helpers (nx_cc-lean). Sovereign. 12// HONEST: a CONSTRAINED grammar domain (the affordable landing per the research), not open prose. expect_exit: 0 13import "nx_nofloat_autograd.nx" 14import "nx_syscalls.nx" 15import "nx_gate_emit_lib.nx" 16const Q16: i64 = 65536 17 18 19func dini(a: *i64, n: i64, sd: i64) -> i64 { var i: i64=0; while i<n { a[i]=(((i*7+sd*13+1)%11)-5)*13107; i=i+1 } return 0 } 20func lcg(st: *i64) -> i64 { st[0]=(st[0]*1103515245 + 12345) & 2147483647; return (st[0] >> 15) } 21func cat_of(tok: i64) -> i64 { if tok<2 { return 0 } if tok<5 { return 1 } return 2 } 22// fresh-random grammatical stream: position cat = i%3; article 0..1, noun 2..4, verb 5..7. tgt = next token. 23func make_stream(S: *i64, tgt: *i64, P: i64, st: *i64) -> i64 { 24 var i: i64=0 25 while i<P { let c: i64=i%3; if c==0 { S[i]=lcg(st)%2 } if c==1 { S[i]=2+lcg(st)%3 } if c==2 { S[i]=5+lcg(st)%3 } i=i+1 } 26 i=0; while i<P-1 { tgt[i]=S[i+1]; i=i+1 } 27 tgt[P-1]=S[0] 28 return 0 29} 30 31func clm_fwd(tape: *i64, vals: *i64, st: *i64, W: *i64, ids: *i64, tgt: *i64, T: i64, dm: i64, V: i64, scale: i64, leaves: *i64) -> i64 { 32 let E: *i64=W[0] as *i64; let Wq: *i64=W[1] as *i64; let Wk: *i64=W[2] as *i64; let Wv: *i64=W[3] as *i64; let Wo: *i64=W[4] as *i64; let Wlm: *i64=W[5] as *i64 33 st[0]=0; st[1]=0 34 let nE: i64=nfa_leaf(tape,vals,st,V,dm,E,0) 35 let nWq: i64=nfa_leaf(tape,vals,st,dm,dm,Wq,0) 36 let nWk: i64=nfa_leaf(tape,vals,st,dm,dm,Wk,0) 37 let nWv: i64=nfa_leaf(tape,vals,st,dm,dm,Wv,0) 38 let nWo: i64=nfa_leaf(tape,vals,st,dm,dm,Wo,0) 39 let nWlm: i64=nfa_leaf(tape,vals,st,dm,V,Wlm,0) 40 let nX: i64=nfa_embed(tape,vals,st,nE,ids,T) 41 let nXn: i64=nfa_rmsnorm_rows(tape,vals,st,nX) 42 let nQ: i64=nfa_matmul(tape,vals,st,nXn,nWq) 43 let nK: i64=nfa_matmul(tape,vals,st,nXn,nWk) 44 let nV: i64=nfa_matmul(tape,vals,st,nXn,nWv) 45 let nQr: i64=nfa_rope(tape,vals,st,nQ) 46 let nKr: i64=nfa_rope(tape,vals,st,nK) 47 let nS: i64=nfa_matmul_nt(tape,vals,st,nQr,nKr) 48 let nSs: i64=nfa_cmul(tape,vals,st,nS,scale) 49 let nA: i64=nfa_softmax_rows(tape,vals,st,nSs,1) 50 let nO: i64=nfa_matmul(tape,vals,st,nA,nV) 51 let nOp: i64=nfa_matmul(tape,vals,st,nO,nWo) 52 let nH: i64=nfa_vadd(tape,vals,st,nX,nOp) 53 let nHn: i64=nfa_rmsnorm_rows(tape,vals,st,nH) 54 let nLg: i64=nfa_matmul(tape,vals,st,nHn,nWlm) 55 let nLoss: i64=nfa_softce_rows(tape,vals,st,nLg,tgt) 56 leaves[0]=nE; leaves[1]=nWq; leaves[2]=nWk; leaves[3]=nWv; leaves[4]=nWo; leaves[5]=nWlm; leaves[6]=nLg 57 return nLoss 58} 59func step_all(tape: *i64, grads: *i64, W: *i64, WN: *i64, leaves: *i64, nW: i64, lr: i64, clip: i64, gb: *i64) -> i64 { 60 var i: i64=0 61 while i<nW { let ar: *i64=W[i] as *i64; let cn: i64=WN[i]; let nd: i64=leaves[i]; var c: i64=0; while c<cn { var g: i64=nfa_grad(tape,grads,nd,c); if g>clip{g=clip} if g<0-clip{g=0-clip} gb[c]=g; c=c+1 } nfa_sgd(ar,gb,cn,lr); i=i+1 } 62 return 0 63} 64func amx(tape: *i64, vals: *i64, logn: i64, r: i64, V: i64) -> i64 { let o: i64=tape[7*logn+5]; var b: i64=0; var bv: i64=vals[o+r*V]; var j: i64=1; while j<V { if vals[o+r*V+j]>bv { bv=vals[o+r*V+j]; b=j } j=j+1 } return b } 65// site 1: train on fresh-random grammatical streams 66func do_train(tape: *i64, vals: *i64, grads: *i64, st: *i64, W: *i64, WN: *i64, S: *i64, tgt: *i64, P: i64, dm: i64, V: i64, scale: i64, leaves: *i64, gb: *i64, steps: i64, sdat: *i64) -> i64 { 67 var ep: i64=0 68 while ep < steps { make_stream(S,tgt,P,sdat); let nl: i64=clm_fwd(tape,vals,st,W,S,tgt,P-1,dm,V,scale,leaves); nfa_backward(tape,vals,grads,st[0],nl); step_all(tape,grads,W,WN,leaves,6,6554,262144,gb); ep=ep+1 } 69 return 0 70} 71// site 2: teacher-forced next-CATEGORY accuracy over N held-out fresh streams (position i predicts cat (i+1)%3) 72func eval_tf(tape: *i64, vals: *i64, st: *i64, W: *i64, S: *i64, tgt: *i64, P: i64, dm: i64, V: i64, scale: i64, leaves: *i64, N: i64, sdat: *i64, totp: *i64) -> i64 { 73 var ok: i64=0; var tp: i64=0; var e: i64=0 74 while e<N { 75 make_stream(S,tgt,P,sdat) 76 let nl: i64=clm_fwd(tape,vals,st,W,S,tgt,P-1,dm,V,scale,leaves) 77 var i: i64=0 78 while i<P-1 { if cat_of(amx(tape,vals,leaves[6],i,V))==((i+1)%3) { ok=ok+1 } tp=tp+1; i=i+1 } 79 e=e+1 80 } 81 totp[0]=tp 82 return ok 83} 84// site 3: free generation coherence -- fixed-T decode from a seed article; count tokens in the grammatically-correct category 85func gen_coherent(tape: *i64, vals: *i64, st: *i64, W: *i64, gen: *i64, P: i64, dm: i64, V: i64, scale: i64, leaves: *i64, outtok: *i64) -> i64 { 86 var z: i64=0; while z<P { gen[z]=0; z=z+1 } // 0 = "the" (valid article seed) 87 let Tf: i64 = P-1 88 var step: i64=1 89 while step <= Tf { 90 let nl: i64=clm_fwd(tape,vals,st,W,gen,gen,Tf,dm,V,scale,leaves) 91 gen[step]=amx(tape,vals,leaves[6],step-1,V) 92 step=step+1 93 } 94 var ok: i64=0; var i: i64=1 95 while i<P { if cat_of(gen[i])==(i%3) { ok=ok+1 } outtok[i]=gen[i]; i=i+1 } 96 outtok[0]=gen[0] 97 return ok 98} 99 100func main() -> i64 { 101 g_puts("nx_nofloat_grammar gate (constrained-grammar -> coherent NOVEL generation; the affordable land)\n" as *u8) 102 var pass: i64=0; var total: i64=0 103 let V: i64=8; let P: i64=12; let dm: i64=24; let scale: i64=13377 104 let tape: *i64 = sys_mmap(512*7*8) as *i64 105 let vals: *i64 = sys_mmap(65536*8) as *i64 106 let grads: *i64 = sys_mmap(65536*8) as *i64 107 let st: *i64 = sys_mmap(2*8) as *i64 108 let nW: i64=6 109 let W: *i64 = sys_mmap(nW*8) as *i64 110 let WN: *i64 = sys_mmap(nW*8) as *i64 111 WN[0]=V*dm; WN[1]=dm*dm; WN[2]=dm*dm; WN[3]=dm*dm; WN[4]=dm*dm; WN[5]=dm*V 112 var wi: i64=0 113 while wi<nW { let a: *i64=sys_mmap(WN[wi]*8) as *i64; dini(a,WN[wi],wi+1); W[wi]=a as i64; wi=wi+1 } 114 let leaves: *i64 = sys_mmap(8*8) as *i64 115 let gbuf: *i64 = sys_mmap(4096*8) as *i64 116 let S: *i64 = sys_mmap(P*8) as *i64; let tgt: *i64 = sys_mmap(P*8) as *i64 117 let totp: *i64 = sys_mmap(8) as *i64; let sdat: *i64 = sys_mmap(8) as *i64 118 let outtok: *i64 = sys_mmap(P*8) as *i64 119 120 sdat[0]=12345 121 do_train(tape,vals,grads,st,W,WN,S,tgt,P,dm,V,scale,leaves,gbuf,30000,sdat) 122 123 // T2: held-out grammar accuracy (teacher-forced next-category) 124 sdat[0]=55554444 125 let ok: i64 = eval_tf(tape,vals,st,W,S,tgt,P,dm,V,scale,leaves,150,sdat,totp) 126 let tp: i64 = totp[0] 127 // T1: free generation coherence (the actual "landing") 128 let gen: *i64 = sys_mmap(P*8) as *i64 129 let gok: i64 = gen_coherent(tape,vals,st,W,gen,P,dm,V,scale,leaves,outtok) 130 g_puts(" [measure] held-out next-category acc=" as *u8); g_pn(ok); g_puts("/" as *u8); g_pn(tp); g_puts(" free-gen coherent tokens=" as *u8); g_pn(gok); g_puts("/" as *u8); g_pn(P-1); g_puts(" (chance~33%)\n" as *u8) 131 // print the generated sentence as category letters (A=article,N=noun,V=verb) + token ids 132 g_puts(" generated grammar: " as *u8) 133 var pi: i64=0 134 while pi<P { let c: i64=cat_of(outtok[pi]); let lab: *u8=sys_mmap(2); if c==0 { lab[0]=65 as u8 } if c==1 { lab[0]=78 as u8 } if c==2 { lab[0]=86 as u8 } sys_write(1,lab,1); pi=pi+1 } 135 g_puts(" (expected A N V A N V ...)\n" as *u8) 136 137 var t1: i64=0; if gok*100 >= (P-1)*90 { t1=1 } 138 pass=pass+g_check("T1: GENERATES coherent grammar -- free-decoded stream is category-valid >= 90% (novel coherent gen)" as *u8, t1); total=total+1 139 var t2: i64=0; if ok*100 >= tp*90 { t2=1 } 140 pass=pass+g_check("T2: learned the grammar on HELD-OUT streams (teacher-forced next-category >= 90% >> 33% chance)" as *u8, t2); total=total+1 141 142 var okall: i64=0; if pass==total { okall=1 } 143 if okall==1 { 144 let logf: i64 = sys_openat_append("knowledge/status/nofloat_grammar.log" as *u8, 420) 145 if logf >= 0 { let w0: i64=sys_write(logf,"NOFLOATGRAMMAR constrained-grammar coherent generation measured\n" as *u8,63); sys_close(logf) } 146 } 147 g_puts("---- grammar gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 148 if okall==1 { g_puts("verdict=GREEN (the affordable landing: a no-float LM learns a grammar and GENERATES coherent novel sentences)\n" as *u8); sys_exit(0); return 0 } 149 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 150}