详解RoPE

参考链接
复数基本知识

概述

Transformer模型本身不具备处理序列顺序的能力(自注意力机制是排列不变的),因此需要位置编码(Position Embedding)来为输入序列的每个位置注入位置信息。在经典的 Transformer 中,我们可以:

  • 直接加一个位置向量(绝对位置编码),例如把 “位置 m m m” 的向量记为 x m + p m x_m + p_m xm+pm
  • 或在注意力公式里显式注入相对位置信息(相对位置编码),例如对注意力分数 q i T k j q_i^Tk_j qiTkj 额外加上和 ( i − j ) (i-j) (ij) 有关的bias。

但是,这两种方法各有优缺点:

  • 绝对位置编码实现简单、计算开销小,但它本身并不直接表达“相对位置”,对于长序列外推往往有局限。
  • 相对位置编码能让注意力“直接感知”相对位置信息,但实现时常要改动注意力公式,结构更复杂。

因此作者提出 RoPE,出发点是为了能利用上 token 之间的相对位置信息,“通过绝对位置编码的方式实现相对位置编码”。为了达到这个目的,假设通过下述运算来对 q, k 添加绝对位置信息:
q ~ m = f ( q , m ) , k ~ n = f ( k , n ) \tilde{q}_m = f(q, m), \quad \tilde{k}_n = f(k, n) q~m=f(q,m),k~n=f(k,n)

也就是说,我们分别对 q, k 设计 f(⋅,m)f(⋅,n)使得经过该变换后, q ~ m \tilde{q}_m q~m k ~ n \tilde{k}_n k~n 就带有了 ”绝对位置信息”。

Attention的核心运算是内积,所以只要 让两个带位置信息的向量 q ~ m \tilde{q}_m q~m k ~ n \tilde{k}_n k~n内积时自动带出相对位置信息(也就是让内积只和 n − m n-m nm 有关),就能让模型感知到相对位置。

因此假设存在恒等关系:
⟨ f ( q , m ) , f ( k , n ) ⟩ = g ( q , k , ( n − m ) ) ⟨f(q,m),f(k,n)⟩=g(q,k,(n−m)) f(q,m),f(k,n)⟩=g(q,k,(nm))
所以我们要求出该恒等式的一个(尽可能简单的)解。


RoPE(旋转位置编码)就是作者设计的一个具体的函数 f。它的核心思想是:

  • 把向量分成两两一组,在每个二维子空间做一个跟位置索引 m 相关的旋转

  • 类似地,对 k 向量在位置 n 上做相应旋转。

  • 由于旋转矩阵有 R m ⊤ R n = R n − m \mathcal{R}_m^\top \mathcal{R}_n = \mathcal{R}_{n-m} RmRn=Rnm 这样的性质,最终就得到:

    q ~ m T k ~ n = q T R n − m k , \tilde{q}_m^T \tilde{k}_n = q^T \mathcal{R}_{n-m} k, q~mTk~n=qTRnmk,

    只和 (n−m) 有关,从而实现了“相对位置编码”的效果。


RoPE求解过程

