Transformer 架构
2017 年 Google 一篇《Attention Is All You Need》,彻底改变了 AI 的发展轨迹。七年后的今天,你用的 ChatGPT、Claude、DeepSeek、文心一言,底层全部基于 Transformer。这篇文章从正面和侧面两个维度,把 Transformer 说透。
一、Transformer 架构的正面
(一)Transformer 架构兼顾了宏大和细腻
在 Transformer 之前,处理序列数据的主力是 RNN、LSTM 和 CNN。它们各有各的局限,而 Transformer 的出现,把这些问题一次性解决了。
RNN --- 串行的"传话者"
RNN 的工作方式:
输入: "我 爱 北京 天安门"
│ │ │ │
▼ ▼ ▼ ▼
[h1]→[h2]→[h3]→[h4] → 输出
只能一个词一个词地读,后面的词必须等前面的算完。
致命缺陷:
① 无法并行 --- 必须按顺序,GPU 的并行能力完全浪费
② 梯度消失 --- 序列超过 50 步,靠前的信息几乎传不到后面
"我出生在...(200 个字后)...我的家乡很美" → 模型忘了"我"是谁
LSTM --- 给 RNN 装了"选择性记忆"
LSTM 的改进:
加了三个门(遗忘门、输入门、输出门),让网络自己决定记住什么、忘掉什么。
遗忘门:旧信息哪些该扔了?
输入门:新信息哪些值得记?
输出门:现在该输出什么?
进步:序列长度扩展到 ~200 步
局限:仍然是串行,200 步以上照样忘
CNN --- 并行了,但视野短
CNN 用卷积核一次看相邻的几个词:
"我 爱 北京 天安门"
└─┬─┘ ← 卷积核大小 2,只能看两个词
① 可以并行 → 快!
② 视野 = 卷积核大小 → 远距离的两个词"我"和"天安门"没法直接建立联系
③ 堆叠多层才能扩大感受野 → 效率低
Transformer --- 一举解决所有问题
| RNN/LSTM | CNN | Transformer | |
|---|---|---|---|
| 并行计算 | ❌ 串行 | ✅ 并行 | ✅ 完全并行 |
| 长距离依赖 | ❌ 梯度消失 | ⚠️ 需堆叠多层 | ✅ 一步到位 |
| 全局视野 | ⚠️ 有衰减 | ❌ 感受野有限 | ✅ 每个词都能看所有词 |
| 训练速度 | 慢 | 中 | 快 |
Transformer 怎么做到了"兼顾宏大和细腻"?
宏大 --- 注意力机制让每个词都能直接和所有其他词交互,全局视野
→ 第 1 个词和第 1000 个词的距离,和相邻词一样近
细腻 --- 多头注意力从多个不同的侧面理解语义
→ "苹果"在吃的一面(食物),在买的一面(产品),在科技的一面(公司)
→ 多个头各自捕获不同层面的关系
(二)Transformer 注意力机制
1. 注意力机制是什么
本质就是:给每个东西打一个重要性分数。
你要找"昨天和谁一起吃饭",你自己就是查询(Query)。
你脑子里想"昨天的事",然后在记忆中扫描:
上班 --- 不重要(分数低)
午饭 --- 很重要(分数高!)→ 张三也在!
下班 --- 不重要
你的大脑自动给每段记忆分配了"注意力权重",
权重高的被放大,权重低的被忽略。
数学表达:
Attention(Q, K, V) = softmax(Q · K^T / √d_k) · V
Q (Query) = 我想查什么?
K (Key) = 每个元素的"索引"
V (Value) = 每个元素的"内容"
三步:
① Q 和所有 K 做点积 → 相似度分数
② 除以 √d_k(防止值太大)→ softmax 转成概率
③ 用概率加权 V → 输出 = 相关内容的高亮总结
2. 自注意力机制是什么
Q、K、V 都来自同一句话,这就叫 Self-Attention(自注意力)。
句子:"小明说他很累"
普通 Attention: 用问题去查文档(Q ≠ 文档)
Self-Attention: 句子用自己去查自己(Q = K = V = 这句话)
效果:每个词都和其他所有词算一遍关系
"累" → 和"小明"关系强(谁累?)
"累" → 和"很"关系也强(有多累?)
"他" → 和"小明"关系最强("他"指的是小明!)
这一步解决的核心问题:
传统 RNN 读"他"时,只能通过隐状态间接知道"他 = 小明"
Self-Attention 读"他"时,直接和"小明"做了注意力计算 → 关系明确
3. 自注意力机制的核心原理
输入:"我 爱 北京"
│
▼ 乘以 W_Q 矩阵 → Q(查询向量)
▼ 乘以 W_K 矩阵 → K(键向量)
▼ 乘以 W_V 矩阵 → V(值向量)
对于"我爱北京",计算"我"的输出:
Score = Q_我 · K_我、Q_我 · K_爱、Q_我 · K_北京
= [0.8, 0.3, 0.1]
softmax → [0.65, 0.25, 0.10]
Output = 0.65 × V_我 + 0.25 × V_爱 + 0.10 × V_北京
关键发现:
"我"的最终表示 = 65% 的自己 + 25% 的"爱" + 10% 的"北京"
→ "我"不再是孤立的词,而是融合了整个句子上下文的"我"
为什么叫"自"注意力?
Q、K、V 全部来自同一句话。一句话里的每个词,
都在"问"整句话的其他词 ------ 谁和我有关系?关系有多强?
结果就是:每个词都不是孤立的,而是带着整句上下文的融合体。
4. 多头注意力机制
单头的局限:
一个注意力只能关注一种关系(语法?语义?指代?)
就像看一个人,只能从一个角度看
多头的做法:
并行做 8 次注意力计算(8 个头),每个头有自己的 W_Q、W_K、W_V
每个头学到不同的东西:
头 1 → "它"指代"猫"
头 2 → "猫"是主语,"吃"是谓语
头 3 → "猫"和"鱼"是被吃的关系
头 4 → "黑色的"修饰"猫"
...
8 个头各输出一个向量 → 拼在一起 → 乘以一个 W_O → 最终输出
这就是 BERT 论文里著名的可视化图:
某个头专门关注"下一个词"
某个头专门关注"动词和宾语的关系"
某个头专门关注"修饰词和被修饰词"
某个头专门关注"两个相距很远的词之间的指代"
多个头 = 从多个侧面理解同一句话 = 兼顾了宏大和细腻
5. 位置编码
Self-Attention 有一个致命缺陷:
它对每个词都是平等的,"我爱你"和"你爱我",算出来一样!
原因:Attention(Q,K,V) 里只有内容的相似度,没有位置信息。
位置编码的作用:给每个词注入一个"我是第几个"的信号。
原始论文的方法(正弦余弦编码):
PE(pos, 2i) = sin(pos / 10000^(2i/d))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d))
pos = 词的位置,i = 向量的维度索引
特性:
① 每个位置的编码是唯一的
② 两个位置的编码之间的距离可以反映它们的相对距离
③ 不需要学习(固定的数学公式)
④ 可以外推到比训练时更长的序列
现代变体:
- 可学习的位置编码(BERT 用这个)
- RoPE(旋转位置编码)--- 在复数空间中旋转向量,更自然
几乎所有 2024-2025 的大模型都用 RoPE
- ALiBi(线性偏置)--- 不需要位置编码,直接给 Attention 加偏置
二、Transformer 架构的侧面
(一)Transformer 架构的继承和集成
Transformer 不是凭空产生的,它继承了两个重要计算范式。
1. 什么是概率性计算?
概率性计算 = 输出的是一个"概率分布",不是精确值。
Transformer 的 Softmax 就是概率性计算:
Q · K 的点积 → [2.0, 1.5, 0.5]
Softmax → [0.57, 0.34, 0.09]
含义:
模型不是"肯定"某个词最重要,而是"57% 的概率认为第一个词最重要"。
这种"模糊"恰恰是语言理解的优势 --- 语言本身就是模糊的。
概率性计算的好处:
① 允许不确定性 → "打"可以是"打篮球"也可以是"打电话"
② 梯度可导 → 反向传播时必须用概率,不能用硬选择
③ 多模态输出 → 可以给出 Top-N 最可能的结果
2. 什么是确定性计算?
确定性计算 = 同样的输入一定得到同样的输出。
Transformer 里的确定性计算:
① 矩阵乘法(Q·K^T)--- 输入确定,输出就确定
② 层归一化(Layer Normalization)--- 确定的数学公式
③ 残差连接(Residual Connection)--- 确定的加法
④ 前馈网络(Feed Forward)--- 确定的矩阵运算
两者的关系:
Transformer = 确定性计算(矩阵运算)拍出来原始分数
+ 概率性计算(Softmax)把分数变成概率
确定性做"计算"(算相似度),概率性做"选择"(加权求和)。
两者配合:
确定性给了模型可解释的底层
概率性给了模型处理语言模糊性的能力
(二)反向传播机制
反向传播是 Transformer 的"老师",告诉模型"你哪里错了,往哪个方向改"。
工作流程:
前向传播 → 输入 → 一层层算 → 输出 → 和正确答案对比 → 算 Loss
反向传播 → 从 Loss 出发 → 链式法则一层层传回梯度 → 更新参数
Transformer 能反向传播的关键:
Self-Attention 全部是矩阵乘法 + Softmax → 全程可导
和 RNN 不一样,RNN 的反向传播要沿时间展开,计算量大且容易梯度消失
为什么 Transformer 反向传播特别稳定?
RNN:梯度要沿时间步一层层往回传,步数多了梯度趋近于 0
Transformer:梯度只需在层之间传(6 层、12 层、24 层...)
每层内部的 Attention 是并行计算的
没有"时间步"这个维度 → 梯度消失比 RNN 轻得多
这也是 Transformer 能堆 100 层而 RNN 只能堆几层的根本原因
(三)神经网络
Transformer 的每一层包含两个核心子层,都是神经网络:
子层一:多头自注意力(Multi-Head Self-Attention)
→ 让每个词融合上下文中其他词的信息
子层二:前馈网络(Feed-Forward Network)
→ 对每个词独立做非线性变换
→ 两层的全连接网络,中间用 ReLU/GELU 激活
FFN(x) = W_2 · GELU(W_1 · x + b_1) + b_2
为什么需要 FFN?
注意力只负责"看别人",FFN 负责"想自己"。
打个比方:
注意力 = 开会,听所有人发言,把大家的信息融合起来
FFN = 会后自己思考消化,形成自己的理解和观点
Transformer 一层 = 开一次会(Attention)+ 自己想一想(FFN)
Transformer 24 层 = 开了 24 次会,想了 24 次
(四)掩码机制
两种掩码,各自解决不同问题:
① Padding Mask(填充掩码)
问题:句子不一样长怎么办?
"我上学" → 3 个词
"我今天去学校上学" → 7 个词
补到一样长:"我上学[PAD][PAD][PAD][PAD]"
→ Padding Mask 让 Attention 完全忽略 [PAD],不给它任何权重
② Look-Ahead Mask(自注意掩码 /因果掩码 / 上三角掩码)
问题:GPT 在生成文本时,不能偷看后面的词!
第 1 步生成"我"时,序列是:已生成(空)
第 2 步生成"爱"时,序列是:已生成("我") ← 只能看到"我"
第 3 步生成"北京"时,序列是:已生成("我爱") ← 只能看到"我爱"
方法:把注意力矩阵的上三角(未来位置)全部掩码为 -∞
softmax(-∞) = 0 → 对未来的注意力权重为 0
Encoder(BERT)不需要这个掩码,可以双向看
Decoder(GPT)必须用这个掩码,保证自回归生成
(五)残差连接
问题是:网络越深,越难训练。
14 层的 Transformer → 梯度在 LayerNorm 和 Attention 之间丢失
→ 浅层参数几乎不更新
残差连接的解决:
Output = LayerNorm(x + Sublayer(x))
不是"算一个新的替代旧的",而是"算一个新的,叠在旧的上面"
→ 梯度可以通过残差通道直接传到浅层
→ 哪怕 Sublayer 部分的梯度消失了,x 的梯度还在
效果:
① 训练更快 --- 梯度有"高速公路"直达浅层
② 能堆更多层 --- 不怕梯度消失
③ 信息更完整 --- 原始输入不被丢弃
直观理解:
没有残差:你每次都要重新把整个故事讲一遍,讲着讲着就忘了一开始说的什么
有残差: 你每次在上一版基础上加新内容,永远保留最初的版本
(六)位置编码(侧面视角)
前面从"做什么"的角度讲了,这里从"为什么"的角度讲。
为什么位置编码是加法而不是拼接?
x_final = word_embedding + position_encoding
拼接的话:向量维度翻倍 → 后面所有矩阵都要变大 → 参数翻倍
加法的话:维度不变 → 后面的计算完全不受影响
实验证明:加法和拼接效果差不多,但加法高效得多
为什么正弦和余弦?
sin(α+β) = sin(α)cos(β) + cos(α)sin(β)
这个公式意味着:位置 pos+1 的编码可以从位置 pos 的编码通过一个线性变换得到!
模型可能学到这个隐含的"距离感"
三、小结
Transformer 做对了什么?
-
用 Attention 取代 RNN 的循环
→ 并行 + 长距离 + 稳定梯度
-
多头从多个侧面理解语义
→ 每一个头学会关注不同类型的关系
-
残差连接让梯度直达浅层
→ 能堆 24/96/100+ 层而不会训不动
-
位置编码给无序注入有序
→ "我爱你"≠"你爱我"
-
掩码机制让自回归生成成为可能
→ 这就是你为什么能跟 ChatGPT 一个字一个字地对话
他天赋异禀,为"大"而生,创造性的同时解决了长距离和并行计算两大问题,
同样的他也是一个集大成者,他把统计学习、并行计算、确定性计算等等在同一体系里面协同起来。
展望未来,transformer架构目前已经为很大大模型奠定了基础,以后也一定会继续发光发热。