设计位置编码
Gall 定律
一个有效的复杂系统通常是从一个有效的简单系统演化而来的
—— John Gall
本文将带你一步步探究 Transformer 模型中先进的位置编码技术。我们将通过迭代改进编码位置的方法,最终得出 旋转位置编码 (Rotary Postional Encoding, RoPE),这也是最新发布的
问题陈述
你可以通过词语与其他词语的关系来理解一个词语的意义
—— John Rupert Firth
在所有问题中,首先要做的是理解 我们到底在解决什么问题。Transformer 中的自注意力机制用于理解序列中词元之间的关系。自注意力是一种 集合 操作,这意味着它是 排列等变的。如果我们不通过位置编码来丰富自注意力,许多重要的关系将 无法被确定。
下面通过一个例子更好的说明此问题。
引导示例
以下面这句话为例,单词的位置不同:
显然,“dog” 在两个位置上指代的是两个不同的实体。让我们看看如果我们首先对它们进行词元化,使用 Llama 3.2 1B 模型获得词元嵌入,并将它们传递给
import torch
import torch.nn as nn
from transformers import AutoTokenizer, AutoModel
model_id = "meta-llama/Llama-3.2-1B"
tok = AutoTokenizer.from_pretrained(model_id)
model = AutoModel.from_pretrained(model_id)
text = "The dog chased another dog"
tokens = tok(text, return_tensors="pt")["input_ids"]
embeddings = model.embed_tokens(tokens)
hdim = embeddings.shape[-1]
W_q = nn.Linear(hdim, hdim, bias=False)
W_k = nn.Linear(hdim, hdim, bias=False)
W_v = nn.Linear(hdim, hdim, bias=False)
mha = nn.MultiheadAttention(embed_dim=hdim, num_heads=4, batch_first=True)
with torch.no_grad():
for param in mha.parameters():
nn.init.normal_(param, std=0.1) # Initialize weights to be non-negligible
output, _ = mha(W_q(embeddings), W_k(embeddings), W_v(embeddings))
dog1_out = output[0, 2]
dog2_out = output[0, 5]
print(f"Dog output identical?: {torch.allclose(dog1_out, dog2_out, atol=1e-6)}") #True
如我们所见,如果没有任何位置编码,那么经过多头自注意力操作后, 同一个词元在不同位置的输出是相同的,尽管这些词元代表的是不同的实体。接下来,我们将开始设计一种增强自注意力位置编码的方法,使其能够根据位置来区分单词之间的关系。
理想的位置编码方案应该如何表现?
理想属性
让我们尝试定义一些理想的属性,使优化过程尽可能简单。
属性 1 - 每个位置的唯一编码 (跨序列)
每个位置都需要一个唯一的编码,无论序列长度如何,该编码保持一致 - 位置 5 的词元应该具有相同的编码,无论当前序列的长度是 10 还是 10,000。
属性 2 - 两个编码位置之间的线性关系
位置之间的关系应该是数学上简单的。如果我们知道位置 的编码,那么计算位置 的编码应该很简单,使模型更容易学习位置模式。
如果你考虑我们在数轴上如何表示数字,很容易理解 5 离 3 有 2 步之遥,或者 10 离 15 有 5 步之遥。相同的直观关系应该存在于我们的编码中。
属性 3 - 泛化到比训练中遇到的序列更长的序列
为了增加模型在现实世界的实用性,它们应该能够泛化到训练分布之外。因此,我们的编码方案需要足够灵活,以适应非预期的输入长度,而不会违反任何其他理想属性。
属性 4 - 由模型可以学习的确定性过程生成
如果我们的位置编码可以从确定性过程中得出,那将是理想的。这将使模型更有效地学习我们编码方案背后的机制。
属性 5 - 可扩展到多个维度
随着多模态模型的普及,我们的位置编码方案能够自然地从 扩展到 至关重要。这将使模型能够处理图像、脑部扫描等二维和四维数据。
现在我们知道了理想的属性 (以下称为 ),让我们开始设计和迭代我们的编码方案。
整数位置编码
第一个可能的方案是简单地将词元的位置整数值添加到每个词元嵌入的分量中,值的范围从 ,其中 是当前序列的长度。
在上面的动画中,我们利用索引值为 词元创建了位置编码向量并将其添加到词元嵌入中。这里的嵌入值是 Llama 3.2 1B 中的真实值的一个子集。我们可以观察到它们集中在 0 附近。这是希望避免训练过程中的
很明显,我们当前的简单方法会带来问题。位置值的大小远大于输入的实际值。这意味着信噪比非常低,模型很难将语义信息与位置编码区分开。
有了这个新的认识,一个自然的后续步骤是通过 来规范化位置值。这样将值限制在 0 到 1 之间,但引入了另一个问题。如果我们选择 为当前序列的长度,那么位置值在不同长度的序列中会完全不同,从而违反了 。
是否有更好的方法确保我们的数字在 0 到 1 之间?如果我们仔细思考一下,可能会想到从十进制转到二进制数。
二进制位置编码
与其将 (可能已经规范化的) 整数位置添加到每个词元的嵌入分量中,我们不如将位置转换成二进制表示,并将其 拉伸 以匹配我们的嵌入维度,如下所示。
我们已经将感兴趣的位置信息 (252) 转换为其二进制表示 (11111100),并将每一位加到词元嵌入的相应分量中。最低有效位 (LSB) 将在每个后续词元中在 0 和 1 之间循环,而最高有效位 (MSB) 将在每 个词元中循环,其中 是位数。你可以在下面的动画中看到不同索引的二进制位置编码向量 。
我们解决了值域的问题,并获得了在不同序列长度下都一致的唯一编码。如果我们绘制一个低维的嵌入表示,并观察对不同值加入二进制位置向量后的变化,会发生什么呢?
我们可以看到,结果非常“跳跃”(这符合二进制离散性的预期)。优化过程更喜欢平滑、连续和可预测的变化。我们是否知道哪些函数的具有与此类似的值域,同时也是平滑和连续的?
稍作思考就会发现, 和 恰好符合这个需求!
正弦位置编码
上面的动画展示了位置嵌入的可视化,其中每个分量交替来自 和 ,并逐步增加其波长。如果将其与前一个动画对比,你会注意到惊人的相似性!
我们现在得到了 正弦嵌入,其最初在
其中, 是词元的位置索引, 是位置编码向量的分量索引, 是模型的维度, 是 基波长 (以下简称为 ),它根据分量索引被拉伸或压缩。你可以代入一些实际的值,直观地感受这种几何级数的变化。
乍看之下,这些公式中有些部分可能会让人困惑。例如,作者为什么选择 ?为什么我们要对偶数和奇数位置分别使用 和 ?
选择 作为基准波长似乎是通过实验确定的 。解读同时使用 和 的意义较为复杂,但对于我们逐步理解问题的方法却至关重要。关键在于,我们希望两个位置编码 之间具有线性关系。要理解使用 和 如何联合产生这种线性关系,我们需要深入了解一些三角学知识。
假设一个正弦和余弦组成的序列对,每个序列对对应一个频率 。我们的目标是找到一个线性变换矩阵 ,该矩阵可以将这些正弦函数按照固定偏移量 进行平移:
这些频率 遵循随维度索引 减小的几何级数,其定义为:
为了找到这个变换矩阵,我们可以将其表示为一个通用的 2×2 矩阵,其系数为未知数 、 、 和 :
通过对右侧应用三角函数的加法公式,我们可以将其展开为:
通过匹配系数,我们可以得到一组方程:
通过比较 和 的系数,我们可以解出未知系数:
最终得到的变换矩阵 为:
如果你曾从事过游戏编程,可能会觉得这个结果似曾相识。没错,这就是
因此,
-
Noam Shazeer https://en.wikipedia.org/wiki/Noam_Shazeer -
Attention is all you need https://arxiv.org/abs/1706.03762
绝对位置编码 vs 相对位置编码
认识到旋转的重要性后,让我们回到引导示例,并尝试为下一次迭代探索一些灵感。
上图展示了词元的绝对位置以及从 到其他词元的相对位置。通过正弦位置编码,我们生成了一个表示绝对位置的独立向量,并利用一些三角技巧将相对位置编码了进来。
当我们试图理解这些句子时, this 单词是这篇博客中第 2157 个词的重要性有多大?或者我们更关心它与周围单词的关系?单词的绝对位置对于其意义来说很少重要——真正重要的是单词之间的相互关系。
在上下文中理解位置编码
从现在开始,我们需要将位置编码放在 自注意力机制的上下文中 中分析。再强调一次,自注意力机制让模型能够评估输入序列中不同元素的重要性,并动态调整它们对输出的影响。
在之前的所有迭代中,我们生成了一个独立的位置信息向量,并在 、 和 投影之前将其 加到 词元嵌入上。这样做实际上是将位置信息与语义信息混合在一起,对嵌入向量的范数进行了修改。为了避免污染语义信息,我们应该尝试使用乘法进行编码。
用词典的类比来说,当我们查找一个单词 (query) 在词典 (keys) 中的含义时,邻近的单词应该比远处的单词有更大的影响。这种影响是通过 的点积来决定的,因此位置编码应该集中在这里!
点积的几何解释为我们提供了一个极好的灵感: 我们可以通过改变两个向量之间的角度来调整点积的结果。此外,通过旋转向量,我们不会改变向量的范数,从而不会影响词元的语义信息。
现在,我们知道应该把注意力放在哪里,并从另一个视角看到了为什么旋转是一种合理的“通道”来编码位置信息——让我们把一切整合起来吧!
旋转位置编码 (RoPE)
旋转位置编码 (Rotary Positional Encoding,简称 RoPE ) 是在
-
RoFormer 论文 https://arxiv.org/pdf/2104.09864 -
Jianlin Su https://x.com/bojone1993 -
让研究人员绞尽脑汁的 Transformer 位置编码 https://kexue.fm/archives/8130 -
Transformer 升级之路:2、博采众长的旋转式位置编码 https://kexue.fm/archives/8265
如果直接跳到最终结果,可能会觉得它像是某种“魔法”。但通过将正弦位置编码放在自注意力 (尤其是点积) 的背景下思考,我们可以看出它的核心逻辑。
与正弦位置编码类似,我们将向量 或 (而非投影前的 ) 分解为二维的对/块。不同于通过将基于逐渐减小频率的正弦函数生成的向量相加来直接编码 绝对 位置,RoPE 通过 对每一对分量应用旋转矩阵 来编码 相对 位置。
令 或 为位置 处的输入向量。我们创建一个块对角矩阵,其中 是对应分量对的旋转矩阵:
与正弦位置编码类似, 的定义如下:
实际上,我们并不直接通过矩阵乘法计算 RoPE,因为使用稀疏矩阵会导致计算效率低下。取而代之,我们可以利用计算规律直接对分量对分别应用旋转操作:
就是这么简单!通过在 和 的二维块上巧妙地应用旋转操作,并从加法切换为乘法,我们可以显著提升评估性能 。
将 RoPE 扩展到 - 维
我们已经探讨了 RoPE 的 情况,到这里为止,我希望你已经对这种直观上难以理解的 Transformer 组件有了一定的认识。接下来,我们来看看如何将其扩展到更高维度的数据,例如图像。
一个直观的想法是直接使用图像的 坐标对。这看起来很合理,毕竟我们之前就是随意地将分量配对。然而,这将是一个错误! 在 情况下,我们通过对输入向量中分量对的旋转来编码相对位置 。对于 数据,我们需要独立地编码水平和垂直的相对位置 (例如 和 )。RoPE 的精妙之处在于其如何处理多维度。与其尝试在单次旋转中编码所有位置信息,不如在 同一维度内配对分量并旋转,否则我们会混淆 和 偏移信息。通过分别处理每个维度,我们保持了数据的自然结构。这一方法可以推广到任意多维数据!
位置编码的未来
RoPE 是位置编码的最终形式吗?DeepMind 的
未来可能会有一些突破,或许从信号处理中汲取灵感,例如小波或分层实现。随着模型越来越多地被量化以便于部署,我也期待在低精度计算下仍然保持鲁棒性的编码方案出现。
结论
在 Transformer 中,位置编码常被视为事后的补丁。我认为我们应当改变这种看法——自注意力机制有一个“致命弱点”,它需要被反复修补。
希望这篇博客能让你明白,即便这种方法起初看起来难以直观理解,你也可以发现最新的状态 -of-the-art 位置编码。在后续文章中,我将探讨如何实践 RoPE 的具体实现细节以优化性能。
这篇文章最初发布在
参考文献
-
Transformer Architecture: The Positional Encoding https://kazemnejad.com/blog/transformer_architecture_positional_encoding/ -
Rotary Embeddings: A Relative Revolution https://blog.eleuther.ai/rotary-embeddings/ -
How positional encoding works in transformers? https://www.youtube.com/watch?v=T3OT8kqoqjc -
Attention Is All You Need https://arxiv.org/pdf/1706.03762 -
Round and round we go! What makes Rotary Positional Encodings useful? https://arxiv.org/pdf/2410.06205 -
RoFormer: Enhanced Transformer with Rotary Position Embedding : 正弦和二进制动画来源于视频 。 : 使用 可生成 个唯一位置,理论上下文长度上限约为 63,000。 : 本文部分内容参考自这篇精彩的文章 (作者:Amirhossein Kazemnejad )。 : 相关实验数据请参见EleutherAI 的这篇文章 。https://arxiv.org/pdf/2104.09864 https://www.youtube.com/watch?v=T3OT8kqoqjc0 https://kazemnejad.com/blog/transformer_architecture_positional_encoding/ https://blog.eleuther.ai/rotary-embeddings/ https://kazemnejad.com/
原文链接:
https://hf.co/blog/designing-positional-encoding 原文作者: Christopher Fleetwood
译者: chenin-wang
本文分享自微信公众号 - Hugging Face(gh_504339124f0f)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
小米加大对 AI 大模型投入,正搭建 GPU 万卡集群
据界面新闻独家报道,小米正在积极搭建自己的GPU万卡集群,并对AI大模型进行大规模投资。 据悉,小米大模型团队成立之初便已拥有6500张GPU资源,显示出小米在AI领域的决心和实力。 尽管小米方面尚未对此消息发表评论,但知情人士透露,该计划已实施数月,雷军在其中扮演了关键领导角色,强调小米在AI硬件领域的重视。“在AI硬件这件事情上,最核心的是手机而不是眼镜,小米在这个领域不‘all in’是不可能的。” 2023年4月,小米AI实验室大模型团队正式成立,栾剑担任负责人,向AI实验室主任王斌汇报。栾剑曾在东芝(中国)研究院、微软(中国)工程院等机构担任要职,拥有丰富的AI领域经验。 小米对AI大模型的重视度提升此前已有信号。12月20日,据第一财经报道,DeepSeek开源大模型DeepSeek-V2的关键开发者之一罗福莉将加入小米,或供职于小米AI实验室,领导小米大模型团队。 相关阅读 DeepSeek 开源大模型关键开发者之一罗福莉将加入小米 小米成立AI平台部,任命张铎为AI平台负责人
- 下一篇
飞轮科技荣获中国电信星海大数据最佳合作伙伴奖!
近日,由中国电信集团数据发展中心主办的数据要素合作论坛在广州召开。大会以“数聚共生·智启未来”为主题,旨在展示数据要素应用成果,探索数据要素创新实践。与会期间,为了感谢 2024 年生态合作伙伴对中国电信数据业务发展工作的支持,会议举行了“星海大数据·最佳合作伙伴奖”颁奖仪式。飞轮科技凭借其在数据分析领域的卓越表现与深厚实力,获得这一殊荣。 作为中国电信的长期合作伙伴,飞轮科技持续致力于为中国电信提供先进的数据分析技术与解决方案支持。 在开源技术方面,飞轮科技为中国电信全国各省集团提供了 Apache Doris 这一高性能、实时分析型数据库的技术支持服务,助力其构建高效、灵活的数据处理与分析平台。在产品合作方面,飞轮科技为中国电信引入了现代化数据仓库 SelectDB,该产品基于 Apache Doris 内核构建,通过实时、统一、弹性、开放的核心能力,为企业提供高性价比、简单易用、安全稳定、低成本的实时大数据分析支持,以及更加安全、稳定的开发和使用体验。 在双方的紧密合作下,Apache Doris 和 SelectDB 已在中国电信多个项目中成功应用,并取得了显著成果。 在业务...
相关文章
文章评论
共有0条评论来说两句吧...