跳转至

残差连接与归一化

残差连接最初是为了解决什么问题?在 Transformer 中如何具体应用?

残差连接最初在ResNet中被提出,核心要解决的问题是深度网络的退化问题:当网络层数增加到一定程度后,训练误差和测试误差不降反升,这不是由过拟合引起的,而是优化困难导致的。从数学上看,深层网络可以看作是一系列非线性变换的复合,在反向传播时,梯度需要经过多层链式求导。每经过一层,梯度都可能被权重的谱半径缩放。如果大部分层的缩放因子小于1,梯度呈指数级衰减(梯度消失);如果大于1,则指数级爆炸。残差连接通过引入恒等映射的旁路,将层的输出从 F(x) 改为 F(x) + x。这样梯度可以沿着旁路直接传播,至少保证有一路梯度不受变换层的缩放影响,从而让深层网络的训练变得可行。

在Transformer中,残差连接的具体应用方式是将每个子层(多头自注意力和前馈网络)的输入直接加到其输出上:output = LayerNorm(x + Sublayer(x))。这意味着每个子层学习的是相对于输入的残差,而非完整的输出表示。这种设计带来的好处不仅是梯度流动的改善:它让模型可以更容易地学习“恒等映射”——如果某个子层对当前表示没有正面贡献,模型只需将其权重推向零,使得该子层的输出趋近于零,残差连接就能几乎原样保留输入。这样,深层Transformer实际上是在一个“默认恒等”的基础上逐步修正表示,每一层的任务被分解为“在已有表示上做微小的调整”,大大降低了优化的难度。

image.png


请画出 Pre-Norm 和 Post-Norm 的结构图,并解释流程差异。

Post-Norm(原始Transformer):

输入 x
  └→ [Multi-Head Attention] → 输出 attn_out
       └→ x + attn_out → LayerNorm → 输出 h1
  └→ [Feed-Forward Network] → 输出 ff_out
       └→ h1 + ff_out → LayerNorm → 输出 h2

归一化放在残差相加之后。子层输出先与输入相加,再通过LayerNorm。

Pre-Norm(现代标准):

输入 x
  └→ LayerNorm → [Multi-Head Attention] → 输出 attn_out
       └→ x + attn_out → 输出 h1
  └→ LayerNorm → [Feed-Forward Network] → 输出 ff_out
       └→ h1 + ff_out → 输出 h2

归一化放在子层之前。输入先经过LayerNorm,再进入注意力或FFN,然后与原始输入残差相加。相加后不再做归一化(或者仅在最后输出层做一次)。

流程差异的本质:

  • Post-Norm中,残差路径上的信号(x)会与经过变换的噪声(子层输出)混合后一起被归一化,归一化会重新缩放整个混合信号。这导致残差旁路的“纯净”梯度信号在归一化中被稀释,每一层都可能对梯度产生缩放效应,加深网络时梯度容易消失或爆炸。

  • Pre-Norm中,残差路径完全绕过了归一化,梯度可以通过残差连接直接从深层传到浅层而不受任何缩放。归一化只作用于进入子层的输入,控制子层的输入分布,但不影响残差梯度的流动。这使得深层网络的训练稳定性大幅提升,成为现在几乎所有大模型的标准。


为什么 Pre-Norm 通常比 Post-Norm 训练更稳定?梯度流动有什么不同?

本质差异在于残差分支上的梯度是否经过归一化层的缩放。

在Post-Norm中,子层的输出与残差输入相加后进入LayerNorm。LayerNorm的梯度包括对输入的缩放因子(与输入方差相关)。反向传播时,梯度流经LayerNorm会被该缩放因子乘上,不同层、不同位置的缩放因子不同且会随着训练动态变化。当层数很多时,这些缩放因子的乘积可能指数级放大或缩小梯度,导致训练不稳定。此外,Post-Norm在初始化阶段,残差分支的输出方差与主路径不匹配,需要精心设计初始化(如DeepNorm)来缓解。

