实验课:给我们自己的模型装上稳定性仪表
这一课不讲新概念。前五课的每一条结论,都放到我们自己从 0 训练的 3.7M 参数模型上核对。所有图表直接读实验导出的真实日志;每张图下面的「口径」一行写明模型、语料、步数、种子,「读图」一行由数据现算。
为什么这里不用例句:我们的模型是在《三國志演義》上训练的,词表只有 2,048,「小明把苹果给了小王」不在它的训练分布里;这一课看的是整个验证集上的仪表读数,不是某一句话。
实验是怎么设计的
一次只改一项,其余全部与基线相同(4 层、d = 256、8 头、RoPE、Pre-LN · RMSNorm、SwiGLU、AdamW lr 3e-3、cosine、warmup 100、裁剪 1.0、fp32、400 步、种子 1337):
| 组 | 改了什么 | 回答哪一课的问题 |
|---|---|---|
| ① 归一化位置 | Post / Pre × lr 1e-2 / 3e-2,全部不 warmup;另加 12 层的 Post / Pre,和 12 层有 warmup 的 Post | 第 2 课 |
| ② QK-Norm | 开 / 关 × lr 3e-3 / 1e-2 / 3e-2(warmup 100) | 第 3、4 课 |
| ③ 初始化 | init_std ∈ 0.002 / 0.02 / 0.2 / 1.0 | 第 1 课 |
每次评估(每 20 步)在验证集前 8 个 256-token 窗口上多做一次前向,记下所有层、所有头 softmax 之前的最大 q·k/√d(「最大注意力 logit」),以及输出 logit 的最大绝对值;梯度范数是裁剪前的全局范数,每 5 步记一次均值与最大值。
先写下你的预测(读完前五课再猜,猜错比猜对更有用):
- 不 warmup、学习率 1e-2 时,Post-LN 和 Pre-LN 谁会出事?「出事」会是发散成 NaN,还是别的样子?
- 不开 QK-Norm,学习率从 3e-3 放大 10 倍到 3e-2,最大注意力 logit 的终值会放大几倍?
- 开了 QK-Norm 之后,最大注意力 logit 能不能超过 √32 ≈ 5.66?
- init_std = 1 时,开局 loss 是多少?(第 1 课的组件能算出来)
一、先看验收表
MILESTONES「C8 稳定性」的验收只看四个量:是否发散、梯度范数峰值、最大注意力 logit 终值、开局 loss 与 ln V 的差。这张表把 17 个对照 run 的四个量排在一起(有几个 run 在不同组里重复出现,比如基线同时是 QK-Norm 关 · lr 3e-3 和 init_std 0.02)。
二、归一化放在哪(第 2 课)
对照你的预测 1:Post-LN 没有发散成 NaN,而是卡在 unigram 基线——最终 val 与「只按字频猜」的 6.6247 几乎一样;梯度范数也没有飙升(和同设置的 Pre-LN 逐对比一比「梯度范数峰值」)。这是「训不动」的一种样子——第 2 课的 β 图给了一种解释:Post-LN 对参数扰动更敏感,开局那几步大更新可能把它推进一个出不来的区域;但这是解读,本轮没有做能确认机制的消融。「更小的学习率 + warmup 能不能救回来」已经补测(第 2 课「补充实验」):4 层 Post-LN 学习率 1e-3 时,不 warmup 6.627、warmup 100 步 4.865;3e-4 时 5.496 / 5.478;词向量放大 16 倍仍停在 6.626。比 100 步更长的 warmup 还没有测。切到「最大注意力 logit」:Pre-LN 不 warmup 时也在长,只是没有卡住。
三、QK-Norm(第 3、4 课)
对照预测 2、3:关着 QK-Norm,学习率 3e-3 → 3e-2,最大 logit 终值从 49.9 到 6784;开着 QK-Norm,最大值能超过 5.66,因为 5.66 是增益为 1 时的上界,增益是可学习的——逐层终值表里能看到每一层各自长到了多少。
四、初始化(第 1 课)
对照预测 4:第 1 课的蒙特卡洛与这里的实测应该对得上;表里「预测」一列用的就是第 1 课那个公式。
五、最大注意力 logit:所有 run 放在一起
六、把结论对回前五课
| 课 | 那一课的结论 | 在我们的模型上看什么 |
|---|---|---|
| 第 1 课 | 开局 loss ≈ ln V;σ 太大开局 logits 爆,太小学不动 | 四档初始化的开局 loss − ln V 与最终 val;开局 logit 标准差的预测与实测 |
| 第 2 课 | Post-LN 对扰动敏感,离不开 warmup | Post-LN 四组都卡在 unigram,包括有 warmup 的 12 层组;Pre-LN 不 warmup 也在学 |
| 第 3 课 | spike 的前提是参数状态:logit 被一步步养大 | 最大注意力 logit 随学习率、随 warmup 的增长(本规模上没有真的 spike) |
| 第 4 课 | QK-Norm 从源头按住注意力 logit | 开 / 关对比:学习率越大,最大 logit 终值差得越多(倍数见「三」的读图);val loss 不变差 |
| 第 5 课 | SP 下每一步的改动 ∝ 宽度 × η | 本轮 C8 实验不涉及;C6 的宽度 × 学习率扫描见第 5 课 |
这些结论只在这个规模上成立:3.7M 参数(12 层组约 10M)、约 50 万 token 的语料、400 步、单种子 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条我们自己的实验;噪声底线按 C14:同配置 5 次重跑极差 0.016、3σ ≈ 0.020(ref_baseline 与 baseline 这一对差约 0.014);单种子下是否发散对学习率敏感。 出处待补 。没有一条曲线出现真正的 loss spike——PaLM 说 spike 只在最大的模型上出现,我们能看到的是它的前提(logit 的增长)。实验课的价值不在「证明谁最好」,在于练习先写下预测、只改一项、连同条件报告结论,以及学会读仪表。
七、为项目拍板
你要拍板的三件事(对应章首页的项目里程碑):
- 要不要 QK-Norm?依据「三」:最大注意力 logit 终值差多少,val loss 有没有变差(差距小于噪声的不算)。
- warmup 能不能省?依据「二」:Pre-LN 不 warmup 时 val 比基线差多少、最大 logit 长到多少;Post-LN 不在候选里(C4 已选 Pre-LN)。
- 初始化标准差取多少?依据「四」:开局 loss − ln V 与最终 val。
验收标准(全部可测):选定配置不发散;开局 loss − ln V 不大于基线的 0.0606;梯度范数峰值与最大注意力 logit 终值写进报告并与基线对比;两个配置相差小于噪声底线(C14:同配置 5 次重跑极差 0.016,3σ ≈ 0.020)时,不下结论,换 3 个种子取均值。
🔍 自己复现这个实验
脚本在 04-实践项目/experiments/exp_c8_stability.py,训练配置沿用 04-实践项目/configs/baseline.json,开关在 model.norm_pos、model.qk_norm、model.init_std 与 train.lr、train.warmup_steps;与其他章配置相同的 run(C4 的两组不 warmup、C5 的 lr 1e-2、C6 的 lr 3e-2)直接复用。导出到 知识平台/src/data/project/c08-stability.json,本页所有图表自动读它。最大注意力 logit 由 experiments/common.py 的探针在每次评估时记录,不参与训练。
一句话
下一个缺口
训练一个参数,要几字节? → C9 第 1 课:训练一个参数,要几字节?