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}