Transformer|架构演进(4):Position Encoding 系统(1)——理解绝对位置编码

阅读提示: 我们要进入一个重要的环节:位置编码,虽然它看起来没有Attention和FFN看起来那么重要,本质上有点类似于Vocab输入后的再加工环节,但是笔者认为当今大模型现在的进化快速,至今没人知道实际的原理是什么,而影响这个大黑盒的原因可以非常笼统地分为2面:原材料与模型本身。我们考虑去处理原材料,他可以是文本,图像,视频,各种实验数据,从原材料到模型本身去必须要经过一层加工部分,让模型尽可能逼近最佳地对原材料资源的获取,达到目的方向的资源上限,这会非常有挑战性。我们调侃数据处理工为一种dirty work的时候,需要想想它不可或缺的作用。话不多说,我们开始吧。祝食用愉快~🕶️

导言

图 1 正弦编码

在 Vocab 系统里,我们讨论了模型如何把自然语言压缩成 token,再通过 embedding 和 LM Head 在“文本世界”和“向量世界”之间来回转换。

但 token 进入模型之后,还有一个非常关键的问题:

“ Transformer 怎么知道这些 token 的顺序? ”

Tokenizer 只告诉模型“有哪些 token”,embedding 只给每个 token 一个向量。但一句话的意义不仅取决于有哪些词,还取决于这些词出现的顺序。

比如:

狗 咬 人
人 咬 狗

这两个句子包含的 token 很接近,但语义完全不同。

Self-Attention 本身并不天然知道顺序。如果不额外注入位置信息,Transformer 很难区分“谁在前,谁在后”。这就是 Position Encoding / Positional Embedding 要解决的问题。

从 2017 年原始 Transformer 到现代长上下文 LLM,位置编码经历了非常清晰的演化路线:从绝对位置,到相对位置,再到 RoPE 以及围绕 RoPE 的长上下文扩展。

Position Encoding 的几大路线

在正式讲绝对位置编码之前,先给出一张整体地图。

位置编码方法大致可以分成几类。

绝对位置编码

这是最早、最直观的路线。

“ 核心想法是:第 0 个位置、第 1 个位置、第 2 个位置……每个位置都有一个对应的位置向量。模型输入时,把 token embedding 和 position embedding 加起来。 ”

典型方法包括:

原始 Transformer 使用的是固定正弦位置编码。BERT、GPT-2 等模型则大量使用 learned absolute position embedding。

相对位置编码

绝对位置编码告诉模型:这个 token 在第几个位置。

但语言中很多关系更像是相对关系。比如主语和谓语之间相隔多少 token,括号和括号之间距离多远,函数定义和调用之间间隔多长。

因此,后续出现了相对位置方法。它们不直接编码绝对位置,而是在 attention 里加入 query 和 key 之间的相对距离。

典型方法包括:

RoPE

RoPE 是现代 LLM 中最重要的位置编码之一。

它在 attention 的 Q 和 K 上施加与位置有关的旋转。这样 attention score 天然带有相对位置信息。

典型代表包括:

Attention Bias

还有一类方法不显式给 hidden state 添加位置向量,直接给 attention score 加上位置偏置。代表方法是 ALiBi。

ALiBi在 attention score 里加一个和距离成比例的线性惩罚。距离越远,注意力分数越低。

它的目标是提升长度外推能力。

长上下文 RoPE Scaling

“ 现代长上下文模型中,RoPE 仍然很主流。但原始 RoPE 在训练长度之外会遇到外推问题。 ”

于是出现了很多 RoPE scaling 方法,例如:

它们的核心目标是:在不完全重训模型的情况下,把上下文从 2K、4K、8K 扩展到 32K、128K 甚至更长。

Position Encoding 的必要性

要理解位置编码,先要理解一个事实:

“ Self-Attention 本身是 permutation equivariant 的。 ”

简单说,如果我们不加位置编码,只把一组 token embedding 输入 self-attention,那么模型对这些 token 的顺序并不敏感。

Self-Attention 的核心计算是:

然后:

这里的 是输入 token embedding 矩阵,每一行对应一个 token。

如果我们打乱输入 token 的顺序,本质上就是对 的行做一个置换。Self-Attention 的输出也会跟着做同样的置换,但不会知道这个置换本身代表了什么顺序变化。

也就是说,attention 可以建模 token 之间的关系,但它不知道这些 token 原本处在第几个位置。

因此,Transformer 必须额外注入位置信息。

