附录 C 关键节点拆解 Ⅱ:2023–2024,开源标准配方与第一轮分化¶
这一篇的任务:这两年里,开源模型先是收敛到一套所有人都用的配方,然后又沿着三个方向分开——省 KV、上稀疏、换掉注意力本身。本书第 7、9、12、13、14 章讲的正是这三个方向,这里给它们配上真实的模型和数字。
C.1 LLaMA 1/2/3:标准配方是怎么定下来的,又是怎么被自己推翻的¶
LLaMA 1(2023.02,Meta,arXiv:2302.13971)¶
7B / 13B / 33B / 65B 四个尺寸,小模型训 1.0T token,大模型训 1.4T。它验证的是 Chinchilla 那条结论,但走得更远:在同等质量下选更小的模型、喂更多数据,因为部署方便。
它的结构是一份极简清单,三处改动全部来自附录 B.6 的零件库:
| 相对于 GPT-2 的改动 | 来自 | 章节 |
|---|---|---|
| LayerNorm → RMSNorm(Pre-Norm) | Zhang & Sennrich 2019 | 第 5.2 节 |
GELU FFN → SwiGLU(d_ff ≈ 8/3 d) |
Shazeer 2020 | 第 5.3 节 |
| 可学习位置嵌入 → RoPE | Su et al. 2021 | 第 6.2 节 |
| 所有 bias 去掉 | PaLM | 第 5 章 |
这四条就是"现代稠密 Transformer"的全部定义。 从 2023 年到今天,你打开任何一个开源模型的 modeling_*.py,这四条都在。第 8 章逐行读的那个 8B 模型,主干就是这套。
LLaMA 2(2023.07,arXiv:2307.09288)¶
2T token,4K 上下文。架构上唯一的重要变化是 34B / 70B 用了 GQA。
GQA 的论文(Ainslie et al., arXiv:2305.13245)做了一件很实用的事:证明可以把已经训好的 MHA 检查点,通过对 K/V 头做均值池化再用原始预训练算力的约 5% 继续训,转换成 GQA 模型。这让 GQA 几乎零成本地铺开了。
为什么是 GQA 而不是 MQA:MQA 把 KV 压到一个头,省得最狠,但质量掉得能看出来,而且在张量并行下所有卡要共享同一份 K/V,切分变别扭。GQA 让 KV 头数等于并行度的整数倍,每张卡正好分到自己的那份(第 7.3 节)。又一个"系统约束决定建模选择"的例子。
Llama 3 / 3.1(2024,arXiv:2407.21783)¶
8B / 70B / 405B,15.6T token,128K 上下文,词表扩到 128256,全系列都用 GQA(8 个 KV 头)。
两个值得单独记住的决定:
- 8B 模型训了 15T token,约 1800 token/参数,是 Chinchilla 最优点的近百倍。 报告里明说了理由:训练只花一次,推理要花无数次。这是附录 B.5 那"第三次修正"最清楚的实例。
- 405B 用的是稠密而不是 MoE,理由是这个规模下稠密模型训练更稳、实现更简单。这个选择在一年之后就成了少数派——2025 年之后的旗舰几乎全是 MoE(附录 D)。记下这一点,因为它说明"当前的主流"有多短命。
C.2 Mistral 与 Mixtral:把两件事带进开源¶
Mistral 7B(2023.09,arXiv:2310.06825)¶
32 层,d=4096,GQA 8 个 KV 头,滑动窗口注意力(SWA)窗口 4096。
滑动窗口的逻辑很直接:每个 token 只看最近 W 个。单层的感受野是 W,但 L 层堆起来,信息可以逐层往前传递,理论感受野是 L × W——和 CNN 靠堆层扩大感受野是同一个道理(附录 A.5 提到的 Swin 对照)。
它真正的工程价值是 rolling buffer KV cache:既然只看最近 W 个 token,KV Cache 就可以是一个固定大小 W 的环形缓冲区,写满之后覆盖最旧的。KV 显存从"随序列线性增长"变成"常数",这是第 11 章讲滑动窗口时那笔账的实际落地。
它的局限也在这里:需要精确回看窗口之外的某个具体 token 时(长文档里找一个数字),逐层传递传不过来。这个局限直接催生了后来"局部层 + 全局层交替"的混合设计(C.4、第 14 章)。
Mixtral 8x7B(2023.12,arXiv:2401.04088)¶
每层 8 个专家,每 token 选 top-2,总参数 46.7B,激活参数 12.9B。
它是第一个证明"MoE 值得部署"的开源模型。请特别注意那两个数字的关系:
- 计算量按 12.9B 算 → 推理速度接近一个 13B 模型;
- 显存按 46.7B 算 → 你需要能装下 47B 的卡。
MoE 是拿显存换计算,不是白赚。 这笔账第 9.6 节算过,这里是它第一次真实地摆在开源用户面前。名字里的 "8x7B" 也有误导性:专家只替换 FFN,注意力是共享的,所以总参数不是 8×7=56B。
C.3 DeepSeek-V2(2024.05):MLA 这笔账怎么算¶
论文:arXiv:2405.04434,236B 总参数 / 21B 激活。
它一次给了两个后来被广泛采用的东西。
MLA(多头潜在注意力)¶
问题:GQA 省 KV 是靠减少 KV 头数,但减到一定程度质量会掉。有没有办法既保住多头的表达力,又把缓存压下去?
做法:不缓存每个头的 K 和 V,而是把它们联合压缩成一个低秩潜在向量(V2 里是 512 维),只缓存这个向量;每层用上投影矩阵在计算时把它还原成各头的 K/V。关键技巧在于这些上投影矩阵可以吸收进查询与输出的投影里,所以推理时并不真的展开,额外计算很小。
一个不得不打的补丁:RoPE 是作用在 K 上的位置相关旋转,如果 K 是从潜在向量现算出来的,旋转就没法预先合并进矩阵。DeepSeek 的解法是解耦 RoPE——拿出一小部分维度(每头 64 维)单独承载位置信息,这部分按常规方式缓存,其余维度走压缩路径。第 7.4 节讲的就是这个结构。
收益:报告称 KV 缓存相比同规模稠密模型减少约 93%。代价是实现复杂——这也是为什么 MLA 虽然效果好,两年里跟进的团队仍然不算多。
DeepSeekMoE¶
两个改动,都在第 9.5 节:
- 细粒度专家:把专家切得更小、数量更多(160 个路由专家),同样的激活参数量下组合数指数级上升,专家更容易分工。
- 共享专家:留 2 个所有 token 都过的专家,负责通用能力,把路由专家解放出来学专门知识。
C.4 Gemma 2(2024.06):1:1 交替,以及用蒸馏做小模型¶
论文:arXiv:2408.00118,2B / 9B / 27B。
架构上的关键选择是局部与全局注意力 1:1 交替:奇数层用 4096 的滑动窗口,偶数层用全注意力。这比 Mistral 的"全部都是局部"更进一步,也是后来所有混合架构的模板——多数层便宜,少数层保留精确回看能力(第 14.2 节)。
其他两点:
- logit soft-capping:用
tanh把注意力 logits 和最终输出 logits 软性限幅,防止数值爆炸。这个设计在 Gemma 3 里被去掉了,因为它和 FlashAttention 的融合核不兼容——一个建模技巧如果拖累了核实现,通常活不长,这是本书反复出现的主题。 - 2B 和 9B 是从更大的教师模型蒸馏出来的,而不是从头预训练。这让小模型在同样的参数量下明显更强;蒸馏属训练方法,细节在第三册。
C.5 另一条路线:注意力能不能整个换掉¶
与上面"改进注意力"平行,2023–2024 年有一批工作试图取消注意力的 O(n²) 和随长度增长的 KV。
| 工作 | 核心机制 | 章节 |
|---|---|---|
| RetNet(2023.07,arXiv:2307.08621) | retention 机制,同一套参数有并行/循环/分块三种等价形式 | 第 12.2 节 |
| RWKV | 线性注意力 + 类 RNN 的时间衰减,训练可并行 | 第 12.2 节 |
| Mamba(2023.12,arXiv:2312.00752) | 选择性状态空间:让 SSM 的参数依赖输入,配硬件感知的并行扫描 | 第 12.3 节 |
| Mamba-2(2024.05,arXiv:2405.21060) | 状态空间对偶,证明 SSM 与线性注意力是一回事,状态可以做得更大 | 第 12.1 节 |
| Gated DeltaNet(2024.12,arXiv:2412.06464) | delta rule 的定向修正 + 遗忘门控,成为后来 Qwen3-Next 那条线的基础 | 第 12.5 节 |
| Jamba(2024.03,arXiv:2403.19887) | Transformer + Mamba + MoE,注意力与 Mamba 层约 1:7 | 第 14 章 |
这一年的结论是清楚的:纯线性/状态模型在语言建模的困惑度上可以追平,但在需要精确回看的任务(长上下文检索、多跳、in-context 学习大量示例)上稳定地落后。原因在第 12.6 节——固定大小的状态就是一个信息瓶颈,这是数学性质,不是调参问题。
于是所有人都走向了混合。Jamba 是第一个把这个结论产品化的开源模型,它的 1:7 比例和 Gemma 2 的 1:1 是同一个问题的两个答案。2025 年之后这个比例基本收敛到 3:1 附近(附录 D)。
C.6 DeepSeek-V3(2024.12):一次把零件凑齐¶
论文:arXiv:2412.19437,671B 总参数 / 37B 激活,14.8T token。
它的重要性不在于发明了什么,而在于把前面所有零件在一个模型上同时跑通了,而且训练成本低得让整个行业重新算账:
| 模块 | 用的是什么 | 章节 |
|---|---|---|
| 注意力 | MLA(承自 V2) | 第 7.4 节 |
| FFN | DeepSeekMoE,256 个路由专家 + 1 个共享,top-8 | 第 9.5 节 |
| 负载均衡 | 免辅助损失:给每个专家一个可调偏置,只影响选谁、不进入梯度 | 第 9.4 节 |
| 输出 | MTP:额外预测下一个之后的 token,训练加监督、推理当草稿头 | 第 15.4 节 |
| 训练精度 | FP8 混合精度 | 第二册 |
| 路由的系统约束 | 节点受限路由(每个 token 的专家不跨太多节点) | 第二册第 6 章 |
免辅助损失这一条尤其值得体会。传统 MoE 用一个辅助损失惩罚不均衡,但这个损失与语言建模目标冲突,是在拿质量换均衡。DeepSeek 的做法是把均衡挪出梯度:观察到某个专家过载就调低它的偏置,让它下一批少被选中。同样的目标,从"改目标函数"换成"改系统状态",代价就消失了。 这是本书里最漂亮的工程思路之一。
C.7 长上下文的三个补丁¶
这两年模型的上下文从 4K 涨到 128K,靠的不只是架构,还有三个不改结构的补丁:
- YaRN(2023.09,arXiv:2309.00071):按频率分段地缩放 RoPE——低频维度(管长距离)插值,高频维度(管局部)保持原样,再配一个温度修正。只需少量长文本继续训练就能把窗口拉长若干倍(第 6 章)。
- Attention Sink / StreamingLLM(2023.09,arXiv:2309.17453):发现模型会把大量注意力质量倾倒在最前面几个 token 上(哪怕它们语义无关),所以做流式推理时必须保留最开头的几个 token,否则质量崩塌。这个现象后来被直接写进架构——gpt-oss 给每个头加了可学习的 sink 偏置(第 11.2 节,附录 D.1)。
- FlashAttention-2:把 FlashAttention 的并行策略和工作划分重做,显著提升 GPU 利用率(第二册)。
这三个补丁的共同点是都不改变参数结构,因此可以套用到已有模型上。判断一篇长上下文论文时,先分清它属于"改架构"还是"打补丁"——后者的落地门槛低一个数量级。
C.8 两年里零件的流向¶
| 零件 | 2023 初 | 2024 末 | 章节 |
|---|---|---|---|
| 归一化 / 激活 / 位置 | RMSNorm + SwiGLU + RoPE | 没变 | 第 5、6 章 |
| KV 优化 | MHA 为主 | GQA 成标配,MLA 在头部模型里 | 第 7 章 |
| FFN | 稠密 | 头部模型转向细粒度 MoE + 共享专家 | 第 9 章 |
| 注意力范围 | 全注意力 | 局部/全局交替开始流行 | 第 12、14 章 |
| 序列建模 | 只有注意力 | 线性/状态模型作为混合的一半 | 第 13、14 章 |
| 输出头 | 单 token | MTP 出现 | 第 15 章 |
| 上下文 | 4K | 128K–256K | 第四部分 |
| 训练精度 | bf16 | FP8 进入前沿 | 第二册 |
三条经验:
- 主干配方(第 5、6 章那几样)两年没动过。 变化全部集中在注意力和 FFN 这两个"贵"的地方——因为优化压力就来自那里。
- 每一个架构选择都能追溯到一个成本约束。 GQA 来自 KV 显存,MoE 来自计算量,混合来自长上下文,MTP 来自 decode 的访存瓶颈。第 4 章那三个公式是理解这一切的入口。
- 凑齐零件比发明零件更难,也更有价值。 DeepSeek-V3 没发明多少新东西,但它证明了这些东西能同时工作。
核心问答¶
Q1:MLA 这么省,为什么跟进的人不多? 实现复杂度高(解耦 RoPE、矩阵吸收、推理时的两种等价形式),对推理框架的核支持要求高,而 GQA 已经足够好且零成本。技术扩散的阻力常常在生态而不在指标——这和 ALiBi 输给 RoPE 是同一类故事。
Q2:Mixtral 的 8x7B 为什么不是 56B? 因为专家只替换 FFN,注意力层和嵌入是所有专家共享的。这也是为什么第 16 章要教你手算参数量——从 config 自己算一遍,比记住厂商的命名可靠。
Q3:滑动窗口和线性注意力都是"省长序列开销",区别在哪? 滑动窗口仍然是精确注意力,只是限制了范围,窗口内的信息是精确的、窗口外完全看不到(靠层数间接传)。线性注意力对全部历史都有响应,但历史被压进一个固定大小的状态,全都是有损的。一个是硬截断,一个是全局压缩,失效模式完全不同(稀疏见第 11 章,线性见第 12 章)。
Q4:Gemma 2 的 logit soft-capping 被删掉,是不是说明它本来就没用? 不是。它在 Gemma 2 上确实起到了稳定作用。删掉是因为收益比不上"不能用融合核"的损失。在这本书里你会不断看到这种权衡:一个数值技巧的命运往往由核实现决定,而不是由它自身的效果决定。
Q5:2024 年末如果我要自己设计一个 30B 模型,照抄谁? 主干照抄 LLaMA 3(RMSNorm + SwiGLU + RoPE + GQA + 无 bias),这部分几乎没有争议;FFN 侧决定要不要上 MoE(看部署显存);注意力范围决定要不要局部/全局交替(看目标上下文长度)。剩下的都是数字,第 16 章教你怎么算。