Peri-LN
Paper · ICML 2025 · arXiv 2502.02732v3

Peri-LN:在子层两端各放一个归一化,让残差干道既通梯度又不积方差

Post-LN 把 LN 压在残差相加之后,方差稳了,梯度却要一层层穿过 LN;Pre-LN 把 LN 挪到模块输入,梯度通了,模块输出却直接堆进残差干道。 这篇论文把 Gemma、OLMo 等模型里已经出现的第三种做法命名为 Peri-LN:模块输入和输出都归一化。作者用方差递推和梯度上界解释它为什么有效,并在 400M / 1.5B / 3.2B、30B token、5 个种子上与 Post-LN、Pre-LN 对比。

Jeonghoon Kim 等 · NAVER Cloud · KAIST · NAVER AI Lab arXiv 2502.02732v3 ↗
TL;DR · 30 秒抓住核心

三种放置的差别只在 LN 放在子层的哪个位置,但它决定了残差干道是不是被归一化。Post-LN 把 LN 放在残差相加之后(Figure 2 的 C),主路径被压住,梯度却要穿过 LN。

Pre-LN 只归一化模块输入(A),残差干道没有 LN,梯度路径更直;代价是模块输出不经归一化就加进干道。§3.2 指出,初始化时 Pre-LN 的方差近似随深度线性增长,但训练开始后会指数上升;Figure 1 用 1.5B 模型追踪了这一点。

Peri-LN 在模块输入和输出各放一个 LN(A + B),即 yl = xl + Norm(Module(Norm(xl)))。如果归一化后的模块输出方差近似常数 β0,则 Var(xl+1) ≈ Var(xl) + β0(Eq. 4),方差增长从乘法变成加法。Proposition 3.1 进一步给出:对最后一层 MLP 权重,Pre-LN 的梯度范数正比于 ||h||,而 Peri-LN 的上界带一个阻尼因子 1/||a||(Eq. 8)。

Table 1 的 3.2B 模型平均分 58.56,Pre-LN 56.69,Post-LN 46.45;C4 evaluation loss 3.11,Pre-LN 3.20。论文没有做显著性检验,这些是 5 个训练种子下的均值与标准差所对应的点差。

58.56
3.2B 平均基准分
Pre-LN 56.69 / Post-LN 46.45
3.11
3.2B C4 evaluation loss
Pre-LN 3.20 / Post-LN 4.43
+1.87pp
3.2B 平均分相对 Pre-LN
58.56 − 56.69
01

Pre-LN 的残差干道越干净,巨量激活越容易一路带到最后一层

先建立问题:LN 放在哪里,决定了模块输出能不能污染残差干道;而这个问题在训练开始后才会暴露。

Transformer 的一个子层可以写成 yl = xl + Module(xl)。残差连接把 xl 原样送到下一层,Module 只负责在主干上加一个增量。LN 放在增量的哪一侧,决定了这个增量在汇入主干前是否被约束。

Post-LN

LN 在残差相加之后

yl = Norm(xl + Module(xl))(Eq. 1)。主路径上的每一步都被归一化,激活不会逐层放大。

代价是反向传播要穿过每一层的 LN。§3.1–3.2 说,深层模型里这会削弱梯度流,可能出现部分梯度消失和更慢的收敛。

Pre-LN

LN 只在模块输入

yl = xl + Module(Norm(xl))(Eq. 2)。残差主路径上没有 LN,梯度可以沿恒等路径直接回传。

代价是 Module(Norm(xl)) 没有归一化就加到 xl 上。模块输出一旦很大,就会沿着残差路径一路保留。

论文把后者和 Sun et al. (2024) 的 massive activations 联系起来:Pre-LN 的残差恒等路径没有归一化,大激活可以从浅层一直传到深层。§3.2 的原句是:

“Pre-LN normalizes xl before the module but leaves the module output unnormalized, allowing hidden-state variance to accumulate exponentially once parameter updates amplify the input.”

关键在“once parameter updates amplify the input”。初始化时,Pre-LN 的方差增长看起来只是随深度线性增加(Kedia et al., 2024,转引);但论文观察的是训练过程。Figure 1 用 1.5B 模型从初始化追到 6.3B token;§3.2 的文字结论是 Post-LN 的方差大致恒定,Pre-LN 在训练开始后指数上升。Figure 1 的 caption 则笼统写 “the growth in hidden-state variance for both Pre-LN and Post-LN architectures”,措辞比 §3.2 正文更宽泛。Peri-LN 的受控方差是 §3.3 引入 Output-LN 之后讨论的。

