🧠 图解记忆:多频率给位置坐标,相位差携带相对距离;点击图片可查看原图。
💡 答案要点
位置编码 = 让模型知道token的位置信息
为什么需要位置编码?
问题:不含位置编码的 Self-Attention 对输入置换是等变的,无法单独区分词序
python
# 改变输入顺序会相应改变输出位置,但不会自动知道“第几个 token”的语义
input1 = ["狗", "咬", "人"]
input2 = ["人", "咬", "狗"]
# 若忽略输出位置的同样置换,计算结构本身不含绝对顺序信息解决: 加入位置信息
python
embedding_with_pos = word_embedding + positional_encodingSin/Cos位置编码公式
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: embedding维度(如512)具体计算示例:
python
import numpy as np
def get_positional_encoding(max_len, d_model):
pe = np.zeros((max_len, d_model))
for pos in range(max_len):
for i in range(0, d_model, 2):
# 偶数维度: sin
pe[pos, i] = np.sin(pos / (10000 ** (i/d_model)))
# 奇数维度: cos
if i+1 < d_model:
pe[pos, i+1] = np.cos(pos / (10000 ** (i/d_model)))
return pe
# 示例: max_len=100, d_model=512
pe = get_positional_encoding(100, 512)
# 位置0的编码
print(pe[0]) # [sin(0/1), cos(0/1), sin(0/464), cos(0/464), ...]
# 位置1的编码
print(pe[1]) # [sin(1/1), cos(1/1), sin(1/464), cos(1/464), ...]为什么选sin/cos?
优势1: 表示相对位置
python
# 数学性质: sin/cos的线性组合
sin(α + β) = sin(α)cos(β) + cos(α)sin(β)
cos(α + β) = cos(α)cos(β) - sin(α)sin(β)
# 意味着: PE(pos+k)可由PE(pos)线性变换得到
# 模型容易学习相对位置关系优势2: 泛化到未见过的长度
python
# 训练: max_len=512
# 推理: len=1024 # 超出训练长度
# sin/cos是连续函数,可以外推
pe_1024 = get_positional_encoding(1024, 512) # 依然有效!优势3: 不同频率捕捉不同范围
python
# 低频(i接近0): 变化慢,捕捉长距离关系
PE(pos, 0) = sin(pos / 1) # 周期短,变化快
# 高频(i接近d_model): 变化快,捕捉近距离关系
PE(pos, 511) = sin(pos / 10000) # 周期长,变化慢可视化:
Position 0: [0.00, 1.00, 0.00, 1.00, 0.00, 1.00, ...]
Position 1: [0.84, 0.54, 0.01, 1.00, 0.00, 1.00, ...]
Position 2: [0.91,-0.42, 0.02, 1.00, 0.00, 1.00, ...]
↑ 快变化 ↑ 慢变化其他位置编码方法
| 方法 | 原理 | 优缺点 | 应用 |
|---|---|---|---|
| Sin/Cos | 固定公式 | ✅泛化好 ❌不可学习 | 原始Transformer |
| Learned PE | 可学习embedding | ✅适应任务 ❌不泛化 | BERT |
| RoPE | 旋转位置编码 | ✅长文本好 | LLaMA |
| ALiBi | 注意力偏置 | ✅超长文本 | MPT |
RoPE简介(LLaMA使用):
python
# 不是加法,而是旋转
# Q和K乘以旋转矩阵
Q_rot = rotate(Q, position)
K_rot = rotate(K, position)
# 优势: 相对位置信息更明确
# LLaMA-2可处理4K→32K上下文面试话术:
"Sin/Cos编码的巧妙之处在于:1)不同频率捕捉不同距离 2)可外推到训练时未见长度 3)相对位置可线性表示。现代LLM如LLaMA改用RoPE,在超长文本上表现更好。我们项目用ALiBi,32K上下文零成本扩展。"
