从零开始理解大模型(五):Transformer 全景——积木怎么搭成大厦

欢迎阅读「从零开始理解大模型」系列 —— 十篇文章,从"下一个词预测"到完整的大模型心智模型。每篇配可运行代码。
第一篇:一切从"猜下一个词"开始
第五篇:Transformer 全景——积木怎么搭成大厦
第六篇:训练——70 亿个参数是怎么"学"出来的
第七篇:推理——你按下回车后的这一秒发生了什么
第八篇:上下文窗口——大模型的"工作记忆"
第九篇:Scaling Law——为什么"大力出奇迹"有效
第十篇:从大模型到 Agent——下一个词预测如何长出手脚
作者:十一
前四篇,我们一块一块地认识了积木:
但光有积木还不够。Attention 只是 Transformer 一层的一半,另一半是什么?GPT-2 有 12 层,LLaMA 有 32 层,为什么要叠这么多?
这篇把积木搭成完整的大厦。读完之后,大模型从输入到输出的每一步,你都明白了。
▍一、先说结论

一句话版本:Transformer = (Attention + FFN) × N 层,再加点"胶水"。就这么简单的结构,重复 N 次,就是所有大模型的骨架。
▍二、先打个比方,建立全局感觉
想象一家公司,一份报告要经过 12 个部门审阅。
每个部门固定做两件事:
-
开会(Attention)—— 大家坐在一起,互相交流信息。每个人听完别人的发言,更新自己的理解。"你们都说说,我综合一下。"
-
回工位写总结(FFN)—— 开完会,每个人回去独自思考,把讨论内容消化成自己的判断。"我自己想想,这事到底意味着什么。"
另外有两个保障机制:
-
保留原件(残差连接)—— 每次修改,都在原件上叠加,不会覆盖原件。"改归改,原来的东西不能丢。"
-
统一格式(LayerNorm)—— 每次流转前,把报告里的数字拉到统一范围。"大家别一个写米、一个写公里,先统一度量衡。"
12 个部门审完,报告里既有所有部门的意见,又没丢失原始信息。
这就是 Transformer 干的全部事情。 下面一个一个展开。
▍三、一层 Transformer 长什么样
画成流程图:
输入向量
│
▼
┌─────────────────────────────────────┐
│ ① LayerNorm(统一格式) │
│ ② Multi-Head Attention(开会) │
│ ③ 残差连接:输出 = 输入 + 开会结果 │
├─────────────────────────────────────┤
│ ④ LayerNorm(统一格式) │
│ ⑤ FFN(独立思考) │
│ ⑥ 残差连接:输出 = 输入 + 思考结果 │
└─────────────────────────────────────┘
│
▼
输出向量(送去下一层继续处理)
上半部分是 Attention——让词和词之间互相交流。下半部分是 FFN——让每个词自己消化信息。中间的 LayerNorm 和残差连接做稳定保障。
写成代码,核心就四行:
residual = hidden
hidden = residual + attention(layernorm_1(hidden)) # 开会 + 保留原件
residual = hidden
hidden = residual + ffn(layernorm_2(hidden)) # 独立思考 + 保留原件
看着是不是特别朴素?别小看它——GPT-4、Claude、LLaMA、DeepSeek,内部全是这四行在不断重复。
下面逐个讲解三个你还没见过的新组件。
▍四、FFN——"开完会了,自己坐下来想一想"
4.1 光开会还不够
第四篇讲的 Attention,让每个词都"听到了"其他词的信息。处理 "Thank you very" 的时候,"very" 知道了前面有 "Thank" 和 "you"。
但"听到"不等于"想明白"。
就像你参加了一场会,听了一大堆发言,脑子里全是信息碎片。你还得回到工位上坐下来,自己理一理:**"这些信息综合起来,到底说明什么?"**
这个"坐下来理一理"的步骤,就是 FFN(Feed-Forward Network,前馈网络)。
为什么叫"前馈"?因为数据只往前走,不回头——当前 token 的信息处理完后,直接"喂"给下一层,不会把自己的输出再喂回自己。没有循环、没有反复,一路向前。
4.2 它到底怎么做的
公式长这样:
FFN(x) = W₂ · GELU(W₁ · x + b₁) + b₂
这里的 W₁、W₂ 是训练时学出来的权重矩阵,训练完就固定不变了。同一层里所有 token 共用同一组 W₁、W₂——不是每个 token 各有一份。
别被公式吓着。拆开来看就是三步:
输入(768 个数字)
│
▼ 第一步:"展开"—— 乘一个大矩阵,768 维变成 3072 维
│ 就好比把一页笔记铺开到四页纸上,有更多空间做标注
│
▼ 第二步:"划重点"—— 用激活函数(GELU)过一遍
│ 就好比拿一支半透明荧光笔划重点:
│ - 特别重要的内容(正数)会被高亮保留
│ - 不太重要的内容(负数)也不会被完全涂黑,而是被轻轻压低、保留一点点痕迹
│
▼ 第三步:"压缩"—— 再乘一个大矩阵,3072 维压回 768 维
│ 就好比把四页标注总结回一页精华
│
▼ 输出(还是 768 个数字)
有一个特别重要的特点:FFN 只看自己,不看别人。 "very" 做 FFN 的时候,完全不管 "Thank" 和 "you" 在干嘛。这和 Attention 正好反过来——Attention 是"大家一起交流",FFN 是"每个人独自思考"。
4.3 为什么说 FFN 是"知识库"
有一个有趣的发现:大模型记住的事实(比如"法国首都是巴黎")主要存在 FFN 的权重里。
打个比方:
-
Attention 是搜索引擎——在上下文里搜到了 "Thank you" 这个线索 -
FFN 是大脑里的记忆——看到这个线索后,从记忆中调出 "much" 这个最强搭配
一个负责找线索,一个负责给答案。两者配合,才能又找对又答对。
▍五、残差连接——"改归改,原件必须留着"
5.1 世界上最简单的操作
输出 = 输入 + f(输入) // f 是 Attention 或 FFN
就是把输入原封不动加到输出上。对,就这么简单。
但为什么叫"残差"? 移项一下就明白了:
f(输入) = 输出 - 输入 = 残差
Attention 和 FFN 学到的东西,不是"完整答案该长啥样",而是"跟输入差多少"。这个差值就叫残差。
学一个小的修正量,比从零学一个完整答案简单多了。这就是残差学习的核心思想,名字也从这来。
5.2 没有它,12 层就废了
想想"传话游戏":你悄悄告诉第一个人一句话,一个传一个,传 12 轮——最后一个人说出来的,跟原话八竿子打不着。
没有残差连接的 Transformer 就是这样。12 层一叠,原始信息早就面目全非了。而且训练的时候,调参数的信号(叫"梯度")要从第 12 层一路传回第 1 层,每过一层就弱一点。传 12 层下来,信号几乎没了——前面的层调不动参数,就等于白训练。
这个问题叫梯度消失,是深层网络最经典的老大难。
5.3 加上它之后,画风完全不同
残差连接等于给每一层装了一条直通管道:
输入 ──────┬──────────────────────────────────┐
│ │
▼ │ 直通管道
Attention/FFN 处理 │(原始信息直接穿过去)
│ │
▼ │
修正量(Δ)───────→ (+) ◄────────────────┘
│
▼
输出 = 输入 + Δ
不管 Attention/FFN 处理得多好或多烂,原始输入都通过直通管道完整到达了终点。
所以每一层不需要"从零开始写一份新报告",只需要在原报告上批注几句修改意见:
Layer 1 输出 = Embedding + Δ₁ ← 第一个部门批了几句
Layer 2 输出 = Embedding + Δ₁ + Δ₂ ← 第二个部门又批了几句
...
Layer 12 输出 = Embedding + Δ₁ + ... + Δ₁₂ ← 12 个部门的修改意见叠在一起
就像改文章——不是每一稿从头写,而是在上一稿基础上改红字。改 12 轮,肯定比从零写 12 遍容易得多。
用 transformer_anatomy.py[1] 可以验证:即使经过 12 层变换,输出和原始 Embedding 的余弦相似度还是很高。原始信息确实通过直通管道保到了最后。
▍六、LayerNorm——"每次传递前,先统一度量衡"
6.1 为什么需要
你去菜市场买菜,一个摊位标价"3",另一个标价"3000"。哪个贵?不知道——因为一个单位是"元/斤",另一个是"元/吨"。数字大小没意义,除非单位统一。
Transformer 里也是这样。向量经过矩阵乘法和加法之后,有些维度的数字飙到 100,有些缩到 0.001。差了十万倍。后续的 Softmax 看到这种极端分布就懵了:它会把几乎全部注意力给最大的那个值,其他值全变成零。
数字大小太离谱,后面的计算全带跑偏了。
6.2 怎么解决
LayerNorm 干的事特别朴素:把向量里所有数字"拉"回差不多大的范围。
LayerNorm(x) = γ · (x - μ) / σ + β
拆开来看:
-
先算平均值(μ),把所有数字都减去平均值——让中心归零 -
再算散开程度(σ),除以它——让大小统一 -
最后乘以 γ 加上 β——留一点微调余地(γ 和 β 是训练时学出来的)
看个具体例子:
输入: [100.0, 0.001, -50.0, 25.0] ← 差距十万倍,后续计算会炸
↓ 减均值 18.75,除标准差 55.9
输出: [1.45, -0.34, -1.23, 0.11] ← 都在 -2 到 +2 之间了,好处理多了
就像考试成绩——原始分可能是 150 分满分、也可能是 10 分满分,没法比。但转成"标准分"之后,所有人的成绩都在同一个尺度上了。
LayerNorm 的参数很少——GPT-2 每层只有 3072 个——但缺了它模型就训不出来。真正的四两拨千斤。
▍七、拆开 GPT-2,看参数都在哪
四个组件都认识了。现在打开 GPT-2 的"引擎盖",看看 1.24 亿个参数到底怎么分配的。
先算一下每个组件有多少参数。GPT-2 的关键数字:向量维度 d=768,注意力头数 12,FFN 扩展倍数 4,词表 50257,最大位置 1024。
Embedding:
-
Token Embedding:每个 token 一个 768 维向量 → 50257 × 768 = 38,597,376 -
Position Embedding:每个位置一个 768 维向量 → 1024 × 768 = 786,432
Attention(每层):
-
Q、K、V 三个权重矩阵,每个 768×768 → 3 × 589,824 = 1,769,472 -
输出投影矩阵 O:768×768 = 589,824 -
四个偏置项:768 × 4 = 3,072 -
每层合计:约 236 万
FFN(每层):
-
W₁ 扩展矩阵:768 × 3072 = 2,359,296 -
W₂ 压缩矩阵:3072 × 768 = 2,359,296 -
两个偏置项:3072 + 768 = 3,840 -
每层合计:约 472 万(是 Attention 的两倍,因为有 4 倍扩展)
LayerNorm(每层):
-
每层两组(Attention 前 + FFN 前),每组有 γ 和 β 各 768 个 → 768 × 2 × 2 = 3,072
现在看运行 transformer_anatomy.py[1] 得到的实际分布:
组件 参数量 占比
──────────────────────────────────────────────────
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 的两倍。为啥?因为 FFN 有 4 倍扩展(768→3072→768),两个大矩阵。FFN 是"知识库"嘛,存知识当然需要空间。
Embedding 在小模型里占比惊人。 GPT-2 的 Embedding 占了 31%。但在更大的模型(比如 LLaMA 7B)里,Embedding 只占 2% 左右——因为模型变大的时候,Transformer 层的参数增长速度远超 Embedding。
LayerNorm 小到可以忽略。 只有 38,400 个参数。但没它整个模型就训练不了。最不起眼的组件,反而最不能少。
完整拆解和数据流追踪代码见附件 transformer_anatomy.py[1]。
▍八、为什么要叠这么多层
GPT-2 叠了 12 层,LLaMA 7B 叠了 32 层。能不能把一层做得特别大,只用一层搞定?
不行。原因有两个。
8.1 不同层看不同层次的东西
就像人理解一句话,有从浅到深的过程:

第三篇的实验展示过:同一个词 "bank",在"银行"和"河岸"两个语境下,向量差异是一层一层加大的:
Layer 0: 相似度 1.000 ← 完全一样("这个 bank 啥意思我还不知道")
Layer 3: 相似度 0.887 ← 开始有点不同了("后面好像跟了 money...")
Layer 6: 相似度 0.778 ← 差距越来越大
Layer 9: 相似度 0.691
Layer 12: 相似度 0.614 ← 彻底区分了("这个是银行,那个是河岸")
浅层做粗活,深层做细活。一层搞不定的事情,叠几层就能搞定。
8.2 多层 = 多步推理
有些理解需要想好几步。
比如这句话:"The trophy doesn't fit in the suitcase because it is too big"——这里的 "it" 指 trophy 还是 suitcase?
-
浅层:先认出 "it" 是代词,要找它指的是谁 -
中间层:注意到 "too big" 说的是尺寸 -
深层:推理——"太大"所以放不下。放不下的应该是 trophy(要是 suitcase 太大,反而装得下啊)。所以 "it" = trophy
一步到位做不出这种推理。每多一层,模型就多一次"想一想、改一改"的机会。
层数不是越多越好,但深度确实带来推理能力。
▍九、完整架构图:把所有积木拼起来
到这里,所有零件你都认识了。拼在一起:
输入文本: "Thank you very"
│
▼ ─── 分词(第二篇)
[10449, 345, 845] ← 3 个 token ID
│
├─▶ Token Embedding(查表) ← 3 个 768 维向量
├─▶ Position Embedding(查表) ← 3 个位置向量
▼ ─── 加在一起(第三篇)
[向量₁, 向量₂, 向量₃] ← 初始表示
│
│ ┌────────────────────────────────────────┐
│ │ Transformer Layer × 12 │
│ │ │
│ │ LayerNorm → Attention(12头)→ 残差 │ ← 开会
│ │ LayerNorm → FFN(768→3072→768)→ 残差 │ ← 独立思考
│ │ │
│ └────────────────────────────────────────┘
│ ↑ 重复 12 次(GPT-2)/ 32 次(LLaMA 7B)
│
▼ ─── 最终 LayerNorm
▼ ─── LM Head(768 → 50257)
▼ ─── Softmax
[..., P("much")=0.992, ...] ← 50257 个概率
│
▼ ─── 选 token(第一篇)
" much"
就这些了。没有更多隐藏模块。
GPT-4、Claude、LLaMA、DeepSeek——底层全是这个结构。区别只在三个数字:

同样的架构,放大规模而已。所以用 GPT-2 理解原理,跟用 GPT-4 完全等价。
▍十、LM Head 与权重共享
架构图最后的 "LM Head(768→50257)" 把向量变回 50257 个概率——模型内部一直在操作向量,这一步翻译回"每个词有多大可能性"。
很多模型(包括 GPT-2)中,LM Head 和 Token Embedding 共享同一个权重矩阵——同一张 50257×768 的表,进去的时候按行查向量,出来的时候做矩阵乘法算概率。12 层 Transformer 的任务,就是把最后一个位置的向量推向 "much" 对应的方向。推得越准,概率越高——第一篇看到的 99.2% 就是这么来的。
▍十一、五篇回顾
到这里,前五篇构成了一条完整的链路。大模型从输入到输出的每一步,你都看过了:

前五篇回答了"大模型是什么"。 后五篇回答"怎么变得更好":训练(第六篇)、推理优化(第七篇)、上下文窗口(第八篇)、Scaling Law(第九篇)、和 Agent 结合(第十篇)。
▍十二、结语
回头看,Transformer 简单到令人吃惊。
总共就两种核心运算——Attention(开会讨论)、FFN(独立思考)。加上 LayerNorm 统一格式、残差连接保留原件,然后重复 N 次。
同一个结构,拿去翻译、写代码、做数学、聊天——通通能用。你不需要给每种任务设计不同的模型,只需要把这个简单结构做得足够大。
"The unreasonable effectiveness of simple architectures."
架构够通用,规模就是最好的武器。
下一篇,我们讲这些参数怎么从一堆随机数变成能对话的"大脑"——70 亿个数字,是怎么"学"出来的。
本文配套代码:transformer_anatomy.py[1](模型拆解、参数统计、数据流追踪、残差连接验证)。需要 Python 3.8+、transformers、torch。

扫码回复“大模型”
获取本系列文章完整配套代码
「从零开始理解大模型」是「从零开始理解 Agent」的姊妹系列。Agent 系列讲"四肢",本系列讲"大脑"。建议对照阅读 专栏入口。
相关链接
[1] transformer_anatomy.py: https://github.com/GitHubxsy/nanoAgent/blob/claude/organize-teaching-materials-4hnRP/llm-from-scratch/transformer_anatomy.py
今日推荐
关注AGENT魔方公众号,回复大模型
领取「从零开始理解大模型」实操配套代码
加速入门和掌握Agent:

- 点赞
- 收藏
- 关注作者
评论(0)