这不只是训练曲线好不好看。Figure 11 追踪 3.2B 模型的全局 top-100 绝对激活值:Pre-LN 在 0.5B token 左右就超过 FP16 可表示上限 65,504,而 Peri-LN 一直低于这条线。Appendix K 还提到,V100 不支持 BF16,这类溢出会直接变成数值问题。

本节结论

问题不是“要不要 LN”,而是“LN 要不要碰残差主路径”

Post-LN 让 LN 碰主路径,换来稳定方差,但梯度要穿过它;Pre-LN 让主路径保持干净,换来梯度通路,但模块输出可以不受约束地加进去。两条路都把同一个 trade-off 推到了极端。

02

Post-LN 管住方差但压住梯度,Pre-LN 放开梯度却放开方差

两条主流路线不是谁对谁错,而是把同一个 trade-off 推向了相反的两端;先看清各自卡在哪。

放置位置只有三个:A、B、C

Figure 2 把 LN 的可能位置拆成三个:A 在模块输入,B 在模块输出,C 在残差相加之后。三种策略的勾选表如下(转录自 Figure 2):

Figure 2(§3.1–3.3)的 A/B/C 勾选表(转录)
策略A · 模块输入B · 模块输出C · 残差相加之后
Post-LN××✓
Pre-LN✓××
Peri-LN✓✓×

这张表已经说明了三者的结构差异:Post-LN 只有 C,Pre-LN 只有 A,Peri-LN 同时有 A 和 B,但没有 C。也就是说,Peri-LN 保留了 Pre-LN 的干净主路径,同时在模块输出汇入残差之前加了一道约束。

梯度范数的排序,和分数排序并不一致

§4.4 和 Figure 5(a) 报告:在训练稳定的 run 里,final-layer gradient norm 满足 Post-LN > Pre-LN > Peri-LN。但 Table 1 的 benchmark 平均分排序是 Peri-LN > Pre-LN > Post-LN。两组排序方向相反。

论文没有把 final-layer gradient norm 当作排名指标;§5.2 更关心的是梯度在层间是否均匀:Figure 7 显示 Post-LN 在训练后期的低层梯度变小,Pre-LN 在初始化阶段反向传播时梯度变大,而 Peri-LN 在初始化和训练结束时都保持较均匀的逐层分布。推断(依据:§4.4 只报告排序,§5.2 才把“均匀”作为稳定性的解释;两处量的口径不同。)

共同盲区

两者都没有在“模块输出汇入残差之前”做约束

Post-LN 在汇入之后归一化,Pre-LN 在汇入之前只归一化输入。前者让主路径被 LN 覆盖,后者让未归一化的模块输出直接进入主路径。Peri-LN 选的是第三条:在汇入之前,对模块输出本身做归一化。

03

Peri-LN 把模块输出也归一化,方差从指数增长变成每层加一个常数

核心只有一行公式;真正要理解的是它为什么能把方差增长从乘法变成加法,以及梯度上界里的阻尼因子从哪来。

yl = xl + Norm( Module( Norm(xl) ) )
Eq. 3 · 输入侧沿用 Pre-LN 的 Norm(xl);输出侧新增的 Norm 是 Peri-LN 与 Pre-LN 的关键结构差别

与 Pre-LN 相比,Peri-LN 多了最外层的 Norm;与 Post-LN 相比,这个 Norm 没有放在残差相加之后,所以主路径仍然没有 LN。论文在 §3.3 里把这一步写成 Norm(Module(Norm(xl))),并指出如果这一项的方差近似常数 β0,就有:

Var(xl+1) ≈ Var(xl) + β0
Eq. 4 · 每层只加一个常数项;结果是线性或次指数增长,而不是 Pre-LN 的指数增长

这就是“外围归一化”的核心:它不改变残差主路径的结构,只在模块输出汇入主路径之前把增量的尺度固定住。主路径仍然可以直通梯度,但不会再被一个未归一化的大增量反复放大。

Proposition 3.1:Pre-LN 的梯度正比于 ||h||,Peri-LN 多了一个分母

