一、Attention 只是积木的一半
上篇文章讲完了 Attention 的工作原理。
每个 token 向其他所有 token 提问,根据相关性动态加权,输出一个"看过上下文"后的新向量。同一个"苹果",在"我买了一个苹果"里被解读为水果,在"苹果发布了新款 iPhone"里被解读为公司------Attention 让它能看见世界。
但如果你把整个 Transformer 拆开,Attention 只占一半。
另一半是什么?GPT-2 有 12 层,LLaMA 有 32 层,为什么要叠这么多层?每层的信息传递是怎么保证的?如果只靠 Attention,深层网络能训练得动吗?
这篇文章把积木全部摊开。
二、一层 Transformer:开会 + 独思
先看全局。
Transformer 的一层,来来回回就两种运算交替进行:
bash
输入向量
│
▼ LayerNorm(格式对齐)
│ Q, K, V 投影 → Attention → 残差连接
│
▼ LayerNorm(再次对齐)
│ FFN 独立处理 → 残差连接
│
▼ 输出向量(进入下一层)
Attention 让 token 们互相交流,FFN 让每个 token 独立消化。LayerNorm 做格式对齐,残差连接做信息保藏。
代码核心只有四行:
bash
residual = hidden
hidden = residual + attention(layernorm_1(hidden)) # 开会,保留原件
residual = hidden
hidden = residual + ffn(layernorm_2(hidden)) # 独立思考,保留原件
GPT-4、Claude、LLaMA、DeepSeek------内部全是这四行在不断重复,重复 12 次、32 次、80 次。

三、FFN:开完会,该自己想了
3.1 光开会不够
上篇文章里,Attention 让"苹果"向"买"和"一个"发起询问,发现自己在"购买"语义框架里。听见上下文了,这很好。
但听见不等于想明白。
就像你参加了一场讨论会,听了一堆发言,脑子里全是碎片。散会之后你还得回到工位,独自消化:这个"苹果"到底是水果还是手机?
FFN(Feed-Forward Network,前馈网络)就是这一步。
3.2 它在做什么
公式是 FFN(x) = W₂ · GELU(W₁ · x + b₁) + b₂。
W₁ 和 W₂ 是训练时学出来的权重矩阵,一层里所有 token 共用同一组。
三步理解:
bash
输入向量(768 维)
│
▼ 展开:乘 W₁,768 维 → 3072 维
│ 把一页笔记摊开到四页,有更多地方标注
│
▼ 划重点:GELU 激活函数过一遍
│ 正值保留放大,负值不会被清零,而是压低留个痕迹
│ 这和 ReLU 不一样------信息保留更完整
│
▼ 压缩:乘 W₂,3072 维 → 768 维
│ 把四页标注总结回一页精华
│
▼ 输出向量(768 维)
关键特性:FFN 只看自己,不看别人。 "苹果"在做 FFN 时,完全不管旁边"买""一个"在干什么。这和 Attention 正好相反------Attention 是大家一起开会,FFN 是每个人独自思考。
3.3 FFN 为什么像个知识库
研究发现,大模型记住的事实------比如"法国首都是巴黎"------主要存在 FFN 的权重里。
还是"我买了一个苹果"的例子。
Attention 负责找线索:上下文里有"买了",而且和"苹果"匹配度很高,这大概率是个消费场景。
FFN 负责给答案:它从训练时记住的统计规律里调出知识------"买"和"水果苹果"高频共现,"买"和"公司苹果"低频共现。综合上下文,选水果。
Attention 找线索,FFN 给答案。两者缺一不可。
3.4 参数去哪儿了
GPT-2 里,FFN 占 45.5% 的参数,Attention 只占 22.8%。原因很简单:768→3072→768,两张大矩阵。推理成本高,很大程度上就是因为 FFN 每次都要跑这一套。
四、残差连接:改归改,原件要留住
4.1 一行代码
残差连接的本质:
bash
输出 = 输入 + f(输入)
把输入原封不动加到输出上。叫"残差"是因为移项之后:f(输入) = 输出 - 输入,这个差值就是残差。
Attention 和 FFN 学到的不是"完整答案",而是"跟输入差多少"。学一个小的修正量,比从零学一个完整答案容易得多。
4.2 没有它会怎样
没有残差连接,首先是信息丢失。想象传话游戏:一句话传 12 轮,到最后面目全非。深层变换会让原始信息层层衰减。
更严重的是梯度消失。训练时梯度要从最后一层往回传,每过一层衰减一点。传 12 层下来,前面几层的参数基本收不到信号,等于白训练。
4.3 有它就完全不一样
残差连接给每层装了一条直达通道:
bash
输入 ───────────┬──────────────────────────┐
│ 直达通道(原始信息通过) │
▼ │
Attention/FFN 处理 │
│ │
▼ │
修正量 Δ ──→ (+) ◄─────────────┘
│
▼
输出 = 输入 + Δ
无论 Attention 和 FFN 处理成什么样,原始输入都完整到达终点。
这意味着每一层不需要重写,只需要批注:
bash
Layer 1 输出 = Embedding + Δ₁
Layer 2 输出 = Embedding + Δ₁ + Δ₂
...
Layer 12 输出 = Embedding + Δ₁ + ... + Δ₁₂
改 12 轮,比从零写 12 遍容易得多。

