code wiki / _hdl_build / nx_mt_r3_gate.nx

nx_mt_r3_gate.nx source

↩ module page · 206 lines · 9918 B

1// nx_mt_r3_gate.nx -- GATE for MT-R3: REAL TEXT via the production BPE tokenizer (nx_bpe). The 2// MT arc moves off hand-coded integer toy indices: input/output are now actual TEXT STRINGS, 3// tokenized to subword IDs by the team's shipped Byte-Pair-Encoding organ and detokenized back. 4// The learned word-map (proven in R0/R1/R2, reused from nx_mt_core) maps EN token IDs -> ES 5// token IDs in between. This is the text-interface bookend the rest of the arc needs; it does 6// NOT yet do open-vocabulary sentence MT (that's R4: real corpus / trained weights). 7// 8// Sovereign self-contained vocab (no external files; nx_bpe builds vocab in-code): 9// EN (with merges, so encoding is real BPE): bytes g o s e a t ; merges (e,a)->ea, (s,ea)->sea, 10// (t,ea)->tea, (g,o)->go. Words: "sea" "tea" "go" each encode to ONE token; "ea" is a SHARED 11// subword of sea/tea. Out-of-vocab "seat" decomposes to known subwords [sea, t]. 12// ES (decode side): whole-word tokens "mar" "te" "ir". 13// translation map (learned via nx_mt_core): sea->mar, tea->te, go->ir. 14// 15// FOUR GATES: 16// A BPE ROUND-TRIP: decode(encode(x)) == x byte-exact for "sea","tea","go". 17// B SUBWORD DECOMPOSITION (the BPE value): encode("seat") == [sea, t] (OOV word -> known 18// subwords) and round-trips byte-exact -- a hand-coded index table cannot do this. 19// C END-TO-END TEXT TRANSLATE: translate("sea")=="mar", translate("tea")=="te", 20// translate("go")=="ir" (real string in, real string out; 3/3). 21// D UNTRAINED FAILS (liar-kill): the zero-epoch map mistranslates (< 3/3) -> the LEARNED map 22// does the translating, not the tokenizer. 23// 24// genealogy_id: sennrich_haddow_birch_2016_bpe (realized_in nx_bpe) + rumelhart_1986_backprop 25// lineage_id: sovereign_neural_mt_r3_bpe_realtext_v1 26// license_tier: ORIGINAL 27import "nx_bpe.nx" // nx_bpe_vocab_new / add_token / add_merge / encode / decode (+ nx_intern/loop/tier) 28import "nx_mt_core.nx" // mt_train / mt_argmax (the learned map) 29import "nx_autograd.nx" // ag_constf + nx_syscalls 30import "nx_syscalls.nx" 31 32const M3_LOG: *u8 = "knowledge/status/mt_r3.log" 33 34const C_G: *u8 = "g" as *u8 35const C_O: *u8 = "o" as *u8 36const C_S: *u8 = "s" as *u8 37const C_E: *u8 = "e" as *u8 38const C_A: *u8 = "a" as *u8 39const C_T: *u8 = "t" as *u8 40const C_EA: *u8 = "ea" as *u8 41const C_SEA: *u8 = "sea" as *u8 42const C_TEA: *u8 = "tea" as *u8 43const C_GO: *u8 = "go" as *u8 44const C_SEAT: *u8 = "seat" as *u8 45const C_MAR: *u8 = "mar" as *u8 46const C_TE: *u8 = "te" as *u8 47const C_IR: *u8 = "ir" as *u8 48 49func m3_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 } 50func m3_wn(fd: i64, v: i64) -> i64 { 51 let bb: *u8 = sys_mmap(28); var m: i64 = v 52 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 53 let t: *u8 = sys_mmap(28); var k: i64 = 0 54 if m == 0 { t[0] = 48; k = 1 } 55 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 56 var i: i64 = 0 57 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 58 sys_write(fd, bb, k); return 0 59} 60func m3_streq(a: *u8, la: i64, b: *u8, lb: i64) -> i64 { 61 if la != lb { return 0 } 62 var i: i64 = 0 63 while i < la { if a[i] != b[i] { return 0 } i = i + 1 } 64 return 1 65} 66 67// translate a text string EN->ES via BPE-encode -> learned map (per token) -> BPE-decode. 68// writes ES bytes into out, returns ES byte length (or -1 on encode error). 69func m3_translate(v_en: *NxBpeVocab, v_es: *NxBpeVocab, W: *i64, S: i64, T: i64, text: *u8, tlen: i64, out: *u8) -> i64 { 70 let en_ids: *i64 = (sys_mmap(64 * 8)) as *i64 71 let n: i64 = nx_bpe_encode(v_en, text, tlen, en_ids) 72 if n < 0 { return 0 - 1 } 73 let es_ids: *i64 = (sys_mmap(64 * 8)) as *i64 74 var k: i64 = 0 75 while k < n { es_ids[k] = mt_argmax(W, S, T, en_ids[k]); k = k + 1 } 76 return nx_bpe_decode(v_es, es_ids, n, out) 77} 78 79// does translate(text) == expect ? 80func m3_check(v_en: *NxBpeVocab, v_es: *NxBpeVocab, W: *i64, S: i64, T: i64, text: *u8, tlen: i64, expect: *u8, elen: i64) -> i64 { 81 let out: *u8 = sys_mmap(64) 82 let m: i64 = m3_translate(v_en, v_es, W, S, T, text, tlen, out) 83 if m < 0 { return 0 } 84 return m3_streq(out, m, expect, elen) 85} 86 87func m3_demo(fd: i64, v_en: *NxBpeVocab, v_es: *NxBpeVocab, W: *i64, S: i64, T: i64, text: *u8, tlen: i64) -> i64 { 88 let out: *u8 = sys_mmap(64) 89 let m: i64 = m3_translate(v_en, v_es, W, S, T, text, tlen, out) 90 m3_w(fd, " " as *u8); sys_write(fd, text, tlen); m3_w(fd, "->" as *u8) 91 if m > 0 { sys_write(fd, out, m) } 92 return 0 93} 94 95func m3_emit(fd: i64, r: *i64) -> i64 { 96 m3_w(fd, "MTR3GATE authored=organ engine=bpe-tokenizer+scalar-tape-map task=realtext-translate" as *u8) 97 m3_w(fd, " | A_roundtrip_pass=" as *u8); m3_wn(fd, r[0]) 98 m3_w(fd, " | B_subword_pass=" as *u8); m3_wn(fd, r[1]); m3_w(fd, " seat_ntokens=" as *u8); m3_wn(fd, r[2]) 99 m3_w(fd, " | C_translate_pass=" as *u8); m3_wn(fd, r[3]); m3_w(fd, " correct=" as *u8); m3_wn(fd, r[4]); m3_w(fd, "/3" as *u8) 100 m3_w(fd, " | D_untrained_fails_pass=" as *u8); m3_wn(fd, r[5]); m3_w(fd, " untrained_correct=" as *u8); m3_wn(fd, r[6]); m3_w(fd, "/3" as *u8) 101 if r[7] == 1 { m3_w(fd, " verdict=GREEN\n" as *u8) } else { m3_w(fd, " verdict=RED\n" as *u8) } 102 return 0 103} 104 105func main() -> i64 { 106 var ok: i64 = 1 107 108 // ---- EN vocab with real BPE merges ---- 109 let v_en: *NxBpeVocab = nx_bpe_vocab_new(512, 64, 16) 110 let id_g: i64 = nx_bpe_add_token(v_en, C_G, 1) 111 let id_o: i64 = nx_bpe_add_token(v_en, C_O, 1) 112 let id_s: i64 = nx_bpe_add_token(v_en, C_S, 1) 113 let id_e: i64 = nx_bpe_add_token(v_en, C_E, 1) 114 let id_a: i64 = nx_bpe_add_token(v_en, C_A, 1) 115 let id_t: i64 = nx_bpe_add_token(v_en, C_T, 1) 116 let id_ea: i64 = nx_bpe_add_token(v_en, C_EA, 2) 117 let id_sea: i64 = nx_bpe_add_token(v_en, C_SEA, 3) 118 let id_tea: i64 = nx_bpe_add_token(v_en, C_TEA, 3) 119 let id_go: i64 = nx_bpe_add_token(v_en, C_GO, 2) 120 nx_bpe_add_merge(v_en, id_e, id_a, id_ea) // (e,a)->ea 121 nx_bpe_add_merge(v_en, id_s, id_ea, id_sea) // (s,ea)->sea 122 nx_bpe_add_merge(v_en, id_t, id_ea, id_tea) // (t,ea)->tea 123 nx_bpe_add_merge(v_en, id_g, id_o, id_go) // (g,o)->go 124 125 // ---- ES vocab (decode side) ---- 126 let v_es: *NxBpeVocab = nx_bpe_vocab_new(256, 16, 4) 127 let id_mar: i64 = nx_bpe_add_token(v_es, C_MAR, 3) 128 let id_te: i64 = nx_bpe_add_token(v_es, C_TE, 2) 129 let id_ir: i64 = nx_bpe_add_token(v_es, C_IR, 2) 130 131 let S: i64 = id_go + 1 // max EN id + 1 132 let T: i64 = id_ir + 1 // max ES id + 1 133 134 // ---- learned map: sea->mar, go->ir, tea->te ---- 135 let srcs: *i64 = (sys_mmap(3 * 8)) as *i64 136 let tgts: *i64 = (sys_mmap(3 * 8)) as *i64 137 srcs[0] = id_sea; tgts[0] = id_mar 138 srcs[1] = id_go; tgts[1] = id_ir 139 srcs[2] = id_tea; tgts[2] = id_te 140 let W: *i64 = (sys_mmap(T * S * 8)) as *i64 141 let lf: *i64 = (sys_mmap(8)) as *i64 142 let ll: *i64 = (sys_mmap(8)) as *i64 143 mt_train(W, S, T, srcs, tgts, 3, 1, 300, ag_constf(1, 4), lf, ll) 144 145 // ---------- Gate A: BPE round-trip ---------- 146 let tok: *i64 = (sys_mmap(64 * 8)) as *i64 147 let buf: *u8 = sys_mmap(64) 148 var roundtrip_pass: i64 = 1 149 var ne: i64 = nx_bpe_encode(v_en, C_SEA, 3, tok) 150 var nd: i64 = nx_bpe_decode(v_en, tok, ne, buf) 151 if m3_streq(buf, nd, C_SEA, 3) != 1 { roundtrip_pass = 0 } 152 ne = nx_bpe_encode(v_en, C_TEA, 3, tok); nd = nx_bpe_decode(v_en, tok, ne, buf) 153 if m3_streq(buf, nd, C_TEA, 3) != 1 { roundtrip_pass = 0 } 154 ne = nx_bpe_encode(v_en, C_GO, 2, tok); nd = nx_bpe_decode(v_en, tok, ne, buf) 155 if m3_streq(buf, nd, C_GO, 2) != 1 { roundtrip_pass = 0 } 156 if roundtrip_pass != 1 { ok = 0 } 157 158 // ---------- Gate B: subword decomposition of OOV "seat" ---------- 159 let seat_n: i64 = nx_bpe_encode(v_en, C_SEAT, 4, tok) 160 var subword_pass: i64 = 1 161 if seat_n != 2 { subword_pass = 0 } 162 if subword_pass == 1 { if tok[0] != id_sea { subword_pass = 0 } } 163 if subword_pass == 1 { if tok[1] != id_t { subword_pass = 0 } } 164 nd = nx_bpe_decode(v_en, tok, seat_n, buf) 165 if m3_streq(buf, nd, C_SEAT, 4) != 1 { subword_pass = 0 } 166 if subword_pass != 1 { ok = 0 } 167 168 // ---------- Gate C: end-to-end text translation ---------- 169 var correct: i64 = 0 170 correct = correct + m3_check(v_en, v_es, W, S, T, C_SEA, 3, C_MAR, 3) 171 correct = correct + m3_check(v_en, v_es, W, S, T, C_TEA, 3, C_TE, 2) 172 correct = correct + m3_check(v_en, v_es, W, S, T, C_GO, 2, C_IR, 2) 173 var translate_pass: i64 = 1 174 if correct != 3 { translate_pass = 0 } 175 if translate_pass != 1 { ok = 0 } 176 177 // ---------- Gate D: untrained map fails (liar-kill) ---------- 178 let W0: *i64 = (sys_mmap(T * S * 8)) as *i64 179 let lf0: *i64 = (sys_mmap(8)) as *i64 180 let ll0: *i64 = (sys_mmap(8)) as *i64 181 mt_train(W0, S, T, srcs, tgts, 3, 1, 0, ag_constf(1, 4), lf0, ll0) // 0 epochs 182 var ucorrect: i64 = 0 183 ucorrect = ucorrect + m3_check(v_en, v_es, W0, S, T, C_SEA, 3, C_MAR, 3) 184 ucorrect = ucorrect + m3_check(v_en, v_es, W0, S, T, C_TEA, 3, C_TE, 2) 185 ucorrect = ucorrect + m3_check(v_en, v_es, W0, S, T, C_GO, 2, C_IR, 2) 186 var untrained_fails_pass: i64 = 1 187 if ucorrect >= 3 { untrained_fails_pass = 0 } 188 if untrained_fails_pass != 1 { ok = 0 } 189 190 // ---------- emit ---------- 191 let r: *i64 = (sys_mmap(8 * 8)) as *i64 192 r[0] = roundtrip_pass; r[1] = subword_pass; r[2] = seat_n 193 r[3] = translate_pass; r[4] = correct 194 r[5] = untrained_fails_pass; r[6] = ucorrect; r[7] = ok 195 m3_emit(1, r) 196 m3_w(1, "MT-R3 real-text:" as *u8) 197 m3_demo(1, v_en, v_es, W, S, T, C_SEA, 3) 198 m3_demo(1, v_en, v_es, W, S, T, C_TEA, 3) 199 m3_demo(1, v_en, v_es, W, S, T, C_GO, 2) 200 m3_w(1, "\n" as *u8) 201 let logf: i64 = sys_openat_append(M3_LOG, 420) 202 if logf >= 0 { m3_emit(logf, r); sys_close(logf) } 203 204 if ok == 1 { return 0 } 205 return 1 206}