论文考虑最后一层 MLP 的权重 W(2),令 h = ReLU(x̃W(1) + b(1))。两种策略的梯度行为分别是:

Pre-LNx̃ = Norm(x),a = MLP(x̃),o = x + a (Eq. 5)
梯度∂L(o)/∂W(2)i,j ∝ ||h|| (Eq. 6)
Peri-LNx̃ = Norm(x),a = MLP(x̃),ã = Norm(a),o = x + ã (Eq. 7)
梯度∂L(o)/∂W(2)i,j ≤ 4γ√D ||h|| / ||a|| (Eq. 8)
Eq. 5–8 · 论文分析的是最后一层 MLP 权重 W(2);Eq. 8 的阻尼来自对 a 的归一化
Pre-LN

梯度随 ||h|| 放大

模块输入先归一化,输出直接加回残差(Eq. 5)。梯度对最后一层 MLP 权重的范数正比于 ||h||(Eq. 6)。

当 massive activation 让 ||h|| 很大时,梯度范数可以随之爆炸,导致训练不稳定。

Peri-LN

梯度被 ||a|| 阻尼

模块输入和输出都归一化(Eq. 7)。梯度上界带一个 1/||a|| 的阻尼因子(Eq. 8)。

即使 ||h|| 很大,这个比值也能保持有界。论文称之为 self-regularizing gradient。

注意这个上界的范围:它只针对最后一层 MLP 权重 W(2) 的梯度,是局部上界,不是逐层或全局上界。§3.4 与 Appendix C 给了形式化陈述和证明,但论文没有给出端到端的全局收敛证明。这个边界在 §07 还会再提一次。

自己动手:切换三种放置,看 LN 到底碰不碰主路径

下图只画前向放置。点按钮切换策略,观察 A、B、C 三个位置哪些被启用,以及对应的方差行为和梯度通路。

残差恒等路径(没有 LN) x_l y_l Module Attention / MLP + Norm Norm Norm A · 输入 B · 输出 C · 相加后
A = 模块输入;B = 模块输出;C = 残差相加之后。位置与 Figure 2 的勾选表一致。
A · 模块输入
ON
B · 模块输出
—
C · 相加之后
—
当前放置:Pre-LN
Pre-LN 只在 A 放 LN。主路径没有 LN,模块输出不经归一化就加进残差;训练开始后方差会指数累积(§3.2, Figure 1)。
位置定义来自 Figure 2;A/B/C 的公式与方差/梯度讨论见 §3.1–3.3。
这个交互覆盖了什么,没覆盖什么?点开看分支对照

覆盖的分支:三个前向放置与 Figure 2 的勾选表一一对应——Post-LN 只有 C;Pre-LN 只有 A;Peri-LN 有 A 和 B。A/B/C 的位置定义逐字来自 Figure 2 与 §3.1–3.3 的公式。

没覆盖的分支:反向传播的具体路径、embedding/final LN、γ 的可学习性、Attention 与 MLP 两个子层的重复结构。图中的 Module 是二者的抽象;真实 block 里每个子层各有一套 A/B,见 §05 的结构图。

参数 → 结果(2 组):

  • Pre-LN → A 开、B 关、C 关 → 主路径无 LN;模块输出未归一化;方差在训练开始后指数增长(§3.2)。
  • Peri-LN → A 开、B 开、C 关 → 主路径无 LN;模块输出先归一化再汇入;若其方差近似 β0,方差每层加一个常数(Eq. 4)。

这个交互没有数值常量;判定来自 Figure 2 的勾选表和 §3.1–3.3 的公式,不是从表格读数。

04

训练配方没有为 Peri-LN 特调:30B token、5 个种子、标准 Megatron-LM

把实验条件摊开看:规模、数据、优化器和 SFT 都沿用 DCLM / Llama 3 的一套设置;论文没有报告 Peri-LN 的吞吐或显存开销。

模型规模是 400M、1.5B、3.2B(均不含 embedding 参数),每个规模训练 30B token,使用 5 个随机种子;序列长度 8192,数据是 DCLM-baseline,tokenizer 是 TikToken 的 cl100k base,架构主要跟随 Llama 3(SwiGLU MLP),归一化层主要用 RMSNorm,训练框架是 Megatron-LM(§4.1)。

