大家好,今天的这篇文章,我想避开复数的推导,从一些全新的、更好玩、更可视化的角度,来探究RoPE的原理和各种性质。
这里所说的“可视化”,不仅仅是大家熟悉的“空间向量的旋转”,
而是:
-
具体能让你在调控RoPE的超参时,可以在脑海里快速绘制出一副图,预估你的调参对模型效果的大致影响
-
或者是当你想探寻衰减性和外推性时,你的脑海里不再仅有代表结果的那一副曲线图,你能动态地绘制出这些重要的性质是怎么一步步产生的。
诸如此类。而当你看完这篇文章,你就能站在几何的角度去理解复数推导的过程了(复数的运算本身就具有几何意义,本文也会给出一定解读)。
【全文目录如下】
一、原始Transformer函数式位置编码
1.1 从旋转的角度理解原理
1.2 这个位置编码为什么得不到人们的青睐
二、RoPE
2.1
在做一件什么事
2.2 旋转角度:二维空间
2.3 旋转角度:高维空间
(1)可以使用一个很小的
吗
(2)钟表视角下的高维旋转
2.4 理解衰减性:从傅立叶变换的角度(
快乐版
)
2.5 理解外推性:基数的选择
(1)可视化位置编码的训练过程
(2)基数的选择
一、原始Transformer函数式位置编码
1.1 从旋转的角度解读
transformer位置编码原理我们在
这篇
文章中详细讲过,这里我们对它进行一个快速的回顾解读。了表达方便,
我们先以二维特征空间为例
,根据transformer PE的构造方法,我们有:
其中
是我们设定好的常数。
那么根据:
我们可以把
和
的关系拆解成:
从这个拆解关系我们可以直观看出,
由于
是一个表示顺时针旋转的正交矩阵(正交意味着旋转不改变向量的模长, 只改变方向), 则
其实就是以
为基础, 顺时针旋转
这个角度而来。
为了直观体会到这点, 我们以
为基础, 画图看一下不同的
是如何旋转而来的:
在直观理解了如何从
推导至
的基础上, 我们来探究
的性质:
由于
是预先设定好的一个常数, 所以当我们假设某个 t 固定不变, 然后慢慢增大
时,
逐渐变小,
这也意味着相距较远的两个位置编码的内积越小, 即内积可以用于反馈两个位置向量在绝对位置上的远近。
但是,细心的你一定发现了,
如果我保持红色
不变,顺时针慢慢转动绿色PE时,可能会出现下图的情况,即图中所示的两个绿向量和红向量的内积是一样的,但是左侧绿向量明明距离红向量更远
,此时,我们似乎无法从内积大小判断两个位置向量的远近:
那该怎么办呢?我们有一个粗暴但有效的解决方法:让每次位置变动时的转动角度小一些,不就可以了吗?
由于我们转动角度为
,
这意味着只要我们尽量把
设置得小一些(这就意味着调大了
的周期)
, 让绿线旋转的幅度小一些, 使得不管有多少个位置向量, 绿线都在第一和第四象限内移动, 不就可以了吗? 这就是关于
的一个最简单的直观解释, 在后文中, 我们还会结合更细致的内容, 继续探寻
在更高维的位置向量特种空间中的作用。
1.2 缺陷
从1.1节的介绍中,我们提取到两个关于transformer原始位置编码的重要信息:
-
在设置合适的值的前提下,每个位置都能取到唯一的位置编码(绝对性)
-
一个位置编码可以由另一个位置编码旋转而来(相对性),且在设置合适的
值的前提下,两个位置编码的内积大小可以反应位置的远近,内积越大,距离越远(远程衰减性)。
我们固定住某个 t , 变动
, 来可视化一下
的变动趋势:
如图:
-
-
纵轴表示固定某个
的情况下, 改变
后得到的
和
的内积
-
d表示不同的hidden_size(例如在1.1节中,我们就假设d = 2)
从图中我们可以发现:
-
在固定某个
的情况下,两个位置编码的内积具有对称性
(很简单,对照1.1的圆圈,想象cos函数的对称性。更严谨的推导参见开头引用的文章的3.3节(1)部分)
-
在固定某个
的情况下,两个位置编码的内积具有远程衰减性(在上面实验图对应的原始论文中被称为“距离意识(distance-aware)”)
,即两个位置编码相距越远,距离越小。
看起来,transformer的原始位置编码应该已经足够好了,可是为什么在很长的一段时间里,人们还是普遍用可学习式的位置编码,甚至还有很多实验证明了transformer的这种位置编码对最终的效果没有起到实质性帮助呢?
这是因为, 我们上述的一切分析, 都是在原始位置编码
上的结果, 我们一般把位置编码和输入层的token相加, 然后让他们继续去做接下来的计算。可是, transformer架构是复杂的, 更详细地说,
当 token向量进入attention层时, 起作用的还是
这个部分吗?
为了更详细探究这个问题,我们假设:
-
分别为两个不同位置的原始token向量, 其尺寸为(hidden_size, 1)
-
分别为两个不同位置的原始PE向量, 其尺寸为 (hidden_size, 1)
-
分别为尺寸为 (hidden_size, hidden_size) 的Q、K矩阵
那么数据过attention部分可以表示成:
我们只关注其中和两个位置变量都相关的部分
,也就是:
从中我们不难发现, 经过attention层后, 位置编码真正起作用的不再是
, 而是引入了线性变化后的
。
那么再引入这种线性变化后,位置编码还能保持上述所说的绝对性、相对性和远距离衰减性这种优良性值吗? 我们同样用实验的方式来细看这一点。
由于
本质上可以合成一种线性变化, 所以我们可以随机初始化一个线性矩阵来代替它, 在我们的实验中, 我们做了三组试验:
同样, 我们固定住某个我们固定住某个
, 变动
, 来可视化一下这三组试验的结果:
上图中的榾线和绿线即表示两位置编码内积间引入线性变化
后的结果, 可以发现相比于标准的蓝线
,
原始位置编码的优良性质(远程衰减性等)都受到了极大程度的破坏。
总结来看, 虽然原始transfomer位置编码本身考虑了绝对性、相对性和远程衰减性, 但是由于位置编码经过 attention层后, 最终起作用的形式是
而不是
, 而进一步我们通过实验直观证明了插入一个线性变化会极大破坏位置编码设计之初的各种优良性质, 所以早期 transformer的这种函数式的位置编码并没有得到大家的青睐。
二、RoPE
在第一部分的分析中,我们已经知道attention层的计算
会破坏掉输入层位置编码的优良性质,那么我们自然而然会想到:
如果我直接在attention层中融入位置信息
,也就是我直接把位置编码作用于
,这样我不就能维持位置编码优良性质不变吗?(在接下来的讲解中,为了表达方便,我们直接用下标m和n表示两个位置)
2.1
在做一件什么事
这里
都是尺寸为
(hidden_size, 1)
的向量。
我们知道,当我们计算
时,我们是在做attention score的计算,其结果表示m位置的token和n位置token间的相关性分数。
现在让我们切换一下视角,这个相关性分数其实就是两个特征向量之间的内积,在一定程度上衡量了两个向量之间的相似性。
现在我们希望把位置编码的信息直接引入
中,这也就意味着,
我们希望根据|n-m|的结果,给这个内积计算一定的惩罚:
你可能觉得有些抽象,不要紧,我们马上仿照1.1中的方式,给出可视化的解释
2.2 旋转角度:二维空间
假设原始
的特征向量如下:
模仿 1.1 的方式, 如果我们想让
具备位置信息, 我们可以分别把他们旋转 m 和 n 度。
在 1.1 中我们采用顺时针旋转,在这里我们使用逆时针旋转
(没有特殊原因,只是为了和原始rope旋转方式贴合),那么我们可以得到如下结果, 其中
分别表示旋转后的结果:
可以发现, 旋转过后, 随着
差值的变大,
在保持向量模长不变的情况下,
我们拉远了
两者之间的距离, 也即降低了它们的内积, 最后达到降低(惩罚)attention score的效果。
同时, 和1.1中一样, 我们同样需要引入用于参数
, 通过拉长三角函数周期的方式确保不同位置的向量不发生碰撞。
我们以上图中的
为例, 当保持其模长不变的情况下, 它的逆时针运动轨迹是一个圆, 这也意味着一个较小的
和一个较大的
代表的向量可能会重合, 所以我们需要使用
这种形式, 对
每次旋转的幅度加以控制。
总结起来,在二维特征空间下,
我们定义了一个逆时针正交旋转矩阵(正如1.1所说,正交旋转矩阵保证了模长不变,即维护q,k原始的特征,只单纯做旋转使其拥有绝对位置信息
):
其中
表示绝对位置,例如0,1,2...
接着我们将其作用到attention部分的计算上,则有:
端详上面这个等式,我们可以发现:
2.3 旋转角度:高维空间
(1) 可以使用一个很小的吗
到目前为止,我们都在讨论二维特征空间下的位置编码,那么到了高维特征空间,位置编码应该如何设计,比如此时我们有:
其中
就是我们所说的hidden_size。
我们先再次把目光聚焦回二维特征空间上, 这次我们只看
(因为
也是同理)
正如2.2节所说, 我们通过旋转的方式赋予原始