正弦位置编码
公式:
其中:
m:序列下标
i:维度下标
d:维度
输入融合:
可以看出,正弦PE是直接对输入直接加上PE,再计算QKV
假设有一个词嵌入:
针对这个3*4的嵌入,根据公式可计算出其固定的近似PE:
那么:X = E + PE
正弦位置编码有一个致命缺陷:不能表征两个序列的相对位置关系,只和绝对位置相关,这样就会导致一个问题:当推理输入的序列长度比训练的要长,那么推理效果会急剧下降
下面来做一个公式推到,就清晰了:
设两个位置m,n:
计算Q和K的点积(即注意力权重):
矩阵转置性质:,
那么:
即:
最终:
可以看出来,公式中不存在m-n(相对距离),所以说正弦位置编码只能建模绝对位置
RoPE
RoPE可以很好的解决PE没有相对位置的问题,有以下几个特点:
- 不直接把位置向量加到词嵌入
- 把 Q、K 的特征向量每两个维度当成平面坐标,按 token 位置做二维旋转
- Q (m) 和 K (n) 做点积,结果只和两个 token 的相对距离 m-n有关,天然区分语序
- V 不做任何旋转。
要理解旋转位置编码,我们需要先复习一下复数:
我们平时的1、2、-3、0.5都是实数,只能画在一条数轴上。 但数学需要描述「平面上的点」,于是发明复数,把一维数轴扩展成二维复平面
复数:
复数通用形式:
- a:实部,对应平面 X 轴坐标
- b:虚部,对应平面 Y 轴坐标
- i:虚数单位,核心规则:
对应这平面坐标(a, b)
举例:
:对应平面点(3, 4)
任意复数,对应平面向量
:
- 向量长度(模):
- 乘以特殊复数
:表示向量绕远点逆时针旋转
弧度,长度不变。这就是RoPE的底层几何逻辑。
我们回到RoPE中来:
单头维度 h,向量两两分组,每组二维旋转矩阵:
对位置 m 的原始向量,分组旋转得到
,等价于:
为什么旋转矩阵是这样的呢?用刚刚的复数知识推导一下就明了了:
对维度两两分组,把向量看做复数,然后乘以对应的旋转复数,其实就完成的旋转位置编码:
旋转因子:
其中:
那么:
回顾一下:,对应平面向量
那么由上述公式就可得到旋转后的结果:
为什么说旋转位置编码只和相对位置有关系
设 Query 位置 m,Key 位置 n:
即只和n-m的相对位置有关。
RoPE的设计另一个精妙之处
单头维度 d,维度分组
它的基础频率:,变形
位置pos的旋转角度为:
。注意这里的
是弧度制,不是角度制,并且
- 那么当m很小时(维度小),
,每向后移动 1 个 token(pos+1),旋转角度 + 1 弧度,旋转极快.它可以区分相邻、短距离词语,捕捉局部语法。例如“我 吃 饭”,模型需要分清「我和吃」、「吃和饭」这种局部语序,快旋转的低 m 分组提供巨大角度差,保证近距离词语不会混淆
- 当m 很大,后半段维度,
,pos 哪怕增加上千,总旋转角度增量极小,旋转非常缓慢。 可以捕捉远距离依赖,长距离 token 之间角度差距不会爆炸
既精妙又“危险”
RoPE的巨大缺陷恰巧就发生在高频区(即m比较小的分组),当推理的序列长度很大,比训练时的最大序列长度还要大时,会带来极大的旋转角度,也给模型带来从没见过的相对位置,,
超出训练见过的角度分布,模型无法识别相对距离;虽然低频大m分组本身旋转极慢不受影响,但无法修复局部语序崩坏。
当前主流的RoPE变体都是为了解决这个问题的