summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuren Hao <yurenh2@illinois.edu>2026-07-12 04:07:09 -0500
committerYuren Hao <yurenh2@illinois.edu>2026-07-12 04:07:09 -0500
commit155478b7ffdd9015fde13884b1ebff9b92148a20 (patch)
treed0cfb583f2714b6c73d6f623a6cbeab77dcba0c2
parente73679570dc91d60dd69bfc2ef8155676f635f39 (diff)
RESULT 13: bsign neutral at 4k (1.7382 vs 1.7314); 42M gap-chasing closed at noise floor; pivot to Stage-2 pipeline + E-tier
-rw-r--r--docs/campaign/CASCADE_ABLATION_PLAN.md10
-rw-r--r--ep_run/casc_eq_train.py3
2 files changed, 13 insertions, 0 deletions
diff --git a/docs/campaign/CASCADE_ABLATION_PLAN.md b/docs/campaign/CASCADE_ABLATION_PLAN.md
index f3b9f87..61860f6 100644
--- a/docs/campaign/CASCADE_ABLATION_PLAN.md
+++ b/docs/campaign/CASCADE_ABLATION_PLAN.md
@@ -528,3 +528,13 @@ stage1b_f3e3cont (floor 3e-3 from s45000): **1.2883** vs stage1b 1.2808 (floor 1
competitive at full ImageNet by Kerjan-Hoier-Scellier) then centered (2x nudge) if needed;
(b) fb K=3 finite-relaxation bias; (c) Muon x gradient-noise interaction; (d) ~0.02-0.03 of the 0.05
is metric-noise band. Recipe note: random-sign is a one-line trainer change (sign of beta_t per step).
+
+### RESULT 13 (2026-07-12): bsign (random-sign beta) NEUTRAL at 4k — 42M gap-chasing has hit the noise floor. THREAD CLOSED.
+bsign 3-seed: 1.7031/1.7562/1.7552 (mean 1.7382) vs single-sided 1.7314 vs BP+Muon 1.7098. The bias
+reduction is cancelled by injected update-direction variance at this horizon (seed spread now dominates:
+s1 alone beat the BP mean). Ledger of the residual-0.05 epoch gap after three probes: NOT late-beta-SNR
+(f3e3cont), NOT K (K5 probe), NOT first-order sign bias at short horizon (bsign). Remaining mass:
+~0.02-0.03 metric-noise band + small unattributed accumulation. **Decision: stop polishing 42M.**
+Carry `--bsign_rand` and a future centered mode as Stage-2 A/B flags; the gap question re-opens at
+300M/real-corpus where it means something. Effort pivots to: (1) Stage-2 data pipeline (FineWeb-Edu +
+32k tokenizer), (2) E-tier tolerance suite on the idle farm (hardware track / UIUC outreach feed).
diff --git a/ep_run/casc_eq_train.py b/ep_run/casc_eq_train.py
index ad82b5e..91a1cca 100644
--- a/ep_run/casc_eq_train.py
+++ b/ep_run/casc_eq_train.py
@@ -40,6 +40,7 @@ ap.add_argument('--zloss', type=float, default=0.0) # z-loss coefficient on
ap.add_argument('--kretry', type=int, default=0) # >0: on drift-reject, RETRY the batch once with this many fb rounds (diag B: K8 converges the marginal batches) instead of dropping it
ap.add_argument('--bf_late', type=float, default=0.0) # >0: raise beta_floor to this value from step --bf_late_at (late-training SNR fix; dose-response 2026-07-10)
ap.add_argument('--bf_late_at', type=int, default=25000)
+ap.add_argument('--bsign_rand', action='store_true') # random-sign beta per step (KHS 'random scheme'): averages the O(beta) single-sided bias at single-phase cost
ap.add_argument('--bf16', action='store_true') # cast model to bf16 (E-accumulation + tok_sigma stay fp32) — the x0.5 cost lever, GATE before production
ap.add_argument('--dtop_every', type=int, default=1) # 1 = exact (DEFAULT, BP-parity); 2 = fast mode (~20% cheaper, ~4% CE tax at high lr)
ap.add_argument('--gate_every', type=int, default=200) # in-training cos(EP,BP) telemetry; <=0 = fully BP-free (no bp_gate at all)
@@ -280,6 +281,7 @@ def dFdtheta(zs, x, y, beta):
SIG0 = None
+BGEN = torch.Generator().manual_seed(args.seed + 990) # separate RNG: sign flips must not shift the data stream
GOV = {'K': None, 'bscale': 1.0, 'gema': None, 'drift': 0.0, 'gn': 0.0, 'sig': 0.0}
def ep_step(x, y):
"""single-sided EP with a QUALITY-GOVERNED estimator: beta_t = beta0*bscale*sig0^2/sig^2,
@@ -296,6 +298,7 @@ def ep_step(x, y):
fl = args.beta_floor
if args.bf_late > 0.0 and GOV.get('step', 0) >= args.bf_late_at: fl = args.bf_late
if fl > 0.0: beta_t = max(beta_t, fl)
+ if args.bsign_rand and torch.rand((), generator=BGEN).item() < 0.5: beta_t = -beta_t
z0, zs, ins, outs = free_states_graphed(x)
zs_free = [z.clone() for z in zs]
free_ce = F.cross_entropy(readout(zs_free[-1]).reshape(-1, vocab), y.reshape(-1)).item()