在Pre-Norm中,残差路径从输出直接连到输入,完全绕过了LayerNorm。反向传播时,梯度可以沿着残差连接无障碍地流动,不受任何归一化层的缩放影响。归一化只用于调控进入子层的输入,相当于对子层的输入进行了“白化”预处理,使子层能更稳定地学习,但不阻碍梯度的跨层传播。这就像给每层加了一个输入调节器,而保留了一条畅通无阻的梯度高速公路。

此外,Pre-Norm使得子层(注意力或FFN)的输入分布更稳定——LayerNorm将输入归一化到均值为0、方差为1(或RMS归一化),这样不论前面层的输出如何漂移,进入当前子层的分布始终可控。这使得学习率可以设置得更大,训练收敛更快,且对初始化不敏感。


LayerNorm 的计算公式是什么?它是在哪个维度上进行归一化的?

LayerNorm的公式为:

image.png

其中:

  • xx 是输入张量,在Transformer中形状为 (batch, seq_len, d_model)

  • μμ 和 σ2σ2 分别是沿着最后一个维度(d_model维度)计算的均值和方差。即对于每个token的表示向量,独立计算其自身的均值和方差,跨token之间不共享统计量。

  • ϵϵ 是防止除零的小常数。

  • γγ 和 ββ 是可学习的缩放和偏移参数,形状与 d_model 相同。

  • ⊙⊙ 表示逐元素乘法。

归一化的维度:LayerNorm是对每个样本的每个位置的特征向量进行归一化。与BatchNorm完全不同:BatchNorm是对整个batch中所有样本的同一特征维度进行归一化。Transformer采用LayerNorm的根本原因是文本序列是变长的,且不同样本的序列长度不同,batch内统计量不稳定;同时自回归解码时,序列长度逐步增长,无法用BatchNorm做全局统计。LayerNorm对每个token独立归一化,天然适合序列模型。


RMSNorm 与 LayerNorm 的本质区别是什么?为什么 RMSNorm 能节省计算?

LayerNorm需要计算两个统计量:均值(中心化)和方差(缩放)。RMSNorm则只计算均方根值(Root Mean Square),完全去掉了中心化步骤。公式为:

image.png

节省计算的原因:

  • 省去了均值计算:无需对 d_model 维度的元素求和再除以维度。

  • 省去了减去均值的操作:减少了一次逐元素的减法。

  • 省去了偏移参数 β 的存储和计算(RMSNorm通常只保留缩放参数 γ,不保留 β )。

对于大模型,这些节省在每一次前向和反向传播中累积,总体可减少约5-10%的归一化计算开销。考虑到Transformer中每个子层前后都有归一化,层数众多,节省相当可观。LLaMA、Llama 2、Mistral等主流模型均采用RMSNorm。


RMSNorm 去掉了什么?这样做为什么没有严重损害性能?

RMSNorm去掉了中心化(减去均值)操作和偏移参数 ββ

为什么去掉中心化没有严重损害性能?

  • 后续的线性变换(如注意力中的QKV投影、FFN中的全连接层)本身就可以学习到对输入进行平移。如果数据没有中心化,权重矩阵的偏置项(如果有)或者权重的列均值可以吸收这个偏移。现代Transformer中很多已去除线性层的偏置,此时RMSNorm去中心化的影响更明显,但实验表明,模型可以通过调整缩放参数 γγ 和后续权重来补偿。

  • 从特征学习角度看,重要的是不同维度的相对大小和方差。RMSNorm保留了每个token向量的范数(通过RMS缩放),确保了特征的尺度一致。而均值偏移只是一个全局平移,深层网络可以通过学习来适应这种平移。实际上,有理论分析认为,均值的移除在某些情况下甚至可能破坏有用的特征偏移信息,但实践表明RMSNorm至少与LayerNorm持平,甚至在某些任务上略优。

  • RMSNorm仍然保留了最关键的操作:根据特征的RMS进行缩放,这控制了激活值的范围,防止方差爆炸或消失。因此它继承了LayerNorm最主要的稳定训练的功能。

