从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 40 分钟 页内实验 ×4
C8 稳定性:放大后为什么会炸 第 2 课

原版 Transformer 为什么离不开 warmup?

Post-LN 与 warmup:归一化放在哪
原版 Transformer 把 LayerNorm 放在残差加法之后(Post-LN):初始化时最后一层的梯度不随层数变小,给所有权重同样一点扰动,输出变化随层数线性增长——只能用 4,000 步 warmup 慢慢起步。Pre-LN 把归一化挪进支路,主路只剩加法,敏感度只按 log N 增长,于是可以不靠 warmup 起步;代价是深层写入被稀释。
❓

本课一问:2017 年的原版 Transformer 用了 4,000 步 warmup。C5 第 4 课说 warmup 管的是开局——可今天的 Pre-LN 模型 warmup 短得多,有的研究甚至直接去掉。原版为什么格外离不开它?

这一课先不碰:训练到一半才出现的 spike(第 3 课)、注意力 logit 失控(第 4 课)。这一课只看「开局那几步」。

从已有出发

从已有出发 · 累计数据流 点已学环节看形状与参数
解码层
从已有出发 · 训练的一步(点任一环节看它在 Qwen/Qwen3.8-27B 上有多大) 本课本章后面的课

三条旧线索摆在一起:

这一课的例句用法:让「小明把苹果给了小王」这 5 个位置的向量(随机数代替)穿过 Post-LN 与 Pre-LN 两种堆叠,比较它们对同一点参数扰动的反应。

