1. 为什么 Transformer 需要位置编码?

Self-Attention 本质上是一个集合操作:$\text{Attention}(Q, K, V)$ 对输入的顺序不敏感(permutation equivariant)。如果打乱输入顺序,输出只是相应打乱,不包含任何顺序信息。但语言有明确的顺序语义(“猫追狗” ≠ “狗追猫”),必须注入位置信息。

2. 绝对位置编码

2.1 Sinusoidal (原版 Transformer)

Vaswani 等人提出用正弦/余弦函数生成位置编码:

$$ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$

$$ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$

性质:

  • 不同维度对应不同频率的正弦波,从 $2\pi$ 到 $10000 \times 2\pi$
  • 对于任意偏移 $k$,$PE_{pos+k}$ 可以表示为 $PE_{pos}$ 的线性变换:$\sin(pos + k) = \sin(pos)\cos(k) + \cos(pos)\sin(k)$
  • 理论上可以外推到比训练时更长的序列,但实际效果不佳
import torch
import math

def sinusoidal_pos_encoding(max_len, d_model):
    pe = torch.zeros(max_len, d_model)
    position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
    div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
    pe[:, 0::2] = torch.sin(position * div_term)
    pe[:, 1::2] = torch.cos(position * div_term)
    return pe

2.2 Learned Positional Embedding

BERT、GPT-2 使用可学习的位置 Embedding:

self.position_embeddings = nn.Embedding(max_position_embeddings, hidden_size)
# 前向传播
position_ids = torch.arange(seq_len).unsqueeze(0)
embeddings = token_embeddings + self.position_embeddings(position_ids)

优点:灵活,模型可以学习最优的位置表示。缺点:硬编码了最大长度,无法外推。

3. RoPE (Rotary Position Embedding)

3.1 核心思想

RoPE(Su et al., 2021)将位置信息编码为旋转操作:在二维平面上旋转 Query 和 Key 向量,使得 Attention Score 自然地依赖于相对位置。

3.2 数学推导

对于二维向量 $q = (q_0, q_1)$,在位置 $m$ 处旋转角度 $m\theta$:

$$ R(m, \theta) q = \begin{pmatrix} \cos(m\theta) & -\sin(m\theta) \ \sin(m\theta) & \cos(m\theta) \end{pmatrix} \begin{pmatrix} q_0 \ q_1 \end{pmatrix} $$

对 $d$ 维向量,将其分成 $d/2$ 组二维平面,每组使用不同频率 $\theta_i = 10000^{-2i/d}$:

$$ q_m^T k_n = (R_m q)^T (R_n k) = q^T R_m^T R_n k = q^T R_{n-m} k $$

关键性质: Attention Score 只依赖相对位置 $n - m$,而非绝对位置。

3.3 高效实现

def apply_rotary_pos_emb(q, k, cos, sin):
    """q, k: (batch, n_heads, seq_len, d_head)
       cos, sin: (seq_len, d_head)"""
    def rotate_half(x):
        x1 = x[..., :x.shape[-1] // 2]
        x2 = x[..., x.shape[-1] // 2:]
        return torch.cat((-x2, x1), dim=-1)
    
    q_embed = (q * cos) + (rotate_half(q) * sin)
    k_embed = (k * cos) + (rotate_half(k) * sin)
    return q_embed, k_embed

def precompute_rope_cis(head_dim, max_seq_len, theta=10000.0):
    freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2).float() / head_dim))
    t = torch.arange(max_seq_len).float()
    freqs = torch.outer(t, freqs)  # (seq_len, head_dim/2)
    cos = torch.cos(freqs)
    sin = torch.sin(freqs)
    # 复数形式:更优雅的实现
    cis = torch.polar(torch.ones_like(freqs), freqs)  # e^{i*freqs}
    return cis

3.4 RoPE 的优势

  • 相对位置编码:天然编码相对位置,无需显式相对位置矩阵
  • 无需额外参数:不需要可学习的 Embedding
  • 可外推:理论上可以应用于训练时未见过的长度(配合缩放技巧)
  • 已被广泛采用:LLaMA、Qwen、Mistral、ChatGLM 等

4. ALiBi (Attention with Linear Biases)

4.1 方法

ALiBi(Press et al., 2022)不修改输入 Embedding,而是在 Attention Score 上加一个与距离成正比的偏置:

$$ \text{Attention}(q_i, k_j) = \text{softmax}\left(q_i k_j^T - m \cdot |i - j|\right) $$

其中 $m$ 是每个 Head 独有的斜率,按几何序列设置:$m_h = \frac{1}{2^{8/h}}$

4.2 特点

  • 无位置参数:不需要位置 Embedding,减少参数量
  • 天然外推:训练 1024 长度,可以直接在 2048+ 长度上推理,性能不退化
  • 简单高效:只是在 Attention Score 上加一个偏置矩阵

4.3 局限

  • 外推时性能虽然不退化,但也没有提升(不像 RoPE 配合 NTK/YaRN 可以真正扩展)
  • 在超长上下文(32K+)场景下不如 RoPE + 外推方案灵活

5. 长度外推技术

5.1 Position Interpolation (PI)

Chen et al. (2023) 提出简单缩放:将位置索引缩放到训练范围内。

$$ \text{RoPE}(x, m’) = \text{RoPE}\left(x, \frac{m \cdot L_{train}}{L_{target}}\right) $$

效果:4K 训练 → 8K 推理可行,但更长(32K+)效果下降明显。

5.2 NTK-aware Interpolation

关键观察:PI 对所有频率统一缩放,但高频维度需要更精细的处理。NTK-aware 方案修改 RoPE 的 base:

$$ \theta’i = \theta_i \cdot \left(\frac{L{target}}{L_{train}}\right)^{-d/(d-2)} $$

等价于:高频部分几乎不缩放(保持局部注意力精度),低频部分大幅缩放(扩展感受野)。

5.3 YaRN (Yet another RoPE extensioN)

YaRN 进一步优化,将频率维度分为三个区域:

  1. 高频区:不缩放(保持局部模式识别能力)
  2. 低频区:完全 PI 缩放(扩展范围)
  3. 过渡区:平滑插值

同时引入 Attention 温度缩放:$\text{softmax}(\text{scores} / t)$,$t = 0.1 \cdot \ln(s) + 1$。

5.4 长度外推效果对比

方法4K→8K4K→16K4K→32K4K→64K需要微调
直接外推
PI少量
NTK-aware否(少量)
YaRN少量

6. 各方案对比总结

方案类型外推能力参数量代表模型
Sinusoidal绝对0Transformer
Learned绝对$L_{max} \times d$BERT, GPT-2
RoPE相对(旋转)中(配合外推强)0LLaMA, Qwen
ALiBi相对(偏置)强(不退化)$h$BLOOM, MPT

7. 实践建议

  1. 新项目首选 RoPE:配合 YaRN 或 NTK 可以灵活扩展上下文
  2. 需要快速外推:ALiBi 可以零成本外推 2-4 倍
  3. 超长上下文(100K+):RoPE + YaRN 微调 + Ring Attention 是当前最佳方案
  4. 注意 RoPE base 的选择:base=10000 是默认值,部分模型用 500000 或 1000000 来获得更好的长序列初始化

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。