所以,RMSNorm相当于LayerNorm的一个极简有效版本,去除了对性能影响较小的组件,实现了计算加速。


DeepNorm 是如何改进 Post-Norm 的,使得训练更深的 Transformer 成为可能?

DeepNorm是微软在DeepNet中提出的一种改进Post-Norm的方案,目的是稳定训练数百甚至上千层的Transformer。其核心思想是通过精心设计的初始化和残差缩放来抑制Post-Norm中模型更新的幅度。

具体做法:

image.png

这样做的效果是,在训练初期,每个子层的输出几乎为零,整个模型近似恒等映射。梯度在反向传播时,由于残差分支被减弱,Post-Norm中的归一化层对梯度的缩放效应被抵消了,深层梯度不至于消失或爆炸。随着训练进行,模型逐渐增大子层的贡献,但始终被 DeepNorm 的结构所约束,更新量保持可控。

DeepNorm通过残差缩放解决了Post-Norm中“越深归一化层越多,梯度乘积越不稳定”的问题,在千层Transformer上取得了成功训练。


在 Pre-Norm 架构中,残差连接的分支输出乘以一个小于 1 的常数有什么作用?

image.png

作用:

  • 稳定早期训练:在训练开始时,子层权重是随机初始化的,其输出可能带有很大的方差。乘以一个小常数可以有效抑制子层输出的幅度,使得模型在早期表现得接近恒等映射,输出主要由残差旁路的原始输入决定。这避免了初期激活值爆炸,使得梯度流动更加平稳。

  • 模拟更浅的网络:小α意味着模型需要更大的学习率或更长的训练时间来让子层发挥作用。这实际上创造了一种从浅到深的“课程学习”效应:模型初始时更依赖浅层表示,随着训练逐步加深影响。

  • 与DeepNorm结合:在DeepNorm中,这种缩放被系统化,与初始化配合,使得Post-Norm也能训练深层网络。在Pre-Norm中,虽然稳定性已有改善,但极深时仍可能需要这种缩放来进一步控制。

需要注意,过小的α会减慢收敛速度;过大则起不到稳定作用。实践中,这个值通常由初始化策略(如Xavier、Kaiming)隐式控制,或显式设置为与层数相关的衰减因子。


训练非常深的 Transformer 时,如何初始化残差连接的权重以确保信号传播?

确保信号在深层Transformer中平稳传播需要两个条件:前向传播时激活值方差稳定,反向传播时梯度方差稳定。针对残差网络的初始化策略主要包括:

  • 标准初始化的修正:对于Pre-Norm Transformer,通常使用Xavier或Kaiming初始化来初始化线性层的权重,使得前向方差保持1。因为Pre-Norm中残差连接绕过了归一化,主要需要控制子层内部的方差。

  • 残差分支的零初始化:将每个子层的最后一个线性层(如FFN的W2、注意力输出投影)初始化为零,这样子层的初始输出为零,整个模型初始化为恒等映射。这是最直接的保障,但可能限制了早期的学习速度。

  • Fixup初始化:对于无归一化的深层残差网络,Fixup通过缩小某些层的权重(如将残差分支的最后一层权重按层数平方根缩放),并设置特定的偏置,来保持信号平稳。

  • T-Fixup:专门针对Transformer的Fixup,结合零初始化和部分参数缩小,使得无需LayerNorm也能训练深层Transformer。

  • DeepNorm:如前所述,系统化地缩放部分权重和残差,并设计对应的初始化参数,直接针对Post-Norm深层训练。

  • MAGNETO/ReZero:在每个子层的输出上乘以一个可学习的零初始化参数,训练初期全部为零,逐渐学习。

核心思想都是让网络在初始时接近恒等映射,从而使得梯度能够无衰减地反向传播。


为什么 LayerNorm 需要可学习的缩放和偏移参数?去掉会怎样?

