diff options
| author | Yuren Hao <yurenh2@illinois.edu> | 2026-07-16 04:33:29 -0500 |
|---|---|---|
| committer | Yuren Hao <yurenh2@illinois.edu> | 2026-07-16 04:33:29 -0500 |
| commit | 35e7582287ab5a82bf57561895b5a095dc9b6e24 (patch) | |
| tree | 650d64e699c1ba996e784284e9ac8001def3ba26 /ep_run/casc_eq_train.py | |
| parent | 5f8dd1c4d7106665cf9722e7a394893bb87c9b07 (diff) | |
RESULT 29: qcomp8 tax-free (+0.0018) = T64 8-bit compute green light; --centmirror ships (cos 1.000000000, 1.72x -> 1.39x)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FAPDWQ49M5Ye3NpTndTpn
Diffstat (limited to 'ep_run/casc_eq_train.py')
| -rw-r--r-- | ep_run/casc_eq_train.py | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/ep_run/casc_eq_train.py b/ep_run/casc_eq_train.py index 17a0c70..8e246d1 100644 --- a/ep_run/casc_eq_train.py +++ b/ep_run/casc_eq_train.py @@ -71,6 +71,9 @@ ap.add_argument('--qcomp_bits', type=int, default=0) # STAGE-0 T64 scenario ap.add_argument('--qup_bits', type=int, default=0) # STAGE-0: quantize weights to an absolute # per-tensor grid after each update (stochastic # rounding); emulates finite analog cell levels +ap.add_argument('--centmirror', action='store_true') # centered's -beta pass initialized as the MIRROR + # of the +beta solution (d- = -d+ at shared anchor) + # + one polish sweep; skips its free pass entirely ap.add_argument('--centfast', action='store_true') # centered via ONE doubled batch [x;x], +beta/-beta halves # (shared kernels; math identical to sequential centered) args = ap.parse_args() @@ -369,6 +372,7 @@ def relax(z0, zs, ins, outs, y, beta, K, x, bmask=None): GOV['rho'] = rlist[-1] / rlist[-2] # per-sweep contraction ratio = live loop-gain meter GOV['res'] = rlist[-1] GOV['kuse'] = K + GOV['_last_d'] = d return zs, outs prev_res, k = None, 0 @@ -386,6 +390,7 @@ def relax(z0, zs, ins, outs, y, beta, K, x, bmask=None): forces(True) # final graphed round at the settled state (theta-read) rebuild(True) GOV['kuse'] = k + 1 + GOV['_last_d'] = d return zs, outs def dFdtheta(zs, x, y, beta): @@ -496,9 +501,28 @@ def ep_step(x, y): gsC = torch.autograd.grad(obj_loss(readout(zp[-1].detach()).reshape(-1, vocab), y.reshape(-1)), all_params, allow_unused=True) b2 = -beta_t if EST == 'centered' else 2.0 * beta_t - z0b, zsb, insb, outsb = free_states_graphed(x) - zsb_free = [z.clone() for z in zsb] - zpb, lob = relax(z0b, zsb, insb, outsb, y, b2, GOV['K'], x) + if EST == 'centered' and args.centmirror: + # MIRROR WARM-START: d-(free anchor) = -d+ exactly (linear in beta); init the -beta + # states as the mirror of the settled +beta solution, then ONE polish sweep corrects + # the O(beta^2) even part. Skips the second free pass and K-1 sweeps. + dm = [(-di).detach() for di in GOV['_last_d']] + zsb_free = zs_free + prev = z0 + zsb, insb, outsb = [], [], [] + with torch.autocast('cuda', dtype=torch.bfloat16, enabled=args.amp): + for l in range(args.L): + i = prev.detach().requires_grad_(True) + o = blocks[l](i, mask) + zsb.append(o.detach().float() + dm[l]) + insb.append(i); outsb.append(o) + prev = zsb[l] + _k1 = GOV.get('kuse') + zpb, lob = relax(z0, zsb, insb, outsb, y, b2, 1, x) + GOV['kuse'] = _k1 # telemetry: report the +beta pass's K, not the mirror polish + else: + z0b, zsb, insb, outsb = free_states_graphed(x) + zsb_free = [z.clone() for z in zsb] + zpb, lob = relax(z0b, zsb, insb, outsb, y, b2, GOV['K'], x) with torch.no_grad(): drift2 = sum(float((a - b).norm()) for a, b in zip(zpb, zsb_free)) / max( sum(float(b.norm()) for b in zsb_free), 1e-9) |
