在钟表王国里,老王是专修大钟楼的老师傅。镇上这座大钟由 64 对齿轮塔驱动,每对齿轮塔的转速都不同——编号越小的塔转得越快,像秒针;编号越大的塔转得越慢,像时针。大钟出厂时,钟面只能显示 2048 个小时刻度(对应模型训练时见过的 2K 上下文)。有一天镇长下令:“我要一块能显示 128K 小时的钟!”有人提议什么都不改,让指针继续往下转——结果指针转到了钟面上根本不存在的刻度,钟楼发出刺耳的乱响(这就是外推崩溃)。有人提议把所有齿轮统一减速 64 倍,把 128K 小时硬塞进 2048 的钟面——钟是能走了,可秒针几乎不转,连 12:01 和 12:02 都分不清(这就是朴素位置插值)。老王思考很久,最终拿出一套方案:用“波长卷尺”量每对齿轮,在对数调校台上让转速平滑过渡(频率感知插值),再给钟摆加一个“助力器”补偿摆动幅度(注意力温度缩放),最后只需试运行 1000 圈就能正式挂钟。这套方案,就是 YaRN。

岗位关联

学会 YaRN,你就掌握了把任何 RoPE 预训练大模型扩展到 128K+ 上下文的工程钥匙——千步微调、即插即用,这是大模型长文本落地中最抢手的能力之一。

目录
  1. 可视化演示
  2. RoPE 旋转编码
  3. 外推成败关键
  4. 朴素位置插值
  5. NTK 感知缩放
  6. YaRN 对数插值
  7. 注意力温度缩放
  8. 轻量微调适配
  9. 128K 应用效果
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示RoPE频率插值、分段缩放策略与注意力温度调整,切换模式查看YaRN核心技术。

本节配有交互动效(进入视口后自动加载,约 3KB)。

RoPE频率插值机制 YaRN在对数空间对旋转位置编码频率进行线性插值,扩展上下文窗口 λ\' = λ / s 插值后波长拉伸,支持更长的位置范围

RoPE 旋转编码

老王的工具箱里有一份祖传的“齿轮转速表”:64 对齿轮塔,第 i 对的转速是 10000 的 -2i/d 次幂。编号 0 的塔一转就是一圈,编号 63 的塔要转上万圈才走一格——从秒针到时针,一整套“速度频谱”就靠这一条公式铺开。大语言模型里的 RoPE(旋转位置编码)用的正是同一套逻辑:位置不是贴标签,而是让向量旋转一个角度。

具体来说,RoPE 把每个 token 的 query(查询)和 key(键)向量按维度两两配对,第 i 对分量在位置 p 处旋转 p·θ_i 弧度。i 越小旋转越快,i 越大旋转越慢,这样不同维度各自负责不同粒度的距离感:快齿轮管“挨得近不近”,慢齿轮管“离得多远”。

θi=b−2id\displaystyle \theta_i = b^{-\frac{2i}{d}}

1. 全局基数 b:b=10000 是钟楼的总动力刻度,决定所有齿轮转速的量级,也决定位置编码的整体“分辨率”。

b=10000\displaystyle b = 10000

2. 维度对编号 i:i 从 0 到 d/2−1 标记第几对齿轮塔,配对的两个分量共享同一转速,协同完成二维旋转。

i∈{0,1,…,d2−1}\displaystyle i \in \left\{0, 1, \dots, \frac{d}{2}-1\right\}

3. 指数式转速:转速随 i 按基数 b 的 −2i/d 次幂指数衰减,形成从“秒针”到“时针”的完整速度频谱,token 的位置 p 就编码为累计旋转角 p·θ_i。

θi=b−2id\displaystyle \theta_i = b^{-\frac{2i}{d}}

理解了转速表,就明白了为什么“位置”在 RoPE 里不是一张查询表,而是一组会旋转的指针。接下来要回答的问题是:当指针转出钟面,会发生什么?

外推成败关键