缩放参数 γ 和偏移参数 β 为归一化后的表示提供了恢复原始表达能力的可能。如果没有 γβ,LayerNorm强制输出的每一维都是均值为0、方差为1的分布。这会限制模型的表示能力:模型可能需要在某些维度上具有更大的方差来编码重要信息,或者需要非零均值来区分不同的特征模式。

去掉这些参数后,每一层的输出都被严格归一化到固定的均值和方差,网络的灵活性大幅下降。实验表明,去掉可学习参数的LayerNorm会导致性能明显下降,尤其是在深层网络中。不过,γβ 并非在所有情况下都不可或缺——RMSNorm就成功去掉了 β,只保留了 γ。这暗示偏移参数的重要性可能低于缩放参数。缩放参数允许模型动态调整各维度的信息量,这是最关键的部分;而均值偏移可以被后续线性层的偏置或权重部分吸收。


在推理部署时,LayerNorm 或 RMSNorm 可以与前面的线性层融合吗?如何融合?

可以。LayerNorm/RMSNorm在推理时可以与紧邻的前一个线性层垂直融合,以减少内存访问和计算步骤。

融合原理:

image.png

image.png

对于LayerNorm(包含减均值),融合更复杂,因为需要均值的计算,但均值和RMS可以一次遍历同时计算。通用的融合做法是使用自定义CUDA kernel或利用推理框架(如TensorRT、ONNX Runtime)中的图优化,将MatMul + LayerNorm合并为一个算子。这可以减少显存带宽压力,加速推理。


为什么 Transformer 不能直接用 BatchNorm?分析其不适用的根本原因。

BatchNorm在Transformer中不适用的根本原因有几点:

  • 变长序列问题:文本序列长度不一,BatchNorm需要在每个特征维度上统计整个batch的均值和方差。为了做有效的batch统计,通常需要对序列进行padding到相同长度,并mask掉padding位置。但即使mask,padding位置的数值(通常为0)仍会影响统计量,导致均值和方差估计有偏,尤其当序列长度差异巨大时。

  • 自回归生成的不兼容:在解码器(如GPT)中,推理是自回归的,每次输入序列长度递增1。BatchNorm依赖完整的batch统计,对于单个样本自回归生成,无法计算有意义的batch统计量。即便训练时可以用整个batch,推理时无法保证一致的batch统计,导致训练和推理不一致。

  • 对batch size敏感:BatchNorm的效果高度依赖足够大且多样的batch size。NLP任务中batch size通常较小,尤其长序列时,batch内统计量噪声大,导致性能下降。而LayerNorm对每个样本独立计算,完全不受batch size影响。

  • 序列中不同位置的统计特性可能不同:文本中位置信息的差异性(例如句首和句尾)使得将所有位置的同一特征维度混合做归一化并不合理。

综上,LayerNorm因其独立于batch、独立于序列长度的特性,天然适配Transformer。因此,在Transformer中,LayerNorm被广泛采用。


在 Decoder 中,Pre-Norm 和 Post-Norm 对自回归生成的质量有何不同影响?

在自回归解码器中,模型逐token生成,每步的输出作为下一步的输入。

  • Post-Norm:每一步的生成过程中,残差分支与子层输出相加后进入LayerNorm。由于LayerNorm对整体进行重新缩放,在自回归步骤间,这种缩放可能导致早期生成的token表示随着后续归一化而发生微妙的“漂移”。从生成质量上看,Post-Norm可能导致长序列生成时的不稳定,有研究观察到Post-Norm Transformer在长文本生成时更容易出现重复和退化。

  • Pre-Norm:残差路径未经过归一化,因此后续层的处理不会改变残差流上已生成token的原始信号。这使得历史信息能够更稳定地向前传递,对长序列生成的连贯性更有益。实验表明,Pre-Norm在自回归语言建模和长文本生成中往往优于Post-Norm,训练也更稳定。

