前三篇我们逐步拆解了 Transformer 的核心组件:注意力动机(为什么需要)、QKV 运算(怎么算)、多头注意力与位置编码(怎么同时看多个关系、怎么记住顺序)。今天我们把所有组件拼回一起,看 Transformer 的 整体骨架——编码器与解码器如何堆叠,残差连接和层归一化如何让它堆到很深,以及前馈网络在其中扮演什么角色。

最终要回答一个根本问题:为什么 Transformer 能堆到 96 层甚至更深,而 RNN 堆到 8 层就难以训练?


本篇问题边界

我们只讲 Transformer 的 宏观架构:编码器与解码器各自包含哪些子层,这些子层如何连接,为什么这些设计让模型能堆叠得更深、训练得更快。不重复前几篇讲过的注意力具体计算、多头细节或正弦波位置编码公式——它们已经装进每个子层内部了。


Encoder-Decoder:两半骨架

原始 Transformer 遵循经典的 Encoder-Decoder(编码器-解码器)结构 1

  • 编码器(Encoder):读取输入序列(如 "I love you"),为每个词生成一个上下文感知的表示
  • 解码器(Decoder):根据编码器的输出,逐词生成目标序列(如 "Je t'aime")

编码器由 N=6N=6完全相同的层 堆叠而成。解码器也是 N=6N=6 个相同层堆叠,但每层比编码器多一个子层 1

每个编码器层包含 两个子层

  1. 多头自注意力(Multi-Head Self-Attention)——让每个词看所有其他词
  2. 前馈网络(Feed-Forward Network, FFN)——逐位置独立加工

每个解码器层包含 三个子层

  1. 掩码多头自注意力(Masked Multi-Head Self-Attention)——只允许看已生成的词,不能偷看未来的词
  2. 交叉注意力(Cross-Attention)——解码器的 Query 去关注编码器的输出(Key 和 Value 来自编码器)
  3. 前馈网络——与编码器相同

每个子层外围都包裹着 残差连接 + 层归一化(图中标注为 "Add & Norm")12

Transformer 整体架构图:编码器(左)与解码器(右)的堆叠,每个子层外围有残差连接和层归一化

上图来自《动手学深度学习》,清晰展示了编码器 6 层堆叠、解码器 6 层堆叠,以及每个子层周围的 "Add & Norm" 结构 2


残差连接:让梯度有一条「高速公路」

堆叠多层神经网络的经典问题是 梯度消失:梯度从输出层往输入层反向传播时,每经过一层就乘以一个权重矩阵,网络越深,梯度越容易衰减到零。

残差连接(Residual Connection)的解决方案简单到令人惊讶:把层的输入直接加到输出上 3

输出=LayerNorm(x+Sublayer(x))\text{输出} = \text{LayerNorm}(x + \text{Sublayer}(x))

其中 Sublayer(x)\text{Sublayer}(x) 是注意力或前馈网络对输入 xx 的处理结果。关键操作是 x+x +——把原始输入直接加到处理结果上。

类比:高速公路。 想象一个多层建筑,每层都有复杂的加工车间。残差连接就是在每层旁边修了一条 直达电梯——信息既可以走车间(经过注意力或 FFN 的复杂变换),也可以直接坐电梯通过。梯度反向传播时,也可以走这条电梯直达输入层,几乎不衰减 4

这就是为什么 Transformer 可以堆到 96 层(GPT-3),甚至上千层(某些研究模型),而 RNN 堆到 8 层以上就很难训练。残差连接让信息在层间传递时多了一条「直达通道」,梯度不会因为层数加深而消失 34

层归一化:把数值拉回稳定区间

即使有了残差连接,深层网络中的数值仍然可能随着层数增加而变得过大或过小。层归一化(Layer Normalization, LayerNorm)就是用来解决这个问题的 2

LayerNorm 对每个 token 的向量做归一化:减去均值,除以标准差,然后再用可学习的缩放和平移参数调整。

LayerNorm(x)=γxμσ+ϵ+β\text{LayerNorm}(x) = \gamma \cdot \frac{x - \mu}{\sigma + \epsilon} + \beta

其中 μ\muσ\sigma 是当前向量所有维度的均值和标准差,γ\gammaβ\beta 是可学习的参数。

