Transformer 原理

GPT-3 175B 的配置表里有三个数字,第一次看很容易混在一起:

1
2
3
96 层
12288 隐藏维度
96 个注意力头

它们说的完全不是一回事:

  • 96 层:文字要连续加工 96 轮。
  • 96 个头:每一轮里,同时有 96 个「小组」从不同角度聚合信息。
  • 12288:每个 Token 用 12288 个数字表示。

这一篇就沿着这三个数字,把注意力机制从头捋一遍。

1. Wq、Wk、Wv 是参数,Q、K、V 是临时结果

这是最容易混的一对概念,先分开:

是什么 什么时候存在
Wq、Wk、Wv 可训练的权重矩阵 训练完就固化在模型里
Q、K、V 输入算出来的中间结果 每换一句话就重新算一遍

它们的关系是三条并行的全连接分支:

1
2
3
┌→ Q = X·Wq + bq
输入向量 X ─────────┼→ K = X·Wk + bk
└→ V = X·Wv + bv

至于 Q、K、V 各自代表什么,最省事的记法是三张「卡片」:

  • Q,Query:我现在想找什么信息?
  • K,Key:我身上有什么特征,可以被谁找到?
  • V,Value:别人找到我以后,我实际能提供什么信息?

然后一句话概括整个过程:

用 Q 和所有 K 算出匹配程度,再按匹配程度对所有 V 加权求和。

注意最后那句的主语——加权求和的对象是 V,不是 K。 这一步错的人很多。

2. 走一遍完整流程:「苹果手机很好用」

把句子拆成三个 Token,每个词先有自己的初始向量:

1
2
3
苹果   → x0
手机 → x1
很好用 → x2

现在站在「苹果」这个位置,任务是判断它是水果还是品牌。

第一步:算「苹果」的 Q

1
q苹果 = x苹果 × Wq

这个 Q 问的是:为了理解我现在的含义,我应该去找什么线索?

第二步:每个词都生成自己的 K,然后逐个匹配

1
2
3
k苹果   = x苹果 × Wk
k手机 = x手机 × Wk
k很好用 = x很好用 × Wk

K 就像是贴在每个词身上的标签:

1
2
3
苹果的 K:我可能是水果,也可能是品牌
手机的 K:我属于电子产品
很好用的 K:这是对产品的评价

拿「苹果」的 Q 去点乘每一个 K,得到原始相关度:

1
2
3
q苹果 · k苹果   → 0.1
q苹果 · k手机 → 0.7
q苹果 · k很好用 → 0.2

到这一步模型其实在表达:为了理解「苹果」,最该关注「手机」。

第三步:Softmax 之后,对 V 加权求和

每个词还会产生自己的 V:

1
2
3
v苹果   = x苹果 × Wv
v手机 = x手机 × Wv
v很好用 = x很好用 × Wv

V 才是这个词真正能提供给别人的信息。把上面那三个原始相关度过一遍 Softmax,变成加起来等于 1 的注意力权重,再对 V 加权求和:

1
2
3
4
苹果的新向量
= 0.1 × v苹果
+ 0.7 × v手机
+ 0.2 × v很好用

新向量里混进了大量「手机」的信息,模型因此更容易判断:这里的「苹果」是品牌,不是水果。

这就是课件里说的信息聚合。

3. 它其实还是那个 z = wx + b

这一步能消掉很多神秘感。

神经网络的基本形式是:

1
z = wx + b

Q、K、V 的计算本质上还是它,唯一的区别是——输入不再是一个数字,而是一个很长的向量,所以 w 也从标量变成了矩阵:

1
2
3
Q = X·Wq + bq
K = X·Wk + bk
V = X·Wv + bv

换句话说:

  • Wq 是一层全连接神经网络的权重
  • Wk 是另一层
  • Wv 又是另一层

写成一个极小的例子,矩阵里每个数都是要学的参数:

1
2
3
4
Wq = [
[ 0.2, 0.5],
[ 0.8, -0.1]
]

这些参数一开始知道该干什么吗

不知道。训练刚开始时 Wq、Wk、Wv 基本都是随机值。

1
预测结果 → 计算损失 → 反向传播 → 梯度下降

反复很多轮之后,它们各自长出了分工:Wq 学着生成「查询信息」,Wk 学着生成「匹配标签」,Wv 学着提取「实际内容」。

所以这三组矩阵的功能不是程序员规定出来的,是数据训出来的。

4. 一层里做了什么:Attention + MLP

一个 GPT 式的 Transformer 层,其实只包含两件事:

1
2
3
4
5
6
7
8
9
10
11
12
13
输入 X
↓
多头自注意力 Attention
不同 Token 之间交换信息
↓
残差连接、归一化
↓
前馈网络 MLP
每个 Token 单独加工刚收到的信息
↓
残差连接、归一化
↓
输出给下一层

拆成两句话:

  1. Attention:大家互相交换资料。
  2. MLP:每个人独立加工收到的资料。

交换和加工交替进行,才算完整的一层。

5. 为什么要堆 96 层

关键在一点:第二层接收到的不是最初的词向量,而是第一层的输出。

1
2
3
4
5
第 1 层:用自己的 Wq₁、Wk₁、Wv₁ → 注意力聚合 → X₁
第 2 层:用自己的 Wq₂、Wk₂、Wv₂ → 注意力聚合 → X₂
第 3 层:用自己的 Wq₃、Wk₃、Wv₃ → X₃
……
第 96 层 → X₉₆

每一层都保存着自己独立的一套矩阵,而且通常互不相同。

96 轮会议

拿这句话举例:

1
小明把书送给小红,因为她很喜欢这本书。

第一层之前,「她」只有初始向量。第一层聚合之后,「她」的向量里已经混进了一些「小红」的信息。

第二轮再开会时,「喜欢」就能和已经携带了「小红」信息的「她」交流,从而建立「小红喜欢书」的关系。

用一句话概括这个递进:

1
词与词的关系 → 短语关系 → 句子结构 → 指代关系 → 语义和逻辑关系

这只是帮助理解的直觉,并不表示官方规定「第 3 层学语法、第 40 层学逻辑」。不同的分工是模型在训练中自己形成的。

为什么一次 Attention 不够

换成这个例子更明显:

1
2
小王告诉小李,他的公司开发了一款产品,
这款产品因为价格便宜而非常受欢迎。

要理解「受欢迎」,得先把一串关系接起来:

1
2
3
4
5
6
受欢迎
↑ 因为价格便宜
↑ 价格属于这款产品
↑ 这款产品由公司开发
↑ 公司可能属于「他」
↑ 「他」指谁还得结合上下文

单次 Attention 理论上可以让任意两个词直接交流,但一次交流很难完成这么多层的组合加工。多层的价值就在这里:

1
2
3
4
第一层建立简单关系
第二层把简单关系组合起来
第三层再组合前面的结果
……

类比算术:

1
2
3
先算 a + b
再算 (a + b) × c
再算 ((a + b) × c) - d

每一步都不复杂,串起来才能算复杂的东西。

6. 多头注意力:一层里的 96 个观察角度

先看一个头有什么局限。还是这句话:

1
小明把苹果手机送给小红,因为她很喜欢这款手机。

如果只有一个注意力头,站在「她」的位置,它只能生成一套权重:

1
2
3
4
5
小明  :0.10
苹果 :0.05
手机 :0.15
小红 :0.60
喜欢 :0.10

这套权重主要在表达「她指的是小红」。但这句话里同时存在好几种关系:

  • 「苹果」和「手机」组成产品名
  • 「送给」的对象是「小红」
  • 「她」指「小红」
  • 「喜欢」的对象是「手机」
  • 「因为」表示原因

一套权重装不下所有关系。

多头 = 96 个调查员同时读一句话

1
2
3
4
5
头 1:重点看「谁指代谁」
头 2:重点看「动作和对象」
头 3:重点看「修饰关系」
头 4:重点看「原因和结果」
……

每个头有自己的一组参数:

1
2
3
4
头 1:Wq¹、Wk¹、Wv¹
头 2:Wq²、Wk²、Wv²
头 3:Wq³、Wk³、Wv³
……

于是同一个 Token 经过不同的头,会算出不同的 Q、K、V。同样地,「哪个头负责什么」是训练出来的,不是人工分配的。

96 个头各算各的,然后拼起来:

1
2
3
4
5
6
┌→ 头 1 → O₁
输入 X ─────────┼→ 头 2 → O₂
├→ 头 3 → O₃
└→ ……

O₁ + O₂ + O₃ + …… → 拼接 → 经过 Wo 融合 → 输出

所以多头不是从多个答案里挑一个,而是:

把多个角度得到的信息全部保留下来,再融合成一个新向量。

多头不会把计算量乘以 96

这是最容易误算的一处。

如果每个头都拿完整的 12288 维去算,那确实会夸张到 96 倍。但实际做法是把总维度分给各个头:

1
12288 ÷ 96 = 128 维

每个头只处理 128 维:

1
2
3
4
Q: [1300, 128]
K: [1300, 128]
V: [1300, 128]
O: [1300, 128]

拼回去:

1
96 × 128 = 12288

又变回 [1300, 12288],可以继续交给 MLP 或者下一层。

所以多头的作用不是堆 96 倍算力,而是把同一个表示空间划分成 96 个不同的观察角度。总计算量和一个完整的 12288 维头基本相当。

一个小规模的例子:原始向量 8 维、2 个头,每个头处理 4 维。

1
2
3
4
头 1 输出:[0.2, 0.8, 0.1, 0.5]
头 2 输出:[0.7, 0.3, 0.9, 0.4]

拼接后: [0.2, 0.8, 0.1, 0.5, 0.7, 0.3, 0.9, 0.4]

又变回 8 维,随后再经过 Wo 把不同头的信息充分混合。

7. 289 这个数字是怎么来的

回头补上开头那个数。

每个注意力头有三组投影矩阵:

1
2
3
Wq:生成查询 Q
Wk:生成键 K
Wv:生成值 V

96 个头:

1
96 × 3 = 288 组

所有头的结果拼接之后,再经过一个公共的融合矩阵:

1
288 + 1(Wo)= 289

这个数算得对,但叫它「289 个神经网络」不准确。更准确的说法是:

289 组线性变换矩阵,前 288 组属于 96 个注意力头,最后 1 个 Wo 负责融合。

还要注意这个 289 只统计了注意力部分——MLP 里的矩阵、以及所有归一化层的参数都没算进去。

8. 几处需要再精确一点的地方

一、少了一个 √d

完整的注意力公式是:

1
Attention(Q, K, V) = softmax(QKᵀ / √d_k) · V

前面「Q 和 K 算匹配程度 → Softmax」之间省略了除以 √d_k 这一步。d_k 是每个头的维度,GPT-3 里是 128,所以除的是 √128 ≈ 11.3。

为什么必须除:Q 和 K 的每一维如果都近似独立随机,点积的方差会随维度线性增长。128 维点积出来的数值会很大,Softmax 在这种输入下会变得极其尖锐——几乎退化成 one-hot,梯度趋近于 0,训练就推不动了。除以 √d_k 的作用是把方差拉回 1 附近。

二、归一化的位置和原始论文不一样

上面画的流程是「先加残差、再归一化」,这是 2017 年原始 Transformer 的做法(Post-LN):

1
Post-LN:LayerNorm(x + Sublayer(x))

GPT-2 把它改成了先归一化再进子层,GPT-3 沿用(GPT-3 论文里写的是 pre-normalization):

1
Pre-LN:x + Sublayer(LayerNorm(x))

顺带还有两个改动:GPT-2 在最后一层之后额外加了一个 LayerNorm;残差分支的权重按 1/√N(N 是残差层数)缩放初始化——堆到 96 层的时候,这一步对训练稳定性相当关键。

三、1300 不是 GPT-3 的固定值

96 层、12288 维、96 头这三个数确实是 GPT-3 175B 的真实配置(论文 Table 2.1)。但课件里的 1300 只是举例用的输入长度,不是模型参数。GPT-3 的上下文窗口是 2048 个 Token。

9. 小结

一、Wq、Wk、Wv 是参数,Q、K、V 是临时结果。 参数训练完就固化在模型里,QKV 每换一句话重算一遍。

二、注意力干的事一句话说完: 用 Q 和所有 K 算匹配程度,Softmax 归一化成权重,再对 V 加权求和。加权的是 V,不是 K。

三、它没有脱离 z = wx + b。 只是输入从标量变成了向量,w 变成了矩阵,所以 Wq、Wk、Wv 就是三层并行的全连接。它们的分工不是设计出来的,是训出来的。

四、一层做两件事:Attention 交换信息,MLP 单独加工。

五、96 层是 96 轮加工,不是把原句重复算 96 遍。 每层都有自己的 Wq、Wk、Wv,接收的是上一层的输出。

六、多头不是多层。 多层增加理解的深度,多头增加同一层观察问题的角度。96 个头是把 12288 维拆成 96 份各 128 维并行计算,不是 96 倍计算量。

七、课件里那几个数都能对上。 96 层、12288 维、96 头、每头 128 维,都是 GPT-3 175B 的真实配置;1300 只是举例的输入长度。

参考

作者

wangyawei

发布于

2026-09-15

更新于

2026-09-15

许可协议