这就是位置编码的动机

绝对位置编码的基本思想

“ 绝对位置编码是最直观的一类方法。 ”

它给每个位置分配一个位置向量:

其中 是最大序列长度。

假设第 个 token 的 token embedding 是:

它的位置向量是:

那么输入 Transformer 的向量就是:

也就是说,绝对位置编码采用的是“相加”方式:

token embedding + position embedding → input representation

这样做以后,同一个 token 出现在不同位置时,进入模型的表示就不同。

例如,“巴黎”出现在句首和句尾时,token embedding 相同,但位置向量不同:

这就给模型提供了简单的顺序信息。

相加 or 拼接?

“ 一个自然问题是:为什么位置向量要和 token embedding 相加,而不是拼接? ”

如果拼接,可以写成:

这样似乎更清楚地区分了 token 信息和位置信息。

当然,相加也有代价:token 信息和位置信息会混在一起,不再显式分离。这也是后续一些论文重新思考 absolute position embedding 的原因。

但从工程角度看,相加非常简单稳定,因此成为最早的主流做法。

Sinusoidal Positional Encoding

2017 年的 Attention Is All You Need 使用的是固定正弦位置编码。

它不是可学习参数,而是一个确定函数。

公式是:

这里:

它的设计方式是:每两个维度组成一组正弦/余弦波,不同维度使用不同频率。

低维使用较高频率,可以区分局部位置;高维使用较低频率,可以表示更长范围的位置变化。

构造流程

可以把正弦位置编码的构造过程拆成四步。

图 2 前50个位置在不同 embedding 维度上的正弦位置编码值

1. 先确定最大长度和 hidden size

假设模型最大长度是 ,hidden size 是 。

我们要构造一个位置编码矩阵:

其中第 行就是位置 的位置向量。

2. 每个位置都要生成一个 维向量

对于每个位置:

都要生成:

3. 每两个维度使用一组 sin/cos

第 维使用 sine:

第 维使用 cosine:

其中:

4. 把位置向量加到 token embedding 上

如果 token embedding 是:

位置编码是:

输入 Transformer 的向量就是:

这样,同一个 token 出现在不同位置时,最终输入向量不同。

不同频率?

“ 如果只用一种频率,位置编码会很容易出现周期性混淆。 ” 可以把正弦位置编码的构造过程拆成四步。

图 3 正弦位置编码不同维度对应不同频率,不同频率覆盖不同位置尺度。

例如只用:

那么随着 增大,sin 值会不断周期性重复。不同位置可能得到相同或非常接近的值。

但语言里的位置关系既有局部关系,也有长距离关系。

模型既需要知道:

所以正弦位置编码使用了一组频率。

高频维度变化快,适合区分局部位置;低频维度变化慢,适合表达长距离位置。

这就是多频率设计的核心价值。

相对偏移

“ 只用 sine 也能表示周期变化,为什么还要 cosine? ”

一个重要原因是:sin 和 cos 可以组成二维旋转空间。

对于某个频率 ,位置 的编码可以写成:

当位置增加一个偏移 时:

这说明:

可以由:

通过一个只和偏移 有关的线性变换得到。

更具体地说,在每个频率对应的二维子空间里,位置增加 相当于旋转一个角度 。

这就是正弦位置编码非常重要的性质:

“ 它虽然是绝对位置编码,但天然包含相对偏移结构。 ”

这也是后来 RoPE 的思想来源之一。RoPE 更进一步,不是把 sin/cos 加到 token embedding 上,而是直接在 Q/K 空间里做旋转,让 attention score 显式依赖相对距离。

从傅立叶视角理解正弦位置编码

正弦位置编码也可以从傅立叶特征的角度理解。

傅立叶分析的核心思想是:复杂信号可以由不同频率的正弦和余弦基函数组合表示。

换句话说,sin/cos 是一组非常基础的“频率基”。

在位置编码里,我们并不是要还原一个连续信号,而是要把离散位置 映射到一个高维空间。使用多频率 sin/cos,相当于给位置加了一组 Fourier features:

这种映射有几个好处。

1. 把一维位置映射到高维周期特征

原始位置只是一个整数:

这个整数本身很难让神经网络直接利用。

傅立叶特征把它展开成多个频率下的响应。模型可以通过后续线性层组合这些频率,学习复杂的位置模式。

2. 多尺度表示

不同频率对应不同尺度。

高频捕捉短距离差异,低频捕捉长距离趋势。