和 BatchNorm 的区别: BatchNorm 在一个 batch 的所有样本之间做归一化(依赖 batch 大小,对变长序列不稳定),而 LayerNorm 对 每个样本、每个位置独立 做归一化。自然语言处理中序列长度不一,LayerNorm 更适合 2

需要注意的是,原始 Transformer 使用的是 Post-LN 结构(先执行子层,再加残差 + LayerNorm) 1。但后来的实践中发现 Pre-LN(先 LayerNorm,再执行子层,最后加残差)训练更稳定,不需要学习率预热 5。现代大模型几乎都使用 Pre-LN。


前馈网络(FFN):每个词再做一次独立加工

注意力层的输出已经包含了上下文信息——每个词都「看过」所有其他词。但 注意力本身是线性加权求和,还需要非线性变换来增加模型的表达能力 1

前馈网络就是做这个的:它是一个两层的 MLP(多层感知机),对每个位置 独立且相同 地处理。

FFN(x)=max(0,xW1+b1)W2+b2\text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2

  • 第一层把 dmodel=512d_{\text{model}}=512 维映射到 dff=2048d_{ff}=2048 维(扩大 4 倍)
  • 中间用 ReLU 激活函数引入非线性
  • 第二层把 2048 维映射回 512 维

为什么叫「逐位置」(position-wise)? 因为同样的 MLP 网络对序列中每个位置的向量都应用一遍——但参数是 跨位置共享的(同一层内所有位置用同一组 W1,W2W_1, W_2)。不同层之间的参数不同 1

前馈网络贡献了 Transformer 中大部分参数——在 dmodel=512,dff=2048d_{\text{model}}=512, d_{ff}=2048 时,单层 FFN 的参数量约为 512×2048+2048×5122.1M512 \times 2048 + 2048 \times 512 \approx 2.1M,而注意力层的参数量约为 4×512×5121.0M4 \times 512 \times 512 \approx 1.0M(含 QKV 和输出投影)。FFN 的参数量大约是注意力层的两倍 16

类比:注意力像小组讨论,FFN 像个人思考。 注意力层让所有词互相交流,吸收别人的观点;FFN 让每个词独自消化吸收的信息,形成更丰富的内部表示。两者交替进行,一个负责「交流」,一个负责「思考」 6


为什么这套结构能高度并行、撑起大模型?

现在我们把所有组件连起来,看一个完整编码器层的数据流:

输入多头自注意力Add & NormFFNAdd & Norm输出\text{输入} \rightarrow \text{多头自注意力} \rightarrow \text{Add \& Norm} \rightarrow \text{FFN} \rightarrow \text{Add \& Norm} \rightarrow \text{输出}

这个流程重复 NN 次(原始是 6 次),然后进入解码器。

并行性来自两个层面:

  1. 序列内部并行: 自注意力中所有位置同时计算 QKQK^\topVV 的加权——矩阵乘法是 GPU 最擅长的操作。而 RNN 必须按顺序计算 h1h2hTh_1 \rightarrow h_2 \rightarrow \dots \rightarrow h_T,无法并行 7

  2. 层间稳定叠加: 残差连接让梯度能够无损地穿过数十层,层归一化防止数值爆炸。这两者让堆叠深度不再是训练瓶颈——你可以堆到 96 层、几百层,只要 GPU 内存装得下 5

实测对比:训练一个 8 层 LSTM 在 8 张 V100 上需要几天,而同等规模的 Transformer 可以在几小时内完成,训练速度提升 5–10 倍 17。在大模型时代,「训练得起」就是核心竞争力。


上下文关联

到此为止,我们已经完成了 Transformer 核心架构的完整拼图:

  • 第一篇: RNN 的串行瓶颈 → 注意力动机
  • 第二篇: QKV 运算 → 自注意力如何算
  • 第三篇: 多头注意力 + 位置编码 → 多个视角 + 顺序信息
  • 本篇: Encoder/Decoder 堆叠 + 残差连接 + LayerNorm + FFN → 完整架构 + 可规模化

下一篇可以进入 训练与推理细节——Masked Attention 如何保证自回归、KV Cache 如何加速推理、或者训练时的损失函数与优化策略。你感兴趣哪个方向?