RoPE 位置编码详解

旋转位置编码(Rotary Position Embedding, RoPE)由 Su 等在 2021 年提出,用旋转矩阵把位置信息编码进 query 与 key 向量,使两个位置的内积只依赖它们的相对距离与方向。它已被 LLaMA、Qwen、Gemma 等广泛采用。

数学形式

对维度 d 的向量,按奇偶维度两两配对,在每对上做角度 theta_i 与 position 的旋转。位置 m 的向量 x 经旋转矩阵 R^m 映射为 R^m x。注意力分数 q_m^T k_n 因此等于 (R^m q)^T (R^n k),只含相对位置 m-n。

import torch
def build_rope(dim, seq_len, base=10000.0):
    inv = 1.0 / (base ** (torch.arange(0, dim, 2) / dim))   # 频率
    pos = torch.arange(seq_len).float()
    freqs = torch.outer(pos, inv)                            # (seq, d/2)
    return torch.cat([freqs.cos(), freqs.sin()], dim=-1)     # 旋转表

为什么好

RoPE 让相对位置天然进入注意力,外推性好;配合线性缩放即可扩展上下文(见位置插值)。它不增加参数量,且可与因果掩码无缝结合。

实现要点

实际实现常把 cos/sin 表缓存,对 q、k 按 (cos, sin) 做旋转拼接,避免逐 token 重复计算。长上下文下需与缩放策略配合,防止远端位置衰减过快。

小结

RoPE 用旋转矩阵把绝对位置编码进 q、k,使注意力分数仅依赖相对位置,外推友好且零额外参数,是现代大模型的主流位置编码方案。

参考与延伸阅读

本文累计阅读