code wiki / _hdl_build / nx_mt_r0_gate.nx

nx_mt_r0_gate.nx source

↩ module page · 279 lines · 12043 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" 34import "nx_gate_verdict.nx" 35 36const MT_LOG: *u8 = "knowledge/status/mt_r0.log" 37const MT_S: i64 = 6 // source vocab size 38const MT_T: i64 = 6 // target vocab size 39 40// demo words (file-scope consts; long/literal strings must not live inline -> empty .s) 41const EN0: *u8 = "hello" as *u8 42const EN1: *u8 = "family" as *u8 43const EN2: *u8 = "love" as *u8 44const EN3: *u8 = "good" as *u8 45const EN4: *u8 = "day" as *u8 46const EN5: *u8 = "water" as *u8 47const ES0: *u8 = "familia" as *u8 48const ES1: *u8 = "bueno" as *u8 49const ES2: *u8 = "hola" as *u8 50const ES3: *u8 = "dia" as *u8 51const ES4: *u8 = "agua" as *u8 52const ES5: *u8 = "amor" as *u8 53const ESQ: *u8 = "?" as *u8 54 55func mt_en(i: i64) -> *u8 { 56 if i == 0 { return EN0 } 57 if i == 1 { return EN1 } 58 if i == 2 { return EN2 } 59 if i == 3 { return EN3 } 60 if i == 4 { return EN4 } 61 if i == 5 { return EN5 } 62 return ESQ 63} 64func mt_es(j: i64) -> *u8 { 65 if j == 0 { return ES0 } 66 if j == 1 { return ES1 } 67 if j == 2 { return ES2 } 68 if j == 3 { return ES3 } 69 if j == 4 { return ES4 } 70 if j == 5 { return ES5 } 71 return ESQ 72} 73 74// ---- logging (mirrors nx_train_r1_gate idioms) ---- 75func 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 } 76func mt_wn(fd: i64, v: i64) -> i64 { 77 let bb: *u8 = sys_mmap(28); var m: i64 = v 78 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 79 let t: *u8 = sys_mmap(28); var k: i64 = 0 80 if m == 0 { t[0] = 48; k = 1 } 81 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 82 var i: i64 = 0 83 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 84 sys_write(fd, bb, k); return 0 85} 86// f32 -> round(v*1000) as signed int (no f32->int converter; nearest by linear advance, values O(1)) 87func mt_f32_to_milli(v: i64) -> i64 { 88 var s: i64 = nx_f32_mul(v, nx_i32_to_f32(1000)) 89 var neg: i64 = 0 90 if nx_f32_lt(s, AG_F32_ZERO) == 1 { neg = 1; s = nx_f32_neg(s) } 91 let half: i64 = ag_constf(1, 2) 92 var m: i64 = 0 93 var go: i64 = 1 94 while go == 1 { 95 let mid: i64 = nx_f32_add(nx_i32_to_f32(m), half) 96 if nx_f32_lt(mid, s) == 1 { 97 m = m + 1 98 if m >= 100000 { go = 0 } 99 } else { go = 0 } 100 } 101 if neg == 1 { return 0 - m } 102 return m 103} 104 105// argmax over the output vector for source token i: o_j = W[j*MT_S + i] (one-hot input picks 106// column i). First-max on ties (so the W=0 untrained model predicts token 0 for every source). 107func mt_argmax(W: *i64, i: i64) -> i64 { 108 var bestj: i64 = 0 109 var best: i64 = W[0 * MT_S + i] 110 var j: i64 = 1 111 while j < MT_T { 112 let o: i64 = W[j * MT_S + i] 113 if nx_f32_gt(o, best) == 1 { best = o; bestj = j } 114 j = j + 1 115 } 116 return bestj 117} 118 119// accuracy: how many of the MT_S sources the model maps to the given target indices. 120func mt_accuracy(W: *i64, tgt: *i64) -> i64 { 121 var c: i64 = 0 122 var i: i64 = 0 123 while i < MT_S { 124 if mt_argmax(W, i) == tgt[i] { c = c + 1 } 125 i = i + 1 126 } 127 return c 128} 129 130// full-batch GD training of the learned word-map W (MT_T x MT_S) on the given targets, MSE to the 131// one-hot target vector, zero-init, lr=1/20. Writes final W (MT_T*MT_S f32) + first/last mean loss. 132func mt_train(epochs: i64, tgt: *i64, Wout: *i64, lfirst: *i64, llast: *i64) -> i64 { 133 let NW: i64 = MT_T * MT_S 134 let W: *i64 = (sys_mmap(NW * 8)) as *i64 135 var z: i64 = 0 136 while z < NW { W[z] = AG_F32_ZERO; z = z + 1 } 137 let lr: i64 = ag_constf(1, 4) // factor |1-2lr|=0.5/epoch -> full f32 convergence 138 let wn: *i64 = (sys_mmap(NW * 8)) as *i64 // tape node index for each W param 139 let tape: *i64 = (sys_mmap(4096 * 5 * 8)) as *i64 140 let np: *i64 = (sys_mmap(8)) as *i64 141 var ep: i64 = 0 142 while ep < epochs { 143 *np = 0 144 // W params as leaves 145 var p: i64 = 0 146 while p < NW { wn[p] = ag_leaf(tape, np, W[p]); p = p + 1 } 147 // one-hot target constants as leaves (reused) 148 let one: i64 = ag_leaf(tape, np, AG_F32_ONE) 149 let zero: i64 = ag_leaf(tape, np, AG_F32_ZERO) 150 var nsum: i64 = ag_leaf(tape, np, AG_F32_ZERO) 151 var i: i64 = 0 152 while i < MT_S { 153 var j: i64 = 0 154 while j < MT_T { 155 var tn: i64 = zero 156 if tgt[i] == j { tn = one } 157 let res: i64 = ag_sub(tape, np, wn[j * MT_S + i], tn) 158 let sq: i64 = ag_mul(tape, np, res, res) 159 nsum = ag_add(tape, np, nsum, sq) 160 j = j + 1 161 } 162 i = i + 1 163 } 164 ag_backward(tape, *np, nsum) // nsum = sum-of-squared-errors over all terms 165 if ep == 0 { *lfirst = ag_val(tape, nsum) } 166 *llast = ag_val(tape, nsum) 167 p = 0 168 while p < NW { 169 W[p] = nx_f32_sub(W[p], nx_f32_mul(lr, ag_grad(tape, wn[p]))) 170 p = p + 1 171 } 172 ep = ep + 1 173 } 174 var q: i64 = 0 175 while q < NW { Wout[q] = W[q]; q = q + 1 } 176 return 0 177} 178 179// emit the live translations the trained model produces (honest demo + operator-visible proof). 180func mt_demo(fd: i64, W: *i64) -> i64 { 181 mt_w(fd, "MT-R0 translations:" as *u8) 182 var i: i64 = 0 183 while i < MT_S { 184 let pj: i64 = mt_argmax(W, i) 185 mt_w(fd, " " as *u8); mt_w(fd, mt_en(i)); mt_w(fd, "->" as *u8); mt_w(fd, mt_es(pj)) 186 i = i + 1 187 } 188 mt_w(fd, "\n" as *u8) 189 return 0 190} 191 192func mt_emit(fd: i64, r: *i64) -> i64 { 193 mt_w(fd, "MTR0GATE authored=organ engine=scalar-tape-autograd-f32 task=learned-bilingual-wordmap" as *u8) 194 mt_w(fd, " | A_learns_pass=" as *u8); mt_wn(fd, r[0]) 195 mt_w(fd, " acc=" as *u8); mt_wn(fd, r[1]); mt_w(fd, "/" as *u8); mt_wn(fd, MT_S) 196 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]) 197 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]) 198 mt_w(fd, " | C_bitexact_pass=" as *u8); mt_wn(fd, r[6]) 199 mt_w(fd, " | D_datadriven_pass=" as *u8); mt_wn(fd, r[7]) 200 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]) 201 if r[10] == 1 { mt_w(fd, " verdict=GREEN\n" as *u8) } else { mt_w(fd, " verdict=RED\n" as *u8) } 202 return 0 203} 204 205func main() -> i64 { 206 var ok: i64 = 1 207 let NW: i64 = MT_T * MT_S 208 209 // demo dictionary targets (a permutation) and a DIFFERENT permutation for gate D 210 let tgt: *i64 = (sys_mmap(MT_S * 8)) as *i64 211 tgt[0] = 2; tgt[1] = 0; tgt[2] = 5; tgt[3] = 1; tgt[4] = 3; tgt[5] = 4 212 let tgt2: *i64 = (sys_mmap(MT_S * 8)) as *i64 213 tgt2[0] = 1; tgt2[1] = 4; tgt2[2] = 0; tgt2[3] = 5; tgt2[4] = 2; tgt2[5] = 3 214 215 // ---------- Gate A: the net LEARNS to translate ---------- 216 let W: *i64 = (sys_mmap(NW * 8)) as *i64 217 let lf: *i64 = (sys_mmap(8)) as *i64 218 let ll: *i64 = (sys_mmap(8)) as *i64 219 mt_train(300, tgt, W, lf, ll) 220 let acc: i64 = mt_accuracy(W, tgt) 221 var learns_pass: i64 = 1 222 if acc != MT_S { learns_pass = 0 } 223 if nx_f32_lt(*ll, ag_constf(1, 1000)) != 1 { learns_pass = 0 } // mean loss < 1/1000 224 if nx_f32_lt(*ll, *lf) != 1 { learns_pass = 0 } // loss decreased 225 if learns_pass != 1 { ok = 0 } 226 227 // ---------- Gate B: untrained (zero-epoch) model FAILS ---------- 228 let W0: *i64 = (sys_mmap(NW * 8)) as *i64 229 let lf0: *i64 = (sys_mmap(8)) as *i64 230 let ll0: *i64 = (sys_mmap(8)) as *i64 231 mt_train(0, tgt, W0, lf0, ll0) // 0 epochs -> stays zero-init 232 let acc0: i64 = mt_accuracy(W0, tgt) 233 var untrained_fails_pass: i64 = 1 234 if acc0 >= MT_S { untrained_fails_pass = 0 } 235 if untrained_fails_pass != 1 { ok = 0 } 236 237 // ---------- Gate C: bit-exact reproducible ---------- 238 let Wr: *i64 = (sys_mmap(NW * 8)) as *i64 239 let lfr: *i64 = (sys_mmap(8)) as *i64 240 let llr: *i64 = (sys_mmap(8)) as *i64 241 mt_train(300, tgt, Wr, lfr, llr) 242 var bitexact_pass: i64 = 1 243 var c: i64 = 0 244 while c < NW { if Wr[c] != W[c] { bitexact_pass = 0 } c = c + 1 } 245 if bitexact_pass != 1 { ok = 0 } 246 247 // ---------- Gate D: data-driven (anti-hardcode liar-kill) ---------- 248 let Wd: *i64 = (sys_mmap(NW * 8)) as *i64 249 let lfd: *i64 = (sys_mmap(8)) as *i64 250 let lld: *i64 = (sys_mmap(8)) as *i64 251 mt_train(300, tgt2, Wd, lfd, lld) 252 let acc_new: i64 = mt_accuracy(Wd, tgt2) 253 let acc_old: i64 = mt_accuracy(Wd, tgt) 254 var datadriven_pass: i64 = 1 255 if acc_new != MT_S { datadriven_pass = 0 } 256 if acc_old >= MT_S { datadriven_pass = 0 } 257 if datadriven_pass != 1 { ok = 0 } 258 259 // ---------- emit ---------- 260 let r: *i64 = (sys_mmap(11 * 8)) as *i64 261 r[0] = learns_pass; r[1] = acc; r[2] = mt_f32_to_milli(*lf); r[3] = mt_f32_to_milli(*ll) 262 r[4] = untrained_fails_pass; r[5] = acc0 263 r[6] = bitexact_pass; r[7] = datadriven_pass; r[8] = acc_new; r[9] = acc_old 264 r[10] = ok 265 mt_emit(1, r) 266 mt_demo(1, W) 267 let logf: i64 = sys_openat_append(MT_LOG, 420) 268 if logf >= 0 { mt_emit(logf, r); mt_demo(logf, W); sys_close(logf) } 269 270 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 271 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 272 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 273 let ctr__dry: *i64 = gv_ctr() 274 ctr__dry[0] = ok 275 ctr__dry[1] = 1 276 let rc__dry: i64 = gv_verdict("MT-R0-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 277 sys_exit(rc__dry) 278 return rc__dry 279}