返回博客

RoPE 改频率后,旧 KV cache 还能用吗?

从同频旋转推导相对位置与混合相位误差,沿固定版本实现检查缓存顺序,用两层算例区分局部重相位、历史重建和长上下文能力。

长上下文配置经常写成一个倍率,推理系统却把历史 key 当成不可变对象。若倍率或频率在 decode 中变化,下一枚 token 面对的究竟是哪一种模型?本文沿旋转恒等式、缓存存储顺序与深层依赖逐步回答,并提供可执行的局部修复与整网反例。

先定义你要复现的计算

把上下文上限调大,系统依然能生成;这并不能证明它复现了你想要的长上下文模型。先选一个最小基线:权重固定、关闭 dropout、因果掩码固定,在整段提示词上采用同一张预先确定的 RoPE 频率表,然后一次完整 prefill。目标是让分块 prefill 和逐 token decode,在相同 token、位置与配置下得到与这条路径一致的结果,容许预先声明的浮点误差。

另一个合法目标,是明确规定频率随在线长度改变的推理过程。它是一条有历史的执行轨迹,未必等同于“用最终频率重算整段”。本文讨论两者的接口,不把所有动态 RoPE 变体判为错误。尤其不能先在完整序列上算一次新频率,再把它当作逐步改频率的唯一正确答案,而没有说明目标。

本篇从 RoFormer 的旋转结构和 Position Interpolation 的缩放出发。RoFormer 首发于 2021 年 4 月 20 日,本文读的是 2023 年 11 月 8 日提交的 arXiv v5;PI 首发于 2023 年 6 月 27 日,读的是次日提交的 v2。这是基础机制分析,不是把旧论文写成新发布。实现例子核对到 Hugging Face Transformers 的固定提交 536ecc007387a50e77603bb5d92100e9b07514cc;没有运行真实 LLM、GPU 或服务性能测试。

相对位置来自同一组旋转

设一个注意力头的维数为 \(d\),其中偶数维 \(r\le d\) 参与旋转,其余通道保持不变。用列向量,\(m\) 是 query 的位置,\(n\) 是 key 的位置。\(q_m=W_Qh_m\)、\(k_n=W_Kh_n\)、\(v_n=W_Vh_n\) 是未旋转的投影。频率向量为 \(\omega\),旋转后的向量为 \(\widehat q_m=R_\omega(m)q_m\)、\(\widehat k_n=R_\omega(n)k_n\)。原始常见频率约定是 \(\omega_i=b^{-2i/r}\),\(b>1\),\(i=0,\ldots,r/2-1\)。具体模型的旋转维数和基数应从配置核对,不能直接套用示例。

\[R(\phi)=\begin{bmatrix}\cos\phi&-\sin\phi\\\sin\phi&\cos\phi\end{bmatrix},\qquad R_\omega(p)=\operatorname{diag}\bigl(R(p\omega_0),\ldots,R(p\omega_{r/2-1}),I_{d-r}\bigr)\]

每个二维块是正交矩阵,因此不改变该块范数。本文把坐标两两相邻排列;有些实现把前半维与后半维配对。二者可通过同一个坐标置换对应,但若只换布局而不同时换投影、频率广播和缓存格式,内积不会自动保持。

\[\ell_{mn}=\frac{\widehat q_m^{\top}\widehat k_n}{\sqrt d}+M_{mn},\qquad M_{mn}=\begin{cases}0,&n\le m\text{ and valid},\\-\infty,&\text{otherwise}.\end{cases}\]

这里 \(M\) 同时排除未来 token、padding 和不属于同一序列的 token;softmax 沿允许的 key 维归一化,再加权求和 \(v_n\)。旋转维数为 \(r\) 不意味着温度应该改为 \(\sqrt r\):最小基线仍按完整头维数 \(d\) 缩放。若一个 query 行没有任何有效 key,须按实际系统约定处理,不能对全负无穷行直接归一化。

固定频率:缓存为什么成立

正交性与同频旋转的可加性给出下面的恒等式。注意 \(n-m\) 的符号来自本文列向量约定;如果换一种复数内积写法,符号可能看起来不同,不能混用。

