跳至内容

位置编码全解析:让 Transformer 拥有“顺序感”

了解 Transformer 如何跟踪词序,对比正弦、可学习、相对、RoPE 与 ALiBi 编码,并查看 PyTorch 实现。
更新 2026年8月14日  · 14分钟

用 AI 探索

ChatGPTClaudePerplexity

想象一下,您在读一本小说,但页面上的每个词都被随机打乱。即使您认识每个单词,情节也会完全丢失,因为词语的顺序决定了含义。工程师最初设计大语言模型(LLM)时,也面临着类似的难题:当模型的核心机制是并行处理时,如何让它理解词语的先后顺序?

这正是位置编码发挥作用的地方。本文将探讨位置编码的内部工作原理,以及它们如何赋予 Transformer 对顺序的感知。我们将从最初的正弦公式,到现代的旋转嵌入,逐步梳理其演进,并介绍如何在您的下一个机器学习项目中实现它。如果您对底层架构还不熟悉,建议先阅读我们的Transformer 工作原理指南。

什么是位置编码?

位置编码是一种让神经网络理解输入数据顺序的技术。它相当于一组坐标,表示一个 token 的相对或绝对位置,并与标准的数据表示合并。

文本进入神经网络之前,词语会被转换为连续的数值形式,称为嵌入。然而,标准嵌入只捕捉语义信息:它们不会告诉您一个词在文本中的位置。您可以通过我们的课程Introduction to Embeddings with the OpenAI API了解这一过程的具体机制。

位置编码是直接加到这些 token 嵌入上的一个额外数学层。通过将语义表示与位置“印记”结合,Transformer 模型可以区分出现在句子不同部分的相同词语。

置换不变性问题

序列数据高度依赖顺序。在自然语言中,“the dog bit the man”和“the man bit the dog”含义截然不同。

自注意力中的置换不变性问题

历史上,循环神经网络(RNN)长短期记忆网络(LSTM)天然可以处理这一点。它们按顺序处理 token,意味着网络在完成第一个词的计算后,才会“摄取”第二个词。类似地,卷积神经网络(CNN)使用局部滑动窗口处理数据,从而捕捉像素或相邻词语的空间排列。

Transformer完全放弃顺序处理。它们并行处理所有 token。Transformer 的核心引擎是自注意力机制,它会在同一时间为序列中的每个 token 两两计算关系得分。从数学上讲,自注意力具有置换不变性。如果您打乱输入序列,自注意力机制对词对输出的注意力得分将完全相同。

如果没有保序机制,模型将完全丧失序列信息。语义会坍缩为一个无序的“词袋”。位置编码通过强制改变输入向量来解决置换不变性问题,使得自注意力机制对位置 1 的 token 与位置 10 的 token 给出不同的反应。

位置编码如何工作?

位置编码通过在输入 token 向量到达自注意力层之前进行数学修改来起作用。这确保模型在计算关系时同时考虑含义与位置。

直观一点看:把标准 token 嵌入想象成会议上的姓名牌。姓名牌告诉您此人是谁,但他在会场的哪里并不会改变他是谁或与他人的关系。位置编码就像在姓名牌上加了一个座位号。两者结合后,您既知道此人是谁,也知道他坐在哪里,从而为他可能发生的互动提供了上下文。

在 Transformer 中,这种结合通常通过逐元素相加来实现。模型将一个词的语义嵌入向量,与相同维度的一个位置编码向量相加。得到的向量包含一种微妙的调制,后续层会学会将其解释为空间坐标。

示例计算

看一个简化示例。假设我们的嵌入空间维度为 4。我们要处理位于序列位置 0 的词“DataCamp”。

  1. 语义嵌入:神经网络取回“DataCamp”的嵌入,可能是 [0.51, -0.22, 0.88, 0.14]。
  2. 位置编码:位置公式为位置 0 生成一个坐标向量。本例中,假设它计算得到 [0.00, 1.00, 0.00, 1.00]。
  3. 组合:将两向量逐元素相加。
  4. 最终输入:前向传播接收 [0.51, 0.78, 0.88, 1.14]。

即使相同的 token “DataCamp”稍后出现在位置 5,其位置编码向量也会不同。因此,对自注意力机制而言,最终的输入向量将看起来完全不同。

正弦位置编码

最初的“Attention Is All You Need”论文提出了一种用基础三角函数生成位置向量的巧妙方法。这种方法无需任何可学习权重,完全依赖固定的数学函数。

数学基础

