diff options
| author | Yuren Hao <yurenh2@illinois.edu> | 2026-07-11 07:19:40 -0500 |
|---|---|---|
| committer | Yuren Hao <yurenh2@illinois.edu> | 2026-07-11 07:19:40 -0500 |
| commit | 4d0840cbe7ff16f384c02a42aef2f65f4a3ca24c (patch) | |
| tree | e693ff48025e9140788b24d404d8c6ee37378ba6 | |
| parent | c1a44c3e9181c98d6d3bf8207dbc73a026a077fa (diff) | |
RESULT 11: stage1b sealed (gap 0.050); beta ceiling unfound (3e-3 -> cos 0.9974); K exonerated on OLMo2; bf16 naive-cast dead at any beta (TF32 stays cost baseline); f3e3 CE-endpoint cont launched
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FAPDWQ49M5Ye3NpTndTpn
| -rw-r--r-- | docs/campaign/CASCADE_ABLATION_PLAN.md | 18 | ||||
| -rw-r--r-- | ep_run/casc_eq_train.py | 12 |
2 files changed, 28 insertions, 2 deletions
diff --git a/docs/campaign/CASCADE_ABLATION_PLAN.md b/docs/campaign/CASCADE_ABLATION_PLAN.md index 0560a07..8483820 100644 --- a/docs/campaign/CASCADE_ABLATION_PLAN.md +++ b/docs/campaign/CASCADE_ABLATION_PLAN.md @@ -492,3 +492,21 @@ double-sided ±β (kills O(β) Taylor bias, unlocks ~10× β for SNR, 2× nudge 2k-step probe when implemented) → fp64 E-accumulation / readout averaging. Analog note: this constraint IS the hardware constraint (ε = device noise); β-scheduling learned here = chip ops manual; hardware bonus = nudge amplitude free under multiplicative noise (r-indifference). + +### RESULT 11 (2026-07-11): stage1b SEALED (gap 0.22->0.050); beta ceiling not reached; K exonerated on OLMo2; bf16 naive-cast dead. +- **stage1b endpoints: EP+Muon+floor-ramp 1.2808 | BP+Muon 1.2311 -> epoch gap 0.050** (fixed-floor was + +0.22). EP now beats the old BP-AdamW epoch (1.2509/1.2750). Intervention-timing quad complete: + fixed-floor 1.4802 / lift@40k 1.4479 / full ramp 1.2808 -- monotone earlier-is-better dose curve. +- **Gap probes @s45000 (2k-step sustained traces):** control cos 0.9947 | b2e3 0.9968 | **b3e3 0.9974 + (deficit halved, zero drift/skips)** | K5 0.9951 ~= control -> **K-invariance now proven on BOTH + architectures; the residual deficit is beta-liftable, not relaxation-depth.** sigma(W_out)=80 by 45k: + without the floor beta_t would be ~1e-6 -- the floor carries the entire late phase. + CE-endpoint test launched: stage1b_f3e3cont (s45000 -> 58.8k at floor 3e-3, farm). If it closes to + <=0.03, next-flagship recipe = ramp ...->3e-3@~35k; else double-sided (queued) takes the residual. +- **bf16 gate: naive full-cast FAILS at any beta.** floor 3e-4 -> cos 0.33; 3e-3 -> 0.67; 1e-2 -> 0.65 + (no longer SNR-limited: bf16 rounding distorts the nudged equilibrium itself; beta cannot compensate). + Speed was 2.1x (5.2 it/s). VERDICT: cost baseline stays TF32 (validated); the x0.5 lever requires + proper mixed precision (bf16 weights/matmuls + fp32 states/accumulation, autocast-style) -- queued as + engineering upside, NOT in the Ben cost baseline. Wall-1 physics predicted all of this (SNR ∝ beta/eps; + bf16 eps ~8000x fp32): the fp32/bf16/analog-noise beta-epsilon scaling story now has a second + measured point. diff --git a/ep_run/casc_eq_train.py b/ep_run/casc_eq_train.py index 5a3e640..ad82b5e 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('--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) ap.add_argument('--gate_govern', action='store_true') # let gate cos adjust K/bscale (default: observe-only => training control is BP-free) @@ -173,6 +174,13 @@ if args.resume: if _ck.get('lnf') is not None and not isinstance(ln_f, nn.Identity): ln_f.load_state_dict(_ck['lnf']) start_step = int(_ck.get('step', 0)) print(f'[resume] loaded {args.resume} at step {start_step}', flush=True) +if args.bf16: + for _m in (tok, pos, blocks): + _m.to(torch.bfloat16) + if not isinstance(ln_f, nn.Identity): ln_f.to(torch.bfloat16) + if args.untie: + with torch.no_grad(): W_out.data = W_out.data.to(torch.bfloat16) + print('[bf16] model cast to bfloat16 (E-accum + sigma stay fp32)', flush=True) if args.opt == 'muon': from muon import build_hybrid opt, sched = build_hybrid(blocks, all_params, args.lr, args.muon_lr, args.warmup, @@ -220,7 +228,7 @@ def free_states_graphed(x): @torch.no_grad() def tok_sigma(iters=8): """top singular value of tok.weight (power iteration on the raw matrix).""" - W = W_out if args.untie else tok.weight + W = (W_out if args.untie else tok.weight).float() v = torch.randn(W.shape[1], device=dev); v /= v.norm() sig = 1.0 for _ in range(iters): @@ -312,7 +320,7 @@ def ep_step(x, y): return free_ce, beta_t, GOV['K'], False GOV['drift'] = drift E = 0.0 - for z, o in zip(zp, last_outs): E = E + 0.5 * ((z.detach() - o) ** 2).sum() + for z, o in zip(zp, last_outs): E = E + 0.5 * ((z.detach().float() - o.float()) ** 2).sum() # fp32 accumulation (bf16-safe; no-op in fp32) obj = E / (NBT * beta_t) + obj_loss(readout(zp[-1].detach()).reshape(-1, vocab), y.reshape(-1)) gs = torch.autograd.grad(obj, all_params, allow_unused=True) gn = 0.0 |