\[\bigl(R_\omega(m)q_m\bigr)^{\top}R_\omega(n)k_n=q_m^{\top}R_\omega(n-m)k_n\]

这说明:在固定未旋转 \(q_m,k_n\) 时,显式位置项只依赖相对位置。它不表示语义内容只依赖距离,也不证明任何长度的检索都有效。相邻 token 可以有不同内容投影,正弦项也不保证每个固定内容对的分数随距离单调衰减。

\[R_\omega(m+c)^{\top}R_\omega(n+c)=R_\omega(n-m)\]

若所有位置同时平移 \(c\),并在同一频率下同时调整 query 与 key,局部点积不变。这不允许只把新 query 的位置归零,却保留旧 key 的相位;也不允许随意删除历史 token 后宣称整网不变。整网平移等价还要求位置只通过这种 RoPE 进入、掩码与内容相同、没有依赖绝对位置的其他模块或长度触发参数。

在固定协议的因果模型中,历史 token 的隐藏状态不依赖未来 token。于是缓存历史层的 key/value,可以让当前 token 复用它们。分块大小不应改变目标数学计算,但浮点舍入、不同内核归约次序和量化可能使逐位相同不成立。

PI 的基础变换可以写成:

\[p\mapsto p/s,\qquad \omega_i^{\prime}=\omega_i/s,\qquad s=L^{\prime}/L>1\]

把位置除以 \(s\),等价于把对应频率除以 \(s\)。相邻位置的相位间隔因此缩小,不是免费增加记忆。PI 论文同时研究了新长度上的适配微调;这个坐标变换自身既不保证长距离任务质量,也没有证明跨倍率复用旧缓存。最稳妥的接口是:本次请求开始前确定并冻结这张频率表,再进行 prefill。

新 query 遇到旧 key:相位多了什么

先固定未旋转投影,隔离旋转接口。假设历史 key 以旧频率缓存,当前 query 使用新频率,且注意力幅度系数为 1。对一个允许的 key,混合路径的分数与块内相位如下;掩码在两条比较路径中相同,因而省略。

\[\ell_{mn}^{\mathrm{mix}}=\frac{q_m^{\top}R_{\omega^{\mathrm{new}}}(m)^{\top}R_{\omega^{\mathrm{old}}}(n)k_n}{\sqrt d},\qquad \phi_i^{\mathrm{mix}}=n\omega_i^{\mathrm{old}}-m\omega_i^{\mathrm{new}}\]

目标固定新频率的相位应为 \((n-m)\omega_i^{\mathrm{new}}\)。两者之差是 \(n(\omega_i^{\mathrm{old}}-\omega_i^{\mathrm{new}})\)。多出来的项与历史 key 的绝对位置有关,所以“本来是相对位置”不能消去它。\(n=0\) 的键不受这个旋转差影响,某些内容对也恰好不改变点积;这不是每一对 token 都必然出错的论断。

一个原创二维反例足够:令 \(q_m=k_n=(1,0)^{\top}\),\(m=2\)、\(n=1\),旧频率为 \(\pi/2\),新频率为 \(\pi/4\)。混合分数是 \(1/\sqrt2\approx0.70711\),而统一新频率分数是 \(1/2\)。这是执行过的合成算术,不是模型注意力的实测分布。

\[\left|\ell_{mn}^{\mathrm{mix}}-\ell_{mn}^{\mathrm{new}}\right|\le\frac{\lVert q_m\rVert_2\lVert k_n\rVert_2}{\sqrt d}\max_i 2\left|\sin\frac{n\Delta\omega_i}{2}\right|,\qquad \Delta\omega_i=\omega_i^{\mathrm{new}}-\omega_i^{\mathrm{old}}\]

证明可直接落到实现:二维旋转差的谱范数是 \(2|\sin(n\Delta\omega_i/2)|\),块对角矩阵取各块最大值,再用 Cauchy–Schwarz。这个因子还不超过 \(\min\{2,|n|\lVert\Delta\omega\rVert_{\infty}\}\)。小频率变化可以积累为非小相位变化,但因子有界且周期振荡,不是位置越大误差必然越大。该界只控制固定投影的一个 logit;softmax、值向量和深层反馈尚未计入,不能换算成困惑度、正确率或服务质量。

