code wiki / _hdl_build / nx_nofloat_transformer.nx

nx_nofloat_transformer.nx source

↩ module page · 118 lines · 8334 B

1// nx_nofloat_transformer.nx -- SOVEREIGN NO-FLOAT TRANSFORMER BLOCK (the AI culmination), pure integer Q16, 2// deterministic. Pre-norm block: h = x + SelfAttn(LayerNorm(x)); out = h + FFN(LayerNorm(h)). New primitive = 3// integer LayerNorm (mean/var + Newton integer sqrt for std). Self-attention reuses fixed-point exp/softmax. 4// FFN = matvec -> ReLU -> matvec. Everything integer => bit-exact deterministic (the moat vs float transformers). 5// T1 integer sqrt correct (sqrt_q16(4)=2, sqrt_q16(9)=3). T2 LayerNorm normalizes (output mean ~= 0). 6// T3 full block runs end-to-end (output transformed vs input, bounded). T4 (EXCEED) determinism bit-identical. 7// expect_exit: 0 Sovereign: nx_syscalls. 8import "nx_syscalls.nx" 9import "nx_g_puts_lib.nx" 10 11func g_pn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var x: i64=v; if x<0{b[0]=45;sys_write(1,b,1);x=0-x} if x==0{b[0]=48;sys_write(1,b,1);return 0} var d: i64=0; var y: i64=x; while y>0{d=d+1;y=y/10} var i: i64=d-1; y=x; while i>=0{b[i]=(48+(y%10)) as u8;y=y/10;i=i-1} sys_write(1,b,d); return 0 } 12func ck(name: *u8, c: i64) -> i64 { if c==1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) } g_puts(name); g_puts("\n" as *u8); return c } 13 14const Q: i64 = 16 15const ONE: i64 = 65536 16const D: i64 = 4 17const T: i64 = 2 18const LOG2E: i64 = 94548 19const C1: i64 = 45426 20const C2: i64 = 15743 21const EPS: i64 = 65 // ~0.001 in Q16 (layernorm epsilon) 22func fxmul(a: i64, b: i64) -> i64 { return (a*b)>>Q } 23func relu(x: i64) -> i64 { if x>0 { return x } return 0 } 24func iabs(v: i64) -> i64 { if v<0 { return 0-v } return v } 25 26func isqrt(n: i64) -> i64 { if n<2 { return n } var x: i64=n; var y: i64=(x+1)/2; while y<x { x=y; y=(x + n/x)/2 } return x } 27func sqrt_q16(y: i64) -> i64 { return isqrt(y*ONE) } // sqrt of a Q16 value, result in Q16 28 29func exp_fx(x: i64) -> i64 { 30 var xx: i64=x; if xx>0 { xx=0 } 31 let yabs: i64=fxmul(0-xx, LOG2E); let nabs: i64=yabs>>Q; let fabs: i64=yabs-(nabs<<Q) 32 let f2: i64=fxmul(fabs,fabs); let p: i64=ONE+fxmul(fabs,C1)+fxmul(f2,C2); let inv: i64=(ONE*ONE)/p 33 if nabs>=31 { return 0 } return inv>>nabs 34} 35func dotp(a: *i64, b: *i64, n: i64) -> i64 { var s: i64=0; var i: i64=0; while i<n { s=s+fxmul(a[i],b[i]); i=i+1 } return s } 36// LayerNorm of vector x[0..D) -> out[0..D): zero-mean, unit-var (then identity affine). 37func layernorm(x: *i64, out: *i64) -> i64 { 38 var sum: i64=0; var i: i64=0; while i<D { sum=sum+x[i]; i=i+1 } let mean: i64=sum/D 39 var vs: i64=0; i=0; while i<D { let d: i64=x[i]-mean; vs=vs+fxmul(d,d); i=i+1 } let var_: i64=vs/D 40 let std: i64=sqrt_q16(var_+EPS) 41 i=0; while i<D { out[i]=((x[i]-mean)*ONE)/std; i=i+1 } return mean 42} 43func matvec(W: *i64, v: *i64, out: *i64) -> i64 { var i: i64=0; while i<D { var s: i64=0; var j: i64=0; while j<D { s=s+fxmul(W[i*D+j], v[j]); j=j+1 } out[i]=s; i=i+1 } return 0 } 44 45// one pre-norm transformer block over x[T*D] -> out[T*D]. 46func block(x: *i64, out: *i64, W1: *i64, W2: *i64) -> i64 { 47 let ln: *i64 = sys_mmap(T*D*8) as *i64 48 // LayerNorm each token (index math, unambiguous) 49 var t: i64=0; while t<T { let xi: *i64 = sys_mmap(D*8) as *i64; let oi: *i64 = sys_mmap(D*8) as *i64; var k: i64=0; while k<D { xi[k]=x[t*D+k]; k=k+1 } layernorm(xi, oi); k=0; while k<D { ln[t*D+k]=oi[k]; k=k+1 } t=t+1 } 50 // self-attention over the T tokens: scores[i][j]=dot(ln_i,ln_j); softmax over j; attn_i = sum_j w_j * ln_j 51 let h: *i64 = sys_mmap(T*D*8) as *i64 52 var i: i64=0 53 while i<T { 54 let sc: *i64 = sys_mmap(T*8) as *i64; let a: *i64 = sys_mmap(T*8) as *i64; let lni: *i64 = sys_mmap(D*8) as *i64 55 var k: i64=0; while k<D { lni[k]=ln[i*D+k]; k=k+1 } 56 var j: i64=0; while j<T { let lnj: *i64=sys_mmap(D*8) as *i64; var m: i64=0; while m<D { lnj[m]=ln[j*D+m]; m=m+1 } sc[j]=dotp(lni,lnj,D); j=j+1 } 57 var mx: i64=sc[0]; j=1; while j<T { if sc[j]>mx { mx=sc[j] } j=j+1 } 58 var sume: i64=0; j=0; while j<T { a[j]=exp_fx(sc[j]-mx); sume=sume+a[j]; j=j+1 } 59 j=0; while j<T { a[j]=(a[j]*ONE)/sume; j=j+1 } 60 var d: i64=0; while d<D { var acc: i64=0; j=0; while j<T { acc=acc+fxmul(a[j], ln[j*D+d]); j=j+1 } h[i*D+d]=x[i*D+d]+acc; d=d+1 } // residual 61 i=i+1 62 } 63 // FFN with pre-norm + residual: out = h + W2*relu(W1*LN(h)) 64 i=0 65 while i<T { 66 let hi: *i64=sys_mmap(D*8) as *i64; let lnh: *i64=sys_mmap(D*8) as *i64; var k: i64=0; while k<D { hi[k]=h[i*D+k]; k=k+1 } 67 layernorm(hi, lnh) 68 let m1: *i64=sys_mmap(D*8) as *i64; matvec(W1, lnh, m1); k=0; while k<D { m1[k]=relu(m1[k]); k=k+1 } 69 let m2: *i64=sys_mmap(D*8) as *i64; matvec(W2, m1, m2) 70 k=0; while k<D { out[i*D+k]=h[i*D+k]+m2[k]; k=k+1 } 71 i=i+1 72 } 73 return 0 74} 75 76func main() -> i64 { 77 g_puts("nx_nofloat_transformer (SOVEREIGN no-float TRANSFORMER BLOCK -- integer LayerNorm+sqrt+attention+FFN, deterministic)\n" as *u8) 78 var pass: i64=0; var total: i64=0 79 80 g_puts(" integer sqrt: sqrt_q16(4.0)="); g_pn(sqrt_q16(4*ONE)); g_puts(" (want 131072=2.0) sqrt_q16(9.0)="); g_pn(sqrt_q16(9*ONE)); g_puts(" (want 196608=3.0)\n" as *u8) 81 var t1: i64=0; if sqrt_q16(4*ONE)==(2*ONE) { if sqrt_q16(9*ONE)==(3*ONE) { t1=1 } } 82 pass=pass+ck("T1: integer Newton sqrt correct (sqrt 4.0=2.0, 9.0=3.0 in Q16)" as *u8, t1); total=total+1 83 84 let tok: *i64=sys_mmap(D*8) as *i64; tok[0]=ONE; tok[1]=2*ONE; tok[2]=0; tok[3]=4*ONE 85 let lno: *i64=sys_mmap(D*8) as *i64; layernorm(tok, lno) 86 var lnsum: i64=lno[0]+lno[1]+lno[2]+lno[3] 87 g_puts(" LayerNorm([1,2,0,4]) = ["); g_pn(lno[0]); g_puts(","); g_pn(lno[1]); g_puts(","); g_pn(lno[2]); g_puts(","); g_pn(lno[3]); g_puts("] sum(mean*D)="); g_pn(lnsum); g_puts(" (~0)\n" as *u8) 88 var t2: i64=0; if iabs(lnsum)<(ONE/10) { t2=1 } 89 pass=pass+ck("T2: LayerNorm normalizes -- output is ~zero-mean (sum ~= 0)" as *u8, t2); total=total+1 90 91 // build the block input + weights 92 let x: *i64=sys_mmap(T*D*8) as *i64; x[0]=ONE; x[1]=2*ONE; x[2]=0; x[3]=ONE; x[4]=3*ONE; x[5]=0; x[6]=ONE; x[7]=2*ONE 93 let W1: *i64=sys_mmap(D*D*8) as *i64; let W2: *i64=sys_mmap(D*D*8) as *i64 94 var i: i64=0; while i<D*D { W1[i]=ONE/2; W2[i]=ONE/3; i=i+1 } // simple fixed weights 95 let out: *i64=sys_mmap(T*D*8) as *i64; block(x, out, W1, W2) 96 var changed: i64=0; var bounded: i64=1; i=0; while i<T*D { if out[i]!=x[i] { changed=1 } if iabs(out[i])>(1000*ONE) { bounded=0 } i=i+1 } 97 g_puts(" block out[0..3]=["); g_pn(out[0]); g_puts(","); g_pn(out[1]); g_puts(","); g_pn(out[2]); g_puts(","); g_pn(out[3]); g_puts("] (transformed + bounded)\n" as *u8) 98 var t3: i64=0; if changed==1 { if bounded==1 { t3=1 } } 99 pass=pass+ck("T3: full transformer block runs end-to-end (LN->attn->residual->LN->FFN->residual); output transformed + bounded" as *u8, t3); total=total+1 100 101 let out2: *i64=sys_mmap(T*D*8) as *i64; block(x, out2, W1, W2) 102 var same: i64=1; i=0; while i<T*D { if out[i]!=out2[i] { same=0 } i=i+1 } 103 var t4: i64=0; if same==1 { t4=1 } 104 pass=pass+ck("T4 (EXCEED): DETERMINISTIC -- two block runs are BIT-IDENTICAL (float transformers cannot guarantee)" as *u8, t4); total=total+1 105 106 g_puts(" >> the SOVEREIGN no-float TRANSFORMER BLOCK runs in pure integer + is deterministic. The full stack:\n" as *u8) 107 g_puts(" matmul + train(SGD) + multilayer-backprop + attention/softmax + LayerNorm + the assembled block -- all no-float.\n" as *u8) 108 g_puts(" CLIMB: multi-head + Q/K/V projections + positional encoding + stack N blocks + a tokenizer = a sovereign deterministic LLM; MEASURE vs MLPerf.\n" as *u8) 109 110 var okall: i64=0; if pass==total { okall=1 } 111 g_puts("---- nx_nofloat_transformer: passed "); g_pn(pass); g_puts(" / "); g_pn(total); g_puts(" ----\n" as *u8) 112 if okall==1 { 113 let logf: i64=sys_openat_append("knowledge/status/nofloat_transformer.log" as *u8, 420) 114 if logf>=0 { let z: i64=sys_write(logf,"NXNOFLOATTRANSFORMER GREEN: integer LayerNorm+sqrt + self-attention + residual + FFN = full transformer block, deterministic\n" as *u8,119); sys_close(logf) } 115 g_puts("verdict=GREEN (the sovereign no-float TRANSFORMER BLOCK: integer LayerNorm+attention+FFN+residual, deterministic; the AI culmination toward a sovereign LLM)\n" as *u8); sys_exit(0); return 0 116 } 117 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 118}