summaryrefslogtreecommitdiff
path: root/ep_run/casc_eq_train.py
diff options
context:
space:
mode:
Diffstat (limited to 'ep_run/casc_eq_train.py')
-rw-r--r--ep_run/casc_eq_train.py12
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':