🔧 为什么需要“位置插值”?
大语言模型如 GPT、LLaMA 等在训练时使用的是有限长度的上下文窗口(如 2048 token)。如果想在推理阶段扩展上下文到 4K、16K、100K 甚至百万 token,必须解决一个核心问题:
原始位置编码机制不支持未见过的位置索引!
例如:
- RoPE(旋转位置编码)是 GPT 系列中使用的机制,训练时只学习到 2048 个位置索引。
- 如果你强行外推,比如输入 4096 个 token,它就必须处理未见过的位置,从而性能显著下降。
于是引入插值:把原本“稀疏的”位置信息,插值成“密集的”分布,让模型在训练过的位置区间“内”继续工作,而不是外推“未知位置”。
回顾rope
mmm 是 token 在序列中的位置编号(position index),比如在一句话中:
“The cat sat on the mat”
如果我们将这句话 tokenize 为:
| Token | Index mmm |
|---|---|
| The | 0 |
| cat | 1 |
| sat | 2 |
| on | 3 |
| the | 4 |
| mat | 5 |
那么:
- 第一个 token “The” 的位置是 m=0m = 0m=0;
- 第二个 token “cat” 的位置是 m=1m = 1m=1;
- 以此类推。
在位置编码中,我们通常对每个 token 使用它的 mmm 值来生成对应的旋转编码。
iii 是 embedding 向量维度中的索引(维度编号)
假设一个 token 的嵌入向量维度 d=8d = 8d=8,我们可以将它分为 4 个维度对:
| iii | 维度对 (2i,2i+1)(2i, 2i+1)(2i,2i+1) |
|---|---|
| 0 | (0, 1) |
| 1 | (2, 3) |
| 2 | (4, 5) |
| 3 | (6, 7) |
RoPE 在每个维度对 (2i,2i+1)(2i, 2i+1)(2i,2i+1) 上使用不同的频率 θi\theta_iθi 来控制旋转角度:
θi=1100002i/d \theta_i = \frac{1}{10000^{2i / d}} θi=100002i/d1
- iii 越大,频率 θi\theta_iθi 越小;
- 这意味着高维旋转更慢、低维旋转更快;
RoPE 编码每个 token 的嵌入向量时,使用如下公式在维度对 (2i,2i+1)(2i, 2i+1)(2i,2i+1) 上进行旋转:
[x2irotx2i+1rot]=[cos(θi⋅m)−sin(θi⋅m)sin(θi⋅m)cos(θi⋅m)][x2ix2i+1]\begin{bmatrix} x_{2i}^{\text{rot}} \\ x_{2i+1}^{\text{rot}} \end{bmatrix} =\begin{bmatrix} \cos(\theta_i \cdot m) & -\sin(\theta_i \cdot m) \\ \sin(\theta_i \cdot m) & \cos(\theta_i \cdot m) \end{bmatrix} \begin{bmatrix} x_{2i} \\ x_{2i+1} \end{bmatrix}[x2irotx2i+1rot]=[cos(θi⋅m)sin(θi⋅m)−sin(θi⋅m)cos(θi⋅


6487

被折叠的 条评论
为什么被折叠?



