Attention Is All You Need(Vaswani et al., 2017)是现代大语言模型的架构起点:论文本身处理的是机器翻译这个 seq2seq 问题,提出完全舍弃循环(RNN)与卷积、只用 attention 机制堆叠出来的 Transformer。今天绝大多数大语言模型都是这个架构的变体,但多数是只保留 decoder、且在细节上做了不少调整的版本,跟原始论文本身并不完全相同。这篇文章先把原始论文的架构拆到最细,再说明现代 decoder-only LLM 具体改了哪些地方。
1. 为什么要用 Attention 取代 RNN
RNN 处理序列时,每个时间步的计算都依赖前一步的隐藏状态,本质上是串行的:处理第 个词元之前,必须先算完第 个。这代表 RNN 没办法在序列长度这个维度上并行,训练长序列时 GPU 的并行运算能力用不上,也让长距离依赖必须靠隐藏状态一路传递,容易随距离增加而衰减。
Transformer 的核心想法是:让序列中任意两个位置之间的信息传递,都只需要一步 attention 计算,不需要沿着中间的位置逐步传递。训练阶段(有完整的目标序列可用时)所有位置的 attention 可以完全并行计算;序列变长也不会增加位置之间传递信息所需的步数。代价是自注意力的计算量随序列长度呈平方增长,这也是后续大量长序列优化工作要解决的问题,但不是这篇论文本身要处理的范围。
2. Scaled Dot-Product Attention
2.1 Query、Key、Value 与张量形状
Attention 的输入是三组向量:Query()、Key()、Value()。单一个 attention head 里,若序列长度为 ,,、( 是被查询的序列长度;self-attention 里 ,encoder-decoder cross-attention 里 是 encoder 输出的序列长度)。计算公式是:
算出每个 query 对每个 key 的相似度分数,形状是 ;对每一行做 softmax,得到每个 query 位置对所有 key 位置的注意力权重;权重乘上 ,等于用这组权重对 value 向量加权平均,输出形状是 。
2.2 为什么要除以
若 的每个分量都近似独立、均值 0、方差 1, 里每个内积是 项乘积的和,方差会随 线性增长。 较大时,内积数值本身会变得很大,把 softmax 推进梯度极小的饱和区间,训练会变得困难。除以 把内积的方差重新拉回常数量级,这是论文里明确指出、也是”scaled”这个字的来源。
3. Multi-Head Attention
单一个 attention head 只能学到一种相似度度量方式。Multi-head attention 把 各自用 组不同的线性投影 投影到较低维度,并行算出 个 head 的 attention 输出,再把 个输出串接起来,用另一个线性层 投影回原本的维度:
原始论文的 base model 用 、,每个 head 的 。切成多个较窄的 head 而不是用一个宽 head,让模型可以同时关注不同子空间里不同种类的关系(例如某些 head 倾向捕捉语法结构、某些倾向捕捉指代关系),而总计算量跟单一个全宽度 head 大致相同。
4. Encoder 与 Decoder 的区块结构
4.1 Encoder block:两个子层
每个 encoder block 由两个子层组成:self-attention,接着是 position-wise feed-forward network(见第 5 节)。每个子层外面都包一层残差连接加上 Layer Normalization。原始论文用的是 post-LN:先计算子层本身,加回残差,再做归一化,也就是 ,顺序是”子层 → 残差相加 → LayerNorm”,归一化在残差相加之后。base model 叠 6 层这样的 encoder block。
4.2 Decoder block:三个子层,含 cross-attention
Decoder block 比 encoder 多一个子层,总共三个:第一个是加了 causal mask 的 self-attention(见 4.3),第二个是 encoder-decoder cross-attention——这个子层的 来自 decoder 上一个子层的输出, 和 来自 encoder 最后一层的输出,让 decoder 每个位置都能查询整个输入序列——第三个是跟 encoder 相同的 FFN。三个子层同样各自包一层残差加 post-LN。
4.3 Causal mask:确保训练和推理一致的因果性
Decoder 在生成第 个词元时,只能依赖第 到 个已生成的词元,不能看到未来的词元。训练时用 teacher forcing,一次把整个目标序列输入,若不做任何处理,self-attention 会让每个位置都看得到后面的词元,等于作弊。解法是在 算完、做 softmax 之前,把上三角(对应”查询位置早于被看的位置”)的分数设成 ,softmax 之后这些位置的权重会变成 0,等于强制每个位置只能关注自己与更早的位置。这个机制让训练时的并行计算跟推理时”一次只能看到已生成部分”的限制维持一致。
5. Position-wise Feed-Forward Network
FFN 对序列中每个位置独立且相同地套用同一组参数的两层全连接:
输入输出维度都是 ,中间隐藏层维度 通常远大于 (base model 用 ,是 的 4 倍),激活函数是 ReLU。FFN 不是把 attention 的 转换成输出维度——attention 子层自己的输出投影 才是做这件事——FFN 的角色是在每个位置上,对 attention 子层算出的结果做一次非线性的逐位置转换,让模型在混合了跨位置信息之后,还有能力对单一位置的表示做更复杂的非线性处理。现代模型常把 ReLU 换成 GELU、SwiGLU 等变体,但”逐位置的两层非线性转换”这个角色没有变。
6. Embedding 与位置编码
6.1 输入嵌入、权重缩放与输出层共享权重
输入词元先查表转成 维的嵌入向量,论文里这个嵌入会再乘上 ,让嵌入的数值量级跟后面加上去的位置编码相当。输出端把 decoder 最后的表示投影回词表大小、再做 softmax 预测下一个词元,这个投影矩阵跟输入嵌入表共享同一组权重(weight tying),减少参数量,也让输入输出的向量空间维持一致的几何关系。
6.2 原始论文的正弦位置编码
Self-attention 本身对输入顺序不敏感——打乱输入位置,attention 算出来的加权平均结果不会变——所以需要额外注入位置信息。原始论文用固定(不学习)的正弦函数:
是序列中的位置, 是维度索引。这组编码直接加到输入嵌入上。选择正弦函数的原因之一是它让任意固定偏移量 的位置编码 ,可以写成 的线性函数,理论上让模型更容易学会依赖相对位置的模式,也让模型有机会处理比训练时看过的序列更长的输入。
现代 decoder-only LLM 多半不用这种绝对位置编码,改用 RoPE(旋转位置编码) 或 ALiBi 之类的相对位置方法,直接把位置信息算进 attention 分数本身,而不是加在输入嵌入上;这类方法对长序列外推的效果通常优于原始论文的正弦编码,是原始论文之后才发展出来的做法,并不是原始 Transformer 架构的一部分。
7. 训练与推理的差异
原始论文的训练用 teacher forcing(每一步都输入真实的前文词元,而不是模型自己上一步的预测)、Adam 优化器搭配一套先线性升温再依步数衰减的学习率排程、对每个子层输出和嵌入加总后做 dropout,以及 label smoothing(,让目标分布不是硬性的 one-hot,避免模型对预测过度自信)。评估翻译质量时使用 beam search。
推理阶段没有真实的目标序列可以参考,decoder 必须自回归:每次只生成一个词元,把它接到已生成的序列后面,再喂回模型生成下一个。原始论文的解码方式只有贪心搜索和 beam search;top-k、top-p(nucleus sampling)、temperature 这类采样策略,是后来的研究(大致在 2018 年之后,随开放式文本生成的需求发展出来)针对开放式生成任务提出的方法,不属于 2017 年原始论文的内容,但是现代 decoder-only LLM 推理时的标准做法:temperature 缩放 logits 分布的尖锐程度,top-k 只在概率最高的 个词元里采样,top-p 则取概率总和达到 的最小候选集合再采样,贪心解码(等于每次都选概率最高的词元)可以看成 top-k=1 或 temperature 的特例。
8. 从原始论文到现代 decoder-only LLM
现代大语言模型(GPT 系列及其后继者)多半只保留 decoder,拿掉 encoder 和 cross-attention,靠 causal self-attention 同时处理输入与生成,这也是”decoder-only”名称的由来。除了架构的取舍,常见的具体差异还包括:把 post-LN 换成 pre-LN(LayerNorm 放在子层之前,残差路径上不经过归一化,),这让深层模型的训练稳定性明显提升,是超大模型能叠到几十甚至上百层的重要原因之一;位置编码换成 RoPE 或 ALiBi;FFN 的激活函数换成 GELU 或 SwiGLU。这些改动大多是 2017 年之后、为了训练更深更大的模型而陆续提出的工程改良,理解原始论文的每个组件在做什么,是判断这些改良各自解决了什么问题的前提。