第 9 讲 · 勘误与补注
本页记录四类内容:与母本讲义的差异、术语与译法的统一、录播年代之后发生的工程默认变化,最后是本教程自身的更正记录。 使用方式:读到某节觉得「母本没这么讲」或「书里和论文对不上」时先查本页;查不到再标「需核实」并记入第四节。
一、对照母本讲义的补注
母本 MIT 6.S191 在讲 Transformer 时只提示「大模型需要分布式训练」,没有展开并行、显存与容错。本讲是本教程新增的整讲,因此这一节的对照对象是「母本的一句话提示」与「公开技术报告里的工程结论」之间的距离。
| 主题 | 母本 / 公开材料的处理 | 本教程的补齐(位置) |
|---|---|---|
| 显存构成 | 母本未展开;技术报告只在“基础设施”一节列配置 | 五账单的逐项来源与 推导、可复算的 7B 例题(9.1.2、例 9.1.1);三种写法的静态账对照(例 9.5.1) |
| 数据并行与梯度同步 | 母本一句「多 GPU 时同步梯度」 | 环状 All-Reduce 的通信量推导 、与批大小无关的论证、梯度累积与等效批(9.2.2、定义 9.2.2) |
| 分片 | 报告常直接给「ZeRO-2 / FSDP」这样的结论 | ZeRO 三级各自的分片对象、每卡账与通信变化(定义 9.2.3);什么时候分片反而更慢的四条判据(方法 9.2.2) |
| 张量并行 | 报告给配置(TP=8)不给账 | 列切 / 行切的通信差异与形状推演、「列切 → 逐元素 → 行切」的唯一性论证、按头切与序列并行(9.3.2、定义 9.3.2) |
| 流水线并行 | 报告给 与气泡率 | 气泡公式的三步推导与两极限读法、三种压气泡手段各自的代价、1F1B 改变了什么(9.4.2、方法 9.4.1) |
| 混合精度 | 母本一句话提示 fp16 / bf16 | 位布局差异、损失缩放的动态策略、FP8 的逐张量缩放与硬件门槛(定义 9.5.1、定义 9.5.2) |
| 容错 | 报告里是「中断率」统计 | MTBF 的 量级表、checkpoint 四种策略与最优间隔的期望损失分析、恢复一致性的五项状态(9.6.3、9.6.4) |
| 微调与 PEFT | 母本在 Lab 语境提到微调 | LoRA / QLoRA 的账本重算(7B GB)与「什么时候不必并行」(例 9.5.4、9.7.3) |
一句话总结差异:公开材料给「用了什么配置、达到了什么吞吐」,本教程补「这些数字怎么算出来、算错时长什么样」。本讲不改变任何公开结论的方向,只把每一步的账与判据写出来。
二、术语与常见译误
用法:当你在「同一个词指向两件事」上卡住时来查。以下八条都是本讲内部就构成实际困惑的对比。
| 术语 | 常见误用/误译 | 正确理解 |
|---|---|---|
| DP vs DDP | 把两者当同义词,于是「DP 省显存」这类话开始流传 | DP 是并行范式的名字(每卡一份完整模型状态、切数据);DDP 是它的一个具体实现(PyTorch 的 DistributedDataParallel,反向中分桶异步 All-Reduce 梯度)。DP 不省显存——它要求每卡都装得下完整模型状态(定义 9.2.1) |
| shard vs partition | 中文一律译「分片」,于是「流水线把层分片」这种说法出现 | shard(分片)指把同一份张量 / 状态切成 各存一份(ZeRO / FSDP 的用法);partition(划分)用于把层或数据分配给不同卡(流水线的 stage、数据分区)。流水线切的是层(划分),FSDP 切的是状态(分片),两者可以叠加但机制不同 |
| ZeRO stage 与 FSDP 的关系 | 以为 FSDP 是「第四级 ZeRO」或「另一个 ZeRO」 | FSDP = ZeRO-3 语义在 PyTorch 原生实现里的落地(分片持有 + 按需 all-gather + 用完即散)(定义 9.2.4)。ZeRO-1/2/3 是分片粒度递进的命名;FSDP2 是后续重写(逐参数 DTensor 分片,见第三节)。说「FSDP 就是 ZeRO-3 的工程版」可以,说「第四阶段」不行 |
| micro-batch vs global batch | 把两者混用,于是等效批算错、学习率缩放改错 | micro-batch 是一次前向真正吃进去的那一小批(决定激活显存);global batch(等效批) 是一次优化器更新累计的样本总数 (定义 9.2.2、方法 9.4.2)。学习率只跟等效批联动,显存只跟 micro-batch 联动 |
| tensor parallel vs model parallel | 用「模型并行」统称 TP 与 PP,于是通信与气泡的代价说不清 | 早期文献的 model parallelism 泛指「切开模型」(含 TP 与 PP 两种);本讲一律用精确词:TP 切层内权重与激活(每层都要通信、延迟敏感)、PP 切层(段间 P2P、气泡大)(9.3、9.4) |
| activation vs model state | 说「显存不够就分片」,不区分缺的是哪一本账 | 模型状态 = 参数 + 梯度 + 优化器状态 + 主权重,、与批大小无关(定义 9.1.1);激活 = 前向中间张量,、用完可释放。分片 / 8-bit 优化器只动状态,梯度累积 / 重计算只动激活(9.1.1、9.1.3) |
| loss scaling vs FP8 缩放 | 以为「都用缩放」,可以照搬 fp16 的配方 | fp16 的 loss scaling 是一个标量乘在损失上(把整条反向的梯度抬离下溢区);FP8 的缩放是逐张量(甚至逐块)一个因子,且要用上一步统计量做延迟缩放(定义 9.5.1、定义 9.5.2) |
| 模型字节数 vs 参数量 | 通信量公式里把 与 混用,导致结果差 2 倍 | 是参数个数; 是这些参数占的字节数(bf16 下 )。梯度 All-Reduce 的通信量写作 ,其中 是被归约张量的字节数(bf16 梯度时 GB, 较大时每卡 GB 量级;正文 例 9.2.2 用的是含 因子的精确式,得 24.5 GB) |
三、时效补注
本讲涉及的默认答案是硬件与框架的函数,不是数学结论。下表按「主题 / 早期口径 / 截至 2025 年的实践 / 本教程的处理」列出;凡涉及版本与倍数的条目一律以官方文档与你自己的实测为准。
| 主题 | 早期口径 | 截至 2025 年的实践 | 本教程的写法 |
|---|---|---|---|
| 分片的框架形态 | ZeRO 阶段由 DeepSpeed 配置驱动(2019–2021 年代) | PyTorch 原生路线:FSDP 之后是 FSDP2(fully_shard + 逐参数 DTensor 分片,2024 年起,无对应论文,以官方文档为准) | 定义 9.2.4 给 FSDP2 的三点变化,代码片段标「字段随版本变化,需核实」 |
| 低精度训练 | fp16 + 动态损失缩放 | BF16 是安全默认;FP8(E4M3 / E5M2,NVIDIA + Arm + Intel 联合定义,2022;Hopper 及之后原生支持张量核心)成为「有硬件 + 有官方配方」时的加速项 | 9.5.1 讲位布局,9.5.2 讲 FP8 的缩放与门槛 |
| 流水线调度 | GPipe(先全前向再全反向)→ 1F1B → 交错调度 | zero-bubble(把反向拆成输入梯度与权重梯度、用后者填空档,2024)成为拓展方向 | 方法 9.4.1 三种手段并列,并注明 zero-bubble 属拓展内容、收益须实测 |
| 跨机通信优化 | 直接 All-Reduce / Reduce-Scatter | ZeRO++(分层分区、量化梯度、二级分区,2023)与「用节点内带宽换跨机带宽」的思路 | 9.6.2 的拓展 note 给出三条思路,标「需按你的环境实测」 |
| 优化器状态压缩 | 全部 fp32 | 8-bit 优化器(分块量化的 m,v,bitsandbytes 一类实现)在单卡微调里近乎默认, | 9.5.4 给定义与代价,并在 方法 9.5.1 的对照表里给 7B 的 GB |
| 微调范式 | 全参微调为主 | LoRA / QLoRA 成为受限显存下的默认(QLoRA 2023;主干 4 bit + 低秩适配器) | 定义 9.5.5、例 9.5.4 给出可复算账本 |
| 大规模故障率 | 「坏了重启」 | 万卡级训练把中断视为工程常量,公开报告(如 Llama 3 技术报告,2024)给出中断率统计 | 9.6.4 用 的量级表,并注明引用报告须核对统计窗口 |
| 框架 API 字段 | 各框架自成体系 | torch.distributed.pipelining、torch.distributed.checkpoint、DeepSpeed ZeRO 配置、peft / bitsandbytes 量化配置等字段名与语义随版本变化 | 正文所有代码片段只作概念锚点,凡字段处一律标「以你所用版本为准,需核实」 |
一条通用提醒:本讲所有带宽、算力与故障率数字都是量级(NVLink 约 300 GB/s、IB 400 Gb/s GB/s、单卡有效算力 FLOP/s、/小时)。它们的用途是让你在动手之前算出量级,不是用来预测你的集群。报价必须用你自己的硬件实测校准(9.7.4)。
四、本教程更正记录
| 位置 | 原表述 | 更正 | 说明 |
|---|---|---|---|
本讲目录下的讲末六页(summary.md / errata.md / exercises.md / checklist.md / recall-cards.md / mock-exam.md) | 曾为单行占位文件(内容仅一行提示),构建后会渲染成空页 | 已补齐完整六页:节一览 + 一条主线 + 三句话带走;四节勘误;A/B/C/D 四组习题(C 组每题含可运行验收标准);八条目标自检;四组回忆卡 + Anki 导出;100 分闭卷自测卷 + 评分标准 + 漏点定位表 | 占位页会让读者误以为「本讲没有练习与自测」。补齐后盒子配平自查命令输出「全部配平」,且六页互引与对正文的引用均为相对路径(同讲 secNN.md、跨层 ../../labs/lab3.md) |
| 例 9.1.2、例 9.4.2、例 9.5.2、9.7 | 激活按「每层每 token 约 34 字节」计算,算式漏掉隐藏维 (写成了 ),单位也把 MB 标成了 GB | 已修正:口径改写为「每 token 每 hidden 元素约 34 字节」,算式补上 (如 字节 ≈ 34 GB),并同步更新 例 9.4.2、例 9.5.2、9.7 与自测卷第 18 题的数值 | Megatron 系论文的激活估算写成 形式:34 是「每个 hidden 元素」的字节数,必须乘 才是每 token 的量。漏掉 ()与把 MB 写成 GB()两个错误方向相反、量级相近,因此单看结论数字「似乎合理」——这正是它值得记进勘误的原因:量纲检查要做两次(维度因子 + 单位),一次不够 |
| 速查背记卡「第 9 讲」一节 | 用 9.1–9.9 的知识单元编号(9.3 = ZeRO、9.4 = 张量并行、9.5 = 流水线并行) | 本讲正文保持节号 9.1–9.7(9.2 = 数据并行与 ZeRO、9.3 = 张量并行、9.4 = 流水线并行);引用速查卡时请注明其编号口径 | 两套编号并存本身不是错误(速查卡是知识点清单,不是节目录),但混用会造成「9.3 到底是 ZeRO 还是张量并行」的沟通事故。本页只记录该差异,不改动速查卡 |
待核实的开放条目(发现新差异时追加到本表,不要就地改动正文):
| 位置 | 现象 | 待核实的问题 |
|---|---|---|
| 9.1.3、9.5.3 | 激活经验系数「每 token 每 hidden 元素约 34 字节」,选择性重算约 18、全层重算约 2(单位同为字节/(token·hidden 元素)) | 系数随实现与版本变化(是否重算注意力、是否实体化 softmax、是否 FlashAttention),且 34 一项不含注意力矩阵(Megatron 把它单列为 )——报价请用自己的实现实测 |
| 9.2.4 | ZeRO-3 通信量「升至约 1.5 倍」 | 该倍数随分片粒度、预取深度与算子融合变化,应以你自己的 profiler 实测为准 |
| 9.5.4 | CPU offload 让训练慢「1.5–3 倍甚至更多」 | 与 PCIe 代际、offload 范围(只 offload 优化器状态 vs 连参数)、批大小强相关 |
| 9.6.4 | 单卡小时故障率 与 MTBF 表(8192 卡 小时) | 量级参考;引用具体集群或报告的数字时须核对统计窗口与「组件故障」的口径 |
| 9.6.5 | 5D 配平的示例表(7B / 70B / 400B+ / MoE 各一行) | 教学示例,表达的是「各轴怎么分」的推理方式,不是任何具体报告配置的复述 |
| 9.7.4 | 单卡有效算力 FLOP/s → 吞吐 token/s/卡 | 有效算力随模型、精度、内核质量与批大小变化,只用于判断「是否差一个数量级」 |
| 9.3.3、9.4.4 | Dropout 掩码跨卡一致性的实现细节;全局批记账是否含 因子 | 两处正文均已自标「需核实」,需按所用框架版本与 GPipe 论文的记账口径核对 |