正弦位置编码使用不同频率的正弦和余弦函数来编码位置信息。原始公式规定,对于给定位置(pos)和嵌入向量中的特定维度索引(i),编码按如下方式计算:

  • 偶数维(2i):PE(pos, 2i) = sin(pos / 10000^(2i/dmodel))

  • 奇数维(2i+1):PE(pos, 2i+1) = cos(pos / 10000^(2i/dmodel))

在该公式中,dmodel是嵌入向量的总维度。沿着向量维度从索引 0 到 dmodel 前进时,正弦函数的波长呈几何级数增长。

优势与性质

这种几何级数的频率带来了若干明显优势。

  1. 正弦与余弦输出严格被限定在 -1 到 1 之间。这种有界性确保位置编码不会在数值上压过语义嵌入。
  2. 这些函数具有周期性。由于三角加法公式,线性变换可以很容易地把未来位置(pos + k)的编码表示为当前位置(pos)的函数。这个性质天然地让模型能够学习相对位置编码。
  3. 正弦编码使用固定参数。不需要可学习权重,大幅降低内存开销。由于其依赖连续的数学函数,模型在理论上具有外推能力,意味着它可以为训练中未见过的更长序列映射位置坐标。

可视化

为了理解正弦编码,将其可视化为热力图会有所帮助。

正弦位置编码矩阵

可视化的 x 轴表示嵌入维度大小,y 轴表示 token 的位置。

左侧较低的维度在负值与正值之间快速振荡,使其能够区分相邻的 token 位置。随着维度索引增大,波长变长,编码变化更为缓慢。这些维度捕捉更远距离上的位置差异。

对于图中展示的 50 个位置,许多高维看起来几乎是均匀的竖条。这是因为它们的波长很长,在这样较短的序列范围内,正弦值接近 0、余弦值接近 1,而非严格的 0 与 1。因此,交替的条纹反映的是相邻的正弦—余弦维度,而不是简单的二进制编码。对于更长的序列,这些维度也会开始显著变化。

要点是,不同频率为模型在多个尺度上提供位置信息:变化快速的维度捕捉相邻 token 之间的细粒度差异,变化缓慢的维度则跟踪更长序列中的整体位置。

可学习的位置编码

虽然固定的数学公式很优雅,但现代深度学习架构往往依赖数据来学习最优表示。可学习的位置嵌入将布局的重任完全交给训练阶段。

概念与实现

与其用正弦和余弦函数硬编码位置值,可学习的位置嵌入把位置坐标视为常规的可训练参数。

模型会初始化一个完全空白的嵌入矩阵,其中每一行对应一个特定的序列位置。在标准的反向传播训练循环中,网络会与语义 token 嵌入一同更新这些位置权重,以最小化整体损失函数

比较优势

可学习的位置嵌入的首要优势是极强的灵活性。它可以完全自由地学习最适合特定数据集的精确位置表示。BERT 与 GPT-2 等架构因其高度适应性和在下游任务上的强劲表现,成功推广了这种方法。

局限与挑战

可学习的位置嵌入最大的局限是序列长度的硬边界。如果一个模型用最多 2,048 个可学习位置向量训练,那么它在物理上无法处理 2,049 个 token 的文档。

这种限制严重削弱了长度外推能力,并且往往需要代价高昂的再训练来扩展上下文窗口

相对位置编码

随着模型演进以处理更长的文档,工程师们意识到,词语的绝对位置往往不如其与其他词之间的相对距离重要。

向相对位置的概念转变

思考短语“the rapid advancement of AI”。无论该短语出现在文档的最开头还是结尾,“advancement”和“AI”之间的语法关系都完全一致。相对位置编码放弃绝对网格坐标,转而只关注相互作用 token 之间的距离偏移。

在注意力机制中的实现

为实现相对编码,工程师直接修改注意力得分的计算,而不是在网络最开始就改变输入嵌入。

当计算“query”矩阵与“key”矩阵之间的注意力得分时,会加入一个额外的可学习偏置项,表示相对距离。此修改保证了文本的平移不变性。若想更深入了解这些矩阵如何运作,请参阅我们关于LLM 中注意力机制的指南。

实践权衡

这种方法能带来高度准确的上下文理解,但会引入严重的计算开销。为每个注意力头计算独特的相对距离矩阵会显著增加内存消耗,也会使用于加速文本生成的内部缓存机制变得更复杂。

绝对 vs 相对位置信息

在绝对与相对编码之间做选择,取决于具体任务。

  • 绝对编码在空间布局严格、且优先考虑快速执行时表现出色。
  • 相对编码在长文本自然语言处理中更胜一筹,因为语法结构完全依赖局部上下文距离,而非绝对文档坐标。