同一个块,归一化放在两个位置(C4 第 3 课)
主路:加法之后还要过 LayerNorm xₗ[T × d] 注意力直接读主路 Δ₁ + LayerNorm FFNReLU(原版) Δ₂ + LayerNorm xₗ₊₁[T × d]

    先自己设计:就用原版 Post-LN,开局直接上峰值学习率

    原版的学习率公式(Vaswani et al. 2017 式 3)是 lrate = dmodel−0.5 · min(step−0.5, step · warmup−1.5),warmup = 4,000:前 4,000 步线性爬升,在第 4,000 步到峰值 512−0.5 × 4000−0.5 = 6.99e-4,之后按 1/√step 下降 。朴素的想法:warmup 只是慢,去掉它,开局就用峰值。

    去掉之前,先测一件事:Adam 第 1 步让所有参数同时动一点,整个网络的输出会动多少?下面给 Post-LN 和 Pre-LN 两种堆叠的所有权重加上同样大小(各自标准差的 1%)的随机扰动,量输出变化:

    1. ① 朴素方案
    2. ② 它在哪失败
    3. ③ 改进方案
    朴素方案Post-LN:x ← LN(x + F(x)),开局直接上峰值学习率
    同样一点扰动,输出变多少:Post-LN vs Pre-LN

    计算中……(浏览器里真算前向与反向,种子固定)

    🎯

    试三件事:① 把左图横轴切到 log₂ N:Pre-LN 那条线变成近似直线(与 ln N 成正比),Post-LN 那条向上弯;② 拖右图的 N,看 Pre-LN 的 β 怎样随层号变小,Post-LN 的 β 始终在一个范围里;③ 点「直接扰动测一遍」,核对左图的估计量和真扰动的方向一致。

    改进:把归一化挪进支路——两种解释

    「Post-LN 为什么离不开 warmup」有两篇代表性的分析,解释的角度不同,结论都是 Pre-LN 更稳,但原因的说法并不一致,两篇都值得知道。

    解释一(Xiong et al. 2020):最后一层的梯度不随深度变小

    初始化时,梯度落在哪几层:Post-LN vs Pre-LN

    计算中……(浏览器里真算前向与反向,种子固定)

    Xiong et al. 2020 定理 1:初始化时最后一层 FFN 第二个矩阵的梯度上界
    👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
    条件:平均场理论下,初始化时刻,注意力权重在初始化时是均匀的(W_Q、W_K 取 0)等简化假设;以概率至少 0.99 − δ − ε 成立。上面组件的「真算」就在同样的均匀注意力假设下复现了这两个斜率。

    Xiong 的推理链是:Post-LN 靠近输出的参数梯度大 → 开局直接用大学习率会不稳 → warmup 在实践上帮了忙;于是 Pre-LN 可以去掉 warmup,他们在翻译与 BERT 上验证了去掉 warmup 仍能达到可比结果 。

    解释二(Liu et al. 2020):不是梯度大小,是「放大效应」

    Liu 等人明确反驳:梯度不均衡不是根本原因——单独修好梯度并不能让 Post-LN 稳。他们指出的是每一层对自己那条支路的依赖程度 β:Post-LN 每一层都把「上一层 + 本支路」重新归一化,本支路一直占很大一份;于是参数的一点改动会被层层放大,推论 2 给出输出变化是 O(N),Pre-LN 是 O(log N) 。这正好接上 C5:Adam 第 1 步让所有参数一起走 ±η,Post-LN 把这一步放大成对输出的大扰动;warmup 让 η 从很小开始,等于在最敏感的时候把步子压小。

    两种解释都指向同一个改法:把归一化挪进支路。Pre-LN 的主路上只剩加法,C4 第 2 课的展开式 xL = x0 + Σ Fl 原样成立。归属要写对:GPT-2(2019)报告里写着「把 LayerNorm 挪到每个子块的输入」 ;Xiong 2020 自己也写明 Pre-LN「已在若干系统中实现」,引的第一个是 2018 年的 Tensor2Tensor——Pre-LN 不是 Xiong 发明的,Xiong 补的是理论。

    我们自己的模型上:不 warmup、学习率 1e-2 与 3e-2

    真训练日志 · 只改归一化位置、学习率与 warmup
    项目实测 · 不 warmup、高学习率:Post-LN vs Pre-LN

    C4 的同一组对照(含 lr 3e-3、warmup 100 的 Post-LN)

    这组结果要带着条件读。四个 Post-LN run 的最终 val 都停在 unigram 基线 6.6247 附近——只按字频猜下一个 token,完全没用上上下文;连 12 层、有 100 步 warmup 的那一组也是(最终 6.6272),C4 那组基线学习率 3e-3 加 warmup 的 Post-LN 同样如此。这些 run 都没有发散成 NaN,梯度范数也没有飙升(见表中「梯度范数峰值」一列,和同设置的 Pre-LN 比):Post-LN 在我们这里的失败不是「炸」,是「卡死」。而同样不 warmup 的 Pre-LN 一直在学(4 层 lr 1e-2 最终 5.680)。

    补充实验:学习率降下来,warmup 救得回 Post-LN 吗?

    上面的学习率(3e-3 起)比原版 Transformer 的峰值 7.0e-4 大好几倍。于是我们把 4 层 Post-LN 的学习率降到 1e-3 和 3e-4,各跑「不 warmup」与「warmup 100 步」两组,其余设置不变:

    4 层 Post-LN不 warmupwarmup 100 步
    学习率 3e-3—6.627
    学习率 1e-36.6274.865
    学习率 3e-45.4965.478

    学习率 1e-3 这一行就是本课一问的答案:不 warmup,Post-LN 照样卡在字频基线;只加 100 步 warmup,它就训到了比 3e-4 还低的 loss。学习率再降到 3e-4,开局那一步本身就够小,有没有 warmup 差别不大——warmup 管的正是「峰值学习率下的开局」。而学习率 3e-3 时,100 步 warmup 已经不够。

    我们还排除了一个嫌疑:项目没有把词向量乘 √d,会不会是它让 Post-LN 卡住?把词向量放大 16 倍再跑,4 层 Post-LN 仍停在 6.626,嫌疑排除。

    保留意见:单种子、4 层与 12 层、400 步;warmup 只试了 100 步,远短于原版的 4,000 步。结论只在这个规模上成立。

    ⚠

    常见误解一:「warmup 只是为了让 Adam 的二阶矩估计准。」这是 RAdam 给出的解释之一(C5 第 4 课)。Xiong 发现 warmup 对 Adam 以外的优化器也很有帮助,说明它不只是 Adam 的事;本课两种解释都指向结构本身的敏感度。

    常见误解二:「Pre-LN 严格优于 Post-LN。」Pre-LN 更好训,但「同样设置下效果常常不如 Post-LN」也是被反复报告的现象:Pre-LN 残差流越积越长,深层每一层的写入只占很小一份(上面右图的 β),相当于有效深度变浅了。所以 2022 年的 DeepNet 反而回到 Post-LN,靠放大残差、缩小初始化训到了 1,000 层 。

    常见误解三:「有了 Pre-LN,就可以不要 warmup。」Xiong 在他们的设置下去掉了 warmup,但今天的大模型几乎都还留着一段:Llama 3 405B 8,000 步,DeepSeek-V3 2K 步(C5 第 4 课的表)。Pre-LN 让 warmup 不再是生死线,开局的其他理由(Adam 首步 ±η、大 batch)仍在。

    新失败:深层被稀释——2026 年的分叉

    Pre-LN 解决了开局,却留下一个结构性的代价:残差流随深度变长,越往后的子层写入的占比越小。2024–2026 年,各家在这里分了岔:

    做法代表改了什么出处
    Pre-Norm + zero-centered RMSNorm锚点 Qwen3.8-27B(64 层)保持 Pre-Norm,归一化增益写成 1 + w(C4 第 3 课)模型卡与 config
    放大残差的 Post-LNDeepNet(2022)x ← LN(α·x + F(x)),配套缩小初始化arXiv 2203.00555
    归一化挪到子层输出OLMo 2h = x + RMSNorm(Attn(x)),同时加 QK-Norm;两者单独用都不好,一起用把梯度 spike score 从 0.108 降到 0.069OLMo 2 §3.3.2
    加宽残差流DeepSeek-V4 的 mHC、Qwen3.8-Flash-Next 的 Gated Residual一条残差流变成 4 条:mHC 用双随机约束的 n × n 矩阵混合;Gated Residual 去掉混合矩阵,读时逐元素 sigmoid 门、写时每条流一个标量C15 展开

    OLMo 2 自己写明「reordered norm」这个想法来自 Liu et al. 2021(Swin Transformer V2),又被 Chameleon 采用 。没有唯一正解:这是 2026 年分歧最大的地方之一。

    🔍 苏剑林的直观解释:Pre-LN 为什么「更好训但效果常常更差」

    苏剑林《为什么 Pre Norm 的效果不如 Post Norm?》(2022-03-29)的核心观察:Pre-LN 第 t 层的输出 xt+1 = xt + Ft(Norm(xt)),当 t 较大时 xt 已经很长,再加一个量级固定的 Ft,xt+1 与 xt 几乎一样;于是相邻两层近似可以合并成「一层更宽的」,名义上的深度被折算成了宽度。Post-LN 每一步都重新归一化,没有这种折算,深度是「真深度」,所以训好了效果更好,只是更难训。这和上面 β 图看到的是同一件事。脚本访问该站返回 403,内容按 Wayback 存档核对;本课没有复现他文中的实验。

    证据三问

    问本课的回答
    ① 它解决什么问题?让训练可以不依赖长 warmup 就用上正常的学习率:把参数扰动对输出的放大从 O(N) 降到 O(log N)
    ② 数学上为什么可能有效?Xiong 定理 1(最后一层梯度 Post 与 L 无关、Pre ∝ 1/√L)与 Liu 推论 1–2(Post O(N)、Pre O(log N))都在各自的简化假设下可证 ;「所以需要 warmup」是理论动机,两篇的归因并不一致
    ③ 实验上为什么最后选了它?Xiong 在翻译与 BERT 上去掉 warmup 仍达到可比结果;Liu 的 18 层 Post-LN 训不动;GPT-2 之后几乎所有大模型采用 Pre-Norm;我们的项目里 Post-LN 四组都卡在 unigram

    一句话

    📌
    Post-LN 把每个子层都放在主路上重新归一化,越深越放大参数扰动,只能靠 warmup 慢慢起步;Pre-LN 让主路只剩加法,于是稳——代价是深层写入被稀释。
    🚦

    先停在这里:记住「Post-LN 放大扰动 O(N)、Pre-LN O(log N)」和「Pre-LN 的代价是深层被稀释」。
    再深一层:读 Liu et al. 2020 的 §4(放大效应)和苏剑林那篇,比较两种解释。

    下一个缺口

    开着梯度裁剪、用了 Pre-LN,为什么训练到一半还会 loss spike? → 第 3 课:开着梯度裁剪,为什么还会 loss spike?

    回扣:C5 第 6 课纠正过「开了裁剪就不会 spike」——PaLM 开着裁剪仍有约 20 次。下一课兑现。另外注意上面的项目表:Pre-LN 不 warmup 的 run 没崩,最大注意力 logit 却涨到了上千,这颗雷在第 3、4 课引爆。

    你可能会问