Transformer 原理
GPT-3 175B 的配置表里有三个数字,第一次看很容易混在一起:
1 | 96 层 |
它们说的完全不是一回事:
- 96 层:文字要连续加工 96 轮。
- 96 个头:每一轮里,同时有 96 个「小组」从不同角度聚合信息。
- 12288:每个 Token 用 12288 个数字表示。
这一篇就沿着这三个数字,把注意力机制从头捋一遍。
1. Wq、Wk、Wv 是参数,Q、K、V 是临时结果
这是最容易混的一对概念,先分开:
| 是什么 | 什么时候存在 | |
|---|---|---|
| Wq、Wk、Wv | 可训练的权重矩阵 | 训练完就固化在模型里 |
| Q、K、V | 输入算出来的中间结果 | 每换一句话就重新算一遍 |
它们的关系是三条并行的全连接分支:
1 | ┌→ Q = X·Wq + bq |
至于 Q、K、V 各自代表什么,最省事的记法是三张「卡片」:
- Q,Query:我现在想找什么信息?
- K,Key:我身上有什么特征,可以被谁找到?
- V,Value:别人找到我以后,我实际能提供什么信息?
然后一句话概括整个过程:
用 Q 和所有 K 算出匹配程度,再按匹配程度对所有 V 加权求和。
注意最后那句的主语——加权求和的对象是 V,不是 K。 这一步错的人很多。
2. 走一遍完整流程:「苹果手机很好用」
把句子拆成三个 Token,每个词先有自己的初始向量:
1 | 苹果 → x0 |
现在站在「苹果」这个位置,任务是判断它是水果还是品牌。
第一步:算「苹果」的 Q
1 | q苹果 = x苹果 × Wq |
这个 Q 问的是:为了理解我现在的含义,我应该去找什么线索?
第二步:每个词都生成自己的 K,然后逐个匹配
1 | k苹果 = x苹果 × Wk |
K 就像是贴在每个词身上的标签:
1 | 苹果的 K:我可能是水果,也可能是品牌 |
拿「苹果」的 Q 去点乘每一个 K,得到原始相关度:
1 | q苹果 · k苹果 → 0.1 |
到这一步模型其实在表达:为了理解「苹果」,最该关注「手机」。
第三步:Softmax 之后,对 V 加权求和
每个词还会产生自己的 V:
1 | v苹果 = x苹果 × Wv |
V 才是这个词真正能提供给别人的信息。把上面那三个原始相关度过一遍 Softmax,变成加起来等于 1 的注意力权重,再对 V 加权求和:
1 | 苹果的新向量 |
新向量里混进了大量「手机」的信息,模型因此更容易判断:这里的「苹果」是品牌,不是水果。
这就是课件里说的信息聚合。
3. 它其实还是那个 z = wx + b
这一步能消掉很多神秘感。
神经网络的基本形式是:
1 | z = wx + b |
Q、K、V 的计算本质上还是它,唯一的区别是——输入不再是一个数字,而是一个很长的向量,所以 w 也从标量变成了矩阵:
1 | Q = X·Wq + bq |
换句话说:
Wq是一层全连接神经网络的权重Wk是另一层Wv又是另一层
写成一个极小的例子,矩阵里每个数都是要学的参数:
1 | Wq = [ |
这些参数一开始知道该干什么吗
不知道。训练刚开始时 Wq、Wk、Wv 基本都是随机值。
1 | 预测结果 → 计算损失 → 反向传播 → 梯度下降 |
反复很多轮之后,它们各自长出了分工:Wq 学着生成「查询信息」,Wk 学着生成「匹配标签」,Wv 学着提取「实际内容」。
所以这三组矩阵的功能不是程序员规定出来的,是数据训出来的。
4. 一层里做了什么:Attention + MLP
一个 GPT 式的 Transformer 层,其实只包含两件事:
1 | 输入 X |
拆成两句话:
- Attention:大家互相交换资料。
- MLP:每个人独立加工收到的资料。
交换和加工交替进行,才算完整的一层。
5. 为什么要堆 96 层
关键在一点:第二层接收到的不是最初的词向量,而是第一层的输出。
1 | 第 1 层:用自己的 Wq₁、Wk₁、Wv₁ → 注意力聚合 → X₁ |
每一层都保存着自己独立的一套矩阵,而且通常互不相同。
96 轮会议
拿这句话举例:
1 | 小明把书送给小红,因为她很喜欢这本书。 |
第一层之前,「她」只有初始向量。第一层聚合之后,「她」的向量里已经混进了一些「小红」的信息。
第二轮再开会时,「喜欢」就能和已经携带了「小红」信息的「她」交流,从而建立「小红喜欢书」的关系。
用一句话概括这个递进:
1 | 词与词的关系 → 短语关系 → 句子结构 → 指代关系 → 语义和逻辑关系 |
这只是帮助理解的直觉,并不表示官方规定「第 3 层学语法、第 40 层学逻辑」。不同的分工是模型在训练中自己形成的。
为什么一次 Attention 不够
换成这个例子更明显:
1 | 小王告诉小李,他的公司开发了一款产品, |
要理解「受欢迎」,得先把一串关系接起来:
1 | 受欢迎 |
单次 Attention 理论上可以让任意两个词直接交流,但一次交流很难完成这么多层的组合加工。多层的价值就在这里:
1 | 第一层建立简单关系 |
类比算术:
1 | 先算 a + b |
每一步都不复杂,串起来才能算复杂的东西。
6. 多头注意力:一层里的 96 个观察角度
先看一个头有什么局限。还是这句话:
1 | 小明把苹果手机送给小红,因为她很喜欢这款手机。 |
如果只有一个注意力头,站在「她」的位置,它只能生成一套权重:
1 | 小明 :0.10 |
这套权重主要在表达「她指的是小红」。但这句话里同时存在好几种关系:
- 「苹果」和「手机」组成产品名
- 「送给」的对象是「小红」
- 「她」指「小红」
- 「喜欢」的对象是「手机」
- 「因为」表示原因
一套权重装不下所有关系。
多头 = 96 个调查员同时读一句话
1 | 头 1:重点看「谁指代谁」 |
每个头有自己的一组参数:
1 | 头 1:Wq¹、Wk¹、Wv¹ |
于是同一个 Token 经过不同的头,会算出不同的 Q、K、V。同样地,「哪个头负责什么」是训练出来的,不是人工分配的。
96 个头各算各的,然后拼起来:
1 | ┌→ 头 1 → O₁ |
所以多头不是从多个答案里挑一个,而是:
把多个角度得到的信息全部保留下来,再融合成一个新向量。
多头不会把计算量乘以 96
这是最容易误算的一处。
如果每个头都拿完整的 12288 维去算,那确实会夸张到 96 倍。但实际做法是把总维度分给各个头:
1 | 12288 ÷ 96 = 128 维 |
每个头只处理 128 维:
1 | Q: [1300, 128] |
拼回去:
1 | 96 × 128 = 12288 |
又变回 [1300, 12288],可以继续交给 MLP 或者下一层。
所以多头的作用不是堆 96 倍算力,而是把同一个表示空间划分成 96 个不同的观察角度。总计算量和一个完整的 12288 维头基本相当。
一个小规模的例子:原始向量 8 维、2 个头,每个头处理 4 维。
1 | 头 1 输出:[0.2, 0.8, 0.1, 0.5] |
又变回 8 维,随后再经过 Wo 把不同头的信息充分混合。
7. 289 这个数字是怎么来的
回头补上开头那个数。
每个注意力头有三组投影矩阵:
1 | Wq:生成查询 Q |
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 只是举例的输入长度。
参考
- Attention Is All You Need(2017,原始 Transformer):https://arxiv.org/abs/1706.03762
- Language Models are Few-Shot Learners(GPT-3,配置见 Table 2.1):https://arxiv.org/abs/2005.14165
- GPT-2 论文(pre-normalization 出自这里):https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf
- The Illustrated Transformer(图解,适合配合看):https://jalammar.github.io/illustrated-transformer/
- 相关:LLM 请求与流式响应 —— https://wywzixin.github.io/agent/llm-request-streaming/
- ReAct 与 Agent Loop —— https://wywzixin.github.io/agent/react-agent-loop/
- 向量数据库:FAISS 与 Pinecone —— https://wywzixin.github.io/agent/vector-database/
Transformer 原理