Transformer 为什么总是把残差连接和 LayerNorm 放在一起:让深层训练更稳定
围绕残差连接与层归一化结构,解释 Add & Norm 如何保留信息、稳定特征尺度并帮助梯度穿过多层 Transformer。
相关工具
文中那个 Add & Norm 结构
资料 在介绍编码器结构时特别提醒:每个编码器的每个子层,包括 Self-Attention 和 FFN,都有一个残差连接,再执行层标准化。这个结构常被简写为 Add & Norm,其中 Add 指残差相加,Norm 指 LayerNorm。
设子层输入为 x,子层计算结果为 F(x),最直观的写法是先得到 x + F(x),再进行 LayerNorm。这里的 F(x) 可以是多头注意力,也可以是位置前馈网络;两种子层都沿用同样的基本思路。
它们放在一起并不是因为 LayerNorm 会自动产生残差,或者残差会自动完成归一化,而是两种机制分别解决不同问题:一条路径保留和传递信息,归一化则控制合并后表示的数值尺度。

子层输出与原输入做残差相加,再经过 LayerNorm,输入输出保持相同的模型维度。
残差连接为什么要绕过子层
如果每个子层都必须完全替换输入,深层网络中的信息只能沿着一条很长的变换链向前传递。某一层的变换如果不适合当前输入,早期表示可能逐渐被削弱,梯度也要连续穿过许多复杂函数。
残差连接在子层旁边提供一条直通路径,让输出变成原输入加上子层带来的更新。子层不必从零构造完整表示,只需要学习“在原有信息上增加什么变化”。
这并不意味着子层只能做很小的调整,而是给模型保留了一个稳定的基线。如果某层需要显著改变表示,F(x) 可以提供较大更新;如果暂时不需要,原输入仍然可以沿残差路径继续向后传递。
残差如何帮助梯度向底层传播
反向传播时,残差相加会让梯度同时经过主路径和子层路径。主路径近似保留了一个直接的梯度通道,子层路径则携带具体变换产生的梯度更新。两条路径的贡献相加后,底层更容易接收到有效信号。
如果没有残差,梯度需要完全依赖每个子层的导数连续传递;层数增加后,梯度可能变得很小或很不稳定。残差不是从数学上保证永远不会梯度消失,但它显著改善了深层网络的传播条件。
这也是 Transformer 可以堆叠很多编码器或解码器层的重要原因之一。多层结构带来更强表示能力,同时也带来更长的优化路径,残差连接为这条路径提供了稳定支撑。

梯度可以沿残差主路径直接回传,也可以经过注意力或 FFN 子层回传,两条路径共同帮助深层训练。
LayerNorm 具体稳定了什么
残差相加会把输入和子层输出合并。随着层数增加,不同层输出的数值尺度可能发生变化,某些特征维度可能变得特别大,另一些维度可能特别小。LayerNorm 会针对单个位置的特征维度进行归一化,使后续计算面对更可控的表示范围。
LayerNorm 不是把所有 token 混在一起计算,也不是沿序列维度做注意力。它通常在每个位置内部处理 d_model 个特征,因此不会改变序列中不同位置之间的语义关系,只调整当前向量的尺度和中心位置。
归一化之后一般还会使用可学习的缩放和偏移参数,让模型在稳定数值范围的基础上保留恢复或调整表示分布的能力。它的作用是提供稳定条件,不是直接替模型完成语义理解。
为什么残差和 LayerNorm 不是一个机制
残差连接回答的是“原输入如何继续向后传递”,LayerNorm 回答的是“合并后的特征如何保持合适尺度”。一个偏向信息路径和梯度路径,一个偏向数值分布和训练稳定性。
如果只有残差,没有归一化,信息虽然更容易传递,但多层相加后仍可能出现数值尺度漂移;如果只有归一化,没有残差,输入信息仍然要完全穿过每个子层,深层优化会缺少直接通道。
Add & Norm 把两者放在同一子层边界上,让每次更新都同时具备“保留原表示”和“控制新表示尺度”的条件。Transformer 结构图中反复出现这个模块,就是因为注意力和 FFN 都需要这两类帮助。
Post-Norm 和 Pre-Norm 有什么区别
一种常见写法是 Post-Norm:先计算子层 F(x),与 x 做残差相加,再对结果做 LayerNorm,可以写成 LayerNorm(x + F(x))。这是原始 Transformer 结构中常见的表达方式。
另一种写法是 Pre-Norm:先对输入做 LayerNorm,再把归一化后的结果送入子层,最后与原输入做残差相加,可以写成 x + F(LayerNorm(x))。两者都包含残差和归一化,但计算顺序不同。
Pre-Norm 通常能让深层模型的梯度路径更直接,训练往往更容易稳定;Post-Norm 则保持另一种子层输出归一化布局。阅读实现时不能只搜索 LayerNorm 是否存在,还要确认它位于残差相加前还是后。

