目 录CONTENT

文章目录

【理论】深入理解Transformer中的正弦位置编码

EulerBlind
2025-09-30 / 0 评论 / 0 点赞 / 7 阅读 / 0 字

引言

位置编码(Positional Encoding)是Transformer架构中一个精妙而关键的组件。不同于卷积神经网络天然具备的空间感知能力,Transformer的自注意力机制本身是位置无关的——如果不加入位置信息,模型无法区分"我爱你"和"你爱我"。本文将深入探讨Transformer为何选择正弦位置编码,以及这个设计背后的数学原理和工程考量。

问题的本质:Transformer需要位置感知

自注意力的位置盲区

Transformer的核心——自注意力机制(Self-Attention)——具有置换不变性(permutation invariant)。这意味着:

输入1: ["我", "爱", "你"]
输入2: ["你", "爱", "我"]
输入3: ["爱", "你", "我"]

# 如果没有位置编码,这三个输入在自注意力中会产生相同的注意力权重分布

但在自然语言中,词序至关重要。不同的排列组合会产生完全不同的语义。因此,必须显式地向模型注入位置信息

与CNN的对比

卷积神经网络在图像处理中天然具有位置感知:

  • 卷积核在空间上滑动,自动编码了相对位置关系
  • 不同位置的特征通过空间结构保持关联

Transformer缺少这种天然的位置感知机制,需要通过位置编码来弥补。

正弦位置编码的设计

核心公式

Transformer论文《Attention Is All You Need》(Vaswani et al., 2017)提出的正弦位置编码公式为:

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)

符号说明:

  • pos:token在序列中的位置索引,pos \in [0, 1, 2, ..., seq\_len-1]
  • i:embedding向量的维度索引,i \in [0, 1, 2, ..., d_{model}/2-1]
  • d_{model}:embedding的维度大小(如512或768)
  • 10000波长缩放常数,控制不同维度的频率范围

10000这个魔法数字的含义

公式中的 10000 是一个精心选择的超参数,它的作用是控制位置编码的频率范围:

频率计算:
\text{frequency}_i = \frac{1}{10000^{2i/d_{model}}}

不同维度的波长:

  • 维度 i=0(最高频): 波长 = 2\pi \cdot 10000^0 = 2\pi \approx 6.28
  • 维度 i=d_{model}/4(中频): 波长 = 2\pi \cdot 10000^{0.5} = 628
  • 维度 i=d_{model}/2-1(最低频): 波长 ≈ 2\pi \cdot 10000 = 62832

为什么选择10000?

  1. 覆盖常见序列长度:最低频率的波长约为62832,远大于常见的序列长度(512-4096)
  2. 避免频率混淆:在实际使用的序列长度范围内,不同位置的编码组合几乎不会重复
  3. 数值稳定性:既不会太大导致梯度消失,也不会太小导致频率过密

公式的结构解析

1. 偶数和奇数维度配对

公式将每个维度 i 分成一对:

  • 偶数维度 2i:使用 \sin 函数
  • 奇数维度 2i+1:使用 \cos 函数

这种配对设计类似于复数表示:e^{i\theta} = \cos(\theta) + i\sin(\theta),提供了相位正交的两个信息通道。

2. 频率随维度递减

指数项 10000^{2i/d_{model}} 使得:

  • i 越小 → 频率越高 → 波长越短 → 捕捉局部位置关系
  • i 越大 → 频率越低 → 波长越长 → 捕捉全局位置关系

这类似于傅里叶变换中用不同频率的正弦波组合来表示复杂信号。

维度 i 的含义:常见误解

这里需要特别澄清一个容易混淆的概念。在NLP任务中有三个"长度":

vocab_size = 50000   # 词汇表大小
seq_len = 128        # 序列长度(一句话有多少个token)
d_model = 512        # embedding维度(每个token用多少维向量表示)

公式中的 i 指的是第三个:embedding的维度索引!

完整示例

假设输入句子:"我 爱 自然 语言 处理"(5个token)