Table 2(v3)转录:预训练通用配置
Global BatchWeight DecayIterationsOptimizerLR ScheduleWarmupWeight Init.
2560.03314400AdamCosine10%0.02
Table 4(v3)转录:模型配置(不含 embedding 参数)
Sizen_layersn_headsd_modeld_head
400M2481024128
1.5B24162048128
3.2B32162560160

学习率方面,§4.2 说 Pre-LN 在所有规模上的最佳学习率都是 2 × 10-3,因此 Pre-LN 和 Peri-LN 都用这个值;Post-LN 的合适学习率更低,Appendix E.1 单独做了搜索。SFT 用 LIMA 的 1,000 条样本,训练 15 个 epoch,batch size 128,Adam 初始学习率 1e-5,cosine schedule;checkpoint 按 OpenBookQA、CommonSenseQA 和 GLUE NLI 上的表现挑选(Appendix D.2)。

工程视角

多出来的是一次 Norm,但没有吞吐数字

从结构上看,Peri-LN 在每个子层多一次归一化:Pre-LN 每个子层一次,Peri-LN 是两次。论文没有报告这部分带来的吞吐、显存或 FLOPs 变化;Table 2 只给训练超参。能还原的是配置,不是耗时。推断(依据:全文没有吞吐/显存表格;§7.2 只讨论精度约束。)

05

一个 block 里,LN 把 Attention 和 MLP 各包了两圈

把 Eq. 3 落成结构:输入 embedding 可选归一化,每个子层的输入和输出各一次 LN,最后再归一化输出。

Token Embedding Norm(optional) Eq. 3 第 1 步 Peri-LN Block × N Attention + MLP Final Norm Eq. 3 第 3 步 LM Head 虚线框:Eq. 3 标为 optional;§5.3 的 γ 实验省略了它 Attention 子层 x_l Norm A Attention Norm B + 残差 中间状态 中间状态进入 MLP 子层 MLP 子层 x' Norm A MLP Norm B + 残差 x_{l+1}
图:Peri-LN 的整体流程(上)与单个 block 内部(下)。按 §3.3 Eq. 3 与 Figure 2 重绘。
覆盖:embedding/final LN 的位置、Attention 与 MLP 各自的输入/输出 LN、残差相加的位置。 未覆盖:反向传播路径、γ 的动态、QK-Norm;图中的 Module 是 Attention/MLP 的抽象。

这张图里有两个容易混淆的点。第一,Peri-LN 的残差主路径仍然没有 LN;它只是把每个子层的输出在加回残差之前归一化。第二,§3.3 的架构描述说 Peri-LN “further normalizes the input and final output embeddings”,Eq. 3 也在最后对 xL 做一次 Norm,但第 1 步(输入 embedding)标为 optional;§5.3 说,为了单独考察 output-LN 的作用,那个实验省略了 embedding LN。因此页面把输入侧画成 optional,而不把“Peri-LN 默认含 embedding LN”当成 Table 1 的设定。推断(依据:§3.3 的架构描述与 Eq. 3 的 optional 标注;§5.3 明说该实验省略 embedding LN。)

与 OLMo2-style 的 Peri-LN(含 QK-Norm)相比,论文在 Appendix H 里说两者整体表现可比,Peri-LN 在 400M 和 1B(原文正文;Appendix H 的 Figure 33 标的是 1.5B)规模上略有优势;但这条对比不是本文的主实验,Table 1 也不包含 QK-Norm 变体。

06

增益不大但方向一致:3.2B 平均分 +1.87 个百分点,C4 loss 低 0.09

先看 Table 1 的完整转录,再用交互切换三个规模;最后看两个反直觉的发现:梯度范数排序与分数排序相反,以及强 weight decay 也补不上差距。

