Transformer 的位置编码

        Transformer模型中,位置编码是必不可少的,Attention模块是无法捕捉输入顺序的,要加入Token位置信息有两个方向:

        1、绝对位置编码:将位置信息融入到输入中;

        2、相对位置编码:微调Attention结构,使其能分辨不同位置的Token。

        远程衰减性-Distant Decay:位置编码应能捕获到序列中相隔较远的单词之间的关系,即相隔较远的单词之间的位置编码相似度应较低。具备远程衰减性的位置编码可以使模型学习到更多的长距离依赖关系,从而提高模型的性能。

绝对位置编码

使用固定的正弦和余弦函数,每个token不同位置编码是通过正弦和余弦函数生成的,可以捕获到不同位置之间的关系,且具有良好的远程衰减性。当两个位置的编码相差较大时相似度较低,便于模型区分这些位置。当两个位置相隔较近时相似度较高,便于模型理解它们之间的关系。

        简单暴力,短文本性能高;但外推性差;长度超限只能截断/插值;参数量 len×d

相对位置编码

只编码距离不编码绝对下标。

Relative Position Representation-RPR

在注意力得分里加一项可学习偏置 a_ij = f(i−j), f2k+1 个可学习标量(距离截断到 ±k)。A_ij = (q_i^T k_j) / √d + a_{i−j}

天然对长度外推友好;同一距离共享参数,广泛用于 Transformer-XL、T5。

旋转位置编码--RoPE

目前LLM标配,通过绝对位置编码的方式实现相对位置编码。RoPE(q,m) = R_θ^m · q,R_θ^m 是 2×2 旋转块对角矩阵,θ = 10000^(-2i/d) 。保持线性形式,可插值到任意长度(LLaMA-2 Long 32 k 即用线性插值 RoPE)。只改矩阵乘法,零额外参数;绝对位置隐性、相对位置显性。

ALiBi(Attention Linear Biases)

不给向量,直接给注意力分数加线性负偏置 −m·|i−j|;斜率 m 随头序号固定。

  • 零参数量;外推性能极佳(BLOOM 用 2048 训练→ 8500 推理仍稳定)。

  • 缺点:短距离惩罚过大,极短文本效果略差。

绝对PE与RoPE对比

绝对PE:给每个 token 附加一个唯一向量,模型把“位置”当成额外特征。

PE(pos, 2i)   = sin( pos / 10000^(2i / d) )
PE(pos, 2i+1) = cos( pos / 10000^(2i / d) )

  • pos:token 下标(从 0 开始)

  • i :维度编号(从 0 到 d/2-1)

  • d :向量维度

纯自注意力里,q、k、v 是同一输入 x 经过三个独立线性投影得到的,因此在“加”绝对位置编码时,它们先被加上完全相同的 PE 向量;但在处理非常长的序列时可能效果不佳,因为绝对位置编码的分辨率有限,且在微调预训练模型时,序列长度的变化可能导致模型性能下降。

RoPE不给向量,而把 query/key 向量旋转一个与下标差有关的角度,让注意力系数自带相位差 ⇒ 位置信息隐式进入内积。把 q、k 的内部二维子向量按各自下标旋转不同角度——v 向量不旋转(因为注意力里只用它做“内容”,不参与相似度打分)

RoPE通过引入旋转矩阵来动态地调整词嵌入向量,以反映它们在序列中的相对位置。RoPE 对于每个位置 i 定义了一个旋转矩阵 Ri​。这个矩阵可以分解为两个部分,cosine矩阵和sine矩阵。对于一个维度为 d 的向量,将其分为两半,前一半与cosine矩阵相乘,后一半与sine矩阵相乘。

        一个序列中的词嵌入向量 v,对于位置 i,RoPE将通过以下方式修改向量:vi,1:d/2​是向量的前一半,𝑣𝑖,𝑑/2+1:𝑑vi,d/2+1:d​是后一半。

        RoPE适用于单个序列内部的位置编码,也适用于不同序列之间的相对位置编码。当两个序列被拼接在一起时,RoPE可以通过不同的旋转矩阵来区分这两个序列的位置信息,从而帮助模型理解它们之间的关系。

  • 灵活性:RoPE允许模型在训练过程中动态学习位置信息,使模型能适应不同长度的序列。
  • 效率:相较于添加额外的位置编码向量,RoPE只需要计算旋转矩阵,更为高效。
  • 长距离依赖性:RoPE通过相对位置编码帮助模型捕获更长距离的依赖关系。

对于序列中的每一个位置 i,构建一个基于该位置的旋转矩阵 Ri​,Ri 一部分是基于余弦函数的旋转,另一部分是基于正弦函数的旋转,Ri(cos)​ 和 Ri(sin)​ 。

𝑅𝑖(𝑐𝑜𝑠)=𝑑𝑖𝑎𝑔(cos⁡(𝑖/100002𝑗/𝑑));𝑅𝑖(𝑠𝑖𝑛)=𝑑𝑖𝑎𝑔(sin⁡(𝑖/100002𝑗/𝑑))