这和傅立叶表示中“高频表示细节,低频表示整体结构”的直觉一致。

3. 有利于外推

因为正弦位置编码是函数形式,不是有限参数表。只要给定任意位置 ,都可以计算:

这让它在形式上可以外推到比训练长度更长的位置。

不过要注意:

“ 函数能计算更长位置,不代表模型一定能正确使用更长位置。 ”

模型是否具备长上下文能力,还取决于训练长度、训练数据、attention pattern、优化过程和任务监督。

为什么底数是 10000?

原始 Transformer 里使用的是:

这个 10000 其实算是一个经验设计。它的作用是控制频率范围。

频率为:

因此,10000 决定了最低频和最高频之间的跨度。

所以 10000 可以理解为一种让频率覆盖从局部到全局的尺度选择。

后来 RoPE 中也有类似的 base 参数,例如很多模型使用:

或者为了长上下文改成更大的 base,例如某些模型会使用更大的 rope theta。

这说明位置编码里的频率范围,其实是长上下文能力的一个重要部分。

Learned Absolute Position Embedding

“ 后来很多模型没有使用固定正弦函数,而是直接学习一个位置 embedding table。 ”

形式是:

其中 是最大上下文长度。

第 个位置的位置向量就是:

输入仍然是:

这种方法叫 Learned Absolute Position Embedding。

BERT、GPT-2 等模型都采用了类似思想。

它的好处是非常直接:位置向量由模型自己学习,不需要人为指定 sin/cos 频率。只要训练数据足够,模型可以学到对任务最有用的位置模式。

在固定长度任务中,learned absolute position embedding 通常非常有效。

比如 BERT 的最大位置长度通常是 512。对于很多分类、抽取、句子匹配任务,512 以内的 learned absolute position embedding 足够好。

GPT-2 使用 learned position embedding,在固定上下文窗口内也表现稳定。

Learned Position Embedding 的 forward 过程

“ 既然这是一个可学习参数,那么你是否好奇它在整个模型的训练过程中是怎么被训练的呢?往下看,先看forward过程。 ”

假设输入序列是:

法国 的 首都 是 巴黎

它的 token embedding 是:

对应的位置 embedding 是:

那么模型真正输入的是:

这些 进入 Transformer,经过多层 attention 和 FFN,最后产生 loss。

Learned Position Embedding 的 backward 过程

训练时,loss 会对输入向量 产生梯度:

因为:

所以对 token embedding 和 position embedding 的梯度是相同路径分出来的:

也就是说,位置向量 会根据它所在位置对最终预测的影响被更新。

如果位置 0 经常承担句首角色,位置 1 经常承担句子早期上下文角色,那么这些位置 embedding 会逐渐学到和这些位置功能相关的表示。

位置向量会被哪些信号更新?

以 causal LM 为例,假设训练句子是:

法国 的 首都 是 巴黎

模型会预测每个位置的下一个 token。

位置 0 的输入会影响后面多个预测;位置 3 的输入会直接影响预测“巴黎”。

因此,位置 embedding 的更新来自所有经过该位置输入向量的 loss 信号。

如果位置 在很多训练样本中出现,它对应的位置向量 会不断被更新。

同时这解释了 learned absolute position embedding 的一个重要问题:

“ 它只会学到训练中出现过的位置分布。 ”

如果训练时很少出现接近最大长度的位置,这些位置的 embedding 会训练不足。

而如果推理时使用超过训练长度的位置,那些位置根本没有 learned embedding。

Learned Absolute 在训练长度以内的效果

Learned position embedding 的优势是灵活。

正弦位置编码预先规定了位置向量的结构,而 learned position embedding 让模型自己决定每个位置应该是什么向量。

如果任务长度固定,训练数据充足,learned absolute position embedding 可以直接优化到任务最需要的位置模式。

比如 BERT 的很多任务都在 512 token 内,模型只需要学好:

在这种固定窗口内,learned position embedding 通常很有效。

它不需要满足 sin/cos 结构,也不需要具备外推性质,只需要在训练窗口内服务好任务目标。这就是它的优势。

正弦编码和 Learned 编码的对比

可以从几个维度比较这两种绝对位置编码。

方法 参数 结构偏置 训练长度内表现 长度外推 典型模型
Sinusoidal PE 无参数 强,多频率 Fourier 特征 稳定 形式上可外推 原始 Transformer
Learned Absolute PE 有参数 弱,完全从数据学 训练长度内强 较弱 BERT、GPT-2

