code wiki / _hdl_build / nx_mt_core.nx
nx_mt_core.nx source
↩ module page · 95 lines · 4183 B
1// nx_mt_core.nx -- reusable CORE of the sovereign neural MT arc (GEN-WL-WL-NN-TRANSLATION).
2// A learned word-map W (T x S), SHARED across all sequence positions, trained by the team's
3// scalar-tape autograd (MSE to one-hot targets, full-batch gradient descent, zero-init).
4// Applied per-position it translates token SEQUENCES of any length. R0 (nx_mt_r0_gate) proved
5// the single-token atom inline; this factors that into a reusable organ and generalizes it to
6// multi-token sequences with weight-sharing. Because W is position-independent, the map
7// GENERALIZES to HELD-OUT sequences (combinations never trained). CONTEXT / reordering (an
8// output token depending on MORE THAN its own input token) is R2, via fnet_mix -- not here.
9//
10// Shared-weight gradient note: a param W[j,s] is one tape leaf referenced by EVERY (sentence,
11// position) token whose source word is s, so backward accumulates m contributions -> the GD
12// update factor is (1 - 2*lr*m) where m = that word's occurrence count. Callers must pass an lr
13// with 2*lr*m_max < 2 (convergence) -- lr is a PARAMETER, never hardcoded (no magic numbers).
14//
15// genealogy_id: rumelhart_1986_backprop (realized_in nx_autograd)
16// lineage_id: sovereign_neural_mt_core_shared_wordmap_v1
17// license_tier: ORIGINAL
18import "nx_autograd.nx" // ag_* tape + transitively nx_f32 / nx_f32_div / nx_f32_cvt / nx_syscalls
19import "nx_syscalls.nx"
20const K_MAGIC_8192: i64 = 8192
21
22// per-token argmax: o_j = W[j*S + s] (one-hot source picks column s). First-max on ties, so the
23// zero-init (untrained) model deterministically predicts target token 0 for every source.
24func mt_argmax(W: *i64, S: i64, T: i64, s: i64) -> i64 {
25 var bestj: i64 = 0
26 var best: i64 = W[0 * S + s]
27 var j: i64 = 1
28 while j < T {
29 let o: i64 = W[j * S + s]
30 if nx_f32_gt(o, best) == 1 { best = o; bestj = j }
31 j = j + 1
32 }
33 return bestj
34}
35
36// per-token accuracy over a sentence set. srcs/tgts are flat (n_sent*L) arrays of token indices.
37func mt_seq_acc(W: *i64, S: i64, T: i64, srcs: *i64, tgts: *i64, n_sent: i64, L: i64) -> i64 {
38 var c: i64 = 0
39 var k: i64 = 0
40 let n: i64 = n_sent * L
41 while k < n {
42 if mt_argmax(W, S, T, srcs[k]) == tgts[k] { c = c + 1 }
43 k = k + 1
44 }
45 return c
46}
47
48// full-batch GD training of the shared word-map W (T x S) over a set of token sequences. Loss =
49// sum over every (sentence,position) token of squared-error(W column -> one-hot target). Zero-
50// init; caller supplies lr (see shared-weight note above). Writes first/last sum-loss.
51func mt_train(W: *i64, S: i64, T: i64, srcs: *i64, tgts: *i64, n_sent: i64, L: i64, epochs: i64, lr: i64, lfirst: *i64, llast: *i64) -> i64 {
52 let NW: i64 = T * S
53 var z: i64 = 0
54 while z < NW { W[z] = AG_F32_ZERO; z = z + 1 }
55 let wn: *i64 = (sys_mmap(NW * 8)) as *i64
56 let tape: *i64 = (sys_mmap(K_MAGIC_8192 * 5 * 8)) as *i64
57 let np: *i64 = (sys_mmap(8)) as *i64
58 let ntok: i64 = n_sent * L
59 var ep: i64 = 0
60 while ep < epochs {
61 *np = 0
62 var p: i64 = 0
63 while p < NW { wn[p] = ag_leaf(tape, np, W[p]); p = p + 1 }
64 let one: i64 = ag_leaf(tape, np, AG_F32_ONE)
65 let zero: i64 = ag_leaf(tape, np, AG_F32_ZERO)
66 var nsum: i64 = ag_leaf(tape, np, AG_F32_ZERO)
67 var k: i64 = 0
68 while k < ntok {
69 let s: i64 = srcs[k]
70 let tt: i64 = tgts[k]
71 var j: i64 = 0
72 while j < T {
73 var tn: i64 = zero
74 if tt == j { tn = one }
75 let res: i64 = ag_sub(tape, np, wn[j * S + s], tn)
76 let sq: i64 = ag_mul(tape, np, res, res)
77 nsum = ag_add(tape, np, nsum, sq)
78 j = j + 1
79 }
80 k = k + 1
81 }
82 ag_backward(tape, *np, nsum)
83 if ep == 0 { *lfirst = ag_val(tape, nsum) }
84 *llast = ag_val(tape, nsum)
85 p = 0
86 while p < NW {
87 W[p] = nx_f32_sub(W[p], nx_f32_mul(lr, ag_grad(tape, wn[p])))
88 p = p + 1
89 }
90 ep = ep + 1
91 }
92 return 0
93}
94
95func main() -> i64 { return 0 } // library organ; proven by nx_mt_r1_gate