- 1. 论文概述
- 2. 论文的背景与动机:RNN/LSTM 的局限
- 3. Self-Attention 机制
- 4. Scaled Dot-Product Attention
- 5. Multi-Head Attention
- 6. Positional Encoding
- 7. Encoder-Decoder 整体架构
- 8. Feed-Forward Network、Layer Normalization、Residual Connection
- 9. 训练策略
- 10. 核心实验结果
- 11. 对后续研究的影响
- 12. PyTorch 核心代码示例
- 13. 结语
- 参考资料
1. 论文概述
"Attention Is All You Need" 是 2017 年在 NeurIPS 上发表的论文,由 Google Brain 和 Google Research 的 Ashish Vaswani、Noam Shazeer、Niki Parmar、Jakob Uszkoreit、Llion Jones、Aidan Gomez、Lukasz Kaiser、Illia Polosukhin 共同撰写。这篇论文表明,完全摒弃传统的 Recurrence 与 Convolution,仅凭 Attention 机制就能够构建 Sequence-to-Sequence 模型,堪称深度学习史上真正的转折点。
论文提出的 Transformer 架构在 WMT 2014 English-to-German 翻译任务上取得了 28.4 BLEU,在 English-to-French 上取得了 41.8 BLEU,超越了此前所有模型。更重要的是,这一架构此后成为了 BERT、GPT、T5、ViT 等几乎所有现代 AI 主流模型的基础。
2. 论文的背景与动机:RNN/LSTM 的局限
2.1 Sequential Processing 的瓶颈
在 Transformer 出现之前,Sequence Modeling 的标准是 RNN(Recurrent Neural Network)及其变体 LSTM(Long Short-Term Memory)、GRU(Gated Recurrent Unit)。它们按 的顺序处理序列,同时更新 hidden state 。
这种顺序处理特性带来了两个根本性问题。
第一,无法并行化。 由于每个时间步的计算都依赖于前一个时间步的结果,GPU 的并行处理能力无法被有效利用。序列长度越长,训练时间就呈线性增长。
第二,Long-range Dependency 问题。 理论上 LSTM 能够学习长期依赖,但实际上序列越长,捕捉远距离 token 之间关系就越困难。这是因为所有的历史信息都必须压缩进 hidden state 这样一个固定大小的向量中。
2.2 Attention 的出现与局限
Bahdanau 等人(2014)提出的 Attention 机制,让 Decoder 能够直接访问 Encoder 的全部 hidden state,从而大幅缓解了 Long-range Dependency 问题。但由于它依然是在 RNN 之上附加Attention 的形式,Sequential Processing 的瓶颈依旧存在。
论文的核心问题正是:"抛开 Recurrence,仅靠 Attention 是否足够?"
答案是肯定的,而其成果正是 Transformer。
3. Self-Attention 机制
3.1 核心概念:Query、Key、Value
Self-Attention 的核心思想是,序列中的每个 token 直接计算自己与其他所有 token 之间的关系。为此,每个输入向量被转换为三种角色。
- Query (Q):"我在寻找什么样的信息?"
- Key (K):"我能提供的信息的标识符是什么?"
- Value (V):"我实际传递的信息是什么?"
对输入序列 ,通过可学习的权重矩阵生成 Q、K、V。
其中 ,。
3.2 直观理解
用信息检索系统来类比会更容易理解。假设在图书馆里找书,Query 就是「深度学习入门书」这样的检索词,Key 是每本书的标题或标签,Value 是书的实际内容。Self-Attention 的本质,就是让 Query 与 Key 相似度更高的书,其 Value 被更多地取用。
Self-Attention 与 RNN 的决定性区别在于,序列内任意两个 token 之间的路径长度(path length)始终为 。RNN 是 ,CNN 是 (dilated)或 (普通)。正是这一短路径长度,让模型能够有效学习 Long-range Dependency。
4. Scaled Dot-Product Attention
4.1 公式
论文提出的 Attention 函数的精确公式如下。
让我们逐步拆解这个公式。
Step 1:相似度计算()
计算 Query 与 Key 的 Dot Product。结果是一个 大小的 Attention Score 矩阵。其中每个元素 表示第 个 token 的 Query 与第 个 token 的 Key 之间的相似度。
Step 2:Scaling()
越大,Dot Product 值的方差就越大,从而导致 Softmax 的梯度变得极小。具体来说,若 与 的每个分量都是均值为 0、方差为 1 的独立随机变量,那么 的方差就是 。除以 可以将方差归一化为 1,使 Softmax 稳定运作。
论文也通过实验验证了这一 Scaling 的重要性——当 较小时,Additive Attention 与 Dot-Product Attention 的性能相近;但当 较大时,未经 Scaling 的 Dot-Product Attention 性能会大幅下降。
Step 3:Softmax
对经过 Scaling 的 Score 应用 Softmax,得到 Attention Weight。由于每一行的总和为 1,它相当于对 Value 做加权平均时的权重。
Step 4:与 Value 的加权求和
最终,将 Attention Weight 与 Value 相乘,每个 token 的输出就是所有 token 的 Value 按相关性比例合成的向量。
4.2 Masking
在 Decoder 的 Self-Attention 中,必须防止未来 token 的信息泄露给当前 token。为此,在 Softmax 之前,会使用 Masked Attention,将未来位置对应的 Score 设为 。
其中 是 Upper Triangular Matrix,在不被允许的位置为 ,在被允许的位置为 。
5. Multi-Head Attention
5.1 单一 Attention 的局限
如果只使用一个 Attention 函数,模型就只能从单一视角把握 token 之间的关系。例如在句子 "The cat sat on the mat because it was tired" 中,「it」指代「cat」的句法关系,与「tired」描述「cat」状态的语义关系,就很难被同时捕捉到。
5.2 Multi-Head Attention 的结构
论文通过并行运行多个 Attention 来解决这一问题。
其中每个 head 定义如下。
各 head 的权重矩阵为 、、,最终的输出投影为 。
5.3 论文中的设置
论文使用了 个 head,并设置 。由于总维度被 head 数量均分,Multi-Head Attention 的总计算成本与 Single-Head Attention 几乎相同。
根据论文的 Ablation Study,当 head 数为 1 时 BLEU 下降了 0.9 个百分点;而当 head 数过多时(例如 32 个), 会变得过小,反而导致性能下降。
5.4 三种使用方式
在 Transformer 中,Multi-Head Attention 被用在三个地方。
- Encoder Self-Attention:在 Encoder 内部,输入序列的每个 token 都会参考其他所有 token。Q、K、V 全部由前一个 Encoder 层的输出生成。
- Decoder Self-Attention(Masked):在 Decoder 内部,通过 Masking 使其只能参考目前为止已生成的 token。
- Encoder-Decoder Attention(Cross-Attention):Decoder 的 Query 参考 Encoder 的 Key、Value。这一部分与传统 Seq2Seq 模型中的 Attention 最为相似。
6. Positional Encoding
6.1 必要性
Self-Attention 本质上与顺序无关(permutation invariant)。即使改变输入 token 的顺序,Attention 的输出值(除了顺序变化之外)依然相同。而在自然语言中,语序是极为重要的信息,因此必须显式地注入位置信息。
6.2 Sinusoidal Positional Encoding
论文提出了利用正弦与余弦函数的 Positional Encoding。
其中 是序列内的位置, 是维度索引。该 Encoding 会被加到(element-wise addition)输入 Embedding 上,再传入模型。
6.3 为什么是 Sinusoidal?
选择这一函数有明确的理由。
相对位置表示:对任意固定偏移量 , 都可以表示为 的线性变换。这使得模型能够更容易学习相对位置关系。
无需学习的泛化能力:能够自然地扩展到训练数据中未出现过的更长序列。论文将其与可学习的 Positional Embedding 进行比较后,报告称两种方式的结果「几乎相同」,并出于泛化能力的考虑,最终选择了 Sinusoidal 方式。
频率谱:维度越低( 越小)波长越短,用于精细的位置区分;维度越高波长越长,用于编码更大范围的位置关系。
7. Encoder-Decoder 整体架构
7.1 Encoder 结构
Encoder 由 个相同的层组成。每一层包含两个 Sub-layer。
- Multi-Head Self-Attention
- Position-wise Feed-Forward Network
每个 Sub-layer 都应用了 Residual Connection 与 Layer Normalization。
7.2 Decoder 结构
Decoder 同样由 个相同的层组成,但与 Encoder 不同的是,每层包含三个 Sub-layer。
- Masked Multi-Head Self-Attention:为保持 Auto-regressive 特性,对未来位置进行 Masking。
- Multi-Head Cross-Attention:以 Encoder 的输出作为 Key、Value。
- Position-wise Feed-Forward Network
7.3 整体流程
输入序列经过 Embedding + Positional Encoding 后进入 Encoder,经过 6 层处理后的 Encoder 输出被传递给 Decoder 的 Cross-Attention。Decoder 以此前生成的 token 作为输入,输出下一个 token 的概率分布,这一过程会一直重复,直到出现序列结束 token。所有 Sub-layer 的输出维度都统一为 。
8. Feed-Forward Network、Layer Normalization、Residual Connection
8.1 Position-wise Feed-Forward Network(FFN)
每个 Attention Sub-layer 之后都跟着一个 Position-wise FFN。所谓「Position-wise」,是指对每个位置(token)独立地、共享同一组权重来应用。
这是在两个 Linear Transformation 之间插入 ReLU 激活函数的结构。输入与输出的维度为 ,内部维度为 。也就是说,这是一个先扩展 4 倍再缩回原尺寸的 Bottleneck 结构。
这个 FFN 等价于两次 1x1 Convolution,其作用是对每个 token 进行非线性变换,把 Attention 捕捉到的关系信息转化为更丰富的表示。
8.2 Residual Connection
这是一种将每个 Sub-layer 的输入加到其输出上的 Skip Connection。
这一设计借鉴自 ResNet,能让梯度在深层网络中顺畅流动,从而稳定训练。为使 Residual Connection 正常工作,相加的两个张量维度必须相同,这正是所有 Sub-layer 与 Embedding 的输出维度统一为 的原因。
8.3 Layer Normalization
每个 Sub-layer 的输出都会应用 Layer Normalization。与 Batch Normalization 不同,Layer Normalization 是在单个样本内对所有 Feature 进行归一化,因此不依赖于批大小。
其中 与 是该层所有维度上的均值与标准差, 与 是可学习参数。论文采用了 Post-Norm(在 Sublayer 输出 + Residual 之后应用 LN)方式。
9. 训练策略
9.1 Optimizer 与 Learning Rate Schedule
论文使用了 Adam Optimizer,同时搭配了一种独特的 Learning Rate 调度方式。这一调度方式后来被广泛称为「Noam Scheduler」。
该调度方式的核心是 Warmup。在最初的 (论文中为 4,000 步)内,Learning Rate 线性增加,此后则按步数的平方根倒数比例递减。
之所以需要 Warmup,是因为训练初期 Adam 的二阶矩估计并不稳定。在初期保持较低的 Learning Rate,可以防止参数发生剧烈变化,等到矩估计趋于稳定后再正式展开训练。
Adam Optimizer 的超参数为 ,,。 被设置为比常见的 0.999 更小的 0.98,这一点很特别,通常被解读为是为了适应 Attention Score 分布的快速变化。
9.2 Regularization
Residual Dropout:对每个 Sub-layer 的输出应用 Dropout(rate = 0.1)后,再进行 Residual Connection。此外,在 Encoder 与 Decoder 中,Embedding + Positional Encoding 之和也会应用 Dropout。
Label Smoothing:应用了 的 Label Smoothing。这是一种将正确类别的目标概率设为 而非 1、其余类别的目标概率设为 的技巧。论文报告称,Label Smoothing 会使 Perplexity 恶化,但会提升 Accuracy 与 BLEU Score。这是因为它能防止模型变得过度自信,从而提升泛化性能。
9.3 训练数据与硬件
- WMT 2014 English-German:约 450 万个句对,使用 Byte-Pair Encoding(BPE)构建的约 37,000 个共享词表
- WMT 2014 English-French:约 3,600 万个句对,使用 32,000 个 Word-piece 词表
- Batch:包含约 25,000 个 Source token + 25,000 个 Target token
- Hardware:8 块 NVIDIA P100 GPU
- 训练时间:Base 模型约 12 小时(100K steps),Big 模型约 3.5 天(300K steps)
10. 核心实验结果
10.1 机器翻译性能
| Model | EN-DE BLEU | EN-FR BLEU | Training Cost (FLOPs) |
|---|---|---|---|
| Transformer (Base) | 27.3 | 38.1 | |
| Transformer (Big) | 28.4 | 41.8 | |
| 既有 SOTA(含 Ensemble) | 26.36 | 41.29 | - |
Transformer Big 模型在 EN-DE 上超越了此前最佳性能超过 2 个 BLEU,在 EN-FR 上也刷新了 SOTA。更令人惊讶的是,这一性能是以既有模型训练成本的一小部分达成的。
10.2 模型规模比较
| Config | Parameters | |||||
|---|---|---|---|---|---|---|
| Base | 6 | 512 | 2048 | 8 | 64 | 65M |
| Big | 6 | 1024 | 4096 | 16 | 64 | 213M |
10.3 Ablation Study 核心结果
论文的 Ablation Study 清楚地展示了每个设计决策的重要性。
- Attention Head 数量: 时 BLEU 下降 0.9, 或 时 变得过小,导致性能下降
- (Key 维度):减小会导致质量下降。直接影响 Dot-Product Attention 的表达能力
- (模型维度):越大性能提升越一致
- Dropout:没有 Dropout 会发生过拟合,性能大幅下降
- Positional Encoding:可学习方式与 Sinusoidal 方式性能几乎相同
10.4 English Constituency Parsing
为了验证在翻译任务之外的泛化能力,论文还将该架构应用于 English Constituency Parsing(句法分析)任务。仅使用 WSJ 数据取得了 91.3 F1,在半监督学习设定下取得了 92.7 F1,展现出与任务专用模型相当的竞争力。这证明了 Transformer 是一种不局限于机器翻译的通用序列模型。
11. 对后续研究的影响
Transformer 架构几乎成为了现代 AI 所有重大进展的基础。
11.1 BERT(2018,Google)
仅使用 Transformer 的 Encoder 部分,进行了双向(Bidirectional)预训练。通过 Masked Language Modeling(MLM)与 Next Sentence Prediction(NSP)这两项预训练任务,在 11 个 NLP 基准测试上取得了 SOTA。BERT 确立了 NLP 领域的 Transfer Learning 范式。
11.2 GPT 系列(2018 年~,OpenAI)
仅使用 Transformer 的 Decoder 部分,进行了 Auto-regressive Language Modeling。从 GPT-1(117M)到 GPT-2(1.5B)再到 GPT-3(175B)逐步扩大规模,证明了 Scaling Law 的威力。GPT-3 展现出了 Few-shot Learning 能力,开启了 AI 的新可能性,成为后续 ChatGPT、GPT-4 所引领的大规模语言模型(LLM)革命的起点。
11.3 此后
- T5(2019):将所有 NLP 任务统一为 Text-to-Text 格式,使用完整的 Encoder-Decoder 结构
- ViT(2020):将 Transformer 应用于 Computer Vision,把图像切分为 patch 后作为序列处理
- DALL-E、Stable Diffusion:在图像生成中运用 Transformer
- AlphaFold 2:在蛋白质结构预测中运用 Attention 机制
一篇论文,超越了 NLP,变革了 Computer Vision、生物学、音乐、机器人学等几乎所有 AI 领域。
12. PyTorch 核心代码示例
12.1 Scaled Dot-Product Attention
import torch
import torch.nn as nn
import torch.nn.functional as F
import math
def scaled_dot_product_attention(
query: torch.Tensor,
key: torch.Tensor,
value: torch.Tensor,
mask: torch.Tensor = None,
dropout: nn.Dropout = None
) -> tuple[torch.Tensor, torch.Tensor]:
"""
Scaled Dot-Product Attention 实现。
Args:
query: (batch, h, seq_len, d_k)
key: (batch, h, seq_len, d_k)
value: (batch, h, seq_len, d_v)
mask: Attention mask (optional)
Returns:
output: (batch, h, seq_len, d_v)
attention_weights: (batch, h, seq_len, seq_len)
"""
d_k = query.size(-1)
# Step 1 & 2: QK^T / sqrt(d_k)
scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
# Masking(Decoder Self-Attention 等场景)
if mask is not None:
scores = scores.masked_fill(mask == 0, float('-inf'))
# Step 3: Softmax
attention_weights = F.softmax(scores, dim=-1)
if dropout is not None:
attention_weights = dropout(attention_weights)
# Step 4: Weighted sum of values
output = torch.matmul(attention_weights, value)
return output, attention_weights
12.2 Multi-Head Attention
class MultiHeadAttention(nn.Module):
def __init__(self, d_model: int = 512, h: int = 8, dropout: float = 0.1):
super().__init__()
assert d_model % h == 0, "d_model must be divisible by h"
self.d_model = d_model
self.h = h
self.d_k = d_model // h
# Q, K, V, Output 各自的 Linear projection
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model)
self.dropout = nn.Dropout(dropout)
def forward(
self,
query: torch.Tensor,
key: torch.Tensor,
value: torch.Tensor,
mask: torch.Tensor = None
) -> torch.Tensor:
batch_size = query.size(0)
# 1) Linear projection 后 reshape 为 (batch, h, seq_len, d_k)
Q = self.W_q(query).view(batch_size, -1, self.h, self.d_k).transpose(1, 2)
K = self.W_k(key).view(batch_size, -1, self.h, self.d_k).transpose(1, 2)
V = self.W_v(value).view(batch_size, -1, self.h, self.d_k).transpose(1, 2)
# 2) Scaled Dot-Product Attention(所有 head 并行执行)
attn_output, attn_weights = scaled_dot_product_attention(
Q, K, V, mask=mask, dropout=self.dropout
)
# 3) 将各 head 结果 Concatenate:(batch, seq_len, d_model)
attn_output = (
attn_output.transpose(1, 2)
.contiguous()
.view(batch_size, -1, self.d_model)
)
# 4) Final linear projection
return self.W_o(attn_output)
12.3 Positional Encoding
class PositionalEncoding(nn.Module):
def __init__(self, d_model: int = 512, max_len: int = 5000, dropout: float = 0.1):
super().__init__()
self.dropout = nn.Dropout(dropout)
# 生成大小为 (max_len, d_model) 的 Positional Encoding 矩阵
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) # (max_len, 1)
div_term = torch.exp(
torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)
) # (d_model/2,)
pe[:, 0::2] = torch.sin(position * div_term) # 偶数维度: sin
pe[:, 1::2] = torch.cos(position * div_term) # 奇数维度: cos
pe = pe.unsqueeze(0) # (1, max_len, d_model) - 添加 batch 维度
self.register_buffer('pe', pe) # 注册为 buffer 而非可学习参数
def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
Args:
x: (batch, seq_len, d_model) - Embedding 输出
Returns:
(batch, seq_len, d_model) - 加上 Positional Encoding 后的结果
"""
x = x + self.pe[:, :x.size(1), :]
return self.dropout(x)
12.4 Transformer Encoder Layer
class TransformerEncoderLayer(nn.Module):
def __init__(self, d_model: int = 512, h: int = 8, d_ff: int = 2048, dropout: float = 0.1):
super().__init__()
# Sub-layer 1: Multi-Head Self-Attention
self.self_attn = MultiHeadAttention(d_model, h, dropout)
self.norm1 = nn.LayerNorm(d_model)
self.dropout1 = nn.Dropout(dropout)
# Sub-layer 2: Position-wise FFN
self.ffn = nn.Sequential(
nn.Linear(d_model, d_ff),
nn.ReLU(),
nn.Dropout(dropout),
nn.Linear(d_ff, d_model),
)
self.norm2 = nn.LayerNorm(d_model)
self.dropout2 = nn.Dropout(dropout)
def forward(self, x: torch.Tensor, mask: torch.Tensor = None) -> torch.Tensor:
# Sub-layer 1: Self-Attention + Residual + LayerNorm
attn_output = self.self_attn(x, x, x, mask)
x = self.norm1(x + self.dropout1(attn_output))
# Sub-layer 2: FFN + Residual + LayerNorm
ffn_output = self.ffn(x)
x = self.norm2(x + self.dropout2(ffn_output))
return x
上述代码中,self.self_attn(x, x, x, mask) 的 Q、K、V 全部来自同一个输入 x,这正是被称为「Self」-Attention 的原因。若是 Cross-Attention,则只需将 K 与 V 换成 Encoder 的输出即可。
13. 结语
"Attention Is All You Need" 并不只是提出了一个机器翻译模型。它打破了 Recurrence 这一由来已久的惯性,用实证证明了「仅靠 Attention 就足够」这一大胆主张。
这篇论文的核心贡献可以总结如下。
- 去除 Recurrence:以可并行处理的架构大幅提升训练速度
- Self-Attention:以 路径长度直接建模序列中所有 token 之间的关系
- Multi-Head Attention:从多个视角同时捕捉关系
- Scalability:简洁而可扩展的架构设计,使后续可以扩展到数十亿乃至数万亿参数的模型
自这篇论文发表的 2017 年以来,Transformer 已经超越 NLP,扩散到 Vision、Audio、Biology、Robotics 等几乎所有 AI 领域。正如论文标题所说,Attention 确实就是 All You Need。
参考资料
- Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, L., & Polosukhin, I. (2017). Attention Is All You Need. NeurIPS 2017. https://arxiv.org/abs/1706.03762
- 论文全文(HTML 版本): https://arxiv.org/html/1706.03762v7
- NeurIPS 官方 PDF: https://papers.neurips.cc/paper/7181-attention-is-all-you-need.pdf
- Jay Alammar, The Illustrated Transformer: https://jalammar.github.io/illustrated-transformer/
- Harvard NLP, The Annotated Transformer: http://nlp.seas.harvard.edu/2018/04/03/attention.html
- Devlin, J. et al. (2018). BERT: Pre-training of Deep Bidirectional Transformers. https://arxiv.org/abs/1810.04805
- Radford, A. et al. (2018). Improving Language Understanding by Generative Pre-Training (GPT). https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf
- UvA Deep Learning Tutorials - Transformers and Multi-Head Attention: https://uvadlc-notebooks.readthedocs.io/en/latest/tutorial_notebooks/tutorial6/Transformers_and_MHAttention.html
- Wikipedia - Attention Is All You Need: https://en.wikipedia.org/wiki/Attention_Is_All_You_Need
현재 단락 (1/259)
"Attention Is All You Need" 是 2017 年在 NeurIPS 上发表的论文,由 Google Brain 和 Google Research 的 Ashish Vaswa...