绝对位置编码在 Encoder 和 Decoder 中的不同表现

“ 绝对位置编码在 encoder-only 和 decoder-only 模型中有不同特点。 ”

Encoder-only 模型

BERT 这类 encoder-only 模型通常使用双向 attention。输入长度相对固定,很多任务也在 512 token 内完成。

因此 learned absolute position embedding 在 BERT 中非常自然。对于分类、抽取、匹配任务,这通常就足够。

Decoder-only 模型

GPT 类 decoder-only 模型是自回归生成。它每次根据前文预测下一个 token。

早期 GPT / GPT-2 使用 learned absolute position embedding,也可以工作。

但随着上下文窗口不断变长,learned absolute position embedding 的限制就更明显。

如果训练窗口是 1024,那么模型对 1024 之后的位置没有自然定义。即使扩展表,也需要额外训练。

这也是为什么现代 decoder-only LLM 后来更倾向 RoPE、ALiBi 或其他更适合长度扩展的方案。

绝对位置编码为什么会被后续方法取代?

绝对位置编码解决了 Transformer 的第一个问题:没有顺序感。但它没有很好解决第二个问题:如何建模 token 之间的相对距离。

在短序列任务中,绝对位置足够好。但在长文本、代码、对话、工具调用、长文档 QA 中,模型更需要知道:

“ 当前 token 和另一个 token 相隔多远,它们之间的相对关系是什么。 ”

这个问题更贴近 attention 的结构。

因为 attention 本来就是在计算 token 与 token 之间的关系。

所以,位置编码的第二阶段自然走向了 relative positional encoding。

从绝对位置到现代长上下文

小结

绝对位置编码是 Transformer 位置建模的起点。它的基本思想非常简单:给每个位置一个位置向量,然后和 token embedding 相加。

原始 Transformer 使用固定正弦位置编码。它通过多频率 sin/cos 函数,为每个位置生成一个结构化位置向量。它的一个重要性质是,对于固定偏移 , 可以由 线性表示,这让模型有机会学习相对位置关系。

后来的 BERT、GPT-2 等模型大量使用 learned absolute position embedding。它在训练长度内灵活有效,但最大长度固定,长度外推能力较弱。

绝对位置编码的贡献是明确的:它让 Transformer 获得顺序感。

但它的局限也很明显:相对距离建模不直接,位置和内容纠缠,learned absolute 难以外推到更长上下文。

所以,位置编码的演化自然走向了下一阶段:相对位置编码。

笔者的话

“ 这里是位置编码的第一部分,简单介绍了一下比较有代表性的2种编码方式,后续会聚焦于更加常用的方法。虽然这里绝对位置编码看起来已经较为落后,但是他的编码方式在一些特定领域的任务上还是展现出一定的效果,以巧妙的方式与应用场景结合。 ”

参考文献与延伸阅读

  1. Vaswani et al., 2017. Attention Is All You Need.

原始 Transformer 论文,提出 sinusoidal positional encoding。
https://arxiv.org/abs/1706.03762

  1. Devlin et al., 2018. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding.

BERT 使用 learned absolute position embeddings,典型最大长度为 512。
https://arxiv.org/abs/1810.04805

  1. Radford et al., 2019. Language Models are Unsupervised Multitask Learners.

GPT-2 使用 learned absolute position embeddings。
https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf

  1. Shaw et al., 2018. Self-Attention with Relative Position Representations.

相对位置编码经典工作 https://arxiv.org/abs/1803.02155

  1. Dai et al., 2019. Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.

使用相对位置机制支持跨 segment 长程建模。
https://arxiv.org/abs/1901.02860

  1. Raffel et al., 2020. Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer.

T5 使用 relative position bias。
https://arxiv.org/abs/1910.10683

  1. Su et al., 2021. RoFormer: Enhanced Transformer with Rotary Position Embedding.

提出 RoPE,现代 LLM 中广泛使用。
https://arxiv.org/abs/2104.09864

  1. Press et al., 2022. Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation.

提出 ALiBi。
https://arxiv.org/abs/2108.12409

  1. Chen et al., 2023. Extending Context Window of Large Language Models via Positional Interpolation.

RoPE 长上下文扩展中的 Position Interpolation。
https://arxiv.org/abs/2306.15595

  1. Peng et al., 2023. YaRN: Efficient Context Window Extension of Large Language Models.

RoPE 长上下文扩展方法。
https://arxiv.org/abs/2309.00071