05 · 架构 · 14 min

完整的Transformer

拼接各个部分:多头注意力、前馈网络、归一化、残差连接。

所有这些,就为了这个

现在我们已经有了所有拼图的碎片:

  • 文本变成了 Token(第 02 章)。
  • Token 在语义空间中变成了向量(第 03 章)。
  • 注意力机制让每个向量关注其他向量并重新配置自身(第 04 章)。

现在只需要理解如何将这些碎片组合成一个完整的模型。答案优雅而极简:堆叠。

基本模块

现代 Transformer 是同一个小模块重复 N 次。这个模块包含两个子模块:

  1. 一个多头注意力层,让 Token 之间相互通信。
  2. 一个前馈网络(FFN)——两个线性变换中间夹着一个非线性函数——对每个 Token独立地进行变换。

围绕这两个子模块,还有两个固定结构:

  • 层归一化(LayerNorm)位于每个子模块之前:对向量进行归一化以稳定学习过程。
  • 残差连接围绕每个子模块:模块的输出是输入加上变换结果,而不仅仅是变换结果本身。

按照一个 Token 穿过的顺序,把鼠标依次悬停在下面示意图的六个层级上。每到一层,只问自己一个问题:这个子模块是让 Token 之间互相通信,还是各管各地单独处理每一个?

把鼠标悬停在子模块上以查看它的作用:attention 在 token 之间扩散信息,feed-forward 在局部对其进行变换,归一化与残差稳定整个流程。叠加 32 或 96 次,就构成了 GPT-4 或 Claude。

答案是:这六个层级里,只有一个让信息在 Token 之间流动——多头注意力。其余的全都逐位置、彼此孤立地工作。这就是接下来整章都要记住的分工:注意力负责混合,前馈网络负责变换,归一化和残差负责稳住。除此之外再无别的东西——同样这个模块重复 12 次是 GPT-2 small,重复 96 次就是 GPT-3。

为什么残差连接改变了一切

这可能是这十年中最重要的架构技巧。没有残差连接,堆叠 96 个连续模块意味着将信号通过 96 个级联变换传递。梯度(学习信号)在每一层都会衰减。几层之后,什么都学不到了。

有了残差连接,模块学习的是一个修改量,而不是全面的变换:输出 = 输入 + f(输入)。原始信号始终完整地穿过整个网络,而每个模块都对它进行一点丰富

没有残差连接,深层 Transformer 无法训练。有了它,叠加 100+ 层都不是问题。

FFN,被遗忘的另一半

我们谈注意力机制谈得很多。而 FFN 拥有两倍于注意力的参数量,却鲜有人提及。

在每一层,注意力机制之后,每个 Token 都经过一个MLP

FFN(x) = Linear_2(GELU(Linear_1(x)))

Linear_1 将向量投影到4 倍宽的中间维度(对于 GPT-2 small,通常是 4 × 768 = 3072)。Linear_2 将其带回到原始维度。这种先扩展再收缩的过程,正是模型存储大部分事实知识的地方——专有名词、学到的关联、重复出现的模式。

上面这个写法是 GPT-2 的。近年的模型用 SwiGLU 取代了 GELU:它用三个矩阵而不是两个,扩展倍数则改成接近 8/3 倍,好让参数量保持不变。但原理没变:先扩展,再收缩。

当人们谈论模型有"700 亿个参数"时,绝大多数参数都住在 FFN 里。

位置与因果性

还有两个我们尚未提到的细节:

位置编码。 注意力机制是置换不变的:如果你打乱句子的 Token,注意力会返回同样的结果(只是顺序也被打乱了)。这不是我们想要的。为了让大语言模型知道"猫吃了鱼"和"鱼吃了猫"是不同的,我们在每个嵌入向量中注入位置信息位置编码RoPE、ALiBi……)。目前,RoPE(旋转位置嵌入)是业界惯例。

因果掩码。 正如我们在第 4 章看到的,在生成模型中,每个 Token 只能关注它的前序 Token。因果掩码被应用于注意力矩阵:在 softmax 之前,未来的位置被设为 −∞。这迫使模型去预测,而不是复制

需要多少个模块?

从 GPT-2 到今天,骨架始终没变:一模一样的模块层层堆叠、残差连接、每个子模块前做一次归一化。变化最大的,是规模

模型模块数维度注意力头数参数量
GPT-2 small1276812117M
GPT-2 XL481600251.5B
GPT-3961228896175B
Llama 3 70B8081926470B

更多模块 = 可能进行更多组合推理(每一层都可以建立在前一层的抽象之上)。更大的维度 = 每个 Token 的容量更大。更多的注意力头 = 可以同时提出更多"问题"。

不过"架构是一样的"这个说法也得小心:它在整体蓝图上成立,落到具体零件就不对了。从 2019 年到今天,几乎每一个组件都被换成了更高效的版本:RoPE 取代了学习式位置编码,RMSNorm 取代了 LayerNorm,SwiGLU 取代了 GELU,GQA 取代了经典多头注意力——还不算下文要讲的 Mixture of Experts 变体。图纸相同,零件已全部换过。

输出:从向量到分布

到这一步,最后一个模块为每个位置给出一个数千维的向量。我们如何把它转换回词表上的概率分布?

只需一步。把这个向量乘以一个维度为 (d_model × |vocab|) 的矩阵 W_out,然后应用 softmax。结果:每个位置上有一个关于词表中所有 Token 的概率分布——GPT-2 约 5 万个,Llama 3 约 12.8 万个,GPT-4o 约 20 万个。这就是大语言模型的输出——一个分布。

一个优雅的细节:在许多模型里(GPT-2、Gemma……),W_out 与输入嵌入矩阵共享权重(weight tying)。把 Token 5234 映射到向量的同一变换,反过来运行就把向量映射回 Token 5234 的概率。既节省了参数,又能更好地泛化。大模型(GPT-3、Llama 70B、Mistral……)则相反,把两个矩阵分开:到了那个规模,这点参数开销可以忽略不计,而两个自由矩阵的效果好过一个被绑住的矩阵。

Mixture of Experts:不是所有参数都会激活

最近的模型中出现了一种逐渐占主导地位的架构变体:Mixture of ExpertsMoE)。Mixtral、DeepSeek、Qwen、Llama 4 都采用了它——这一点是确定的,它们的架构都已公开。至于闭源模型(GPT-4、Gemini),我们手上只有泄露和推测:很可能是,但从未被官方证实。每次读到关于专有模型的数字,这个分寸都值得记在心里。

思路是:不再为每个模块只设一个 FFN,而是并行放置多个(通常为 8 到 128 个专家)。对于每个 Token,一个小的路由网络(router)会挑选出两到四个——对该 Token 最相关的那几个。只有这些专家被激活。

后果:一个模型可以拥有 4000 亿"总"参数,但每个 Token 只激活 500 亿。大模型的容量,小模型的计算开销。 这就是 Mixtral 8×7B(470 亿参数)在推理时能够与远比它大的稠密模型一较高下的原因。

代价:显存(VRAM)必须能容纳所有专家(否则就要换入换出),而且路由会给训练带来一层不稳定性。这仍然是非常活跃的研究领域。

简洁的奇迹

整个大厦建立在一个单一的模式之上:重复、归一化、加到自身。没有针对语法的特定结构,没有独立的语义模块,没有硬编码的语言学规则。

Transformer 对语言一无所知。它只知道如何通过观察谁与谁相似来混合向量。

所有的复杂性都从训练中涌现——这就是下一章的主题。

更新于