张芷铭的个人博客

深度学习中的位置编码原理及应用

什么是位置编码

位置编码(Positional Encoding)是Transformer架构中引入序列顺序信息的关键机制。由于Transformer的自注意力机制本身不具备顺序敏感性,无法区分像“猫追老鼠”和“老鼠追猫”这类语序不同的句子,位置编码通过向输入向量添加位置信息,使模型能够理解序列中元素的排列顺序。目前普遍的做法是相加,其数学表达为: $$ \text{Input} = \text{TokenEmbedding}(x_i) + \text{PositionalEncoding}(pos_i) $$ 其中$x_i$表示输入元素,$pos_i$表示其在序列中的位置。这种设计让模型同时获取语义信息和位置信息,成为现代大模型处理序列数据的基石。

为什么计算出的位置编码不直接和token concat呢?或者其他做法?直接把位置编码加到token上不会改变token编码好的语义吗?

  1. 解释一 ![[Pasted image 20250817225545.png]]
  2. 解释二:引用苏建林博客:#

[!quote] 相乘式的位置编码 刚才我们说到,输入xk与绝对位置编码pk的组合方式一般是xk+pk,那有没有“不一般”的组合方式呢?比如xk⊗pk(逐位相乘)?我们平时在搭建模型的时候,对于融合两个向量有多种方式,相加、相乘甚至拼接都是可以考虑的,怎么大家在做绝对位置编码的时候,都默认只考虑相加了?

很抱歉,笔者也不知道答案。可能大家默认选择相加是因为向量的相加具有比较鲜明的几何意义,但是对于深度学习模型来说,这种几何意义其实没有什么实际的价值。最近笔者看到的一个实验显示,似乎将“加”换成“乘”,也就是xk⊗pk的方式,似乎比xk+pk能取得更好的结果。具体效果笔者也没有完整对比过,只是提供这么一种可能性。关于实验来源,可以参考《中文语言模型研究:(1) 乘性位置编码》

视频:

博客:


位置编码的发展历程

位置编码技术自2017年提出后经历了显著演进:

  1. [[绝对位置编码]](2017):原始Transformer采用固定正弦/余弦函数生成位置编码: $$ \begin{aligned} 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) \end{aligned} $$ 通过几何级数频率分布捕捉多尺度位置关系,支持长度外推但不可训练。

  2. 可学习位置编码(2018):BERT、GPT等模型将位置编码改为可训练参数矩阵,提升短文本任务表现但牺牲了长度外推能力。

  3. 相对位置编码(2020):Transformer-XL、T5引入相对位置偏置,直接建模元素间距离而非绝对位置,改善长序列处理能力。

  4. 旋转位置编码(2021)RoFormer: Enhanced Transformer with Rotary Position … RoPE通过向量旋转将相对位置信息融入注意力机制: $$ \begin{bmatrix} q_m \ q_{m+1} \end{bmatrix} \otimes \begin{bmatrix} \cos m\theta & -\sin m\theta \ \sin m\theta & \cos m\theta \end{bmatrix} $$ 在LLaMA、ChatGLM等模型中实现高效的长上下文建模。

  5. 线性偏置编码(2022):ALiBi直接在注意力分数添加与距离成正比的负偏置: $$ \text{Attention} = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}} + m\cdot|i-j|\right)V $$ 无需额外参数即支持超长文本推理。


核心原理与数学推导

正弦位置编码的特性

  1. 多尺度位置表示:高频分量($i$较大)编码局部位置关系,低频分量($i$较小)编码全局位置关系。
  2. 相对位置线性表达:偏移$k$后的位置编码可表示为原始编码的线性变换: $$ PE_{pos+k} = T_k \cdot PE_{pos} $$ 其中$T_k$是仅依赖$k$的变换矩阵,该性质源于三角函数的加法公式。
  3. 边界外推性:理论上可处理任意长度序列,但实际中外推超过训练长度时高频分量稳定性下降。

旋转位置编码的数学本质

RoPE的核心思想是通过旋转矩阵保持向量模长不变,使注意力分数仅依赖相对位置差。二维情况下旋转操作: $$ Rot_\theta(x) = \begin{bmatrix} \cos\theta & -\sin\theta \ \sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} x_0 \ x_1 \end{bmatrix} $$ 扩展到高维后,$Q$和$K$的内积转化为: $$ \langle Rot_m(q), Rot_n(k) \rangle = \langle q,k \rangle \cos((m-n)\theta) $$ 使注意力分数仅与相对位置差$|m-n|$相关


位置编码的适用场景对比

编码类型短文本任务长文本任务计算效率典型模型
正弦/余弦编码中等良好Transformer, ViT
可学习绝对编码优秀中等BERT, GPT-2
相对位置编码良好优秀中等Transformer-XL, T5
RoPE旋转编码良好优秀LLaMA, ChatGLM
ALiBi线性偏置中等优秀极高BLOOM, Falcon

选型建议

  • 机器翻译/结构敏感任务:正弦编码或混合编码
  • 内容主导任务(如分类):可学习位置编码
  • 长文本生成:RoPE或ALiBi
  • 轻量化需求:ALiBi(无额外参数)

最新研究进展

  1. 多维位置编码:针对图像/视频数据开发空间-时间联合编码框架,如Vision Transformer中的2D位置编码。
  2. 动态位置感知:微软提出神经微分方程位置编码,实现连续位置建模。
  3. 外推性增强:Meta的随机化位置采样策略提升RoPE在超长序列的表现。
  4. 无损压缩编码:Google研究二进制位置表示,用$O(\log n)$空间替代$O(n)$存储。

代码实现示例

正弦位置编码(PyTorch)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import torch
import math

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

此函数生成符合Transformer原论文的位置编码矩阵。

RoPE旋转位置编码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class RotaryEmbedding(torch.nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2).float() / dim))
    
    def forward(self, x):
        seq_len = x.shape[1]
        t = torch.arange(seq_len, device=x.device).type_as(self.inv_freq)
        freqs = torch.einsum('i,j->ij', t, self.inv_freq)
        return torch.cat((freqs, freqs), dim=-1)

def rotate_half(x):
    x1, x2 = x.chunk(2, dim=-1)
    return torch.cat((-x2, x1), dim=-1)

def apply_rotary_pos_emb(x, cos, sin):
    cos = cos[:, :, None, :]
    sin = sin[:, :, None, :]
    return (x * cos) + (rotate_half(x) * sin)

此实现通过复数旋转高效计算相对位置。


推荐学习资源

  1. 基础理论:https://arxiv.org/abs/1706.03762 - 位置编码的原始论文
  2. 相对位置编码:https://arxiv.org/abs/1803.02155 - 相对位置的开山之作
  3. RoPE详解:https://arxiv.org/abs/2104.09864 - 旋转位置编码理论
  4. ALiBi论文:https://arxiv.org/abs/2108.12409 - 线性偏置位置编码
  5. 视频教程:https://www.bilibili.com/video/BV1xR1RY9ECm - 三维可视化讲解正弦编码

位置编码技术如同给Transformer装上了“序列之眼”,使其能洞察语言与时空的秩序。随着大模型向百万级上下文迈进,位置编码的创新仍将是突破长文本处理边界的关键力量。

question

要是token的维度不是偶数怎么办?

💬 评论