LLM(六)——Position Encoding
RNN的结构包含了序列的时序信息,而Transformer却完全把时序信息给丢掉了,比如“狗咬我”,和“我咬狗”,两者的意思千差万别,故为了解决时序的问题,Transformer的作者用了一个绝妙的办法:位置编码(Positional Encoding)
一、绝对位置编码(Absolute Positional Encoding)
1.1 简介
将每个位置编号,从而每个编号对应一个向量,最终通过结合位置向量和词向量,作为输入embedding,就给每个词都引入了一定的位置信息,这样Attention就可以分辨出不同位置的词了。
- 如果简单粗暴的话,直接给每个向量分配一个数字,比如1到1000之间
- 也可以用one-hot编码表示位置

- <<Attention Is All You Need>>论文中作者通过sin函数和cos函数交替来创建 positional encoding,其计算positional encoding的公式如下
其中,pos相当于是每个token在整个序列中的位置,相当于是0, 1, 2,
3…(看序列长度是多大,比如10,比如100),
| 位置向量的第多少维(0 2 4等偶数维用sin函数计算) | i | 2i | 2i+1 |
|---|---|---|---|
| 0 | i = 0 // 2 = 0 | 2i = 0 | |
| 1 | i = 1 //2 =0 | 2i = 0 | 2i+1 = 1 |
| 2 | i = 2 // 2 = 1 | 2i = 2 | |
| 3 | i = 3 // 2 = 1 | 2i = 2 | 2i+1 = 3 |
| 4 | i = 4 // 2 = 2 | 2i = 4 | |
| 5 | i = 5//2 = 2 | 2i = 4 | 2i + 1 =5 |
| …. | |||
| 510 | i = 510 // 2 = 255 | 2i = 510 | |
| 511 | i = 511 // 2 = 255 | 2i = 510 | 2i + 1 = 511 |
相当于2i是指向量维度中的偶数维,即第0维、第2维、第4维…,第510维,用sin函数计算;2i+1 是向量维度中的奇数维,即第1维、第3维、第5维..,第511维,用cos函数计算。
1.2 例子
假如要编码”我爱你”的位置向量,假定每个token都具备512维,如果位置下标从0开始时,则根据位置编码的计算公式可得
- 当对
上的单词”我”进行位置编码时,它本身的维度有512维
- 当对
上的单词”爱”进行位置编码时,它本身的维度有512维

然后再叠加上embedding向量,可得

- 当对
上的单词”你”进行位置编码时,它本身的维度有512维
最终得到的可视化效果如下图所示

1.3 代码
1 | |
代码中div_term如下:
其中的中括号对应的是一个从 0 到
这里使用指数和对数运算的原因是为了确保数值稳定性和计算效率:
- 一方面,直接使用幂运算可能会导致数值上溢或下溢。当
较大时, 中的幂可能会变得非常小,以至于在数值计算中产生下溢。通过将其转换为指数和对数运算,可以避免这种情况,因为这样可以在计算过程中保持更好的数值范围 - 另一方面,在许多计算设备和库中,指数和对数运算的实现通常比幂运算更快。这主要是因为指数和对数运算在底层硬件和软件中有特定的优化实现,而幂运算通常需要计算更多的中间值
所以,使用指数和对数运算可以在保持数值稳定性的同时提高计算效率。
由于
由于
二、相对位置编码(Relative Positional Encoding)
2.1 简介
最先介绍相对位置编码的是论文《self-attention with relative positional representation》(RPR)。后面各种相对位置编码变体基本也是依葫芦画瓢的简单修改。

RNN中,第一个”I”与第二个”I”的输出表征不同,因为用于生成这两个单词的hidden states是不同的。对于第一个”I”,其hidden state是初始化的状态;对于第二个”I”,其hidden state是编码了”I think therefore”的hidden state。所以RNN的hidden state 保证了在同一个输入序列中,不同位置的同样的单词的output representation是不同的。

