

在自然语言中,顺序决定一切。
“狗咬人” 是一个普通的事情,而 “人咬狗” 就是一个新闻头条。这两个句子使用完全相同的词元(tokens)--“人”、“狗”、“咬”;但含义却截然相反。同样,“She only told him that she loved him” (她只告诉了他她爱他) 与 “Only she told him that she loved him” (只有她告诉他她爱他) 之间的语义差异,完全由 “only” 这个词的位置决定。
对人类来说,感知这种顺序就像呼吸一样自然,但对于在 2017 年彻底改变了自然语言处理(NLP)领域的 Transformer 架构而言,这却是它最大的缺陷。
Transformer 架构的核心是 Self-Attention 机制。这个名字带有一些误导性,当我们听到 Attention 时,我们会联想到一个按顺序阅读、聚焦的认知过程;然而,Transformer 的自注意力在本质上是对 语义相关性 的度量,而非对 序列位置 的感知。
在没有额外辅助的情况下,Self-Attention 机制会将输入 “人咬狗” 和 “狗咬人” 视为一个 词袋(Bag of Words),它能出色地计算出 “人” 和 “狗” 在语义上高度相关,但它无法分辨出 “人” 是在 “狗” 之前还是之后。它知道 “有哪些词”,却不知道 “这些词在哪里”。
这种天生的 “顺序失忆症” ,源于 Transformer 追求极致并行化所做出的架构上牺牲;为了解决这个核心矛盾,大神们引入了一个巧妙的 “补丁”,即 位置编码(Positional Encoding)。
要理解为什么 Transformer 需要一个外部的 “补丁” 来感知顺序,我们必须首先要知道它所取代的对象:循环神经网络(RNN)。
在 Transformer 出现之前,RNN 及其变体(如 LSTM )是序列处理的事实标准,如同 CV 领域的 CNN 一样,RNN 的架构设计从根本上就与顺序绑定。

RNN 以 顺序方式(sequential manner) 处理输入,一次一个词元,一个词元在时间步 t 的隐藏状态 ,是其输入 和前一个时间步的隐藏状态 的函数:
这种递归结构是 RNN 的核心,信息必须按顺序流经这个 “时间链”。因此,RNN 相当于免费获得了位置信息:第五个词元只能在第四个词元处理完毕后才能被处理。这种模式完美地编码了顺序,但也是它最大的弱点:它无法并行计算,导致训练极其缓慢,并且难以捕捉长距离依赖关系 。
Transformer 架构的出现,就是为了打破 RNN 的顺序依赖,实现大规模并行化,它彻底抛弃了递归,转而使用自注意力机制,“将一个句子作为一个整体(as a whole)来处理” 。
然而,这种并行化是有代价的,自注意力机制在数学上是 **置换等变(Permutation Equivariant)**的。我们来解构自注意力的核心计算:
X,它由 个词元的嵌入向量 组成。问题的“元凶” 就在第 2 步。
想象一下,输入是 ["I", "am", "a", "robot"],模型使用 矩阵来计算 "robot"(在位置 4)的 Query 向量。
现在,我们打乱输入序列,变成 ["robot", "am", "a", "I"]。当模型处理 "robot"(现在在位置 1)时,它仍然使用完全相同的 矩阵进行计算。由于 "robot" 的词嵌入是相同的,它在两个句子中生成的 Query 向量 也是 完全相同 的。
模型无法学习到 “当 ‘robot’ 在第 4 个位置时,它应该这样提问(Query)” 和 “当 ‘robot’ 在第 1 个位置时,它应该那样提问”。模型对所有位置 “一视同仁”。这种对顺序的不敏感性,就是所谓的 置换不变性(技术上是等变性,即输入置换,输出也以相同方式置换)。
唯一的解决方案是:在自注意力机制介入之前,必须让输入 本身就包含位置信息。我们必须 “污染” 原始的词嵌入,使 Embedding("robot") + PE(pos=1) 和 Embedding("robot") + PE(pos=4) 在输入层就变得不同。
这就是位置编码的切入点:它是一种将位置索引(如 1, 2, 3...)转换为高维向量,然后将其注入到词嵌入中的技术。
第一部分主要来聊一下正弦编码。在原版 Transformer 论文 《Attention Is All You Need》 中,作者们提出了一种极其精妙且无需学习的方案来生成位置向量:正弦位置编码(Sinusoidal Positional Encoding) 。
其思想是使用不同频率的正弦(sin)和余弦(cos)函数来生成一个 维的位置向量。对于一个给定的位置 和嵌入维度 (从 0 到 ),编码公式定义如下:
其中:
10000 是一个超参数,用于控制波长范围。乍一看,这个公式非常神秘,为什么是正弦和余弦?可以从下面几个方面来看看函数特性:
这个公式给人最精妙的感觉在于它如何模拟了一个 “多尺度时钟”,或者一个 “连续的二进制计数器” 。下面来分析一下分母
它控制着波的 频率(或波长)
这种设计与 二进制计数 异曲同工,在二进制中,最低有效位(LSB)每 1 个数字就交替一次(0, 1, 0, 1...);次低位每 2 个数字交替一次(0, 0, 1, 1...);更高位则以更慢的频率交替。正弦函数就是这种“交替位”的 “浮点连续对应物”。
位置编码热力图 是将 “序列位置 × 编码维度” 的二维矩阵用颜色映射展示出来,从而可视化模型在每个位置上注入的位置信息结构。

