Transformer完全拆解:从注意力机制到大模型基石
2026/9/16 23:40:19 网站建设 项目流程

2017年,谷歌机器翻译团队发表了一篇标题相当“霸气”的论文——《Attention Is All You Need》。当时NLP圈的主流还是LSTM、GRU这类循环神经网络,结果这篇论文直接放话:RNN和CNN都不用了,只用注意力机制就足够了。七年多过去,回头看,这句话不仅兑现了,还彻底重塑了整个深度学习版图。你现在用到的任何一个大模型,底层骨干基本都能追溯到这篇文章。

今天我想带大家把这篇文章重新读一遍,但不是逐句翻译论文,而是把重点放在“它为什么这样设计”上面。Transformer的总体架构到底是什么?每个模块解决什么问题?哪些细节最容易被忽略但又至关重要?在拆解完这些之后,我还会结合Transformer在机器翻译、预训练语言模型、计算机视觉里的演进,聊聊这个架构的生命力体现在哪里。无论你是刚入门准备手写第一个Transformer,还是想系统梳理一遍底层原理,这篇文章都能给你一个相对完整的参考框架。

1. 论文在挑战什么:RNN/LSTM时代的痛点

在进入架构细节之前,得先理解当时的位置。如果不清楚Transformer要“革”的是谁的命,很多设计选择你会看不懂。

1.1 循环神经网络的天花板:串行计算与长距离遗忘

在Transformer出现之前,序列建模的主流方案是RNN系家族。LSTM和GRU通过门控机制缓解了梯度消失问题,在机器翻译、文本分类等任务上取得了很不错的效果。但这类模型有两个“天生”的麻烦,躲不掉。

第一是串行计算。RNN必须在时间步上一步步往后推:处理第t个词之前,必须先把第t-1个词的隐状态算出来。这种顺序依赖直接导致它很难大规模并行训练,序列越长,训练时间越长。当时训练一个像样的神经机器翻译模型,动辄几天甚至几周,是家常便饭。

第二是长距离依赖问题。虽然后来LSTM的遗忘门能“记住”信息,但距离太远的关键信息仍然容易在逐步传递中被稀释。比如“我在北京长大,后来去上海工作,所以我非常喜欢北京的饮食”,最后那个“北京”要和最开头的“北京”建立关联,中间隔了十几个单词。对RNN而言,这条路要经过十几个时间步的隐状态传播,信息早已“失真”。

1.2 注意力机制的最初角色:翻译时的“临时查资料”

其实注意力机制在Transformer之前已经存在。2014年Bahdanau等人把注意力引入神经机器翻译,基本思路是:解码器在生成每个目标语言单词时,不要只盯着编码器的最后一个隐状态,而是对所有源语言位置的隐状态做加权求和,权重由当前解码状态和每个源位置的相关性决定。

这个机制在当时的理解很通俗:翻译某个目标词的时候,模型会“回头看一眼”源句里哪些词更重要。比如翻译“苹果”这个词时,注意力权重会主要落在源句中对应的“apple”上。

但注意,在那个时候,注意力只是RNN的“补丁”。主干依然是循环网络,注意力只负责在解码阶段做信息检索。没人敢说把循环网络整个扔掉。

《Attention Is All You Need》的贡献恰恰在于一个极具魄力的主张:不用RNN、不用CNN,把注意力机制直接作为整个模型的主干。换句话说,注意力不只负责“查资料”,连“读资料”“写报告”全包了。论文后面的实验证明,这一拍脑袋式的激进想法,竟然在翻译效果和训练速度上双杀当时的强基线模型。

2. 总体架构拆解:Transformer由哪些模块组成

2.1 Encoder-Decoder整体骨架与数据流向

Transformer是一个标准的Encoder-Decoder架构,整个网络由编码器(Encoder)和解码器(Decoder)两部分组成。

编码器负责把输入序列“理解”成一组上下文表示,解码器负责根据这些表示逐个生成输出序列。论文里的配置是Encoder和Decoder各6层(N=6),所有层都用相同的结构,但参数各自独立。

