第 25 章 现代稠密 LLM 的三个组件:RoPE、RMSNorm 与 SwiGLU
把红钥匙线索移到离问题更远的地方,模型就需要使用另一种位置关系。可是,允许输入更长,并不能证明它会正确使用远处信息。要判断块内的一项改动是否有帮助,先得找到它改变了哪一步计算,再跟着数值走一遍。配置中的名称本身,证明不了远距离记忆或判断力。
第 17 章的块有三种不同需要:注意力要知道位置,每个子层的输入尺度要受控,前馈网络要在每个位置做非线性变换。本章更换这三个机制,保留因果可见性和残差相加。它们是稠密块内的局部选择,并不是一条注定更好的升级路线。
25.1 让位置信息进入查询与键的比较
Section titled “25.1 让位置信息进入查询与键的比较”可学习的绝对位置,原本把一行存储的位置数值加到 token 表示上。另一种做法,是改变投影后查询与键的比较方式。回想第 3 章的二维箭头:逆时针转四分之一圈,会把 [x,y] 变成 [-y,x],长度不变,但方向变了,与另一个箭头的点积也可能改变。
例 25.1:通过两次旋转表示相对位置。 旋转以前,投影后的查询与键都是 [1,0]。本教学例规定,每前进一个位置就转四分之一圈,位置从 0 开始计。现在求的是尚未缩放的点积,还没有除以头宽度的平方根,也没有做 Softmax。
表 25.1:先分别旋转,再求点积。 这些是精确的构造值,不是生产模型的频率安排。
| 查询位置 | 键位置 | 旋转后的查询 | 旋转后的键 | 点积 |
|---|---|---|---|---|
| 0 | 0 | [1,0] | [1,0] | 1 |
| 0 | 1 | [1,0] | [0,1] | 0 |
| 1 | 2 | [0,1] | [-1,0] | 0 |
| 0 | 2 | [1,0] | [-1,0] | −1 |
第二行是 ,第三行则是 。两个位置同时前进一格,位置差不变,这次比较的结果也不变。这些是代数比较;后续因果掩码仍会排除未来的键,例如位置 0 的查询不能使用位置 1 的键。位置编码不会赋予访问未来 token 的权限。
转过任意角度 ,可以写成:
正弦和余弦说明单位长度的箭头转过某个角度后指向哪里。转零度,余弦为 1、正弦为 0,结果不变;转四分之一圈,余弦为 0、正弦为 1,恰好得到 [-y,x]。角度常用弧度表示:一整圈是 ,四分之一圈就是 。完成本例不需要更多三角函数值。
旋转位置编码(rotary position embeddings,RoPE) 对投影后的 Q、K 坐标对进行随位置变化的旋转。不同坐标对通常采用不同角速度。对某一个角速度 ,查询和键位于 时,有:
是这对查询和键的坐标向量,点积把对应坐标相乘再求和。把两支箭头同时转回查询已经转过的角度,点积不变,右边就只剩相对转角。代入 和本例的四分之一圈单位向量,右边是在比较 [1,0] 与 [0,1],结果为零,与表 25.1 一致。
本章的变体不旋转 V。注意力仍要按头宽度的平方根缩放分数、应用可见性掩码、沿来源位置归一化,再混合值。RoPE 改的是 Q/K 比较怎样感知位置,没有改变来源轴的含义,也没有改变残差连接。
这个机制本身证明不了长上下文外推有效。本例只有一种角速度,甚至每四个位置就会重复。真实的多频率配置复杂得多,但把最大上下文字段调大,并不会教会模型使用陌生距离。训练长度、频率配置和远距离测试仍然重要。应该把红/蓝线索移远并改变它,而不只是展示输入缓冲区能装下一段长文本。
25.2 不减均值,也能控制幅度
Section titled “25.2 不减均值,也能控制幅度”第 17 章的 LayerNorm 先减去一行的均值,再用偏差算出尺度并相除。现在换一种方式:直接把原坐标平方、取平均、开平方,用这个 均方根(root mean square) 作分母。这样控制了幅度,却保留了整行的偏移。
例 25.2:分母里的每个数从哪里来。 一个 token 行是 [3,4],平方为 9、16,平均为 。分母取二,是因为这一行有两个坐标,不是批次里有两个 token。均方根约为 3.535534,相除后得到 [0.848528,1.131371],保留六位小数。归一化后,坐标的平方平均为一:原平方和 25 除以 12.5,再对两个坐标取平均,正好是 1。
加上稳定项和每个坐标可学习的缩放系数,均方根归一化(RMSNorm) 写为:
是一个 token 行中的坐标数, 选中输出坐标, 遍历计算共同分母所需的全部坐标。 是第 个坐标学得的缩放系数。本章变体没有可学习的偏移量。正的稳定项 防止全零行除以零。例 25.2 仅为了非零行的手算 ,把缩放系数设为一、epsilon 设为零;配套配置则在根号内使用 0.000001。
给两个原坐标都加一,就能看出它与 LayerNorm 的区别。[4,5] 的 RMSNorm 分母是 20.5 的平方根,结果约为 [0.883452,1.104315],方向已经不同。如果 LayerNorm 的缩放系数为一、没有偏移、epsilon 为零,那么 [3,4] 与 [4,5] 却都变成 [-1,1],因为减去均值后的偏差相同。不减均值,改变的是一种不变性,不是给同一运算换个简短名字。
epsilon 为零时,若原坐标都乘同一个正数,这个倍数会在分子、分母中抵消。固定正 epsilon 后,只能近似抵消。全零行配零 epsilon 没有定义,练习程序因此会明确拒绝它。论文在特定设置中观察到均方根缩放有效,但任何一种归一化,都不能单独保证训练稳定或答案正确。
25.3 让 FFN 的一条支路调节另一条
Section titled “25.3 让 FFN 的一条支路调节另一条”Mini GPT 把一行扩展到隐藏宽度,经 ReLU 把负坐标置零,再投影回来。门控变体则先从同一个输入产生 两行 隐藏数值,再逐项相乘,让一条支路调节另一条支路的贡献。这些操作仍在一个 token 位置的坐标内部进行,没有因此关注新的位置。
例 25.3:完整计算一个二维门控 FFN。 输入为 ,没有偏置,使用以下矩阵。与第 5 章一样,矩阵行对应输入坐标,列对应输出坐标。
门控投影得到 ,另一条投影得到 。门控支路使用 ,它也称为系数固定为一的 Swish。在 1 处,值为 ;在 −1 处,为 。与 ReLU 不同,它保留一个较小的负值。它也不是概率,因为 SiLU 输出不局限在零到一之间。
两条支路按对应位置相乘,不是两两全乘。第一项为 ,第二项为 。再把这行乘以 :第一个输出把两项相加,得到 0.655293;第二个输出取第二项,得到 −0.806824。最终 FFN 输出为 [0.655293,-0.806824]。计算使用未舍入值,最后显示时才取六位小数。
这就是 SwiGLU 前馈运算:
表示逐项相乘。输入宽度为 、隐藏宽度为 时,两份输入矩阵的形状都是 ,下投影矩阵为 。两条隐藏支路必须逐坐标对齐,输出则回到 ,才能加上残差行。本局部例只计算 FFN,没有把这行输入冒充成整个训练好模型块的输出。
表 25.2:隐藏宽度相同,与参数预算相同,是两种比较。 此处只数 FFN 矩阵,不计偏置和归一化参数。
| FFN | 输入宽度 | 隐藏宽度 | 矩阵参数 |
|---|---|---|---|
| ReLU,两份矩阵 | 12 | 48 | |
| SwiGLU,三份矩阵 | 12 | 48 | |
| SwiGLU,三份矩阵 | 12 | 32 |
同样的隐藏宽度,门控版本会用更多参数。把隐藏宽度从 48 减为 32,才能匹配这里的参数预算。哪一种学得更好,需要控制条件进行训练和评测;计数本身证明不了质量提高。
25.4 把三项改动放回同一个块
Section titled “25.4 把三项改动放回同一个块”- 一组数字X [B, T, 12] → 沿 12 个坐标做 RMSNorm
- 处理步骤投影 Q/K/V → 3 个头 × 4 个坐标
- 处理步骤旋转 Q/K 坐标对;V 不旋转
因果注意力 → 拼接 → 输出投影 [B, T, 12];加上原来的 X 得到 R。
- 处理步骤R → 第二次 RMSNorm
- 模型保存的数值门控矩阵 [12, 32] 与上投影 [12, 32]
- 处理步骤SiLU(门控支路) × 上投影支路,逐项相乘
- 模型保存的数值下投影 [32, 12] → 加 R
R 另有一路绕过 FFN。此配置更换了机制,不能直接加载原有 MG-2 权重。
图 25.1 对应原创教学配置 data/part-v/modern-config.json。hidden_size=12、query_heads=3、head_dim=4 相互吻合,因为 。第一次 RMSNorm 在注意力以前读取每行的 12 个坐标。Q、K 拆成三个头,再按坐标对旋转;V 保留普通投影后的值。经过带掩码的注意力、头拼接和输出投影,再加上原输入,得到残差行 R。
第二次 RMSNorm 读取 R。两条 FFN 投影各产生 32 个坐标,SiLU 作用于门控支路,两路乘积投影回 12,再加 R 得到块输出。两条绕过子层的路径都保留。pre_norm=true 指定归一化位置,bias=false 解释为什么没有仿射偏移;ffn_hidden_size=32 同时对应两条支路,不只对应其中一条。rope_theta=10000 指多频率位置安排使用的底数,不是手算中的四分之一圈。
这些是 教学字段 ,不表示任何框架都能接受这个文件。2048 个槽位是声明的配置容量,不是实测的有效上下文长度。MG-2 的形状不同,还使用可学习的位置行、带偏移的 LayerNorm 和 ReLU FFN。不能把它的现有权重直接装进新结构,就期待行为保持一致。标量练习复现的是三个局部算例,并未声称已经训练出一个现代替代模型。
25.5 本章小结
Section titled “25.5 本章小结”RoPE 改变位置信息进入 Q/K 比较的方式;RMSNorm 缩放每个 token 行,却不减去均值;SwiGLU 先做两条隐藏投影,经逐项门控后回到残差宽度。位置、形状和失败条件,比组件名称更重要。这些改动没有改变因果可见性,不保证长上下文能力,也没有实现服务优化。下一章换一组比较维度:保存的历史、注意力工作量,以及每个 token 实际使用多少参数。
25.6 习题
Section titled “25.6 习题”- 在四分之一圈的例子中,把查询和键放到位置 2、3。求它们的向量和点积。位置 2 的因果查询能使用键 3 吗?
- 用单位缩放系数、零 epsilon 归一化
[0,2]。分母为什么是根号二,而不是二?换成[0,0]会怎样? - 给
[3,4]的两个坐标都加十,RMSNorm 一定保留原结果吗?与 LayerNorm 减均值的作用比较。 - 把例 25.3 的 换成单位矩阵。新 FFN 输出是什么?为什么没有因此增加 token 之间的交互?
- 输入宽度为 24,ReLU 隐藏宽度为 96。门控隐藏宽度取多少,才能使无偏置矩阵参数相等?写出两边计数。
- 配置把
max_sequence_slots翻倍,训练和权重不变。能据此建立什么结论?还需要怎样的红/蓝测试?
25.7 参考解答
Section titled “25.7 参考解答”- 两个向量为
[-1,0]、[0,-1],点积为零,相对转角仍是四分之一圈。代数比较可以成立,但因果掩码仍排除查询 2 对键 3 的访问。 - 坐标平方的平均为 ,所以结果为 。若除以长度二,平方和为一;均方根归一化要求平方的平均为一。全零行需要正 epsilon,零 epsilon 会使分母为零,运算没有定义。
- 不一定。RMSNorm 使用原值的平方,共同加上一个偏移会改变分母与输出。LayerNorm 则通过减均值消除共同偏移,在规定的缩放与 epsilon 条件下,中心化偏差不变。
- 输出是下投影以前的乘积
[1.462117,-0.806824]。单位矩阵保留两个坐标。计算始终发生在一行内部,没有加入对其他位置的访问。 - ReLU 为 。门控隐藏宽度 64 时,。若仍用 96,预算会增加一半。
- 如果实现支持,它可能允许更大的输入缓冲区,但不能证明会正确使用远处信息。应把成对红/蓝及改变颜色的线索放到更远处,固定提问和评分规则,报告全部距离条件下的结果,而不是只挑一个成功的长提示。
25.8 参考文献
Section titled “25.8 参考文献”- Su 等,RoFormer。第 3.1—3.2 节推导旋转及相对 Q/K 比较;本章四分之一圈为原创教学值。
- Zhang、Sennrich,Root Mean Square Layer Normalization。第 4 节和表 1 区分缩放与减均值,本章明确规定 epsilon 和缩放系数。
- Shazeer,GLU Variants Improve Transformer。公式 4—6 定义门控 FFN,论文也说明了匹配参数实验中为何缩小隐藏宽度。