Post-Norm 在残差相加后归一化,Pre-Norm 在进入子层前归一化,二者计算顺序不同。
编码器和解码器都需要这套结构
编码器的 Self-Attention 和 FFN 子层都可以配套残差与 LayerNorm。解码器的掩码自注意力、Encoder-Decoder Attention 和 FFN 也需要类似的处理。解码器多一个交叉注意力子层,就相应多一组子层边界上的稳定结构。
残差连接的输入输出需要保持相同的 d_model 维度,因此注意力和 FFN 即使在内部改变了表示空间,最终也要映射回模型维度。LayerNorm 则在每个子层边界控制这一表示的特征尺度。
这套结构让编码器和解码器可以反复堆叠。不同子层负责不同的信息交互,但都能共享“原表示 + 子层更新 + 归一化”的深层组织方式。
如何判断 Add & Norm 接入是否正确
先看形状:残差相加的两路张量必须具有相同形状,通常都是 [batch, seq, d_model]。如果 FFN 中间维度扩大后没有映射回来,或者注意力输出没有回到 d_model,残差就无法逐元素相加。
再看顺序:确认实现采用的是 Post-Norm 还是 Pre-Norm,不能把一种结构的公式套到另一种代码上。还要检查每个子层是否都有对应的残差,而不是只在整个编码器堆栈末尾做一次。
最后看数值和训练曲线。LayerNorm 输出的特征尺度应保持相对稳定,残差路径应确实连接了子层输入和输出。若深层训练异常,优先检查归一化位置、残差分支和学习率等基础结构。
把残差和 LayerNorm 放回 Transformer 主线
Transformer 的注意力和 FFN 负责产生表示更新,残差连接负责保留原表示并提供直接梯度路径,LayerNorm 负责让更新后的特征尺度更可控。三者分工不同,却在每个子层边界上共同构成深层计算的稳定基础。
文中“每个子层都有一个残差连接,再执行层标准化”的描述,重点不在于记住一个固定方框,而在于理解为什么每个子层都需要自己的信息通道和尺度控制。只在网络最后统一处理,无法替代每层内部的稳定机制。
记住一句话:残差让表示和梯度有路可走,LayerNorm 让这条路上的数值不至于失控。Transformer 能够把注意力、FFN 和这些结构反复堆起来,靠的正是这种层级化的组织方式。
常见问题
Add & Norm 中的 Add 指什么?
Add 指子层输出与子层输入做残差相加,例如 x + F(x),随后通常再进行 LayerNorm。
LayerNorm 会在不同 token 之间混合信息吗?
通常不会。LayerNorm 主要在每个位置的特征维度内部进行归一化,Self-Attention 才负责位置之间的信息交互。
Pre-Norm 一定比 Post-Norm 更好吗?
不一定。Pre-Norm 往往更容易训练深层模型,但具体效果还取决于模型规模、初始化、学习率和整体架构。关键是确认实现顺序与训练配置匹配。