如果只看整体数据流,一次前向传播大概是这样:

  1. 输入句子中的每个词先映射为词向量(Embedding),维度d_model=512。
  2. 在词向量上叠加位置编码(Positional Encoding),给模型注入词的顺序信息。
  3. 向量序列进入Encoder,经过6层编码块,每层都是“多头自注意力 + 前馈网络”的组合,并且在每个子层外都有残差连接和层归一化。
  4. Encoder的输出作为Decoder的“记忆库”,Decoder在每层里通过“交叉注意力”不断从这个记忆库中提取信息。
  5. Decoder在生成第i个位置时,会屏蔽掉第i个位置之后的词,保证自回归特性,也就是只能看到已经生成的词。
  6. 最后通过一个线性层+Softmax,输出下一个词的概率分布。

整个过程中,核心信息交换机制只有一个:注意力机制。这也是“Attention Is All You Need”这个名字的由来。

2.2 编码器层与解码器层的差异对比

Encoder的每一层有两个子层:

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

每个子层后面都接一个残差连接和LayerNorm,论文中用公式表示为:

LayerNorm(x + Sublayer(x))

Decoder的每一层则多了一个子层,共三个:

  • Masked Multi-Head Self-Attention(带掩码的多头自注意力)
  • Multi-Head Cross-Attention(交叉注意力,也叫Encoder-Decoder Attention)
  • Position-Wise Feed-Forward Network

多头自注意力里的“自”字意味着Q、K、V都来自同一个输入序列,模型在输入序列内部建立位置之间的关联。交叉注意力不一样,它的Q来自Decoder上一层的输出,而K、V来自Encoder的输出,这样解码器就能“读取”编码器对源句的完整理解。

我刚开始读论文时容易犯的一个错误是把这两个注意力混淆。其实记住一句话就行:Self-Attention负责“内部交流”,Cross-Attention负责“外部吸收”。

2.3 超参数与数据形状变化

论文中Base模型的核心超参数如下表所示:

  • 层数 N:6
  • 隐藏维度 d_model:512
  • 多头注意力头数 h:8
  • 每头维度 d_k = d_v:64
  • 前馈网络中间层维度 d_ff:2048
  • 总参数量:约6500万
  • Dropout:0.1
  • Label Smoothing:0.1

为了真正理解Transformer,我建议你把数据张量在每个模块前后的形状变化写一遍。假设输入一个批次,形状为(batch_size, seq_len):

  • 经过Embedding后变成(batch_size, seq_len, 512)
  • 加上位置编码,形状不变
  • 进入多头自注意力:Q/K/V分别由输入乘上权重矩阵得到,形状都是(batch_size, seq_len, 512),然后拆成8个头,变成(batch_size, 8, seq_len, 64),注意力计算结束后拼回去又变回(batch_size, seq_len, 512)
  • 经过残差+LayerNorm,形状不变
  • 进入前馈网络:先放大到(batch_size, seq_len, 2048),再缩回(batch_size, seq_len, 512)
  • 6层堆叠结束后输出仍然保持(batch_size, seq_len, 512)

很多搞不清楚Transformer的人,卡就卡在这:注意力拆了又合,维度却没变。本质上Transformer的每一层都是在保持序列长度和特征维度不变的情况下,不断对特征表示做精炼。

3. 核心机制拆解:注意力为什么撑得起整个架构

3.1 缩放点积注意力:Q、K、V到底在做什么

注意力机制的核心是缩放点积注意力(Scaled Dot-Product Attention),公式如下:

Attention(Q, K, V) = softmax(QK^T / √d_k) V

这个公式初看有点抽象,但拆开来说并不复杂。

Q(Query)表示“我在找什么”,K(Key)表示“我是什么”,V(Value)表示“我有什么信息”。整个过程就是:用Q去和每个K做点积,得到相似度分数;再用Softmax把这些分数变成权重;最后用权重去加权求和所有V。

生活化一点的类比是:你在图书馆找一本讲机器学习的书。Q是你脑子里的书名关键词,K是每本书封面上的标签,V是书的内容。你先把关键词和所有书的标签比对一遍,找到相关度最高的几本,然后按照相关程度去翻阅这些书的内容,提取关键信息。

为什么点积可以衡量相似度?两个向量方向越一致,点积越大。这个直觉在线性代数里很清楚,也是注意力计算里最常见的选择。

那为什么要除以√d_k?论文里明确说了:当d_k比较大时,QK^T的点积数值会变得很大,把Softmax推进梯度极小的饱和区,导致训练困难。除以√d_k是为了把点积结果的方差压回1左右。假设Q和K的每个分量都是均值为0、方差为1的独立随机变量,那么点积的方差会等于d_k,标准差为√d_k。除以√d_k后,方差归一,Softmax就能维持一个合理的梯度。

