diff options
| author | Yuren Hao <yurenh2@illinois.edu> | 2026-07-14 11:38:44 -0500 |
|---|---|---|
| committer | Yuren Hao <yurenh2@illinois.edu> | 2026-07-14 11:38:44 -0500 |
| commit | bba77d7a45ac29f5a640dac26c097752db1a59bb (patch) | |
| tree | 528a48f8449f7938c2194e0976c800fbc0473e07 | |
| parent | 70e6ee77b28d447de01b489d8808893d1d9e82dc (diff) | |
bcap v2: absolute-scale gate on rho meter (fixes v1 noise-floor starvation), gentler attack 0.85/floor 0.05; crown c2 relaunched from s215000 with cap armed
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FAPDWQ49M5Ye3NpTndTpn
| -rw-r--r-- | ep_run/casc_eq_train.py | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/ep_run/casc_eq_train.py b/ep_run/casc_eq_train.py index 7b9780c..faf827e 100644 --- a/ep_run/casc_eq_train.py +++ b/ep_run/casc_eq_train.py @@ -351,6 +351,7 @@ def relax(z0, zs, ins, outs, y, beta, K, x): rlist.append(rebuild(k + 1 == K)) if len(rlist) >= 2 and rlist[-2] > 1e-12: GOV['rho'] = rlist[-1] / rlist[-2] # per-sweep contraction ratio = live loop-gain meter + GOV['res'] = rlist[-1] GOV['kuse'] = K return zs, outs @@ -434,10 +435,13 @@ def ep_step(x, y): GOV['drift'] = gdrift if args.beta_cap_rho > 0 and GOV.get('rho') is not None: rho_g = ddp_bcast_scalar(GOV['rho']) # rank0's meter rules (identical control on all ranks) - if rho_g > args.beta_cap_rho: - GOV['cap'] = max(GOV.get('cap', 1.0) * 0.8, 0.02) # back beta off under the wall-2 ceiling - elif rho_g < 0.5 * args.beta_cap_rho: - GOV['cap'] = min(GOV.get('cap', 1.0) * 1.02, 1.0) # slow recovery toward schedule + res_g = ddp_bcast_scalar(GOV.get('res', 0.0)) + # v2: ABSOLUTE-SCALE GATE — rho is only meaningful when the residual is above the noise + # floor; at tiny residuals rho ~ noise/noise ~ 1 and v1 starved beta to the cap floor. + if res_g > 0.02 and rho_g > args.beta_cap_rho: + GOV['cap'] = max(GOV.get('cap', 1.0) * 0.85, 0.05) # attack (gentler than v1) + elif res_g < 0.01 or rho_g < 0.5 * args.beta_cap_rho: + GOV['cap'] = min(GOV.get('cap', 1.0) * 1.02, 1.0) # recover E = 0.0 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) if args.est == 'single': |
