code wiki / _hdl_build / nx_mt_r0_gate.nx

nx_mt_r0_gate.nx source

↩ module page · 271 lines · 11512 B

1// nx_mt_r0_gate.nx -- GATE for MT-R0: the first rung of the SOVEREIGN NEURAL MACHINE TRANSLATION 2// arc (GEN-WL-WL-NN-TRANSLATION). Proves, by RUNNING, that a sovereign neural net LEARNS to 3// translate -- from random/zero init via the team's own scalar-tape autograd, NOT a hardcoded 4// table. The trainable atom of neural MT = a learned bilingual map: one-hot source word -> 5// linear layer W (the learned parameters) -> output vector -> argmax -> target word. Composes 6// ONLY shipped+gated organs (nx_autograd TRAIN-R1 GREEN + nx_f32 tower). No attention/weights 7// loaded; this is the BACKWARD/learning half proven on a translation task in miniature, the 8// foundation the rest of the arc (sequences -> FNet-mix context -> BPE vocab -> corpus -> the 9// /video /translate endpoint) climbs on. 10// 11// Demo dictionary (English -> Spanish), TARGET INDICES ARE A PERMUTATION (not identity) so a 12// pass cannot come from a trivial copy: 13// src EN: 0 hello 1 family 2 love 3 good 4 day 5 water 14// tgt ES: 0 familia 1 bueno 2 hola 3 dia 4 agua 5 amor (vocab in a DIFFERENT order) 15// map: hello->hola(2) family->familia(0) love->amor(5) good->bueno(1) day->dia(3) water->agua(4) 16// => tgt = [2,0,5,1,3,4] (a real permutation the net must LEARN) 17// 18// FOUR GATES: 19// A LEARNS: after training, argmax == tgt for ALL 6 pairs (acc 6/6) AND mean loss < 1/1000 20// AND loss decreased. The exact statement of "the net learned to translate". 21// B UNTRAINED FAILS (liar-kill): the zero-epoch (W=0) model scores < 6/6 -> the LEARNING did 22// it, not the harness/architecture. 23// C BIT-EXACT REPRODUCIBLE: train twice from zero-init; final W bits identical (determinism 24// exceed-axis carried into ML, like TRAIN-R1 gate C). 25// D DATA-DRIVEN (anti-hardcode liar-kill): train against a DIFFERENT permutation tgt2; the net 26// learns tgt2 (acc_vs_tgt2 == 6/6) AND no longer matches the original (acc_vs_tgt < 6/6). 27// Kills any "the answer was baked in" cheat -- it learns whatever data it is given. 28// 29// genealogy_id: linnainmaa_1970_reverse_mode_ad + rumelhart_1986_backprop (realized_in nx_autograd) 30// lineage_id: sovereign_neural_mt_r0_learned_wordmap_v1 31// license_tier: ORIGINAL 32import "nx_autograd.nx" // ag_* tape + transitively nx_f32 / nx_f32_div / nx_f32_cvt / nx_syscalls 33import "nx_syscalls.nx" 34 35const MT_LOG: *u8 = "knowledge/status/mt_r0.log" 36const MT_S: i64 = 6 // source vocab size 37const MT_T: i64 = 6 // target vocab size 38 39// demo words (file-scope consts; long/literal strings must not live inline -> empty .s) 40const EN0: *u8 = "hello" as *u8 41const EN1: *u8 = "family" as *u8 42const EN2: *u8 = "love" as *u8 43const EN3: *u8 = "good" as *u8 44const EN4: *u8 = "day" as *u8 45const EN5: *u8 = "water" as *u8 46const ES0: *u8 = "familia" as *u8 47const ES1: *u8 = "bueno" as *u8 48const ES2: *u8 = "hola" as *u8 49const ES3: *u8 = "dia" as *u8 50const ES4: *u8 = "agua" as *u8 51const ES5: *u8 = "amor" as *u8 52const ESQ: *u8 = "?" as *u8 53 54func mt_en(i: i64) -> *u8 { 55 if i == 0 { return EN0 } 56 if i == 1 { return EN1 } 57 if i == 2 { return EN2 } 58 if i == 3 { return EN3 } 59 if i == 4 { return EN4 } 60 if i == 5 { return EN5 } 61 return ESQ 62} 63func mt_es(j: i64) -> *u8 { 64 if j == 0 { return ES0 } 65 if j == 1 { return ES1 } 66 if j == 2 { return ES2 } 67 if j == 3 { return ES3 } 68 if j == 4 { return ES4 } 69 if j == 5 { return ES5 } 70 return ESQ 71} 72 73// ---- logging (mirrors nx_train_r1_gate idioms) ---- 74func mt_w(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 } 75func mt_wn(fd: i64, v: i64) -> i64 { 76 let bb: *u8 = sys_mmap(28); var m: i64 = v 77 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 78 let t: *u8 = sys_mmap(28); var k: i64 = 0 79 if m == 0 { t[0] = 48; k = 1 } 80 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 81 var i: i64 = 0 82 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 83 sys_write(fd, bb, k); return 0 84} 85// f32 -> round(v*1000) as signed int (no f32->int converter; nearest by linear advance, values O(1)) 86func mt_f32_to_milli(v: i64) -> i64 { 87 var s: i64 = nx_f32_mul(v, nx_i32_to_f32(1000)) 88 var neg: i64 = 0 89 if nx_f32_lt(s, AG_F32_ZERO) == 1 { neg = 1; s = nx_f32_neg(s) } 90 let half: i64 = ag_constf(1, 2) 91 var m: i64 = 0 92 var go: i64 = 1 93 while go == 1 { 94 let mid: i64 = nx_f32_add(nx_i32_to_f32(m), half) 95 if nx_f32_lt(mid, s) == 1 { 96 m = m + 1 97 if m >= 100000 { go = 0 } 98 } else { go = 0 } 99 } 100 if neg == 1 { return 0 - m } 101 return m 102} 103 104// argmax over the output vector for source token i: o_j = W[j*MT_S + i] (one-hot input picks 105// column i). First-max on ties (so the W=0 untrained model predicts token 0 for every source). 106func mt_argmax(W: *i64, i: i64) -> i64 { 107 var bestj: i64 = 0 108 var best: i64 = W[0 * MT_S + i] 109 var j: i64 = 1 110 while j < MT_T { 111 let o: i64 = W[j * MT_S + i] 112 if nx_f32_gt(o, best) == 1 { best = o; bestj = j } 113 j = j + 1 114 } 115 return bestj 116} 117 118// accuracy: how many of the MT_S sources the model maps to the given target indices. 119func mt_accuracy(W: *i64, tgt: *i64) -> i64 { 120 var c: i64 = 0 121 var i: i64 = 0 122 while i < MT_S { 123 if mt_argmax(W, i) == tgt[i] { c = c + 1 } 124 i = i + 1 125 } 126 return c 127} 128 129// full-batch GD training of the learned word-map W (MT_T x MT_S) on the given targets, MSE to the 130// one-hot target vector, zero-init, lr=1/20. Writes final W (MT_T*MT_S f32) + first/last mean loss. 131func mt_train(epochs: i64, tgt: *i64, Wout: *i64, lfirst: *i64, llast: *i64) -> i64 { 132 let NW: i64 = MT_T * MT_S 133 let W: *i64 = (sys_mmap(NW * 8)) as *i64 134 var z: i64 = 0 135 while z < NW { W[z] = AG_F32_ZERO; z = z + 1 } 136 let lr: i64 = ag_constf(1, 4) // factor |1-2lr|=0.5/epoch -> full f32 convergence 137 let wn: *i64 = (sys_mmap(NW * 8)) as *i64 // tape node index for each W param 138 let tape: *i64 = (sys_mmap(4096 * 5 * 8)) as *i64 139 let np: *i64 = (sys_mmap(8)) as *i64 140 var ep: i64 = 0 141 while ep < epochs { 142 *np = 0 143 // W params as leaves 144 var p: i64 = 0 145 while p < NW { wn[p] = ag_leaf(tape, np, W[p]); p = p + 1 } 146 // one-hot target constants as leaves (reused) 147 let one: i64 = ag_leaf(tape, np, AG_F32_ONE) 148 let zero: i64 = ag_leaf(tape, np, AG_F32_ZERO) 149 var nsum: i64 = ag_leaf(tape, np, AG_F32_ZERO) 150 var i: i64 = 0 151 while i < MT_S { 152 var j: i64 = 0 153 while j < MT_T { 154 var tn: i64 = zero 155 if tgt[i] == j { tn = one } 156 let res: i64 = ag_sub(tape, np, wn[j * MT_S + i], tn) 157 let sq: i64 = ag_mul(tape, np, res, res) 158 nsum = ag_add(tape, np, nsum, sq) 159 j = j + 1 160 } 161 i = i + 1 162 } 163 ag_backward(tape, *np, nsum) // nsum = sum-of-squared-errors over all terms 164 if ep == 0 { *lfirst = ag_val(tape, nsum) } 165 *llast = ag_val(tape, nsum) 166 p = 0 167 while p < NW { 168 W[p] = nx_f32_sub(W[p], nx_f32_mul(lr, ag_grad(tape, wn[p]))) 169 p = p + 1 170 } 171 ep = ep + 1 172 } 173 var q: i64 = 0 174 while q < NW { Wout[q] = W[q]; q = q + 1 } 175 return 0 176} 177 178// emit the live translations the trained model produces (honest demo + operator-visible proof). 179func mt_demo(fd: i64, W: *i64) -> i64 { 180 mt_w(fd, "MT-R0 translations:" as *u8) 181 var i: i64 = 0 182 while i < MT_S { 183 let pj: i64 = mt_argmax(W, i) 184 mt_w(fd, " " as *u8); mt_w(fd, mt_en(i)); mt_w(fd, "->" as *u8); mt_w(fd, mt_es(pj)) 185 i = i + 1 186 } 187 mt_w(fd, "\n" as *u8) 188 return 0 189} 190 191func mt_emit(fd: i64, r: *i64) -> i64 { 192 mt_w(fd, "MTR0GATE authored=organ engine=scalar-tape-autograd-f32 task=learned-bilingual-wordmap" as *u8) 193 mt_w(fd, " | A_learns_pass=" as *u8); mt_wn(fd, r[0]) 194 mt_w(fd, " acc=" as *u8); mt_wn(fd, r[1]); mt_w(fd, "/" as *u8); mt_wn(fd, MT_S) 195 mt_w(fd, " loss_first_milli=" as *u8); mt_wn(fd, r[2]); mt_w(fd, " loss_last_milli=" as *u8); mt_wn(fd, r[3]) 196 mt_w(fd, " | B_untrained_fails_pass=" as *u8); mt_wn(fd, r[4]); mt_w(fd, " untrained_acc=" as *u8); mt_wn(fd, r[5]) 197 mt_w(fd, " | C_bitexact_pass=" as *u8); mt_wn(fd, r[6]) 198 mt_w(fd, " | D_datadriven_pass=" as *u8); mt_wn(fd, r[7]) 199 mt_w(fd, " acc_vs_new=" as *u8); mt_wn(fd, r[8]); mt_w(fd, " acc_vs_old=" as *u8); mt_wn(fd, r[9]) 200 if r[10] == 1 { mt_w(fd, " verdict=GREEN\n" as *u8) } else { mt_w(fd, " verdict=RED\n" as *u8) } 201 return 0 202} 203 204func main() -> i64 { 205 var ok: i64 = 1 206 let NW: i64 = MT_T * MT_S 207 208 // demo dictionary targets (a permutation) and a DIFFERENT permutation for gate D 209 let tgt: *i64 = (sys_mmap(MT_S * 8)) as *i64 210 tgt[0] = 2; tgt[1] = 0; tgt[2] = 5; tgt[3] = 1; tgt[4] = 3; tgt[5] = 4 211 let tgt2: *i64 = (sys_mmap(MT_S * 8)) as *i64 212 tgt2[0] = 1; tgt2[1] = 4; tgt2[2] = 0; tgt2[3] = 5; tgt2[4] = 2; tgt2[5] = 3 213 214 // ---------- Gate A: the net LEARNS to translate ---------- 215 let W: *i64 = (sys_mmap(NW * 8)) as *i64 216 let lf: *i64 = (sys_mmap(8)) as *i64 217 let ll: *i64 = (sys_mmap(8)) as *i64 218 mt_train(300, tgt, W, lf, ll) 219 let acc: i64 = mt_accuracy(W, tgt) 220 var learns_pass: i64 = 1 221 if acc != MT_S { learns_pass = 0 } 222 if nx_f32_lt(*ll, ag_constf(1, 1000)) != 1 { learns_pass = 0 } // mean loss < 1/1000 223 if nx_f32_lt(*ll, *lf) != 1 { learns_pass = 0 } // loss decreased 224 if learns_pass != 1 { ok = 0 } 225 226 // ---------- Gate B: untrained (zero-epoch) model FAILS ---------- 227 let W0: *i64 = (sys_mmap(NW * 8)) as *i64 228 let lf0: *i64 = (sys_mmap(8)) as *i64 229 let ll0: *i64 = (sys_mmap(8)) as *i64 230 mt_train(0, tgt, W0, lf0, ll0) // 0 epochs -> stays zero-init 231 let acc0: i64 = mt_accuracy(W0, tgt) 232 var untrained_fails_pass: i64 = 1 233 if acc0 >= MT_S { untrained_fails_pass = 0 } 234 if untrained_fails_pass != 1 { ok = 0 } 235 236 // ---------- Gate C: bit-exact reproducible ---------- 237 let Wr: *i64 = (sys_mmap(NW * 8)) as *i64 238 let lfr: *i64 = (sys_mmap(8)) as *i64 239 let llr: *i64 = (sys_mmap(8)) as *i64 240 mt_train(300, tgt, Wr, lfr, llr) 241 var bitexact_pass: i64 = 1 242 var c: i64 = 0 243 while c < NW { if Wr[c] != W[c] { bitexact_pass = 0 } c = c + 1 } 244 if bitexact_pass != 1 { ok = 0 } 245 246 // ---------- Gate D: data-driven (anti-hardcode liar-kill) ---------- 247 let Wd: *i64 = (sys_mmap(NW * 8)) as *i64 248 let lfd: *i64 = (sys_mmap(8)) as *i64 249 let lld: *i64 = (sys_mmap(8)) as *i64 250 mt_train(300, tgt2, Wd, lfd, lld) 251 let acc_new: i64 = mt_accuracy(Wd, tgt2) 252 let acc_old: i64 = mt_accuracy(Wd, tgt) 253 var datadriven_pass: i64 = 1 254 if acc_new != MT_S { datadriven_pass = 0 } 255 if acc_old >= MT_S { datadriven_pass = 0 } 256 if datadriven_pass != 1 { ok = 0 } 257 258 // ---------- emit ---------- 259 let r: *i64 = (sys_mmap(11 * 8)) as *i64 260 r[0] = learns_pass; r[1] = acc; r[2] = mt_f32_to_milli(*lf); r[3] = mt_f32_to_milli(*ll) 261 r[4] = untrained_fails_pass; r[5] = acc0 262 r[6] = bitexact_pass; r[7] = datadriven_pass; r[8] = acc_new; r[9] = acc_old 263 r[10] = ok 264 mt_emit(1, r) 265 mt_demo(1, W) 266 let logf: i64 = sys_openat_append(MT_LOG, 420) 267 if logf >= 0 { mt_emit(logf, r); mt_demo(logf, W); sys_close(logf) } 268 269 if ok == 1 { return 0 } 270 return 1 271}