不过,Post-Norm通过在训练初期具有更大的有效梯度(因为LayerNorm在残差合并后,实际上放大了有效步长),有时在浅层模型或特定任务上收敛更快。但在深层和长序列场景下,Pre-Norm的优势愈发明显。


请解释“残差流”的概念,以及信息如何通过残差连接在 Transformer 中流动。

残差流是指由残差连接形成的一条贯穿整个Transformer的、信息可以近乎无衰减传播的路径。每一层的残差连接都将该子层的输入直接加到其输出上。如果我们将所有残差路径展开,最终输出可以看作所有层子层输出的加权和加上原始输入嵌入。由于每个子层的输入都是前面所有残差输出的累积,信息可以跨层直接流动,而不必完全依赖每一层的变换。

具体来说,输入嵌入经过第一层后,第一层的输出包含原始嵌入 + 第一层子层的残差。第二层的输入就是第一层的输出,第二层在此基础上加上自己的残差,以此类推。最终输出 = 嵌入 + Σ(每层子层的输出)。这种结构意味着:

  • 浅层特征可以直接传递给深层,不会被中间层“扭曲”或“遗忘”。

  • 梯度反向传播时,每层的梯度可以沿残差流直接传到浅层,而不仅仅依赖通过子层变换的路径。这形成了梯度高速公路。

  • 模型的学习可以看作是在原始表示上逐步叠加修正,每层只需要学习与当前最优表示的差异,降低了优化难度。

残差流是Transformer可扩展性的关键。因为它确保了即使层数很深,信号也不会彻底消失或爆炸。


当模型层数增加到数百层时,即使使用 Pre-Norm 也可能出现训练困难,为什么?有哪些更先进的归一化方法?

Pre-Norm虽然通过残差旁路保护了梯度,但数百层的深度仍会带来问题:

  • 残差累积效应:随着层数增加,残差流上累积的信息量越来越大,输出表示的整体幅度会逐渐增长(因为每层都会加上自己的输出)。即使每层的输出幅度不大,数百层累积下来也可能使信号变得巨大,导致前向激活值爆炸,反向梯度爆炸。

  • 子层输入分布漂移:尽管Pre-Norm在每个子层前都做归一化,但随着网络加深,残差流上的全局统计特性可能缓慢变化,深层子层的输入分布可能与浅层显著不同,使得统一的学习率不再适用。

  • 优化难度:极深网络的损失平面异常崎岖,即使梯度流动通畅,找到好的极小值仍然困难。

更先进的归一化方法:

  • DeepNorm:如前所述,专门为深层Post-Norm设计,但对Pre-Norm同样有效。通过残差缩放和权重初始化,显式控制每层子层输出的幅度,使其随层数衰减,防止残差累积过大。

  • ResiDual:将Pre-Norm和Post-Norm结合,在残差连接的两端都进行归一化,既保护了梯度,又控制了残差流的幅度增长。

  • Value-Residual Learning:将残差连接应用于Value矩阵或特定的组件,而非整个子层,细化信号控制。

  • LayerScale:在残差分支上引入可学习的逐通道缩放参数(初始化为小值),让模型自己学习每层子层的最佳贡献幅度。

  • NormFormer:在注意力之后添加额外的LayerNorm,并对残差分支进行缩放。


在多头注意力和 FFN 之后都加归一化,是否可以只加一个?这样做的效果如何?

可以只加一个,实际上很多现代架构正是这么做的。标准Pre-Norm只在每个子层之前加归一化,子层之后直接残差相加,不再加归一化。这等价于只用了“一个归一化”在两个子层之间(注意:每个子层各有一个归一化,但总共每层有两个归一化)。如果将这两个归一化减少为一个(例如只在注意力之前或只在FFN之前加),实验表明性能会明显下降,因为两个子层的输入分布无法被同时很好地控制。

如果只在层间加一次归一化(例如Post-Norm模式,在两个子层完成并相加后统一归一化),就是原始的Post-Norm设计,缺点前面已分析。

