从多头注意力到完整 Transformer Block:结构、原理与训练逻辑的系统讲解
本文假设你已经了解词向量、位置编码以及单头 Self-Attention 的基本思想。在这个基础上,我们继续向前推进:为什么单头注意力不够用?多头注意力到底在做什么?Attention 之后为什么还要接一个前馈网络?残差连接和层归一化为什么是深层 Transformer 能够训练的关键?最终的 Transformer Block 又如何组成一个完整的语言模型?
我们会尽量把这些问题放在同一条主线里讲清楚:以一个"预测下一个词"的语言模型为例,从输入词向量开始,一步一步说明数据如何被加工,参数如何被训练,以及每个组件为什么必须存在。
一、从任务出发:Transformer 在语言模型中做什么
1. 语言模型的核心任务
为了让讨论有明确的目标,我们采用现代大语言模型最常见的训练任务之一:预测下一个词。
给定一句话的前半部分,例如:
今天天气真好,我想去
模型的任务是预测下一个最可能出现的词,例如:
公园
这看起来只是"猜下一个词",但要做好这件事,模型需要理解词义、语法、指代关系、常识推理,甚至语气和语境。因此,Transformer 并不是简单地查表,而是要把原始词向量逐层加工成更适合预测的语义表示。
2. Transformer 的整体流水线
一个典型的 Decoder-only 语言模型,前向过程大致可以概括为:
词编号 → 词嵌入与位置编码 → 多个 Transformer Block → LM Head → 下一个词的概率分布
更具体地说:
- 输入文本首先被切成 token,并转换为整数编号。
- 每个 token 编号通过词嵌入矩阵变成一个稠密向量。
- 为了让模型知道 token 的位置,再加入位置编码。
- 得到的向量矩阵进入第一个Transformer Block。
- 经过多个 Block 的逐层加工后,得到更高层的语义表示。
- 最后的 LM Head 将某个位置的隐藏向量映射到词表大小的 logits。
- 通过 Softmax 得到下一个词的概率分布。
如果输入序列的形状是 [batch_size, seq_len, d_model],那么经过每一个 Transformer Block 后,形状通常保持不变,仍然是 [batch_size, seq_len, d_model]。也就是说,Block 的工作不是改变序列长度或向量维度,而是不断改变每个 token 向量内部的语义内容。
3. 每个 Block 的作用是什么
很多初学者会问:如果最终目标是预测下一个词,那么每一个 Block 到底在干什么?是不是每个 Block 都在独立预测下一个词?
通常不是这样。每个 Block 并不直接输出最终答案,而是负责把当前表示加工得更好。可以把整个模型想象成一条流水线:
- 浅层 Block 可能更多处理词法、局部搭配、基础语法关系。
- 中层 Block 可能开始理解短语结构、指代关系、句法依赖。
- 深层 Block 可能更多参与语义推理、常识联想、上下文逻辑整合。
当然,这种"浅层做什么、深层做什么"的说法是一种经验性总结,并不是人工硬编码的规则。模型在训练过程中会根据最终损失函数自动调整每一层的参数。但整体规律是明确的:层数越多,信息被反复加工的次数越多,表示就越有机会从字面信息抽象为更复杂的语义信息。
接下来我们会专门研究每个Block内部有什么机制,干了什么。
二、多头注意力:让模型从多个视角理解序列
1. 单头 Self-Attention 的回顾
在单头 Self-Attention 中,每个 token 的输入向量会分别被投影成 Query、Key、Value 三类向量:$Q = XW_Q,\ K = XW_K,\ V = XW_V$。然后计算注意力输出:
$$\text{Attention}(Q, K, V)=\text{Softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$
其中 $d_k$ 是 Query 和 Key 的维度。缩放因子 $\sqrt{d_k}$ 的作用是避免点积过大导致 Softmax 梯度消失。
这个公式的直观含义是:每个 token 用自己的 Query 去和其他 token 的 Key 计算相关性,得到一组注意力权重,然后用这些权重对其他 token 的 Value 做加权求和。最终,每个 token 都会融合来自整个序列的信息。
2. 单头注意力的局限
单头注意力虽然已经能够完成"token 之间交换信息"的任务,但它有一个天然限制:一次 Attention 计算只能形成一种注意力分布。
考虑句子:
苹果发布了新款手机,它的屏幕很亮。
当模型处理"它"这个词时,可能需要同时关注多种信息:
- “它"指代的是"手机”,这是指代关系。
- “屏幕"是"手机"的属性,这是语义属性关系。
- “苹果"在这里可能是公司名,而不是水果,这是实体识别问题。
- “发布了新款手机"构成一个动宾结构,这是语法结构问题。
如果只有一个注意力头,模型只能把这些需求压缩到同一个注意力分布中。它也许能学到某种折中的关注方式,但很难同时兼顾多种关系。
多头注意力的思想很简单:既然一种关注模式不够,那就让多个注意力头并行工作。每个头可以学习不同的关注偏好。最终,这些头的结果被合并起来,形成更丰富的表示。
3. 多头注意力的基本结构
假设输入向量维度 $d_{model} = 512$,使用 $h = 8$ 个注意力头,通常让每个头的维度为 $d_k = d_v = d_{model} / h = 64$。
多头注意力的过程可以分成四步。
第一步,为每个头准备独立的投影矩阵。对于第 $i$ 个头,有投影矩阵 $W_i^Q, W_i^K, W_i^V$,其中 $W_i^Q, W_i^K \in \mathbb{R}^{d_{model} \times d_k}$,$W_i^V \in \mathbb{R}^{d_{model} \times d_v}$。
第二步,每个头独立计算注意力:$\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)$。
第三步,把所有头的输出拼接起来:$\text{Concat}(\text{head}_1, \text{head}_2, \dots, \text{head}_h)$。由于每个头输出 64 维,8 个头拼接后仍然是 512 维。
第四步,对拼接结果再做一次线性投影:
$$\text{MultiHead}(Q, K, V)=\text{Concat}(\text{head}_1, \dots, \text{head}_h)W_O$$
其中 $W_O \in \mathbb{R}^{hd_v \times d_{model}}$。当 $hd_v = d_{model}$ 时,$W_O$ 的形状就是 $[512, 512]$。
因此,多头注意力不是把维度无限扩大,而是在总维度不变的前提下,把表示空间拆成多个子空间,让不同的头在不同子空间中学习不同的注意力模式。
4. 多头分工是训练出来的,不是人工指定的
一个常见误解是:我们在训练前告诉模型,第一个头负责语法,第二个头负责语义,第三个头负责实体。
实际上并不是这样。模型初始化时,所有头的参数都是随机初始化的。训练过程中,模型唯一的监督信号来自最终任务损失,比如"下一个词预测"的交叉熵损失。
如果某个注意力头学会了关注主谓关系,并且这种关注方式有助于降低损失,它就会被强化。如果另一个头学会了关注指代关系,也会被强化。最终不同头表现出不同"专长”,是训练过程中自然涌现的结果,而不是人为预设的规则。
因此,多头注意力的正确理解是:
多头注意力允许模型在不同的表示子空间中,并行学习多种 token 之间的关系模式。
三、前馈网络:每个词位置的非线性加工单元
1. FFN 的本质就是两层感知机
在 Attention 之后,Transformer Block 中通常还会接一个 Feed-Forward Network,简称 FFN。
FFN 的标准形式是
$$\text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2$$
其中 $\max(0, z)$ 是 ReLU 激活函数。现代模型也常用 GELU、SiLU 等激活函数,因此更一般地可以写成 $\text{FFN}(x) = \sigma(xW_1 + b_1)W_2 + b_2$。
从结构上看,FFN 就是一个两层线性网络,中间夹一个非线性激活函数。因此,如果把 FFN 理解为"两层感知机"或"两层 MLP”,这个直觉是完全正确的。
所谓"Feed-Forward”,意思是数据只朝一个方向流动,没有循环结构。这与 RNN 不同。RNN 会按时间步循环处理序列,而 Transformer 中的 FFN 只是对当前位置的向量做一次前向变换。
2. 为什么 Attention 之后还需要 FFN
很多初学者会问:Attention 已经很强了,它能让每个词看到整个上下文,为什么还需要 FFN?
关键在于,Attention 和 FFN 的分工不同。
Attention 的主要职责是"交流"。它让每个 token 根据当前上下文,从其他 token 那里聚合信息。它擅长的是动态路由和信息检索:判断当前 token 应该关注哪些位置,以及关注多少。
但是,Attention 的核心聚合操作本质上是加权求和。虽然 Softmax 本身是非线性的,但从特征变换能力来看,它主要完成的是"把已有信息重新混合"。如果要让模型获得更强的非线性表达能力,就需要 FFN。
FFN 的主要职责是"加工"。每个 token 在经过 Attention 后,已经得到了融合上下文的新表示。接下来,这个 token 需要独自经过一个非线性变换,把混合后的信息进一步提炼成更有用的特征。
可以这样理解:
- Attention 像开会讨论:每个词从其他词那里获取信息。
- FFN 像会后独立思考:每个词根据讨论结果,独自整理、提炼、抽象这些信息。
没有 Attention,token 之间无法交换信息;没有 FFN,模型缺少足够的非线性特征变换能力。二者缺一不可。
3. FFN 为什么要先升维再降维
在标准 Transformer 中,FFN 通常会把中间维度扩大到原来的 4 倍。例如 $d_{model} = 512$,而 FFN 的中间隐藏层维度为 $d_{ff} = 2048$。也就是:
$$x \in \mathbb{R}^{512}\rightarrow xW_1 + b_1 \in \mathbb{R}^{2048}\rightarrow\text{ReLU}\rightarrow(xW_1 + b_1)W_2 + b_2 \in \mathbb{R}^{512}$$
为什么要这样做?
一个直观的几何解释是:低维空间中难以线性分割的复杂结构,在高维空间中更容易被分开。这类似 Cover 定理的思想:复杂模式在高维空间中更容易变得线性可分。
假设原始特征空间只有 512 维,很多复杂语义关系可能纠缠在一起。FFN 先把它映射到 2048 维,相当于把数据展开到一个更宽阔的空间里。在这个空间中,ReLU 可以更容易地对不同特征进行非线性切割。随后,再通过第二个线性层把结果压缩回 512 维,供后续层使用。
因此,FFN 的"升维—激活—降维"结构,可以看作一次在高维空间中进行的复杂非线性特征变换。
此外,从容量角度看,更大的中间维度意味着更多可用于编码知识的隐藏神经元。如果 FFN 的中间层只有 512 个神经元,它能承载的知识模式数量相对有限。扩大到 2048,相当于增加了模型存储知识模式的容量。这与"FFN 是参数化记忆"的视角一致——更大的 FFN 通常会增强模型存储复杂模式的能力。
4. FFN 为什么逐个位置独立处理
FFN 有一个重要特性:它是 position-wise 的,也就是逐位置独立应用。
假设输入序列有 $N$ 个 token,每个 token 是 512 维。FFN 会把这 $N$ 个 512 维向量分别送入同一个两层网络。词与词之间在 FFN 内部不直接交换信息。
这看起来似乎和"上下文理解"矛盾:如果 FFN 独立处理每个词,那它怎么利用上下文?
关键点在于:进入 FFN 之前,每个 token 已经经过了 Attention。此时的每个 token 向量已经不是原始词向量,而是融合了上下文信息的向量。
举例来说,在句子"苹果发布了新款手机"中,“苹果"经过 Attention 后,可能已经吸收了"发布"“手机"等上下文信息。FFN 要做的,不是再次去看其他 token,而是对这个已经包含上下文的"苹果"表示进行深度加工。
所以,FFN 的"独立处理"不是忽略上下文,而是在上下文信息已经被 Attention 聚合之后,对每个位置的新表示做独立变换。
5. FFN 与"记忆"的关系
近年来有一种有影响力的观点认为,Transformer 中的 FFN 可以被看作一种键值记忆库。
FFN 的形式是 $\text{FFN}(x) = W_2 \sigma(W_1x + b_1) + b_2$。我们可以把它粗略地理解为:
- $W_1$ 的每一行像一个"键”。
- 输入 $x$ 与这些键匹配,决定哪些隐藏神经元被激活。
- $W_2$ 的对应列像"值”。
- 被激活的神经元会输出相应的知识或特征。
例如,在大量文本中反复出现"巴黎是法国的首都"这样的模式后,FFN 的某些参数组合可能会记住这种关联。当输入中出现与"巴黎"相关的特征时,FFN 可能更容易激活与"法国"“首都"等概念相关的输出方向。
当然,这种"记忆"不是数据库式的精确存储,而是分布式地编码在大量参数中的统计模式。它更适合理解为一种参数化知识,而不是显式查找表。
但无论是否采用"记忆"这个说法,FFN 都是 Transformer 中提供非线性表达能力和知识存储能力的重要部分。
四、残差连接与层归一化:深层网络的稳定机制
1. 深层网络为什么需要保护机制
现代 Transformer 往往有几十层甚至上百层的block连接。如果没有特殊设计,深层网络很容易遇到两个问题:
第一,梯度消失或梯度爆炸。反向传播时,误差要从最后一层一路传回第一层。如果每层都让梯度乘上一个很小或很大的数,经过几十层后,梯度可能变得极小或极大,导致训练失败。
第二,数值分布不稳定。每一层的输出都会成为下一层的输入。如果某一层的输出数值忽大忽小,下一层就需要不断适应这种变化,训练会非常困难。
为了解决这些问题,Transformer 在每个子层周围引入了两个关键机制:
- 残差连接,用于保持信息和梯度的稳定传递。
- 层归一化,用于稳定每一层内部的数据分布。
2. 残差连接的核心公式
残差连接的形式非常简单:
$$\text{Output} = x + F(x)$$
其中 $x$ 是进入某个子层之前的输入,$F(x)$ 是这个子层的输出。对于 Transformer Block 来说,$F(x)$ 可以是多头注意力,也可以是 FFN。
这个结构的直觉是:不要把原始输入完全丢掉,而是在原始输入的基础上,加上这一层学到的"变化量”。也就是说,网络不是直接学习最终输出 $y$,而是学习一个增量 $\Delta x = F(x)$,最终输出为 $x + \Delta x$。
如果某一层暂时学不到有用的东西,最理想的情况是它输出接近 0,那么 $x + F(x) \approx x$,网络至少可以保持恒等映射,不会让信息在这一层被破坏。
3. 残差连接为什么能帮助梯度传播
残差连接之所以重要,不仅是因为前向传播时保留了原始信息,更因为它在反向传播时提供了一条稳定的梯度路径。
考虑一个简化的标量情况。假设 $y = x + F(x)$,对 $x$ 求导:
$$\frac{\partial y}{\partial x}=1 + \frac{\partial F(x)}{\partial x}$$
如果没有残差连接,即 $y = F(x)$,那么 $\frac{\partial y}{\partial x} = \frac{\partial F(x)}{\partial x}$。如果 $F(x)$ 代表很多层复杂网络,那么反向传播时梯度可能会经过许多小于 1 的导数连乘,最终迅速趋近于 0。
而有了残差连接后,导数中包含一个常数项 1。即使 $F(x)$ 的梯度很小,甚至接近 0,梯度仍然可以通过这个 1 传回去。
在向量情况下,这个 1 对应的是恒等矩阵。也就是说,残差连接提供了一条近似无损的梯度通道。这就是所谓"梯度高速公路"的数学本质。
4. 残差连接为什么用加法,而不是拼接
一个很自然的问题是:如果残差连接是为了保留原始信息,那为什么不把原始输入和子层输出拼接起来,例如 $\text{Concat}(x, F(x))$?
拼接确实可以保留原始信息,但它有几个问题。
第一,维度会不断增长。假设输入是 512 维,子层输出也是 512 维。拼接一次变成 1024 维,再拼接一次变成 1536 维或 2048 维。如果堆叠几十层,维度会迅速膨胀,显存和计算量都难以承受。
第二,加法天然符合"增量学习"的语义。残差连接的思想是:新表示 = 旧表示 + 需要修正的部分。加法直接表达了这种"在原基础上叠加变化量"的关系。
第三,加法能产生恒等梯度路径。对于 $y = x + F(x)$,求导时会得到 $1 + F’(x)$。这个 1 是残差连接能够稳定梯度传播的关键。拼接操作没有这种简洁的恒等梯度结构。如果拼接后还要用线性层压缩维度,梯度路径会变得更复杂,也可能引入新的参数和优化难度。
因此,Transformer 采用加法而不是拼接,是表达简洁性、维度稳定性和梯度传播效率的综合结果。
5. Transformer 的残差连接和 XGBoost 的残差是一回事吗
有些学习者会联想到 XGBoost 中的"残差"概念:前一棵树预测错误,后一棵树继续拟合残差。这个联想很敏锐,但二者并不相同。
XGBoost 属于 Boosting 方法。它的核心思想是串行纠错:第一个模型预测,计算预测值与真实值之间的残差,第二个模型专门拟合这个残差,第三个模型继续拟合剩余残差。这里的"残差"是预测误差,模型明确以误差为拟合目标。
Transformer 中的残差连接来自 ResNet 的思想。它的公式 $y = x + F(x)$ 中的 $F(x)$ 并不是在拟合"预测误差",而是在学习"输入需要增加的变换量"。它是一种网络结构设计,而不是显式的误差修正目标。
因此可以这样区分:
- XGBoost 的残差是训练目标:下一棵树拟合上一棵树的误差。学霸继续去学习上一个学霸的错题本。
- Transformer 的残差是结构机制:每一层在原始输入基础上叠加特征增量,并保证梯度能够稳定回传。防止中途出现一个学渣把训练毁了。
两者都叫"残差",但数学目的和使用方式不同。
6. 层归一化在做什么
层归一化,即 Layer Normalization,简称 LayerNorm,是对某个向量内部的数值分布进行标准化。
对于一个 $d$ 维向量 $x = (x_1, x_2, \dots, x_d)$,LayerNorm 首先计算均值 $\mu = \frac{1}{d}\sum_{i=1}^{d}x_i$ 和方差 $\sigma^2 = \frac{1}{d}\sum_{i=1}^{d}(x_i - \mu)^2$,然后进行标准化:
$$\hat{x}_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}}$$
最后加入可学习参数:$\text{LayerNorm}(x)_i = \gamma_i \hat{x}_i + \beta_i$,其中 $\gamma_i$ 和 $\beta_i$ 是可学习的缩放和平移参数,$\epsilon$ 是一个极小常数,用于防止除以 0。
LayerNorm 的作用是:把每个 token 向量的数值分布拉回到一个相对稳定的范围,避免某些维度过大、某些维度过小,从而让后续层更容易训练。
可以把它理解为:
在网络内部,对每个 token 的特征向量进行局部标准化,以稳定训练过程。
7. 为什么 Transformer 常用 LayerNorm 而不是 BatchNorm
BatchNorm 是在 batch 维度上统计同一个特征的均值和方差。对于图像任务,同一个特征通道在一批图片上统计分布是合理的。
但在自然语言处理中,BatchNorm 有几个不太适合的地方:
第一,不同句子长度可能不同,batch 内统计不够稳定。
第二,语言模型常常使用较小的 batch size,尤其是在推理阶段,batch 统计不可靠。
第三,自回归生成是一个 token 一个 token 进行的,依赖 batch 统计会带来麻烦。
LayerNorm 不依赖 batch。它只对单个样本中的单个 token 向量做归一化,因此更适合序列模型,也更适合训练和推理阶段保持一致的行为。
五、完整 Transformer Block:从组件到整体
1. Pre-Norm 结构
原始 Transformer 论文中使用的是 Post-Norm,也就是先做子层计算,再做归一化:
$$x = \text{LayerNorm}(x + \text{Sublayer}(x))$$
但在现代大语言模型中,更常见的是 Pre-Norm,也就是先归一化,再进入子层:
$$x = x + \text{Sublayer}(\text{LayerNorm}(x))$$
Pre-Norm 的训练通常更稳定,因此被广泛采用。
一个典型的 Pre-Norm Transformer Block 可以写成:
$$x_{mid} = x + \text{MultiHeadAttention}(\text{LayerNorm}_1(x))$$
$$x_{out} = x_{mid} + \text{FFN}(\text{LayerNorm}2(x{mid}))$$
用更流程化的语言描述就是:
- 输入 $x$。
- 对 $x$ 做 LayerNorm。
- 将归一化后的结果送入 Multi-Head Attention。
- 将 Attention 输出与原始 $x$ 相加(残差连接),得到中间结果。
- 对中间结果做 LayerNorm。
- 将归一化后的结果送入 FFN。
- 将 FFN 输出与中间结果相加(残差链接),得到 Block 输出。
- 把输出传给下一个 Block。
在许多模型中,经过所有 Block 之后,还会再接一个最终的 LayerNorm,然后进入 LM Head。
2. 为什么 Attention 和 FFN 要分开设计,而不是揉成一个大黑盒
一个非常深刻的问题是:既然 QKV、FFN、LM Head 最终都通过同一个损失函数训练,为什么不直接设计一个巨大的网络,把所有参数揉在一起,让模型自己学?
理论上,足够大的网络确实可能逼近很多复杂函数。但是,网络结构并不只是数学上的函数逼近器,它还承载了人类对任务结构的先验假设。这种先验假设在机器学习中常被称为归纳偏置。Transformer 的结构设计,就是一种非常有效的归纳偏置。
第一,分工明确降低学习难度。 Attention 处理 token 与 token 之间的信息交换,FFN 处理单个 token 位置上的特征变换。如果让一个没有结构的大黑盒同时完成这两件事,它必须自己在参数中摸索出"哪些参数负责跨 token 交互,哪些参数负责局部特征变换"。这会增加学习难度,也可能需要更多数据和参数。而 Transformer 明确告诉模型:先做一次跨 token 的动态信息聚合,再做一次逐位置的非线性特征加工。
第二,分开设计更利于计算优化。 Attention 需要计算 token 之间的相关性,通常涉及序列长度平方级别的计算 $O(N^2 d)$,其中 $N$ 是序列长度,$d$ 是模型维度。FFN 则是逐位置计算,主要是大规模矩阵乘法 $O(N d d_{ff})$,不涉及 token 之间的两两交互。将二者分开,可以让底层计算库和硬件分别优化这两类操作。例如,Attention 可以使用专门的高效注意力实现,FFN 可以使用高效的矩阵乘法内核。
第三,分开设计也更有利于解释和干预。 Attention 和 FFN 分开后,研究者可以更容易地观察模型内部行为。例如,可以可视化 Attention 权重,观察模型在生成某个词时关注了哪些位置;又如,可以分析 FFN 中某些神经元是否响应特定概念。如果把模型揉成一个完全无结构的黑盒,这些分析和干预都会变得更困难。
3. Block 和 Layer 的区别
初学者常常困惑:一个 Block 看起来只有几个步骤,为什么人们说 Transformer 有几十层、上百层?
一个 Transformer Block 通常包含两个子层:Multi-Head Attention 子层和 Feed-Forward Network 子层。所谓"几十层 Transformer",通常是指把这样的 Block 重复堆叠几十次。例如,一个 96 层模型,可能就是指 96 个 Transformer Block。
当然,不同论文和代码库对"层"的叫法可能略有差异。有时"一层"指一个 Block,有时也可能指一个子层。但现代大模型语境下,说"多少层"通常指的是多少个 Block。
4. 为什么堆叠更多 Block 会得到更深的理解
堆叠 Block 的意义在于反复加工表示。
第一层看到的输入是原始词向量加上位置编码。它只能在比较初级的特征上做注意力匹配和非线性变换。但是,第二层看到的输入已经不是原始词向量,而是第一层加工后的结果。第一层可能已经编码了局部搭配、词性关系、简单句法信息。第二层就可以在这些更抽象的特征上继续建立关系。
以此类推:
- 第 1 层:基于原始 embedding 做初步关系建模。
- 第 5 层:可能形成更稳定的短语或句法表示。
- 第 20 层:可能编码更复杂的语义角色和上下文依赖。
- 第 50 层:可能参与常识推理、风格理解、长距离逻辑关联。
这不是一条严格的人工规则,而是层级特征提取和大规模训练共同作用的结果。层数堆叠拉长了信息加工路径,使模型有机会从浅层模式逐渐过渡到深层模式。
5. 关于残差连接的常见误区
残差连接加上的不是 Q、K 或 V。 多头注意力中,Q、K、V 是中间投影量。残差连接加上的不是它们中的任何一个,而是 Attention 的最终输出——经过多头拼接和输出投影后的结果。也就是说,$x_{mid} = x + \text{MultiHeadAttention}(x)$,而不是 $x + Q$、$x + K$ 或 $x + V$。
LayerNorm 不是只在输入处做一次。 LayerNorm 不是一次性的数据预处理。它在每个 Block 内部都会出现:Pre-Norm 结构中,Attention 前有一次 LayerNorm,FFN 前也有一次。这样做的目的是反复稳定每一层输入的数值分布。
FFN 不是可选项。 没有 FFN,模型会缺少重要的非线性变换能力和知识容量。Attention 负责动态聚合信息,FFN 负责对聚合后的信息进行深度加工。二者共同构成 Transformer Block 的核心。
六、输出层 LM Head 与端到端训练
1. LM Head 是什么
Transformer Block 的输出仍然是 $d_{model}$ 维向量。如果任务是预测下一个词,我们需要把这个向量转换成词表上的概率分布。
这个转换层通常称为 LM Head,也就是 Language Modeling Head。它本质上是一个线性层:$\text{logits} = hW_{LM}$,其中 $h \in \mathbb{R}^{d_{model}}$,$W_{LM} \in \mathbb{R}^{d_{model} \times V}$,$V$ 是词表大小。
如果 $d_{model} = 4096$,词表大小 $V = 50000$,那么 LM Head 的权重矩阵形状就是 $[4096, 50000]$。输出是一个长度为 50000 的向量,每个元素对应词表中一个词的 logit。再经过 Softmax,就得到概率分布。
2. LM Head 与词嵌入矩阵的权重共享
很多模型会采用一个经典技巧:让 LM Head 的权重与输入词嵌入矩阵共享。
假设输入词嵌入矩阵为 $E \in \mathbb{R}^{V \times d_{model}}$。输入阶段,token id 为 $t$ 时,会取出 $E$ 的第 $t$ 行作为词向量。输出阶段,如果共享权重,则 logits 可以写成 $\text{logits} = hE^T$。也就是说,输入时使用的词向量矩阵,在输出时转置后作为分类矩阵使用。
这样做有几个好处:
- 减少参数数量。
- 增强输入表示和输出分类之间的对称性。
- 在某些情况下有助于训练稳定。
当然,并不是所有模型都强制使用权重共享,但这是一个非常常见的工程选择。
3. LM Head 不是静态矩阵
需要特别说明的是,LM Head 并不是一个固定不变的静态矩阵。它和 Attention 中的 $W_Q, W_K, W_V, W_O$,以及 FFN 中的 $W_1, W_2, b_1, b_2$ 一样,都是模型参数,会在训练过程中被更新。
它之所以看起来"像词嵌入矩阵一样重要",是因为它连接了模型内部语义空间和最终输出词表空间。但它仍然是训练出来的,不是一开始就固定好的。
4. 端到端训练:所有参数为同一个损失函数服务
Transformer 的训练不是分阶段孤立训练每个模块。不是先训练 Attention,再训练 FFN,再训练 LM Head。
真实过程通常是:
- 输入一批数据。
- 数据经过所有 Block 和 LM Head,完成一次前向传播。
- 根据预测结果和真实标签计算损失函数,例如交叉熵损失。
- 从损失函数开始反向传播。
- 梯度依次传回 LM Head、最后一个 Block、倒数第二个 Block,直到第一个 Block。
- 优化器根据梯度更新所有相关参数。
也就是说,训练是一条完整的链路。所有参数共同服务于同一个目标:降低最终任务的损失。
因此,Attention 中的 $W_Q, W_K, W_V$ 并不是为了让注意力权重看起来合理而训练,FFN 中的 $W_1, W_2$ 也不是为了让中间特征看起来漂亮而训练。它们都是为了最终预测下一个词更准确而被优化。
5. QKV 参数的训练动机是什么
对于 Attention 来说,训练的目标不是"注意力分布好看",而是"注意力分布有助于降低预测误差"。
如果模型在某个位置预测错了,反向传播会告诉 Attention 参数:当前的 Query、Key、Value 投影方式可能导致了错误的信息聚合。例如,模型本应让"它"更多关注"手机",却错误地关注了其他词。于是梯度会调整 $W_Q, W_K, W_V$,使下一次类似输入下的注意力分布更有利于正确预测。
因此,QKV 的训练导向可以概括为:
学会生成合适的 Query、Key、Value,使 Attention 能够提取对最终预测有用的上下文信息。
6. FFN 参数的训练动机是什么
FFN 的训练目标也不是孤立的。它负责对 Attention 聚合后的结果做进一步加工。如果模型因为缺乏某种常识或语义转换能力而预测错误,梯度会传回 FFN,调整 $W_1, W_2, b_1, b_2$。
例如,如果模型看到"巴黎"后应该更容易预测"法国"相关内容,但当前 FFN 没有给出足够强的相关特征,那么训练过程会逐步加强相关参数,使得类似输入更容易激活有利于正确预测的输出方向。
因此,FFN 的训练导向可以概括为:
学会对融合了上下文的 token 表示进行非线性变换,并编码有助于最终预测的知识与模式。
七、总结
通过上面的讨论,可以把 Transformer Block 的关键组件总结为以下几点:
第一,Multi-Head Attention 让模型在多个子空间中并行学习不同的注意力模式。它负责 token 之间的信息交流。
第二,FFN 是一个逐位置的两层感知机。它负责在每个 token 位置上进行非线性特征变换,并承担重要的知识表达能力。
第三,残差连接通过 $x + F(x)$ 保留原始信息,并提供稳定的梯度传播路径。它学习的是增量,而不是显式预测误差。
第四,LayerNorm 对单个 token 的特征向量进行标准化,稳定网络内部数值分布。它是深层 Transformer 能够稳定训练的重要条件。
第五,现代模型常采用 Pre-Norm 结构:$x = x + \text{Sublayer}(\text{LayerNorm}(x))$,这种结构训练更稳定。
第六,Transformer 的整体训练是端到端的。QKV、FFN、LayerNorm、LM Head 都通过同一个损失函数联合优化。