Transformer的位置编码如果只用绝对位置编码(absulate position encoding),与当前内容在原始句子中的相对位置是没有关系的。对比RNN系列的模型,Transformer的一个缺点是没有从网络结构上对位置信息进行处理,而只是把位置编码加入到了输入层。RPR的动机就是解决Transformer的这个天然缺陷,它的做法是把相对位置编码加入到了self-attention的内部。这样做的好处是当在计算权值或者特征值的时候,额外添加了位置信息,无疑将有助于这两个变量的计算。
RPR提出的模型的原理是在计算第
例如对一个长度为5的序列,它共有9个相对位置编码信息(当前位置编码,当前位置的前4个,当前位置的后四个),如下表所示:
| Index | 解释 | Value |
|---|---|---|
| 3 | 位置i与位置i-1之间的距离 | -1 |
| 4 | 位置i与位置i之间的距离 | 0 |
| 5 | 位置i与位置i+1之间的距离 | 1 |
| 6 | 位置i与位置i+2之间的距离 | 2 |
| 7 | 位置i与位置i+3之间的距离 | 3 |
通过加入上面的相对位置编码信息,再对比一下“I think therefore I am”中两个‘I’的输入有什么不同,如图第一个‘I’的相对位置编码信息:

第二个‘I’的相对位置编码信息:

RPR并没有根据输入序列的长度来确定需要考虑的相对位置之间的距离,而是用了一个固定的常数
2.2 实现
自注意力头对一个输入序列
每个权重系数
并且
RPR需要学习两个相对位置向量,一个是计算第
RPR在self-attention中添加了两个可学习的变量
这里用加法的原因是因为这样设计计算效率更高。
然后学习相对位置表示
相对位置将本来依赖于二元坐标
2.3 其他相对位置编码
三、Rotary Position Embedding(RoPE)
旋转式位置编码(Rotary Position Embedding,RoPE),这是一种配合Attention机制能达到“绝对位置编码的方式实现相对位置编码”的设计。而也正因为这种设计,它还是目前唯一一种可用于线性Attention的相对位置编码。
3.1 欧拉公式
3.1.1 复数
- 一般用
表示复数,实数 叫做复数的实部,实数 叫做复数的虚部

- 复数的辐角是指复数在复平面上对应的向量和正向实数轴所成的有向角

的共轭复数定义为: ,也可记作 ,复数与其共轭的乘积等于它的模的平方,即 ,这是一个实数
根据复数的定义:
- 即把 1 经过2次完全一样的操作:
,变成了 −1 ,那什么样的操作能得到这个效果呢?先旋转 90度,再旋转 90 度就可以了.如下图所示

所以,
- 比如对于
,自然数 1,绕坐标中心旋转180度( ),再平移1 ,就回到坐标原点 - 再比如对于

3.1.2 欧拉公式
当
表达的含义在于该指数函数可以表示为实部为
该欧拉公式相当于建立了指数函数、三角函数和复数之间的桥梁
- 由于有
- 所以,如果
,则有

可以推出:
把复数当作向量来看待,复数的实部是


向量的加减法:


3.2 Rotary Position Embedding
在RoPE中,出发点就是“通过绝对位置编码的方式实现相对位置编码”,这样做既有理论上的优雅之处,也有实践上的实用之处,比如它可以拓展到线性Attention中就是主要因为这一点。为了达到这个目的,给self-attention中的
其中
表示第 个token对应的词向量 集成位置 之后的query向量 表示第 个token对应的词向量 集成位置 之后的 key 向量、 value 向量
然后使用$
Attention的核心运算是内积,所以我们希望的内积的结果带有相对位置信息,因此假设存在恒等关系:
该函数仅将词向量
- 左边算是
和 向量的内积,而这恰好是transformer计算自注意力机制的核心一步,右边等式则意味着 与 的相对位置如此一来,该等式便把“ 和 的内积”与“它们的相对位置”给串起来了 - 左边是含有各自绝对位置信息的
向量和 向量,而这个等式就是RoPE追求的目标,物理含义就是通过显式传入绝对位置信息实现与传入相对位置信息对等的情况
假定现在词嵌入向量的维度是两维
这里面的
首先看第一个
这个式子的右边项有两部分,一部分是
对于
,可知其中的 是个二维矩阵, 是个二维向量,自然相乘的结果也必然是一个二维向量,用对于
,根据欧拉公式 可得由上述第1点结论,可知
从而有
基于上面第2点结论,可知
- 考虑到以下两个关于复数的背景知识
将这个结果表达成实数向量形式,即是
至此,你也就不难发现,这不就是query向量乘以了一个旋转矩阵么
至于第二个式子
最后第三个式子
其中,
- 考虑到
再结合上面第一个式子中的推导,可得
结合
- 接下来证明上述函数
的计算公式是成立的
首先,回顾一下attention操作,位置
可得
相当于[A,B]与[C,D]做内积,则相当于A B横着,C D竖着,最终结果为AC BD,最后再把括号里的项全部对应相乘、展开
- 首先,把上面第二点的式子整理一下,总计8项,为了把
相关的项提取出来,第1项 8项合并处理、第2项 7项合并处理、第3项 6项合并处理、第4项 5项合并处理
其次,考虑到
最后,再把相关项的特点,两次调整下顺序即可。依据以上三点,从而有
如此,也就证明了,位置
最后,把上面的式子一、式子二的最终结果都分别用矩阵向量乘的形式来表达就是:
接下来,我们要计算两个旋转矩阵的乘积,即中间部分的这个式子
展开之后,可得
从而有
上面都还只是针对词嵌入维度为2的情况,那对于
内积满足线性叠加性,因此任意偶数维的RoPE,我们都可以表示为二维情形的拼接,即将词嵌入向量元素按照两两一组分组
利用
每组应用同样的旋转操作且每组的旋转角度计算方式如下:
所以简单来说 RoPE 的 self-attention 操作的流程是

