code wiki / (root) / nx_reader_squad_gate.nx

nx_reader_squad_gate.nx source

↩ module page · 546 lines · 26562 B

1// nx_reader_squad_gate.nx -- RUNG 3 (a/b/c) of the NEURAL PASSAGE READER arc: the reader trains on REAL SQuAD. 2// R3c = ERROR-FEEDBACK SGD (nfa_sgd_ef): R3b's three runs all froze in a Q16 uniform-collapse absorbing state 3// because sub-quantum updates truncate to zero; error-feedback keeps the residuals so no gradient is lost. 4// R3a (2889ff525f) measured the from-scratch wall honestly: the pipeline + STABLE Q16 training work (grad-clip 5// + LR-decay; loss 8401->2286) but at 664 rows the reader MEMORIZES without out-generalizing a question-blind 6// token-prior baseline -- because 131k of 133k params were COLD-START embeddings. 7// R3b (this version) = the measured lever: PRETRAINED SOVEREIGN EMBEDDINGS. The vocab is exact-word (61-bit 8// ehash, same hash as the PPMI/SGNS vocab); the embedding table is INITIALIZED from R1's trained SGNS 9// embeddings (knowledge/index/embed_v1.bin, full-data run) and FROZEN -- trainable params drop 133k -> ~7k 10// (attention block + FFN + span heads only), attacking the memorization directly. Attention alignment 11// (Wq/Wk bilinear) now operates on MEANINGFUL word geometry (question<->context similarity = SGNS cosine). 12// T1 held-out span token-F1: reader > question-blind ablation + 100 permille (liar-kill at pretrained parity) 13// T2 held-out exact-start > 60 permille (chance ~11) 14// T3 pretraining helps: reader F1 > R3a's from-scratch 56 + 50 15// T4 deterministic re-eval 16// Consumes: reader_rows.bin (nx_qabench 'dt'), semppmi_v1.bin (vocab hashes), embed_v1.bin (SGNS Q10). 17// expect_exit: 0 license_tier: ORIGINAL Sovereign: nx_nofloat_autograd + nx_syscalls. 18import "nx_nofloat_autograd.nx" 19import "nx_syscalls.nx" 20 21func rq_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 22func rq_pn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var x: i64=v; if x<0{b[0]=45;sys_write(1,b,1);x=0-x} if x==0{b[0]=48;sys_write(1,b,1);return 0} var d: i64=0; var y: i64=x; while y>0{d=d+1;y=y/10} var i: i64=d-1; y=x; while i>=0{b[i]=(48+(y%10)) as u8;y=y/10;i=i-1} sys_write(1,b,d); return 0 } 23func rq_ck(name: *u8, c: i64) -> i64 { if c==1 { rq_puts(" PASS " as *u8) } else { rq_puts(" FAIL " as *u8) } rq_puts(name); rq_puts("\n" as *u8); return c } 24 25const RQ_E: i64 = 24 // = SGNS embedding dim (embed_v1.bin) 26const RQ_F: i64 = 48 27const RQ_MAXT: i64 = 96 28const RQ_MAXQ: i64 = 20 29const RQ_MAXG: i64 = 8 30const RQ_SCALE: i64 = 13378 // 1/sqrt(24) in Q16 31const RQ_NROWS: i64 = 960 32const RQ_MAXV: i64 = 16384 // exact-word vocab cap (id 0 = SEP; words 1..nw) 33const RQ_MAPN: i64 = 32768 // open-addressing map slots (power of 2) 34// flat weight layout 35const QOFF_EMB: i64 = 0 // [MAXV,E] 393216 (FROZEN; SGNS-initialized) 36const QOFF_WQ: i64 = 393216 // [E,E] 576 37const QOFF_WK: i64 = 393792 38const QOFF_WV: i64 = 394368 39const QOFF_WO: i64 = 394944 40const QOFF_WG: i64 = 395520 // [E,F] 1152 41const QOFF_WU: i64 = 396672 42const QOFF_WD: i64 = 397824 // [F,E] 1152 43const QOFF_US: i64 = 398976 // [1,E] 24 44const QOFF_UE: i64 = 399000 // [1,E] 24 45const RQ_NP: i64 = 399024 46 47// ---- word hashing: EXACTLY the PPMI/SGNS vocab hash (dual djb2, 61-bit) ---- 48func rq_ehash(buf: *u8, off: i64, len: i64) -> i64 { 49 var h1: i64 = 5381 50 var h2: i64 = 77245 51 var i: i64 = 0 52 while i < len { let c: i64 = buf[off+i] as i64; h1 = (h1*33 + c) % 1073741789; h2 = (h2*131 + c) % 1073741783; i = i + 1 } 53 return h1 * 1073741783 + h2 54} 55func rq_bsearch(a: *i64, n: i64, v: i64) -> i64 { 56 var lo: i64 = 0 57 var hi: i64 = n - 1 58 while lo <= hi { let mid: i64 = (lo+hi)/2; if a[mid] == v { return mid } if a[mid] < v { lo = mid+1 } else { hi = mid-1 } } 59 return 0-1 60} 61func rq_lc(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c } 62func rq_isal(c: i64) -> i64 { if c >= 97 { if c <= 122 { return 1 } } if c >= 48 { if c <= 57 { return 1 } } return 0 } 63 64// tokenize buf[0..n) into WORD HASHES (lowercased alnum runs, ehash'd); returns count 65func rq_tok(buf: *u8, n: i64, hout: *i64, cap: i64) -> i64 { 66 let wb: *u8 = sys_mmap(64) 67 var nt: i64 = 0 68 var i: i64 = 0 69 while i < n { 70 let c: i64 = rq_lc(buf[i] as i64) 71 if rq_isal(c) == 1 { 72 var wl: i64 = 0 73 var j: i64 = i 74 var live: i64 = 1 75 while live == 1 { 76 if j >= n { live = 0 } else { 77 let cj: i64 = rq_lc(buf[j] as i64) 78 if rq_isal(cj) == 0 { live = 0 } else { if wl < 48 { wb[wl] = cj as u8; wl = wl + 1 } j = j + 1 } 79 } 80 } 81 if nt < cap { hout[nt] = rq_ehash(wb, 0, wl); nt = nt + 1 } 82 i = j 83 } else { i = i + 1 } 84 } 85 return nt 86} 87 88// vocab: open-addressing hash->local-id map. vst[0]=nw. returns local id (1..nw); 0 reserved for SEP. 89func rq_vid(map: *i64, vhash: *i64, vst: *i64, h: i64) -> i64 { 90 var slot: i64 = h & (RQ_MAPN - 1) 91 if slot < 0 { slot = 0 - slot } 92 var probe: i64 = 0 93 while probe < RQ_MAPN { 94 let e: i64 = map[slot] 95 if e == 0 { 96 // absent -> assign 97 if vst[0] >= RQ_MAXV - 1 { return 1 } // vocab full -> bucket everything into id 1 (rare) 98 vst[0] = vst[0] + 1 99 let id: i64 = vst[0] 100 vhash[id] = h 101 map[slot] = id 102 return id 103 } 104 if vhash[e] == h { return e } 105 slot = (slot + 1) & (RQ_MAPN - 1) 106 probe = probe + 1 107 } 108 return 1 109} 110 111// ---- model forward (R2 architecture; embeddings pre-GATHERED into Xg[T*E]). out[0]=root loss, 112// out[1]=start logits, out[2]=end logits, out[3]=Xg leaf, out[4..12]=other leaves. returns 0. ---- 113func rq_fwd(tape: *i64, vals: *i64, st: *i64, W: *i64, Xg: *i64, tgts: *i64, tgte: *i64, T: i64, useattn: i64, out: *i64) -> i64 { 114 st[0] = 0 115 st[1] = 0 116 let nXg: i64 = nfa_leaf(tape, vals, st, T, RQ_E, Xg, 0) 117 let nWq: i64 = nfa_leaf(tape, vals, st, RQ_E, RQ_E, W, QOFF_WQ) 118 let nWk: i64 = nfa_leaf(tape, vals, st, RQ_E, RQ_E, W, QOFF_WK) 119 let nWv: i64 = nfa_leaf(tape, vals, st, RQ_E, RQ_E, W, QOFF_WV) 120 let nWo: i64 = nfa_leaf(tape, vals, st, RQ_E, RQ_E, W, QOFF_WO) 121 let nWg: i64 = nfa_leaf(tape, vals, st, RQ_E, RQ_F, W, QOFF_WG) 122 let nWu: i64 = nfa_leaf(tape, vals, st, RQ_E, RQ_F, W, QOFF_WU) 123 let nWd: i64 = nfa_leaf(tape, vals, st, RQ_F, RQ_E, W, QOFF_WD) 124 let nUs: i64 = nfa_leaf(tape, vals, st, 1, RQ_E, W, QOFF_US) 125 let nUe: i64 = nfa_leaf(tape, vals, st, 1, RQ_E, W, QOFF_UE) 126 var nH: i64 = nXg 127 if useattn == 1 { 128 let nXn: i64 = nfa_rmsnorm_rows(tape, vals, st, nXg) 129 let nQ: i64 = nfa_matmul(tape, vals, st, nXn, nWq) 130 let nK: i64 = nfa_matmul(tape, vals, st, nXn, nWk) 131 let nV: i64 = nfa_matmul(tape, vals, st, nXn, nWv) 132 let nQr: i64 = nfa_rope(tape, vals, st, nQ) 133 let nKr: i64 = nfa_rope(tape, vals, st, nK) 134 let nS: i64 = nfa_matmul_nt(tape, vals, st, nQr, nKr) 135 let nSs: i64 = nfa_cmul(tape, vals, st, nS, RQ_SCALE) 136 let nA: i64 = nfa_softmax_rows(tape, vals, st, nSs, 1) 137 let nO: i64 = nfa_matmul(tape, vals, st, nA, nV) 138 let nOp: i64 = nfa_matmul(tape, vals, st, nO, nWo) 139 let nOs: i64 = nfa_cmul(tape, vals, st, nOp, 16384) // R3d(b): 0.25x branch scale -- the residual 140 nH = nfa_vadd(tape, vals, st, nXg, nOs) // must DOMINATE so per-token states can't collapse 141 } 142 let nHn: i64 = nfa_rmsnorm_rows(tape, vals, st, nH) 143 let nG: i64 = nfa_matmul(tape, vals, st, nHn, nWg) 144 let nU2: i64 = nfa_matmul(tape, vals, st, nHn, nWu) 145 let nSg: i64 = nfa_silu(tape, vals, st, nG) 146 let nHs: i64 = nfa_hadamard(tape, vals, st, nSg, nU2) 147 let nD: i64 = nfa_matmul(tape, vals, st, nHs, nWd) 148 let nDs: i64 = nfa_cmul(tape, vals, st, nD, 16384) // R3d(b): 0.25x FFN branch -- the diagnosed 149 let nY: i64 = nfa_vadd(tape, vals, st, nH, nDs) // spike source (FFN swamped the residual) 150 let nYn: i64 = nfa_rmsnorm_rows(tape, vals, st, nY) 151 let nLs: i64 = nfa_matmul_nt(tape, vals, st, nUs, nYn) 152 let nLe: i64 = nfa_matmul_nt(tape, vals, st, nUe, nYn) 153 let nCs: i64 = nfa_softce_rows(tape, vals, st, nLs, tgts) 154 let nCe: i64 = nfa_softce_rows(tape, vals, st, nLe, tgte) 155 let nRoot: i64 = nfa_vadd(tape, vals, st, nCs, nCe) 156 out[0] = nRoot 157 out[1] = nLs 158 out[2] = nLe 159 out[3] = nXg 160 out[4] = nWq 161 out[5] = nWk 162 out[6] = nWv 163 out[7] = nWo 164 out[8] = nWg 165 out[9] = nWu 166 out[10] = nWd 167 out[11] = nUs 168 out[12] = nUe 169 return 0 170} 171 172// accumulate grads; embeddings TRAINABLE (SGNS is the INIT, not a freeze -- v1 froze them and the block 173// collapsed into the uniform fixed point: loss 8170 -> exactly 2*ln(86)=8867 stuck, identical states => span 174// grads cancel by symmetry => zero gradient forever). Emb rows scattered back by token id, R3a-style. 175func rq_grab_emb(tape: *i64, grads: *i64, out: *i64, G: *i64, ids: *i64, T: i64) -> i64 { 176 let nXg: i64 = out[3] 177 let gx: i64 = tape[7*nXg+6] 178 var t: i64 = 0 179 while t < T { 180 let id: i64 = ids[t] 181 var e: i64 = 0 182 while e < RQ_E { G[QOFF_EMB + id*RQ_E + e] = G[QOFF_EMB + id*RQ_E + e] + grads[gx + t*RQ_E + e]; e = e + 1 } 183 t = t + 1 184 } 185 return 0 186} 187func rq_grab(tape: *i64, grads: *i64, out: *i64, G: *i64) -> i64 { 188 var k: i64 = 0 189 while k < 9 { 190 var sz: i64 = 576 191 var of: i64 = 0 192 if k == 0 { of = QOFF_WQ } 193 if k == 1 { of = QOFF_WK } 194 if k == 2 { of = QOFF_WV } 195 if k == 3 { of = QOFF_WO } 196 if k == 4 { sz = 1152; of = QOFF_WG } 197 if k == 5 { sz = 1152; of = QOFF_WU } 198 if k == 6 { sz = 1152; of = QOFF_WD } 199 if k == 7 { sz = 24; of = QOFF_US } 200 if k == 8 { sz = 24; of = QOFF_UE } 201 let nid: i64 = out[4+k] 202 let goff: i64 = tape[7*nid+6] 203 var i: i64 = 0 204 while i < sz { G[of+i] = G[of+i] + grads[goff+i]; i = i + 1 } 205 k = k + 1 206 } 207 return 0 208} 209 210// non-embedding weight init (embeddings come from SGNS) 211func rq_init(W: *i64) -> i64 { 212 var i: i64 = 0 213 while i < 576 { W[QOFF_WQ+i] = (((i*13)%9)-4)*(NFA_Q16/32); W[QOFF_WK+i] = (((i*17)%9)-4)*(NFA_Q16/32); W[QOFF_WV+i] = (((i*19)%9)-4)*(NFA_Q16/32); W[QOFF_WO+i] = (((i*23)%9)-4)*(NFA_Q16/32); i = i + 1 } 214 i = 0 215 while i < 1152 { W[QOFF_WG+i] = (((i*29)%9)-4)*(NFA_Q16/40); W[QOFF_WU+i] = (((i*31)%9)-4)*(NFA_Q16/40); W[QOFF_WD+i] = (((i*37)%9)-4)*(NFA_Q16/40); i = i + 1 } 216 i = 0 217 while i < 24 { W[QOFF_US+i] = (((i*5+1)%7)-3)*(NFA_Q16/8); W[QOFF_UE+i] = (((i*11+2)%7)-3)*(NFA_Q16/8); i = i + 1 } 218 return 0 219} 220 221func rq_span_f1(ids: *i64, a: i64, b: i64, gs: i64, ge: i64) -> i64 { 222 let pl: i64 = b - a + 1 223 let gl: i64 = ge - gs + 1 224 if pl <= 0 { return 0 } 225 if gl <= 0 { return 0 } 226 var common: i64 = 0 227 let used: *i64 = sys_mmap(RQ_MAXG*8) as *i64 228 var u: i64 = 0 229 while u < gl { used[u] = 0; u = u + 1 } 230 var p: i64 = a 231 while p <= b { 232 var q2: i64 = 0 233 var got: i64 = 0 234 while q2 < gl { 235 if got == 0 { if used[q2] == 0 { if ids[gs+q2] == ids[p] { used[q2] = 1; common = common + 1; got = 1 } } } 236 q2 = q2 + 1 237 } 238 p = p + 1 239 } 240 if common == 0 { return 0 } 241 return (2*common*1000)/(pl+gl) 242} 243 244func rq_eval(tape: *i64, vals: *i64, st: *i64, W: *i64, dat: *i64, meta: *i64, r0: i64, r1: i64, useattn: i64, res: *i64) -> i64 { 245 let out: *i64 = sys_mmap(16*8) as *i64 246 let Xg: *i64 = sys_mmap(RQ_MAXT*RQ_E*8) as *i64 247 let tgts: *i64 = sys_mmap(8) as *i64 248 let tgte: *i64 = sys_mmap(8) as *i64 249 var f1sum: i64 = 0 250 var exact: i64 = 0 251 var n: i64 = 0 252 var r: i64 = r0 253 while r < r1 { 254 let T: i64 = meta[r*4+0] 255 let qn: i64 = meta[r*4+1] 256 let gs: i64 = meta[r*4+2] 257 let ge: i64 = meta[r*4+3] 258 let ids: *i64 = (dat as i64 + r*RQ_MAXT*8) as *i64 259 var t: i64 = 0 260 while t < T { var e: i64 = 0; while e < RQ_E { Xg[t*RQ_E+e] = W[QOFF_EMB + ids[t]*RQ_E + e]; e = e + 1 } t = t + 1 } 261 tgts[0] = gs 262 tgte[0] = ge 263 rq_fwd(tape, vals, st, W, Xg, tgts, tgte, T, useattn, out) 264 let nLs: i64 = out[1] 265 let nLe: i64 = out[2] 266 var s: i64 = qn + 1 267 var bv: i64 = nfa_val(tape, vals, nLs, qn+1) 268 var j: i64 = qn + 2 269 while j < T { let v: i64 = nfa_val(tape, vals, nLs, j); if v > bv { bv = v; s = j } j = j + 1 } 270 var en: i64 = s 271 var ev: i64 = nfa_val(tape, vals, nLe, s) 272 var lim: i64 = s + RQ_MAXG 273 if lim > T { lim = T } 274 j = s + 1 275 while j < lim { let v2: i64 = nfa_val(tape, vals, nLe, j); if v2 > ev { ev = v2; en = j } j = j + 1 } 276 f1sum = f1sum + rq_span_f1(ids, s, en, gs, ge) 277 if s == gs { exact = exact + 1 } 278 n = n + 1 279 r = r + 1 280 } 281 if n == 0 { res[0] = 0; res[1] = 0; return 0 } 282 res[0] = f1sum / n 283 res[1] = exact * 1000 / n 284 return 0 285} 286 287func rq_train(tape: *i64, vals: *i64, grads: *i64, st: *i64, W: *i64, dat: *i64, meta: *i64, ntrain: i64, useattn: i64, EP: i64, lr: i64, verbose: i64) -> i64 { 288 let out: *i64 = sys_mmap(16*8) as *i64 289 let Xg: *i64 = sys_mmap(RQ_MAXT*RQ_E*8) as *i64 290 let tgts: *i64 = sys_mmap(8) as *i64 291 let tgte: *i64 = sys_mmap(8) as *i64 292 let G: *i64 = sys_mmap(RQ_NP*8) as *i64 293 let EF: *i64 = sys_mmap(RQ_NP*8) as *i64 // error-feedback residuals (R3c: no grad lost to >>16) 294 var zf: i64 = 0 295 while zf < RQ_NP { EF[zf] = 0; zf = zf + 1 } 296 var ep: i64 = 0 297 while ep < EP { 298 var lsum: i64 = 0 299 var nb: i64 = 0 300 var r: i64 = 0 301 while r + 8 <= ntrain { 302 var z: i64 = 0 303 while z < RQ_NP { G[z] = 0; z = z + 1 } 304 var mb: i64 = 0 305 while mb < 8 { 306 let rr: i64 = r + mb 307 let T: i64 = meta[rr*4+0] 308 let gs: i64 = meta[rr*4+2] 309 let ge: i64 = meta[rr*4+3] 310 let ids: *i64 = (dat as i64 + rr*RQ_MAXT*8) as *i64 311 var t: i64 = 0 312 while t < T { var e: i64 = 0; while e < RQ_E { Xg[t*RQ_E+e] = W[QOFF_EMB + ids[t]*RQ_E + e]; e = e + 1 } t = t + 1 } 313 tgts[0] = gs 314 tgte[0] = ge 315 rq_fwd(tape, vals, st, W, Xg, tgts, tgte, T, useattn, out) 316 let nRoot: i64 = out[0] 317 lsum = lsum + nfa_val(tape, vals, nRoot, 0) 318 nfa_backward(tape, vals, grads, st[0], nRoot) 319 rq_grab(tape, grads, out, G) 320 rq_grab_emb(tape, grads, out, G, ids, T) 321 mb = mb + 1 322 } 323 // FULL-param batch-mean + GRAD-CLIP +-4.0 + LR DECAY @8/16 -- EXACTLY the R3a-proven stable recipe 324 var w: i64 = 0 325 while w < RQ_NP { 326 var gv: i64 = G[w] / 8 327 if gv > 262144 { gv = 262144 } 328 if gv < 0-262144 { gv = 0-262144 } 329 G[w] = gv 330 w = w + 1 331 } 332 var elr: i64 = lr 333 if ep >= 8 { elr = lr/2 } 334 if ep >= 16 { elr = lr/4 } 335 nfa_sgd_ef(W, G, EF, RQ_NP, elr) // R3c: error-feedback (sub-quantum residuals kept) 336 nb = nb + 1 337 r = r + 8 338 } 339 if verbose == 1 { rq_puts(" epoch "); rq_pn(ep); rq_puts(" mean_loss_milli="); rq_pn((lsum/(nb*8))*1000/NFA_Q16); rq_puts("\n" as *u8) } 340 ep = ep + 1 341 } 342 return 0 343} 344 345func main() -> i64 { 346 rq_puts("nx_reader_squad_gate (RUNG 3b: SGNS-PRETRAINED frozen embeddings + trainable attention reader on REAL SQuAD)\n" as *u8) 347 var pass: i64 = 0 348 var total: i64 = 0 349 350 // ---- load reader_rows.bin ---- 351 let fd: i64 = sys_openat_rd("knowledge/index/reader_rows.bin" as *u8) 352 if fd < 0 { rq_puts("RED -- reader_rows.bin missing (run: nx_qabench dt)\n" as *u8); return 1 } 353 let cap: i64 = 16777216 354 let raw: *u8 = sys_mmap(cap) 355 var got: i64 = 0 356 var rr2: i64 = 1 357 while rr2 > 0 { rr2 = sys_read(fd, (raw as i64 + got) as *u8, cap - got); if rr2 > 0 { got = got + rr2 } } 358 sys_close(fd) 359 if got < 16 { rq_puts("RED -- reader_rows.bin empty\n" as *u8); return 1 } 360 361 // ---- load SGNS vocab hashes (semppmi vh) + trained embeddings (embed_v1 Q10) ---- 362 let pfd: i64 = sys_openat_rd("knowledge/index/semppmi_v1.bin" as *u8) 363 if pfd < 0 { rq_puts("RED -- semppmi_v1.bin missing\n" as *u8); return 1 } 364 let pcap: i64 = 2097152 365 let pblob: *u8 = sys_mmap(pcap) 366 var pgot: i64 = 0 367 var pr: i64 = 1 368 while pr > 0 { if pgot >= pcap { pr = 0 } else { pr = sys_read(pfd, (pblob as i64 + pgot) as *u8, pcap - pgot); if pr > 0 { pgot = pgot + pr } } } 369 sys_close(pfd) 370 let phi: *i64 = (pblob as i64 + 8) as *i64 371 let nv: i64 = phi[0] 372 if pgot < 32 + nv*8 { rq_puts("RED -- semppmi vh truncated\n" as *u8); return 1 } 373 let vh: *i64 = (pblob as i64 + 32) as *i64 374 let efd: i64 = sys_openat_rd("knowledge/index/embed_v1.bin" as *u8) 375 if efd < 0 { rq_puts("RED -- embed_v1.bin missing (run: nx_embed_train)\n" as *u8); return 1 } 376 let ecap: i64 = 67108864 377 let eblob: *u8 = sys_mmap(ecap) 378 var egot: i64 = 0 379 var er: i64 = 1 380 while er > 0 { if egot >= ecap { er = 0 } else { er = sys_read(efd, (eblob as i64 + egot) as *u8, ecap - egot); if er > 0 { egot = egot + er } } } 381 sys_close(efd) 382 let ehi: *i64 = (eblob as i64 + 8) as *i64 383 let env: i64 = ehi[0] 384 let edim: i64 = ehi[1] 385 if edim != RQ_E { rq_puts("RED -- embed dim mismatch\n" as *u8); return 1 } 386 if env != nv { rq_puts("RED -- embed/vocab nv mismatch\n" as *u8); return 1 } 387 let EQ: *i64 = (eblob as i64 + 24) as *i64 // Q10 rows [nv x 24] 388 rq_puts(" SGNS loaded: vocab nv="); rq_pn(nv); rq_puts(" dim="); rq_pn(edim); rq_puts("\n" as *u8) 389 390 // ---- parse rows -> exact-word vocab + tokenized dataset with gold spans ---- 391 let dat: *i64 = sys_mmap(RQ_NROWS*RQ_MAXT*8) as *i64 392 let meta: *i64 = sys_mmap(RQ_NROWS*4*8) as *i64 393 let qh: *i64 = sys_mmap(64*8) as *i64 394 let ch: *i64 = sys_mmap(4096*8) as *i64 395 let gh: *i64 = sys_mmap(64*8) as *i64 396 let vhash: *i64 = sys_mmap(RQ_MAXV*8) as *i64 397 let vmap: *i64 = sys_mmap(RQ_MAPN*8) as *i64 398 let vst: *i64 = sys_mmap(8) as *i64 399 vst[0] = 0 400 var nrows: i64 = 0 401 var tsum: i64 = 0 402 var off: i64 = 8 403 var scanned: i64 = 0 404 while off + 24 < got { 405 if nrows >= RQ_NROWS { off = got } else { 406 let hp: *i64 = (raw as i64 + off) as *i64 407 let qlen: i64 = hp[0] 408 if qlen < 0 { off = got } else { if qlen > 4000 { off = got } else { 409 let qp: *u8 = (raw as i64 + off + 8) as *u8 410 let hp2: *i64 = (raw as i64 + off + 8 + qlen) as *i64 411 let clen: i64 = hp2[0] 412 let cp: *u8 = (raw as i64 + off + 16 + qlen) as *u8 413 let hp3: *i64 = (raw as i64 + off + 16 + qlen + clen) as *i64 414 let alen: i64 = hp3[0] 415 let ap: *u8 = (raw as i64 + off + 24 + qlen + clen) as *u8 416 off = off + 24 + qlen + clen + alen 417 scanned = scanned + 1 418 var qn: i64 = rq_tok(qp, qlen, qh, RQ_MAXQ) 419 let cn0: i64 = rq_tok(cp, clen, ch, 4096) 420 let gn: i64 = rq_tok(ap, alen, gh, RQ_MAXG) 421 var cn: i64 = RQ_MAXT - qn - 1 422 if cn > cn0 { cn = cn0 } 423 if qn >= 3 { if gn >= 1 { if cn >= 8 { 424 var gs: i64 = 0-1 425 var c: i64 = 0 426 while c + gn <= cn { 427 if gs < 0 { 428 var m: i64 = 1 429 var k: i64 = 0 430 while k < gn { if ch[c+k] != gh[k] { m = 0; k = gn } else { k = k + 1 } } 431 if m == 1 { gs = c } 432 } 433 c = c + 1 434 } 435 if gs >= 0 { 436 let T: i64 = qn + 1 + cn 437 let ids: *i64 = (dat as i64 + nrows*RQ_MAXT*8) as *i64 438 var t: i64 = 0 439 while t < qn { let lid: i64 = rq_vid(vmap, vhash, vst, qh[t]); ids[t] = lid; t = t + 1 } 440 ids[qn] = 0 // SEP = local id 0 441 t = 0 442 while t < cn { let lid2: i64 = rq_vid(vmap, vhash, vst, ch[t]); ids[qn+1+t] = lid2; t = t + 1 } 443 meta[nrows*4+0] = T 444 meta[nrows*4+1] = qn 445 meta[nrows*4+2] = qn + 1 + gs 446 meta[nrows*4+3] = qn + 1 + gs + gn - 1 447 tsum = tsum + T 448 nrows = nrows + 1 449 } 450 } } } 451 } } 452 } 453 } 454 let nw: i64 = vst[0] 455 rq_puts(" scanned="); rq_pn(scanned); rq_puts(" usable="); rq_pn(nrows); rq_puts(" avg T="); rq_pn(tsum/(nrows+1)); rq_puts(" vocab nw="); rq_pn(nw); rq_puts("\n" as *u8) 456 if nrows < 200 { rq_puts("RED -- too few usable rows\n" as *u8); return 1 } 457 var ntrain: i64 = (nrows * 4) / 5 458 let nheld: i64 = nrows - ntrain 459 rq_puts(" train="); rq_pn(ntrain); rq_puts(" held-out="); rq_pn(nheld); rq_puts("\n" as *u8) 460 461 // ---- embedding table: SGNS-initialized (Q10<<6 = Q16), FROZEN; OOV + SEP = deterministic small init ---- 462 let W: *i64 = sys_mmap(RQ_NP*8) as *i64 463 var hits: i64 = 0 464 var wv: i64 = 1 465 while wv <= nw { 466 let r3: i64 = rq_bsearch(vh, nv, vhash[wv]) 467 if r3 >= 0 { 468 // SGNS DIRECTION, R3a-proven AMPLITUDE: raw trained rows are ~10-15x larger than the stable init 469 // scale and drove the Q16 SGD into the uniform absorbing state (v2 collapse); rescale each row to 470 // RMS=0.125 Q16 (8192), preserving the semantic geometry. (Standard pretrained-init rescaling.) 471 var ss: i64 = 0 472 var e2: i64 = 0 473 while e2 < RQ_E { let q6: i64 = EQ[r3*RQ_E + e2] << 6; ss = ss + nfa_qmul(q6, q6); e2 = e2 + 1 } 474 var rms: i64 = nfa_isqrt(((ss / RQ_E) + 1) << 16) 475 if rms < 64 { rms = 64 } 476 e2 = 0 477 while e2 < RQ_E { let q6b: i64 = EQ[r3*RQ_E + e2] << 6; W[QOFF_EMB + wv*RQ_E + e2] = (q6b * 8192) / rms; e2 = e2 + 1 } 478 hits = hits + 1 479 } else { 480 var e3: i64 = 0 481 while e3 < RQ_E { W[QOFF_EMB + wv*RQ_E + e3] = (((wv*7+e3*3)%11)-5)*(NFA_Q16/32); e3 = e3 + 1 } 482 } 483 wv = wv + 1 484 } 485 var e4: i64 = 0 486 while e4 < RQ_E { W[QOFF_EMB + e4] = (((e4*5+2)%9)-4)*(NFA_Q16/12); e4 = e4 + 1 } 487 rq_puts(" SGNS coverage: "); rq_pn(hits); rq_puts("/"); rq_pn(nw); rq_puts(" vocab words pretrained ("); rq_pn(hits*1000/(nw+1)); rq_puts(" permille)\n" as *u8) 488 rq_init(W) 489 490 let tape: *i64 = sys_mmap(4096*7*8) as *i64 491 let vals: *i64 = sys_mmap(262144*8) as *i64 492 let grads: *i64 = sys_mmap(262144*8) as *i64 493 let st: *i64 = sys_mmap(2*8) as *i64 494 let EP: i64 = 24 495 let lr: i64 = 2048 // back to the proven rate: R3d(b) residual-scale (0.25x branches) closes the 496 // basin entrance structurally, so the lr band that trained R3a applies again. 497 498 rq_puts(" training READER (SGNS-INITIALIZED trainable embeddings; R3a-proven recipe)...\n" as *u8) 499 rq_train(tape, vals, grads, st, W, dat, meta, ntrain, 1, EP, lr, 1) 500 let resA: *i64 = sys_mmap(2*8) as *i64 501 rq_eval(tape, vals, st, W, dat, meta, ntrain, nrows, 1, resA) 502 rq_puts(" READER held-out: span-F1="); rq_pn(resA[0]); rq_puts(" permille exact-start="); rq_pn(resA[1]); rq_puts(" permille (chance ~11; R3a from-scratch was F1=56)\n" as *u8) 503 504 rq_puts(" training ABLATION (question-blind, same frozen embeddings/budget)...\n" as *u8) 505 let W2: *i64 = sys_mmap(RQ_NP*8) as *i64 506 var cw: i64 = 0 507 while cw < RQ_NP { W2[cw] = W[cw]; cw = cw + 1 } // same SGNS embeddings 508 rq_init(W2) // fresh non-emb weights (same init as reader) 509 rq_train(tape, vals, grads, st, W2, dat, meta, ntrain, 0, EP, lr, 0) 510 let resB: *i64 = sys_mmap(2*8) as *i64 511 rq_eval(tape, vals, st, W2, dat, meta, ntrain, nrows, 0, resB) 512 rq_puts(" ABLATION held-out: span-F1="); rq_pn(resB[0]); rq_puts(" permille exact-start="); rq_pn(resB[1]); rq_puts(" permille\n" as *u8) 513 514 total = total + 1 515 if resA[0] > resB[0] + 100 { pass = pass + 1; rq_ck("T1 reader beats question-blind ablation by >100 F1 (liar-kill)" as *u8, 1) } else { rq_ck("T1 reader beats question-blind ablation by >100 F1 (liar-kill)" as *u8, 0) } 516 total = total + 1 517 if resA[1] > 60 { pass = pass + 1; rq_ck("T2 reader exact-start > 60 permille (>5x chance)" as *u8, 1) } else { rq_ck("T2 reader exact-start > 60 permille (>5x chance)" as *u8, 0) } 518 total = total + 1 519 if resA[0] > 106 { pass = pass + 1; rq_ck("T3 pretraining helps: F1 > from-scratch 56 + 50" as *u8, 1) } else { rq_ck("T3 pretraining helps: F1 > from-scratch 56 + 50" as *u8, 0) } 520 521 let resC: *i64 = sys_mmap(2*8) as *i64 522 rq_eval(tape, vals, st, W, dat, meta, ntrain, nrows, 1, resC) 523 total = total + 1 524 var t4: i64 = 0 525 if resC[0] == resA[0] { if resC[1] == resA[1] { t4 = 1 } } 526 if t4 == 1 { pass = pass + 1; rq_ck("T4 deterministic re-eval" as *u8, 1) } else { rq_ck("T4 deterministic re-eval" as *u8, 0) } 527 528 let pf: i64 = sys_openat_wr("knowledge/index/reader_neural.bin" as *u8, 0x1a4) 529 if pf >= 0 { 530 let mg: *i64 = sys_mmap(32) as *i64 531 let mgb: *u8 = mg as *u8 532 mgb[0]=78 as u8; mgb[1]=88 as u8; mgb[2]=78 as u8; mgb[3]=82 as u8; mgb[4]=50 as u8; mgb[5]=0 as u8; mgb[6]=0 as u8; mgb[7]=0 as u8 533 mg[1] = nw 534 mg[2] = RQ_E 535 mg[3] = RQ_F 536 sys_write(pf, mg as *u8, 32) 537 sys_write(pf, W as *u8, RQ_NP*8) 538 sys_close(pf) 539 rq_puts(" persisted trained reader -> knowledge/index/reader_neural.bin (NXNR2)\n" as *u8) 540 } 541 542 rq_puts("---- nx_reader_squad_gate: passed "); rq_pn(pass); rq_puts(" / "); rq_pn(total); rq_puts("\n" as *u8) 543 if pass == total { rq_puts("READER RUNG3b GREEN -- SGNS-pretrained sovereign embeddings + trained attention = a GENERALIZING reader on real SQuAD; the question-blind reader cannot.\n" as *u8); return 0 } 544 rq_puts("RED -- rung 3b not fully passed (see numbers)\n" as *u8) 545 return 1 546}