Table 1(v3)完整转录:均值 ± 标准差,5 个训练种子;Loss 为 C4 evaluation loss;SFT Avg. 为指令微调后的平均分;发散的 checkpoint 不计入。
SizeArch.ARC-EasyHellaSwagPIQASIQAWinograndeAvg. ↑Loss ↓SFT Avg. ↑
400MPost-LN35.70 ±1.0928.91 ±0.1662.26 ±0.7334.48 ±1.0450.88 ±0.7542.457.4646.44
400MPre-LN54.87 ±1.6334.17 ±1.6668.79 ±1.3439.73 ±0.5950.88 ±2.3549.693.4349.96
400MPeri-LN57.51 ±0.8137.46 ±0.3469.48 ±0.3940.64 ±0.5152.74 ±0.6751.573.3451.96
1.5BPost-LN42.92 ±0.9331.69 ±0.4166.72 ±0.4035.84 ±0.6150.30 ±1.8745.495.3848.95
1.5BPre-LN61.51 ±1.2239.88 ±1.5371.41 ±0.8841.23 ±0.9754.51 ±2.0753.713.2953.89
1.5BPeri-LN66.17 ±0.2143.94 ±0.3473.63 ±0.2442.34 ±0.8356.64 ±0.4456.553.1856.94
3.2BPost-LN45.30 ±3.2333.59 ±0.4466.45 ±2.8635.82 ±1.0951.10 ±1.6046.454.4349.33
3.2BPre-LN65.24 ±2.3244.23 ±2.3273.86 ±1.1942.68 ±0.0757.42 ±2.5156.693.2057.08
3.2BPeri-LN68.73 ±0.5746.99 ±0.2174.31 ±0.4143.00 ±0.7359.76 ±0.7858.563.1159.02

交互:切换规模,看五个基准上的三路对比

Post-LN Pre-LN Peri-LN

柱高 = 基准分数(0–100),数字标注为原始分数;不显示标准差。

手算核对:Avg 列怎么来的2 组参数 → 结果

口径:Avg 是 5 个基准的等权平均,不是按样本数加权。标准差来自论文报告的 5 个训练种子;论文没有说明用 ÷N 还是 ÷(N−1),本页不重算标准差。

  • 3.2B Peri-LN:(68.73 + 46.99 + 74.31 + 43.00 + 59.76) / 5 = 292.79 / 5 ≈ 58.56(Table 1)。
  • 400M Peri-LN:(57.51 + 37.46 + 69.48 + 40.64 + 52.74) / 5 = 257.83 / 5 ≈ 51.57(Table 1)。

交互里的 15 个柱值逐字来自 Table 1;切换规模只改变数据集,不改变口径。

3.2B 上的三个点差

三个规模的方向一致:400M 是 51.57 / 49.69 / 42.45,1.5B 是 56.55 / 53.71 / 45.49,3.2B 是 58.56 / 56.69 / 46.45(Peri-LN / Pre-LN / Post-LN,Table 1)。论文在 §4.5 还报告,Peri-LN 的跨种子标准差“reduced by more than half”。这是笼统表述;按 5 个基准的跨种子标准差均值复算(Table 1,等权平均):400M 从 1.514 降到 0.544、1.5B 从 1.334 降到 0.412、3.2B 从 1.682 降到 0.540,即平均而言降低一半以上。但并非每个基准都减半,最明显的反例是 3.2B SIQA:Pre-LN ±0.07,Peri-LN ±0.73(Table 1);3.2B HellaSwag 则是 ±2.32 → ±0.21。这里的均值由 Table 1 报告的标准差复算,论文没有说明标准差用 ÷N 还是 ÷(N−1)。

反直觉一:梯度范数排序和分数排序相反

§4.4 的 Figure 5(a) 说,训练稳定时 final-layer gradient norm 的顺序是 Post-LN > Pre-LN > Peri-LN;Table 1 的分数顺序是 Peri-LN > Pre-LN > Post-LN。论文没有把这个梯度范数当作排名指标,而是在 §5.2 用 Figure 7 强调 Peri-LN 的逐层梯度分布更均匀。推断(依据:§4.4 只报告排序;§5.2 才把“层间均匀”作为稳定性的解释。两处量的口径不同,不能直接合并成“梯度越大越好/越差”。)

反直觉二:强 weight decay 能救 Pre-LN,但补不上差距

Table 7 是 400M 模型的 weight decay sweep。把系数从 0.033 加到 0.33(论文称 tenfold rise,§6.1;0.33 / 0.033 = 10),Pre-LN 的平均分从 49.01 升到 49.51,loss 从 3.03 降到 3;Peri-LN 同期从 50.68 升到 52.13,loss 从 2.93 降到 2.90。强 weight decay 能缓解 Pre-LN 的不稳定,但在同一设置下 Peri-LN 仍然更高。

