第 7 章 · RMSNorm

解释 RMSNorm 对隐藏向量做了什么,以及为什么 pre-norm(前置归一化)让深层 Transformer 变得可训练。

每一层都把注意力和 MLP 的输出加回同一条残差流——如果没有归一化,幅值会在 24 层中不断漂移,softmax 会饱和,训练随之崩溃。RMSNorm 的全部职责就是踩住刹车。

7 分钟
前向传播分词嵌入查表× 24 层最终 RMSNormLM head采样
术语表 · 8 个术语
RMSNorm
把 x 除以 sqrt(mean(x^2) + eps),再逐元素乘上可学习的增益 g。不减均值,也没有偏置项。
LayerNorm
它的前辈:先减去 mean(x),再除以标准差,同时带有增益和偏置。RMSNorm 去掉了减均值和偏置这两步。
pre-norm
一种架构选择:在每个子模块之前对残差流做归一化。残差流本身保持未归一化。
post-norm
2017 年原版 Transformer 的模式:先做残差相加,最后归一化。更容易解读,但深层训练困难得多。
variance / std
方差(variance)= 与均值的平方距离的平均值。标准差(std)= 方差的平方根。LayerNorm 除以标准差;RMSNorm 则把均值完全跳过。
L2 norm
向量各元素平方和的平方根。一个标准的幅值度量;RMSNorm 让每个 token 的 L2 落在 sqrt(hidden_dim) 附近。
learned gain (g)
RMSNorm 在除以 RMS 之后施加的逐特征缩放。归一化器携带的唯一可学习参数。
gradient path / identity path
训练信号在网络中反向传播所走的路线。残差高速公路是一条恒等路径(identity path),因为它把信号原样传过去(乘以 1),所以信号不会在多层传播中逐渐缩小到零(消失)。

RMSNorm:让激活值保持可控

一句话:Qwen3.5 的 24 层中,每一层都把注意力和 MLP 的输出加回同一条残差流——如果没有什么东西约束幅值,隐藏向量会一直增长,直到 softmax 饱和、梯度更新失去意义。RMSNorm 就是那个便宜、几乎无状态、负责踩刹车的小技巧。右侧图表展示了一个真实 prompt 的情况:残差流仍随深度爬升大约一个数量级(下方可见的那条线),但每个子模块的输入被 RMSNorm 按平在 √hidden_dim 附近(粉色线)。

在看公式之前,先感受一下刹车要解决的问题。“softmax 饱和”听起来很抽象——下面这个小部件把它变得具体。把一个 token 的幅值往上推,看看下游的 softmax 如何从一个分散的分布坍缩到单一选项上,对其余选项视而不见:

幅值一漂移,softmax 就饱和
同一份分数模式,只扫动整体幅值

六个固定分数(每个 token 一个)。它们的模式从不改变——变的只有整体幅值。把幅值拖高,下游的 softmax 就不再把注意力分散开,而是坍缩到单个 token 上。

32(logit 缩放 1.0×)
√1024 ≈ 32 · 信息充分漂移 · 饱和
信息充分——注意力是分散的top = 0.325
token A
0.325
token B
0.218
token C
0.161
token D
0.132
token E
0.098
token F
0.066

更大的激活幅值把每个分数按同一个倍数放大,使 softmax 尖锐地押在最大的那一个选项上、无视其余——分布饱和了。接近 one-hot 的分布几乎不携带其他选项相互比较的信息,流向它们的梯度也近乎消失。RMSNorm 把每个 token 的幅值钉在 √hidden_dim ≈ 32 附近(对 Qwen3.5-0.8B 来说是 √1024),让下游分布保持信息充分,而不是任由漂移把它压垮。

示意——这是对固定合成分数做的六选一 softmax 示意,不是模型的真实读数。它所预防的真正饱和发生在注意力分数里。softmax 本身是精确的:把分数放大确实会让它向 one-hot 锐化。

公式,只有两行

RMSNorm 把每个 token 的隐藏向量除以它的均方根(root-mean-square),再用可学习的逐特征增益 g 重新缩放:

用四个数亲手算一遍(ε 小到可以忽略,训练前 g = 1)。取 x = [2, −1, 3, 0]。逐项平方: x² = [4, 1, 9, 0]。求均值:(4 + 1 + 9 + 0) / 4 = 3.5。于是 RMS = √3.5 ≈ 1.87,相除得到 y ≈ [1.07, −0.53, 1.60, 0]。大的元素被压小,零仍是零,向量保持原来的形状——改变的只是大小。

这里的 ε(epsilon)是一个极小的常数,保证永远不会除以零;可学习增益 g 是归一化器携带的唯一参数——每个特征一个标量,长度等于 hidden_dim。先除以 RMS,让向量的平均平方幅值落在 1。正是这一步把向量的 L2 范数——L2 范数就是向量的长度,即各元素平方和的平方根——锚定在 √hidden_dim 附近:

  • 经过 RMSNorm 后,各元素平方的均值 ≈ 1;
  • 因此这 1024 个元素的平方和 ≈ 1024(这里 Σ 表示“对所有元素求和”,所以 Σx² ≈ 1024);
  • 因此向量长度 L2 = √(Σx²) ≈ √1024 = 32——“大约 32”就是这么来的。

