Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第 9 讲导览 · 大规模并行训练的秘诀

这一讲要解决的真实问题

前八讲都在回答同一个方向的问题:怎么设计一个能学好的模型。第 9 讲换了一个正交的问题:当模型与数据大到一张卡装不下时,怎么把它训起来。这不是「多买几张卡」那么简单——把 7B 参数的模型按混合精度 Adam 训练,光与优化器相关的静态状态就要 16×7×10916\times7\times10^{9} 字节 ≈112 GB\approx 112\ \text{GB}(算式见 9.1),而一张主流训练卡的显存是 80 GB。模型还没开始算,就已经装不下了。

真实的大规模训练由两条线索驱动。

第一条是切:把数据切给多张卡(数据并行)、把单个权重矩阵切给多张卡(张量并行)、把层切成段分给多张卡(流水线并行), 三者正交,可组合成工业界的 3D 并行;再往前一步,激活也能沿序列维切(序列并行 / 上下文并行), 专家层还能沿专家维切(专家并行),于是有了「5D 并行」。

第二条是省:用低精度换显存与吞吐(BF16 / FP8)、用算力换显存(激活重计算)、 用通信换显存(ZeRO / FSDP 把冗余的模型状态分片),以及用「只训一小部分参数」换显存(LoRA / QLoRA)。

这两条线索的每一次取舍都要落在三个量上:显存够不够、算力用满没有、通信扛不扛得住。 本讲的全部公式与清单,都是为了让这三个量在动手之前就能被算出来——因为在大规模训练里,「先跑一次看看」的代价是几小时到几天。

母本 MIT 6.S191 在讲 Transformer 时提到过「大模型需要分布式训练」,但没有展开;本教程把这一讲补成一条可操作的工程线:

先算账(9.1)→ 再切分(9.2 / 9.3 / 9.4)→ 同时省(9.5)→ 处理工程摩擦(9.6)→ 落到自己的硬件上(9.7)。

凡是超出这本书能核实范围的地方(具体的框架内部实现、某次训练的确切吞吐),都会明确标注「需核实」, 而不是给一个好看的数字。

七节一览

节核心问题关键结论典型陷阱
9.1 问题设定:超过单卡容量显存到底被什么占满了?「放不下」有几种?混合精度 Adam 下模型状态 =16N=16N 字节(参数 2 + 梯度 2 + fp32 主权重 4 + mm 4 + vv 4);激活与批大小、序列长度成正比,且不受分片影响只算参数量、忘了优化器状态与激活;把「放不下」笼统当成一个问题,不分模型状态 / 激活 / 单层
9.2 数据并行:从 DP 到 FSDP每卡一份完整副本为什么浪费?分片能省多少、代价是什么?梯度 All-Reduce 通信量 ≈2P\approx2P(字节,bf16)且与批大小无关;ZeRO-1/2/3 逐级分片后每卡模型状态 16N→11N→7.75N→2N16N\to11N\to7.75N\to2N(8 卡)以为加大批大小会加大通信量(恰好相反);以为分片越彻底越好(ZeRO-3 通信更多、可能更慢)
9.3 张量并行:把一层切开单层放不下时怎么切?为什么要列切与行切成对?列切免通信、行切需一次 All-Reduce;MLP「列切 → 逐元素激活 → 行切」每块前向仅一次 All-Reduce;注意力按头切;通信密集 → 必须留在节点内以为张量并行的通信量会随并行度下降(不会,只随消息变小);跨节点硬上张量并行
9.4 流水线并行:把网络切成段按层切分后,为什么卡在空转?怎么压掉?朴素调度气泡占比 P−1M+P−1\dfrac{P-1}{M+P-1}(推导见 9.4.2);三种手段:增大 micro-batch 数 MM、交错调度、zero-bubble 拆分反向以为流水线能缓解单卡显存(它降低单卡 batch,激活压力更小但每段要排队);以为 1F1B 消除气泡
9.5 显存优化:混合精度、重计算与分片不切模型能省多少?每种手段的代价是什么?BF16 靠宽指数范围免损失缩放;FP8 需缩放且需新硬件;激活重计算用约 1/3 的额外前向换亚线性激活显存;8-bit 优化器省 37.5% 静态显存;QLoRA 把 7B 微调压到「一张 24 GB 卡」量级以为混合精度「白拿不掉点」;把 FP8 缩放与 FP16 的损失缩放搞混;把激活重计算当成能省参数显存
9.6 通信、容错与工程实践通信量怎么估?万卡规模下坏了怎么办?环状 All-Reduce 每卡 ≈2S\approx2S;重叠与分桶是吞吐关键;故障是常态(checkpoint 策略与恢复时间要一起设计);确定性与吞吐常常互斥,要先定口径只算通信量不算通信时间(漏了带宽与延迟);把「能重启」当成「不用做 checkpoint 策略」
9.7 动手:为 Lab 3 选一套并行策略手上只有 1–8 张卡时,究竟该怎么配?五步决策:显存估算 → 是否分片 → 是否 TP/PP → 批大小与梯度累积 → 精度与重计算;接着算吞吐与验收指标;受限显存下 LoRA / QLoRA 往往比任何并行都省照搬大厂配置;只调一个旋钮(批大小 / 梯度累积 / 重计算要成套改);不看扩展效率只看总吞吐