旋转位置嵌入(RoPE)

在不断完善 Transformer 架构的过程中,研究者提出了旋转位置嵌入(RoPE)。它结合了绝对与相对位置编码的优点,并迅速成为业界标准。

创新方法

RoPE 通过旋转变换统一了绝对位置与相对距离。RoPE 不是把向量加到嵌入上,或给注意力得分添加沉重的偏置,而是将嵌入向量映射到复平面上,并按特定角度旋转。该角度的大小完全由 token 在序列中的绝对位置决定。

RoPE 位置编码

数学洞见

在二维空间中,旋转通过标准的二维旋转矩阵实现。对于更高维度,RoPE 仅需把嵌入维度分组成对,并基于绝对位置索引对每一组应用独特的二维旋转。

由于旋转矩阵的几何性质,旋转后的 query 向量与旋转后的 key 向量的点积最终只取决于它们之间的相对角度。因此,RoPE 利用绝对位置映射,自然地编码了 token 之间的相对距离。

RoPE 与正弦编码

如上图所示,正弦编码会改变原始向量的大小与方向;而 RoPE 保留了大小信息,仅需两个位置之间的夹角即可理解它们的相对距离。

线性偏置注意力(ALiBi)

与依赖复杂旋转数学的 RoPE 不同,另一种称为线性偏置注意力(ALiBi)的方法采取了完全不同的思路。

简洁与高效

ALiBi 完全摒弃了在初始 token 嵌入中加入位置信息的想法。词嵌入在进入 Transformer 时保持完全不变。

相反,ALiBi 在注意力计算的最后一步介入。在注意力对数值通过softmax 函数之前,ALiBi 会按两 token 之间的距离减去一个与之成比例的静态惩罚。两个词相距越远,从其注意力得分中减去的惩罚就越大。

性能

这种方法实现非常简单且高效。其最大优势是对长度外推任务极其有效。使用 ALiBi 在 1,024 token 序列上训练的模型,可以轻松在长度加倍的序列上生成连贯文本而不崩溃。

若您对用于快速文本生成与推理的其他先进技术感兴趣,请参阅我们的投机解码指南。

何时使用哪种位置编码

从您的目标出发,再选择适配的方法——有时是一种,有时是多种组合。

  • 需要简单、零参数的基线:正弦(固定公式,无需训练)。
  • 序列长度固定,且想在特定数据集上追求最佳性能:可学习。
  • 需要处理超出训练长度的更长序列:在能外推的技术中,RoPE 最为稳妥。
  • 语法取决于 token 间距离而非其绝对位置:相对或 RoPE。
  • 在构建现代的通用 LLM:RoPE。
  • 长度外推是首要目标,且希望实现最简单:ALiBi。
  • 想要相对位置的好处,但不想承受内存与缓存开销:RoPE(相对编码有益但更昂贵)。

实践实现与架构考量

将理论落地到实践,需要了解如何把位置编码集成到真实代码库中,并管理架构层面的限制。

在 Transformer 中实现位置编码

在 PyTorch 等框架中为 Transformer 添加位置编码,开发者通常会创建一个专门的模块。该模块会一次性生成编码矩阵,并将其注册为 buffer,这样在反向传播时就不会被意外更新。

下面是在前向传播中引入正弦编码的标准实用实现。编码仅根据正弦与余弦公式计算一次,训练期间从不改变,因此它们被存储为 buffer,而不是可学习参数(也因此不会增加训练成本)。

import torch
import torch.nn as nn
import math

class PositionalEncoding(nn.Module):
    def __init__(self, d_model: int, max_len: int = 5000):
        super().__init__()
        
        pe = torch.zeros(max_len, d_model)
        position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
        
        # Calculate the division term for frequencies
        div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
        
        # Apply sine to even indices and cosine to odd indices
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)
        
        pe = pe.unsqueeze(0)
        
        # Register as a buffer
        self.register_buffer('pe', pe)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # Add positional encoding directly to the input embeddings
        seq_len = x.size(1)
        x = x + self.pe[:, :seq_len, :]
        return x

__init__中,模块预计算到 max_len 个位置的编码表:position是一列索引(0、1、2、……),而 div_term是频率,等价于 1 / 10000^(2i/d_model),因此低维对应快波,高维对应慢波。

对偶数维(0::2)应用 sin,对奇数维(1::2)应用 cos,即可填充该表。随后 forward 的唯一运行时代码就是:按输入的序列长度切片该表,并与 token 嵌入逐元素相加。注意该模块假设 batch-first 形状 [batch, seq_len, d_model],因此 forward 在第 1 维上切片。