近年有探索更激进的简化:如只在整个Transformer的第一个层之前加一次归一化,后面完全无归一化。这需要极特殊的初始化(如T-Fixup)和残差缩放,但能够成功训练。不过,推理部署时这种全无归一化的模型更容易出现数值不稳定。

总之,每层两个归一化(Pre-Norm模式)是目前经验上鲁棒性最好、训练最稳定的配置。


为什么在极深 Transformer(如 1000 层)中,Pre-Norm 也会出现训练困难?有哪些更优方案?

即使Pre-Norm保护了梯度,1000层的深度仍面临挑战:

  • 残差信号的方差积累:Pre-Norm下,残差流是各层输出的累加。假设每层子层的输出方差为σ²,1000层累加的总方差约为1000σ²,信号会变得极大,可能超出数值范围。

  • 归一化层的累积缩放效应:虽然梯度不经过归一化,但前向时残差流经过层数的增加,归一化层的输入方差不断增大,RMSNorm/LayerNorm为了维持输出方差,会施加更大的缩放,这会影响子层的有效学习率。

  • 训练时间与资源:1000层意味着巨大的计算和存储开销,即使技术可行,经济上也需权衡。

更优方案:

  • DeepNorm:通过每层的残差缩放(乘以约1/√(2L)),强制残差贡献随层数衰减,总积累方差得到控制。在千层Transformer上已被验证有效。

  • LayerScale:在每个残差分支上使用可学习的通道级缩放,初始化为极小的值,优化过程会逐渐学习合适的贡献。

  • ResiDual:双重归一化加缩放。

  • 跳层连接/随机深度:训练时随机丢弃一些层,相当于训练了较浅网络的集成,正则化且减轻深层负担。


能否在 Transformer 中同时使用 LayerNorm 和 BatchNorm?如果分别用在不同的子层?

理论上可以,但不常见且可能引入复杂性。

  • 如果注意力子层用LayerNorm,FFN子层用BatchNorm,或者反过来:由于两种归一化的统计量计算方式和依赖完全不同,会导致不同子层的输出分布特性差异极大,优化器需要同时适应两种尺度,训练可能不稳定。

  • 在混合精度训练中,BatchNorm对batch size和数值精度敏感,而LayerNorm较鲁棒,两者混用会使数值管理更复杂。

  • 此外,BatchNorm在推理时用全局统计量,LayerNorm用单个样本,两者不一致会导致推理行为与训练有差异。

因此,实践中极少混合使用。Transformer家族几乎统一采用LayerNorm或RMSNorm。


一些模型在 Embedding 之后也加 LayerNorm,这样做的好处和弊端是什么?

好处:

  • 稳定输入分布:嵌入层的输出(可能加上位置编码)的数值范围和方差可能随词汇表和初始化变化。在嵌入后立即LayerNorm,可以将输入统一缩放到适合后续Transformer层的范围,降低对学习率的敏感性,加速收敛。

  • 减少嵌入维度与模型维度的不匹配影响:有时嵌入维度和模型隐藏维度不同,通过LayerNorm可以缓和这种不匹配。

弊端:

  • 增加了计算开销:每个token在进入第一层前额外做一次归一化,对于长序列有不可忽略的时间成本。

  • 可能限制表示:将嵌入向量的均值强制归零、方差归1,可能会丢失嵌入中已经学习到的某些重要先验分布(如低频词的较小模长)。这可能影响模型对稀有词的区分度。

  • 并非总是有益:BERT等早期模型中,嵌入后不接LayerNorm,而是依赖位置编码和后续层来处理分布。

目前,LLaMA、GPT-3等模型未在嵌入后立即加LayerNorm,而是直接进入Transformer层。一些轻量级模型或特定任务中会使用。


RMSNorm 去掉了中心化操作,但为什么模型仍然能有效学习?这是否说明中心化不重要?

