> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/llm_internals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/llm_internals/di-yi-bu-fen-ji-chu-pian/03_components/3.3_position_encoding.md).

# 3.3 位置编码：为什么顺序信息必须显式注入

上一节解释嵌入为何要乘 $\sqrt{d\_{\text{model}}}$ 时，先借用了一个尚未交代的东西：那个值域在 $\[-1, 1]$、随后会被加到嵌入向量上的位置编码。本节交代它从哪里来。

本节只做引子，回答三个问题：不加位置信息时注意力到底丢了什么，为什么是相加而不是拼接，以及位置信息在现代模型中从哪个口子进来。正弦编码的完整频率分析与外推性质留给[第四章](/llm_internals/di-yi-bu-fen-ji-chu-pian/04_position_encoding.md)。

## 3.3.1 置换等变：三行推导与一个数值验证

**无掩码的自注意力对输入顺序是置换等变的**（Permutation Equivariant）：打乱输入的行序，输出也只是跟着换行，每一行的内容不变。

三行推导。设 $P$ 是置换矩阵，输入变成 $X' = PX$。三个投影是逐行做的，因此 $Q' = PQ$、$K' = PK$、$V' = PV$。于是

$$Q'K'^\top = PQ(PK)^\top = P,(QK^\top),P^\top$$

行列被同一个置换重排。逐行 Softmax 与“行列同时置换”可交换，所以 $A' = PAP^\top$，进而

$$A'V' = PAP^\top PV = PAV$$

最后一步用了 $P^\top P = I$。结论：$\text{Attention}(PX) = P \cdot \text{Attention}(X)$。

一个 2 个词元、$d = 2$ 的数值验证。取 $X = \begin{bmatrix}1 & 0\ 0 & 2\end{bmatrix}$，令 $W\_Q = W\_K = W\_V = I$，缩放因子 $\sqrt{2}$。

* 分数 $XX^\top = \begin{bmatrix}1 & 0\ 0 & 4\end{bmatrix}$，除以 $\sqrt{2}$ 得 $\begin{bmatrix}0.7071 & 0\ 0 & 2.8284\end{bmatrix}$。
* 第 1 行 Softmax：$e^{0.7071} = 2.028$，$e^{0} = 1$，权重 $\[0.6698,\ 0.3302]$。
* 第 1 行输出：$0.6698 \times \[1, 0] + 0.3302 \times \[0, 2] = \[0.6698,\ 0.6605]$。
* 第 2 行同理得 $\[0.0558,\ 1.8884]$。

把两行输入对调，输出恰好是上面两行对调，逐位相同。模型看不出“第 1 行在前”这件事。

这与 RNN、CNN 形成对比。RNN 顺序处理，位置天然由时间步携带。CNN 的卷积核本身是平移等变的，单看卷积并不区分绝对位置；它感知的是局部邻接顺序，绝对位置信息主要由填充边界带入。

## 3.3.2 因果掩码是例外

上面的推导有一个前提：注意力没有掩码。带因果掩码时结论不成立。

掩码 $M$ 是一个固定的下三角模式，它并不随输入置换，即 $PMP^\top \neq M$。位置 $i$ 只能看到 ${1, \dots, i}$，能看到的集合大小本身就携带位置信息。

沿用 3.3.1 的数值例子加上因果掩码：第 1 行只能看自己，输出是 $\[1, 0]$；第 2 行不变，仍是 $\[0.0558,\ 1.8884]$。把两行对调后重算，得到第 1 行 $\[0, 2]$、第 2 行 $\[0.6698,\ 0.6605]$，与“输出对调”不同。

所以“Transformer 必须显式注入位置信息，否则无法区分不同顺序的序列”只对**无掩码的双向自注意力**成立。仅解码器模型即使完全不加位置编码也能学到顺序，这条路线称为 NoPE，详见 [4.4 节](/llm_internals/di-yi-bu-fen-ji-chu-pian/04_position_encoding/4.4_alibi_others.md)。显式位置编码在解码器上仍被普遍采用，原因是收敛更快、外推行为更可控，而不是没有它就不工作。

## 3.3.3 相加还是拼接：把分数展开成四项

最直接的注入方式是给每个位置一个向量，与词嵌入**相加**：

$$\text{Input}\_i = \text{Embed}(x\_i) + \text{PE}(i)$$

相加为什么可行，把注意力分数展开就看得见。记内容向量 $e\_i$、位置向量 $p\_i$，则

$$(e\_i + p\_i)^\top W\_Q^\top W\_K (e\_j + p\_j) = e\_i^\top W\_Q^\top W\_K e\_j + e\_i^\top W\_Q^\top W\_K p\_j + p\_i^\top W\_Q^\top W\_K e\_j + p\_i^\top W\_Q^\top W\_K p\_j$$

