跳转到内容

Positional Encoding:顺序从哪里来

直觉版:注意力本身不知道第几个词

Section titled “直觉版:注意力本身不知道第几个词”

自注意力把一组 token 同时拿来比较,如果不加入位置信息,“我爱你”和“你爱我”会很难区分。位置编码就是告诉模型每个 token 在序列里的位置,让它理解顺序、距离和局部结构。

原始 Transformer 使用正弦/余弦绝对位置编码;后续模型更多使用相对位置思想。RoPE 把位置信息融入 Query/Key 的旋转中,使注意力分数自然包含相对距离,对长上下文扩展更友好。

位置编码方案演进图:

graph TD
A[位置编码方案] --> B[绝对位置编码]
A --> C[相对位置编码]
B --> B1[正弦/余弦编码<br/>Vaswani et al. 2017]
B --> B2[可学习位置嵌入]
C --> C1[RoPE<br/>旋转位置编码<br/>Su et al. 2021]
C --> C2[ALiBi<br/>线性偏置<br/>Press et al. 2021]
C --> C3[相对位置偏置]
style B1 fill:#f9f,stroke:#333
style C1 fill:#9f9,stroke:#333
style C2 fill:#99f,stroke:#333

正弦位置编码公式:

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

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

其中:

  • pospos 是词在序列中的位置
  • ii 是维度索引
  • dmodeld_{model} 是模型维度

绝对位置嵌入实现简单,但训练长度之外的外推通常较差。相对位置偏置、ALiBi、RoPE 等方案试图让模型更稳定地处理未见过的长度。实际长上下文系统还会配合插值、缩放、继续训练和检索增强。

位置编码不是孤立模块:它与 tokenizer、训练长度、注意力 kernel、KV cache 和评测集共同决定效果。调大 context window 前,应测试”needle-in-a-haystack”、长文问答、代码定位和多跳依赖,而不仅看模型能否接受更长输入。

import numpy as np
def get_sinusoidal_positional_encoding(seq_len, d_model):
"""
生成正弦位置编码
seq_len: 序列长度
d_model: embedding 维度
"""
position = np.arange(seq_len)[:, np.newaxis]
div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
pe = np.zeros((seq_len, d_model))
pe[:, 0::2] = np.sin(position * div_term) # 偶数维度用 sin
pe[:, 1::2] = np.cos(position * div_term) # 奇数维度用 cos
return pe
# 生成位置编码
seq_len, d_model = 100, 128
pe = get_sinusoidal_positional_encoding(seq_len, d_model)
print(f"位置编码形状: {pe.shape}") # (100, 128)
print(f"第0个位置前8维: {pe[0, :8]}")
print(f"第10个位置前8维: {pe[10, :8]}")
# 可视化:观察位置编码的周期性
# 不同维度的波长不同,低维变化慢,高维变化快
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 4))
plt.imshow(pe.T, aspect='auto', cmap='RdBu_r', vmin=-1, vmax=1)
plt.colorbar(label='编码值')
plt.xlabel('位置')
plt.ylabel('维度')
plt.title('正弦位置编码热图 (低维波长较长,高维波长较短)')
plt.tight_layout()
plt.show()
# 验证相对位置关系:相同距离的点积应相似
print("\n相对位置验证(相同距离的点积应接近):")
for i in range(3):
dot_same = np.dot(pe[i], pe[i+1])
print(f" 位置{i}{i+1}的点积: {dot_same:.4f}")

研究上,位置编码的核心问题是:如何让模型泛化到训练时未见过的长度?正弦编码有明确的封闭形式,但外推性能差;RoPE 通过旋转矩阵实现相对位置编码,配合插值或缩放可在一定程度上扩展。ALiBi 则直接在注意力分数中加入与距离成线性比例的偏置,简单且外推稳定。

更深的问题是:位置信息是否必须以显式编码形式加入?有研究表明,在足够深的网络中,模型可以从注意力模式的统计规律中间接推断位置。此外,无位置编码的架构(如某些状态空间模型)也展示了顺序建模的可能性,挑战了”位置编码是必需品”的传统假设。

🔬 开放研究问题

该领域的关键问题与研究方向:

  1. RoPE 的旋转矩阵形式为何能自然地支持相对位置编码?其外推极限在哪里?
  2. ALiBi 的线性偏置方案与显式位置编码(如正弦/RoPE)在训练动态上有何本质差异?
  3. 超长上下文场景下,位置编码是否仍然是瓶颈?是否存在无需位置编码的替代架构?

本文引用论文

  • Attention Is All You Need — Ashish Vaswani et al. (2017)

    Transformer 架构的奠基之作。作者完全用注意力机制替代了 RNN/CNN,提出多头自注意力与位置编码, 在机器翻译任务上大幅超越此前所有模型。今天所有主流 LLM 的底层架构都源于此论文。

  • RoFormer: Enhanced Transformer with Rotary Position Embedding — Jianlin Su et al. (2021)

    RoPE(旋转位置编码)是目前主流 LLM(LLaMA、Mistral、Qwen 等)采用的位置编码方案。 通过将位置信息以旋转矩阵的形式融入注意力计算,它能优雅地处理相对位置关系, 且在上下文长度外推时表现比绝对位置编码好得多。

  • Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation — Ofir Press et al. (2021)

    把位置信息变成 attention 上的线性偏置,零参数即可外推到训练长度数倍以上。是早期长上下文方案的代表,与 RoPE 形成两条路线之争。

  • XLNet: Generalized Autoregressive Pretraining for Language Understanding — Zhilin Yang et al. (2019)

    提出 Permutation LM 把 AR 和 AE 的好处合并,配合 Transformer-XL 长序列;展示"预训练目标"本身仍然是开放问题,是 BERT 之后最有想象力的替代品。

  • GLM-130B: An Open Bilingual Pre-trained Model — Aohan Zeng et al. (2022)

    清华+智谱开放的中英双语 130B 模型,是中国大模型工业化最早的代表性技术报告。后续 ChatGLM-6B/9B 把开源中文对话推到普及量级。