diff options
| author | Yuren Hao <yurenh2@illinois.edu> | 2026-07-30 15:50:25 -0500 |
|---|---|---|
| committer | Yuren Hao <yurenh2@illinois.edu> | 2026-07-30 15:50:25 -0500 |
| commit | 7ef12f8006ea1b19657fab6aa189785929b1f4a4 (patch) | |
| tree | 0555554c78f637dce433b6042c7ed08911576a96 | |
| parent | 5da39cf68b19b1be997db1956026af3f68576f73 (diff) | |
RESULT 76: 谱仪读出 — 逐块泄漏剖面(C768上6块-0.70..-0.23,C512块8-11也病)+偶性实锤(-β同号)+disp_ratio阈值跨宽度塌缩(~2e-7≈2×fp32 eps)+fp32地板假说(一举解释全部约束); 预注册双证伪已发射(β-scan平移+fp64决定臂); --probe_f64实装
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 | 22 | ||||
| -rw-r--r-- | ep_run/casc_eq_train.py | 16 |
2 files changed, 33 insertions, 5 deletions
diff --git a/docs/campaign/CASCADE_ABLATION_PLAN.md b/docs/campaign/CASCADE_ABLATION_PLAN.md index adbcaca..70a9adc 100644 --- a/docs/campaign/CASCADE_ABLATION_PLAN.md +++ b/docs/campaign/CASCADE_ABLATION_PLAN.md @@ -1894,3 +1894,25 @@ Matched 三口径(同窗 434-440k, n=61/臂): (~22h×3GPU, 等 geo 电池 + 谱仪结果再决定是否值得)。 - 稳定性结论无保留: ×128 位移 190k 步零发散(drift 稳 0.008), 大位移在完整训练尺度安全。 - 按 07-29 条令: class-2 exploratory, 不入 scaling 曲线; 价值 = "泄漏在全程可部分赎回" + 稳定性 + 上述口径教训。 + +## RESULT 76 (2026-07-30): 谱仪主电池读出 — 逐块剖面 + 偶性实锤 + 无量纲阈值塌缩 + fp32地板假说 +仪器: probe_dgspec, 配对差分 L_l(g)=mean_b[gEP_l(g)−gBP_l], NB=384, fp32, 主指标=BP方向带符号投影。 +- **逐块泄漏剖面(g1)**: C768 下6块≈0, 上6块 proj −0.70/−0.59/−0.34/−0.36/−0.32/−0.23(最病=块6=中点, + 非顶); C512 也有泄漏: 块8-11 −0.40/−0.17/−0.13/−0.06(更窄更浅)。与 bpmix 半层分区互证, 首次分辨到块。 +- **偶性实锤**: −β 臂上层泄漏逐块同号同值(−0.690 vs −0.703…) → 泄漏=|位移|的偶函数; 底层微小项随 + β 翻号 = 教科书奇性 O(β) FD 偏差。一次探针分离两病。bsign 治不了泄漏的原因闭环。 +- **读数标定**: 统一增益 g 下健康块 gEP≈g·gBP(proj≈g−1) → 归一保真=(proj+1)/g。病块呈共振曲线: + 块6 峰值在 ×4-8(0.98), ×128 塌到 0.15, ×256 反向; 块7 峰 ×16-32; 块8-11 峰 ×16-64 并过冲(1.1-1.3)。 + 平顶 ×128 对多数块是过量(尤其块6) — 逐块 profile 有真实的每块最优。⚠️ 本电池为全网统一增益(组合 + 态), 与训练的 top-half-only profile 组合不同; g≥128 行疑似弛豫不稳, 降权。 +- **无量纲阈值塌缩(=M1 要找的东西)**: disp_ratio=RMS(d_l)/RMS(z_l) 底→顶衰减 ~1000×(C768 5.5e-5→ + 4.2e-8)。两宽度 24 块合并: **病块 ⟺ ratio≲2e-7, 健康 ⟺ ≳7e-7, 同一阈值跨宽度成立**。 +- **fp32 地板假说(重磅, 待证伪)**: 阈值 2e-7 ≈ 2×fp32 eps(1.19e-7)。假说: 泄漏=模拟器 z=o+d 的 fp32 + 舍入把亚 eps 位移分量抹零, 非模型物理。一次解释全部约束: 定位/宽度加重/∝1/β/偶性/全免疫谱(fp32 + 臂同地板)/BP替换可关/对数剂量律(逐元素比值分布+硬地板→清出比例∝log g)。 +- **预注册证伪(已发射, GPU3 串行)**: (1) β-scan: β/8→块5(ratio 1.5e-7)应转病, β×8→块6-7(1.6e-6/ + 6.7e-7)应痊愈 — 地板论的边界须随 β 精确平移; (2) fp64 决定臂(--probe_f64, 全模型+状态双精度): + 地板论预测上半泄漏塌到≈0; 若存留则地板论死, 泄漏=真物理。 +- 若地板论成立: dgain 整套装置可退役, 修复=状态路径 fp64/补偿求和; LM 尺度 EP gap 的很大一块重述为 + 模拟器精度伪影; 硬件叙事反而加强(基底加性地板的通用设计律: 逐层 nudge 位移必须清过地板 — 板上 + 测量2的数字孪生)。1B 迁移律候选: 一次自由相测 disp_ratio 剖面即得逐层规格, 零训练。 diff --git a/ep_run/casc_eq_train.py b/ep_run/casc_eq_train.py index a9218a0..76b96fd 100644 --- a/ep_run/casc_eq_train.py +++ b/ep_run/casc_eq_train.py @@ -54,7 +54,8 @@ ap.add_argument('--dgain_geo', type=float, default=0.0) # >0: per-layer geomet ap.add_argument('--dgain_geo_cap', type=float, default=0.0) # >0: cap for the geometric profile ap.add_argument('--dgain_rand', type=float, default=0.0) ap.add_argument('--probe_dgspec', type=int, default=0) # >0: M1 spectroscopy, value = n batches; exits before training -ap.add_argument('--probe_gains', default='1,2,4,8,16,32,64,128,256') # >1: per-STEP log-uniform dgain_top in +ap.add_argument('--probe_gains', default='1,2,4,8,16,32,64,128,256') +ap.add_argument('--probe_f64', action='store_true') # fp64 states+model in the probe: the fp-floor decisive arm # >1: per-STEP log-uniform dgain_top in # [1, this] (spread-spectrum probing of the # decade-spread threshold distribution) ap.add_argument('--dgain_top', type=float, default=1.0) # amplify d in STATE FORMATION for blocks @@ -291,6 +292,7 @@ class Olmo2Block(nn.Module): z = z + self.na(self.attn(z)) return z + self.nf(self.ff(z)) +SDT = torch.float64 if args.probe_f64 else torch.float32 # state dtype; fp64 only in probe mode tok = nn.Embedding(vocab, args.C).to(dev) pos = nn.Embedding(args.T, args.C).to(dev) if args.tok_init > 0: @@ -375,7 +377,7 @@ def free_states_graphed(x): for b in blocks: i = prev.detach().requires_grad_(True) o = b(i, mask) - ins.append(i); outs.append(o); zs.append(o.detach().float()) + ins.append(i); outs.append(o); zs.append(o.detach().to(SDT)) prev = zs[-1] return z0, zs, ins, outs @@ -410,7 +412,7 @@ def relax(z0, zs, ins, outs, y, beta, K, x, bmask=None): if bmask is not None: g = g * bmask d[args.L - 1] = (-beta * nbt_loc * g).detach() for l in range(args.L - 2, -1, -1): - d[l] = torch.autograd.grad(outs[l + 1], ins[l + 1], grad_outputs=d[l + 1].to(outs[l + 1].dtype))[0].detach().float() + d[l] = torch.autograd.grad(outs[l + 1], ins[l + 1], grad_outputs=d[l + 1].to(outs[l + 1].dtype))[0].detach().to(SDT) def rebuild(last): nonlocal ins, outs @@ -435,7 +437,7 @@ def relax(z0, zs, ins, outs, y, beta, K, x, bmask=None): if args.dgain_geo_cap > 0: _dg = min(_dg, args.dgain_geo_cap) else: _dg = args.dgain_all * ((GOV.get('dgcur') or args.dgain_top) if l >= args.L // 2 else 1.0) - znew = o.detach().float() + (_dg * d[l] if _dg != 1.0 else d[l]) + znew = o.detach().to(SDT) + (_dg * d[l] if _dg != 1.0 else d[l]) # damped (under-relaxed) mixing: geta<1 restores contraction on stiff operators # (wall-2 toolkit); fixed point unchanged (z = z + geta*(o+d-z) <=> z = o+d) mixed = znew if g_eff >= 1.0 else (zs[l] + g_eff * (znew - zs[l])) @@ -855,6 +857,10 @@ if args.probe_dgspec > 0: # splits odd-in-beta FD bias from even-in-|displacement| leak. Run WITHOUT --amp: the # bf16 floor is width-blind (b15 lesson); fp32 is the instrument-grade path. assert WORLD == 1, 'probe_dgspec is single-GPU' + if args.probe_f64: + tok.double(); blocks.double(); ln_f.double() + if W_out is not None: W_out.data = W_out.data.double() + print('[dgspec] FP64 states+model active', flush=True) import json, sys gains = [float(t) for t in args.probe_gains.split(',')] cfgs = [(f'g{g:g}', g, +1.0) for g in gains] + [('g1neg', 1.0, -1.0)] @@ -886,7 +892,7 @@ if args.probe_dgspec > 0: for l in range(args.L): disp[l] += float(GOV['_last_d'][l].norm() / max(float(zp[l].norm()), 1e-12)) / NB E = 0.0 - for z, o in zip(zp, lo): E = E + 0.5 * ((z.detach().float() - o.float()) ** 2).sum() + for z, o in zip(zp, lo): E = E + 0.5 * ((z.detach().to(SDT) - o.to(SDT)) ** 2).sum() obj = E / (NBT * bt) + obj_loss(readout(zp[-1].detach()).reshape(-1, vocab), y.reshape(-1)) gs = torch.autograd.grad(obj, all_params, allow_unused=True) for j, ix in enumerate(bix): |
