diff options
| author | Yuren Hao <yurenh2@illinois.edu> | 2026-07-17 08:53:33 -0500 |
|---|---|---|
| committer | Yuren Hao <yurenh2@illinois.edu> | 2026-07-17 08:53:33 -0500 |
| commit | 943f8ccc92be87f0ce212947fa268618d4bc37ec (patch) | |
| tree | 6b994a6728209466ec4b4ec47a621a272f355154 /ep_run | |
| parent | da17b9ee54373dd6b715094c00f515931fe90f48 (diff) | |
--beta_sync: synchronous acceptance (this-step relax telemetry gates the commit; reject -> halve beta, retry same batch; failed trial doubles as ceiling measurement for the ride cap)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FAPDWQ49M5Ye3NpTndTpn
Diffstat (limited to 'ep_run')
| -rw-r--r-- | ep_run/casc_eq_train.py | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/ep_run/casc_eq_train.py b/ep_run/casc_eq_train.py index 10e3515..f115a91 100644 --- a/ep_run/casc_eq_train.py +++ b/ep_run/casc_eq_train.py @@ -54,6 +54,9 @@ ap.add_argument('--ddp_grad_test', action='store_true') # one-step grad equival ap.add_argument('--beta_ride', type=float, default=1.0) # cap ceiling: >1 lets the governor RAISE beta # above the schedule, up to ride x schedule ap.add_argument('--beta_ride_up', type=float, default=1.02) # per-step climb rate in the calm branch +ap.add_argument('--beta_sync', type=int, default=0) # >0: SYNCHRONOUS acceptance — this step's own + # relax telemetry gates the commit; on reject, + # halve beta and retry same batch (N halvings max) ap.add_argument('--ride_ema', type=int, default=0) # ride-v2(b): rho-EMA before governor decisions ap.add_argument('--ride_cool', type=int, default=0) # ride-v2(c): post-attack climb cooldown (steps) ap.add_argument('--drift_adapt', type=float, default=0.0) # >0: adaptive drift ceiling = this x trailing @@ -474,9 +477,35 @@ def ep_step(x, y): de = GOV.get('drift_ema') if de is not None: dthr = min(0.5, max(0.05, args.drift_adapt * de)) - if (not math.isfinite(gdrift)) or (gdrift > dthr and not args.noguard): + def _legal(gd): + # SYNCHRONOUS acceptance (--beta_sync): judge THIS step by THIS step's own relax + # telemetry — an out-of-window beta can be attempted but can never COMMIT. + if (not math.isfinite(gd)) or (gd > dthr and not args.noguard): return False + if args.beta_sync > 0: + res_s = ddp_bcast_scalar(GOV.get('res', 0.0)) + rho_s = ddp_bcast_scalar(GOV.get('rho') or 0.0) + if res_s > 0.02 and rho_s > args.beta_cap_rho: return False + return True + if not _legal(gdrift): ok_retry = False - if args.kretry > 0 and math.isfinite(gdrift) and not args.noguard: + if args.beta_sync > 0 and not args.noguard: + for _h in range(args.beta_sync): # halve beta, retry the SAME batch + beta_t = beta_t * 0.5 + GOV['skr'] = GOV.get('skr', 0) + 1 + z0, zs, ins, outs = free_states_graphed(x_in) + zs_free = [z.clone() for z in zs] + zp, last_outs = relax(z0, zs, ins, outs, y_in, +beta_t, GOV['K'], x_in, bmask=bmask) + with torch.no_grad(): + drift = _drift(zp, zs_free) + gdrift = ddp_max_scalar(drift) + if _legal(gdrift): + ok_retry = True + if args.beta_ride > 1.0: # the failed trial IS the ceiling measurement + GOV['cap'] = max(GOV.get('cap', 1.0) * 0.5 ** (_h + 1), 0.05) + break + if ok_retry: + pass + if not ok_retry and args.kretry > 0 and math.isfinite(gdrift) and not args.noguard: GOV['skr'] = GOV.get('skr', 0) + 1 # marginal batch: retry once with deeper relaxation z0, zs, ins, outs = free_states_graphed(x_in) zs_free = [z.clone() for z in zs] @@ -484,7 +513,7 @@ def ep_step(x, y): with torch.no_grad(): drift = _drift(zp, zs_free) gdrift = ddp_max_scalar(drift) - ok_retry = math.isfinite(gdrift) and gdrift <= 0.5 + ok_retry = _legal(gdrift) if not ok_retry: GOV['skd'] = GOV.get('skd', 0) + 1 # drift-guard reject (relaxation non-convergence) for p in all_params: p.grad = None |
