RMSNorm 与 SwiGLU

现代大模型把解码器的 LayerNorm 换成 RMSNorm、ReLU 前馈换成 SwiGLU,本课讲清这两处为什么换、换成什么。

知识课 · 约 30 分钟 · 更新于 2026-08-14

现代大模型改掉的两处:归一化与前馈

我们手上的解码器沿用早期 Transformer 的设计:归一化用 LayerNorm ,前馈网络是 两层全连接夹一个 ReLU 。这套设计能用,但现代大模型(LLaMA、Qwen 等)几乎都改掉了这两处,归一化换成 RMSNorm ,前馈换成 SwiGLU 。

这一课讲清它们 为什么换、换成什么 。先从归一化说起。

从 LayerNorm 到 RMSNorm

回忆「残差与层归一化」里的 LayerNorm:对一个特征向量 ,它先 减去均值 、再除以 标准差 做归一化,最后用可学习的增益 缩放、偏移 平移:

RMSNorm(Root Mean Square Normalization) 把它 简化 了: 不再减均值 ,只保留可学习增益 、去掉偏移 。分母也跟着变了形式。标准差 的定义里带着 ,一旦不做中心化,衡量尺度的量就退化成 均方根(RMS) ,即把每个分量直接平方求平均再开根:

其中 是向量维度, 是防止除零的小常数。

两个公式并排放着,改动究竟落在哪几步并不好认。把同一个向量分别送进两条路,一步步算下来就清楚了:

拖动「整体平移」把整个向量抬高或压低,LayerNorm 的输出一点不变,RMSNorm 的输出却整个换了一副样子。中心化正是把这份偏移抹掉的那一步,RMSNorm 不做它,向量原本带的偏移就留在了输出里:除以尺度量之后,LayerNorm 得到的向量均值必为 0,RMSNorm 只保证均方根为 1,均值仍是原向量那份偏移按比例缩放后的结果。

为什么去掉减均值也行,又省下了什么

RMSNorm 的作者做过消融对比:LayerNorm 里真正起作用的是 按尺度归一 (把向量的整体大小拉到稳定范围),把 中心化 (减均值)这一步去掉,效果几乎不变。既然如此,这一步就能省,省下来的是:

  • 一趟跨特征维的归约 。LayerNorm 要沿特征维扫两趟:先算出均值 ,才能拿它算方差 。RMSNorm 只需一趟,把每个分量平方后求平均即可,中间的减法也一并省了。
  • 一个可学习参数 。既然不再把均值强行拉到 0,也就没有被抹掉的偏移需要 补回来。

从 ReLU 前馈到门控前馈 SwiGLU

再看前馈网络。早期 FFN 只有一条通路: 。现代大模型改用带 门控 的前馈 SwiGLU 。先说清什么是门控。

SwiGLU 据此设计。它用 两个并行 的线性变换处理同一个输入:

  • 一路经过 Swish 激活,产出 门控系数 。Swish 定义为 ,其中 是 sigmoid , (它与上面归一化公式里表示标准差的 不是一回事)。这里的 是送进激活函数的 单个数 ,激活对向量的每个分量分别作用;
  • 另一路保持 线性 ,提供被调节的 内容 。

两路 逐元素相乘 ,再过一个降维线性层输出。一共三个权重矩阵:

其中 表示逐元素相乘, 是两路并行变换, 是输出层。Swish 逐分量作用在 上,对它的每个分量分别算一次(后面那张曲线图的横轴 就是 的某一个分量)。下标是 1、3、2 而不是顺着排,这是沿用 LLaMA 实现里的命名( w1 门控、 w3 内容、 w2 输出),照着读代码时对得上,不用深究。

先把这套结构的整体骨架画出来,三个矩阵各在什么位置、两条支路怎么合起来,一眼就能看清:

这类「一路做门、一路做内容,相乘后再投影」的结构统称 GLU(Gated Linear Unit,门控线性单元) ,门用 Swish 的版本就叫 SwiGLU。换成别的激活也有对应的名字,如 GeGLU、ReGLU。

门控系数的取值范围值得单说。sigmoid 的值域是 0 到 1,LSTM、原始 GLU 里的门就是这么来的,只能决定内容放行多少。而 Swish 把 乘了回去,值域变成 :向上没有界,负半轴还能取到负值。所以 SwiGLU 的门不只是开合,它既能把内容 放大 ,也能 翻号 。Swish 还比 ReLU 平滑,负区间不做硬截断。

下面把这三个函数画在同一坐标系里,横轴是进入激活函数的那个分量 ,纵轴是各自的输出。

把三个矩阵摆进数据流,逐元素相乘那一步做了什么就看得见了:

门控系数逐个位置生效。系数接近 0 的那一位,内容几乎被压掉;系数大于 1,内容被放大;系数取到负值,连符号一起翻过来。这些系数出自 那条支路,与提供内容的 支路各学各的。

门控比 ReLU 前馈多了什么

ReLU 前馈里,中间层某个分量的取值只由它自己那一路线性变换决定,ReLU 拿这个值的正负当开关。SwiGLU 把开关和内容 拆到了两条支路 :调节系数来自另一条独立的线性变换,与被调节的内容分开学。于是同一个分量可以被完全不同的信号放大或压制,系数还是 连续可调 的,而不是 0 与 1 之间的硬切换。

实测下来,同等规模下,SwiGLU 这类门控前馈通常 略优于 ReLU 这类普通激活的 FFN,因此成了现代大模型的默认选择。

动手:实现并验证 RMSNorm

照定义写一个 RMSNorm 模块,对一个张量在特征维上归一化,再跑一批数据核对归一化有没有生效。

对照 nn.LayerNorm 的计算步骤,RMSNorm 少了求均值和减均值这两步,确实更省。

动手:实现 SwiGLU 前馈模块

照公式写出 SwiGLU 模块,再把它和早期的 ReLU 前馈摆在一起,比一比参数量。

SwiGLU 比 ReLU 前馈多一个权重矩阵,为了让 总参数量对齐 ,它的中间维度通常按比例调小(上面把 2048 调到 1365,约 )。跑一遍就能看到,两者参数量基本持平,输出形状一致。

位置编码也还是早期那套

归一化、前馈都换过了。解码器里的 位置编码 ,用的也还是早期那套。

这种编码叫 RoPE,留给「旋转位置编码 RoPE」。