Pre-Norm Transformer 为什么比 Post-Norm 更好训练?残差流的视角解释

我最早学Transformer的时候,照搬原始论文的代码,把LayerNorm放在每个子层的输出后面。训练一个4层的模型倒还好,但一加深到8层,loss就开始抽风,有时直接变成NaN。当时我以为是学习率没调好,折腾了一周,直到偶然把LayerNorm挪到子层之前(也就是Pre-Norm),一切突然变得顺滑。我当时的反应是:就这?挪个位置而已,居然有这么大差别?

AI technology illustration

这个问题困扰了我很久。直到后来我读了关于Transformer训练动态的几篇论文,又动手做了一堆实验,才慢慢想明白。这篇回答,我就用"残差流"的视角,把这件事讲透。

Post-Norm和Pre-Norm,到底差在哪

先看公式。一个Transformer Block里包含两个子层:多头注意力(MHA)和前馈网络(FFN)。假设输入是x,子层用Sub表示,原始Transformer(Vaswani et al., 2017)用的Post-Norm长这样:

x_{l+1} = LN(x_l + Sub(x_l))

Pre-Norm则长这样:

x_{l+1} = x_l + Sub(LN(x_l))

注意LayerNorm的位置。Post-Norm是先做残差相加,再归一化;Pre-Norm是先归一化,再让子层处理,最后加回残差。看起来只是顺序不同,但它们在信息传播上的性质截然不同。

残差流:一条不该被干扰的高速公路

"残差流"是这几年很流行的一个视觉化概念。把整个Transformer想成一条从左到右的主干道,输入数据从起点走到终点。每个Block不是要重建这条路,而是在路边做一些小型修正,让信息更好地流通。

Post-Norm的问题在于,它在每个Block的出口处对整条主干道进行了一次"全面改造"——LayerNorm会把信号重新缩放,均值拉到0,方差拉到1。这意味着,原始主干道上携带的信息尺度被强制改变了。更糟的是,这个缩放因子是随着当前层输出动态变化的,所以梯度在回传时,需要穿过这个动态缩放机制,非常容易导致梯度消失或爆炸。

Pre-Norm则完全不同。它让残差连接的主干保持原样,LayerNorm只作用于子层分支。子层学到的内容,是一个"增量",加回到原始输入上。这就像在道路旁边修匝道,车流在干道上继续行驶,匝道的加减速不影响主路。反向传播时,梯度可以沿着残差连接直接流回任意浅层,没有任何障碍。

我最早以为这只是一个工程优化,但后来看到On Layer Normalization in the Transformer Architecture里的实验,才意识到问题有多严重。他们在相同条件下分别训练Post-LN和Pre-LN的Transformer,发现Post-LN在深层网络里,每个block梯度的范数会出现剧烈的尖峰——某些层梯度暴涨,某些层梯度接近于零,优化器根本无从适应。而Pre-LN的梯度范数在整个训练过程中都非常平稳。这就是"训练崩坏"的直接原因。

你可以做个简单实验:随机初始化一个深层的Post-Norm Transformer,跑一次前向传播,统计每一层输出的范数。你会发现它从上到下波动剧烈——有些层涨到成百上千,有些层又接近零。而Pre-Norm则非常收敛,基本在一个量级。这是因为Pre-Norm的LN在每个block入口先规范化,子层输出自然被限制,而残差直通不改变尺度。

对比项 Post-Norm Pre-Norm
残差流是否恒等 被LayerNorm重新缩放 保持不变
反向梯度稳定性 深层出现尖峰 平稳
对学习率敏感度 很敏感,需要小学习率 不敏感,可用大学习率
大规模深层的表现 很难训练 稳定收敛

为什么Pre-Norm能稳定梯度?因为恒等映射没有断

从梯度反传公式上看,如果使用Pre-Norm,设每一层的输入为x_l,输出x_{l+1}=x_l+f(x_l),其中f(x_l)=Sub(LN(x_l))。那么在反向传播时,对x_l的梯度是

∂L/∂x_l = ∂L/∂x_{l+1} * (I + ∂f/∂x_l)

