年份与会议
2017 · NeurIPS
提出 Transformer 架构,以纯注意力机制替代 RNN/CNN,重写了序列建模的工程范式与研究方向。
年份与会议
2017 · NeurIPS
作者
Ashish Vaswani、Noam Shazeer、Niki Parmar、Jakob Uszkoreit
主题
Transformer
阅读时长
约 3 分钟
收录时间
2017/06/12
在 Transformer 出现之前,主流序列模型主要是 RNN、LSTM 以及少量卷积式 seq2seq。它们都能做机器翻译,但存在两个很现实的工程问题:
《Attention Is All You Need》最重要的贡献,不只是“提出了一种新模型”,而是提出了一个新的判断标准:对于序列建模,是否真的必须依赖递归结构?作者给出的答案是否定的。他们用纯注意力机制搭建了完整的 encoder-decoder 架构,在翻译任务上取得了更好结果,同时显著缩短训练时间。
从今天回头看,这篇论文的真正历史地位在于,它把“并行友好、可扩展、易于堆叠”的设计思路变成了后续大模型时代的默认前提。
Transformer 仍然保留了经典的 seq2seq 任务分解方式:
与传统 seq2seq 的区别在于,Transformer 的每一层都不再依赖循环单元,而是由以下模块组成:
Encoder 的每一层包括“自注意力 + 前馈网络”;Decoder 的每一层包括“带 mask 的自注意力 + encoder-decoder attention + 前馈网络”。这种结构简单、规则、易堆叠,非常适合做深层网络和大规模训练。
如果把这篇论文最关键的结构压成一张图,可以得到下面这条主线:
<g>
<rect x="42" y="92" width="168" height="66" rx="18" fill="#e8f1ff" stroke="#98b7e1" />
<text x="126" y="122" text-anchor="middle" font-size="19" font-weight="700">输入 Token</text>
<text x="126" y="145" text-anchor="middle" font-size="13" fill="#4b5563">Embedding + 位置编码</text>
</g>
<g>
<rect x="260" y="72" width="220" height="208" rx="22" fill="#f6f9ff" stroke="#d7e2f1" />
<text x="370" y="102" text-anchor="middle" font-size="21" font-weight="700">Encoder Stack</text>
<rect x="292" y="122" width="156" height="44" rx="14" fill="#eef6e8" stroke="#a8c48e" />
<text x="370" y="149" text-anchor="middle" font-size="17" font-weight="700">Multi-Head Self-Attention</text>
<rect x="292" y="182" width="156" height="44" rx="14" fill="#fff4dc" stroke="#e2c36f" />
<text x="370" y="209" text-anchor="middle" font-size="17" font-weight="700">Feed Forward</text>
<rect x="292" y="242" width="156" height="24" rx="10" fill="#f4ebff" stroke="#c7afe8" />
<text x="370" y="258" text-anchor="middle" font-size="12" fill="#4b5563">Residual + LayerNorm + 堆叠 N 层</text>
</g>
<g>
<rect x="542" y="72" width="220" height="208" rx="22" fill="#fbfaf5" stroke="#e6ddc4" />
<text x="652" y="102" text-anchor="middle" font-size="21" font-weight="700">Decoder Stack</text>
<rect x="574" y="118" width="156" height="40" rx="14" fill="#fce7ef" stroke="#e2a8bd" />
<text x="652" y="143" text-anchor="middle" font-size="16" font-weight="700">Masked Self-Attention</text>
<rect x="574" y="172" width="156" height="40" rx="14" fill="#e0f2e5" stroke="#8bc09b" />
<text x="652" y="197" text-anchor="middle" font-size="16" font-weight="700">Encoder-Decoder Attention</text>
<rect x="574" y="226" width="156" height="40" rx="14" fill="#fff4dc" stroke="#e2c36f" />
<text x="652" y="251" text-anchor="middle" font-size="16" font-weight="700">Feed Forward</text>
</g>
<g>
<rect x="804" y="92" width="134" height="66" rx="18" fill="#dff4f0" stroke="#8dc7bd" />
<text x="871" y="120" text-anchor="middle" font-size="18" font-weight="700">输出分布</text>
<text x="871" y="143" text-anchor="middle" font-size="13" fill="#4b5563">Linear + Softmax</text>
</g>
<g>
<rect x="42" y="222" width="168" height="58" rx="18" fill="#fef3c7" stroke="#e2c36f" />
<text x="126" y="255" text-anchor="middle" font-size="18" font-weight="700">已生成 Token</text>
</g>
<line x1="210" y1="125" x2="260" y2="125" stroke="#5b6b7f" stroke-width="3" marker-end="url(#transformer-arrow)" />
<line x1="480" y1="125" x2="542" y2="125" stroke="#5b6b7f" stroke-width="3" marker-end="url(#transformer-arrow)" />
<line x1="762" y1="125" x2="804" y2="125" stroke="#5b6b7f" stroke-width="3" marker-end="url(#transformer-arrow)" />
<line x1="210" y1="251" x2="542" y2="251" stroke="#5b6b7f" stroke-width="3" marker-end="url(#transformer-arrow)" />
<line x1="480" y1="206" x2="574" y2="206" stroke="#5b6b7f" stroke-width="3" marker-end="url(#transformer-arrow)" />
<text x="528" y="196" font-size="13" fill="#4b5563">encoder 输出作为 memory</text>
</g>
论文最核心的计算模块可以写成:
Attention(Q, K, V) = softmax(QK^T / sqrt(d_k))V
可以把它理解成一个三步过程:
这里的关键设计有两个:
sqrt(d_k) 做缩放,避免维度增大时点积值过大,导致 softmax 过早饱和,训练不稳定。这一步看似只是一个公式,但它把“序列中任意两个位置的信息交互”变成了一个统一、可并行的矩阵运算。后面几乎所有大模型优化,都是围绕这个内核展开的。
如果只用一个注意力头,模型只能在同一个表示子空间里完成匹配。论文引入多头注意力,是为了让模型在不同子空间中同时学习不同关系,例如:
具体做法是:先把输入分别线性投影为多组 Q/K/V,每组独立做注意力,再把多个头的输出拼接起来,并通过一次线性层融合。这样既保留了并行计算优势,也提升了表示能力。
从后续研究看,多头机制虽然并不保证每个头都“有意义”,但它确实为模型提供了更强的关系建模弹性。很多解释性工作、剪枝工作、长上下文研究,也都是沿着“头的分工”展开的。
纯注意力机制没有天然的顺序感。如果不给模型额外的位置信号,“猫咬狗”和“狗咬猫”对它来说只是同一组 token 的排列变化。
为了解决这个问题,论文引入了位置编码。原文采用的是固定的正弦/余弦位置编码,其优点是:
今天我们已经有了 RoPE、ALiBi、相对位置编码等改进方案,但“位置是序列建模中必须显式处理的信号”这一点,就是由这篇论文明确推到台前的。配合站内的 Transformer 注意力机制入门 和 RoPE Visualizer,会更容易把抽象公式变成直觉。
这篇论文很值得学习的一点,是作者没有停留在概念层面,而是把训练工程也设计得非常完整。几个关键点包括:
这些设计后来几乎都变成了大模型训练的基础模板。即便今天具体实现细节已经演化,例如 pre-norm、更大的 batch、更复杂的 tokenizer,但总体工程逻辑仍然延续自这里。
论文主要在机器翻译任务上验证 Transformer,结论可以概括为三点:
这里最值得读者关注的,其实不是某个具体 BLEU 分数,而是“效果更好 + 训练更快”这个组合。很多架构论文只能在准确率上略胜一筹,却要付出更复杂的工程代价;Transformer 恰恰相反,它把研究价值和工程价值统一了起来。
这篇论文之后,整个领域出现了非常清晰的演化链条:
换句话说,这篇论文不是“某个方向中的一篇代表作”,而是后来大量路线的共同祖先。它定义了现代大模型最重要的接口形式:token、attention、层堆叠、可扩展训练。
当然,Transformer 也不是终点。原始论文中的设计很快暴露出一些边界:
也正因为这些局限足够明确,后续研究者才能围绕它持续改进。很多“后 Transformer”工作,本质上都在回答一个问题:如何保留 Transformer 的表达能力和工程友好性,同时缓解它在长序列、推理成本和对齐阶段的压力。
如果你第一次读原文,不要试图一次记住所有矩阵维度和公式推导,先抓住下面四件事:
理解了这四点,你再去看后续的 BERT、GPT、FlashAttention、RoPE、长上下文优化时,就会知道它们分别是在 Transformer 的哪一个组件上继续演化。
沿着相近主题继续阅读,加深对方法边界与实践场景的理解。
用 MLM 与 NSP 把双向 Transformer 预训练推向主流,重塑了 NLP 从预训练到下游微调的默认范式。
用更克制的参数规模、更长的训练 token 和一组细致的架构改造,证明开源基座模型也能逼近闭源大模型能力。
从“模型为什么需要顺序感”讲到绝对位置、相对位置与 RoPE,建立长上下文位置建模的统一直觉。
用直觉解释、数值例子和最小代码示例,真正理解 Q/K/V、缩放点积注意力与 Multi-Head 的工作方式。