Table 7(v3)转录:400M 模型,weight decay sweep;loss 越低越好,平均分越高越好
400MModelwd 0wd 0.0033wd 0.033wd 0.33
Final Training LossPre-LN3.033.033.033
Final Training LossPeri-LN2.942.942.932.90
Averaged Benchmark ScorePre-LN49.2649.1849.0149.51
Averaged Benchmark ScorePeri-LN51.4151.1450.6852.13

Table 8 和 Table 9 也支持同一方向。Table 8 是 400M 的 Xavier 初始化对比:Xavier 初始化把 Pre-LN 的平均分从 49.01 提到 51.25,把 Peri-LN 从 50.68 提到 52.04。Table 9 改变初始化方差:Peri-LN 的 final pre-training loss 在 2.902–3.027 之间,Pre-LN 在 10/d 时到达 4.526。这些结果说明,调 weight decay 或初始化也能改善 Pre-LN,但论文的实验设置下,Peri-LN 在同样的调参范围内仍然更高。

Table 8(v3)转录:400M 模型,Xavier 初始化 vs 基线(0.02)
400MArchitectureBaseline (0.02)Xavier Initialization
LossPre-LN3.032.95
Peri-LN2.932.91
Avg.Pre-LN49.0151.25
Peri-LN50.6852.04
Table 9(v3)转录:400M 模型,weight-initialization variance 对 final pre-training loss 的影响;越低越好
400MInitialization Variance10/dHe(2/d)LeCun(1/d)1/(10d)Baseline (0.02)
LossPre-LN4.5262.9653.0053.0123.035
Peri-LN3.0272.9292.9152.9022.916
07

它解决的是模块输出的方差累积,不是所有训练不稳定

论文的边界写在实验范围里:Decoder-only、最高 3.2B、30B token、主要用 RMSNorm;没有吞吐/推理开销实验。

边界一

残差主路径仍然没有 LN

§7.2 的原句是:“Both Pre-LN and Peri-LN architectures leave the main hidden state path unnormalized, so once large values arise in earlier layers, they persist through to later layers.” Peri-LN 阻止的是模块输出继续把方差加进主路径,不是清除主路径里已经存在的大值。如果问题主要来自残差状态本身,Peri-LN 不一定是足够的解。

边界二

规模和架构范围有限

实验覆盖 400M、1.5B、3.2B 三个 decoder-only 模型,30B token,DCLM-baseline,Llama 3 风格结构,主要用 RMSNorm。论文没有报告 Encoder-Decoder、ViT、多模态、MoE 或超过 3.2B 的实验;这些架构上的行为需要另行验证。

边界三

增益是点差,不是显著性结论

Table 1 报告的是 5 个训练种子的均值与标准差,论文没有做显著性检验,也没有给出置信区间。3.2B 平均分的差值是 +1.87 个百分点(58.56 − 56.69),C4 loss 差值是 0.09(3.20 − 3.11)。这些点差在三个规模上方向一致,但论文没有做显著性检验,不能读成统计显著。

边界四

额外 LN 的开销没有量化

Peri-LN 在每个子层多一次归一化,但论文没有报告吞吐、显存或 FLOPs 的对比。对训练吞吐敏感的场景,需要自己测这部分开销;不能从 Table 1 的分数直接推断“更划算”。推断(依据:全文没有吞吐/显存表格;§7.2 只讨论精度约束。)

边界五

Pre-LN 也能被 weight decay / 初始化稳定

Table 7 和 Table 8 显示,强 weight decay 或 Xavier 初始化都能改善 Pre-LN。Peri-LN 的优势是在这些调参范围内仍然更高,而不是“Pre-LN 无论怎么调都不行”。如果工程上已经有成熟的 Pre-LN 稳定配方,换架构的收益需要和改动成本一起算。

边界六

理论是局部的,不是端到端收敛证明

Proposition 3.1 给的是最后一层 MLP 权重梯度的上界,Appendix C 有形式化陈述与证明;论文没有给出整个训练过程的全局收敛保证。把它当成“Peri-LN 一定不会发散”的依据,会超出原文的范围。

一句话总结:Peri-LN 管的是“模块输出汇入残差之前”的那一步;它把 Pre-LN 的指数方差增长改成线性增长,但没有把残差主路径变成归一化路径,也没有承诺所有规模、所有架构都同样受益。