重旋转修复的是坐标,不是整段历史

若历史 key 的未旋转投影确实不变,可以先逆旧旋转,再施加新旋转。两者同布局、同旋转维数时,每个块也等价于一次角度差旋转。

\[\widehat k_n^{\mathrm{rephase}}=R_{\omega^{\mathrm{new}}}(n)R_{\omega^{\mathrm{old}}}(n)^{\top}\widehat k_n^{\mathrm{old}}=R_{\omega^{\mathrm{new}}}(n)k_n\]

它是精确算术中的局部恒等式,不能省略“固定 \(k_n\)”这个前提。如果频率策略还对 cos/sin 乘幅度系数,就必须同时处理尺度。为简化幅度式,这里假设完整头都参与旋转,即 \(r=d\),且 \(a_{\mathrm{old}}\ne0\)。下面是相应的键修复;当前 query 也须使用目标新尺度。部分旋转时,应只对旋转子向量应用此式,其余通道按模型约定保留。

\[\widehat k_n^{\mathrm{old}}=a_{\mathrm{old}}R_{\omega^{\mathrm{old}}}(n)k_n,\qquad \widehat k_n^{\mathrm{rephase}}=\frac{a_{\mathrm{new}}}{a_{\mathrm{old}}}R_{\omega^{\mathrm{new}}}(n)R_{\omega^{\mathrm{old}}}(n)^{\top}\widehat k_n^{\mathrm{old}}\]

仅做旋转却不改尺度,会保留不同的点积温度。量化缓存还要考虑反量化、再次量化与累积误差;取逆不意味着能恢复已经丢失的低位精度。

\[k_n^{(\ell)}=W_K^{(\ell)}h_n^{(\ell-1)},\qquad v_n^{(\ell)}=W_V^{(\ell)}h_n^{(\ell-1)},\qquad h_n^{(\ell-1),\mathrm{old}}\not\equiv h_n^{(\ell-1),\mathrm{new}}\]

一般的深层模型里,之前层的注意力已经用旧频率计算过,所以历史隐藏状态可能改变。此时重旋转只得到“新坐标下的旧内容”,并不得到“新频率模型重新计算出的内容”。在这里采用的值不直接施加 RoPE 的路径中,第一层的值可保持相同;深层的值仍会因隐藏状态变化而不同。没有对值施加旋转,并不意味着值对频率配置无依赖。

本篇附带一个两层、单头、二维、恒等 Q/K/V 投影、残差连接且没有 MLP 或归一化的教学网络。三个人工输入向量依次为 \((1,0.2)\)、\((0.3,1)\)、\((-0.8,0.4)\),旧/新频率分别为 \(0.9\)、\(0.2\)。先缓存前两个位置,再在新频率下处理第三个位置。重旋转可使第一层当前输出与全新频率计算相同;重旋转两层旧键、保留旧值后,第二层当前输出与重新 prefill 的欧氏距离约为 \(0.04081\)。历史第二个位置的一层隐藏状态距离约为 \(0.11620\)。这些数值来自实际执行的教学代码,既不是训练模型结果,也不衡量语言质量。

下载原创标准库算术与两层反例代码:Python 3.9 以上,无权重、数据集或网络依赖。实际通过 709 项断言,包括同频内积、共同原点平移、局部重相位、误差界、幅度修复、固定协议前缀一致性和深层反例。随机部分使用固定种子与人工向量;容差针对双精度教学计算,不是实际模型验收阈值。

原创机制示意:冻结新频率并重算整段的目标,与旧频率构建历史缓存后改频率的路径对照;重相位仅修旧键坐标,深层隐藏状态和值仍可能不同。
图 1|缓存一致性的两层条件:旋转坐标一致与历史内容一致。原创分析示意,非实验数据;图中的路径是比较协议,不是所有实现的默认行为。