# 词嵌入后
token_embeddings = [
    [e₀⁽⁰⁾, e₁⁽⁰⁾, ..., e₅₁₁⁽⁰⁾],  # "我" 的512维词向量
    [e₀⁽¹⁾, e₁⁽¹⁾, ..., e₅₁₁⁽¹⁾],  # "爱" 的512维词向量
    [e₀⁽²⁾, e₁⁽²⁾, ..., e₅₁₁⁽²⁾],  # "自然" 的512维词向量
    [e₀⁽³⁾, e₁⁽³⁾, ..., e₅₁₁⁽³⁾],  # "语言" 的512维词向量
    [e₀⁽⁴⁾, e₁⁽⁴⁾, ..., e₅₁₁⁽⁴⁾],  # "处理" 的512维词向量
]

# 位置编码
PE(pos=0) = [sin(0/10000⁰), cos(0/10000⁰), sin(0/10000^(2/512)), cos(0/10000^(2/512)), ..., sin(0/10000^(510/512)), cos(0/10000^(510/512))]
PE(pos=1) = [sin(1/10000⁰), cos(1/10000⁰), sin(1/10000^(2/512)), cos(1/10000^(2/512)), ..., sin(1/10000^(510/512)), cos(1/10000^(510/512))]
...
PE(pos=4) = [sin(4/10000⁰), cos(4/10000⁰), sin(4/10000^(2/512)), cos(4/10000^(2/512)), ..., sin(4/10000^(510/512)), cos(4/10000^(510/512))]

# 最终输入 = 词嵌入 + 位置编码
final_input[pos] = token_embeddings[pos] + PE(pos)

