跳转到内容

Attention Is All You Need:Transformer 开山之作

2017 年 6 月,八位来自 Google Brain、Google Research 与多伦多大学的作者在 arXiv 上传了一篇 15 页的论文。它没有用当时主流的循环神经网络(RNN),也没有用卷积神经网络(CNN),只保留了一个机制——注意力(Attention),却在机器翻译任务上同时做到了效果更好和训练更便宜。

这篇论文就是 Attention Is All You Need,它提出的 Transformer 后来成为 BERT、GPT、T5 的骨架,也是今天所有大语言模型(LLM)和 Agent 系统的共同底座。想真正理解 Agent,先回到这一步。

项目内容
标题Attention Is All You Need
作者Ashish Vaswani、Noam Shazeer、Niki Parmar、Jakob Uszkoreit、Llion Jones、Aidan N. Gomez、Łukasz Kaiser、Illia Polosukhin
机构Google Brain、Google Research、University of Toronto
发表NeurIPS 2017(arXiv:1706.03762,2017 年 6 月 12 日)
核心贡献提出 Transformer:第一个完全基于注意力、不含循环与卷积的序列转换架构
任务机器翻译(WMT 2014 英德、英法)
影响BERT / GPT / T5 / ViT / 现代 LLM 与 Agent 的架构基础
  • 弄清 Transformer 的完整数据流:Encoder、Decoder、残差、LayerNorm 各自做什么;
  • 理解自注意力与多头注意力的公式、直觉和设计动机;
  • 明白为什么需要位置编码,以及它为什么选正弦函数;
  • 看到论文如何用消融实验证明每个部件都不是摆设;
  • 建立理解后续 LLM、RAG、Agent 上下文机制的地基。

RNN 把序列信息压缩进一个隐藏状态,第 tt 步的输出依赖第 t−1t-1 步:

ht=f(ht−1,xt)h_t = f(h_{t-1}, x_t)

这带来两个硬伤:

  • 无法并行:必须逐步计算,序列多长就要串行多久,GPU 利用率上不去;
  • 长距离依赖难学:位置 1 和位置 100 之间的信息,要经过 99 次传递才能相遇,梯度沿路衰减,训练越深越难。

论文原文对此的表述是:循环模型的这种固有顺序性,使得训练样本内部无法并行化,在序列较长时成为关键瓶颈。

ConvS2S、ByteNet 这类模型用卷积核并行提取特征,但单个卷积核只看局部邻域。要让两个相距很远的位置产生联系,只能:

  • 堆叠足够多的卷积层(普通卷积约 O(n/k)O(n/k) 层,膨胀卷积约 O(log⁡kn)O(\log_k n) 层);
  • 付出层数、参数与计算量的代价。

距离越远,路径越长,学习成本越高。

Bahdanau 等人在 2015 年就把注意力机制接到 RNN 编码器-解码器上,用来对齐源语言和目标语言。但它始终是循环结构的补充件——主干仍然是 RNN。

论文提出的问题很直接:既然注意力能建模任意两个位置的依赖,为什么还要 RNN? 于是有了 Transformer:完全移除循环与卷积,只靠注意力 + 前馈网络堆叠。

3. 整体架构:一座 Encoder-Decoder 塔

Section titled “3. 整体架构:一座 Encoder-Decoder 塔”

先看全局数据流:

源序列(如英文)
│
▼
Embedding + 位置编码
│
▼
┌──────────────────┐
│ Encoder × 6 │ ──── K, V ────┐
└──────────────────┘ │
▼
目标序列(已生成部分) ┌──────────────────┐
│ │ Decoder × 6 │
▼ └──────────────────┘
Embedding + 位置编码 │
▼
Linear + Softmax
│
▼
下一个词的概率分布
  • 编码器把源序列编码成一串向量,输出交给解码器的交叉注意力使用;
  • 解码器自回归地生成目标序列:每步看已生成的前缀,再结合编码器输出,预测下一个词。

编码器由 N=6N=6 个完全相同的层堆叠而成,每层只有两个子层:

  1. 多头自注意力(Multi-Head Self-Attention)
  2. 逐位置前馈网络(Position-wise Feed-Forward Network)

每个子层外面都包一层残差连接 + 层归一化:

LayerNorm(x+Sublayer(x))\mathrm{LayerNorm}\big(x + \mathrm{Sublayer}(x)\big)

也就是说,每层实际计算的是:

x←LayerNorm(x+SelfAttention(x))x \leftarrow \mathrm{LayerNorm}(x + \mathrm{SelfAttention}(x)) x←LayerNorm(x+FFN(x))x \leftarrow \mathrm{LayerNorm}(x + \mathrm{FFN}(x))