本讲地图

                    第 9 讲 · 大规模并行训练的秘诀

  9.1 算账(问题设定) ── 显存五账单 16N ── 三堵墙:显存 / 算力 / 通信
        │
        │  算完账才知道缺什么
        ▼
  ┌─────────────────┬─────────────────┬──────────────────┐
  │  9.2 切数据      │  9.3 切单层      │  9.4 切层         │
  │  DP → ZeRO → FSDP│  TP + 序列并行   │  PP + 1F1B       │
  │  通信:梯度       │ 通信:激活(密)  │ 通信:边界(稀)  │
  └────────┬────────┴────────┬────────┴─────────┬────────┘
           │                 │                  │
           └──────────┬──────┴──────────────────┘
                      ▼
        9.5 省:混合精度 / FP8 / 激活重计算 / 8-bit 优化器 / 量化
                      │
                      ▼
        9.6 工程:通信重叠 · checkpoint 与容错 · 确定性 · 5D 配平
                      │
                      ▼
        9.7 落地:给定 1–8 张卡与模型规模 → 一套可运行的配置 + 验收指标
                      │
                      ▼
                    Lab 3(微调一个大语言模型)

  依赖关系:9.2 / 9.3 / 9.4 相互独立,但都建立在 9.1 的账本上;
            9.5 与 9.2–9.4 是「省」与「切」两条并行线索;
            9.6 讲两者叠加后的摩擦;9.7 把它们合成一张决策表。

与母本讲次的对应

本讲内容母本(MIT 6.S191)的处理本教程的补齐
数据并行与梯度同步提到「多 GPU 训练时同步梯度」环状 All-Reduce 的通信量推导、梯度累积与等效批、线性缩放的适用边界(9.2)
显存构成未展开五个账单的逐项来源与 16N16N 推导、可复算的 7B 例题(9.1)
分布式训练框架未展开ZeRO-1/2/3 与 FSDP2、张量并行、流水线并行与气泡公式(9.2–9.4)
混合精度一句话提示FP16 / BF16 位布局差异、损失缩放的动态策略、FP8 与缩放(9.5)
微调与 PEFT在 Lab 语境提到微调LoRA / QLoRA 的显存账重算与「什么时候不必并行」(9.5、9.7)

先修目标与前置知识对照

本讲要用的东西来自哪里在本讲里的角色
链式法则与计算图1.5 反向传播反向传播要保存哪些中间激活——激活显存的来源
Adam 的一阶 / 二阶矩1.6 优化器显存账本里最贵的两项(每参数 8 字节)
批大小与学习率的联动1.6 优化器梯度累积后要不要放大学习率、要不要预热
注意力与前馈的矩阵形状2.4、2.5张量并行按哪个维切、通信量按哪个张量算
归一化层与残差1.2、2.5张量并行时 LayerNorm 要复制还是切分
显存估算与排查清单工具箱本讲账本的简化版,可先读它建立手感