RMSNorm的成功表明,在当前主流Transformer架构中,中心化并非必要的。深层网络中,均值偏移信息可以通过其他机制来传递或学习:

  • 线性变换(权重矩阵)的偏置(如果存在)可以自由地添加偏移。

  • 即使没有偏置,多层非线性叠加后的特征,其不同维度的均值偏移可以通过权重的组合间接产生。

  • RMSNorm的核心功能是控制每层激活的尺度(方差),防止方差爆炸或消失。尺度控制比中心化关键得多。

  • 实验表明,去掉中心化不仅未造成明显性能损失,还简化了计算。

但这不等于说所有场景下中心化都不重要。在一些对数值范围极其敏感的应用(如量化、某些正则化方案)中,中心化可能仍有其作用。只是对于大规模语言模型的预训练,RMSNorm已充分证明其有效性。


残差连接的“恒等映射”假设是否总是成立?有没有工作需要学习一个缩放或门控?

标准的残差连接强制恒等映射(即乘系数1)。但恒等映射假设并非总是最优。有些工作探索了可学习的缩放或门控:

  • Highway Networks:早期工作,使用门控来调节残差比例。

  • LayerScale:为每个残差分支引入一个可学习的逐通道缩放向量,初始化为极小值。训练中自动学习每个特征维度在当前层的最佳残差贡献。

  • ResiDual:在残差连接前后都使用缩放因子。

  • 门控残差连接:类似LSTM/GRU的门,让模型动态决定残差分支的通过量。

这些方法可以让模型更灵活地控制不同层的信息流,有时能提升训练稳定性和最终性能。但会增加参数量和计算开销。标准恒等映射因其简单、有效,仍然是大规模Transformer的首选。


如何从“残差流”的角度理解 Transformer 的表示演化?不同层的残差流主要携带什么信息?

从残差流的角度看,Transformer的初始表示(嵌入)直接贯穿所有层,并在每一层被加上该层子层的输出。因此,最终表示 = 嵌入 + Σ(每层残差)。这可以看作在原始嵌入上不断叠加修正。

信息演化:

  • 浅层:残差分量主要修正局部语法和词性信息,比如将相邻词的上下文融入当前token,或调整词义以适配语境。浅层注意力倾向于关注邻近位置。

  • 中层:开始出现语义组合,残差分量捕获短语级、句子级的语义结构,如同指代消解、语义角色标注等。注意力范围扩大。

  • 深层:残差分量进行高级推理和全局信息整合,如文本蕴含、情感倾向、任务特定的特征组合。注意力可能关注整个序列的关键部分。

通过残差流,浅层的基础信息可以无衰减地流向深层,深层可以在此基础上构建高层语义。这种“叠加修正”的模式也使得模型易于进行分析:可以通过检查残差分量(即每层子层的输出)来推断该层对最终表示的贡献。


在推理时,残差连接会和归一化一起被融合吗?融合后的计算图是怎样的?

可以。推理时的图优化通常将相邻的线性层 + 残差连接 + 归一化融合为一个高效的算子,减少内存读写。

融合后的计算图(以Pre-Norm RMSNorm为例):

原始流程:

1. z = RMSNorm(x)       # 读 x,写 z
2. a = z W_Q            # 读 z,写 a (Q)
3. 注意力计算 ...
4. 残差相加: x + attn_out
5. RMSNorm ...
6. FFN ...
7. 残差相加 ...

融合后,RMSNorm可以与上一个线性层(例如FFN的输出投影)合并为一个kernel:

融合线性+残差+归一化(x, W, γ, residual):
    z = x W               # 在寄存器中计算线性输出
    # 同时累积平方和
    rms = sqrt(mean(z^2))
    z = (z / rms) * γ     # 归一化
    output = z + residual # 残差相加

这样只需要一次读取x,一次写入output,中间步骤全部在寄存器/共享内存完成,大幅减少了显存带宽需求。现代推理引擎(TensorRT、ONNX Runtime、vLLM等)都能自动或手动实现这类融合,是Transformer推理加速的重要手段。