img
通过热力图能够清楚的看到:
结论:
模型不需要理解这个复杂的公式,它只需要学会:通过 “读取” 整个 维的 向量(即同时查看“时针”、“分针”和“秒针”),它就可以获得一个独一无二的(Unique)、代表该词元绝对位置的 “指纹”。
理解了正弦编码的 “是什么” 和 “怎么做” 之后,我们必须回答两个最关键的、也是最反直觉的 “为什么”:
大多数人的困惑是:为什么要把词嵌入(Word Embedding)和位置编码(Positional Encoding)相加?
Input = WordEmbedding + PositionalEncoding按照常规的认知,小朋友都知道不应该把 “把 5 公斤和 30 公里加在一起” ;直观感受,这两种完全不同的信息相加,似乎会相互 “破坏”(damage)或 “污染”(corrupt),为什么不把它们 拼接(Concatenate) 起来呢?这个设计决策背后,应该有三个层面的考量:
因素 | 解释 |
|---|---|
效率问题 | 拼接会使向量维度加倍,如果词嵌入是 512 维,位置编码也是 512 维,拼接后将得到 1024 维,为了将其恢复到模型的标准维度 512,必须额外添加一个线性投影层(Projection Layer),这会引入大量额外的参数和计算开销 |
高维子空间 | “信息破坏” 的直觉在高维空间中并不成立。在高维空间中(例如 ),两个随机选择的向量 “几乎总是近似正交的”(approximately orthogonal)。这意味着,词嵌入向量(代表语义)和位置编码向量(代表顺序)很可能生活在 512 维空间的两个互不干扰的子空间中。尽管它们被 “相加” 到了同一个向量中,但后续的线性变换(如 矩阵)完全可以学会 “独立地” 操作这两个正交的子空间。模型可以学会“关注”向量的某些维度来获取语义信息,同时“关注”另一些维度来获取位置信息。 |
“超集”论点 | 相加是拼接的一种 “超集”(super case);相加方案给予了模型训练(优化过程)最大的灵活性。如果对于某个任务来说,将语义和位置信息严格分离(即拼接)是最好的方案,那么模型在训练过程中 可以学会这样做。例如,模型可以学会将词嵌入的权重集中在前 256 维,同时将位置编码的权重集中在后 256 维,从而在效果上模拟了拼接。因此,相加不是一个硬编码的“妥协”,而是一个更灵活、更通用的选择,它把 “如何组合信息” 这个难题交给了模型自己去学习 |
位置编码的真正巧妙在于一个隐藏特性:它虽然是绝对位置编码(APE),但却极大地方便了模型学习相对位置。《Attention Is All You Need》的作者在论文中提到,他们选择正弦函数的一个原因是,他们假设这能让模型很容易学习到相对位置;因为对于任何固定的偏移量 , 都可以被表示为 的一个 线性函数(linear function) 。
这个 线性函数 到底是什么?它源于三角函数的 “和角公式”,下面使用一个高中数学知识来推演一下这个过程,这里我们先只关注一个频率:
在维度 和 上,位置 的编码向量是:
那么,位置 的编码向量就是:
根据和角公式:
我们将 和 代入,得到:
这可以被写成一个矩阵乘法!
即:
发现了什么?从位置 移动到 的变换,等价于用一个 的 旋转矩阵 去乘以 。这个旋转矩阵 最关键的特点是:它只取决于相对偏移量 ,而与绝对位置 完全无关!
这意味着什么?????
模型要计算 “向右移动 2 个位置”()的变换,无论是从 到 ,还是从 到 ,这个变换(旋转矩阵 )是完全相同的。
自注意力机制可以通过其线性变换( 等)非常容易地学会这个旋转操作,模型只需要学会一个对应于 “相对距离为 2” 的线性变换,就可以在序列中的任何地方复用它。
这就是正弦编码设计的精髓:它用一种编码 绝对位置 的方法,为模型学习 相对位置 提供了极其强大的数学捷径。
位置编码的演进反映了 NLP 领域从固定任务模型向超长上下文大型语言模型的转变。
《Attention Is All You Need》 论文发表后不久,一个问题自然就出现了:为什么要用一个固定的、人为设计的公式?为什么不让模型自己“学习”最好的位置表示呢?
这就是 可学习的绝对位置编码(Learned Absolute Positional Embeddings) 的理念。
nn.Embedding(max_sequence_length, d_model) 层。如果最大长度是 512,模型就创建 512 个 维的向量,并在训练过程中像学习词嵌入一样学习它们。NLP 数据集上可能带来比固定正弦波更好的性能。原版 Transformer 论文确实做过对比实验,发现可学习编码和正弦编码 “产生了几乎相同的结果”,他们最终选择正弦编码,正是因为他们 “假设它能让模型外推到更长的序列”,而 BERT 之所以选择可学习编码,是因为它的设计范式是用于固定长度(如 512)的 fine-tuning,它更关心在特定任务上的 “灵活性”,而非 “长度泛化性”。
另一条发展路线从根本上质疑了最初的假设:也许模型根本不关心 “这个词在绝对位置 5”,它只关心 “这个词在那个词左边 3 个位置” 。这就是 相对位置编码(Relative Positional Encoding, RPE)的理念。
RPE 改变了之前的范式,它不修改输入嵌入,相反,它在自注意力计算的核心 QK^T 注意力分数矩阵上,直接注入一个 “偏置”(bias)。
其中 和 是查询和键的索引, 是一个可学习的偏置,它只取决于两个词元之间的相对距离() 。最后是当今最 SOTA 的选择,它融合了绝对编码和相对编码的优点:旋转位置编码(Rotary Position Embedding, RoPE) 。
RoPE 既不“添加”位置向量,也不“偏置”注意力分数,它 “旋转” 和 向量 。RoPE 的“旋转”操作,就是前面提到的从正弦编码的三角恒等式中推导出的那个 线性变换(旋转矩阵)。RoPE 使用绝对位置( 和 )来执行编码(旋转),但其最终的注意力行为(点积)却只取决于相对位置() 。位置编码的演进,是从一个为 “顺序失忆症” 打上的 “补丁”,演变为 Transformer 架构中(尤其是现代 LLM)最核心、最精妙的设计之一,以下表格总结了本文讨论的四种主要位置编码技术:
特性 (Feature) | 正弦编码 | 可学习编码 | 相对偏置 | 旋转编码 |
|---|---|---|---|---|
核心机制 | “添加”固定的 向量到输入 | “添加”一个可学习的查找表向量 | 在注意力分数 上“添加” 一个可学习的偏置 | “旋转” 和 向量 |
编码类型 | 绝对位置 | 绝对位置 | 相对位置 | 绝对位置 (编码) + 相对位置 (注意力) |
是否可学习 | 否 (Fixed) | 是 (Trainable) | 是 (偏置是可学习的) | 否 (旋转函数是固定的) |
长度外推性 | 良好 | 差 | 良好 | 极好 |
代表模型 | Transformer | BERT, GPT-2 | Transformer-XL | LLaMA, PaLM, Gemma |
没有绝对完美的编码,只有合适的选择,从 BERT 的可学习编码(优先考虑任务灵活性)到 LLaMA 的 RoPE(优先考虑长度泛化性),编码方法的选择深刻地反映了模型的设计哲学。理解这些基本原理,从置换不变性的根源,到高维子空间的组合,再到旋转,对于我们理解和改进当今(及未来)的大型模型的工作原理至关重要。