Transformer位置编码全解析:从绝对正弦到RoPE与ALiBi

发布时间:2026/10/19 4:39:10
Transformer位置编码全解析:从绝对正弦到RoPE与ALiBi 这个系列写到编号 002上一篇聊了 Transformer 的整体框架这次专门把位置编码这一块掰开揉碎。位置编码这个词听起来像个小配角实际上一半的序列模型训练事故都跟它有关尤其是你一旦开始把输入长度拉到训练时见过的范围之外。我最近在调一个轻量翻译模型训练数据挺干净验证集 BLEU 却一直卡在 20 上下折腾了两天才定位到问题输入序列悄悄拉长到训练时的一倍多位置编码方案却还是最朴素的绝对表。这篇文章我会从为什么需要位置编码讲起把三角函数编码的推导、相对位置编码的演进、当下主流大模型在用的 RoPE 和 ALiBi以及真实可用的长度外推手段一次讲清楚。无论你是刚开始看 Transformer 的初学者还是已经在做微调推理的工程师这期内容都能帮上忙。1. 为什么 Transformer 离不开位置编码1.1 并行注意力机制丢失的顺序信息先说结论自注意力机制天生是“不分先后”的。你把序列 [我, 爱, 你] 换成 [你, 爱, 我]如果只让模型看词向量集合它看到的其实是同一组向量。注意力层做的事是在所有 token 之间两两计算相关性权重这个计算只关心“内容和内容之间像不像”完全不关心谁先谁后。这在并行计算上是巨大优势但也带来了根本性缺陷。循环网络是按时间步一个一个走完的每一步天然携带前面的历史信息顺序是结构赋予的卷积网络虽然也是并行但卷积核有固定感受野局部窗口本身能区分相对位置。Transformer 为了彻底并行把顺序这层结构丢掉了所以必须靠额外注入的位置信息把“顺序”找回来。我在做文本匹配实验时踩过很直观的坑让模型判断“小明打了小红”和“小红打了小明”是否同义。如果不加位置编码模型几乎无法学习“谁打了谁”这种依赖语序的逻辑关系它在语义空间里看到的两个句子过于相似。加了位置编码之后同样的数据、同样的训练轮数准确率明显上升。这就是位置编码存在的第一个理由让并行模型重新获得顺序感知能力。1.2 位置编码需要满足哪些条件既然要注入位置信息自然会问什么样的注入方式才算合格我看过大量设计方案之后总结了四个核心条件。位置编码要能区分不同位置。同一个词出现在第 5 个位置和第 100 个位置编码差异不能小到让模型忽略。其次数值要有界且稳定否则会干扰词向量的梯度更新。第三点比较关键模型最好能从编码里推断出“两个 token 隔了多远”这叫相对位置可解性。最后一个条件是扩展性也就是训练长度之外的位置最好也能被合理表示。你可以把位置编码想象成给一条街道上的门牌号编号。最笨的办法是每一户挂一个独一无二的牌子牌子越多越难维护好一点的办法是让门牌号之间有规律比如隔几户增加固定的号码这样即使你走到没挂牌的街区也能按照规律猜出门牌应该是什么样子。可学习绝对位置编码就是第一种思路三角函数编码就是第二种思路。整个位置编码的发展史本质上是往“机器能说人话”的方向走而不是粗暴堆积参数。2. 经典正弦位置编码从公式到实现2.1 公式背后的逐维度频率直觉原始 Transformer 用的正弦位置编码公式如下[ PE_{(pos, 2i)} \sin\left(\frac{pos}{10000^{2i/d}}\right) ][ PE_{(pos, 2i1)} \cos\left(\frac{pos}{10000^{2i/d}}\right) ]其中 (pos) 是 token 在序列里的位置(i) 是维度下标(d) 是编码维度。单看公式有点枯燥但它内部藏着一个很优雅的设计不同维度的“频率”不一样。低维度的 (i) 比较小分母的 (10000^{2i/d}) 小频率就高位置稍微变化一点编码值就明显变化适合精细区分相邻 token高维度的 (i) 接近 (d/2)频率很低适合表达大范围的位置关系。这种多尺度频率设计本质上类似二进制编码的平滑版本。二进制里低位频繁翻转、高位缓慢变化正弦编码把这种特性连续化了所以模型可以用不同的注意力头去关注不同粒度的位置关系。我之前想过另一个问题为什么偶数维用 sin、奇数维用 cos而不是都用 sin因为只有这样才能让相对位置信息以线性变换的形式表达出来。这一点是整套编码的灵魂。2.2 相对位置信息的线性表达推导假设我们固定一个偏移量 (k)来看位置 (posk) 的编码如何由位置 (pos) 的编码推导出来。对第 (2i) 维[ \sin(w_i(pos k)) \sin(w_i \cdot pos)\cos(w_i \cdot k) \cos(w_i \cdot pos)\sin(w_i \cdot k) ]其中 (w_i 1/10000^{2i/d})。再看第 (2i1) 维[ \cos(w_i(pos k)) \cos(w_i \cdot pos)\cos(w_i \cdot k) - \sin(w_i \cdot pos)\sin(w_i \cdot k) ]把这两个式子写成矩阵形式位置 (posk) 的编码 ([ \sin, \cos ]) 恰好等于位置 (pos) 的编码乘以一个旋转矩阵[ \begin{bmatrix} \cos(w_i k) \sin(w_i k) \ -\sin(w_i k) \cos(w_i k) \end{bmatrix} ]这个矩阵只和偏移量 (k) 有关和当前位置 (pos) 无关。意思是模型任何一个线性层只要能模拟二维旋转就能从当前位置编码里“还原”出任意相对距离的信息。自注意力计算 (QK^T) 时这些旋转信息会直接参与相关性打分所以模型不只能看到绝对位置还能感知到相对位置。这就是正弦编码能以零参数方式具备相对位置表达能力的原因。2.3 一份可直接复用的 PyTorch 实现实践中我一般会把编码表预计算好forward 里直接查表相加下面这段代码足够应付大多数场景。import torch import math def get_sinusoid_encoding_table(max_len, d_model): pe torch.zeros(max_len, d_model) position torch.arange(0, max_len).unsqueeze(1).float() div_term torch.exp( torch.arange(0, d_model, 2).float() * -(math.log(10000.0) / d_model) ) pe[:, 0::2] torch.sin(position * div_term) pe[:, 1::2] torch.cos(position * div_term) return pe.unsqueeze(1) # [max_len, 1, d_model]在模型 forward 里这样用self.pe get_sinusoid_encoding_table(max_len, d_model) def forward(self, x): seq_len x.size(1) x x self.pe[:seq_len].to(x.device) return x几个实操细节。d_model必须是偶数如果模型维度是奇数最后会有一维拿不到 sin/cos我的处理方法是补零。混合精度训练下预计算表建议保持 float32不要被 AMP 强制降成 fp16否则长序列下误差会累积到可见的程度。另外正向传播里 PE 表是常量张量不参与梯度计算不用担心它被误更新。3. 从绝对到相对编码方案的演进路线3.1 可学习位置编码的极限原版正弦编码之后最流行的一类做法是把位置编码改成可学习参数。具体来说就是初始化一个位置 Embedding 表形状是 [max_len, d_model]让它在训练中和词向量一起更新。当时很多经典预训练模型都采用这种方案因为它们有海量训练数据模型完全有能力自己去学出一套合适的位置表示。可学习方案的优势是灵活性高参数可以根据数据分布自适应调整。缺点是扩展性极差一旦训练时最大长度定在 512推理时想用到 1024 就直接报错或乱给出随机初始化向量。我做过一组对比实验用 512 长度的可学习位置编码训练好的模型强行推理 1024 长度的输入效果几乎等于随机猜测。更麻烦的是训练时位置 Embedding 如果不加约束某些位置的表征可能漂移得厉害你观察 attention 图时会发现某些位置权重异常突出这种异常很难从 loss 曲线上察觉。后来一些项目尝试把 max_len 预先设得很大比如 4096用较少数据训练但高序号位置的 Embedding 因为见过太少实际还是处于半随机状态。这就像一本字典里大部分词条都被翻阅过最后面几百页却是空白查起来自然不可靠。这说明绝对位置思路的上限就在这里位置表容量越大需要的训练数据越多否则尾部就是无效参数。3.2 相对位置编码与解耦注意力相对位置编码的核心思路是模型不需要知道每个词在序列中的绝对坐标只需要知道“两个词之间隔了几个位置”。最早的相对位置方案里注意力打分同时引入内容相关项和位置相关项位置相关项基于相对距离 (i-j) 查表。有一类代表性做法更简洁直接在注意力 logits 上按距离加一个可学习偏置。偏置的构造不是每个距离一个参数而是做了分段分桶。比如近距离 0 到 3 的偏置精细到每个距离中等距离用更粗的桶最远处共享几个分段参数。这样既控制了参数量又让偏置的粒度分配符合语言规律相邻词的相对顺序非常关键远处词的精确距离则没那么重要。再进一步有方案把内容信息和位置信息彻底解耦内容到内容的注意力、内容到位置的注意力分开计算最后相加。这样做的直接好处是模型可以分别建立两套关系一个是“这个词和哪个词相关”一个是“这个词和哪个距离的槽位相关”。阅读理解这类对语序敏感的任务使用解耦注意力提升非常明显。我在一个序列标注任务里试过从绝对编码直接切到相对偏置同样预算下 F1 涨了不少。直觉上也很容易理解中文分词和命名实体识别本质依赖局部次序比如“中华人民共和国”里“中华”和“人民”的搭配关系距离信息比绝对位置重要得多。4. 现代大模型的两大主流RoPE 与 ALiBi4.1 RoPE 的旋转思想近两年开源大模型里出现频率最高的位置编码方案是 RoPE旋转位置编码。它不走“把位置向量加到 Embedding 上”的路线而是把位置信息直接注入到 Query 和 Key 的向量旋转里。想象一个二维平面上的词向量位置 (m) 对应把这个向量旋转 (m\theta) 角度。扩展到多维时RoPE 把向量的维度两两分成子空间每个子空间旋转不同的角度角度随维度按类似正弦编码的频率递减。用复数角度看位置为 (m) 的二维向量乘以 (e^{im\theta})旋转后高维向量就带上了位置标签。RoPE 最妙的地方在注意力计算。经过旋转的 Query 和 Key 做点积时结果只和两者旋转角的差值有关也就是说点积天然包含 (m-n) 的相对距离信息。模型不需要额外学习位置表也不需要在注意力里加偏置旋转本身就完成了相对位置的表达。这一点让它既有绝对位置编码的实现简洁性又有相对位置编码的外推优势。4.2 RoPE 的实现细节与常见坑下面是一份标准的 RoPE 预计算和旋转代码我直接用它处理 Q 和 K。import torch def precompute_rope_cache(seq_len, dim, base10000.0): inv_freq 1.0 / (base ** (torch.arange(0, dim, 2).float() / dim)) t torch.arange(seq_len).float() freqs torch.einsum(i,j-ij, t, inv_freq) cos torch.cos(freqs) sin torch.sin(freqs) return cos, sin # 都是 [seq_len, dim//2] def rotate_half(x): x1 x[..., : x.shape[-1] // 2] x2 x[..., x.shape[-1] // 2:] return torch.cat((-x2, x1), dim-1) def apply_rope(q, k, cos, sin): cos cos.unsqueeze(0).unsqueeze(0) sin sin.unsqueeze(0).unsqueeze(0) q_rot (q * cos) (rotate_half(q) * sin) k_rot (k * cos) (rotate_half(k) * sin) return q_rot, k_rot注意这里 Q 和 K 必须同时旋转V 不能碰。V 是携带内容信息的向量如果也旋转等于改变了内容表征会破坏注意力的寻址能力。我见过有人图省事把整组 QKV 一起旋转结果是训练不收敛排查了很久才发现问题出在这。另一个很隐蔽的坑是旋转矩阵作用于 Q、K 时如果设备上用的是 fp16长序列下小角度旋转的浮点误差会被放大。我的经验是 cos/sin 表始终用 float32 预计算只在缓存到 GPU 时转为当前精度。还有推理时序列长度一旦超过训练时缓存长度必须重新生成更长序列的 cos/sin 表否则下标越界或者直接取空。4.3 ALiBi 的极简形态与对比ALiBi带线性偏置的注意力走的是另一条完全不同的路它不增加任何位置参数不修改 Embedding只在注意力分数上加一个与距离成正比的负偏置。[ score(Q, K)_i Q_i K_j - m \cdot |i - j| ]距离越远惩罚越大。每个注意力头用不同的斜率 (m)通常取几何序列 (2^{-8 \cdot n/h})。这样不同的头有不同的“视野”头 1 视野窄只看近邻后面的头视野逐渐变宽。整个方案简单到了极致训练时可以完全不管输入序列长度因为偏置形式天然支持任意距离。ALiBi 最大的优势是免训练外推模型用短序列训练直接拿到长序列上推理效果衰减比罗氏可学习编码平滑得多。不过它也有天然短板远距离 token 的注意力被明确压低了所以建模超长距离依赖的能力受限。如果你做的任务强依赖几百步以上的远距离关联ALiBi 不一定是首选。四个主流方案放一起看会更清楚方案是否增加参数长度外推能力是否改动注意力典型适用场景绝对正弦编码否中可数学外推但效果一般否原版 Transformer、中短序列可学习绝对表是参数量随长度涨差否定长任务、经典预训练相对偏置少量分桶较好是对位置次序敏感的任务RoPE否较好配合插值效果优秀是当前大模型主流选择ALiBi否强免微调可外推是训练短、推理长的场景5. 长度外推真正能在线上用起来的手段5.1 外推问题的本质长度外推指的是训练时只见过 2048 长度的序列推理时直接给它 8192甚至 16384 长度的输入。很多人觉得位置编码是固定函数外推应该没问题但实测下来模型照样崩。根本原因在于训练时的位置分布和推理时的位置分布完全不同不是编码算不出来而是模型没有学会在长位置区间上做正确的注意力分配。拿 RoPE 举例它虽然是相对位置编码旋转角度本身不受训练长度限制但训练数据里所有相对距离都被截断在 2048 以内模型没见过更大的相对距离注意力打分在面对未知距离时会出现失真。更麻烦的是RoPE 的高频子空间对位置变化极其敏感位置一远高频部分快速旋转模型被困在训练分布之外的模式里。所以外推难是一个系统性现象不是换一种编码就能解决的。5.2 PI、NTK 与 YaRN 插值实战解决外推工程上最常用的手段是位置插值。Position Interpolation 的思路很好理解把 8192 的新位置索引统一除以缩放因子 4映射回模型熟悉的 2048 区间。比如新位置 8000 除以 4 变成 2000模型一看这个数值在训练范围内就不慌了。PI 方案稳定但均匀压缩位置会让高频分量的分辨率下降相邻位置的区分度变差需要微调千步左右才能恢复。NTK-aware 插值是另一种思路不压缩位置索引而是修改旋转编码里的 base 参数。把原始的 10000 换成一个更大的值低频分量的旋转速度变慢高频分量尽量保持不变。这样在推理时可以直接把 4096 的模型硬顶到 16K不需要微调也能跑但质量比微调后的模型差不少。YaRN 在 NTK 基础上进一步改进引入了注意力温度调整和局部窗口窗函数。它既修正了高频失配又抑制了远端注意力峰值是目前免微调外推方案里效果最好的之一。我有一次实际扩长度的经历某个开源 2B 模型原本训练长度只有 4096业务需要支持 16384。我先试 NTK-aware 零微调硬顶结果短文本任务没问题长文本生成出现大量重复片段。后来改用 PI 加上 5000 步小学习率微调效果就稳了。这里给一个建议如果能做微调就老老实实用 PI 或 YaRN 微调如果必须零微调上优先 YaRN 而不是裸 NTK。插值后学习率不要超过原训练底数的四分之一否则位置信息刚被压缩模型很容易把已有能力冲掉。6. 常见问题与排查速查6.1 训练正常推理崩的定位方法这类问题最常见的一句话是“我训练 Loss 降得挺正常怎么一上线就崩”。如果模型在短验证集上正常长序列上表现离谱位置编码就是第一个怀疑对象。我的排查步骤很简单。第一步拿到一段长输入打印每一层的注意力权重看是否存在局部坍缩也就是所有注意力集中到同一个 token。第二步换上训练时的短序列如果短序列正常而长序列崩基本可以判定长度外推失配。第三步直接冻结所有参数只训练位置编码相关部分如果 Loss 恢复很快更说明问题出在位置表示上。还有一个容易忽视的场景是索引越界。可学习位置表在序列长度超过 max_len 时通常会直接崩溃但 RoPE 缓存如果忘记扩展异步模式下可能不会立刻报错而是拿到错位数据表现为结果随机。这种问题最坑定位时一定要先打印实际用到的缓存长度。6.2 选型与工程经验给个简单的选择流程。训练序列长度固定且不超过 512 的中小型任务用可学习绝对表省心省力。需要做通用的文本生成模型准备大规模长序列训练直接上 RoPE。特别吃长序列免微调外推的场景ALiBi 值得优先考虑。任务本身高度依赖词之间的相对次序比如序列标注、信息抽取相对偏置方案往往最稳。最后还有一些零散但实用的经验。RoPE cache 计算时建议一次性算到模型可能遇到的最大长度多耗一点显存换运行时安全。混合精度下注意力分数建议在 fp32 下做累加避免长序列下点积误差堆积。观察训练曲线时如果 Loss 曲线平滑下降但验证集指标原地踏步可以检查位置编码相关参数的梯度范数如果远大于词向量梯度说明位置信息正在喧宾夺主通常需要降低位置编码的初始幅度。我自己每次新项目开工前都会跑一个几十步的最小验证拿两对词序相反的句子直接看模型注意力图能不能区分开。这个测试 5 分钟出结果但已经帮我避开了至少三次训练白费的惨案。位置编码这个看似不起眼的模块真的值得每次训练前都给它几十秒的注意力。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询