Skip to content
🔗 分享本题
查看我的学习进度 →

LayerNorm 与 RMSNorm 对比动漫知识图:LayerNorm 先减均值中心化再按方差归一化并缩放平移,RMSNorm 不做中心化,只按均方根归一化并缩放

🧠 图解记忆:LayerNorm 先中心化再缩放,RMSNorm 只按均方根缩放;点击图片可查看原图。

LayerNorm = 对每个样本的每个位置,沿特征维度做标准化;RMSNorm 是其简化版,去掉了均值中心化,只保留归一化。

两者的计算公式对比

LayerNorm(x):
  μ = mean(x, dim=-1)          # 计算均值
  σ² = var(x, dim=-1)          # 计算方差
  x̂ = (x - μ) / √(σ² + ε)     # 标准化
  output = γ * x̂ + β           # 可学习的缩放+平移

RMSNorm(x):
  r = RMS(x) = √(mean(x²) + ε) # 均方根(不含均值中心)
  x̂ = x / r                    # 归一化
  output = γ * x̂               # 只有缩放(没有β偏置)

关键区别

维度LayerNormRMSNorm
均值中心化✅ 减去均值❌ 不减
参数数量2个/层(γ + β)1个/层(仅 γ)
计算量稍大(多一次均值计算)更小
效果几乎相同基本等价甚至略好
使用现状GPT-2, BERTLLaMA, Qwen, DeepSeek, Claude

为什么 RMSNorm 更流行?

  1. 计算更快:省掉均值计算,推理时 Faster
  2. 参数更少:少一半参数(没有 β),减少过拟合风险
  3. 数值稳定性足够:对大多数架构,去均值带来的收益极小
  4. 实验验证:LLaMA 论文实证发现两者效果几乎一致,RMSNorm 略胜
python
# RMSNorm 简洁实现
import torch.nn as nn

class RMSNorm(nn.Module):
    def __init__(self, dim, eps=1e-6):
        super().__init__()
        self.eps = eps
        self.weight = nn.Parameter(torch.ones(dim))

    def forward(self, x):
        # x: [batch, seq, hidden]
        rms = torch.rsqrt(torch.mean(x ** 2, dim=-1, keepdim=True) + self.eps)
        return self.weight * x * rms  # γ * (x / RMS(x))

面试加分点

  • 有些模型采用 混合方案:Attention 层用 RMSNorm,FFN 层用 LayerNorm(如部分 Qwen 变体)
  • SwiGLU 激活函数常与 RMSNorm 一起出现,组成现代 Transformer Block 的标准配置:x -> RMSNorm -> SwiGLU(FFN) -> Residual

面试话术:

"LayerNorm 和 RMSNorm 的核心区别是:LayerNorm 做了均值中心化+方差归一化,RMSNorm 只做 RMS 归一化。实践证明两者效果几乎一样,但 RMSNorm 少算了一步均值、少一半参数,所以现在的主流模型(LLaMA/Qwen/DeepSeek)都切到了 RMSNorm。我在本地跑 llama.cpp 的时候也能感受到微妙的速度提升。"