这个小细节后来被无数工作沿用,但你真去问一些调过模型的人,未必能说出这层数学原因。这就是论文比博客和二手教程更值得读的地方。

3.2 多头注意力:让模型从多个角度“看”序列

单个注意力头只能在一套语义空间里做匹配,论文选择了多头注意力(Multi-Head Attention)来让模型同时关注不同信息子空间。

实现方法是:把d_model=512的向量投影成h=8组,每组维度64,分别做独立的注意力计算,得到8个输出后再拼接回去,最后经过一个线性投影。

为什么不直接用一个更大的注意力头?论文的消融实验给了一个很直观的答案:多头效果显著优于单头。因为不同的头捕捉的是不同类型的依赖关系。有的头关注句法关系(代词指向哪个名词),有的头关注相邻词的局部关系,有的头关注长距离的核心信息。让8个头并行,相当于请了8个专家从不同角度审查同一份材料,最后汇总意见,自然比一个专家拍板更全面。

一个常见的误解是:多头注意力是不是把参数量增加了几倍?其实不会,因为每个头的维度变成了原来的1/h,总的计算量和单头大注意力基本一致。把512维拆成8个64维,算完再拼回来,矩阵运算总量没有膨胀。

3.3 位置编码:让没有顺序观念的注意力“知道”顺序

注意力机制本身是无序的。你把一句话里的词随便打乱顺序,注意力的计算结果不会改变,因为加权求和只需要QK匹配分数,不包含位置信息。这当然不行,语言是强顺序依赖的。

论文采用了一种正弦位置编码方案:

PE(pos, 2i) = sin(pos / 10000^(2i/d_model)) PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

其中pos是词的位置索引,i是维度索引。不同的维度对应不同的正弦波频率。这样设计的一个精妙之处在于:对于任意固定的偏移k,PE(pos+k)都可以表示为PE(pos)的线性函数。也就是说,模型很容易通过线性变换学到相对位置关系。

论文实验证明,可学习的位置编码和正弦位置编码效果几乎没有差别,所以最终选择了正弦方案,因为它不需要额外训练参数,而且理论上可以外推到训练时没有见过的序列长度。

后来业界演化出了很多替代方案,比如GPT用的可学习位置编码、现在大模型广泛使用的RoPE旋转位置编码、还有ALiBi这类加偏置的方案。但核心思想都是一样的:位置信息必须显式注入模型,只是注入方式各有侧重。

3.4 两种掩码机制

Transformer里有两处用到了Mask,容易混淆。

第一处是Padding Mask。因为训练通常是按batch做的,一个batch内的句子长短不一,短句需要填充到和最长句一样的长度。填充的部分没有实际语义,注意力计算时要屏蔽掉,否则模型会把无效位置的信息也加权进来。实现方式很简单:在填充位置的注意力分数上加一个极大的负数,Softmax之后权重就趋近于0。

第二处是Look-Ahead Mask,只用在Decoder的Self-Attention里。解码器是自回归生成的,预测第i个词时,只能看到第1到第i-1个词,不能提前看到后面的词。实现时构造一个上三角矩阵,将上三角部分全部置为负无穷(比如-1e9),这样每个位置在计算注意力时只能“看”到自己左侧的信息。

这个掩码机制是序列生成任务能不能正确训练的关键。很多人手写Transformer出bug,最后发现都是Mask加错了位置或者形状对不上。

4. 容易被忽略的工程细节:残差、归一化与前馈网络

4.1 残差连接配套LayerNorm的奥秘

Transformer每个子层都在做同一件事:先算子层结果,然后做残差连接,最后做层归一化。这个“先残差后归一化”的顺序,后来被称为Post-LN。

残差连接解决的是深层网络训练中的梯度消失问题:梯度可以直接从上层“抄近路”传回下层,不用每次都穿透整个子层结构。这让模型可以堆到几十层、上百层而不至于训练崩溃。

LayerNorm和BatchNorm的区别值得多说一句。BatchNorm是在Batch维度上做统计归一化,但在NLP场景里有两个问题:一是序列长度动态变化,不同batch的统计量不稳定;二是当batch size比较小时,BatchNorm的均值方差估计会很抖。LayerNorm则是对单个token的特征维度做归一化,不依赖batch大小,且在训练和推理时行为一致,所以更适配Transformer这种结构。

