一个被忽视的基本问题

2017年,当Vaswani等人在论文《Attention is All You Need》中提出Transformer架构时,他们做出了一个看似合理的假设:模型应该能够外推到比训练时更长的序列。原论文中写道:“我们推测它可能外推到比训练时遇到的序列更长的序列。”

然而,这个假设在随后的五年里一直缺乏系统性的验证。直到2022年,来自华盛顿大学和Meta AI的研究团队才首次系统性地回答了这个基本问题:Transformer到底能不能处理比训练时更长的输入序列?

答案令人意外:如果使用原始的正弦位置编码(Sinusoidal Positional Encoding),模型的外推能力非常有限——大约只能处理比训练长度多50个token的序列。一旦超出这个范围,困惑度(perplexity)就会急剧上升,模型性能断崖式下跌。

这个发现揭示了Transformer架构中一个长期被忽视的缺陷:位置编码的选择直接决定了模型能否处理比训练时更长的序列。而这个问题在实际应用中极为重要——当我们希望模型处理更长的文档、更复杂的对话时,往往受限于训练时设定的上下文长度。

为什么注意力机制需要位置信息

要理解位置编码的外推性问题,首先需要理解为什么Transformer需要位置编码。

自注意力机制的核心操作是计算序列中所有位置之间的关系。给定一个输入序列 $x_1, x_2, ..., x_n$,自注意力计算每个位置的查询(Query)与所有位置的键(Key)之间的相似度:

$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$

这个计算过程具有一个关键特性:排列等变性(Permutation Equivariance)。如果我们打乱输入序列的顺序,输出序列也会以相同的方式被打乱,但每个位置的计算结果不会改变。换句话说,自注意力机制本身无法区分"猫追狗"和"狗追猫"——它看到的是相同的词集合,却丢失了顺序信息。

graph LR
    subgraph "原始输入"
        A1["猫"] --> A2["追"] --> A3["狗"]
    end
    
    subgraph "打乱输入"
        B1["狗"] --> B2["追"] --> B3["猫"]
    end
    
    A1 & A2 & A3 --> C["自注意力<br/>(排列等变)"]
    B1 & B2 & B3 --> C
    
    C --> D["无法区分顺序!"]

这正是位置编码存在的意义:为模型注入序列顺序信息。原始Transformer采用的做法是在输入嵌入层添加位置向量:

$$x'_i = x_i + p_i$$

其中 $p_i$ 是位置 $i$ 对应的位置编码向量。

graph TD
    A["输入Token序列"] --> B["词嵌入层"]
    C["位置索引<br/>1, 2, 3, ..."] --> D["位置编码层"]
    B --> E["加法操作"]
    D --> E
    E --> F["带位置信息的嵌入"]
    F --> G["Transformer层"]

正弦位置编码的理论困境

原始Transformer提出了两种位置编码方案:可学习的位置编码和正弦位置编码。Vaswani等人倾向于正弦位置编码,理由是它"可能允许模型外推到更长的序列"。

正弦位置编码的定义如下:

$$PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right)$$$$PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right)$$

其中 $pos$ 是位置索引,$i$ 是维度索引,$d$ 是嵌入维度。

从理论上讲,这个设计确实具有一定的外推潜力。正弦函数是周期函数,理论上可以处理任意位置索引。然而,实验结果表明,这种理论优势在实际中几乎不存在。

问题出在哪里?当模型在训练时只见过位置0到L-1的编码,在推理时遇到位置L及以后的编码时,这些新位置的编码虽然是有效的正弦值,但它们代表的特征空间是模型从未学习过的。模型学会了如何利用前L个位置的模式进行推理,却不知道如何解释第L+1个位置的信息。

graph TD
    subgraph "训练阶段"
        A1["位置 0~L-1<br/>模型见过"]
        A2["位置编码分布<br/>已学习"]
    end
    
    subgraph "推理阶段"
        B1["位置 0~L-1<br/>正常工作"]
        B2["位置 L~∞<br/>从未见过!"]
    end
    
    A1 --> A2
    B1 --> C["性能正常"]
    B2 --> D["困惑度崩溃"]