这里的单位矩阵I直接来自残差连接,它让梯度能够无损耗地向前传播。即使∂f/∂x_l的范数在某些层变得很小,只要有这个I在,梯度就至少能保持自身的范数。

而Post-Norm的公式是x_{l+1}=LN(x_l+f(x_l)),残差连接被包在LayerNorm里面,经过LN后,x_{l+1}不再是x_l+f(x_l)的简单形式,而是整体重新缩放后的结果。所以梯度中缺少一个干净的恒等项,取而代之的是LayerNorm的雅可比矩阵。这个雅可比矩阵在某些输入分布下可能产生规避性的缩放,导致梯度严重衰减。

再直观一点:把每个Block看作对输入进行"重写"。Post-Norm每次都会将上一层的输出"洗牌"后传给下一层,而Pre-Norm则保留原来的大部分信息,只附加一个小修正。显然,前者的信息在不同层之间更容易发生不可逆的混淆,后者的信息流则透明得多。

为什么GPT、LLaMA都倒向了Pre-Norm

翻一翻如今的主流模型架构,GPT-2、GPT-3、LLaMA、Mistral,无一例外都用了Pre-Norm。GPT-3的论文里甚至专门写道,为了稳定训练,他们使用了Pre-LayerNorm。这不是偶然,而是因为目标规模越来越大、层数越来越深,Post-Norm的脆弱性完全暴露了。

我自己的经验也印证了这一点。有次我尝试在一个12层、768维的模型上对比两种结构,Post-Norm在训练到某一步时loss突然飙升到正常值的十倍,然后永远降不回来;而Pre-Norm从头到尾没有这种问题。从那以后,我再也没有用Post-Norm做过新实验。

但Pre-Norm是不是就完全更好?也不是。它也有一个隐蔽的代价:由于每个Block只在残差分支上做更新,主干流始终保留早期的表示,这导致网络深处难以对原始输入进行大幅度改写。换句话说,模型的表达能力在某些任务上可能被削弱。这也解释了为什么有时Post-Norm在小模型和浅层网络上反而能取得略高的最终精度。

Post-Norm的复辟?DeepNorm和ResiDual

既然Post-Norm理论上表达能力更强,那么如果能解决它的训练不稳定性,是不是就能兼得鱼和熊掌?一些研究正是这么干的。

微软的DeepNorm提出在Post-Norm的基础上,对残差分支乘以一个小于1的缩放因子,并配合特殊初始化,让深层模型在Post-Norm下也能稳定训练。而ResiDual则同时保留Pre和Post两条残差路径,试图把前者的训练稳定性和后者的表达能力合二为一。

这些工作的存在说明,"Pre vs Post"不是一锤定音的是非题,而是稳定性和表达能力之间的权衡。我们目前默认用Pre-Norm,只是因为稳定性的优先级更高而已。

三个常见误区

误区一:LayerNorm放哪都一样

如果放的位置会影响残差流的性质,那当然不一样。Post-Norm的LN在残差相加之后,相当于对整体输出做变换,残差连接形同虚设。

误区二:Pre-Norm只是让输入标准化

它不止如此。Pre-Norm的关键在于标准化的对象是子层的输入,而不是残差流的输出,这保留了恒等映射。

误区三:Pre-Norm一定比Post-Norm精度高

不一定。在小模型浅层,Post-Norm有时能略胜一筹,只是Pre-Norm在稳定性和可扩展性上压倒性胜出。

说人话的总结

Pre-Norm之所以比Post-Norm更好训练,最本质的原因在于它保护了残差流这个"信息高速公路"。残差连接是Transformer能够堆到几十层的基石,而Post-Norm在每一层出口都设置了一个"收费站",强制重设信号尺度,这实际上破坏了恒等映射。Pre-Norm则把收费站挪到了侧道,让主干道畅通无阻,子层只负责在侧道上做修正。

所以训练稳定性不是玄学,也不是工程细节,而是架构设计对信息流的影响。下一次你看到一个新的Transformer变体时,不妨先问问:它的残差流还干净吗?

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/539.html

(0)
上一篇 2天前
下一篇 2天前

相关推荐