后续很多工作发现,Post-LN在深层模型上训练不稳定,于是GPT系列采用了Pre-LN,也就是把LayerNorm挪到子层之前:x + Sublayer(LayerNorm(x))。Pre-LN的训练更稳定,但表示能力会有轻微损失。这个细节是工程师调模型时的宝贵经验,论文本身没提,但对理解后续架构演进很重要。

4.2 前馈网络:注意力只管“交流”,FFN负责“思考”

前馈网络(FFN)部分是Transformer里最容易被人忽略但其实很重要的模块。公式如下:

FFN(x) = max(0, xW1 + b1)W2 + b2

它在每个位置上独立做两次线性变换,中间夹一个ReLU激活函数,先扩大到2048维再缩回512维。

注意力机制本身是“token之间”的信息交换,属于线性加权,表达能力有限。FFN是对每个位置的特征做非线性变换,相当于每个词在被注意力“混合”之后,再独立地“思考”一遍,精炼自己的特征。在计算机视觉领域,ViT论文里甚至发现,FFN内部的隐藏层激活天然对应着图片里的某些模式类别,说明FFN承担了相当一部分“记忆和抽象”的功能。

至于为什么中间维度是2048而不是别的数,论文用的是4倍经验值。后来的很多模型也会用4倍,算是行业默认的“甜点值”。如果你压缩这个维度,模型容量会明显下降;但盲目扩大,收益递减且训练成本剧增。

4.3 训练技巧与优化器设置:论文里写得清清楚楚

论文的实验配置是国内很多二手教程不会细讲的,但恰恰是“复现论文”的重点:

  • 优化器采用Adam,β1=0.9,β2=0.98,ε=1e-9。
  • 学习率采用动态调度:先线性warmup,再按步数倒数衰减。公式是:

lr = d_model^(-0.5) · min(step^(-0.5), step · warmup_steps^(-1.5))

其中warmup_steps=4000。在训练初期,学习率从0线性爬升,防止模型一开始就跑飞;warmup结束后按step的倒数衰减,让模型慢慢收敛。

  • 正则化方面,使用了Residual Dropout,p=0.1,对每个子层输出、以及Embedding和位置编码相加后的结果都做Dropout。
  • 还用了Label Smoothing,ε=0.1。这个操作的直观效果是让模型不要对训练标签过于自信,降低过拟合,虽然会略微提高困惑度,但能提升翻译质量和准确率。

训练成本方面,论文里给的数据是Base模型在8张P100 GPU上训练12小时,大约跑了10万步。当时这个效率对机器翻译任务来说已经是质的飞跃,放到现在的大模型训练上更不敢想象。

5. 论文怎么证明自己:实验效果与消融分析

5.1 翻译任务上的降维打击

Transformer在WMT 2014英德翻译任务上BLEU值达到28.4,比之前最好的结果提升了2个BLEU以上;英法翻译任务上BLEU达到41.8,同时训练成本大幅降低。

当时对比的基线包括各种使用了注意力机制的RNN模型。论文还专门列出了不同模型达到相同效果所需的训练成本,Transformer在取得更高BLEU的同时,训练时间还比当时最强的LSTM系统少了差不多一个数量级。这种“效果更好+速度更快”的双重优势,让学术界几乎没有拒绝它的理由。

5.2 消融实验揭示了几个重要结论

论文做了大量消融实验,有几个结论对我理解架构非常有帮助:

  • 去除多头注意力(退化为单头),BLEU下降明显,验证了多头的必要性。
  • 把注意力头维度从64增大,性能反而下降;固定每个头维度为64是最佳选择。
  • 用可学习位置编码替换正弦位置编码,效果差异很小,说明关键不在于编码形式,而在于位置信息是否被注入。
  • 增大注意力计算时的核大小或使用更复杂的非线性注意力,并不能带来增益,点积注意力这个最简单的选择反而是最稳的。

消融实验的价值在于:它告诉我们哪些设计是必需品,哪些是锦上添花。即便到了今天,当有人问我“Transformer能不能精简一点”,我都会拿这些实验结果说事:别乱砍头,别乱换位置编码。

5.3 注意力的可解释性:可视化带来的惊喜

论文里还放了几张注意力可视化图,展示翻译时不同head的权重分布。比如有些head会在句法层面将动词和其主语对齐,有些head会关注相邻词之间的局部依赖,有些head则捕捉长距离的“核心词呼应”。

