从正余弦位置编码到 RoPE

其实对位置编码的理解一直处在一个比较感性的位置,比如我大概知道正余弦位置编码和 RoPE 的区别,但是当询问一些细节的时候就不行,比如手撕位置编码。因此今天就再系统的梳理一下吧。

直观理解标准的正余弦位置编码

对于标准的正余弦位置编码,公式如下:

乍一看其实涉及到很多变量,这个时候我们最好还是从感性理解入手。pos 其实就是我们的 Token 位置索引,然后 就是我们的维度索引, 是总维度。我们先假设每个 Token 只有一个维度,这样的话,从 Token 位置这个维度,其实就是一个正弦函数随着位置索引的变化。这个时候是有周期的。

image.png

然后我们加上一个维度,第二个维度,从 Token 维度看过去也是一个周期函数,只不过这次换成了 余弦函数,但是频率和第一个维度是相同的。

然后我们加上第三个维度,这次又回到正弦函数,但是频率更慢了一些…

相当于:低纬度 Token 捕获的是相邻 Token 之间的细微的位置变化(快节奏),而高纬度 Token 捕获的是长距离的宏观的位置关系(慢节奏)。

为什么要正余弦交叉?

但是这就引出了一个问题:为什么要正余弦交叉呢?

要知道标注的正余弦位置编码是加在 Embedding 上的,当计算位置 和位置 的得分的时候,点积结果如下:

可以看到,这里的公式是可以解析成三部分:

  • 语义-语义
  • 语义-位置
  • 位置-位置

受限语义-语义比较好理解,语义-位置网上也有人解释,但是比较牵强,我感觉更像噪声。然后就是最重要的位置-位置,用来确定相对距离。

那么我们现在关注一下下面这个公式,这个如何计算呢?

我们取一对相邻的维度,比如第 0 维度和第 1 维度。

  • 位置 的向量:
  • 位置 的向量:

我们要计算相似度点积,也就是:

可以看到,点积结果直接反应了相对距离 k。

存在哪些问题?

既然加法这么好,为什么现在的 RoPE 又回到乘法旋转了?

注意看注意力得分公式:

里面存在大量单独的位置编码 。假设训练的序列是 512,那么在推理的时候遇到 512 以后的位置,模型就会遇到未见过的位置编码。但是位置编码不是具有周期性的吗?为什么会遇到未见过的数据呢?

注意看在低纬度里,比如 ,频率为 1,周期就是 6.28 个 Token。但是到了高频,频率就是 ,周期就是

看到了吗,虽然低纬度的编码在重复,但是加上高维,模型还是会遇到未见过的位置向量。

RoPE 如何解决?

RoPE 并不是直接作用在 Embedding 层,而是作用在 矩阵上,具体来说:

  • Token 先转换成语义向量语义向量
  • 经过 矩阵投影,得到原始的
  • 旋转操作:
    • 进行旋转操作:
    • 进行旋转操作:
    • 保持不变: 向量直接进入下一步。
  • 使用旋转后的 计算点积得分。

从正余弦位置编码到 RoPE
https://d4wnnn.github.io/2026/03/11/Notion/从正余弦位置编码到 RoPE/
作者
D4wn
发布于
2026年3月11日
许可协议