- 对于 token 序列中的每个词嵌入向量,首先计算其对应的 query 和 key 向量
- 然后对每个 token 位置都计算对应的旋转位置编码
- 接着对每个 token 位置的 query 和 key 向量的元素按照 两两一组 应用旋转变换
- 最后再计算 query 和 key 之间的内积得到 self-attention 的计算结果
3.3 代码实现
3.3.1 非LLaMA版的实现
sinusoidal_position_embedding:这个函数用来生成正弦形状的位置编码。这种编码用来在序列中的令牌中添加关于相对或绝对位置的信息
1 | |
为方便和transformer的位置编码做对比,故这里也假定output_dim = 512
- 首先,有 ids 张量,当 output_dim 为 512 时,则
ids = [0,0, 1,1, 2,2, …, 254,254, 255,255]
然后用一个基数为10000的指数运算,使用了公式 torch.pow(10000, -2 * ids / output_dim)
- 执行 embeddings = position * theta 这行代码,它会将 position 的每个元素与 theta 的相应元素相乘,前三个元素为
- 接下来我们将对 embeddings 的每个元素应用 torch.sin 和 torch.cos 函数
对于 torch.sin(embeddings),取 embeddings 中的每个元素的正弦值:
对于 torch.cos(embeddings),取 embeddings 中的每个元素的余弦值:
最后,torch.stack([torch.sin(embeddings), torch.cos(embeddings)], dim=-1) 将这两个新的张量沿着一个新的维度堆叠起来,得到的 embeddings如下
RoPE:这个函数将相对位置编码(RoPE)应用到注意力机制中的查询和键上。这样,模型就可以根据相对位置关注不同的位置
1 | |
- sinusoidal_position_embedding函数生成位置嵌入。在output_dim=512的情况下,每个位置的嵌入会有512个维度,但为了简单起见,我们只考虑前8个维度,前4个维度为sin编码,后4个维度为cos编码。所以,可能得到类似以下的位置嵌入
1 | |
- 然后,提取出所有的sin位置编码和cos位置编码,并在最后一个维度上每个位置编码进行复制
1 | |
- 更新query向量
首先构建一个新的q2向量,这个向量是由原来向量的负的cos部分和sin部分交替拼接而成的。用cos_pos对q进行元素级乘法,用sin_pos对q2进行元素级乘法,并将两者相加得到新的query向量
1 | |
公式如下
- 更新key向量
对于key向量,处理方法与query向量类似
1 | |
attention的编码实现
attention:这是注意力机制的主要功能
- 首先,如果use_RoPE被设置为True,它会应用RoPE,通过取查询和键的点积(并进行缩放)
- 然后,进行softmax操作来计算注意力分数,以得到概率,输出是值的加权和,权重是计算出的概率
- 最后,旋转后的
和 计算点积注意力后,自然就具备了相对位置信息
1 | |
3.3.2 LLaMA版的实现
接下来,再来看下LLaMA里是怎么实现这个旋转位置编码的,具体而言,LLaMA 的model.py文件里面实现了旋转位置编码
首先,逐一实现这三个函数precompute_freqs_cis,reshape_for_broadcast,apply_rotary_emb
1 | |
之后,在注意力机制的前向传播函数中调用上面实现的第三个函数 apply_rotary_emb,赋上位置信息
1 | |
四、ALiBi
ALiBi全称是Attention with Linear Biases,通过论文《Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation》提出,其不像标准transformer那样,在embedding层添加位置编码,而是在softmax的结果后添加一个静态的不可学习的偏置项(说白了,就是数值固定)