然后让 g 按模型的需要给每个特征重新加权。初始时每个特征的 g = 1,所以训练前 RMSNorm 只是把幅值标准化;训练中模型学到哪些特征更重要,并把这些信息写进 g

可学习增益 γ——唯一被训练的参数

RMSNorm 唯一可学习的参数就是这个逐特征增益——每个特征一个标量(长度 1024,初始化为 1.0,没有偏置)。训练学会放大哪些特征、压低哪些特征。

逐特征增益(采样 48 个)学到的 γ
↑ 放大(γ > 1)↓ 抑制(γ < 1)
放大
26 个特征
抑制
22 个特征
最小 γ
0.39
最大 γ
1.84

有了可学习增益,每个特征都被独立地重新加权——本样本中 26 个被放大(γ > 1),22 个被抑制(γ < 1)。

示意——γ 是从 1024 个特征中合成采样的 48 个(围绕 1.0 的固定种子抽样),并非 Qwen3.5-0.8B 实际学到的增益。但形状——大多数特征接近 1,少数被明显放大或抑制——与真实归一化层一致。

和更早的 LayerNorm 摆在一起,简化之处一目了然:

# RMSNorm — what every modern LLM uses
y = x / sqrt(mean(x²) + ε) * g
                              ↑
                       single learned vector

# LayerNorm — what the 2017 transformer used
y = (x - mean(x)) / sqrt(var(x) + ε) * g + b
     ↑—————————                  ↑
   subtract mean first        plus learned bias

顺带解释 LayerNorm 那一行里的两个词,因为演示面板的统计框也会用到它们:var(x)——方差——是与均值的平方距离的平均值,而 std(标准差)是它的平方根。去掉减均值和偏置就是全部差别。Llama、Mistral、Qwen、DeepSeek——你能遇到的每个开源 LLM 都在用 RMSNorm;更简单的公式在质量上经验性地不相上下,运行起来还略快一些。

pre-norm 与 post-norm

下面的示意图展示了归一化在一层内部的位置。现代模型堆叠全都采用 pre-norm(前置归一化):残差高速公路保持未归一化,梯度因此能沿一条干净的恒等路径流过它。post-norm(后置归一化,2017 年的原版做法)把归一化放在残差高速公路——6 层没问题,24 层就很痛苦。

Post-norm(2017 年原版)
x残差attn / mlp+RMSNormx_out
归一化位于残差高速公路上。梯度在每一层都要多挤过一道归一化。6 层训练没问题;超过 20 层就很痛苦。
Pre-norm(Qwen3.5 与现代 LLM)
x残差(未归一化)RMSNormattn / mlp+x_out
归一化只作用于子模块的输入。残差高速公路保持未归一化——梯度沿干净的恒等路径流动。24 层以上依然稳定。

为什么 post-norm 在深层会变得痛苦?归一化不只重新缩放前向流动的激活值——它同样会重新缩放训练时反向流动的学习信号。在 post-norm 里,这个信号在 24 层中的每一层都要穿过一次归一化,24 次小的缩放会累乘成一次大的缩放。pre-norm 的恒等路径把这 24 次全部绕开。

演示展示了什么

L2/tok across layers(跨层 L2/tok)图表(演示面板顶部)是本章的点睛之笔——一条曲线持续上漂,一条曲线被按住不动。下方的单层明细让你抽查任意一层的统计量。底部的尺度不变性游乐场则是一个合成的 256 维向量,你可以把它拉伸 0.1×–10×,亲自确认输出幅值确实不依赖输入的尺度。

工程要点
  • RMSNorm 在下一个子模块读取输入之前,把输入幅值压到大约 sqrt(hidden_dim)——对 Qwen3.5-0.8B 来说约为 32。
  • pre-norm 让残差流保持未归一化,梯度因此能沿一条恒等路径流动;这正是 24 层堆叠能训得动的原因。
  • 去掉 LayerNorm 的减均值和偏置在质量上基本无损,计算上还略微更省——每个现代开源 LLM 都这么做。
动手练习

自动运行结束后,用 Layer 选择器在第 0 层和第 22 层之间来回切换。比较 "Input RMSNorm input" 与 "Input RMSNorm output" 的 L2/tok 数值。随着深度增加各自如何变化?哪一个大致保持不变?

随堂测验
1. 与更早的 LayerNorm 相比,RMSNorm 去掉了什么?
2. 为什么 pre-norm 是 20 层以上 Transformer 的标准选择?
3. 经过 RMSNorm 和可学习增益之后,一个 token 隐藏向量的 L2 大致落在什么量级?

动手试试

互动演示加载中……