位置偏置与“中间遗失”现象

在映射长序列长度时,一个意料之外的后果是位置偏置。这常常表现为“中间遗失”现象:在处理海量文档时,语言模型往往更容易记住提示开头或结尾的信息,而对中间部分的记忆较差。这似乎很熟悉,因为人类记忆也类似(至少对我来说是这样;别告诉我只有我会把一本书的开头和结尾记得比中间清楚!)。

理论认为,这是因为注意力机制被无关上下文淹没,自然会锚定在早期 token(设定指令)和最新 token(短期记忆中最近)的信息上。为缓解这种偏置,开发者会使用先进的分块策略与语义检索系统。

面向专门领域的位置编码

Transformer 已不再局限于文本。位置编码的理念也迅速适配到多个领域的不同数据类型。

对于视觉 Transformer,图像会被切分为网格补丁。简单的 1D 序列编码无法在二维空间中捕捉空间邻近性。因此,视觉模型经常使用 2D 的可学习位置编码,同时考虑图像补丁的 X 与 Y 坐标。

对于连续时间序列模型也有类似改造,使用专门的编码来跟踪时间距离、季节性和时间戳。

位置编码的进一步研究

随着更大上下文窗口的竞赛加速,优化模型对“位置”的理解仍是机器学习研究中高度活跃且关键的方向。

长度外推与上下文扩展

当今用户希望一次性处理整个代码库或系列小说的海量上下文窗口。由于从零开始在超长序列上训练模型过于昂贵,研究者依赖上下文扩展技术。

例如,位置插值方法会在数学上把更长序列的位置信息压缩进原始训练长度的范围内。像 YaRN 这样的自适应方法会动态调整 RoPE 参数的旋转频率,从而无缝拉伸模型对距离的理解。

没有显式位置编码的 Transformer

令人惊讶的是,一些研究表明显式位置编码并不总是必需的。在仅解码(decoder-only)的因果语言模型中,标准的因果掩码(强制 token 只能回看)会天然泄露时间顺序信息。

这意味着,或许仅通过因果掩码,加上策略性的温度调节与架构调整,就能隐式地学习位置规则。

挑战与未来方向

终极边界凸显了在严格适配(为特定序列长度优化性能)与完美外推(让模型可无限泛化)之间的持久权衡。

新兴研究领域高度聚焦多模态编码。构建能融合 3D 视频坐标、文本与音频流的通用位置表示,是下一代人工智能模型的一个目标。

结语

位置编码弥合了并行处理与序列理解之间的鸿沟,使我们能够构建按顺序处理海量数据的模型。我们探讨了可学习与相对嵌入所带来的极致灵活性,以及 RoPE 与 ALiBi 等现代创新如何在数学优雅与计算效率之间取得平衡。

随着上下文窗口从几千个 token 扩展到数百万个,向神经网络精确告知“事物位于何处”的这一步简单数学操作,仍将是模型设计的核心所在。

如果您想更深入并进行实操练习,建议报名我们的Developing Large Language Models技能路径。

位置编码常见问答

什么是机器学习中的位置编码?

位置编码是一种数学技术,用于为神经网络提供序列中数据的顺序信息。

为什么 Transformer 模型需要位置编码?

与逐步处理数据的传统循环神经网络不同,Transformer 使用自注意力机制同时处理所有数据。由于自注意力天然具有置换不变性,它会把输入当作无序的“词袋”。位置编码通过在模型处理前,直接将序列坐标注入数据来解决此问题。

绝对与相对位置编码有何区别?

绝对位置编码根据 token 在序列中的精确索引为其分配固定坐标。相对位置编码忽略精确的网格位置,转而计算两个相互作用 token 之间的距离,仅关注它们的上下文偏移。

什么是旋转位置嵌入(RoPE)?

RoPE 是一种广泛使用的编码方法,它将 token 嵌入映射到复平面,并按其绝对位置决定的角度进行旋转。当模型计算注意力得分时,两个旋转向量之间的关系完全取决于它们的相对距离。

什么是可学习的位置嵌入?

与采用正弦和余弦等固定数学公式不同,可学习的位置嵌入把空间坐标作为可训练权重处理。模型会初始化一个位置的空白矩阵,并在训练中更新这些坐标,为特定数据集学习最优的空间表示。

主题

热门 Transformer 课程

Tracks

开发大型语言模型

16小时
学习使用 PyTorch 和 Hugging Face 开发大型语言模型(LLMs),运用最新的深度学习和 NLP 技术。
查看详情Right Arrow
开始课程
查看更多Right Arrow