沿源码检查:缓存里到底存什么

以固定提交的 Llama 路径为例,未旋转 query/key/value 的头张量常写作 \([B,H_q,T,d]\)、\([B,H_{kv},T,d]\)、\([B,H_{kv},T,d]\)。\(B\) 是批大小,\(T\) 是当前输入块长度,\(H_q,H_{kv}\) 分别是 query 与 key/value 头数。分组 query attention 的复用或展开应由实际注意力后端处理,不能把缓存先人为复制到所有 query 头再计算存储收益。

该源码在 decoder 层循环前生成共享的 cos/sin,再传给各层。Attention 层投影并整理头维后,使用传入的 cos/sin 对 query/key 应用 RoPE;随后调用 past_key_values.update;把当前 query 与包含历史的 key/value 交给注意力后端。普通 DynamicLayer.update 沿序列轴拼接传入的 key/value,所以这条路径的旧 key 已带旋转。这里的 DynamicCache 只是缓存容量会增长,和动态改变 RoPE 频率不是同一个概念。

该提交的 dynamic_rope_update 在相应 dynamic 配置下根据本次 max(position_ids)+1 及既有阈值状态更新 inv_freq,也更新相关尺度;短长度还可能触发恢复原始频率。这个更新器本身没有遍历并重算历史 KV,普通拼接缓存也没有做这件事。只有在选定路径实际改变频率、旧旋转键被保留且没有其他补偿时,才进入前面的混合相位分析。不同模型、专用 kernel、缓存类或服务协议需要分别核验;这不是“所有 Transformers 缓存都错误”的结论。

固定频率的实现验收可以按四步走。第一,记录实际位置与掩码,不能用缓存槽下标代替 position_ids:padding、packed sequence 和滑动窗口都可能使二者不同。第二,在请求开始时生成并冻结实际频率及尺度,所有块和后续 token 使用同一协议。第三,缓存每层历史 key/value,并按因果掩码读取。第四,用整段冻结频率的完整前向作为数值对照。遇到配置变更时,优先使旧前缀缓存失效并重新 prefill;“保存未旋转 key”只解决最后的旋转接口,不会自动重建其上游隐藏状态。

计算账本:一次旋转与一次重建差在哪里

令 \(N\) 是缓存的历史 token 数,\(L_{\mathrm{layers}}\) 是层数,\(s_{\mathrm{elem}}\) 是每个 K/V 元素的字节数。下面的缓存字节式假设 K 和 V 都有头维 \(d\)、同一存储精度,忽略量化元数据、分页、对齐和共享前缀;这里只作通常的稠密 KV 基线。

\[\mathrm{KV\ bytes}=2L_{\mathrm{layers}}B H_{kv}N d\,s_{\mathrm{elem}},\qquad \mathrm{rephase\ work}=O(L_{\mathrm{layers}}B H_{kv}Nr)\]

重旋转通常要读写各层旧键、读取位置及频率并做成对运算;上式只计旋转通道工作,不包括反量化、重新分配、同步或上游重建。如果另外长期保留未旋转 key,会增加额外存储,不能同时宣称缓存字节不变。幅度也变时还需逐元素缩放。

重新 prefill 整个历史不仅算 RoPE,还需所有层投影、注意力、MLP 等。在标准稠密因果注意力中,prefill 的注意力算术量级随 \(N^2\) 增长;当前单个 token 的 decode 注意力与历史 key/value 的读取消耗随 \(N\) 增长。这些是不同计算阶段。FlashAttention 一类分块方法可减少中间矩阵与显存往返,但不能把稠密注意力的所有两两点积数量直接变成线性。

因此“键重旋转便宜”并不证明“它等价于重建”,而“重新 prefill 昂贵”也不使不一致的缓存自动有效。实际时间取决于后端、精度、批大小、历史长度、内存带宽和调度。本文只给账本和教学算例,没有吞吐、显存峰值或加速倍数的实测。把频率策略冻结在请求开始前,有时是减少协议切换成本的工程选择;是否牺牲短上下文质量仍需独立测量。

可检验对照:先查协议,再谈长上下文质量

