浅谈位置编码(RoPE)
当前版本为本文的尝鲜版,稳定版尚未发布:
稳定版已发布
位置编码:
https://zhuanlan.zhihu.com/p/454482273
transformer的sin位置编码本身已经包含了相对位置信息,本身就是一种包含相对信息的绝对位置编码。因为它符合一种形式:
而这种编码一种比较尴尬的地方就在于,这仍然是一种绝对位置编码,虽然token之间的位置编码可以互相转换,但是每个token的位置编码还和自己的位置强相关,有点等差数列的意思。(抽象到一维的情况,假如我们使用的位置编码就是一维自然数,那也符合这种形式),所以这仍然是绝对位置编码
希望可以有一种完全的相对位置编码,也就是位置编码在后续的forward中完全不会产生绝对位置的信息。
这里苏剑林给介绍了一下一些位置编码
https://zhuanlan.zhihu.com/p/352898810
ROPE:
本人建议观看视频:https://www.bilibili.com/video/BV1F1421B7iv
以下内容摘编自:十分钟读懂旋转编码(RoPE)
首先,位置编码本身并不一定需要是一个显式的embedding向量,可以是一种“信息”,融入到模型中即可,这是理解RoPE的一个关键点。一般的位置编码是计算一个embedding向量,和正常的word embedding相加。比如:
这里 \(P_{emb}\)是位置编码, \(X_{emb}\)是词嵌入。我们把上式写成:
这里的 \(f\)的作用就是”对 \(X_{emb}\)施加位置编码“。因此,位置编码可以视为一种”施加“作用。然后,先说RoPE的位置编码计算方法:对于序列中的第m个token,它的词嵌入为 \(\boldsymbol{x}_m\),计算它的 \(\boldsymbol{q}_m,\boldsymbol{k}_m\):
然后,对其”施加位置编码信息“:
然后,把 \(\boldsymbol{qpos}_m\)和 \(\boldsymbol{kpos}_m\)当成之前的Query和Key向量进行attention计算即可。这里的 \(\boldsymbol{R}^\theta_{d,m}\)和位置m相关,这样就包含了位置的信息,但是,推导后实际上在后续self-attention计算中和绝对位置是无关的。这个公式可见:R的计算公式
这个大的矩阵可以提前计算好放在那里。
简洁地写一下,“施加”的意思就是,对原始的q,k向量做旋转,旋转的角度则由自己的绝对位置决定。但是,要旋转一个向量,只能旋转二维向量,我们很好理解二维坐标系中的旋转,那么高维向量怎么旋转?作者的做法是,把高维向量两两一组,每个组内的两个向量做二维旋转。
我们可以看到,上面相当于对原始的q和k向量做了旋转,旋转的角度就是你的绝对位置。我们将旋转矩阵记为\(R(m;\theta)\),其中\(\theta\)是频率,m是位置(旋转角)。对于一个attention计算过程:
\(q\cdot k^T\),就变成了\(qR(m)\cdot (kR(n))^T=qR(m)R(n)^Tk^T\),这里需要插播两个旋转矩阵的性质:
对于旋转矩阵R(m),有
- R(m+n)=R(m)R(n)
- R(m)^T=R(-m)
所以\(q\color{red}{R(m)}\cdot (k\color{red}{R(n)})^T=qR(m)R(n)^Tk^T=q\color{red}{R(m-n)}k^T\)
在attention计算中,自然而然的就考虑到了二者的相对位置:(m-n),计算过程变化为:
\(qk^T\rightarrow q\color{red}{R(m-n)}k^T\)
这样自然融入了相对位置信息