📌欧拉公式: e i θ = cos ⁡ θ + i sin ⁡ θ e^{i\theta}=\cos\theta + i\sin\theta eiθ=cosθ+isinθ

  1. 在二维情形的推导思路
    1.1 二维旋转的数学表示
    在二维空间中,向量 q = [ q x ​ , q y ​ ] q=[q_x​,q_y​] q=[qx,qy] 绕原点旋转角度 θ \theta θ 的操作可通过旋转矩阵实现:
    R θ = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] , q ′ = R θ   q R_{\theta} = \begin{bmatrix}\cos \theta & -\sin \theta \\\sin \theta & \cos \theta\end{bmatrix}, \quad q' = R_{\theta} \, q Rθ=[cosθsinθsinθcosθ],q=Rθq
    这一操作保持向量长度不变,仅改变方向。向量 k k k 同理。
    复数视角的旋转:
    二维旋转也可用复数乘法表示。将向量 q q q 视为复数 q = q x + i q y q=q_x+iq_y q=qx+iqy,那么绕原点逆时针旋转一个角度 θ ,就可以用“复数乘以复指数”的形式来表达:
    q ′ = q ⋅ e i θ = ( q x + i   q y ) ( cos ⁡ θ + i   sin ⁡ θ ) q' = q \cdot e^{i\theta} = (q_x + i \, q_y) \bigl(\cos \theta + i \,\sin \theta\bigr) q=qeiθ=(qx+iqy)(cosθ+isinθ)
    展开可以得到:
    q ′ = q x ′ + i q y ′ = ( q x c o s θ − q y s i n θ ) + i ( q x s i n θ + q y c o s θ ) q' = q_x' + iq_y' = (q_xcosθ−q_ysinθ)+i(q_xsinθ+q_ycosθ) q=qx+iqy=(qxcosθqysinθ)+i(qxsinθ+qycosθ)
    即:
    q x ′ = q x c o s ( θ ) − q y s i n ( θ ) q_x'=q_xcos(θ)−q_ysin(θ) qx=qxcos(θ)qysin(θ)
    q y ′ = q x s i n ⁡ ( θ ) + q y c o s ⁡ ( θ ) q_y'=q_xsin⁡(θ)+q_ycos⁡(θ) qy=qxsin(θ)+qycos(θ)
    这恰好就是一个 2D 旋转矩阵作用在向量 ( q x , q y ) (q_x, q_y) (qx,qy) 上的结果:
    ( q x ′ q y ′ ) = ( cos ⁡ ( θ ) − sin ⁡ ( θ ) sin ⁡ ( θ ) cos ⁡ ( θ ) ) ( q x q y ) \begin{pmatrix} q_x' \\ q_y' \end{pmatrix} = \begin{pmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{pmatrix} \begin{pmatrix} q_x \\ q_y \end{pmatrix} (qxqy)=(cos(θ)sin(θ)sin(θ)cos(θ))(qxqy)
    这样,“向量的内积”可以转化为“复数相乘后取实部”的形式(如果我们考虑 ⟨ q , k ⟩ = R e ( q ′ ∗   k ′ ‾ ) ⟨q,k⟩ = Re(q' * \,\overline{k'}) q,k=Re(qk)

    1.2 让内积只依赖 n − m n-m nm
    将向量 q q q 视为复数: z q = q x + i q y z_q = q_x + iq_y zq=qx+iqy
    我们要在 z q z_q zq 上注入位置 m m m 的信息,记为:
    z q , m = f ( z q , m ) z_{q,m} = f\bigl(z_q, m\bigr) zq,m=f(zq,m)
    同理,
    z k , n = f ( z k , n ) z_{k,n} = f\bigl(z_k, n\bigr) zk,n=f(zk,n)
    我们希望
    R e [ z q , m   z k , n ‾ ] Re[z_{q,m}\,\overline{z_{k,n}}\bigr] Re[zq,mzk,n]
    只和 (n - m) 有关,其中   z k , n ‾ \, \overline{z_{k,n}} zk,n表示共轭, 一个自然的做法是,在复数上“乘一个随位置改变的相位因子”(详细推导过程可见 参考链接),即:
    z q , m = z q ⋅ e i m θ , z k , n = z k ⋅ e i n θ z_{q,m}=z_q⋅e^{imθ}, z_{k,n} = z_k⋅e^{inθ} zq,m=zqeimθ,zk,n=zkeinθ
    其中 θ 是一个常数。
    为什么这样就可以?

  • 两者相乘时:
    z q , m   z k , n ‾ = ( z q e i m θ )   ( z k e i n θ ) ‾ = z q   z k ‾ ⋅ e i m θ e − i n θ = z q   z k ‾ ⋅ e i ( m − n ) θ . z_{q,m}\, \overline{z_{k,n}}=(z_qe^{imθ})\, \overline{(z_ke^{inθ})}=z_q\,\overline{z_k}⋅e^{imθ}e^{−inθ}=z_q\,\overline{z_k}⋅e^{i(m−n)θ}. zq,mzk,n=(zqeimθ)(zkeinθ)=zqzkeimθeinθ=zqzkei(mn)θ.

  • 这样其实部就是:
    R e [ z q , m   z k , n ‾ ] = R e [ z q   z k ‾ ∗ ⋅ e i ( m − n ) θ ] , Re[z_{q,m}\,\overline{z_{k,n}}]=Re[z_q\,\overline{z_k}∗⋅e^{i(m−n)θ}], Re[zq,mzk,n]=Re[zqzkei(mn)θ],
    只依赖于 (m - n),这样就达到了我们的目标。

    1.3 确定幅度和相位
    刚才我们只给出了一个“相位旋转” e i m θ e^{im\theta} eimθ。要更加严格的满足
    ⟨ f ( q , m ) , f ( k , n ) ⟩ = g ( q , k , ( n − m ) ) ⟨f(q,m),f(k,n)⟩=g(q,k,(n−m)) f(q,m),f(k,n)⟩=g(q,k,(nm))
    可能还需要考虑幅度是否也跟 m m m 有关。经过仔细推敲(或直接对比实验),通常让幅度保持不变是最简单可行的:也就是只做“纯旋转”而不改变向量模长。
    因此,在二维情况下,最终我们定
    z q , m = z q ⋅ e i m θ , z_{q,m}=z_q⋅e^{imθ}, zq,m=zqeimθ,
    并不会再多乘一个 α ( m ) \alpha(m) α(m) 这样的幅度函数。这样即可保证
    z q , m   z k , n ‾ = ( z q   z k ‾ ) ⋅ e i ( m − n ) θ z_{q,m}\,\overline{z_{k,n}}=(z_q\,\overline{z_k})⋅e^{i(m−n)θ} zq,mzk,n=(zqzk)ei(mn)θ
    只跟 m−n 有关

    1.4 回到实数向量形式
    从几何上,这就对应旋转矩阵
    ( cos ⁡ ( m θ ) − sin ⁡ ( m θ ) sin ⁡ ( m θ ) cos ⁡ ( m θ ) ) ( q x q y ) \begin{pmatrix} \cos(m\theta) & -\sin(m\theta) \\ \sin(m\theta) & \cos(m\theta) \end{pmatrix} \begin{pmatrix} q_x \\ q_y \end{pmatrix} (cos(mθ)sin(mθ)sin(mθ)cos(mθ))(qxqy)
    所以我们把二维向量 ( q x , q y ) (q_x,q_y) (qx,qy) 在平面上“逆时针旋转” m θ m\theta mθ 的角度,这就完成了“在位置 m m m上对向量 q \boldsymbol{q} q 做编码”。

  1. 推广到高维空间
    多维向量可以“拆分成若干个 2D 子空间”来做同样的旋转。
  • 例如一个 4 维向量 q = (q₀, q₁, q₂, q₃),可以拆成两组:(q₀, q₁) 和 (q₂, q₃),分别旋转不同频率的角度。
  • 更一般的 d 维向量(d 为偶数)可以拆成 d/2 组,每组用
    θ i = 1 1000 0 2 i d \theta_i = \frac {1} {10000^{\frac{2i}{d}}} θi=10000d2i1
    等不同的角度。这样就类似于多频率的"分块旋转",形成 RoPE 在实际 Transformer 里的实现方式。
    这样我们就得到了 RoPE 最常见的形式:
    R m = ( cos ⁡ ( m θ 0 ) − sin ⁡ ( m θ 0 ) sin ⁡ ( m θ 0 ) cos ⁡ ( m θ 0 ) ⋱ cos ⁡ ( m θ d 2 − 1 ) − sin ⁡ ( m θ d 2 − 1 ) sin ⁡ ( m θ d 2 − 1 ) cos ⁡ ( m θ d 2 − 1 ) ) \mathcal{R_m} = \begin{pmatrix}\cos(m\theta_0) & -\sin(m\theta_0) & & & \\\sin(m\theta_0) & \cos(m\theta_0) & & & \\ & & \ddots & & \\ & & & \cos\bigl(m\theta_{\frac{d}{2}-1}\bigr) & -\sin\bigl(m\theta_{\frac{d}{2}-1}\bigr) \\ & & & \sin\bigl(m\theta_{\frac{d}{2}-1}\bigr) & \cos\bigl(m\theta_{\frac{d}{2}-1}\bigr)\end{pmatrix} Rm= cos(mθ0)sin(mθ0)sin(mθ0)cos(mθ0)cos(mθ2d1)sin(mθ2d1)sin(mθ2d1)cos(mθ2d1)
    对应地,RoPE 的编码可写为:
    f ( q , m ) = R m q f(q,m)= \mathcal{R_m}q f(q,m)=Rmq
    此外,利用正交矩阵的性质(不改变向量模长),经过旋转后的内积满足:
    ( R m q ) ⊤ ( R n k ) = q ⊤ R n − m k (\mathcal{R_m}q)^⊤(\mathcal{R_n}k)=q^⊤\mathcal{R_{n−m}}k (Rmq)(Rnk)=qRnmk
    这正好实现了仅依赖于相对位置信息的效果。
  1. 高效实现
    由于 R m {\mathcal{R}}_m Rm矩阵存在大量零元素,直接用矩阵乘法计算会浪费算力。实际中推荐使用分组的方式,通过逐位对应的乘法实现:

f ( q , m ) = ( q 0 q 1 q 2 q 3 ⋮ q d − 2 q d − 1 ) ⊗ ( cos ⁡ ( m θ 0 ) cos ⁡ ( m θ 0 ) cos ⁡ ( m θ 1 ) cos ⁡ ( m θ 1 ) ⋮ cos ⁡ ( m θ d 2 − 1 ) cos ⁡ ( m θ d 2 − 1 ) )    +    ( −   q 1 q 0 −   q 3 q 2 ⋮ −   q d − 1 q d − 2 ) ⊗ ( sin ⁡ ( m θ 0 ) sin ⁡ ( m θ 0 ) sin ⁡ ( m θ 1 ) sin ⁡ ( m θ 1 ) ⋮ sin ⁡ ( m θ d 2 − 1 ) sin ⁡ ( m θ d 2 − 1 ) ) . f(\mathbf{q}, m)= \begin{pmatrix} q_0 \\ q_1 \\ q_2 \\ q_3 \\ \vdots \\ q_{d-2}\\ q_{d-1} \end{pmatrix} \otimes \begin{pmatrix} \cos\bigl(m\theta_0\bigr) \\ \cos\bigl(m\theta_0\bigr) \\ \cos\bigl(m\theta_1\bigr) \\ \cos\bigl(m\theta_1\bigr) \\ \vdots \\ \cos\bigl(m\theta_{\tfrac{d}{2}-1}\bigr) \\ \cos\bigl(m\theta_{\tfrac{d}{2}-1}\bigr) \end{pmatrix} \;+\; \begin{pmatrix} -\,q_1 \\ q_0 \\ -\,q_3 \\ q_2 \\ \vdots \\ -\,q_{d-1}\\ q_{d-2} \end{pmatrix} \otimes \begin{pmatrix} \sin\bigl(m\theta_0\bigr) \\ \sin\bigl(m\theta_0\bigr) \\ \sin\bigl(m\theta_1\bigr) \\ \sin\bigl(m\theta_1\bigr) \\ \vdots \\ \sin\bigl(m\theta_{\tfrac{d}{2}-1}\bigr) \\ \sin\bigl(m\theta_{\tfrac{d}{2}-1}\bigr) \end{pmatrix}. f(q,m)= q0q1q2q3qd2qd1 cos(mθ0)cos(mθ0)cos(mθ1)cos(mθ1)cos(mθ2d1)cos(mθ2d1) + q1q0q3q2qd1qd2 sin(mθ0)sin(mθ0)sin(mθ1)sin(mθ1)sin(mθ2d1)sin(mθ2d1) .

小结

总结下来,求解 f(q,m) 的过程可以概括为:

  1. 目标:让带位置索引的 q̃ₘ 和 k̃ₙ 做内积时只与相对位置 (n−m) 相关。

  2. 二维简化:先考虑二维向量,将其映射为复数 z q z_q zq

  3. 设计思路:在复数上乘以相位因子 eⁱᵐᶿ,使得相乘结果只依赖于 (m−n)。

  4. 得到

    z q , m = z q ⋅ e i m θ ⟺ ( 实数形式 ) ( cos ⁡ ( m θ ) − sin ⁡ ( m θ ) sin ⁡ ( m θ ) cos ⁡ ( m θ ) ) ( q x q y ) . z_{q,m} = z_q·eⁱᵐᶿ ⟺ (实数形式) \begin{pmatrix} \cos(m\theta) & -\sin(m\theta) \\ \sin(m\theta) & \cos(m\theta) \end{pmatrix} \begin{pmatrix} q_x \\ q_y \end{pmatrix}. zq,m=zqeimθ(实数形式)(cos(mθ)sin(mθ)sin(mθ)cos(mθ))(qxqy).

  5. 高维推广:将高维向量按两两一组分块进行旋转,并使用不同的 θ 来捕捉多种频率。

通过这种"旋转"方式,我们构造出了 RoPE 的位置编码函数 f,实现了将"绝对位置 (m,n)"转化为注意力内积中的相对位置 (n−m) 的效果。

一些补充知识

f(q,m) 和 f(k,n) 各表示什么?

  • q ~ m = f ( q , m ) \tilde{q}_m = f(q,m) q~m=f(q,m):可以理解为"对原向量 q q q 做了一个跟位置 m m m 相关的变换"。
    • 因为位置 m m m 是一个整数或索引,所以 f f f 其实是"(向量)×(位置索引)→(新向量)"的映射。
    • 例如 RoPE 中就是通过"旋转矩阵"对向量进行旋转,旋转角度取决于 m m m
  • 同理, k ~ n = f ( k , n ) \tilde{k}_n = f(k,n) k~n=f(k,n) 表示对原向量 k k k 做了与位置 n n n 相关的变换。

这样做的目的:

  1. 每个位置(绝对位置)都有自己的"旋转"或"变换"方式,这就叫做"绝对位置编码"。
  2. 但是当我们把 q ~ m \tilde{q}_m q~m k ~ n \tilde{k}_n k~n 做内积时,希望这个内积只和 n−m 有关,也就是能体现出相对位置。

q T k q^Tk qTk 和原论文中的 Q K T QK^T QKT 有什么区别

只是标量点积矩阵乘法的两种视角:

在谈到“注意力公式”时,最核心的一步是 向量与向量之间的点积(内积),其结果应该是一个标量,用于衡量两者的相似度。在数学计法中,如果 q q q k k k 都是列向量(形状为 (d, 1)), 那么它们的点积就是

q T k ∈ R q^T k \in \mathbb{R} qTkR

这种写法更偏向数学定义,把每个 token 的 Query/Key 看成单独向量去做内积。

在实际的 Transformer 实现中,我们常常一次处理整条序列

  • 设序列长度为 n,词向量维度为 d。
  • 将所有 Query 向量拼成一个矩阵 Q \mathbf{Q} Q,形状通常是 (n,d)。
    • 其中第 i 行 Q_i 就是 token i 的 Query(通常是行向量)。
  • 同理,将所有 Key 向量拼成一个矩阵 K \mathbf{K} K,形状也是 (n,d)。

此时做矩阵乘法:

Q K T ∈ R n × n QK^T \in \mathbb{R}^{n \times n} QKTRn×n

  • 结果是一个 n ∗ n n*n nn 的矩阵,每个元素 (i, j) 对应第 i 个 Query 和第 j 和 key 的内积:

[ Q K T ] i , j = Q i K j T = q i T k j . [QK^T]_{i,j} = Q_i K_j^T = q_i^T k_j. [QKT]i,j=QiKjT=qiTkj.

  • 这正好构成了整条序列上所有 (i,j) 两两 token 间的相似度分数。

因此, Q K T QK^\mathsf{T} QKT 是把所有单个向量点积拼成一个矩阵的做法,二者本质一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值