下面是建议的真实模型实验,本文没有执行。第一组比较同一冻结协议的完整 prefill、至少两种块大小的 prefill 与逐 token 缓存 decode。固定权重/adapter、token、掩码、位置、精度及注意力后端;逐层比较当前隐藏状态、旋转后的 key、未直接旋转的 value 和最终 logits。最大绝对差与相对差都要记录,并依据参考精度预先设容差,不要用“最终文本一样”代替数值验收。

第二组刻意跨越动态频率阈值。保留实际频率和尺度日志,比较:不处理旧缓存、只重旋转旧键、以及新协议下完整重建。把分块边界安排在阈值前后,再换另一种分块方式。先确认目标是冻结新频率还是声明过的在线变更轨迹;若是后者,每条路径须遵循相同更新时机,不能拿不同调度的结果混为同一模型。检查频率并非只在长长度更新、短请求恢复原始频率的情况;不要让上一条请求的状态悄悄进入下一条。

第三组验证内容能力。缓存协议一致之后,再比较原长度和扩展长度上的语言建模、位置分层检索、多证据组合及干扰文本。模型适配方式、训练 token、输入/输出 token 预算、上下文中的证据位置与可读取 token 数保持可比较。检索一个密钥不等于可靠整合整段文档;能分配更长 KV 不等于模型学会更长上下文。

层次实际验收不能推出
二维旋转固定投影下的点积、重相位与误差界真实模型质量或服务加速
多层缓存协议相同目标与更新时机下逐层状态及 logits仅靠重旋转修复全部历史内容
长上下文能力公平预算、位置分层任务、困难反例配置上限或缓存容量就是可靠上下文

缓存身份至少要覆盖:模型与 adapter 版本、完整前缀 token、掩码与真实位置约定、每层频率/尺度及其生成策略、坐标布局、精度/量化格式。频率是在线长度的函数时,仅记录 factor 不够,还要能恢复每段缓存构建时实际使用的表与更新状态。这个清单是本文提出的工程验收建议,不是上述库已实现的完整缓存键格式。

结论的边界很清楚:同一组旋转才有同一条相对位置恒等式;重旋转旧键可以修复局部坐标,但整网缓存复用还需要历史内容状态一致。选择冻结、重建或明确的在线协议,先把目标计算说清楚,再比较成本与质量。

研究工具说明:论文元数据与版本使用 citation-management 工作流独立核对,方法出处见 Kassis 等人的 Scientific Agent Skills。此处仅说明研究流程,不作为 RoPE 或模型性能证据。

参考资料

  1. Su et al. RoFormer: Enhanced Transformer with Rotary Position Embedding — arXiv v5, revised 2023-11-08 · 2021-04-20 · 查阅 2026-10-10
  2. Chen et al. Extending Context Window of Large Language Models via Position Interpolation — arXiv v2, revised 2023-06-28; title follows the PDF · 2023-06-27 · 查阅 2026-10-10
  3. Hugging Face Transformers: pinned Llama projections, rotary embedding and cache update order · 查阅 2026-10-10
  4. Hugging Face Transformers: pinned RoPE frequency computation and dynamic updater · 查阅 2026-10-10
  5. Hugging Face Transformers: pinned DynamicLayer and cache implementations · 查阅 2026-10-10
  6. Hugging Face Transformers documentation: rotary embeddings utilities · 查阅 2026-10-10
  7. Hugging Face Transformers documentation: how caching works · 查阅 2026-10-10
  8. Kassis et al. Scientific Agent Skills — research-tool provenance; arXiv v2 revised 2026-09-02 · 2026-08-30 · 查阅 2026-10-10
利友诚

关于作者

利友诚 · Youcheng Li

北京大学智能学院人工智能专业博士研究生,导师为王立威教授;Isoplex Intelligence(壹索智能)联合创始人兼 CTO。

研究关注医疗人工智能、生成式基础模型、诊断推理与科学智能体。以第一作者或共同第一作者身份在 Nature Biomedical Engineering、Scientific Data、KDD 和 PLOS Computational Biology 发表研究。