4.4 残差连接保证了什么
经过 12 层,每一层的输出都可以分解为 原始 Embedding + Δ₁ + Δ₂ + ... + Δₙ。
原始信息始终存在于最终输出里,被层层修正,但从未丢失。这也是为什么经过 12 层变换之后,"苹果"的向量仍然和初始 Embedding 保持相当高的相似度------残差连接就是那条安全绳。
五、LayerNorm:先统一度量衡
5.1 为什么需要
菜市场买菜,甲摊位标价"3",乙摊位标价"3000"。哪个贵?不知道------因为单位不同,一个"元/斤",一个"元/吨"。
Transformer 里也是这样。向量经过矩阵运算之后,有些维度是 100,有些是 0.001,差了几万倍。Softmax 看到这种分布就会把所有注意力都给最大的那个值,其他全部归零。
5.2 怎么解决
LayerNorm 把向量里所有数字拉回差不多大的范围:
bash
LayerNorm(x) = γ · (x - μ) / σ + β
三步:减均值、除标准差(统一大小),再乘 γ 加 β(留一点微调空间,γ、β 是训练学出来的)。
例子:
bash
输入: [100.0, 0.001, -50.0, 25.0] 差了几万倍,计算会炸
输出: [1.45, -0.34, -1.23, 0.11] 全部落在 -2 到 +2 之间
就像把原始成绩转成标准分------不管满分 150 还是 10 分,大家都在同一尺度上了。
参数很少,GPT-2 每层只有 3072 个。但缺了它模型就练不出来。四两拨千斤。
六、为什么需要这么多层
GPT-2 有 12 层,LLaMA 7B 有 32 层。能不能把一层做得特别大,只用一层搞定?
不行,有两个原因。
6.1 不同层做不同层次的事
还是"苹果"的例子。在"我买了一个苹果"里是水果,在"苹果发布了新款 iPhone"里是公司。两个 Embedding 向量完全相同------训练完就固定了。Attention 让它们看见了不同的上下文,但理解层次的深化,靠的是层层叠加。
"苹果"在两种语境下的向量相似度,随层数变化:
bash
Layer 0: 1.000 完全一样(还不知道啥意思)
Layer 3: 0.887 开始有区别了
Layer 6: 0.778 差距越来越大
Layer 12: 0.614 彻底区分了
前几层在认字断句,中间层在理解句子结构,后几层在做推理、调用知识。浅层做粗活,深层做细活。一层搞不定的事,叠几层就能搞定。
6.2 多层就是多步推理
有些理解需要想好几步。"我买了一个苹果"为例:
浅层处理"我"和"买",发现"买"是及物动词,后面大概率跟名词或数量词。中间层看到"一个",确认后面是个可数的名词对象。深层综合"买"+"一个"的上下文,从 FFN 记忆里调出两条知识------"买"和"苹果"高频共现,"苹果"和"水果"高频共现------两者汇聚,输出水果的语义。
每多一层,就多一次"想一想、改一改"的机会。12 层就是 12 次精炼。
七、GPT-2 参数大起底:FFN 占了近一半?
四个组件都认识了。现在看看 1.24 亿参数怎么分配的。
配置:向量维度 768,注意力头数 12,FFN 扩展 4 倍,词表 50257,位置编码 1024。
bash
Token Embedding 38,597,376 31.0%
Position Embedding 786,432 0.6%
Attention(12层合计) 28,348,416 22.8%
FFN(12层合计) 56,669,184 45.5%
LayerNorm + 其他 38,400 0.0%
三个发现:
FFN 是大头。 占 45.5%,接近 Attention 的两倍。768→3072→768,两张大矩阵。存知识当然要空间。
Embedding 在小模型里占比极高。 GPT-2 里占 31%,但 LLaMA 7B 里只占 2% 左右------模型变大时,层参数增长远快于词表。
LayerNorm 参数少到可以忽略。 只有 38400 个,但缺了它模型练不出来。最不起眼的组件,反而最不能少。
八、完整架构:把所有积木拼起来
所有零件都认识了。现在把"我买了一个苹果"跑一遍完整流程:
bash
输入: "我买了一个苹"
│
▼ 分词
["我", "买", "了", "一", "个", "苹"]
│
├─ Token Embedding 查表 → 6 个 768 维向量
├─ Position Embedding 查表 → 6 个位置向量
│
▼ 加在一起 → 初始向量序列
│
│ ┌────────────────────────────────────┐
│ │ Transformer Layer × 12 │
│ │ │
│ │ LayerNorm → Attention → 残差 │
│ │ LayerNorm → FFN → 残差 │
│ └────────────────────────────────────┘
│ 重复 12 次
│
▼ 最终 LayerNorm
▼ LM Head(768 → 50257,映射到词表概率)
▼ Softmax
[..., P("果")=0.987, ...]
│
▼ 采样输出
"果"
就这些。没有更多隐藏模块。
GPT-4、Claude、LLaMA、DeepSeek,底层全是这个结构。
GPT-2 是 12 层、768 维、12 头,1.2 亿参数。LLaMA 7B 是 32 层、4096 维、32 头,70 亿参数。LLaMA 70B 是 80 层、8192 维、64 头,700 亿参数。
同一套架构,放大而已。用 GPT-2 理解原理,跟理解 GPT-4 没有本质差别。
九、结语
Transformer 核心就两种运算:
Attention 让 token 互相看见上下文。FFN 让每个 token 独立消化信息。LayerNorm 统一格式,残差连接保留原件。然后重复 N 次。
同一套结构,翻译能用,写代码能用,做数学、聊天都能用。架构通用,规模就是武器。
前三篇文章从 Token、Embedding、Attention 讲到完整 Transformer 架构,核心问题已经回答了。接下来要说的是:几十亿个参数,是怎么从一堆随机数变成能对话的"大脑"的?
下篇揭晓。