2.4 位置编码
Sinusoidal、Learned、RoPE、ALiBi 四种位置编码的数学形式、长度外推能力与实践取舍
为什么需要位置编码
Self-Attention 有一个容易被忽视的特性:对输入的排列对称(permutation-equivariant)。交换序列中任意两个 token,输出结果只是对应位置也发生交换——模型完全不知道谁在前谁在后。
对语言来说这是灾难性的:
小明打了小红 vs. 小红打了小明
两句话词完全相同,但意思相反。如果模型丢失了位置信息,这两句话的表示会被压成同一个。
**位置编码(Positional Encoding, PE)**的任务就是:把"谁在第几个位置"的信息显式注入进模型。历史上有四种主流方案,我们按时间线依次看。
方案一:Sinusoidal PE(Vaswani 2017 原式)
原论文提出了一种无参数的位置编码,用正弦/余弦函数按频率编码位置:
其中 是 token 在序列中的位置, 是隐维度的索引()。
核心性质:对任意固定偏移 , 可以表示为 的线性变换。这保证了模型在学习"相对位置"关系时不会被绝对位置卡住。
使用方式:加在词嵌入上。
Sinusoidal PE 的优势是无需训练、对超出训练长度的序列有一定外推能力。劣势是注入方式是加法,和词嵌入共享同一向量空间,表达能力受限。
方案二:Learned PE(BERT / GPT-2 / GPT-3)
最朴素的方案——把位置本身当成 token,查一个可学习的嵌入表:
self.pos_embedding = nn.Embedding(max_seq_len, d_model)
h0 = token_embed(x) + self.pos_embedding(torch.arange(n))BERT、GPT-2、GPT-3 都采用这种方案。
优势:实现极简单,效果好。
致命劣势:max_seq_len 是硬上限。训练时 ,推理时就完全不能处理更长序列——查表会越界。GPT-3 的 2048 上下文窗口就是这个原因。
方案三:RoPE(旋转位置编码)
Rotary Position Embedding(RoPE)(Su et al., 2021)是目前大模型的事实标准,被 LLaMA、Qwen、ChatGLM、DeepSeek 等一致采用。
核心思想
不再把位置信息加到 embedding 上,而是把位置直接"旋转"进 Q 和 K。在计算 Attention 之前,对 Query 和 Key 按位置做2D 旋转:
把 维向量两两配对成复数 ,对第 个复数旋转角度 ( 是 token 位置):
用实数矩阵写,对每一对坐标 做旋转:
关键性质:点积只依赖相对位置
神奇的是,经 RoPE 旋转后的 只依赖相对位置 ,与绝对位置无关:
这一性质让 RoPE 兼具绝对位置的编码方式和相对位置的比较语义,是它成功的关键。
外推与 NTK 缩放
RoPE 的另一大优势是可外推:训练时 ,推理时 时,只要调整频率基(从 改大),模型不需要重训也能处理更长序列。这一技巧被称作 NTK-aware RoPE,是 LLaMA 2 → LLaMA 3 支持 128K 上下文的关键工具。
# 极简 RoPE 实现(LLaMA 风格)
def rotate_half(x):
x1, x2 = x.chunk(2, dim=-1)
return torch.cat([-x2, x1], dim=-1)
def apply_rope(q, k, cos, sin):
# cos / sin 形状 (seq_len, d_head)
q_rot = q * cos + rotate_half(q) * sin
k_rot = k * cos + rotate_half(k) * sin
return q_rot, k_rot方案四:ALiBi(Attention with Linear Biases)
ALiBi(Press et al., ICLR 2022)的思路更激进——完全不加位置编码,而是在注意力分数上直接加一个线性偏置:
其中 是每个头固定的斜率(不同头用不同的 )。距离越远,惩罚越大;距离越近,几乎没有惩罚。
特点:
- 实现极简,几乎不增加参数
- 外推能力最强——天然支持任意长度
- 缺点:对结构化位置信息的捕捉弱于 RoPE
ALiBi 在 BLOOM、MPT 等模型中使用,但主流大模型(LLaMA 系)仍选 RoPE。
四种方案对比
| 方案 | 代表模型 | 实现方式 | 外推能力 | 参数 |
|---|---|---|---|---|
| Sinusoidal | Transformer 原版 | 加在 embedding 上 | 中 | 0 |
| Learned | BERT / GPT-2 / GPT-3 | 可学习查表 | 无(硬上限) | |
| RoPE | LLaMA / Qwen / DeepSeek | 旋转 Q / K | 强(配合 NTK) | 0 |
| ALiBi | BLOOM / MPT | 在 score 上加线性偏置 | 最强 | (每个头一个斜率) |
长上下文:位置编码的现代战场
LLM 的上下文窗口从 2K(GPT-3)→ 4K(LLaMA 1)→ 8K / 32K(LLaMA 2 / Qwen 2)→ 128K / 200K(LLaMA 3 / Claude)→ 1M(Gemini 1.5)的跨越,很大一部分工作都压在位置编码上。
主要手段:
- NTK-aware RoPE / YaRN:通过调整 RoPE 的频率基,让模型在不重训的情况下支持更长上下文
- Position Interpolation(PI):把长序列的位置"压缩"到训练长度范围内
- ALiBi / RoPE + 指数衰减:用衰减项压制过远距离的注意力
实践建议:除非做基础研究,直接用 RoPE + YaRN 是 2024–2026 年的默认选择。对长文档任务,先把模型切换到 128K 以上版本(Qwen2.5-7B-128K、LLaMA-3.1-128K),再用 RAG / 文档切片做工程上的补充。
本节小结
| 要点 | 内容 |
|---|---|
| 为什么需要 PE | Self-Attention 对位置排列对称,必须显式注入位置 |
| Sinusoidal | 无参数、能外推;注入方式受限(加法) |
| Learned | 简单有效;硬上限(不能外推) |
| RoPE | 旋转 Q/K;相对位置天然;当前事实标准 |
| ALiBi | 注意力分数上的线性偏置;外推最强 |
| 长上下文 | NTK-aware RoPE / YaRN 是关键工具 |
下一节我们从"单个 Block"放大到"整个模型"——看看同样的 Transformer 可以怎样被拼装成 BERT、GPT 和 T5 三种形态。