从旋转矩阵到 RoPE:为什么旋转位置编码天然表达相对位置
RoPE,全称是 Rotary Position Embedding,即旋转位置编码。它的核心思想可以概括为一句话:
不用“加法”把位置塞进词向量,而是用“旋转”把位置编码进 Query 和 Key 的几何关系里。
要真正理解 RoPE,需要依次搞清楚四件事:旋转矩阵是怎么来的,m,nm,nm,n 代表什么,RoPE 如何把位置变成旋转,以及为什么旋转后的点积只依赖相对位置。
零、旋转矩阵是怎么来的
二维旋转矩阵不是凭空记出来的,它来自一个基本事实:
任意线性变换,只要知道它把基向量变到哪里,就能确定整个矩阵。
二维平面中有两个标准基向量:
e1=(10),e2=(01) e_1= \begin{pmatrix} 1\\ 0 \end{pmatrix}, \quad e_2= \begin{pmatrix} 0\\ 1 \end{pmatrix} e1=(10),e2=(01)
其中 e1e_1e1 指向 xxx 轴正方向,e2e_2e2 指向 yyy 轴正方向。
现在我们希望把整个平面逆时针旋转角度 α\alphaα。
先看第一个基向量 e1e_1e1。它原本在 0∘0^\circ0∘ 方向,旋转 α\alphaα 后,会落到单位圆上角度为 α\alphaα 的位置,因此:
Rαe1=(cosαsinα) R_\alpha e_1= \begin{pmatrix} \cos\alpha\\ \sin\alpha \end{pmatrix} Rαe1=(cosαsinα)
再看第二个基向量 e2e_2e2。它原本在 90∘90^\circ90∘,也就是 π2\frac{\pi}{2}2π 方向。逆时针旋转 α\alphaα 后,它会到达:
π2+α \frac{\pi}{2}+\alpha 2π+α
所以它的新坐标是:
Rαe2=(cos(π2+α)sin(π2+α))=(−sinαcosα) R_\alpha e_2= \begin{pmatrix} \cos(\frac{\pi}{2}+\alpha)\\ \sin(\frac{\pi}{2}+\alpha) \end{pmatrix}= \begin{pmatrix} -\sin\alpha\\ \cos\alpha \end{pmatrix} Rαe2=(cos(2π+α)sin(2π+α))=(−sinαcosα)
矩阵的两列正好就是两个基向量变换后的结果,因此旋转矩阵为:
Rα=(cosα−sinαsinαcosα) R_\alpha= \begin{pmatrix} \cos\alpha & -\sin\alpha\\ \sin\alpha & \cos\alpha \end{pmatrix} Rα=(cosαsinα−sinαcosα)
其中第一列表示 xxx 轴基向量旋转后去了哪里,第二列表示 yyy 轴基向量旋转后去了哪里。
对于任意二维向量:
v=(xy)=xe1+ye2 v= \begin{pmatrix} x\\ y \end{pmatrix}= xe_1+ye_2 v=(xy)=xe1+ye2
旋转后就是:
Rαv=xRαe1+yRαe2 R_\alpha v= xR_\alpha e_1+yR_\alpha e_2 Rαv=xRαe1+yRαe2
代入上面的结果:
Rαv=x(cosαsinα)+y(−sinαcosα) R_\alpha v= x \begin{pmatrix} \cos\alpha\\ \sin\alpha \end{pmatrix} + y \begin{pmatrix} -\sin\alpha\\ \cos\alpha \end{pmatrix} Rαv=x(cosαsinα)+y(−sinαcosα)
所以:
Rαv=(xcosα−ysinαxsinα+ycosα) R_\alpha v= \begin{pmatrix} x\cos\alpha-y\sin\alpha\\ x\sin\alpha+y\cos\alpha \end{pmatrix} Rαv=(xcosα−ysinαxsinα+ycosα)
这就是二维旋转矩阵的来源。RoPE 后面用到的所有公式,本质上都建立在这个旋转矩阵之上。
一、mmm 和 nnn 从哪里来
RoPE 中的 mmm 和 nnn 并不神秘,它们就是 Token 在序列中的位置编号。
比如输入一句话:
“我 喜欢 吃 烤肉” \text{“我 喜欢 吃 烤肉”} “我 喜欢 吃 烤肉”
那么可以编号为:
我→0,喜欢→1,吃→2,烤肉→3 \text{我}\rightarrow 0,\quad \text{喜欢}\rightarrow 1,\quad \text{吃}\rightarrow 2,\quad \text{烤肉}\rightarrow 3 我→0,喜欢→1,吃→2,烤肉→3
所以 mmm 和 nnn 本质上就是 Token 的索引。第 mmm 个 Token 的 Query 记作 qmq_mqm,第 nnn 个 Token 的 Key 记作 knk_nkn。
模型不需要额外“推理”出 mmm 和 nnn,它们天然来自输入序列的位置。
二、RoPE 如何把位置变成旋转
RoPE 的做法不是把位置向量加到词向量上,而是根据位置编号旋转 Query 和 Key。
二维情况下,如果原始 Query 向量是:
q=(q1q2) q= \begin{pmatrix} q_1\\ q_2 \end{pmatrix} q=(q1q2)
第 mmm 个位置就让它旋转角度:
mθ m\theta mθ
也就是:
q~m=Rmθq \tilde q_m= R_{m\theta}q q~m=Rmθq
其中:
Rmθ=(cos(mθ)−sin(mθ)sin(mθ)cos(mθ)) R_{m\theta}= \begin{pmatrix} \cos(m\theta)&-\sin(m\theta)\\ \sin(m\theta)&\cos(m\theta) \end{pmatrix} Rmθ=(cos(mθ)sin(mθ)−sin(mθ)cos(mθ))
所以:
q~m=(q1cos(mθ)−q2sin(mθ)q1sin(mθ)+q2cos(mθ)) \tilde q_m= \begin{pmatrix} q_1\cos(m\theta)-q_2\sin(m\theta)\\ q_1\sin(m\theta)+q_2\cos(m\theta) \end{pmatrix} q~m=(q1cos(mθ)−q2sin(mθ)q1sin(mθ)+q2cos(mθ))
同理,对于第 nnn 个位置的 Key:
k=(k1k2) k= \begin{pmatrix} k_1\\ k_2 \end{pmatrix} k=(k1k2)
RoPE 会让它旋转角度 nθn\thetanθ:
k~n=Rnθk \tilde k_n= R_{n\theta}k k~n=Rnθk
即:
k~n=(k1cos(nθ)−k2sin(nθ)k1sin(nθ)+k2cos(nθ)) \tilde k_n= \begin{pmatrix} k_1\cos(n\theta)-k_2\sin(n\theta)\\ k_1\sin(n\theta)+k_2\cos(n\theta) \end{pmatrix} k~n=(k1cos(nθ)−k2sin(nθ)k1sin(nθ)+k2cos(nθ))
因此,RoPE 的本质就是:
位置编号 m⟶旋转角度 mθ \text{位置编号 }m \quad\longrightarrow\quad \text{旋转角度 }m\theta 位置编号 m⟶旋转角度 mθ
位置不再是一个额外加进去的向量,而是变成了向量空间中的旋转角度。
三、旋转后的点积为什么只依赖相对位置
注意力分数来自 Query 和 Key 的点积。经过 RoPE 后,计算的是:
q~m⋅k~n \tilde q_m\cdot \tilde k_n q~m⋅k~n
把上面的两个旋转向量代入:
q~m⋅k~n=(q1cosmθ−q2sinmθ)(k1cosnθ−k2sinnθ)+(q1sinmθ+q2cosmθ)(k1sinnθ+k2cosnθ) \begin{aligned} \tilde q_m\cdot \tilde k_n =& (q_1\cos m\theta-q_2\sin m\theta) (k_1\cos n\theta-k_2\sin n\theta)\\ &+ (q_1\sin m\theta+q_2\cos m\theta) (k_1\sin n\theta+k_2\cos n\theta) \end{aligned} q~m⋅k~n=(q1cosmθ−q2sinmθ)(k1cosnθ−k2sinnθ)+(q1sinmθ+q2cosmθ)(k1sinnθ+k2cosnθ)
展开并整理后得到:
q~m⋅k~n=(q1k1+q2k2)cos((m−n)θ)+(q1k2−q2k1)sin((m−n)θ) \tilde q_m\cdot \tilde k_n= (q_1k_1+q_2k_2)\cos((m-n)\theta) + (q_1k_2-q_2k_1)\sin((m-n)\theta) q~m⋅k~n=(q1k1+q2k2)cos((m−n)θ)+(q1k2−q2k1)sin((m−n)θ)
这里用到了两个三角恒等式:
cosAcosB+sinAsinB=cos(A−B) \cos A\cos B+\sin A\sin B=\cos(A-B) cosAcosB+sinAsinB=cos(A−B)
sinAcosB−cosAsinB=sin(A−B) \sin A\cos B-\cos A\sin B=\sin(A-B) sinAcosB−cosAsinB=sin(A−B)
这一步就是 RoPE 的关键。
最终公式中不再单独出现 mmm,也不再单独出现 nnn,只剩下:
m−n m-n m−n
也就是说,RoPE 影响注意力分数的不是“这个词在第几个位置”,而是“两个词相隔多远”。
比如两个词分别在位置 111 和 333,相对距离是:
3−1=2 3-1=2 3−1=2
如果整句话整体平移到位置 100011000110001 和 100031000310003,相对距离仍然是:
10003−10001=2 10003-10001=2 10003−10001=2
RoPE 会让这两种情况对应同一个相对旋转角:
(m−n)θ (m-n)\theta (m−n)θ
所以它天然具有一种平移不变性:整体位置变了,但相对距离不变,注意力中的位置关系也保持一致。
四、为什么一个数字 mmm 能表示位置
这里还有一个容易卡住的问题:mmm 只是一个整数,为什么它能变成有效的位置特征?
如果只在一个二维平面上旋转,确实会有重复问题。
假设:
θ=10∘ \theta=10^\circ θ=10∘
那么:
m=1⇒10∘ m=1\Rightarrow 10^\circ m=1⇒10∘
而:
m=37⇒370∘=10∘ m=37\Rightarrow 370^\circ=10^\circ m=37⇒370∘=10∘
第 111 个位置和第 373737 个位置在这个二维平面上重合了。也就是说,单个旋转平面无法唯一表示长序列位置。
真实大模型的做法是使用 多频旋转。
假设一个 attention head 的维度是 128128128,RoPE 会把它拆成 646464 组二维平面:
(q1,q2), (q3,q4), …, (q127,q128) (q_1,q_2),\ (q_3,q_4),\ \dots,\ (q_{127},q_{128}) (q1,q2), (q3,q4), …, (q127,q128)
每一组二维平面都有自己的旋转频率:
θ1,θ2,…,θ64 \theta_1,\theta_2,\dots,\theta_{64} θ1,θ2,…,θ64
第 iii 组的旋转角度是:
mθi m\theta_i mθi
通常这些频率按指数规律衰减,例如:
θi=10000−2i/d \theta_i=10000^{-2i/d} θi=10000−2i/d
其中 ddd 是 head dimension。
直观理解,RoPE 给每个位置安排了一组“多频时钟”。
高频维度转得快,适合捕捉相邻 Token 的细粒度顺序;低频维度转得慢,适合区分长距离位置。即使某个高频平面转了一圈重合了,其他中低频平面通常还没有重合。
所以位置 mmm 最终不是由一个角度表示,而是由一串角度组合表示:
(mθ1, mθ2, …, mθ64) (m\theta_1,\ m\theta_2,\ \dots,\ m\theta_{64}) (mθ1, mθ2, …, mθ64)
这串多频角度就是位置 mmm 的高维旋转指纹。
更准确地说,它不是保证在无限长度上永不重复,而是在模型设计的上下文长度和数值精度范围内,提供了足够丰富、足够可区分的位置表示。
五、RoPE 和绝对位置编码的本质区别
传统绝对位置编码,例如 BERT、GPT-2 一类方法,通常是把位置向量直接加到词向量中。
设第 mmm 个 Token 的词向量是 xmx_mxm,位置向量是 pmp_mpm,则输入表示为:
hm=xm+pm h_m=x_m+p_m hm=xm+pm
然后生成 Query 和 Key:
qm=(xm+pm)Wq q_m=(x_m+p_m)W_q qm=(xm+pm)Wq
kn=(xn+pn)Wk k_n=(x_n+p_n)W_k kn=(xn+pn)Wk
注意力分数为:
Scoreabs=qmknT \text{Score}_{abs} = q_m k_n^\mathrm{T} Scoreabs=qmknT
展开后:
Scoreabs=(xm+pm)WqWkT(xn+pn)T \text{Score}_{abs} = (x_m+p_m) W_q W_k^\mathrm{T} (x_n+p_n)^\mathrm{T} Scoreabs=(xm+pm)WqWkT(xn+pn)T
其中会出现一个纯绝对位置项:
pmWqWkTpnT p_m W_q W_k^\mathrm{T} p_n^\mathrm{T} pmWqWkTpnT
其中会出现一个纯绝对位置项:
pmWqWkTpnT p_mW_qW_k^Tp_n^T pmWqWkTpnT
这个项直接依赖 pmp_mpm 和 pnp_npn。
因此,位置 111 和位置 333 的关系由 p1,p3p_1,p_3p1,p3 决定;位置 100011000110001 和位置 100031000310003 的关系由 p10001,p10003p_{10001},p_{10003}p10001,p10003 决定。即使它们的相对距离都等于 222,绝对位置编码也不能天然保证这两种位置关系完全一致。
RoPE 则不同。
RoPE 不把位置作为额外向量加进去,而是把位置变成旋转角度:
m→mθi m\rightarrow m\theta_i m→mθi
然后通过旋转后的 Query 和 Key 做点积,使绝对位置 m,nm,nm,n 在公式中自然合并成相对位置:
m−n m-n m−n
所以 RoPE 不是简单地告诉模型“这个词在第几个位置”,而是让模型在注意力分数中直接感知“两个词之间相隔多远”。
总结
RoPE 的逻辑可以串成一条完整链路:
首先,二维旋转矩阵来自标准基向量的旋转结果:
Rα=(cosα−sinαsinαcosα) R_\alpha= \begin{pmatrix} \cos\alpha&-\sin\alpha\\ \sin\alpha&\cos\alpha \end{pmatrix} Rα=(cosαsinα−sinαcosα)
然后,RoPE 把 Token 的位置编号 mmm 映射成旋转角度 mθm\thetamθ:
m→mθ m\rightarrow m\theta m→mθ
接着,它对第 mmm 个位置的 Query 和第 nnn 个位置的 Key 分别旋转:
q~m=Rmθq,k~n=Rnθk \tilde q_m=R_{m\theta}q, \quad \tilde k_n=R_{n\theta}k q~m=Rmθq,k~n=Rnθk
最后,两者点积后,绝对位置 m,nm,nm,n 消失,只留下相对距离:
m−n m-n m−n
因此,RoPE 的本质是:
用旋转矩阵把位置编号变成几何角度,再通过 Query 和 Key 的点积,把绝对位置自然转化为相对位置。
相比绝对位置编码,RoPE 更符合语言中的结构规律:很多时候,真正重要的不是一个词出现在第几个座位,而是它和另一个词之间隔了多远。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)