7.4 RoPE 与长度外推:旋转位置编码、NTK 与 YaRN
1.从 3.8 那个旋转矩阵说起
先带你回看一个细节。3.8 节讲 Transformer 的正弦位置编码时,我推过这么一步:对任意偏移 ,位置 的编码可以写成位置 编码的线性函数,而且那个 矩阵只依赖 、不依赖绝对位置 。把它抄下来:
你盯着这个矩阵看一眼——它就是一个旋转矩阵。也就是说,正弦编码之所以能"表达相对位置",本质是因为它对位置的变换是旋转,而旋转量只跟位置差有关。这是个很漂亮的巧合,但 3.8 那套方案用它用得不够爽,原因有两个:
第一,正弦编码是"加"在输入上的。 它把位置向量 直接加到 token 的表示 上,。可我们真正在乎的,是注意力打分时 和 的内积里有没有相对位置信息。位置信息先加到 ,再经过若干层线性变换变成 、,这中间位置信号会被一次次稀释,能不能完整活到内积那一刻,其实没有保证。
第二,它编码的是绝对位置。 相对位置只是正弦公式的一个"副产品"——靠那个旋转矩阵的性质间接得到的。既然相对位置才是注意力真正想用的,那为什么不一上来就直接把相对位置"烤"进内积里?
RoPE(Rotary Position Embedding,旋转位置编码,Su 等人 2021 年的 RoFormer 论文)干的就是这件事。它的口号一句话:别加位置了,直接旋转 和 ,让它们的内积天然只依赖相对位置。
2.目标:让内积只依赖相对位置
把目标说精确。设 是第 个位置上某个查询向量, 是第 个位置上某个键向量。我们希望找到一个对位置的变换 ,使得打分时
也就是内积只跟相对位置 有关,跟绝对位置 、 本身无关。这样模型学到的就是"差了多远"该打多少分,换个地方这套打分照样成立——这正是外推能力(换个没见过的长度还能用)的根基。
那 该长什么样?答案有点意外但事后想很自然:旋转。
3.为什么是旋转:复数视角
先看最简单的二维情形,最能看清道理。把 的两个分量拼成一个复数 。在复数里,给一个数"乘 "就是把它旋转 。我们干脆定义位置变换就是乘旋转因子:
两个二维向量的点积,等于这两个复数乘积的实部。于是
那个 只含相对位置 ,绝对位置 、 在这一步彻底抵消掉了。目标达成。
你可能会问:为什么非得是旋转,平移、缩放不行吗?因为要让"各自带上绝对位置 、 之后,内积里却只剩 ",唯一能做到的正交变换就是旋转(反射也算,但反射会打乱方向、不实用)。而且旋转保范数——它不改变 、 的长度,所以不会破坏向量的尺度,注意力分数该多大还是多大,训练稳。这两条(保相对位置 + 保范数)是 RoPE 能干净工作的数学底座。
4.推广到高维:分块旋转
实际模型的 、 是高维向量,不是二维。怎么推广?RoPE 的做法很直接:把 个维度两两配对,每一对当成上面那个二维情形,各转各的,角度不同。
设 是偶数(每头维度数),把它分成 对 ,第 对的旋转角速度记为 。定义一个 的分块对角旋转矩阵
位置 的 旋转一下:;同理 。打分时
旋转矩阵有个好性质 (转置就是反向旋转),所以 ,代入得
又是只剩相对位置 。漂亮,干净利落。
角速度 怎么取。 RoPE 沿用了正弦编码那套频率设计:
也就是角速度随维度索引 按几何级数衰减(base 取 )。 小的维度(低维) 大、转得快、频率高; 大的维度(高维) 小、转得慢、频率低。这和 3.8 节正弦编码里"低维高频、高维低频"是同一个思路——不同维度负责不同"刻度":高频维度周期短,负责精细的近距离相对位置;低频维度周期长,负责粗略的远距离相对位置。你看,RoPE 和正弦编码本就是同源的,只是前者把"加位置"换成了"旋转 "。
还有个工程上很讨喜的点:RoPE 不改注意力公式,不增加参数,连 都不碰——只是在 、 进 softmax 之前各自乘个旋转矩阵。所以它能像一块积木一样塞进任何现成的 Transformer,几乎零成本。这也是它能迅速铺开的原因之一。
5.为什么 RoPE 成了主流
位置编码的方案不止一种,简单对比一下你就能看出 RoPE 为什么能赢:
- 绝对位置编码(3.8 的正弦、或可学习的位置向量):位置靠"加",多层之后稀释;而且本质编码的是绝对位置。外推时一过训练长度,没见过的绝对位置就直接 OOD(超出分布)。
- ALiBi(Press 等人 2021):不编码位置向量,而是直接在注意力分数上加一个随距离线性衰减的偏置——离得越远扣越多分。简单粗暴,相对位置,但它"只看距离不看内容",且外推能力一般,后来被 RoPE 这条线比下去了。
- RoPE:相对位置、烤进内积、不增参数、保范数、外推相对友好(下一节专门讲怎么外推)。
到 2026 年,几乎所有主流的 decoder-only 大模型——LLaMA 全系、Qwen、DeepSeek、GLM、Kimi、Mistral——位置编码都用 RoPE。这就是为什么值得单开一节把它讲透。
6.长度外推:训练 4k,推理 32k 怎么办
RoPE 虽然外推相对友好,但不是天生就能外推。真正的问题来了:模型训练时上下文只给到 (比如 4k),推理时却想撑到 (比如 32k、100k)。位置一超过 ,旋转角 就会出现训练时没见过的大角度,模型一下子 OOD,效果直接崩。
注意,这和 7.3 节讲的是两码事。7.3 讲的是"算力/显存撑不撑得住"( 的计算和 KV cache 的显存),是划不划得来的问题;本节讲的是"位置编码泛化泛不泛",是能不能用的问题。长上下文要真正落地,这两半都得解决——光把注意力改成稀疏、把 KV cache 量化了,位置编码外推不了,照样白搭。这就是为什么这一节要紧跟在 7.3 后面。
于是有了下面这套"长度外推"的方法。核心思想就一个:想方设法让推理时的旋转角别超出训练时见过的范围,或者让没见过的维度"见多识广"一点。
位置插值(Position Interpolation,PI)。 Chen 等人 2023 年提的,最朴素的一招。思路是:推理时把位置 整体缩放成 (),让所有位置"压"回训练见过的角度范围。比如训练 4k、想推到 32k,就令 ,相当于把 线性压成 。
代价很直接:所有频率被一视同仁地压扁,近距离的分辨率全盘下降——原来相邻两个位置在第 维差 ,现在差 ,挤在一起了,近距离的精细相对位置就模糊了。好在它只要少量长文本微调就能 work,实现又极简(改一个缩放系数),所以是工程上最常用的"快速外推"。
NTK-aware。 bloc97 在 2023 年提的,从频率轴入手,比 PI 更精细。关键观察是:RoPE 不同维度的频率不一样,它们的命运也不同。
- 高频维度( 小、 大):周期短,训练长度内早就转过好几圈了,见多识广,本来就能外推。
- 低频维度( 大、 小):周期长,训练时可能连一个完整周期都没走完,一外推就踩进没见过的角度,这才是崩的根源。
NTK 的招:调大 base( 一个更大的数),效果是把低频维度变得更慢(周期拉得更长,让它别急着踩出训练范围),而高频维度几乎不动——等于牺牲一点低频的"远距离分辨",换取外推能力,同时保住高频负责的近距离精度。和 PI 相比,NTK 更好地保留了近距离的精细建模。
YaRN。 Peng 等人 2023 年提的,是 NTK 的精修版,目前效果最好的外推方法之一。它引入一个判据叫临界波长(critical wavelength):
- 波长 (短于训练长度)的维度——训练时已经转过完整周期,保持不变;
- 波长 的维度——训练时没转完,做插值(类似 PI,但只对这些维度做)。
也就是说 YaRN 分频段、分力度处理:能外推的维度别瞎动,不能外推的维度才压。最后再配一个温度系数修正一下注意力分布的熵(外推后分数会变得过尖或过平,得校准一下)。DeepSeek 的长上下文扩展、Qwen 的长文本版本都用过 YaRN 或它的变体。
三句话区分它们,方便记:
- PI:在位置轴上整体压(所有频率一起压),简单,但近距离分辨率全降。
- NTK-aware:在频率轴上拉伸低频,保住高频的近距离精度。
- YaRN:分频段精细处理(短波不动、长波插值)+ 熵修正,效果最好。
7.和 7.3、9.2 串起来
把这一节放进大图景里:一个真正的长上下文大模型,是三件事叠起来的结果——
- 架构上算得少、算得快:稀疏注意力/NSA/混合架构(7.3)+ FlashAttention(7.3);
- 位置编码上能外推:RoPE + YaRN/NTK(本节);
- 显存上装得下:KV cache 量化、PagedAttention(9.2、8.1)。
三个一起,才是 2026 年长上下文能落地的完整答案。少了哪一块——比如架构优化到飞起,但位置编码外推不了——长上下文照样立不住。
8.练习
Q1. RoPE 为什么用"旋转"来编码位置,而不是平移或缩放?
因为唯一能让"各自带上绝对位置 、 之后,内积里却只剩相对位置 "的变换是正交变换(旋转/反射)。旋转还保范数,不改变 、 的长度,注意力分数的尺度稳定。平移和缩放都不满足"在内积里抵消成相对位置"这一条。
Q2. 位置插值(PI)和 NTK-aware 的核心区别是什么?各自牺牲了什么?
PI 在位置轴上整体缩放,对所有频率一视同仁地压,近距离分辨率全盘下降;NTK 在频率轴上只拉伸低频维度(负责外推的),高频(负责近距离精细)几乎不动,所以近距离精度保得更好。PI 简单但牺牲近距离分辨率,NTK 更精细、实现略复杂。
Q3.(大厂面试题) 训练长度 4k,想让模型支持 32k 上下文,你会怎么做?为什么不能光靠"把窗口开到 32k 重新训练"?
光把窗口开到 32k 重训成本太高:注意力 、长文本数据也未必够。工程做法是三件事配合:架构上用稀疏注意力/混合架构省算力(7.3),KV cache 量化省显存(9.2),位置编码上用 RoPE + YaRN/NTK 把外推做到 32k(本节),再加少量长文本继续预训练微调。三个维度一起上才经济可行——光解决架构、位置编码外推不了,照样立不住。
9.小结
位置编码是长上下文"另一半"硬骨头。RoPE 把相对位置烤进 的内积——简洁、不增参数、保范数、外推友好,成了 2026 年主流 LLM 的标配;而长度外推三件套(PI/NTK/YaRN)让它能从训练长度延展到更长的推理长度。到这里,第七卷的前沿架构和位置编码就都备齐了。下一篇我们退一步,用一张选型决策树把这些架构串起来,告诉你什么场景该选什么。
下一章见。