Skip to content
🔗 分享本题
查看我的学习进度 →

位置编码动漫知识图:自注意力本身不能区分排列顺序,Token Embedding 加入位置坐标后才能分辨语序,并对比 Sin Cos、Learned、RoPE 与 ALiBi

🧠 图解记忆:内容向量告诉模型是什么,位置编码告诉模型在哪里;点击图片可查看原图。

💡 答案要点

位置编码 = 给每个token注入位置信息

为什么需要?

问题:
  Self-Attention 是置换不变的(permutation-invariant)

例子:
  "我 爱 你" 和 "你 爱 我"
  如果没有位置编码,Attention 输出可能相同
  → 无法区分顺序

解决:
  加入位置信息,让模型知道每个token的位置

Transformer 的位置编码(Sinusoidal):

公式:

python
PE(pos, 2i)   = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

其中:
  pos: 位置(0, 1, 2, ...
  i:   维度索引(0 到 d_model/2
  d_model: 模型维度(如512)

实现:

python
def positional_encoding(max_len, d_model):
    # 创建位置矩阵
    position = torch.arange(max_len).unsqueeze(1)  # (max_len, 1)

    # 创建维度矩阵
    div_term = torch.exp(
        torch.arange(0, d_model, 2) *
        -(math.log(10000.0) / d_model)
    )  # (d_model/2,)

    # 初始化位置编码
    pe = torch.zeros(max_len, d_model)

    # 偶数维度用sin
    pe[:, 0::2] = torch.sin(position * div_term)

    # 奇数维度用cos
    pe[:, 1::2] = torch.cos(position * div_term)

    return pe

# 使用
pe = positional_encoding(max_len=100, d_model=512)
# pe.shape: (100, 512)

# 加到输入上
x = embedding(input_ids) + pe[: input_ids.size(1)]

为什么用sin/cos?

优势:

  1. 确定性:位置固定,不需要学习
  2. 可生成任意位置的编码:公式能计算训练长度之外的位置,但模型在更长序列上的有效能力仍需实测
  3. 周期性:不同位置间有规律的相对关系

相对位置关系:

python
# PE(pos + k) 可以表示为 PE(pos) 的线性组合
# 这让模型能学习相对位置

例如:
  PE(5) 和 PE(10) 的距离
  = PE(1) 和 PE(6) 的距离
  (相对距离都是5)

可视化(前10个位置,前64维):

位置  维度0  维度1  维度2  维度3  ...
0     0.00   1.00   0.00   1.00
1     0.84   0.54   0.01   1.00
2     0.91  -0.42   0.02   1.00
3     0.14  -0.99   0.03   1.00
...

其他位置编码方案:

方案优点缺点应用
Sinusoidal确定性,可计算更长位置训练长度外效果无保证Transformer
Learned可学习,灵活超出已训练位置通常需要扩展并继续训练BERT
RoPE相对位置,旋转实现复杂LLaMA
ALiBi注意力偏置需要重训练BLOOM

现代改进:RoPE(Rotary Position Embedding):

python
# LLaMA/GPT-NeoX 使用
# 核心思想:在注意力计算时旋转 Q 和 K

def apply_rotary_emb(q, k, cos, sin):
    # 旋转 Q 和 K
    q_rot = rotate_half(q)
    k_rot = rotate_half(k)

    q = q * cos + q_rot * sin
    k = k * cos + k_rot * sin

    return q, k

# 优势:
#   - 相对位置编码
#   - 便于表达相对位置信息
#   - 长度扩展仍需要缩放策略并通过目标任务验证

面试话术:

"Transformer 需要额外注入位置信息。Sin/Cos 编码无训练参数且能计算任意位置;RoPE 通过旋转 Q、K 让注意力分数自然携带相对位置信息。两者在训练长度外都不能只凭公式宣称有效,必须做长上下文评测。"

📚 参考:RoFormer:Rotary Position Embedding(RoPE 论文)