diag 表示创建一个对角矩阵,对角线元素由给定的数组或列表决定;j 是从0开始的索引,直到 d/2−1,代表了向量中的位置;100002𝑗/𝑑 为缩放频率。

        完整的旋转矩阵 Ri 为,Ri 与原始向量 v 结合,又由于只对向量的一半进行旋转,因此可以简化为,这样,原始的词嵌入向量 v 转换成了带有位置信息的新向量 v′。这个新的向量在后续的计算中将包含关于它在序列中的相对位置的信息,而不仅仅是其语义信息。RoPE能够在不增加模型参数的情况下,有效地将位置信息嵌入到词嵌入中,同时保持了模型的计算效率。

位置向量计算示例

日志:Received block 123
token : [Received, block, 123]
ID    : [ 1234, 5678, 9101 ]     
下标 i:    0      1      2

维度取 d=4 最简明,head=1,忽略batch

绝对PE:

PE(i,2t)   = sin( i / 10000^(2t/d) )
PE(i,2t+1) = cos( i / 10000^(2t/d) )

这里 d=4,因此 t=0,1 两组角度。

it=0t=1最终4维向量
0sin0=0cos0=1[0, 1, 0, 1]
1sin(1/1)≈0.8415cos(1/1)≈0.5403[0.8415, 0.5403, 0.0998, 0.9950]
2sin2≈0.9093cos2≈-0.4161[0.9093, -0.4161, 0.1987, 0.9801]

位置0:

PE(0,0) = sin(0/1) = 0
PE(0,1) = cos(0/1) = 1
PE(0,2) = sin(0/100) = 0
PE(0,3) = cos(0/100) = 1
向量 = [0, 1, 0, 1]

位置1:

PE(1,0) = sin(1/1) = 0.84147098
PE(1,1) = cos(1/1) = 0.54030231
PE(1,2) = sin(1/100) ≈ 0.00999983
PE(1,3) = cos(1/100) ≈ 0.99995000
向量 = [0.8415, 0.5403, 0.0100, 0.9999]

位置2:

PE(2,0) = sin(2) ≈ 0.90929743
PE(2,1) = cos(2) ≈ -0.41614684
PE(2,2) = sin(2/100) ≈ 0.01999867
PE(2,3) = cos(2/100) ≈ 0.99980000
向量 = [0.9093, -0.4161, 0.0200, 0.9998]

位置3:

PE(3,0) = sin(3) ≈ 0.14112001
PE(3,1) = cos(3) ≈ -0.98999250
PE(3,2) = sin(3/100) ≈ 0.02999550
PE(3,3) = cos(3/100) ≈ 0.99955000
向量 = [0.1411, -0.9899, 0.0300, 0.9996]

维索引偶/奇三角函数角度 = pos / ?例 pos=1
0sinpos / 1sin(1)
1cospos / 1cos(1)
2sinpos / 100sin(0.01)
3cospos / 100cos(0.01)

每连续两维 (2i, 2i+1) 共用同一个角度分母,然后sin→偶下标,cos→奇下标

RoPE:

只给query/key向量加旋转,不改动token嵌入本身。

假设 q_i(或k_i)已经拿到4维向量:q_i = [a, b, c, d]

① 两两复数化
把相邻两维看成复数:

z_0 = a + bj
z_1 = c + dj

② 距离-旋转
对内积另一端q_i · k_j只关心相对距离Δ=i-j,给出自身位置i的旋转因子(后面与k_j做内积时再用Δ=i-j)。旋转角 θ_t = 10000^(-2t/d)t=0: θ_0=1 rad, t=1: θ_1=0.01 rad

ẑ_t = z_t · e^(i·i·θ_t)(e^(iα)=cosα + i sinα)

it=0 旋转t=1 旋转旋转后4维实部/虚部
0e^(i·0)=1+0je^(i·0)=1+0jq_0 不变
1e^(i·1)≈0.5403+0.8415je^(i·0.01)≈0.99995+0.0100j实部/虚部线性组合即可
2e^(i·2)≈-0.4161+0.9093je^(i·0.02)≈0.9998+0.0200j同上,用2×2块对角乘
  • 绝对PE给每个token额外贴一个4维向量;

  • RoPE把q,k内部每2维旋转一个与下标成正比的角度,不产生新参数,也不改变嵌入表。

如:输入 token-1(位置 i=1)的嵌入 x = [1.0, 0.5, -0.5, 1.5] # 4 维