镇长说“我要 128K 小时的钟面”,第一个冒出来的馊主意是:什么都不改,让指针接着转。毕竟齿轮没坏,为什么不能多走几圈?可钟面根本没有那些刻度——指针指向 3000 小时的刻度时,整个钟楼的人都不知道那是什么时间。大模型外推时的情况一模一样:位置 p 超过训练长度,旋转角 p·θ_i 进入训练时从未见过的数值区间。

注意力机制要计算两个 token 的相关性,RoPE 下这个相关性只取决于相对位置 p−q:把 key 旋转 (p−q) 的角度再和 query 点积。训练时,模型只见过 (p−q) 在 2048 以内的旋转组合;一旦相对距离超过窗口,高频维度已经转了成百上千圈,旋转角落在哪一象限完全不可预测,点积结果剧烈抖动,softmax 后的注意力分数要么爆炸、要么错乱。

apq=softmax(qp⊤R(p−q) kqd)\displaystyle a_{pq} = \mathrm{softmax}\left( \frac{q_p^\top R(p-q)\, k_q}{\sqrt{d}} \right)

1. 相对位置旋转:R(p−q) 把 key 旋转到与 query 对齐的坐标系,让注意力只依赖两个 token 的距离,而不是绝对位置。

R(p−q)=∏iRi((p−q)θi)\displaystyle R(p-q) = \prod_{i} R_i\big((p-q)\theta_i\big)

2. 点积相似度:旋转后的 query 与 key 做点积,数值越大表示该位置的 token 与当前查询越相关。

qp⊤R(p−q) kq\displaystyle q_p^\top R(p-q)\, k_q

3. softmax 归一:先除以 √d 稳定方差,再做 softmax,得到当前 query 对所有 key 的注意力权重分布。

apq=softmax(qp⊤R(p−q) kqd)\displaystyle a_{pq} = \mathrm{softmax}\Big(\frac{q_p^\top R(p-q)\, k_q}{\sqrt{d}}\Big)

外推行不通,指针在空白刻度上乱摆,钟楼发出刺耳噪音。于是有人想到:与其让指针乱转,不如把整个 128K 小时压缩进 2048 的钟面——这就是朴素位置插值。

朴素位置插值

第二个方案粗暴但直观:把所有齿轮统一减速 64 倍。原来走 64 个小时的路程,现在只走 1 个小时,这样 128K 个小时就能全部映射进 2048 的钟面。训练时见过的每个刻度都能对上,模型不至于完全失智。但代价立刻显现:秒针几乎不转,12:01 和 12:02 的夹角肉眼不可见。

朴素位置插值(naive Position Interpolation, PI)在数学上就是把每个位置的旋转角乘以 N_old/N_new = 1/s。对高频维度(小 i)来说,它们原本负责区分相邻 token,被压缩后相邻位置的旋转角差趋近于零——短距离的“分钟精度”彻底丢失。想恢复精度,只能靠大规模重训让模型重新适应被抹平的角度差异,成本极高。

θiPI=θi⋅1s=θis\displaystyle \theta_i^{PI} = \theta_i \cdot \frac{1}{s} = \frac{\theta_i}{s}

1. 缩放比 s:s 是新窗口与旧窗口的比值,2K→128K 时 s=64,代表所有刻度被压缩到原来的 1/64。

s=NnewNold=64\displaystyle s = \frac{N_{new}}{N_{old}} = 64

2. 统一缩放:所有维度的旋转角都乘以 1/s,等价于把位置 p 压缩成 p/s,再映射回训练过的窗口。

θiPI=θi⋅1s\displaystyle \theta_i^{PI} = \theta_i \cdot \frac{1}{s}

3. 高频代价:相邻位置的角度差同样被压缩 64 倍,高频维度几乎无法区分“这一步”和“下一步”。

(p+1)θiPI−p θiPI=θis\displaystyle (p+1)\theta_i^{PI} - p\,\theta_i^{PI} = \frac{\theta_i}{s}

统一减速保住了“能走”,却牺牲了“精准”。老王的直觉是:秒针和时针的使命本来就不一样,凭什么让秒针也跟着变慢?这个直觉催生了按频率区别对待的思路。

NTK 感知缩放