怎么用这一讲

读法建议:三种读法,按你的目标选

A. 只做过一次单卡训练(建议顺序读):9.1 全读 → 9.2 全读 → 9.3 / 9.4 读「定义 → 直觉 → 例题」,proof 框第一遍可跳 → 9.5 全读 → 9.6 读第一、三、四小节 → 9.7 全读并动手做一遍账。预计 4–6 小时。

B. 立刻要跑一次多卡训练(倒着读):先读 9.7 的五步决策表 → 回来读 9.1 的账本与 9.5 的对照表 → 遇到具体瓶颈(OOM / GPU 利用率低 / 扩展效率差)时再查 9.2–9.4 与 9.6。预计 2 小时拿到可运行配置。

C. 面向面试或答辩(按判断读):只读每节的「关键结论」表、errata 框与 9.6.5 的 5D 配平表,再把 9.7 的排错清单背下来。本讲在海报、简历与面试中出现频率最高的问题是「ZeRO 三个阶段分别分片了什么、通信量怎么变」。

可以跳的框:::: note[skip] 与嵌套的 ::: proof(第一遍)。不能跳的框:每节的 intuition(建立手感)与 errata(踩过的坑)。

打卡路径:读完一节 → 做该节的「即时自测」(折叠答案先自己写)→ 用 工具箱 第四节的公式把你手头的模型算一遍 → 全部读完后来到 9.7 做一次完整配置。

本讲与 Lab 3 的关系

Lab 3 的任务是「加载一个预训练大语言模型,用 LoRA 在受限显存下微调」。它与本讲的关系是互补而非重叠:

  • Lab 3 走「省」路线:冻结主干、只训低秩适配器 W=W0+BAW=W_0+BA(定义 9.5.1),于是需要优化器照料的参数从 NN 降到 O(r(d+k))O(r(d+k)),显存账本从 16N16N 变成「低精度主干 + 适配器」。这条路不需要多卡,也不需要通信。
  • 本讲走「切」路线:当真要改动全部参数(全参微调、预训练、继续预训练)时,16N16N 的账本无法靠 PEFT 绕过,只能靠 9.2–9.4 的并行与 9.5 的省显存手段。
  • 两讲的接点在 9.7:那一节把「1–8 张卡」的所有情形列成一张表——什么规模该全参 + ZeRO、什么规模该 QLoRA、什么时候两者叠加,并给出排错清单。Lab 3 里的 OOM 排查(先降 batch、再上梯度累积、开混合精度、减 rr 或 max_length)正是那张表的简化版。

一句话:Lab 3 教你「不动大模型就能适配它」,本讲教你「非要动它时怎么动得起」。两者合起来才是完整的工程答案。

本讲不覆盖什么(避免期望错位)

  1. 不讲集群运维的体力活:机房、网络布线、驱动与 CUDA 版本矩阵、容器与调度器(Slurm / Kubernetes)只在本讲需要的地方点到,不展开。
  2. 不给具体厂商硬件的选型建议:所有带宽与算力数字都写成「量级 + 算式」,你可以用自己机器的实测值替换。
  3. 不复述某个框架的完整文档:本讲给接口片段与配置字段,用来锚定概念;真实项目请以对应版本的官方文档为准。
  4. 不承诺任何数字能直接套在你的任务上:账本是下界估算,通信与利用率依赖拓扑与实现,必须实测对账(9.7 的验收步骤)。

读完本讲之后

如果你……下一步去哪
想做习题巩固本讲末的 exercises.md(A 概念 / B 推导 / C 编程 / D 设计)
想立刻把配置写出来9.7 动手 的五步决策表 + 排错清单
想跑一个真实的微调任务Lab 3 · 微调一个大语言模型
想在面试前把结论压成几句话速查背记卡 与 面试与答辩竞技场
想查某个符号或术语符号与缩略语表、易混对照卡