残差连接让梯度可以走「高速公路」,LayerNorm 稳定每层的数值分布——这两件套后来成为深度网络的标配。

解码器同样堆叠 6 层,但每层多了一个子层,顺序是:

  1. 带掩码的多头自注意力(Masked Multi-Head Self-Attention)
  2. 多头交叉注意力(Cross-Attention,也叫 Encoder-Decoder Attention)
  3. 逐位置前馈网络

关键差异在第一个子层:生成第 tt 个词时,模型不能「偷看」第 tt 个词及之后的答案,所以自注意力必须加掩码。而中间的交叉注意力让解码器每一步都能回看整段源序列。

4. 注意力机制:整篇论文的灵魂

Section titled “4. 注意力机制:整篇论文的灵魂”

4.1 直觉:一次可微的「软检索」

Section titled “4.1 直觉:一次可微的「软检索」”

先把注意力当成一次检索:

  • Query(查询):我当前想找什么;
  • Key(键):每个位置「标签」是什么;
  • Value(值):每个位置实际携带的信息。

用 Query 和每个 Key 算相似度,得到一组权重,再对 Value 加权求和。整个过程可微、可并行,比「硬查找」更适合神经网络。

其中 softmax 把分数变成概率分布:

softmax(zi)=ezi∑jezj\mathrm{softmax}(z_i) = \frac{e^{z_i}}{\sum_j e^{z_j}}

论文的核心公式(公式 1):

Attention(Q,K,V)=softmax ⁣(QK⊤dk)V\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}}\right)V
  • Q∈Rn×dkQ \in \mathbb{R}^{n \times d_k}:nn 个查询;
  • K∈Rm×dkK \in \mathbb{R}^{m \times d_k}:mm 个键;
  • V∈Rm×dvV \in \mathbb{R}^{m \times d_v}:mm 个值;
  • QK⊤QK^\top 得到 n×mn \times m 的相似度矩阵,softmax 按行归一化后与 VV 相乘。

为什么要除以 dk\sqrt{d_k}? 这是全文最常被考的一个细节。当 dkd_k 较大时,点积的方差随维度增长,数值会变得很大,softmax 被推向两端、梯度趋近于 0,训练不稳定。除以 dk\sqrt{d_k} 把方差拉回 1 附近,让梯度保持在健康区间。

4.3 为什么用点积,而不是加性注意力

Section titled “4.3 为什么用点积,而不是加性注意力”

当时另一种主流做法是加性注意力(Bahdanau 注意力):

score(q,k)=v⊤tanh⁡(Wqq+Wkk)\mathrm{score}(q, k) = v^\top \tanh(W_q q + W_k k)

论文的取舍是:两者在 dkd_k 较小时效果接近,但点积注意力可以用高度优化的矩阵乘法实现,速度更快、显存更省。工程效率胜出。

4.4 多头注意力:让模型「多线程」看世界

Section titled “4.4 多头注意力:让模型「多线程」看世界”

如果只做一次注意力,模型只能学到一种「关注模式」。Transformer 的做法是把 dmodel=512d_{model}=512 维切成 h=8h=8 份,每份 dk=dv=64d_k=d_v=64 维,并行做 8 次注意力,再拼接、投影:

MultiHead(Q,K,V)=Concat(head1,…,headh) WO\mathrm{MultiHead}(Q, K, V) = \mathrm{Concat}(\mathrm{head}_1, \ldots, \mathrm{head}_h)\,W^O headi=Attention(QWiQ, KWiK, VWiV)\mathrm{head}_i = \mathrm{Attention}(QW_i^Q,\ KW_i^K,\ VW_i^V)

其中投影矩阵 WiQ,WiK∈Rdmodel×dkW_i^Q, W_i^K \in \mathbb{R}^{d_{model} \times d_k},WiV∈Rdmodel×dvW_i^V \in \mathbb{R}^{d_{model} \times d_v},WO∈Rhdv×dmodelW^O \in \mathbb{R}^{h d_v \times d_{model}}。

多头的意义在于:每个头在不同子空间里学习不同关系。论文的注意力可视化显示,有的头盯着句法结构(比如动词与其宾语),有的头负责指代消解,有的头关注相邻位置。多头并不显著增加计算量——因为每头的维度被等比例缩小了。

同一个注意力公式,在 Transformer 里被用了三次:

所在位置Query 来自Key / Value 来自掩码作用
Encoder 自注意力编码器上层编码器上层无源序列内部任意位置互相建模
Decoder 掩码自注意力解码器上层解码器上层有只能看已生成的前缀
Decoder 交叉注意力解码器上层编码器输出无生成时对齐源序列

掩码的实现非常朴素:把 i<ji < j(未来位置)处的分数加上 −∞-\infty,softmax 后这些位置权重为 0:

softmax ⁣(QK⊤dk+M)V,Mij={0i≥j−∞i<j\mathrm{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}} + M\right)V,\quad M_{ij} = \begin{cases} 0 & i \ge j \\ -\infty & i < j \end{cases}

QK⊤QK^\top 是一个 n×nn \times n 的矩阵,序列越长,计算量和显存都按 O(n2)O(n^2) 增长。这既是 Transformer 强大的来源(任意两位置一步直连),也是后来所有「长上下文」优化的靶子(稀疏注意力、Longformer、FlashAttention 等都从这里出发)。

5. 逐位置前馈网络:每个位置独立做一次 MLP

Section titled “5. 逐位置前馈网络:每个位置独立做一次 MLP”

注意力负责「位置之间交流」,FFN 负责「每个位置自己消化」。它逐位置、共享参数地作用:

FFN(x)=max⁡(0, xW1+b1) W2+b2\mathrm{FFN}(x) = \max(0,\ xW_1 + b_1)\,W_2 + b_2
  • 两层线性变换,中间夹一个 ReLU;
  • base 模型里 dmodel=512d_{model}=512,内层维度 dff=2048d_{ff}=2048,即先升维再降回;
  • 从卷积视角看,等价于两个核大小为 1 的卷积。

别小看这个模块:升维到 4 倍再降回的结构占了模型参数的大头,也通常被认为是模型存储「知识」的主要位置。

  • 输入 token 先查嵌入表变成 dmodeld_{model} 维向量;
  • 输出端用一个线性层 + softmax 得到词表概率;
  • 论文让嵌入层与输出线性层共享同一个权重矩阵,并把嵌入乘以 dmodel\sqrt{d_{model}},让嵌入的尺度与位置编码相匹配。

共享权重在词表很大时显著减少参数量,后来也成为 LLM 的标准做法(weight tying)。

自注意力对输入是置换等变的:把序列打乱,输出只是跟着打乱,模型本身感知不到顺序。但语言是有序的,所以必须显式注入位置信息。

论文用不同频率的正弦、余弦函数生成位置编码,直接加到嵌入上:

PE(pos, 2i)=sin⁡(pos100002i/dmodel)PE_{(pos,\,2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) PE(pos, 2i+1)=cos⁡(pos100002i/dmodel)PE_{(pos,\,2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)

其中 pospos 是位置,ii 是维度下标。偶数维用 sin、奇数维用 cos,波长从 2π2\pi 到 10000⋅2π10000 \cdot 2\pi 呈几何级数分布。

为什么选正弦而不是可学习的位置嵌入?

  • 论文实验发现两者效果几乎持平;
  • 正弦编码可以外推到比训练时更长的序列;
  • 一个更漂亮的性质:任意固定偏移 kk,PEpos+kPE_{pos+k} 都可以表示成 PEposPE_{pos} 的线性变换,模型更容易学习「相对位置」关系。

8. 为什么自注意力更好:三组复杂度对比

Section titled “8. 为什么自注意力更好:三组复杂度对比”

论文用一张表对比了不同层类型(Table 1):

层类型每层复杂度顺序操作数最大路径长度
自注意力O(n2⋅d)O(n^2 \cdot d)O(1)O(1)O(1)O(1)
循环层O(n⋅d2)O(n \cdot d^2)O(n)O(n)O(n)O(n)
卷积层O(k⋅n⋅d2)O(k \cdot n \cdot d^2)O(1)O(1)O(log⁡kn)O(\log_k n)
受限自注意力O(r⋅n⋅d)O(r \cdot n \cdot d)O(1)O(1)O(n/r)O(n/r)

这张表要这么读:

  • 最大路径长度决定「两个远距离位置要经过多少步才能交互」。自注意力是常数 1,循环层是 O(n)O(n),卷积层是 O(log⁡kn)O(\log_k n)——路径越短,长距离依赖越容易学。
  • 顺序操作数决定并行度。自注意力与卷积都是 O(1)O(1),循环是 O(n)O(n)。
  • 每层复杂度是代价:自注意力是 O(n2⋅d)O(n^2 \cdot d),当序列长度 nn 小于表示维度 dd 时,反而比循环层更省算力——这正是论文强调自注意力在机器翻译里划算的原因。

9. 训练配置:好结果也是调出来的

Section titled “9. 训练配置:好结果也是调出来的”
项目英德(EN-DE)英法(EN-FR)
数据集WMT 2014,约 450 万句对WMT 2014,约 3600 万句对
分词字节对编码(BPE),共享词表约 3.7 万word-piece,词表 3.2 万
Batch每批约 2.5 万源 token + 2.5 万目标 token同左
  • 硬件:8 块 NVIDIA P100;
  • base 模型训练约 12 小时;
  • big 模型训练约 3.5 天。

使用 Adam(β1=0.9\beta_1=0.9,β2=0.98\beta_2=0.98,ϵ=10−9\epsilon=10^{-9}),学习率按步数动态调整:

lr=dmodel−0.5⋅min⁡(step−0.5, step⋅warmup−1.5)\text{lr} = d_{model}^{-0.5} \cdot \min\left(\text{step}^{-0.5},\ \text{step} \cdot \text{warmup}^{-1.5}\right)

其中 warmup 步数取 4000。前 4000 步线性上升,之后按步数平方根的倒数衰减。这个 warmup + 逆平方根衰减 的调度后来几乎成为 Transformer 训练的标准配方。

  • Dropout:base 用 0.1,big 用 0.3。施加在三个位置:每个子层输出(残差相加前)、嵌入与位置编码之和、注意力权重矩阵。
  • Label Smoothing:标签平滑系数 ϵls=0.1\epsilon_{ls}=0.1。它让模型的困惑度(perplexity)变差,但 BLEU 反而更高——因为模型变得更「不自信」,泛化更好。
  • Checkpoint 平均:对训练后期的多个检查点取平均权重,几乎没有额外成本地稳定涨点。

10. 实验结果:更快、更好、更简单

Section titled “10. 实验结果:更快、更好、更简单”
模型EN-DE BLEUEN-FR BLEU训练成本(FLOPs)
ByteNet23.75——
ConvS2S25.1640.469.6×10189.6 \times 10^{18}
GNMT + RL24.639.922.3×10192.3 \times 10^{19}
ConvS2S Ensemble26.3641.297.7×10197.7 \times 10^{19}
GNMT + RL Ensemble26.3041.161.8×10201.8 \times 10^{20}
Transformer (base)27.338.13.3×10183.3 \times 10^{18}
Transformer (big)28.441.02.3×10192.3 \times 10^{19}
  • big 模型在英德上比此前最好结果(含集成模型)高 2.0 BLEU 以上;
  • 在英法上以单个模型刷新 SOTA,训练成本却不到此前最好模型的四分之一;
  • base 模型只用 12 小时 8 卡 P100 就超过了所有已有单模型。

论文的模型变体实验(Table 3)给出几个重要结论:

  • 多头明显优于单头:单头注意力在英德上掉约 0.9 BLEU;
  • dkd_k 不能太小也不能太大:太小会削弱每个头的表达能力,太大则多头退化为单头的效果且收益递减;
  • Dropout 对大模型至关重要:big 模型去掉 dropout 会明显过拟合;
  • 正弦位置编码 vs 可学习位置编码:效果基本持平,选择正弦更多是出于外推性的考虑。

论文还把 Transformer 用到英语成分句法分析(WSJ 数据集):

  • 仅用 4 万句训练:91.3 F1;
  • 半监督设置(1700 万句):92.7 F1。

这证明纯注意力架构的适用性不止于翻译任务。

论文把不同注意力头的权重画了出来,可以看到清晰的结构:有的头关注相邻词,有的头把动词与远距离的宾语连起来,有的头负责指代关系。这给「多头到底学到了什么」提供了直观证据。

  • 架构上:Transformer 是第一个完全依赖注意力的序列转换模型,训练更快、并行度更高,在翻译任务上同时拿到效果和成本优势;
  • 生态上:BERT(只用 Encoder)、GPT(只用 Decoder)、T5、ViT、以及今天几乎所有 LLM 都是它的变体;
  • Agent 语境下:LLM 是 Agent 的「大脑」,而 LLM 的上下文窗口、工具调用格式、推理链,本质上都是 Transformer 在序列上做条件概率建模的能力延伸。读懂注意力,才知道 Agent 的能力边界从哪来。
英文中文说明
Attention注意力按相关性加权聚合信息
Self-Attention自注意力Q、K、V 来自同一序列
Scaled Dot-Product Attention缩放点积注意力除以 dk\sqrt{d_k} 的点积注意力
Multi-Head Attention多头注意力多个子空间并行注意力
Query / Key / Value查询 / 键 / 值检索三要素
Position-wise FFN逐位置前馈网络对每个位置独立的两层 MLP
Positional Encoding位置编码注入序列顺序信息
Residual Connection残差连接x+Sublayer(x)x + \mathrm{Sublayer}(x)
Layer Normalization层归一化稳定数值分布
Masked Attention掩码注意力遮蔽未来位置,保证自回归
Label Smoothing标签平滑软标签正则化
Warmup学习率预热训练初期逐步提升学习率
Beam Search束搜索解码时保留 top-k 候选
Ablation Study消融实验逐个去掉部件验证贡献