- 当计算每个头的注意力分数时,线性偏差注意力方法ALiBi会向每个注意力分数(
,左)添加一个常数偏差(右)
左边是自注意力得分,关于
所以才有
和 之间的距离是0,所以对应位置就是0 和 之间的距离是相对位置偏移为“k的索引”1 - q的索引,得到1-2 = -1,就对应到了中间矩阵的取值为-1了以此类推,相对距离矩阵的中间对角线上都是0,然后左下角的取值都是对应的k的索引-q的索引了
- 那
具体怎么取值呢,按论文中的说法是
当8个heads的时候,
如果是16个heads,则
相当于追加了一半的
扩展到一般情况就是:对于
这样的
最终整体的公式便是
对于第
五、LLaMA 2 Long中位置编码的修改
LLaMA 2 Long论文《Effective Long-Context Scaling of Foundation Models》,LLaMA 2 Long相比LLaMA 2对位置编码进行了一个非常小的必要修改
在LLaMA 2中,它的位置编码采用的是旋转编码RoPE方法,其通过旋转矩阵来实现位置编码的外推
- 本质上来说,RoPE就是将表示单词、数字等信息的token embeddings映射到3D图表上,给出它们相对于其他token的位置——即使在旋转时也如此
- 这就能够使模型产生准确且有效的响应,并且比其他方法需要的信息更少,因此占用的计算存储也更小
然而,Meta的研究人员通过对70亿规模的LLaMA 2进行实验,确定了LLaMA 2中的RoPE方法的一个局限性,即,阻止注意力模块聚集远处token的信息。为此,Meta想出了一个非常简单的破解办法:
减少每个维度的旋转角度,具体而言就是将超参数“基频(base frequency)b”从10000增加到500000。Meta还通过可视化为螺旋图这一非常有趣的方式,将RoPE ABF与RoPE PI的差异进行了理论分析:

- 上图b旨在说明位置插值对映射向量相对位置的影响,与上图a相比,连续点之间的距离被大幅缩小
- 上图c说明了调整基频对结果的影响,虽然螺旋频率增加导致点之间最小距离缩小,但连续点之间的距离几乎与上图a相同,即螺旋频率增加所带来的影响将在高频段中逐渐减少
总之,与RoPE PI相比,RoPE ABF的优势主要体现在它能以更大的粒度分配嵌入向量(the embedded vectors),从而使模型更容易区分位置。此外,他们还观察到,嵌入向量之间的相对距离既对RoPE PI的关键参数有线性依赖性,也对RoPE ABF的关键参数也有对数依赖性。这也就是为什么可以很容易地对基频这一超参数“下手”。
缩小了RoPE对远端token的衰减效应,并且在扩展LLAMA的上下文长度上优于一项类似的名为“位置插值”的方法RoPE PI(如下图所示,RoPE表示基线方法,RoPE ABF为Meta此次发明的新方法,xPos是另一种应用了该方法的旋转编码变体)

LLaMA 2 Long凭借着这一改动,达成了3.2万的上下文token,并通过长下文连续预训练的共同作用,获得了开头所示的好成绩。
参考
- 一文通透位置编码:从标准位置编码、旋转位置编码RoPE到ALiBi、LLaMA 2 Long
- Effective Long-Context Scaling of Foundation Models
- TRAIN SHORT, TEST LONG: ATTENTION WITH LINEAR BIASES ENABLES INPUT LENGTH EXTRAPOLATION
- Transformer升级之路:2、博采众长的旋转式位置编码
- ROFORMER: ENHANCED TRANSFORMER WITH ROTARY POSITION EMBEDDING
- Transformer升级之路:18、RoPE的底数设计原则
- 详解Transformer-XL
- 【NLP】浅谈 Transformer-based 模型中的位置表示
- [NLP] 相对位置编码(一) Relative Position Representatitons (RPR) - Transformer
- [NLP] 相对位置编码(二) Relative Positional Encodings - Transformer-XL
- How Self-Attention with Relative Position Representationsworks
- 让研究人员绞尽脑汁的Transformer位置编码
- POSITION INFORMATION IN TRANSFORMERS: AN OVERVIEW
- Self-Attention with Relative Position Representations
- The Large Language Model Playbook
- RoPE与多头注意力: 从零开始实现llama3系列2
- Attention Is All You Need
- DeBERTa: Decoding-enhanced BERT with Disentangled Attention
- Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer
- Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context