2022年的ALiBi论文提供了具体的量化数据:使用正弦位置编码的模型在WikiText-103数据集上训练,训练序列长度L=512时,模型只能在L+50的位置保持稳定性能。一旦超出这个范围,困惑度就会线性上升。当序列长度达到L+500时,困惑度已经从20左右恶化到超过40——模型的预测能力几乎崩溃。

相对位置编码的兴起

正弦位置编码属于绝对位置编码:每个位置有一个唯一的向量表示。另一种思路是相对位置编码:不编码位置的绝对值,而是编码两个位置之间的相对距离。

graph TD
    subgraph "绝对位置编码"
        A1["位置1"] --> A2["位置2"] --> A3["位置3"] --> A4["位置4"]
        A1 -.->|PE₁| B1["嵌入₁"]
        A2 -.->|PE₂| B2["嵌入₂"]
        A3 -.->|PE₃| B3["嵌入₃"]
        A4 -.->|PE₄| B4["嵌入₄"]
    end
    
    subgraph "相对位置编码"
        C1["Token₁"] --> C2["Token₂"] --> C3["Token₃"] --> C4["Token₄"]
        C1 & C2 -.->|距离-1| D1["偏置"]
        C1 & C3 -.->|距离-2| D2["偏置"]
        C1 & C4 -.->|距离-3| D3["偏置"]
    end

T5相对位置偏置

T5模型采用了一种简洁的相对位置编码方案。它不再添加位置嵌入,而是在计算注意力分数时添加一个可学习的偏置项:

$$\text{score}(q_i, k_j) = q_i^T k_j + b_{i-j}$$

其中 $b_{i-j}$ 是基于相对距离的可学习偏置。模型为每个相对距离学习一个偏置值,例如距离为0、1、2…的偏置各不相同。

这种设计带来了意想不到的好处:由于相对距离的概念可以自然扩展,T5偏置的外推性明显优于正弦编码。实验显示,T5偏置可以将有效外推范围扩展到约2倍训练长度。但代价是计算效率——T5偏置需要更多的内存和参数,训练速度下降约50%。

旋转位置编码(RoPE)

RoPE是目前最主流的位置编码方案,被GPT-NeoX、LLaMA、PaLM等主流模型广泛采用。它的核心思想是通过旋转矩阵来编码位置信息。

graph TD
    A["输入向量 x"] --> B["线性变换 Wq/Wk"]
    B --> C["分组成二维对"]
    C --> D["旋转操作<br/>R(mθ)"]
    D --> E["输出向量<br/>携带位置信息"]
    
    subgraph "旋转矩阵 R(mθ)"
        F["cos(mθ)  -sin(mθ)"]
        G["sin(mθ)   cos(mθ)"]
    end

RoPE的数学表达如下。对于位置 $m$ 的查询向量和位置 $n$ 的键向量:

$$f_{\{q,k\}}(x_m, m) = \begin{pmatrix} \cos m\theta_1 & -\sin m\theta_1 & 0 & 0 & \cdots \\ \sin m\theta_1 & \cos m\theta_1 & 0 & 0 & \cdots \\ 0 & 0 & \cos m\theta_2 & -\sin m\theta_2 & \cdots \\ 0 & 0 & \sin m\theta_2 & \cos m\theta_2 & \cdots \\ \vdots & \vdots & \vdots & \vdots & \ddots \end{pmatrix} W_{\{q,k\}} x_m$$

其中 $\theta_d = 10000^{-2d/|D|}$ 是第d维的旋转角度。

RoPE的一个关键特性是:两个向量的内积只依赖于它们的相对位置差:

$$f_q(x_m, m)^T f_k(x_n, n) = g(x_m, x_n, m-n)$$

这意味着注意力分数只与相对距离有关,而不与绝对位置有关。这种设计使得RoPE具有比正弦编码更好的外推性,但仍然存在局限:实验表明,RoPE模型大约可以在训练长度的1.1-1.2倍范围内保持性能。

ALiBi:简单而强大的解决方案

2022年ICLR会议上发表的ALiBi(Attention with Linear Biases)提出了一种极简的解决方案:完全抛弃位置嵌入,直接在注意力分数上添加线性惩罚。

ALiBi的核心公式极其简洁:

$$\text{softmax}(q_i K^T + m \cdot [-(i-1), ..., -2, -1, 0])$$

其中 $m$ 是每个注意力头特定的斜率,是一个固定值而非可学习参数。对于8个注意力头,ALiBi使用几何序列:$1/2^1, 1/2^2, ..., 1/2^8$。

这个设计的直观含义是:距离当前查询位置越远的键,受到的惩罚越大。这给模型注入了一种"近因偏好"(recency bias)——更关注附近的token。不同的注意力头使用不同的斜率,允许模型同时关注不同范围的上下文。

graph LR
    A["输入序列"] --> B["词嵌入层"]
    B --> C["无位置编码!"]
    C --> D["注意力计算<br/>Q × K^T"]
    D --> E["添加线性偏置<br/>m × distance"]
    E --> F["Softmax归一化"]
    F --> G["注意力权重"]

ALiBi的效果令人惊讶。在WikiText-103上的实验表明:

  • 训练长度L=512的ALiBi模型,在推理长度1024时可以达到与训练长度L=1024的正弦编码模型相当的困惑度
  • 训练长度L=1024的ALiBi模型,可以稳定处理长度2048甚至更长的序列
  • 最优性能通常出现在约2倍训练长度处,之后性能开始缓慢下降,但不会像正弦编码那样崩溃

更重要的是,ALiBi几乎不增加计算开销。它只是在注意力掩码上添加常数偏置,不引入额外的可学习参数,训练速度与正弦编码几乎相同。

位置插值:让RoPE突破长度限制

尽管ALiBi在外推性上表现出色,但RoPE仍然是目前应用最广的位置编码方案。如何在保留RoPE的同时扩展上下文长度?2023年提出的Position Interpolation(PI)给出了答案。

PI的核心思想非常直观:如果模型在训练时只见过位置0到L-1,那么在推理时,我们不直接使用扩展后的位置索引,而是将新位置"压缩"回原始范围。

具体而言,如果要将上下文从L扩展到L’,对于新的位置索引 $m' \in [0, L')$,我们使用:

$$m = m' \cdot \frac{L}{L'} = \frac{m'}{s}$$

其中 $s = L'/L$ 是扩展比例。这相当于将新的位置线性插值到原始的位置空间中。

graph TD
    subgraph "原始训练空间 [0, L]"
        A1["位置 0"] --> A2["位置 L/2"] --> A3["位置 L"]
    end
    
    subgraph "扩展后空间 [0, L']"
        B1["位置 0"] --> B2["位置 L"] --> B3["位置 2L"] --> B4["..."] --> B5["位置 L'"]
    end
    
    B1 -.->|"插值"| A1
    B2 -.->|"插值"| A2
    B3 -.->|"插值"| A3
    B5 -.->|"插值"| A3
    
    style A3 fill:#f9f,stroke:#333
    style B5 fill:#bbf,stroke:#333

PI的优势在于,它让模型始终工作在"熟悉"的位置空间中。所有位置编码都来自训练时见过的范围,只是分布更密集了。实验表明,使用PI只需要在约10亿token上进行微调(约1000步),就能让LLaMA模型从2048扩展到32768的上下文长度。

然而,PI也有其局限性。线性缩放所有频率会导致高频信息被过度压缩,影响模型对局部关系的理解能力。

NTK感知插值与YaRN

为了解决PI对高频信息的压缩问题,研究者提出了多种改进方案:

NTK-aware插值不统一缩放所有频率,而是调整基础频率:

$$b' = b \cdot s^{\frac{|D|}{|D|-2}}$$

这样,高频分量被缩放较少,低频分量被缩放较多,保留了模型捕捉局部模式的能力。

YaRN方法结合了NTK-by-parts插值和温度缩放,是目前效果最好的RoPE扩展方案之一。其温度缩放公式:

$$\sqrt{\frac{1}{t}} = 0.1 \ln(s) + 1$$

这个经验公式在LLaMA系列模型上表现良好。

LongRoPE:迈向极限的探索

2024年,微软研究团队提出的LongRoPE将上下文扩展推向了新高度:首次将预训练LLM的上下文窗口扩展到2048K(约200万)token。

graph TD
    A["原始模型<br/>上下文 L"] --> B["第一步<br/>扩展到 128K"]
    B --> C["第二步<br/>扩展到 512K"]
    C --> D["第三步<br/>扩展到 2048K"]
    
    subgraph "LongRoPE核心技术"
        E["非均匀缩放"]
        F["进化算法搜索"]
        G["渐进式扩展"]
    end
    
    E & F & G --> B & C & D

LongRoPE的核心创新在于发现了RoPE中的"非均匀性"——不同维度的位置编码对模型的重要性不同。基于这一发现,LongRoPE采用进化算法搜索每个维度的最优缩放因子,而非使用统一缩放。

NoPE:一个令人深思的发现

2023年的一篇论文发现了一个反直觉的结果:在Decoder-only的Transformer语言模型中,完全不使用位置编码(NoPE)的模型,在某些任务上的长度泛化能力甚至优于使用显式位置编码的模型。

这背后的原因是,Decoder-only架构中的因果掩码(causal mask)本身就隐含了位置信息——第i个位置只能看到第1到第i个位置,这种单向信息流本身就编码了一种相对顺序。

graph TD
    subgraph "Decoder因果掩码"
        A1["位置1"] --> A2["位置2"] --> A3["位置3"] --> A4["位置4"]
    end
    
    A1 --> B1["可见: 仅位置1"]
    A2 --> B2["可见: 位置1,2"]
    A3 --> B3["可见: 位置1,2,3"]
    A4 --> B4["可见: 位置1,2,3,4"]
    
    B1 & B2 & B3 & B4 --> C["因果掩码隐含位置信息!"]

NoPE的发现启示我们:位置编码的设计需要考虑模型架构的特点。对于Decoder-only模型,过度显式的位置编码可能反而干扰了模型自然学习位置关系的能力。

位置编码方法对比

下表总结了主要位置编码方法的特点:

方法 类型 外推能力 计算开销 可学习参数
正弦位置编码 绝对 弱(~50 tokens)
可学习位置编码 绝对 无(无法外推)
T5偏置 相对 中等(~2x)
RoPE 相对 中等(~1.1x)
ALiBi 相对 强(>2x)
NoPE 隐式 中等 最低

实践中的选择考量

选择位置编码方案时,需要考虑几个关键因素:

训练成本与推理需求的平衡。如果训练资源有限,但希望模型能够处理长文本,ALiBi是一个极具吸引力的选择。它允许在较短序列上训练(节省计算资源),同时保持对长序列的处理能力。

与现有架构的兼容性。RoPE已被LLaMA、Mistral等主流模型采用,如果要在这些模型基础上进行扩展,PI、YaRN等方法更为适用。

任务特性。对于需要精确位置信息的任务(如代码生成),可能更适合使用显式的位置编码。对于主要依赖局部上下文的任务,ALiBi或NoPE可能表现更好。

开放问题与未来方向

尽管位置编码研究取得了显著进展,仍有许多开放问题值得探索:

外推性的理论界限。ALiBi在约2倍训练长度处达到最优性能,之后性能下降。这个"2倍"是固有的理论限制还是可以通过更好的设计突破?

位置编码与模型能力的交互。不同的位置编码如何影响模型的推理能力、数学能力、代码能力?这方面的系统性研究仍然不足。

多模态场景的位置编码。当模型需要同时处理文本、图像、音频时,如何设计统一的位置编码?不同模态的"位置"概念如何对齐?

结语

位置编码的外推性问题是Transformer架构中的一个基础性问题。从正弦位置编码的外推困境,到ALiBi的简洁解决方案,再到RoPE的插值扩展技术,这个领域的研究揭示了深度学习模型泛化能力的一个重要维度。

令人感慨的是,这个在Transformer诞生时就存在的问题,直到五年后才被系统性地研究和解决。这提醒我们,在追逐更大参数、更多数据的热潮中,一些基础架构层面的问题可能被忽视,而这些问题的解决往往能带来更加本质的改进。

位置编码的选择不再是简单的工程决策,而是需要综合考虑训练效率、推理需求、任务特性的架构选择。理解这些方法的原理和权衡,对于构建高效的序列模型至关重要。