老王围着齿轮箱转了三圈,提出第三个方案:只给慢齿轮减速,快齿轮保持原速!秒针还是秒针,分钟精度一点不丢;时针慢下来,钟面就能多显示几十个小时。这正是 NTK 感知缩放(NTK-aware scaling)的朴素图景:高频维度原样保留,低频维度按需压缩。

NTK-aware 的巧妙之处在于,它不需要逐维手调转速,只要做一件事——把基数 base 从 b 换成更大的 b'。基数变大后,所有维度的转速按指数规律整体下移,但高频端(小 i)受到的影响微乎其微,低频端(大 i)被显著压缩。一石二鸟:短距离精度保住了,长距离覆盖也打开了。

b′=b⋅sdd−2\displaystyle b' = b \cdot s^{\frac{d}{d-2}}

1. 目标倍率 s:s 仍然是新窗口对旧窗口的倍率,它决定整体要“多走多远”。

s=NnewNold\displaystyle s = \frac{N_{new}}{N_{old}}

2. 换基指数:d/(d−2) 略大于 1,由头维度 d 决定,保证最高频维度几乎不变、最低频维度约缩小 s 倍。

dd−2≈1+2d\displaystyle \frac{d}{d-2} \approx 1 + \frac{2}{d}

3. 新基座:把新基数代回转速公式,各维度自动获得与自身频率匹配的缩放量,无需手调。

b′=b⋅sdd−2,θiNTK=(b′)−2id\displaystyle b' = b \cdot s^{\frac{d}{d-2}}, \qquad \theta_i^{NTK} = (b')^{-\frac{2i}{d}}

NTK 方案让钟楼安静了不少,可老王发现两个新问题:齿轮箱转速过渡处有“硬台阶”,咬合时咔咔作响;而且钟摆的摆动幅度明显不对——注意力分布失真了。要解决这两个隐患,需要真正的 YaRN。

YaRN 对数插值

老王拿出“波长卷尺”——波长 λ_i = 2π/θ_i,也就是这对齿轮走一圈所对应的 token 距离。他给齿轮分了三档:波长比旧窗口还短的(高频),保持原速;波长比新窗口还长的(低频),完全压缩;中间的在“对数调校台”上平滑过渡。这就是 YaRN(Yet another RoPE extensioN)的核心思想:按波长分带,频率在对数空间做线性插值。

为什么必须在对数空间?因为频率跨度高达几十倍,线性空间的混合会在中间维度留下“台阶”。而对数空间的线性混合,相当于对频率做等比过渡——过渡带里每一个维度都平滑衔接,没有扭结。γ_i 是 0 到 1 之间随波长爬升的过渡系数,高频端 γ=0(原速),低频端 γ=1(全压缩)。

θiY=θi⋅s−γi,γi=clamp ⁣(log⁡λi−log⁡λoldlog⁡λnew−log⁡λold,  0,  1)\displaystyle \theta_i^{Y} = \theta_i \cdot s^{-\gamma_i}, \qquad \gamma_i = \mathrm{clamp}\!\left(\frac{\log\lambda_i - \log\lambda_{old}}{\log\lambda_{new} - \log\lambda_{old}},\;0,\;1\right)

1. 波长标尺:波长 λ_i 是第 i 对齿轮转一圈走过的 token 数,波长越长的齿轮转得越慢,管得越远。

λi=2πθi=2π b2id\displaystyle \lambda_i = \frac{2\pi}{\theta_i} = 2\pi\, b^{\frac{2i}{d}}

2. 过渡带系数:γ_i 在“旧窗口波长”与“新窗口波长”之间线性爬升,范围被 clamp 在 0 到 1。

γi=clamp ⁣(log⁡λi−log⁡λoldlog⁡λnew−log⁡λold,  0,  1)\displaystyle \gamma_i = \mathrm{clamp}\!\left(\frac{\log\lambda_i - \log\lambda_{old}}{\log\lambda_{new} - \log\lambda_{old}},\;0,\;1\right)

3. 对数线性混合:旋转角的对数在“原值”与“压缩值”之间线性内插,等价于让角速度乘以 s 的 −γ 次幂。

