笔者刚开始对这个东西怎么来的非常不理解,也很迷茫,看了许多篇文章终于有所想法和了解。这里以一个追根溯源的角度,试图还原这个idea的来源。希望大家可以喜欢~
阅读本文需要的前置知识:
1、attention机制
2、了解矩阵乘法和余弦相似度的关系(高中数学)
3、旋转矩阵
4、(可选)欧拉公式
首先,我们得对注意力机制有所了解。我们知道,注意力机制里面用到了三个东西,Q,K,V,我们对着三个东西计算attention-score,然后做softmax,就得到了注意力的结果,那么在transformer中,Q,K,V这三个的attention-score被定义为:
其次,需要大家理解,我们要进行位置编码的目的,是因为attention这里计算attention-score的时候,我们的Q和K都不含有位置信息,但是,在我们的语言中,往往一句话的顺序如果颠倒,那么语义会发生天差地别的变化,因此,把位置信息注入到Q和K中是非常必要的。
那么接下来,我们回顾一下绝对位置编码。
绝对位置编码可以理解为这样一个函数:
绝对位置编码的方式比较暴力,大致可以这样写出来:
关于这个公式的解释,网上很多都有了,这里不做详细的数学阐述,可以简单的理解为对pos的一个映射,每个不同pos的token中的不同特征,都被映射为了一个不同的值。
然后我们把这个位置向量,直接和原来的embedding过的token加起来,就相当于把位置信息注入了。
超暴力有木有!这个直接加进去的东西还能被还原出来,这模型的能力也是够强了!不过坏处就是,这玩意确实就是仅仅记录了他在句子中的位置,并不是去计算和其他词的相对位置,那么,下面开始!
好,下面开始Rope的地方
Rope的中心思路是这样的:
也就是说,我们要找到一个函数满足以上这个形式。
还记得我们前面说到的余弦相似度吗,所以我们初步有一个想法,就是利用attention中计算夹角的这个过程,来把Rope给实现了。而且刚好,attention中的Q,K的那个乘法,可以是做是q对所有向量ki的一个遍历。也就是说,只要我们能把该向量的位置信息以偏转角的形式加入到q和k中,那么他们在计算余弦相似度的时候,自动就会算出这两个位置的差了!
那么现在,问题就转化为,如何把位置信息以偏转角的形式保存?由于我们在attention-score的计算中,QK的乘法其实可以看作是一个内积的过程。那么我们前面已经说过了,内积本质上就是在算一个未归一化的相似度。那么,基于此之上,我们只需要让每个token原本的向量,都任意地旋转一个跟它的位置有关的角度,那么在计算夹角的时候,就会自动计算出和一个相对位置的相似度了!
那么,接下来就是旋转角度和位置的关系,这里我们可以套用原来绝对编码那个地方的旋转角,也可以随便怎么定义。反正核心目的就是让每个token的旋转的角度不同,还和位置有点关系。这里我用原论文的中的定义:
当然哈,有细心的小伙伴可能发现了,你这形状也不对啊,乘不了啊。
事实上,这里确实有一个trick,就是需要把
整理一下整个过程:
我们先把x对半分开,看成是一个(x,y)形式的坐标。我们对于这个坐标,旋转一个和位置有关的角度。
然后把这个和位置有关的角度储存为新的x,这样求内积的时候,就会计算出两个旋转角度之差,这个差,就是我们的相对位置。
当然,原文中还为了装逼,把旋转矩阵搞成了欧拉公式的形式。这里不讲了,本质都是一样的,感兴趣的小伙伴可以去搜搜欧拉公式。不过从某种程度来看,欧拉公式的计算量可能要少一点,不过思想都一样,我就不做强调了。
希望能够帮到对于RoPE有所困惑的小伙伴们呀~
如果您喜欢我的文章,可以考虑打赏以支持我继续创作.