每个位置生成一个 d_{model} 维的位置向量,其中:

  • 维度索引 i:遍历0到255(因为每个 i 对应两维,2i2i+1
  • 位置索引 pos:遍历0到4(5个token的位置)

为什么这个设计如此巧妙?

1. 有界性与数值稳定

\sin(x), \cos(x) \in [-1, 1]

无论序列多长,位置编码的值都在固定范围内,保证了训练的数值稳定性。

对比简单方案:

  • 直接用整数(1, 2, 3, ...):无界,短序列和长序列的数值范围差异巨大
  • 归一化(pos/max_len):依赖序列长度,同一位置在不同长度序列中编码不一致

2. 长度无关性

位置10的编码不依赖序列总长度:

  • 在100 token的序列中,位置10的编码是固定的
  • 在1000 token的序列中,位置10的编码完全相同

这保证了模型的泛化能力。

3. 多频率表示

不同维度捕捉不同尺度的位置信息:

维度范围频率特性波长作用
i \in [0, 64]高频~6-100相邻token的细微差异
i \in [64, 192]中频~100-1000短语级别的位置关系
i \in [192, 256]低频~1000-60000句子级别的全局结构

这种多尺度表示类似于小波变换或傅里叶级数。

4. 相对位置的线性变换性质

这是最优雅的数学性质。利用三角恒等式:

\sin(\alpha + \beta) = \sin(\alpha)\cos(\beta) + \cos(\alpha)\sin(\beta)
\cos(\alpha + \beta) = \cos(\alpha)\cos(\beta) - \sin(\alpha)\sin(\beta)

可以证明,对于固定的位置偏移 k

\begin{bmatrix} PE_{(pos+k, 2i)} \\ PE_{(pos+k, 2i+1)} \end{bmatrix} = \begin{bmatrix} \cos(\theta_k) & \sin(\theta_k) \\ -\sin(\theta_k) & \cos(\theta_k) \end{bmatrix} \begin{bmatrix} PE_{(pos, 2i)} \\ PE_{(pos, 2i+1)} \end{bmatrix}

其中 \theta_k = k / 10000^{2i/d_{model}}

这是一个旋转矩阵!意味着:

  • PE(pos+k) 可以表示为 PE(pos) 的线性变换
  • 模型可以通过学习捕捉相对位置关系
  • 不同位置之间的关系具有一致的几何结构

5. 平滑性与连续性

相邻位置的编码向量高度相似:

\text{similarity}(PE(pos), PE(pos+1)) = \cos(\angle(PE(pos), PE(pos+1))) \approx 1

而距离较远的位置编码差异显著,符合自然语言的局部性特征。

为什么同时使用正弦和余弦?

数学本质

从数学上看,\cos(x) = \sin(x + \pi/2),余弦只是正弦的相位平移。那为什么要同时使用?

关键原因

1. 相位正交性

\sin\cos 在相位上正交(相差90°),提供两个独立的信息维度。这类似于二维平面上的 (x, y) 坐标:

e^{i\theta} = \cos(\theta) + i\sin(\theta)

两个函数配对使用,每个频率可以编码更丰富的信息。

2. 保持线性变换性质

只有同时使用 \sin\cos,才能构成完整的旋转矩阵,实现前面提到的相对位置线性变换性质。

3. 消除歧义性

如果只用 \sin 函数:

  • \sin(x) = \sin(\pi - x):不同位置可能有相同的编码值
  • 同时使用 \sin\cos 可以唯一确定角度(在一个周期内)

周期性:特性还是缺陷?

潜在问题

正弦函数的周期性意味着:

\sin(x) = \sin(x + 2\pi) = \sin(x + 4\pi) = ...

理论上,对于某个特定频率,位置 pos 和位置 pos + 2\pi \cdot 10000^{2i/d_{model}} 会有相同的编码。

为什么实际不是问题?

多频率组合的唯一性:

虽然单个频率会重复,但512个不同频率的组合几乎不会重复。这类似于:

  • 单个时钟表盘会循环
  • 但多个不同速度的表盘组合可以表示很长的时间跨度

实际序列长度的考量:

对于最低频率(i = d_{model}/2 - 1):

\text{周期} = 2\pi \cdot 10000 \approx 62,832

这远大于常见的序列长度:

  • BERT:512 tokens
  • GPT-2:1024 tokens
  • GPT-3:2048 tokens
  • 现代LLM:4096-8192 tokens

只有在极长序列(>10,000 tokens)时,周期性才可能成为问题。

代码实现

import numpy as np
import matplotlib.pyplot as plt

def get_positional_encoding(seq_len, d_model):
    """
    生成正弦位置编码
    
    Args:
        seq_len: 序列长度
        d_model: embedding维度(必须是偶数)
    
    Returns:
        位置编码矩阵,shape: (seq_len, d_model)
    """
    # 初始化位置编码矩阵
    pe = np.zeros((seq_len, d_model))
    
    # 计算位置索引,shape: (seq_len, 1)
    position = np.arange(seq_len).reshape(-1, 1)
    
    # 计算维度索引对应的除数项,shape: (d_model/2,)
    div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
    
    # 偶数维度使用 sin
    pe[:, 0::2] = np.sin(position * div_term)
    
    # 奇数维度使用 cos
    pe[:, 1::2] = np.cos(position * div_term)
    
    return pe

# 使用示例
seq_len = 100
d_model = 512

pe = get_positional_encoding(seq_len, d_model)
print(f"位置编码矩阵形状: {pe.shape}")  # (100, 512)

# 可视化前64维的位置编码
plt.figure(figsize=(12, 8))
plt.imshow(pe[:, :64].T, cmap='RdBu', aspect='auto')
plt.xlabel('Position')
plt.ylabel('Dimension')
plt.title('Positional Encoding Heatmap (first 64 dimensions)')
plt.colorbar()
plt.show()

可视化理解

位置编码的热力图展示了清晰的波纹模式:

  • 横向:不同位置
  • 纵向:不同维度(频率)
  • 上方维度:高频波动(细节)
  • 下方维度:低频波动(全局)

其他位置编码方案

虽然正弦编码是Transformer的经典选择,但后续研究提出了多种改进方案:

1. 可学习位置编码(Learned Positional Embeddings)

代表模型: BERT、GPT系列

position_embedding = nn.Embedding(max_seq_len, d_model)

特点:

  • ✅ 可针对具体任务优化
  • ✅ 某些任务上效果更好
  • ❌ 无法外推到更长序列
  • ❌ 需要更多训练数据

2. 相对位置编码(Relative Position Encoding)

代表模型: Transformer-XL、T5

编码token之间的相对距离而非绝对位置。

特点:

  • ✅ 更符合语言的局部性
  • ✅ 泛化能力强
  • ❌ 实现较复杂

3. 旋转位置编码(RoPE - Rotary Position Embedding)

代表模型: LLaMA、GPT-Neo、PaLM

核心思想: 通过旋转变换直接编码相对位置

\text{Attention}(Q, K) = (R_{\theta, q}Q)(R_{\theta, k}K)^T

其中 R_{\theta} 是旋转矩阵。

特点:

  • ✅ 结合绝对和相对位置优势
  • ✅ 外推性能优异
  • ✅ 数学上更优雅
  • ❌ 需要修改注意力机制

论文: RoFormer (Su et al., 2021)

4. ALiBi(Attention with Linear Biases)

代表模型: BLOOM

核心思想: 直接在注意力分数上添加线性偏置

\text{Attention}(Q, K) = \text{softmax}\left(QK^T - \lambda \cdot |i-j|\right)

特点:

  • ✅ 极简(几乎无额外参数)
  • ✅ 外推能力极强(训练1K,测试10K+)
  • ✅ 避免周期性问题
  • ❌ 较新,应用案例较少

论文: "Train Short, Test Long" (Press et al., 2022)

方案对比

方案参数量外推能力计算复杂度相对位置代表模型
正弦编码0中等间接Transformer
可学习编码O(L \cdot d)BERT, GPT
Transformer-XLO(L \cdot d)中等直接XLNet
RoPE0优秀直接LLaMA
ALiBi0最优直接BLOOM

为什么选择正弦编码?

在2017年Transformer论文发表时,正弦编码被选择的原因:

1. 简洁性原则

  • Transformer是第一个完全基于注意力的架构
  • 避免引入过多需要学习的参数
  • 保持模型的可解释性

2. 理论基础扎实

  • 受信号处理和傅里叶分析启发
  • 具有清晰的数学性质(线性变换、相对位置)
  • 理论上可以外推到任意长度

3. 实验验证

论文实验表明:

  • 正弦编码和可学习编码性能几乎相同
  • 既然效果相当,选择更简单、通用的方案

4. 工程实用性

  • 无需学习,减少训练成本
  • 计算高效(现代硬件对三角函数优化良好)
  • 不占用参数预算

现代实践建议

根据具体需求选择位置编码:

场景推荐方案理由
新的大语言模型RoPE最佳平衡:性能、外推、效率
固定长度任务可学习编码可针对任务优化
超长序列(>8K)ALiBi外推能力最强
经典复现/教学正弦编码简洁、易懂、理论优雅
中等长度通用RoPE或正弦根据实验选择

总结

正弦位置编码是Transformer架构中一个精妙的设计,它通过多频率的周期函数优雅地解决了位置感知问题:

核心优势:

  • 有界归一化,数值稳定
  • 长度无关,泛化能力强
  • 多频率表示,捕捉多尺度位置关系
  • 数学性质优雅,支持相对位置学习
  • 零参数,计算高效

适用性:

  • 中等长度序列(< 4K tokens)表现优秀
  • 是理解位置编码概念的最佳起点
  • 在许多任务上仍然competitive

虽然现代模型(如LLaMA)已经采用更先进的RoPE等方案,但正弦编码的设计思想——用不同频率的组合来表示位置信息——深刻影响了后续所有的改进方案。理解正弦编码,是深入掌握Transformer架构的重要一步。

参考文献

  1. Vaswani, A., et al. (2017). "Attention Is All You Need." NeurIPS. arXiv:1706.03762

  2. Su, J., et al. (2021). "RoFormer: Enhanced Transformer with Rotary Position Embedding." arXiv:2104.09864

  3. Press, O., et al. (2022). "Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation." ICLR. arXiv:2108.12409

  4. Dai, Z., et al. (2019). "Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context." ACL. arXiv:1901.02860

  5. Shaw, P., et al. (2018). "Self-Attention with Relative Position Representations." NAACL. arXiv:1803.02155


本文从数学原理和工程实践两个角度,全面解析了Transformer位置编码的设计哲学,希望能帮助读者真正理解"为什么"而不仅仅是"是什么"。

0
博主关闭了所有页面的评论