从 Bit 到 AGI第五章:Transformer

LayerNorm

从 Bit 到 AGI · 第五章:Transformer · 层归一化如何稳定 768 维激活

作者 David更新于 第 71 篇(共 186 篇)

深层网络中,各层激活的均值和方差会漂移,下一层就要不断适应输入尺度——训练变慢、甚至发散。Layer Normalization(层归一化)在每个 token 的 dmodeld_{\text{model}} 维特征上做标准化,再乘可学习的缩放 γ\gamma、平移 β\beta,把激活拉回稳定区间。Transformer 选 LayerNorm 而非 BatchNorm,因为 NLP 的 batch 小、序列长,且要兼容变长句子。

直觉:每行单独标准化成绩

把每个 token 的 768 维向量看作一名学生的 768 科成绩。LayerNorm 对这一行算均值、方差,变成均值为 0、方差为 1,再按科目重要性(γ\gamma)微调。不同 token(不同行)互不影响;与 BatchNorm「按列、跨 batch 统计」相反。

定义

对单个 token 向量 x∈Rdmodel\mathbf{x} \in \mathbb{R}^{d_{\text{model}}}:

μ=1dmodel∑j=1dmodelxj,σ2=1dmodel∑j=1dmodel(xj−μ)2\mu = \frac{1}{d_{\text{model}}}\sum_{j=1}^{d_{\text{model}}} x_j, \quad \sigma^2 = \frac{1}{d_{\text{model}}}\sum_{j=1}^{d_{\text{model}}} (x_j - \mu)^2 LayerNorm(x)=γ⊙x−μσ2+ϵ+β\text{LayerNorm}(\mathbf{x}) = \gamma \odot \frac{\mathbf{x} - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta

γ,β∈Rdmodel\gamma, \beta \in \mathbb{R}^{d_{\text{model}}} 可学习;ϵ≈10−12\epsilon \approx 10^{-12} 防除零。对 batch 输入 X∈Rn×dmodel\mathbf{X} \in \mathbb{R}^{n \times d_{\text{model}}},在最后一维(768)上独立做 nn 次。

例子

例 1:BERT-base 参数量

每层 2 个 LayerNorm(Attention 后、FFN 后):

2×2×dmodel=4×768=3,072 参数/层2 \times 2 \times d_{\text{model}} = 4 \times 768 = 3{,}072 \text{ 参数/层}

12 层共 36,86436{,}864 参数——相对 attention 的百万级可忽略,但对训练稳定性至关重要。

例 2:数值前后

某 token 768 维,均值 μ=12.3\mu=12.3,标准差 σ=4.1\sigma=4.1。LayerNorm 后近似 μ′=0\mu'=0,σ′=1\sigma'=1(再经 γ,β\gamma, \beta 仿射)。

统计量Norm 前Norm 后(γ=1,β=0\gamma=1, \beta=0)
均值12.3≈0\approx 0
标准差4.1≈1\approx 1

量化

  • FLOPs / token / 层:约 5dmodel5 d_{\text{model}}(均值、方差、减、除、乘加);d=768d=768 时 ≈3.8×103\approx 3.8 \times 10^3,整句 n=512n=512 约 2×1062 \times 10^6 FLOPs
  • 与 BatchNorm 对比:
LayerNormBatchNorm
统计轴特征维 ddbatch × 序列
batch=1 推理正常需 running stats
NLP 变长序列自然需 padding 对齐

RMSNorm(LLaMA 等)去掉减均值,只做 RMS 缩放:x/RMS(x)⋅γ\mathbf{x} / \text{RMS}(\mathbf{x}) \cdot \gamma,略省计算,效果相当。本章以经典 LayerNorm 为准。

常见误区

  1. LayerNorm 在 batch 维归一化:错;在最后一维(hidden)归一化。
  2. γ\gamma 必须初始化为 1:惯例如此,配合 Pre-Norm 深度初始化策略。
  3. Norm 放在残差前还是后:Post-Norm(原论文)与 Pre-Norm(现代 LLM)行为不同,见专篇。

动手试一试

import torch
import torch.nn as nn

n, d_model = 128, 768
x = torch.randn(n, d_model) * 5 + 10  # 故意偏移尺度

ln = nn.LayerNorm(d_model)
y = ln(x)

print(y.mean(dim=-1).abs().max())   # ≈ 0
print(y.std(dim=-1).mean())         # ≈ 1
print(sum(p.numel() for p in ln.parameters()))  # 1536 = 768*2

小结

LayerNorm 对每个 token 的 768 维特征标准化,稳定 12 层堆叠的训练。Transformer 每层两次,参数量 2×768×22 \times 768 \times 2。下一篇讲另一个子层——FFN(前馈网络)。

下一篇:Feed Forward 层

本页目录