summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/campaign/CASCADE_ABLATION_PLAN.md22
-rw-r--r--ep_run/casc_eq_train.py16
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):