log⁡θiY=(1−γi)log⁡θi+γilog⁡θis\displaystyle \log\theta_i^{Y} = (1-\gamma_i)\log\theta_i + \gamma_i\log\frac{\theta_i}{s}

齿轮过渡带终于平滑了,但老王的耳朵还是竖着——钟摆的摆动幅度不对劲。压缩频率改变的不只是齿轮转速,还有注意力分数的“方差”,温度缩放正是为这个问题准备的。

注意力温度缩放

插值之后,所有相对旋转角都变小了,cos 值几乎都贴在 1 附近。这意味着每个 key 和 query 的点积差异被压扁——注意力变成“谁都一样重要”,softmax 之后的分布几乎均匀。对模型来说,这和“失忆”没什么区别:它不再能聚焦关键位置。

YaRN 的解法是在钟摆上加一个“助力器”:把注意力 logits 统一乘以温度系数 t。t 由缩放比 s 和头维度 d 决定,s=64、d=128 时 t≈8。乘上 t 之后,被压扁的差异被重新放大,softmax 的锐度恢复到了预训练阶段的水平——注意力分布重新变得有高有低、层次分明。

t=sd2(d−2),apq=softmax(t⋅qp⊤R′(p−q) kqd)\displaystyle t = s^{\frac{d}{2(d-2)}}, \qquad a_{pq} = \mathrm{softmax}\left( \frac{t \cdot q_p^\top R'(p-q)\, k_q}{\sqrt{d}} \right)

1. 方差压缩:插值后相对旋转角整体变小,logits 的方差远小于预训练时的水平,分布趋近均匀。

Var(qp⊤R′(Δ) k)≪Var(qp⊤R(Δ) k)\displaystyle \mathrm{Var}\big(q_p^\top R'(\Delta)\, k\big) \ll \mathrm{Var}\big(q_p^\top R(\Delta)\, k\big)

2. 温度系数:t 由 s 和 d 共同决定,量化了“需要放大多少倍”才能找回原来的方差量级。

t=sd2(d−2)\displaystyle t = s^{\frac{d}{2(d-2)}}

3. 补偿后的分布:logits 乘以 t 再做 softmax,注意力分布的锐度与预训练阶段基本一致。

apq=softmax(t⋅qp⊤R′(p−q) kqd)\displaystyle a_{pq} = \mathrm{softmax}\Big( \frac{t \cdot q_p^\top R'(p-q)\, k_q}{\sqrt{d}} \Big)

钟摆恢复了正常摆动,大钟看起来已经能挂上 128K 的钟面。但老王知道,新齿轮之间还没磨合过——正式营业前,需要一次轻量的试运行。

轻量微调适配

新钟面和新转速装好了,但齿轮咬合的手感需要适应。好在 YaRN 的插值已经把大部分工作做完了,模型不需要从头学习,只需要“重新校准手感”:用极低的学习率微调约 1000 步,让注意力头在新频率下重新找到熟悉的分布。

微调目标仍然是标准的自回归语言建模——逐 token 预测下一个词,最小化负对数似然。配合“截断序列”技巧,可以在有限的显存里模拟超长距离的注意力依赖,让千步微调真正生效。相比朴素插值动辄需要大量数据的重训,YaRN 的微调成本几乎可以忽略。

L=−1T∑t=1Tlog⁡Pθ(xt∣x<t)\displaystyle \mathcal{L} = -\frac{1}{T}\sum_{t=1}^{T}\log P_\theta(x_t \mid x_{<t})

1. 自回归目标:模型逐 token 预测下一个词,预测越准,单个 token 的对数似然越高。

Pθ(xt∣x<t)\displaystyle P_\theta(x_t \mid x_{<t})

2. 平均损失:在序列长度 T 上取平均,得到整个序列的平均负对数似然,作为微调的优化目标。

L=−1T∑t=1Tlog⁡Pθ(xt∣x<t)\displaystyle \mathcal{L} = -\frac{1}{T}\sum_{t=1}^{T}\log P_\theta(x_t \mid x_{<t})

3. 千步收敛:在低学习率下,约 1000 步即可完成频率感知的重新校准,无需大规模预训练。

θ←θ−η ∇θL,η=2×10−5\displaystyle \theta \leftarrow \theta - \eta\,\nabla_\theta \mathcal{L}, \qquad \eta = 2\times10^{-5}

试运行结束,镇长亲自验收。大家最关心的问题来了:这块 128K 的钟面,到底走得稳不稳、准不准?

128K 应用效果

验收的核心指标是困惑度(PPL)——它衡量模型对文本的“惊讶”程度,数值越低说明模型预测越稳。朴素插值在窗口超过训练长度后 PPL 迅速飙升,而 YaRN 在 128K 甚至更长的窗口下 PPL 保持平稳:这是“走得稳”。

“走得准”则体现在短距离精度上。因为高频维度几乎没动,模型对相邻 token 的敏感度和预训练时一致——短距离困惑度明显低于朴素插值;低频维度的平滑压缩又让远距离信息变得可用。实验表明,YaRN 在检索、长文档问答等下游任务上稳定提升,而微调使用的 token 量只有预训练语料的约千分之一。

PPL=exp⁡(−1N∑n=1Nlog⁡Pθ(xn∣x<n))\displaystyle PPL = \exp\left( -\frac{1}{N}\sum_{n=1}^{N}\log P_\theta(x_n \mid x_{<n}) \right)

1. 困惑度定义:对一段文本计算平均负对数似然再取指数,得到“惊讶程度”的度量。

PPL=exp⁡(−1N∑n=1Nlog⁡Pθ(xn∣x<n))\displaystyle PPL = \exp\Big(-\frac{1}{N}\sum_{n=1}^{N}\log P_\theta(x_n \mid x_{<n})\Big)

2. 超窗验证:在 128K 以上窗口,YaRN 的 PPL 不随长度飙升,验证频率插值的稳定性。

PPL128K≈PPL2K\displaystyle PPL_{128K} \approx PPL_{2K}

3. 短距保真:高频维未动使得短距离困惑度显著低于朴素插值,证明“分钟精度”没有丢失。

PPLyarnshort<PPLPIshort\displaystyle PPL_{yarn}^{short} < PPL_{PI}^{short}

大钟在 128K 的钟面上平稳运行,分钟读数分秒不差。从齿轮转速表到对数调校台,从摆锤助力器到千步试运行,YaRN 用一套完整的工程方案回答了“如何让预训练模型看见更长的世界”。

AI 应用场景

智能客服:一场对话从今往后不再“失忆”

阶段:长上下文推理与模型服务

解决的问题:传统客服模型受 4K/8K 窗口限制,只能截取最近一段对话;用户一小时前说过的关键信息(账户类型、投诉对象)在窗口滑出后彻底丢失。用 YaRN 扩展后,一次前向推理就能容纳整场数小时的长会话,无需额外检索模块即可保持“记忆”。

具体案例:某银行智能客服把 7B 模型从 4K 扩展到 64K 上下文。测试中用户在第 160 轮提问“我刚才说的公积金账户是哪个支行的”,模型直接引用第 2 轮的上下文给出正确答复,而基座模型在相同数据下答错。上线后复杂会话的一次解决率提升约 18%。

长文档问答:一次读完三百页研报

阶段:模型微调与评测

解决的问题:传统方案要把 300 页文档切块后做 RAG 检索,跨章节的因果问题(“第五章的政策变化如何影响第三章的收入假设?”)在切块后信息割裂。YaRN 把窗口扩到 128K 后,模型直接“通读”全文再回答,省去了复杂的检索管线。

具体案例:某券商用 YaRN 扩展 LLaMA-2-7B 至 128K,在 20 篇研报的跨章节问答集上准确率较 RAG 基线提升 22%;微调仅用约 1000 步、数千条长文档样本,一周内完成迭代上线。

推荐系统:把半年行为序列装进一个窗口

阶段:序列特征建模与召回

解决的问题:协同过滤与序列推荐通常把用户行为截断到最近 50~100 条,长尾兴趣(三个月前点击过的冷门品类)被截断丢弃。借助 YaRN,行为序列编码器可以把数千条行为一次编码进注意力窗口,长周期兴趣重新可见。

具体案例:某视频平台的排序模型把用户行为序列从 128 条扩展到 4096 条(约 64K token),长期兴趣信号重新进入注意力范围,冷门但强相关的内容召回率提升 15%,整体观看时长指标提升 3.2%。

Python 演示

python55 行
import mathimport torchimport torch.nn.functional as F  def yarn_inv_freq(dim, s, base=10000.0):    """Compute YaRN frequencies: log-space linear interpolation."""    half = dim // 2    idx = torch.arange(half, dtype=torch.float32)    inv_orig = 1.0 / (base ** (2 * idx / dim))    new_base = base * (s ** (dim / (dim - 2)))    inv_new = 1.0 / (new_base ** (2 * idx / dim))    low = 0.25 * half    high = 0.75 * half    gamma = torch.clamp((idx - low) / (high - low), 0.0, 1.0)    inv_freq = torch.exp((1 - gamma) * torch.log(inv_orig) + gamma * torch.log(inv_new))    return inv_freq, gamma  def rope_rotate(x, pos, inv_freq):    """Apply rotary embedding to x: [n, dim]."""    half = inv_freq.shape[0]    angles = torch.outer(pos, inv_freq)    cos_c = torch.cos(angles)    sin_c = torch.sin(angles)    x1 = x[:, :half]    x2 = x[:, half:]    out1 = x1 * cos_c - x2 * sin_c    out2 = x1 * sin_c + x2 * cos_c    return torch.cat([out1, out2], dim=-1)  def main():    torch.manual_seed(0)    dim, s, n = 64, 16, 512    inv_freq, gamma = yarn_inv_freq(dim, s)    pos = torch.arange(n, dtype=torch.float32)    q = torch.randn(n, dim)    k = torch.randn(n, dim)    q_r = rope_rotate(q, pos, inv_freq)    k_r = rope_rotate(k, pos, inv_freq)    scores = (q_r[0] @ k_r.T) / math.sqrt(dim)    attn = F.softmax(scores, dim=-1)    ent_plain = -(attn * torch.log(attn + 1e-9)).sum().item()    t = s ** (dim / (2 * (dim - 2)))    attn_t = F.softmax(scores * t, dim=-1)    ent_temp = -(attn_t * torch.log(attn_t + 1e-9)).sum().item()    print("gamma range: %.3f - %.3f" % (gamma.min().item(), gamma.max().item()))    print("attention entropy without temp: %.3f" % ent_plain)    print("temperature t: %.3f" % t)    print("attention entropy with temp: %.3f" % ent_temp)  if __name__ == "__main__":    main()
目的:实现 YaRN 的核心频率计算(对数空间线性插值 + 过渡带 γ),并用一个小型注意力演示验证温度缩放对注意力熵的影响。
  1. new_base = base * (s ** (dim / (dim - 2)))NTK 感知缩放的“换基座”,基数变大后各维度自动获得不同缩放。
  2. gamma = torch.clamp((idx - low) / (high - low), 0.0, 1.0)过渡带斜坡:高低频之间平滑爬升的 γ 系数。
  3. inv_freq = torch.exp((1 - gamma) * torch.log(inv_orig) + gamma * torch.log(inv_new))对数空间线性插值,YaRN 的全部精髓。
  4. angles = torch.outer(pos, inv_freq)位置向量与频率向量做外积,得到每个 token 每个维度的累计旋转角。
  5. scores = (q_r[0] @ k_r.T) / math.sqrt(dim)位置 0 的 query 与所有 key 点积,得到原始注意力 logits。
  6. t = s ** (dim / (2 * (dim - 2)))注意力温度系数,s=16、d=64 时约为 3.36。
  7. attn_t = F.softmax(scores * t, dim=-1)温度补偿后的注意力分布,熵显著降低,锐度恢复。

常见误区

误区“外推不行,那我直接把 128K 的位置均匀压到 2K 里不就行了?反正位置就是个整数。” 初学者认为朴素位置插值已经解决了问题,频率只是无关紧要的细节。

正解位置是表象,频率才是本质。朴素插值把所有频率(所有齿轮)统一除以 64,高频维负责的短距离信息被彻底抹平——相邻 token 的旋转角几乎一样,模型只能“猜”局部顺序。YaRN 的核心正是按频率分别对待:高频维原样保留,低频维才插值。只做坐标缩放,等于让秒针和时针一起停摆。

为何常见:因为 RoPE 对用户是黑盒,大家“只见位置、不见频率”,很容易把问题简化成坐标缩放,忽略了位置编码的频谱结构。

误区“YaRN 不就是 NTK 感知缩放吗?换个 base 而已。” 网上不少资料把这两个名词混用。

正解NTK-aware 是 YaRN 的前身:它通过换 base 实现频率的整体平移,但过渡是“硬切”的,且完全没有处理注意力 logits 的方差压缩。YaRN 有两个关键贡献:一是在对数空间做带过渡带的线性插值,让频率平滑变化;二是引入注意力温度缩放,把注意力分布拉回预训练形态。可以说 YaRN 是 NTK-aware 的“完全体”。

为何常见:两者都源于 NTK 视角、公式长得像(都涉及 base 的替换),很多文章为了省事把 YaRN 简单概括为“NTK 变种”,掩盖了它的创新点。

误区“温度系数把 logits 放大,注意力更锐利,是不是窗口想扩多大都行?” 一些工程师把温度当成“超频开关”。

正解温度只补偿插值造成的分布失真,不能凭空创造训练时没见过的位置关系。上下文能扩多长,取决于频率插值后的覆盖范围与微调数据中见过的长距离模式。盲目加大温度会让注意力过于尖锐,反而退化成只看局部。它本质是“恢复出厂设置”,而不是“无上限增强”。

为何常见:“温度”这个词容易让人联想到“调大参数就有更强效果”,忽略了它背后的方差补偿机理和理论边界。

误区“YaRN 论文不是说不用大规模重训吗?那就是开箱即用,加载权重直接上线。” 不少团队跳过了微调步骤。

正解YaRN 的“少量微调”也是微调——约 1000 步、低学习率、配合截断序列技巧,注意力头需要在新频率下重新校准“刻度手感”。完全没有微调时,长窗口推理虽比朴素外推稳定,但困惑度和下游精度仍有明显差距。千步微调是 YaRN 配方里不可省略的一味药。

为何常见:大家把“无需大规模预训练”的亮点放大了,忽略了论文中“依然需要轻量对齐”的细节,导致上线时踩坑。

面试题

Q1. RoPE 用一组旋转角度表示位置,其基本思想是?

单选题 · easy

  • A.把位置标量拼进向量头部
  • B.让查询向量随位置旋转← 正确答案
  • C.用哈希表映射位置
  • D.用可学习的绝对位置表

答案:B。RoPE 把位置编码为旋转操作——token 的 query/key 经旋转后,两个 token 的注意力只取决于旋转角之差,即相对位置。A 把位置当标量拼接,C 是哈希映射,D 是可学习绝对位置表,都偏离了“旋转”思想。就好比问钟楼靠什么计时,答案是齿轮旋转而不是贴标签。

Q2. 朴素位置插值对频率的处理方式是?

单选题 · easy

  • A.全部维度乘以同一缩放因子← 正确答案
  • B.高频维度原样保留
  • C.只压缩低频维度
  • D.用神经网络重新学习

答案:A。朴素插值对所有维度一视同仁:旋转角统一乘以 1/s(s 为窗口缩放比)。B/C 分别是 NTK 感知缩放和 YaRN 的做法,D 是重训而非插值。把所有齿轮一起减速,秒针几乎停转,短距离精度随之丢失——这正是朴素插值的致命伤。

Q3. NTK 感知缩放等价于把 RoPE 的基数 base?

单选题 · mid

  • A.改成更小的基数
  • B.改成更大的基数← 正确答案
  • C.保持基数不变
  • D.将基数替换为 0

答案:B。NTK 感知缩放等价于把 base 从 b 换成 b·s^(d/(d−2))。基数变大后,各维度转速按指数规律整体下移,但高频端受的影响远小于低频端——相当于“只给慢齿轮减速”。A 方向相反会让高频也大幅变动,C 等于没改,D 无意义。

Q4. YaRN 的频率混合发生在哪种空间?

单选题 · mid

  • A.线性空间
  • B.对数空间← 正确答案
  • C.复数空间
  • D.概率空间

答案:B。YaRN 在 log θ 空间做线性插值:γ=0 时保持原转速,γ=1 时为完全压缩,中间的频率按等比曲线过渡。线性空间的混频会在几十倍的频率跨度上产生“台阶”,对数空间才能让过渡带平滑无扭结。复数、概率空间与频率混合无关。

Q5. YaRN 保留原始旋转速度的维度是?

单选题 · mid

  • A.波长较长的低频维
  • B.波长较短的高频维← 正确答案
  • C.所有中间维度
  • D.全部维度统一

答案:B。YaRN 按波长分带:波长比旧窗口还短的维度(高频)保持原速,负责短距离精度;波长接近或超过新窗口的维度(低频)被压缩,负责扩展远距离。A 说反了,C 的中间维度属于过渡带(部分压缩),D 是朴素插值的做法。

Q6. 注意力温度缩放主要补偿什么?

单选题 · mid

  • A.权重参数初始化偏差
  • B.logits 方差被压缩← 正确答案
  • C.激活函数饱和问题
  • D.梯度消失和爆炸

答案:B。频率压缩后相对旋转角变小,cos 差异趋近于 1,logits 的方差被压扁,注意力趋近均匀——“谁都一样重要”。温度系数把 logits 放大 t 倍以恢复锐度。A/C/D 属于训练稳定性话题,与插值引起的分布失真无关,是典型的干扰项。

Q7. 缩放比 s=64、头维度 d=128 时,YaRN 的温度系数 t 约为?

单选题 · hard

  • A.8.2 倍← 正确答案
  • B.64 倍
  • C.0.5 倍
  • D.128 倍

答案:A。由 t = s^(d/(2(d−2))) 代入 s=64、d=128:t = 64^(128/252) ≈ 64^0.508 ≈ 8.2。B 的 64 是缩放比本身,C 会把注意力摊得更平,D 是窗口倍率而非温度。钟摆助力器只需“放大 8 倍左右”,这个量级感是 YaRN 工程调参的基本功。

Q8. 相比朴素位置插值,YaRN 的改进包括?

多选题 · mid

  • A.保留短距离位置精度← 正确答案
  • B.完全无需微调
  • C.频率感知的对数插值← 正确答案
  • D.注意力温度补偿← 正确答案

答案:ACD。YaRN 的核心改进有三:按波长感知频率进行对数插值(C)、高频维保留从而保住短距离精度(A)、温度补偿恢复注意力分布(D)。B 错误——YaRN 仍需约千步轻量微调,只是量级远小于朴素插值的大规模重训。

Q9. 关于 YaRN 的过渡带系数 γ,正确的说法有?

多选题 · extreme

  • A.由每个维度的波长决定← 正确答案
  • B.高频端 γ 接近 0← 正确答案
  • C.低频端 γ 接近 1← 正确答案
  • D.所有维度使用相同 γ

答案:ABC。γ_i 由维度 i 的波长落在哪一段决定:波长小于旧窗口的高频端 γ≈0(原速),波长大于新窗口的低频端 γ≈1(全压缩),过渡带内 γ 从 0 平滑爬到 1。D 说所有维度相同,那是朴素插值“一刀切”的做法,与 YaRN 的频率感知思想矛盾。

Q10. YaRN 轻量微调阶段的特点包括?

单选题 · mid

  • A.大约千步级别即可← 正确答案
  • B.需要从零预训练
  • C.通常采用低学习率
  • D.可配合截断序列技巧

答案:A。YaRN 论文用约 1000 步、低学习率完成轻量微调,并配合“截断序列”技巧在有限显存中近似长距离依赖,B 的从零预训练与“轻量”二字完全矛盾。考生需牢记:YaRN 的定位是“极小代价的适配”,不是重训。