投影后(假设 W_Q=W_K=W_V=I,方便手写,所以 q=k=v=x

  1. 旋转角(与 i=1 对应)
    二维一组,角度 = i / 分母

    • 组 0(维 0&1)(分母=1) θ₀ = 1 rad

    • 组 1(维 2&3) (分母=100) θ₁ = 0.01 rad

  2. 块对角旋转矩阵(2×2×2), R(α) = [[cosα -sinα], [sinα  cosα]]

         R₀ = R(1)      ≈ [[ 0.5403, -0.8415], [ 0.8415,  0.5403]]
         R₁ = R(0.01)   ≈ [[ 0.99995, -0.0100], [ 0.0100,   0.99995]]

     3. 把 qk 按复数视角旋转(v 不动)

q₀ = [1.0, 0.5]        // 二维复数 1+0.5i
q₁ = [-0.5, 1.5]       // -0.5+1.5i
同理 k₀, k₁, 旋转后实部/虚部(即新的 4 维向量)

q̂₀ = Re[(1+0.5i) e^{i·1}] 
    = [1·cos1 - 0.5·sin1, 1·sin1 + 0.5·cos1]
    ≈ [0.5403 - 0.5·0.8415, 0.8415 + 0.5·0.5403]
    ≈ [0.1196, 1.1117]
q̂₁ = Re[(-0.5+1.5i)e^{i·0.01}]
    ≈ [-0.5100, 1.4900]   

拼接得旋转后 query,q̂ = [0.1196, 1.1117, -0.5100, 1.4900]

完全相同的旋转(因为同一位置 i=1),得到 k̂ ≈ [0.1196, 1.1117, -0.5100, 1.4900]

v 保持原样,v = [1.0, 0.5, -0.5, 1.5]

注意力分数只与相对距离有关,若后来 token-j=3 的旋转角 = 3θ₀, 3θ₁,则

A_{1,3} ∝ q̂₁^T k̂₃ = Re[ z₁ e^{i(1-3)θ} ]

只出现角度差 (1-3),绝对下标 1 本身被消掉——外推任意长序列,差角可插值。

RoPE旋转角度的变化:只关心 「相对距离 Δ = i − j」 ,与绝对下标无关;距离每增加 1,角度就线性增加一个固定步长。下面用 4 维向量展示角度怎么变。

角度步长公式:维度 d=4 ⇒ 两组二维平面(t=0,1)

θ_t = 10000^(−2t / d) (单位:弧度/步)

t=0 : θ_0 = 10000^0 = 1.0000 rad / 步
t=1 : θ_1 = 10000^(−2/4) = 0.0100 rad / 步

相对距离 → 旋转角(Δ = i−j)

相对距离 Δ组-0 旋转角 (Δ·θ_0)组-1 旋转角 (Δ·θ_1)
0(自身)0 rad0 rad
+11.00000.0100
+22.00000.0200
+33.00000.0300
−1−1.0000−0.0100
−2−2.0000−0.0200

旋转矩阵即时值

组-0(大角度)Δ=+1:R = [[ cos1  -sin1 ] ≈ [[ 0.5403 -0.8415 ]
                                             [ sin1   cos1 ]]     [ 0.8415  0.5403 ]]

Δ=+2:R = [[ cos2  -sin2 ] ≈ [[ -0.4161 -0.9093 ]
                    [ sin2   cos2 ]]    [  0.9093 -0.4161 ]]

组-1(小角度)Δ=+10:R = [[ cos0.1  -sin0.1 ] ≈ [[ 0.9950 -0.0998 ]
                                               [ sin0.1   cos0.1 ]]    [ 0.0998  0.9950 ]]

RoPE 的旋转角度 = 相对距离 Δ × 固定步长 θ_t
步长只由维度索引 t 决定,与绝对下标、词汇、内容全部无关;距离每远一格,角度线性增加,远处大角度(t=0),近处小角度(t=1…),从而实现“远疏近密”的相对位置感知。

再使用‘日志:Received block 123’做演示

预先算好的角度步长

d=4 ⇒ 两组二维平面

  • 组 0(维 0-1):θ₀ = 1 rad / 步

  • 组 1(维 2-3):θ₁ = 0.01 rad / 步

token绝对下标 i相对距离 Δ=i-j(例 j=0)组-0 旋转角 Δ·θ₀组-1 旋转角 Δ·θ₁2×2 块对角矩阵 R(Δ)(维 0-1 块示例)
Received0Δ=00 rad0 rad单位矩阵 [[1,0],[0,1]]
block1Δ=+11.0000 rad0.0100 rad[[0.5403,-0.8415],[0.8415,0.5403]]
1232Δ=+22.0000 rad0.0200 rad[[-0.4161,-0.9093],[0.9093,-0.4161]]

若 j=1,Δ 依次变成 -1,0,+1,角度符号跟着变负即可

RoPE 把 相邻两维 看成 一个复数(实部 + 虚部),然后乘 e^(i·角度) 实现旋转。

  • 4 维向量 → 2 个复数 → 2 次旋转

  • 768 维向量 → 384 个复数 → 384 次旋转

为了代码清晰把“第 0 个复数”叫 组 0,“第 1 个复数”叫 组 1 ……以此类推。

参考:

RoPE旋转位置编码深度解析:理论推导、代码实现、长度外推 - 知乎 (zhihu.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值