四项分别是内容对内容、内容对位置、位置对内容、位置对位置。模型可以通过 $W\_Q$、$W\_K$ 让不同的子空间承担不同的项，因此无须把两种信息分开存放。

代价也在这个展开式里：四项混在同一个分数中，无法单独调节。后续工作正是从这里切入，TUPE 与 DeBERTa 把这几项拆成独立的可学习分量。

拼接的代价则是维度。把 $d\_p$ 维位置向量拼到嵌入后面，$d\_{\text{model}}$ 随之变大，而每层参数约为 $12 d\_{\text{model}}^2$（见 3.7.7），开销按平方增长。相加把这笔开销降为零。

## 3.3.4 正弦编码速览：一个 4 维算例

原始 Transformer 用**正弦位置编码**（Sinusoidal Positional Encoding）：

$$\text{PE}(pos, 2i) = \sin\left(\frac{pos}{10000^{2i/d\_{\text{model}}}}\right)$$

$$\text{PE}(pos, 2i+1) = \cos\left(\frac{pos}{10000^{2i/d\_{\text{model}}}}\right)$$

取 $d\_{\text{model}} = 4$ 代入。此时 $i$ 只有 0 和 1 两个取值，对应角频率 $\omega\_0 = 1/10000^{0} = 1$ 与 $\omega\_1 = 1/10000^{0.5} = 0.01$。位置每加一，前两维转过 1 弧度（约 57.3 度），后两维只转过 0.01 弧度（约 0.57 度）：从 $pos = 1$ 的 $\[0.8415,\ 0.5403,\ 0.0100,\ 1.0000]$ 到 $pos = 2$，前两维跳到 $\[0.9093,\ -0.4161]$，后两维只挪到 $\[0.0200,\ 0.9998]$。

这就是“低维转得快、高维转得慢”：每一对维度是一个转速不同的指针，低维分辨相邻位置，高维分辨远距离。前四个位置的完整编码矩阵见 [4.1 节](/llm_internals/di-yi-bu-fen-ji-chu-pian/04_position_encoding/4.1_sinusoidal.md)的表 4-1，本节不重复。

波长 $2\pi/\omega$ 的跨度取决于 $d\_{\text{model}}$。本例只有两档，$2\pi \approx 6.28$ 与 $200\pi \approx 628$；$d\_{\text{model}}$ 取到几百以上时，跨度才接近原论文所写的 $2\pi$ 到 $10000 \cdot 2\pi$，其中后者是一个近似值，精确值见 [4.1.2 节](/llm_internals/di-yi-bu-fen-ji-chu-pian/04_position_encoding/4.1_sinusoidal.md)。

正弦编码还有一条常被引用的性质：$\text{PE}(pos + k)$ 可以写成 $\text{PE}(pos)$ 的线性函数，系数只与 $k$ 有关。它为什么成立、能不能真的换来相对位置感知，在 [4.1 节](/llm_internals/di-yi-bu-fen-ji-chu-pian/04_position_encoding/4.1_sinusoidal.md)推导。

## 3.3.5 位置信息在现代模型中的入口

“位置编码加在输入上”这个说法，对今天的主流模型已经不准确。表 3-5 给出三种入口。

| 模型             | 位置机制       | 进入计算的位置          | 实现线索                                    |
| -------------- | ---------- | ---------------- | --------------------------------------- |
| 原始 Transformer | 正弦编码，不可学习  | 输入端与嵌入相加         | 由公式现算，无参数                               |
| GPT-2          | 可学习的绝对位置嵌入 | 输入端与词嵌入相加        | `wpe`，形状 `[1024, 768]`，与 `wte` 逐位相加     |
| Llama 系列       | RoPE，旋转    | 每层注意力内部，旋转 Q 与 K | 输入端不加任何东西；`config.json` 里是 `rope_theta` |

表 3-5：三种位置信息入口。GPT-2 的 `wpe` 行数等于 `n_positions`（1,024），这也是它上下文长度的硬上限；Llama 的 RoPE 不占嵌入端参数，扩上下文只需改旋转的底数与缩放策略（见 [14.7 节](/llm_internals/di-si-bu-fen-mo-xing-yu-qian-yan-pian/14_future_trends/14.7_long_context.md)）。

共同点只有一条：无论在哪个口子进来，位置信息都必须在注意力打分之前进入计算，否则 3.3.1 的置换等变依然成立。[3.8.2 节](/llm_internals/di-yi-bu-fen-ji-chu-pian/03_components/3.8_gpt_inference_flow.md)在走完整流程时，用的是最便于手算的“输入端相加”方案。
