BluScriptCP / source /files /in2_gate.py
unparallelled's picture
Upload source/files/in2_gate.py with huggingface_hub
411a8a3 verified
Raw History Blame Contribute Delete
6.02 kB
#!/usr/bin/env python3
"""
in2_gate.py -- the EXACT layout gate for in2_gen.py output. No GPU, no CUDA.
This is the only exact pre-flight check in the IN2 pilot. The step-0 loss check
was demoted to a diagnostic because its two hypotheses sit only ~0.22 nats apart
(no-induction 4.147 vs strong-induction 3.925, against a 3.901 plain baseline),
which cannot validate a layout. These assertions can.
Checks, per arm dir:
1 file size is exactly examples*T*2 bytes (headerless uint16)
2 every token in [0, VOCAB)
3 no answer span intrudes into the last PAD_TAIL offsets of its example
4 planted spans (needle / probe+answer / decoy) never overlap
5 RETRIEVAL IS ACTUALLY POSSIBLE: the tokens at the probe equal the needle's
key, and the tokens at the answer equal the needle's value. If this fails
the task is unsolvable and the whole experiment is void.
6 batch alignment: re-derive x/y exactly as DataLoaderLite::next_batch does
(x=buf[i], y=buf[i+1], stride B*T*dp) and assert every example boundary
lands on a row boundary
7 arm-specific distance invariants (b: all == span, c: all >= d_min)
Cross-arm:
8 arms B and C have BIT-IDENTICAL answer_start histograms -- the discipline
the whole B-vs-C contrast rests on
Usage
python3 in2_gate.py --dirs /tmp/in2b /tmp/in2c --B 2 --dp 2
"""
import argparse, array, json, os, sys
VOCAB = 50304
fails = []
def check(cond, msg):
print((" ok " if cond else " FAIL ") + msg)
if not cond:
fails.append(msg)
def load(d, split="train"):
js = [f for f in os.listdir(d) if f.endswith(".json") and f"_{split}_" in f]
if len(js) != 1:
raise SystemExit(f"{d}: expected exactly one {split} manifest, found {js}")
man = json.load(open(os.path.join(d, js[0])))
toks = array.array("H")
for sp in man.get("shards", [man["bin"]]):
with open(sp, "rb") as f:
toks.fromfile(f, os.path.getsize(sp) // 2)
return man, toks
def gate_one(d, B, dp, split="train"):
man, toks = load(d, split)
T, n_ex, arm, span = man["T"], man["examples"], man["arm"], man["span"]
kl, vl, pad = man["key_len"], man["val_len"], man["pad_tail"]
print(f"\n=== arm {arm} T={T} examples={n_ex} K={man['K']} ===")
tot = sum(os.path.getsize(sp) for sp in man.get("shards", [man["bin"]]))
check(tot == n_ex * T * 2,
f"1 total size across {len(man.get('shards',[1]))} shard(s) == examples*T*2 "
f"({n_ex*T*2} bytes, got {tot})")
lo, hi = min(toks), max(toks)
check(lo >= 0 and hi < VOCAB, f"2 tokens in [0,{VOCAB}) (min {lo}, max {hi})")
bad_pad = bad_ovl = bad_ret = bad_dist = 0
for ei, recs in enumerate(man["records"]):
base = ei * T
spans = []
for r in recs:
a0, a1 = r["answer_start"], r["answer_start"] + vl
if a1 > T - pad:
bad_pad += 1
spans.append((r["needle_start"], r["needle_start"] + span))
spans.append((r["probe_start"], r["probe_start"] + span))
# 5: the probe must reproduce the needle's key, the answer its value
nk = toks[base + r["needle_start"]: base + r["needle_start"] + kl]
nv = toks[base + r["needle_start"] + kl: base + r["needle_start"] + span]
pk = toks[base + r["probe_start"]: base + r["probe_start"] + kl]
av = toks[base + a0: base + a1]
if nk != pk or nv != av:
bad_ret += 1
if arm == "b" and r["distance"] != span:
bad_dist += 1
if arm == "c" and r["distance"] < man["d_min"]:
bad_dist += 1
spans.sort()
for (s0, e0), (s1, _) in zip(spans, spans[1:]):
if s1 < e0:
bad_ovl += 1
check(bad_pad == 0, f"3 no answer within the last {pad} offsets ({bad_pad} bad)")
check(bad_ovl == 0, f"4 planted spans never overlap ({bad_ovl} bad)")
check(bad_ret == 0, f"5 RETRIEVAL POSSIBLE: probe==key and answer==value ({bad_ret} bad)")
check(bad_dist == 0, f"7 arm-{arm} distance invariant ({bad_dist} bad)")
# 6: DataLoaderLite windowing. next_batch reads B*T+1 tokens and sets
# y[i]=buf[i+1]; pos_ advances by B*T*world. Example boundaries must land on
# row boundaries or an example would straddle two rows.
stride = B * T * dp
check(stride % T == 0, f"6a batch stride {stride} is a multiple of T={T}")
check((n_ex * T) % stride == 0,
f"6b total {n_ex*T} tokens is a whole number of batches (stride {stride})")
if len(toks) >= B * T + 1:
x0 = toks[0:B * T]
y0 = toks[1:B * T + 1]
rows_ok = all(x0[r * T] == toks[r * T] for r in range(B))
check(rows_ok, f"6c row r starts at token r*T for all B={B} rows")
check(y0[T - 1] == toks[T], "6d y[T-1] targets the next example's first token "
"(why PAD_TAIL exists)")
return man
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--dirs", nargs="+", required=True)
ap.add_argument("--B", type=int, default=2)
ap.add_argument("--dp", type=int, default=2)
ap.add_argument("--split", default="train", choices=["train", "val"])
args = ap.parse_args()
mans = {}
for d in args.dirs:
m = gate_one(d, args.B, args.dp, args.split)
mans[m["arm"]] = m
if "b" in mans and "c" in mans:
print("\n=== cross-arm ===")
hb, hc = mans["b"]["answer_start_hist"], mans["c"]["answer_start_hist"]
check(hb == hc, "8 arms B and C have BIT-IDENTICAL answer_start histograms "
f"({len(hb)} vs {len(hc)} distinct offsets)")
check(mans["b"]["seed"] == mans["c"]["seed"], "8b same seed")
check(mans["b"]["answer_tokens"] == mans["c"]["answer_tokens"],
"8c same answer-token count")
print(f"\n{'ALL PASS' if not fails else str(len(fails)) + ' FAILURE(S)'}")
return 1 if fails else 0
if __name__ == "__main__":
sys.exit(main())