位置编码:正弦、RoPE、ALiBi 本节摘要:注意力是置换不变(Permutation-Invariant)的。「The cat sat on the mat」和「mat the on sat cat the」在没有位置信号时产出完全相同的结果——打乱 X 的行,输出行只是跟着打乱,注意力内部没有任何东西关心位置。对于词袋模型这不是 bug,但对于语言、代码、音频、视频——任何顺序承载意义的东西——这是致命的。
本节摘要:注意力是**置换不变(Permutation-Invariant)**的。「The cat sat on the mat」和「mat the on sat cat the」在没有位置信号时产出完全相同的结果——打乱 X 的行,输出行只是跟着打乱,注意力内部没有任何东西关心位置。对于词袋模型这不是 bug,但对于语言、代码、音频、视频——任何顺序承载意义的东西——这是致命的。修法是把位置信息注入嵌入,三个时代的答案各有各的赌注:正弦编码(Vaswani 2017,把 sin/cos 加进嵌入,简单、外推差)、RoPE 旋转位置编码(Su 2021,按位置旋转 Q 和 K,直接在点积里编码相对位置,2026 年统治一切)、ALiBi 线性偏置注意力(Press 2022,完全跳过嵌入,直接按距离给注意力分数加线性惩罚,长度外推极佳)。本节将带你从零实现三种方案,亲测 RoPE 的相对距离不变性,并梳理 YaRN、NTK-aware、LongRoPE 这些长上下文外推技巧。读完本节,你能说清为什么 RoPE 赢了,以及怎么把 8K 上下文扩到 128K。
阅读完本节,你应当能够:
缩放点积注意力 softmax(QKᵀ/√d)V 由两两相似度算出。打乱 X 的行,输出行跟着打乱,注意力内部没有任何东西关心位置。对词袋模型这不是 bug;对语言、代码、音频、视频——任何顺序承载意义的东西——这是致命的。
修法是把位置注入嵌入。三个时代的答案:
到 2026 年,几乎所有前沿开源模型都用 RoPE:Llama 2/3/4、Qwen 2/3、Mistral、Mixtral、DeepSeek-V3、Kimi。少数长上下文模型用 ALiBi 或其现代变体。绝对正弦已成历史。
预计算一个固定矩阵 PE,形状 (max_len, d_model):
PE[pos, 2i] = sin(pos / 10000^(2i / d_model)) PE[pos, 2i+1] = cos(pos / 10000^(2i / d_model))
然后 X' = X + PE[:N],再过注意力。每一维是不同频率的正弦波,模型从相位模式里读出位置。超出 max_len 就失效:模型在训练里只见过 0~2047 的位置,你给它 2048 它就懵了。
RoPE 旋转 Q 和 K(不是嵌入)。对一对维度 (2i, 2i+1):
[q'_2i ] [ cos(pos·θ_i) -sin(pos·θ_i) ] [q_2i ] [q'_2i+1] = [ sin(pos·θ_i) cos(pos·θ_i) ] [q_2i+1] θ_i = base^(-2i / d_head), base 默认 10000
对位置 pos_k 上的键施加同样的旋转。点积 q'_m · k'_n 只取决于 (m - n)——也就是说,注意力分数只取决于相对距离,即使旋转本身是用绝对位置编号的。这是个漂亮的技巧。
RoPE 还能扩展:缩放 base(NTK-aware、YaRN、LongRoPE)就能不重训外推到更长上下文。Llama 3 就这么把 8K 扩到 128K。
💡 关键性质:对任意常数偏移
k,RoPE(q, m+k) · RoPE(k_vec, n+k) == RoPE(q, m) · RoPE(k_vec, n)(浮点误差内)。平移绝对位置不改点积,只有相对距离起作用。这个性质是 RoPE 全部价值的基石。
跳过嵌入技巧,直接偏置注意力分数:
attn_score[i, j] = (q_i · k_j) / √d - m_h · |i - j|
m_h 是每个头专属的斜率(如 1/2^(8·h/H))。近的 token 被放大,远的被惩罚。无训练成本。论文显示其长度外推超过正弦,在原始训练长度上匹敌 RoPE。
| 变体 | 外推能力 | 训练成本 | 用于 |
|---|---|---|---|
| 绝对正弦 | 差 | 免费 | 原 Transformer、早期 BERT |
| 可学习绝对 | 无 | 微小 | GPT-2、GPT-3 |
| RoPE | 配合缩放后好 | 免费 | Llama 2/3/4、Qwen 2/3、Mistral、DeepSeek-V3、Kimi |
| RoPE + YaRN | 极佳 | 微调阶段 | Qwen2-1M、Llama 3.1 128K |
| ALiBi | 极佳 | 免费 | BLOOM、MPT、Baichuan |
RoPE 赢,因为它不改架构就能插进注意力、编码相对位置,且 base 超参给了长上下文微调一个干净的旋钮。
完整代码见原课程 phases/07-transformers-deep-dive/04-positional-encoding/code/main.py。4 行核心:
def sinusoidal(N, d): pe = [[0.0] * d for _ in range(N)] for pos in range(N): for i in range(d // 2): theta = pos / (10000 ** (2 * i / d)) pe[pos][2 * i] = math.sin(theta) pe[pos][2 * i + 1] = math.cos(theta) return pe
把 PE[:N] 加到嵌入矩阵上,再进第一个注意力层。
RoPE 原地操作 Q 和 K,对每对维度旋转:
def apply_rope(x, pos, base=10000): d, out = len(x), list(x) for i in range(d // 2): theta = pos / (base ** (2 * i / d)) c, s = math.cos(theta), math.sin(theta) a, b = x[2 * i], x[2 * i + 1] out[2 * i] = a * c - b * s out[2 * i + 1] = a * s + b * c return out
关键:对位置 m 上的 Q 和位置 n 上的 K 施加同一个函数。点积在每个维度对上拾起一个 cos((m-n)·θ_i) 因子——注意力白捡相对位置。
def alibi_bias(n_heads, seq_len): slopes = [2 ** (-8 * (h + 1) / n_heads) for h in range(n_heads)] bias = [] for m in slopes: bias.append([[-m * abs(i - j) for j in range(seq_len)] for i in range(seq_len)]) return bias # 在 softmax 前加到注意力分数上
把 bias[h] 加到第 h 个头的 (seq_len, seq_len) 注意力分数矩阵,再 softmax。
取两个随机向量 a, b,分别旋转 (pos_a, pos_b) 与 (pos_a + k, pos_b + k),两个点积必须在浮点误差内相等。这个不变性正是 RoPE 的全部意义——绝对偏移无关,只有相对间距起作用。
PyTorch 2.5+ 在 torch.nn.functional 里提供 RoPE 工具;大多数生产代码用 flash_attn 或 xformers,RoPE 在注意力 kernel 内部施加:
from transformers import AutoModel model = AutoModel.from_pretrained("meta-llama/Llama-3.2-3B") # model.config.rope_scaling → {"type": "yarn", "factor": 32.0, # "original_max_position_embeddings": 8192}
2026 年的长上下文技巧:
base 重缩放为 base · (scale_factor)^(d/(d-2)),保护高频维度不被挤扁。⚠️ 设计警示:别在生产里手写 RoPE 而不读 HuggingFace 的
modeling_rope_utils.py——它实现了 default、linear、dynamic、YaRN、LongRoPE、Llama-3 全套缩放方案,边界情况(奇数维度、混合精度)都处理过了。自造容易在长上下文踩坑。
原课程产出 outputs/skill-positional-encoding-picker.md:一个选择器 Skill,给定目标上下文长度、外推需求、训练预算,推荐编码策略(正弦 / RoPE / RoPE+YaRN / ALiBi)。
PE 矩阵(max_len=512, d=128)画成热力图,确认「条纹随维度增大而变宽」的模式。softmax(QKᵀ/√d)V 由两两相似度算出,打乱行只让输出行跟着乱——顺序无感知,对有序数据致命。sin/cos 加进嵌入,无可学习参数,但超出 max_len 就失效——已成历史。q'_m · k'_n 只取决于 m-n,白捡相对位置;2026 年统治一切(Llama、Qwen、Mistral、DeepSeek)。分数 - m_h·|i-j|,近 token 放大远 token 惩罚,长度外推极佳(BLOOM、MPT)。base 是 RoPE 的旋钮:增大 base 在推理时延长上下文,无需重训。base 给长上下文微调干净旋钮。下一节,我们将把前几节的积木拼成完整的 Transformer——编码器和解码器,加上残差连接、层归一化与前馈网络。