这种可视化给了研究者极大的直观信心:模型没有学疯,它学到的关系确实和人对语言的理解方式有相当程度的重合。这也是后来大量“模型可解释性”工作的重要起点。

6. Transformer架构的后世影响:从NLP到CV再到千行百业

6.1 预训练时代的分叉:BERT走Encoder,GPT走Decoder

Transformer出现后,NLP领域迅速分化出两条路线。

BERT选择堆叠Transformer的Encoder,通过完形填空式的预训练任务学习双向上下文表示。这种架构擅长“理解”,在分类、阅读理解、命名实体识别等任务上表现极强。

GPT则选择堆叠Decoder,利用自回归的因果语言模型做预训练。这种架构擅长“生成”,给定前面的词预测下一个词。后来的GPT系列不断验证了“大力出奇迹”的路径:模型够大、数据够多,Decoder-only就能涌现出惊人的通用能力。

从2023年以来的大模型格局看,Decoder-only路线成了绝对主流。原因有很多,包括因果掩码和自回归生成天然适配规模化、训练目标统一、部署链路简洁等。但追根溯源,底子都是Transformer这个架构。

6.2 视觉Transformer:把图像切成单词

Transformer在NLP证明了自己之后,很快被移植到计算机视觉领域。

ViT(Vision Transformer)做了一个非常“粗暴”的迁移:把图像切成一堆固定大小的patch,每个patch拉平成向量,再加位置编码,然后直接送进标准的Transformer Encoder。结果发现只要预训练数据足够大,ViT在图像分类上能逼平甚至超越同规模的CNN。

随后Swin Transformer进一步解决了一个实际问题:ViT的全局自注意力复杂度随图像分辨率平方增长,高分辨率图片根本跑不动。Swin通过“层次化结构 + 窗口局部注意力 + 跨窗口连接”,把复杂度降回线性,在检测、分割等密集预测任务上全面超过CNN基线。

再往后,像HGFormer这类工作开始尝试把超图学习与Transformer结合,探索更高阶的视觉关系建模。Transformer从一个机器翻译模块,变成了通用特征提取器,几乎是“哪里有特征建模,哪里就有Transformer”。

6.3 手写Transformer是理解架构最快的路径

如果你想彻底吃透这篇论文,我最推荐的方式是动手写一遍Transformer。代码框架不复杂,关键是把几个张量形状吃透。比如手写一个单层Encoder的Self-Attention,流程大概是:

  1. 输入形状(batch, seq_len, d_model)
  2. 生成Q、K、V,形状均为(batch, seq_len, d_model)
  3. 拆分多头,变形为(batch, heads, seq_len, d_k)
  4. 计算注意力分数(batch, heads, seq_len, seq_len),除以√d_k
  5. 应用Mask(若有),把需要屏蔽的位置替换为负无穷
  6. Softmax归一化
  7. 乘上V,得到(batch, heads, seq_len, d_k)
  8. 合并头,投影回d_model

这个流程跑一遍,你会对Transformer的每个细节都有肌肉记忆。反正我当初写完之后,再读其他模型源码就轻松了很多。

另外一个容易被忽略的实操点:如果训练时模型不收敛或者NaN,首要排查顺序是学习率是否过大、Mask形状是否正确、LayerNorm是Pre还是Post、残差连接是否加在归一化之前。这些坑我基本都踩过一遍。

6.4 读论文的正确姿势:三遍法

以我反复阅读这篇论文的经验,建议采用三遍读法。

第一遍先看图。把论文里的架构图、表格看一遍,只建立整体印象,不纠结公式。

第二遍抠公式。逐行推导注意力公式、位置编码公式、学习率公式,把每个符号的含义和维度都搞清楚。

第三遍看实验设计。理解消融实验到底在证明什么,训练超参数为什么这样设置,这样才能从“懂原理”进阶到“能复现”。

读论文最大的收益从来不是记住架构图,而是理解作者在每个设计点上的取舍逻辑。这些逻辑才是可以迁移到你自己工作中的真正财富。

最后再分享一个我个人的小习惯:我会把论文里精华的几段原文打印出来贴在工位上。隔一段时间再回头翻一眼,每次都能看出一点点新东西。好的论文就像好的工具,价值不会被时间稀释,只会随着你的经验积累被挖掘得更深。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询