第8讲 · Stanford CS336 语言模型从零开始|:并行(Parallelism)
课程信息
| 课程 | Stanford CS336 Language Modeling from Scratch(Spring 2026) |
| 本讲 | Lecture 8 — Parallelism |
| 视频 | https://www.youtube.com/watch?v=6-cXp-aOmdg |
| 讲者 | 本讲由课程教师主讲(上一讲由 Percy Liang 讲授并行的底层机制) |
| 材料整理 | 本电子书由课堂字幕重构而成,文中「编者说明」「编者拓展」均为编者所加,不代表讲师原话。 |
对应讲次:第8讲(Stanford CS336 语言建模)
制作模型:deepseek-flash(vb compose,据 run.log)
导览
这一讲不是要给出一份"并行算法教科书目录",而是要把"在大集群上训练大模型"这件事,从散落的知识点拼成一张可操作的地图。下面是这张地图。
① 讲师真正提出的核心问题(按他自己的顺序)
- 为什么非要并行? 单卡到底卡在哪两个瓶颈上?(提示:不只是算力,还有内存。)
- 既然要并行,可用的"积木"有哪些——数据并行、张量并行、流水线并行、专家并行,它们各自在切什么、花什么代价?
- 这些积木能不能同时用?讲师的答案是能,甚至到"4D 并行";问题在于怎么组合。
- 给定了网络拓扑 + 模型规模,最优的并行策略是什么?(这正是作业要你算的东西。)
② 难点在哪
- 最容易卡住的一步是 "内存 ≠ 参数"。学生的直觉往往是"参数量就是内存",而讲师反复强调:优化器状态(Adam 的一阶、二阶动量)往往比参数本身更大,而且激活值(activations)在长序列下会彻底盖过参数内存。算错这一步,后面所有内存节省方案都理解不了。
- 第二个坎是 "免费"这个词。ZeRO Stage 1/2 号称"零成本"(与朴素数据并行通信量相同),Stage 3(FSDP)号称"实践中几乎免费",这些说法都依赖 all-reduce = reduce-scatter + all-gather 这一等价性,以及 通信与计算的重叠。不抓住这两条,会误以为是黑魔法。
- 第三个坎是 策略之间的相互牵制:张量并行吃掉带宽、流水线并行制造气泡、专家并行对 DP 布局有额外约束——它们不是能随便拼的乐高。
③ 读者可能带着的疑问
这一讲讲师真正要回答的:为什么大规模训练需要同时叠加多种并行策略?如何在给定硬件下把它们组合起来?
(编者预判)读者可能带着进来、但讲师未必逐个点名的疑问:
- FSDP、ZeRO、DDP 到底有什么区别,名字为什么这么乱?
- 张量并行和流水线并行到底该用哪个、用多少?
- 为什么大家都说 TPU 的并行策略和 GPU 不一样?
- MoE 模型(DeepSeek、Qwen 这类)为什么改写了并行的玩法?
编者说明:以上第 ③ 组的后半部分是本电子书为初学者补足的"提问式入口",讲师在课堂上更多是顺着技术脉络平推;把它们单列出来,是为了让第一次接触并行的读者知道"这堂课会顺手回答哪些你没敢问的问题"。
本讲路线
讲师把内容分成三段:第一段快速复习集合通信原语与硬件拓扑(TPU 环面网格 vs GPU 胖树);第二段是主体,逐个拆解数据并行(含 ZeRO 三级与 FSDP)、流水线并行、张量并行、序列并行、专家并行、上下文并行;第三段把一切收进一张"并行策略总览表",给出一条极简的实用处方,再回到真实训练案例(Olmo、DeepSeek、Yi、Llama 3、Gemma 2、Mixtral、Qwen 3)看这些策略如何组合。
编者拓展|什么是集合通信(collective communication)? 课堂上讲师说"我们只在集合原语的层面讨论,不发数据包"。所谓集合通信原语,是指一组进程协同完成的、有固定语义的通信操作,常见的有: - broadcast:一份数据分发给所有进程; - gather / all-gather:各进程的数据汇集到一处 / 汇集后所有进程都拿到完整副本; - reduce:把各进程的数据按某个算子(如求和)归约到一处; - reduce-scatter:先归约,再把结果分片散发给各进程(每个进程只拿到一片); - all-reduce:归约后让所有进程都拿到完整结果; - all-to-all:每个进程给其他每个进程发一份数据(MoE 路由的核心)。 这些原语在 NCCL(GPU)和 TPU 的通信库中都有高效实现,因此后面讨论通信量时,直接按"发生了几次 all-reduce / all-gather"来记账即可。
一、为什么需要并行:两个瓶颈
(参考时间: 00:00:05)
讲师开场说,上一讲 Percy 覆盖了并行的底层机制,而今天是他"最爱讲的一类内容"——现代语言模型训练中并行是怎么真正运作的,包括很多知识点和冷门细节(trivia)。目标是把"在巨大集群上训练巨大模型"所涉及的种种复杂性讲清楚。
编者说明:这一讲会揭示一个反直觉的事实——可以同时使用的并行策略有很多种。讲到后面会出现"4D 并行"的说法,意思是四种策略同时上;实际上还会更多。而在最大的规模上,你几乎需要把所有这些策略都用上。
计算与内存:两个必须靠多机多卡解决的瓶颈
(参考时间: 00:01:22)
为什么要上并行?因为有两个瓶颈,都只能靠"多机 + 多卡"来化解:
- 计算(compute):我们需要比单芯片能提供的多得多的算力。世界上最快的超级计算机有百亿亿次级(exaflops)的算力,而单块 GPU 远远够不到这个数量级。解决办法就是把大量机器连起来。
- 内存(memory):模型太大了,装不进一块 GPU,所以必须把模型切分成小块。
节点内与节点间:一个贯穿全讲的关键区分
(参考时间: 00:02:18)
一个贯穿整堂课的核心概念区分是:
- 节点内并行(intra-node parallelism):连接非常快,因此可以做通信开销很高的操作。
- 节点间并行(inter-node):通信明显更慢,因此设计流程时必须更尊重信道的通信约束。
编者说明:在 GPU 机器里,"节点"通常指一台机器(8 块 GPU 通过 NVLink 高速互联);跨机通信则走网络(InfiniBand 等),带宽和延迟都差一个档次。TPU 则没有这么鲜明的"单机 8 卡"分界,详见第三节。
讲师强调:今天我们不在数据包层面做文章,而是在集合通信原语层面讨论。所以后面说"这里要做一次 all-reduce""那里要做一次 all-gather"时,就是在为通信量记账。当然,要把这些实现得高效,最终要下到硬件层;但今天的讨论是算法层面的,网络原语都停留在集合(collective)这一层。
二、并行算法前的预备:all-reduce 的等价性
(参考时间: 00:03:14)
有一个等价关系对后面的某个算法极其重要,值得单独拎出来:
$$ \text{all-reduce} \;=\; \text{reduce-scatter} \;+\; \text{all-gather} $$
也就是说,一次 all-reduce 可以拆成"先归约分片(reduce-scatter),再全聚集(all-gather)"两步,二者在通信代价上等价。
有学生插话问:是不是还有别的分解方式?讲师确认确实有其他分解,他之所以强调这一种,是因为它对后面那个算法(ZeRO/FSDP 的梯度处理)特别有用。
编者拓展|为什么 all-reduce = reduce-scatter + all-gather? 直觉上:all-reduce 要求每个进程最终都拿到"所有进程数据的归约结果"。一种实现方式是先让每个进程负责归约出一片结果(reduce-scatter),再让大家把各自那片广播出去,拼成完整结果(all-gather)。 若记数据量为 $M$、进程数为 $N$,在环形(ring)算法下两者通信量都约等于 $2 \cdot \frac{N-1}{N} \cdot M$,在 $N$ 较大时接近 $2M$——这正是后面 ZeRO 记账的关键。
在下文里我们会反复看到这条等价性:凡是"需要一次 all-reduce"的地方,都可以改写成"一次 reduce-scatter + 一次 all-gather",从而把内存分摊到各卡而通信量不变。
三、底层硬件:TPU 与 GPU 的网络哲学
(参考时间: 00:04:20)
大部分讨论是硬件无关的——一旦理解基本概念,就能套用到任意硬件底座上。但讲师还是想在开始前简要谈一下底层硬件栈,一方面它本身就很有趣,另一方面不同模型训练公司会采用不同的并行策略,根源就在硬件。
TPU 的环面网格(toroidal mesh)
TPU 是 Google 的加速器。讲师在 GPU 那一讲里提到过,TPU 有点像"轻量级 GPU",但真正的差别在网络。
TPU 的网络是所谓的环面网格:可以想象成一张网格,然后让网格的边缘互相连接(首尾相接),实际上是一个三维的环面结构。课程里有同学做了一个很酷的三维可视化网页来展示这个环面网格。
其要点是:
- 每块芯片只和邻居相连,邻居会"环绕"回来;
- 由此得到一个非常简单的网络拓扑,可以非常简单地无限扩展;
- 无论网络多大,每块芯片的邻居数基本不变。
GPU 的全互联(all-to-all)与胖树(fat tree)
GPU 的网络哲学截然不同,是全互联(all-to-all)哲学,通常呈树状,常被称为胖树(fat tree):
- 最低层 GPU 之间连接极快;
- 一组 GPU 连成一个 pod(机柜单元);
- 各 pod 之间通过 spine 交换机通信。
于是随着节点数增长,树越来越大,通信拓扑越来越复杂,因为你要一路把所有东西全互联起来。
两种哲学的适用场景
这种设计哲学差异意味着:
- 只和邻居通信时,TPU 很棒、性价比高,而且能在同样功耗下把每条连接做得更"粗壮";
- 以随机、不可预测的方式通信时,GPU 网络更灵活。
讲师引用了 Bill Dally 和 Jeff Dean 关于不同硬件的讨论:GPU 适合专家混合(MoE)这类通信模式不清晰的工作负载(因为 token 会路由到不同专家);TPU 适合密集模型那种可做非常可预测切分的工作负载——也就是后面要讲的张量并行。
一个"今早刚发生"的插曲
(参考时间: 00:07:38)
讲师本打算在这里收住硬件话题,结果就在今天早上,Google 宣布了新的 TPU(AI 系列)。他备课翻到时惊呼:"天哪,这是树状拓扑——他们转向了更像全互联的连接。" 他分析这很合理:现代语言模型都是 MoE,要服务 MoE 就得把 token 路由到不同专家,带宽乱飞,自然需要更强的全互联连接;即便在训练时,其训练芯片 TPU 8T 的跨机架连接也越来越像 GPU——建了一套叫 Virgo 的全互联风格交换机网络。他总结:工作负载正在反过来定义我们需要什么样的网络,TPU 和 GPU 都在各自演化、相互趋近。
另一条极端路线:华为昇腾 910 与"暴力堆通信"
(参考时间: 00:08:43)
讲师喜欢谈中国 AI 圈正在发生的事。他在 GPU 那一讲被问过:"SRAM 那么好,为什么不全用 SRAM 芯片?"——答案就是 Groq,它确实能跑得很好。类似地,有人会问:"既然全互联好,为什么不把所有东西都连起来、用超快的光纤?"——那大概就是华为昇腾 910。
看规格会发现有意思的权衡:
- 单芯片比 H200 差很多,矩阵乘等很多方面都更慢;
- 但如果愿意专门用一整机架的光纤交换机去连接大量芯片(他们做到单机架 384 块),那么"单芯片慢"或许可以用"连接得多得多"来弥补;
- 代价是功耗高得离谱:是同等 Nvidia 系统的四倍。
讲师由此点出硬件设计的普遍真理:想高效利用功耗和制造成本,你会停在某个位置;想暴力堆料,你会停在另一个完全不同的位置。这与 SRAM 的故事如出一辙,是很值得学习的一课。
小结:计算单元是"整个数据中心"
(参考时间: 00:10:33)
把所有内容拼起来,第一件要建立的观念是:
新的计算单元不是单块 GPU,而是整个数据中心。
我们希望同时做到几件事:
- 控制内存用量;
- 控制能投入的算力;
- 而且这些都要无损(lossless)——即用尽手头所有资源。
后面讲的算法,就是通过这些集合通信原语来实现上述目标的。
四、数据并行:从 DDP 到 ZeRO 三级
(参考时间: 00:11:07)
本讲第二段是主体内容,讲用于并行化语言模型的算法。讲师先把它们分成两类:
- 数据并行:把数据分散到各 GPU,四处流动的是数据;
- 模型并行:把模型的不同部分切分出去。
他提醒这个边界其实有点"漏":其中一个算法(指 ZeRO/FSDP)实际上也切参数。但这样分类仍然有助于理解。概念上,我们想同时扩展算力和内存,所以才需要一大堆不同的技巧。
朴素数据并行(DDP)
(参考时间: 00:12:01)
数据并行最容易理解,概念非常简单,也是 LM 训练"标准"的并行方式。
先忘掉 Adam,假设用朴素的 SGD,有大小为 $B$ 的大 batch。每个更新步取 $B$ 个样本、求和梯度、做一次更新。最朴素的做法是:
- 把 batch $B$ 切成 $M$ 份,放在 $M$ 台机器上(每台拿到 $B/M$);
- 各机器各自算梯度;
- 把所有梯度同步(求和)。
其特性:
- 算力扩展:完美(只要每卡样本够多);
- 通信开销:每个 batch 要通信大约两倍参数量的数据(因为梯度要来回传);
- 内存扩展:完全没有。每块 GPU 都有同样的模型副本,还需要同样大小的激活值。这个方案一点内存都省不下来。
编者拓展|通信量"两倍参数"是怎么来的? 朴素 DDP 每步要做一次 all-reduce 归约梯度。用上一节的 ring 公式,$N$ 卡时通信量约 $2M\frac{N-1}{N}$,$M$ 为梯度(即参数量)大小。在 $N$ 大时约等于 $2M$——这就是"两倍参数量"的来源,也是后面所有"免费"说法的基准线。
内存核算:情况比想象中糟得多
(参考时间: 00:13:33)
朴素数据并行解决了算力,却完全没碰内存。于是做一次内存记账。初看内存情况就很糟,实际情况则"非常糟"。
经验法则(取决于精度)大致是:需要约 5 份权重、每参数 16 字节来存储一个模型。具体包含:
- 模型参数本身;
- 存放梯度的地方(进参数之前的累加器);
- 可能需要一个更高精度的累加器用于 SGD 累加(可能只是临时的);
- 如果做 Adam——这才是"坏事"的来源——你需要跟踪梯度的一阶矩和二阶矩,而且要随时间持续跟踪,所以是两份,且出于数值稳定性可能需要高精度存储,代价相当大。
这些统称优化器状态(optimizer state)。而记账显示:优化器状态占用了 SGD 更新绝大部分内存。
用分片换内存:ZeRO 的思想
(参考时间: 00:15:04)
这里有一个非常优雅的想法:把需要的内存切碎、分发到各加速器上,而且用结构化方式切,从而"几乎免费"地获得收益。
用颜色表示:绿色是优化器状态(占大头)、橙色是梯度、蓝色是参数。注意参数和梯度大小相同,而状态更大。
- 若做朴素数据并行,就是把这些状态在 GPU 上完全复制。这不好:消耗了远超所需的内存,且内存随加速器数量线性增长。
- 更好的是把优化器状态分片到各 GPU,能省很多;也可以进一步分片梯度;极端情况下把一切都分片。
右侧显示的内存收益相当惊人,可以从 120 一路降到 1.9。问题只有一个:这样做的代价是什么? 直觉上"天下没有免费的午餐"——基线应该最快,越往下分片,通信代价越大。但讲师说,remarkable 的地方在于其中很多是免费的。下面逐步走。
ZeRO Stage 1
(参考时间: 00:16:49)
Stage 1 最简单:只分片优化器状态,跨 GPU 切分。参数和梯度每个人都要有完整份。
可以这样理解:每个 worker 负责更新一片参数。比如 0 号 GPU 只负责更新第一片,其余更新不管。
流程是:
- 每个人拿到不同数据样本,算出完整梯度;
- 把自己的梯度 reduce-scatter 到其他机器——但别人不需要全部梯度,只需要与它那片更新对应的梯度。所以每个 worker 从"我"这里拿到的是"我"的梯度中属于它那段参数空间的部分——通信量等价于参数量级;
- 每台机器现在能更新了:它有自己的参数、从别人拿到的梯度、以及自己维护的状态;
- 参数更新完后,再 all-gather 回来:我只负责 1/4 的参数,就把更新后的参数发回给所有人。
代价核算:
- 朴素数据并行:一次 all-reduce,通信量约 $2\times$ 参数;
- ZeRO Stage 1:一次 reduce-scatter + 一次 all-gather。
- 但前面说过 reduce-scatter + all-gather = all-reduce——所以 Stage 1 的通信特性与朴素 DDP 完全相同。
结论:ZeRO Stage 1 是免费的内存节省。
内存上,参数之外的所有东西被除以 GPU 数量。
ZeRO Stage 2
(参考时间: 00:19:19)
Stage 2 进一步把梯度也分片。这更棘手,因为过去依赖"能算出完整梯度",现在连完整梯度都物化不了。怎么办?
这其实是一个系统技巧:
- 反向扫过网络时,不必一次性算出完整梯度;
- 可以在反向遍历计算图时,边算边把梯度发给对应的 worker;
- 某一层的梯度在反向图中不再需要时,立即释放。
于是你是在增量地计算并发送梯度。而这与"一次性全算完再发"是等价的——所以并不改变通信量。最后再 all-gather 参数。
结论:ZeRO Stage 2 在不增加任何额外代价的情况下实现了梯度分片。
ZeRO Stage 3(FSDP)
(参考时间: 00:20:27)
最后一个、也是最"毛糙"的,是连参数也一起分片。讲师说,他第一次学到这里时觉得简直是魔法:"前面已经白拿了这么多好处,那就继续推。"
思路沿用 Stage 2 的增量思想:按需发送和接收参数,在遍历计算图的过程中进行。难点在于:任一时刻,每块 GPU 只看到参数、梯度、优化器状态的一片。
这就是 ZeRO Stage 3,也就是 FSDP(如果你在 PyTorch 里并行过任何东西,多半见过它)。
其底层机制是:向前扫时做两次 all-gather、一次 reduce-scatter。流程(从左到右即完整更新过程):
- 加载模型,两块 GPU(上、下);
- 先 all-gather 这一层的权重,做这一层的 forward,然后释放权重(后面不再需要);
- 进入反向:反向需要激活值(已保留)和这一层的参数——按需 all-gather;
- 做完反向,立即 reduce-scatter 梯度;
- 释放权重,重复上述过程;
- 最后更新权重,完成。
通信代价:两次 all-gather + 一次 reduce-scatter。也就是说,比之前多了一次 all-gather。而且看起来"疯"——每一层都在通信,你可能觉得这会极其昂贵、非常糟。
为什么 FSDP 在实际中几乎免费
(参考时间: 00:22:48)
讲师说这里有两个反直觉但重要的想法,使 Stage 3 的开销几乎为零:
- 遍历计算图 + 即时通信 + 立即释放内存(我们已经见过);
- 把通信和计算重叠(overlap)——这是全新的点子。
他展示了一张取自 PyTorch FSDP 架构论文的图。图里有几条"流":CPU 上在做什么、GPU 上做计算、GPU 上做通信(最下面一条)。
工作机制:
- FSDP 必须先拿到参数才能算,所以先 all-gather layer 0;拿到后就能做 forward;
- 但在做 forward 的同时,就请求下一层的参数——一边算一边 all-gather layer 1;
- layer 1 到齐后做 forward 1,同时开始 all-gather layer 2……
- 于是在过程中通信与计算重叠。可能还要花时间释放参数,或者再算一次 forward(比如 $W_0$ 被复用了两次)。
只要你有足够计算量、网络够快,通过重叠通信与计算,FSDP 基本上可以做到免费。你确实会看到一些气泡(bubble,即开销),但如果通信足够快、计算足够大,计算能跑得比通信久,于是你获得内存的大幅改善,却几乎不付内存之外的代价。
编者说明:图里那些"气泡"是通信与计算对齐不完美留下的空隙。讲师的意思不是"完全零开销",而是这些空隙小到在实际训练里可忽略——所以实践中 FSDP 的 GPU 利用率非常接近单卡水平。
三阶段对比与内存折算
(参考时间: 00:24:59)
| 方案 | 通信量 | 是否"免费" |
|---|---|---|
| DDP(朴素数据并行) | 一次 all-reduce,$\approx 2\times$ 参数 | 基准 |
| ZeRO Stage 1 | reduce-scatter + all-gather = all-reduce | 字面意义的免费(通信量不变) |
| ZeRO Stage 2 | 同上 | 免费 |
| ZeRO Stage 3(FSDP) | 多一次 all-gather | 略多,但靠重叠可隐藏 |
实践中,FSDP 跑出来的 GPU 利用率非常接近单卡性能,这让讲师觉得相当了不起,而且概念上很简单。学员的作业里要自己写一个 FSDP 实现——本质上是写一个 wrapper,把任意 module 包成它的 FSDP 版本:all-gather、计算、释放,反向时重复。
内存收益的直观感受:在 A100 上,基线连 7B 模型都装不下;换成 ZeRO Stage 3,可以装下约 500 亿参数的模型。可见 FSDP 带来的内存改善非常显著。
编者说明:有学生追问换成 H100/H200 会怎样,讲师说他没法心算那份"乘 141 除 80"的账,但结论是线性的——换加速器不会改变数学本质,只是把数字整体缩放。
学生问答:FSDP 是不是流水线?
(参考时间: 00:26:13)
有学生问:"是不是从下一块 GPU 拿梯度来算前一块 GPU 的梯度、这是顺序的?" 讲师澄清:那不是 FSDP,那更接近流水线并行。流水线是"一层在一块 GPU、另一层在另一块 GPU"。而在所有 ZeRO/FSDP 情形里,每块 GPU 都会从头到尾走完整个模型,区别只是没有哪块 GPU 同时持有全部参数——它按需请求 layer 0 的参数、算完、再请求下一层。可以理解为"在每次计算操作之间请求参数、释放参数",计算本身和朴素数据并行一样。
第二个问题:"是不是每块 GPU 持有每一层的一部分,优化器就管这部分?" 讲师确认:是的——参数、梯度、优化器状态都跨 GPU 分片。
第三个问题:"为什么通信代价不是乘以层数?" 讲师解释:操作数确实随层数增加,但每次通信的量更小(只是一小块 MLP),与之相比的基准是"归约整个网络"——所以加起来等价。
五、模型并行
(参考时间: 00:28:53)
讲师说他很想在 FSDP 这里结束,但遗憾的是要进入"更丑、更毛糙"的部分。为什么必须继续?两个原因:
原因一:数据并行在"吃"一种稀缺资源——batch size
(参考时间: 00:29:08)
数据并行把 batch size 当成一种资源在消耗。例如 batch size 是 8,就最多只能用 8 块加速器。你可能会想"那就把 batch 越调越大",但不行:存在一个临界 batch size(critical batch size),超过它之后,多加一个 batch 元素带来的收益,不如拿它单独多走一步 SGD。也就是说:
- 小 batch 时,加元素完全有用,等价于多走几步 SGD;
- 到了某一点,收益递减出现;
- 无限大的 batch 并不比无限多步有用。
于是我们面临一个硬权衡:要小 batch 让 GPU 闲置,还是要大 batch 吃优化上的亏? 很难说。
原因二:内存问题并未解决
(参考时间: 00:30:13)
- Stage 1/2 没让内存真正可扩展;
- Stage 2 能切参数内存,但激活值内存以及其它内存并没有被切分或减少。
所以我们需要更细粒度的模型切分方式,才能把内存进一步压下去。这就引出了各种模型并行。
模型并行的共同点与关键差异
模型并行本质上也把参数切到不同 GPU,但与 FSDP 的关键概念差异是:
- FSDP 里切的是参数,但它只是个 wrapper——计算照旧,只是互相传参数而已。飞的是参数。
- 模型并行里,我们要来回传激活值(activations)。例如一层在 GPU 0、下一层在 GPU 1,那么要传的就是中间那层的激活值。
模型并行包含:
- 流水线并行(pipeline parallel):切分"层";
- 张量并行(tensor parallel):切分"矩阵";
- 专家并行(expert parallel):把专家分片到不同位置。
Percy 已经讲过张量并行,所以大家已有大致心智模型。讲师从流水线并行(也叫逐层并行)讲起。
5.1 流水线并行
(参考时间: 00:31:48)
概念上非常简单:"把层切开、放到不同 GPU 上"——你刚学并行时大概就是这么想的。前向传播时传递激活值,反向传播时传递部分梯度。
可怕的"气泡"
如果就这么干,画面会非常难看:假设有 4 块加速器,各处理 1/4 的模型。图上时间从左向右,不同加速器是不同行。于是:
- 0 号先算第一层,算完就停,把计算交给 1 号;
- 此后它在很长时间里什么都不做,直到最后才又有活;
- 前向期间同一时刻只有一块 GPU 活跃;反向同理。
大部分时间 GPU 都在闲置,利用率糟糕透顶。这段什么都不做的区间就叫气泡(bubble)。
解决办法:按 micro-batch 流水
解决办法是批处理/流水化:不再"一层接一层"地串,而是搭一条流水线。图中若有 4 个待处理元素:
- 每处理完一个,就开始下一个;
- 同时把已完成的那个交给下一层。
这样元素像上下楼梯一样向上流、再向下流。要让利用率合理,关键是控制气泡时间与有效计算时间之比:大致是流水级数 / micro-batch 数。为了让气泡趋近于零,就需要很大的 batch——气泡以 $\frac{1}{\text{micro-batch size}}$ 的速度下降。
编者说明:这正是"batch size 是资源"的第二种用法——不仅数据并行在吃它,流水线并行也用它来填气泡。
流水线并行的价值
讲师引用民间说法:"并行代码看起来都很合理、大家都懂,直到你实现流水线并行。" 那为什么还要做?
- 相比 DDP,它能省内存(层被切开了);
- 也能和数据并行组合;
- 最重要的:它有非常好的通信特性——只依赖激活值,量级是 $B \cdot S \cdot H$(batch × 序列长 × 隐维),而且是点对点(一层连另一层),不是全互联。
因此实践中:
流水线并行会放在最慢的网络链路上——如果你有多个数据中心或多个 pod 之间通信慢,就用流水线并行跨越它们,因为它是通信最省的并行方式。
依赖 batch size
流水线性能极度依赖 batch size。讲师引用 Nvidia 的 Megatron-LM 论文里的一系列参数扫描:大 batch + 大流水线尺寸能得到接近"不用流水线"的利用率;但没有大 batch,性能会迅速退化。
学生问答:为什么流水线通信特性好?
(参考时间: 00:36:09)
问:为什么流水线比 FSDP 通信特性好?答:传的东西更少——是 batch × 序列长 × 隐维,几乎总比"传一整个参数矩阵"要小。
更聪明地减少气泡:从调度到"零气泡"
(参考时间: 00:36:34)
人们想了很多更聪明的方法来减小流水线气泡:
- 巧妙调度:把不同层、不同 micro-batch 的前向与反向交错,进一步压小气泡(取自 DeepSeek 的论文)。本质是调整前向/反向计算的时序。
- 零气泡流水线(zero-bubble pipelining)——讲师认为这个更巧妙,它不是调度问题,而是重新审视反向传播的结构。
零气泡的核心洞察:反向传播在每个计算图节点上其实做两件事:
- 把偏导继续往计算图下方传播——这是关键路径上的事,因为下一级必须等到你把这个信号传回去才能开工;
- 计算当前权重的梯度——这是叶子节点上的事,什么时候算都行。
于是把它拆开:用 $B$ 表示"往回流"的那部分,$W$ 表示"算权重导数"的那部分。
做法:尽快算完 $B$(它们必须优先),把 $W$ 推迟到计算有空隙时再算。这样几乎能完全填满流水线。
讲师说这个技术比通常愿意处理的要复杂得多,但几乎能彻底解决流水线气泡问题(取决于 $W$ 与 $B$ 的工作量比例)。他感慨:"这真是太巧妙了,系统层面能做的事情真多。"
提问环节((参考时间: 00:39:20)):讲师在进入下一张复杂幻灯片前停下来答疑,确认大家对流水线没有问题。
5.2 张量并行
(参考时间: 00:39:27)
有一个自然的类比:流水线并行 = 深度方向切分。而模型有两个缩放维度——深度和宽度。那沿宽度切呢?这就是张量并行(Percy 已讲过)。
核心想法:矩阵乘可以拆成更小的矩阵乘,再把部分和加起来——这与 tiling(分块)是同一个道理。这个核心原语反复出现。
一个 GELU 的例子
以 GELU 为例,通常做:
X → 乘矩阵 A → GELU → 乘矩阵 B(下投影) → Z
即一个串行计算。张量并行下:把 $A$ 切成两个子矩阵、$B$ 切成两个子矩阵,并行计算,最后再汇总。
前向与反向的对偶性
有一个重要的事实:前向与反向存在对偶关系。
- 前向:$F$ 是恒等(把 $X$ 复制两份),$G$ 是 all-reduce(把它们合并回来);
- 反向:翻转过来——$G$ 变恒等,$F$ 变成需要对偏导求和的操作。
这个对偶性在写张量并行时很重要。
列切与行切
切分方式有两类:
- 列切(column-wise):发生在输入处——MLP 的输入投影、注意力投影,在每个 Transformer block 里按列切;
- 行切(row-wise):发生在对应第二阶段——MLP 的下投影、注意力的输出,按行切;
- 小层(layer norm、非线性、MoE 里的 routers)则完全复制在各机器上——不值得为它们付切分开销。
何时用张量并行?
张量并行极度饥渴于计算、极度饥渴于通信:每个 matmul 都要通信(前向的 $G$ 里一次 all-reduce,反向一次 all-reduce),通信量是激活值量级,而且非常频繁。
因此:
张量并行只在节点内使用。GPU 上,8 块 GPU 紧密连在一个盒子内,最多到 8 张卡可以承受张量并行;一旦超过节点,就走跨机互联,性能会大幅下降。
这也回到前面 TPU 的话题:TPU 没有"8 卡超快、跨机变慢"的鲜明分界,而是有一大片网格。所以 TPU 用户会声称他们能比 GPU 世界张量并行到更大规模——因为他们能在规则网格上维持高带宽。这使 TPU 与 GPU 在"张量并行 vs 流水线并行"的配比上差异很大。
张量并行 vs 流水线并行
两者都是"模型切分"策略,都能省参数、也可能省激活。对比:
| 张量并行 | 流水线并行 | |
|---|---|---|
| 气泡 | 没有必然气泡 | 有气泡 |
| 复杂度 | 低(切 matmul) | 高 |
| 通信量 | 大($\approx 8 \cdot B S H$ 一次 all-reduce,全互联) | 小($B S H$,点对点) |
| 适用 | 高速互联(节点内) | 慢速链路(跨机/跨数据中心) |
结论:张量并行适合高速互联;其余场景优先流水线并行。
5.3 激活内存与序列并行
(参考时间: 00:45:03)
现在我们更仔细地看内存。对深度学习/语言模型最朴素的内存观是"内存 = 参数"(图里那部分绿色)。讲师已讲了优化器状态(黄色部分)。但看 PyTorch profiler 实测的内存曲线,故事远不止如此:
- 存在大量动态内存,需要存储所有激活值(那些红色大鼓包);
- 计算梯度时,反向扫描要保留它们;
- 内存峰值出现在"最大激活点之后一点"——即开始反向、需要保留很多激活值时。
所以要减内存,就得处理激活这块大红鼓包。
现代 LM 的现实:激活会盖过参数
(参考时间: 00:46:32)
看现代 LM 的内存图:在大模型、中等序列长下,激活内存会彻底"盖住"参数内存。因此任何省内存策略都必须处理激活,只处理参数内存不够。
激活内存的经验公式
如果什么都存,激活量大致是:
$$ \underbrace{34 \cdot S \cdot B \cdot H}_{\text{线性项}} \;+\; \underbrace{5 \cdot \frac{A \cdot S}{H}}_{\text{注意力二次项}} \;=\; S B H\left(34 + \frac{5AS}{H}\right) $$
其中 $S$ = 序列长,$B$ = batch,$H$ = 隐维,$A$ = 注意力头数。$SBH$ 依赖是根本性的:序列、batch、隐维每一维都要存东西,所以 $SBH$ 会反复出现。
那个奇怪的 $5AS/H$ 项来自二次注意力项(含 dropout)——用 Flash Attention 做重计算可以丢掉这一项。
编者拓展|这个公式从哪里来? 更标准地写,单个 Transformer 层的激活约为 $sbh \cdot \left(34 + \frac{5as}{h}\right)$,展开后即 $34sbh + 5as^2b$。前一项是逐点操作、归一化、残差等"线性"存储;后一项是注意力分数矩阵一类 $s^2$ 级别的存储(乘上头数 $a$ 与 batch $b$)。因为序列维是平方增长,长序列下这一项会迅速主导内存——这正是 Flash Attention 用重计算(recompute)把它省掉的价值所在。相关细节可参考 Korthikanti 等人的论文《Reducing Activation Recomputation in Large Transformer Models》。
张量并行对激活的影响
张量并行会切分注意力与 MLP 的矩阵乘,而这两部分正是那 34 里的 24(MLP)与二次注意力项 $5AS/H$。这部分可以除以张量并行度 $T$,算不错——大部分内存能随 $T$ 线性下降。
但有些东西不随之减小:layer norm、dropout、注意力与 MLP 的输入(要作为残差保留给反向)。张量并行不切 layer norm,也就不切这些激活。结果:即便有上千张 GPU 做张量并行,你仍然要承受大约 $10 \times SBH$ 的惩罚。
序列并行(sequence parallel)
(参考时间: 00:49:30)
补救办法是与张量并行搭配使用的序列并行。讲师吐槽这个名字极具误导性——更自然的叫法其实是"上下文并行(context parallel)"。
做法:对那些剩下的轻量项(约 $10 \cdot SBH$,如 layer norm,计算量很小),沿序列维度而非隐维切分。代价是在每次需要这些激活的操作前做 all-gather 与 reduce-scatter。
这与 FSDP 的思想非常像:以分片形式存储激活,需要时再物化出来。同样存在对偶性:前向里 $G$ 是 all-gather、$\bar{G}$ 是 reduce-scatter;反向里两者互换。
激活内存的四级递进
| 方案 | 激活内存 |
|---|---|
| 完全不并行 | $34 \cdot SBH + $ 注意力头项 |
| 张量并行 | MLP 与注意力项 $\div T$,但剩下点对点操作不省(约 $10\,SBH$) |
| 张量并行 + 序列并行 | 完全线性依赖 |
| 再做激活重计算 | 可丢掉二次项,得到 $\dfrac{34 \cdot SBH}{T}$ |
关键结论:$$
\text{激活内存下界} \;\approx\; \frac{34 \cdot S \cdot B \cdot H}{T}
$$
这是"常规训练"下你能合理达到的激活内存下界。手算模型能否装进 GPU 时,记住这个下限,再加上优化器状态、参数、梯度的内存,就能粗略估计总内存需求。
学生问答:重计算能省多少?
(参考时间: 00:51:15)
问:24 里 MLP 那部分不能被重计算省掉吗?答:可以重算 MLP,但在列出的之外做重计算计算代价极高——重算 MLP 意味着反向时再跑一遍 MLP,通常不值得。注意力的重计算一般更便宜,因为它是按 tile 做的,而且你不愿承担那个二次代价(太贵)。
提问环节((参考时间: 00:52:15)):讲师暂停,确认大家对流水线和张量并行没有疑问。
六、专家并行
(参考时间: 00:53:21)
现在讲"标准并行工具箱"里的最后一块:专家并行(expert parallel, EP)。既然 MoE 已是标配(如今大多数大模型都是 MoE),就能利用它的一大好处——专家并行。
讲师认为专家并行在概念上与张量并行类似:
- 都是拿 MLP(网络的 FFN 部分)来切;
- 都会付通信代价;
- 系统行为也大致像张量并行——是高带宽的并行原语,也能减少激活。
为什么 MoE 更偏好 EP 而非 TP?
讲师引用了 Megatron 的并行指南截图,其中一条建议是:EP 优于 TP。原因(也是一份张量并行缺点清单):
- 切得太细,矩阵变小,GPU 利用率变差——你希望 matmul 尽可能大,而张量并行会缩小它;
- MoE 层里,路由稀疏的 token 激活比路由"密集的大张量并行 matmul 激活"容易得多;
- 可以把 token 精确路由到需要的地方,跳过一些开销;
- 既然已经是 MoE,不如让专家数量本身分散到所有设备上。
但 EP 仍然很难
讲师提醒:别以为"EP 好、大家都该用"就完事。EP 依然非常复杂。FSDP 之后的张量并行、流水线并行、专家并行,系统上都很不平凡。他点了两个库来强调这件事的严肃性:
- DeepSeek 的 DeepEP:DeepSeek V3 时代他最爱的成果之一,是自家做专家并行路由与调度的库,深入到底层 GPU 网络原语,试图合并操作、让硬件直接处理某些操作,把 MoE 路由做到尽可能高效;
- NVIDIA 的 Hybrid EP:同样是专家并行调度的高效底层硬件实现。
为什么难? 因为要做大量的 all-to-all dispatch。MoE 的通信模式很像张量并行:每碰到一个 MLP,就要把 token 路由到各处,而且必须低延迟——因为计算在等 token 到达,压缩 dispatch 延迟极其重要。
一个有趣的冷知识:DeepSeek 团队为了榨干最后一点性能,翻出了未公开的 PTX(GPU 机器码),找到如何用这些未公开指令进一步加速网络通信。这就是要到并行与效率前沿所必须达到的层次。
EP 与 DP 的耦合约束
(参考时间: 00:58:03)
前面讲师都假设各种并行原语可以像乐高一样随便拼——对大多数策略确实如此(比如数据并行 + 张量并行很容易组合)。但专家并行有额外约束需要尊重。
朴素做法(许多旧库采用)是让 DP 和 EP 的副本是同一套:比如数据并行度为 8,就把 8 个专家分片到 8 个副本上,数据也分到 8 个副本上、以各种方式路由。也就是说,先按 DP 切 GPU,EP 是这层切分的一个子集。这很自然(因为在路由 token)——但它给 EP 能并行到多远设了上限,并约束了 DP 与 TP 如何交互。
一个有趣的结构性后果:EP 对模型的应用是不均匀的
(参考时间: 00:59:32)
关键事实:MoE 只改 MLP,不改注意力。
- 所以专家并行只并行化 MLP,不并行化注意力;
- 想并行注意力,可能还得用张量并行;
- 但如果你张量并行度很高、专家并行度也很高,矩阵会被切成非常小的块,利用率很差。
于是产生一个别扭的权衡:注意力想要高张量并行度,MLP 想要低张量并行度——互相冲突。
近年来的系统解法:把 MLP 与注意力的张量并行解耦——注意力层用一种张量并行,MoE 层用另一种,从而完全解耦并行策略,得到更复杂但更有效的 EP + TP + DP 组合。
七、上下文并行(Context Parallel / Ring Attention)
(参考时间: 01:01:00)
最后一块是上下文并行,也叫 ring attention:把很长的序列的激活切分到不同加速器上,然后以环状方式沿着网络的 mesh 拓扑,把数据传到需要它的设备。
- ring attention 是原始论文,最早证明了这套在 TPU 上效果很好;
- 上下文并行是把这个做法标准化后的并行策略;
- 两者都用于长上下文扩展阶段和模型推理服务。
讲师不展开讲,因为它在概念上与前面讲过的很多东西重叠——读者理解到这里就够了。
编者拓展|Ring Attention 的一句话 intuition 注意力需要每个 query 看到所有 key/value。把序列切成若干块放到不同设备上后,每块设备先算"本地子注意力",然后把 key/value 块沿环传递给邻居,边传边累加。于是每一轮每个设备都在算,通信与计算重叠;传 $N$ 轮后,每个 query 就见过全部 key。它避免了显式地物化 $S \times S$ 的注意力矩阵,也让超长序列的激活得以分片。
八、并行策略总览表
(参考时间: 01:01:51)
把一切拼起来。讲师做了一张大表,前两行是数据并行,下面是各种模型并行。他用红色标出各方法的主观缺点,用意是传达一个要点:
不存在某个严格占优的并行策略。它们全都是权衡,你必须优雅地管理这些权衡,才能得到好结果。
举例说明这些权衡如何相互补足:
- FSDP 很棒,但帮不了激活,还消耗 global batch size,所以有极限;
- 想省激活,可能得搭配张量并行(它不动 batch size);
- 但张量并行需要快速网络和高带宽;
- 想利用慢速链路,可能得搭配别的策略(如流水线)。
于是你会明白:每一种策略都有自己的位置。并非所有架构都用全部策略,但很多大规模架构会使用其中一大组合。
学生问答((参考时间: 01:03:20)):流水线和 FSDP 对 MoE 适用吗?答:绝对适用。标准建议是 EP 像 TP 一样,最多用到"8 条快连接"级别;现在人们不一定严格照做,但 FSDP/数据并行、流水线、张量并行在前沿模型里都被广泛使用。
编者说明:讲师说的"红色标注缺点"提醒我们,并行策略的选择本质是约束优化——不是挑一个最强的,而是根据网络拓扑、模型形状、batch 预算,把几块拼在一起,让算力和通信都尽量被填满。
九、如何选择并行策略:从"屋顶线"到一句处方
(参考时间: 01:04:03)
讲师说并行有趣的一点是:你可以做数学。可以问:
- 对不同分片策略,每层做多少计算?
- 对不同通信策略,每层做多少通信?
- 若把不同设备分配给不同通信策略,这些量如何扩展?
然后就能算:给定 batch size 和某种并行组合,GPU 利用率是多少——即计算时间与通信时间的比值。
核心判据:只要计算时间比通信时间长,原则上就能把通信隐藏在计算之下,从而高效。
屋顶线(roofline)图
(参考时间: 01:04:56)
讲师展示了一张图:顶部虚线是"高效区"边界——之上是把计算用满,之下是落在坏的一侧、在等通信。
一个符合直觉的现象:
- batch size 足够大(比如每芯片 2000)时,只用 FSDP 就很好——完全 compute-bound;
- 但batch size 下降时,只靠 FSDP 会撞到通信瓶颈;
- 这时引入张量并行(MP),就能把曲线往外推一点,在更小 batch 下仍保持 compute-bound;
- 继续加策略就能继续往外推。
这就是所谓 3D / 4D 并行——"我没听说有 5D"——把所有策略组合起来,在各种通信拓扑下让计算单元满载。
一条极简处方
(参考时间: 01:06:19)
讲师说前面讲了太多一般性内容,可能显得复杂,但策略其实很简单:
1. 只要模型还装不进内存,就用任何必要手段切模型: - 在快速互联上用张量并行或专家并行(如每机 8 卡,就用到 8); - 用流水线并行或 ZeRO Stage 3(FSDP)把剩下的路走完,直到模型装下。 2. 一旦模型装得下,剩下的 GPU 全部拿来做数据并行。 3. 如果 batch size 太小,用梯度累积来提高 GPU 利用率。
这被实践验证
讲师给出 Megatron 的 MoE 并行指南链接,但其思想对密集模型同样适用。指南的条目恰好是上面流程的"反序"表述:
- 尽量少模型并行、多数据并行——能拿 GPU 切数据就拿去切数据;
- 用 GPU 时留在 NVLink 之内(即一台机器 / 一个盒子)——把 EP 和 TP 都限制在一个盒子内;
- 要跨多节点,就用流水线并行;
- 若是 MoE,优先专家并行;
- 若序列很长,用上下文并行(ring attention)。
这与讲师整堂课要传达的思想完全一致,只是以"实践者手册"的形式呈现。
学生问答((参考时间: 01:08:14)):
- 序列并行常与张量并行搭配、以减激活,更像一个附加项,很多情况下不是独立的单独策略。
- 关于"循环 Transformer(loop transformer)传闻会让并行更简单还是更难":讲师说他不太买这传闻的账。若真如此,会更难——FSDP 的前提是"取权重、丢权重、再取回来",而循环模型不丢任何东西;不过它参数效率高,或许很多模型并行就没那么重要了。总之"会不一样"。很有兴趣看看。
十、真实训练案例
(参考时间: 01:09:36)
讲师用一组论文讲真实训练。虽然有些论文较早,但网络基本没怎么变,所以洞见至今适用。
Megatron 的大规模实验(讲师最推荐的资源之一)
(参考时间: 01:09:36)
这是一篇 Nvidia(以及前 Stanford 的 Matei、Deepak 等人)的论文,跨多种配置做大规模并行训练,告诉你随着规模扩大、并行策略该如何变化。图中正是前面讲过的处方:
- 数据并行拉满;
- 张量并行不断增加,直到 8 就停(不再加);
- 从那一刻起流水线并行不断增大;
- 到足够大规模时,数据并行反而下降,最终 DP 只有 6——因为你必须用这么多张量 + 流水线并行才能装下模型,剩下的预算才给数据并行。
把所有策略合起来看,即便 GPU 数量夸张到荒谬,利用率依然非常平稳、很好。讲师说,这正是为什么你会看到这些庞大的数据中心建设:并行策略如此有效、通信硬件如此好,以至于即便巨型数据中心、甚至跨数据中心训练,也能在这些不同区间获得很好利用率。
论文还有很漂亮的定量证据:不同 batch size 下张量并行该停在哪——清楚显示张量并行尺寸为 8,超过就麻烦;流水线并行也需要大 batch 才能高效利用机器(这解释了图中蓝橙之间的间隙,流水线越长,间隙越大)。
另一个反直觉的洞见:应该多做激活重计算。因为重计算能省内存,内存可以换算成 batch size,更大的 batch 又带来更高利用率。这乍看反直觉——通过"多算"来获得更高利用率——但逻辑成立:省内存 → 换更大 batch → 更好利用。
Olmo(AI2,7B)
(参考时间: 01:12:46)
Olmo 是 AI2 的开源 7B 模型,训练在 Dolma 数据集上(细节在 Dolma 论文里)。它完全用 FSDP 训练,跨很多加速器。这是"FSDP 扩展得出奇地好"的例子——训练小模型时,即便到很多 GPU,FSDP 也是相当好的策略。许多 7B 级模型纯用 FSDP 训练。
DeepSeek
- DeepSeek V1:只用数据并行 ZeRO Stage 1,搭配张量并行、序列并行、流水线并行(即前面讲过的经典组合)。
- DeepSeek V3:MoE 模型,除了流水线并行,还用专家并行取代张量并行。其专家并行有点特别:做到 64 路并行(把 8 台机器编成一组,作为专家并行的域)。为了支撑这么大的专家并行,他们用了流水线并行里的那些技巧,避免专家并行出现低利用率期——是相当复杂的招数。
Yi(中国开源权重)
(参考时间: 01:14:23)
经典组合:ZeRO Stage 1 + 张量并行 + 流水线并行。一旦转到 MoE,就把张量并行换成专家并行——两者服务的目标相似,但专家并行更高效。
Llama 3(巨型密集模型)
(参考时间: 01:14:49)
Llama 3 报告讲师很喜欢,因为它是少数逐阶段完整列出并行策略的报告:
- 最上面一行是预热阶段(可忽略);
- 主预训练阶段(中间行)是非常标准的策略:张量并行 8、上下文并行 1、流水线并行 16、数据并行 128——很大的数据并行切分;
- 最后为了做长上下文扩展,上下文并行调高、数据并行调低,以应对这个非常耗内存的阶段。
注意这里用的是张量并行而非专家并行——因为 Llama 3 405B 是巨型密集模型,不是 MoE。
一个值得一提的侧枝:GPU 老坏。如果去这些公司做 infra 工程师,你会发现 GPU 成天坏。据说 Llama 3 405B 训练期间 GPU 坏了 148 次。所以你不仅需要快速并行,还需要冗余来应对各种糟糕情况——这也是一个分布式系统挑战。
Gemma 2(Google 开源)
(参考时间: 01:16:24)
Gemma 2 用 FSDP + 张量并行 + 序列并行,只用这两种策略。讲师之所以拎出它,是因为它基本印证了 Google 的主张:对 TPU,你不需要流水线,只要拿一个超大的环面网格、在其上做张量并行即可。这种"能不能无限扩展"的问题对他而言一直不太清楚,但至少在 Gemma 这个规模上成立。
Mixtral、NeMo Tron 3、Qwen 3
(参考时间: 01:17:04)
在调研今年训练的模型(如 Mixtral 8x22B)时,讲师发现一个宝库:Nvidia 的 Megatron Bridge 仓库,为许多不同模型规模/设置发布了推荐的训练配置。你可以去看他们对 8x22B MoE 或 DeepSeek V3 这种模型给出的配置。
- Mixtral:专家并行 8、流水线并行 4、额外张量并行 4(后者用于注意力层)。符合"EP 大致保持在 8 左右"的处方;
- NeMo Tron 3 Super:沿用 DeepSeek V3 模式,大量专家并行,加上下文并行(至少在这篇文章里,他们在做扩展);
- Qwen 3:沿用 DeepSeek 配方——专家并行 32、流水线并行 8、张量并行 2(后者用来切注意力矩阵等)。
讲师还提到 Nvidia 对不同模型并行方式的基准测试很有意思:即便在张量并行内部,也有各种子配置,会显著影响性能——系统集成的影响相当大。
案例总结
(参考时间: 01:19:04)
共同点:
- 所有模型都尽量用数据并行,把 DP 域最大化;
- 张量并行几乎总是保持在 8 以下;
- 专家并行现在有时可以很大——部分归功于 DeepSeek V3 以及他们为大规模专家并行训练构建的基建。
十一、全讲总结
(参考时间: 01:19:20)
最高层次的观点:我们需要思考多 GPU、多节点、甚至多数据中心的并行,并在这种规模下思考效率。要真正做到高效,必须调动所有手段——因为你既有快链路、又有慢链路,还有"batch size"这类可以被消耗的资源。所有这些资源都要尽量用满。
而给定这一切,组合各种并行形式其实有相当简单的经验法则,最终能达到对计算硬件的近乎满负荷利用。
讲师预告:下周讲缩放定律(scaling laws)。
附:参考与延伸阅读
编者补充
已知疑点
本节集中列出本电子书在重构过程中遇到的所有不确定之处,供读者自行判断。凡涉及具体数字的地方,建议以课程官方讲义与原始论文为准。
-
激活内存公式的精确形式((参考时间: 00:47:00 附近))。 字幕中出现"$34 \cdot S \cdot B \cdot H$ 加上 $5 \cdot AS/H$"的表述,并对 $AS$ 给出口头解释"注意力头数 × 序列长度",但口播含糊。本电子书按标准文献(Korthikanti 等)理解为 $S B H\left(34 + \dfrac{5AS}{H}\right) = 34\,SBH + 5\,A S^2 B$, 其中二次项对应注意力分数矩阵存储。若与官方幻灯片不一致,以幻灯为准。
-
"张量并行通信量 $\approx 8 \cdot B S H$"中的系数 8((参考时间: 00:44:36))。 字幕原始表述为"8 * B * S * H times roughly one all-reduce",但紧接着又说"这不只是点对点,而是 all-to-all"。这个"8"是经验系数还是张量并行度,讲师口播未完全明确,编者倾向理解为与具体并行度相关的经验量级。原文保留其模糊性。
-
ZeRO Stage 1 的 all-gather 时机与内存回收。 字幕讲"参数更新后 all-gather 回去",但对参数副本在更新完成后是否会释放未明说。本电子书按字面记录,未补充推测。
-
华为昇腾 910 单机架 384 卡、功耗为 Nvidia 同类系统 4 倍。 讲师口播"384"和"四倍",未指明用于对比的具体 Nvidia 系统型号。数字沿用原话,确切规格请查官方资料。
-
Llama 3 405B 训练期间"GPU 故障 148 次"。 字幕原话为"failed 148 times",讲师未展开定义(是硬件故障中断次数,还是含软件/网络问题的中断次数均有)。数字沿用原话。
-
DeepSeek V3 的"64 路专家并行"表述。 字幕说"8 台机器一组构成 EP 域"、"64 路并行",但 8 台 × 每台卡数的组合关系未在字幕中完整说明。本电子书按"专家并行域约等于 8 台机器"记录,未补算具体卡数。
-
"TPU AI 今早宣布"((参考时间: 00:07:38))。 这是课堂当天(2026 年春季)的即时新闻,讲师提到的具体产品名("TPU AI"、训练芯片"TPU 8T"、"Virgo 网络")由口播转录,可能存在听写偏差。请以 Google 官方发布为准。
-
Qwen 3 与 NeMo Tron 3 Super 的具体并行配置数字。 字幕给出 Qwen 3 为"EP 32、PP 8、TP 2",Mixtral 为"EP 8、PP 4、TP 4",均属快速口播,数字可能听错,请以 Megatron Bridge 官方配置为准。
-
本讲所涉工具/库的官方地址。 文中对 DeepEP、Megatron、Megatron Bridge、NCCL 等给出的链接为编者查找的常见官方页面,未经课程官方确认;如课程讲义另有指定,以讲义为准。
-
本讲未出现
course/官方讲义与幻灯片。 本书插图以官方 PDF 幻灯片为主(见文末「附录:官方幻灯片(全部)」),并辅以视频帧;页码与视频时间点的对应依据画面匹配推断,可能与实际略有偏差,请以原始视频为准。
附录:课堂未展示的幻灯片
🖼️ 第 1 页幻灯片 · Lecture 8
🖼️ 第 2 页幻灯片 · Outline and goals
🖼️ 第 3 页幻灯片 · Organization today:
🖼️ 第 4 页幻灯片 · Limits to GPU-based scaling – compute
🖼️ 第 5 页幻灯片 · Limits to GPU-based scaling - memory
🖼️ 第 6 页幻灯片 · What do we do? Multi-GPU, multi-machine parallelism
🖼️ 第 7 页幻灯片 · But first.. Some basics about collective communication
🖼️ 第 8 页幻灯片 · Important detail – all reduce vs reduce-scatter-gather.
🖼️ 第 9 页幻灯片 · TPUs vs GPUs – design differences at the comm level
🖼️ 第 10 页幻灯片 · Mesh vs tree vs other
🖼️ 第 11 页幻灯片 · But then things change.. TPU8i/t
🖼️ 第 12 页幻灯片 · Why not connect everything?
🖼️ 第 13 页幻灯片 · Part 1 recap
🖼️ 第 14 页幻灯片 · Part 2 – Standard LLM parallelization primitives
🖼️ 第 15 页幻灯片 · Naïve data parallelism
🖼️ 第 16 页幻灯片 · What’s wrong with naïve data parallel?
🖼️ 第 17 页幻灯片 · What’s wrong with naïve data parallelism? - Memory
🖼️ 第 18 页幻灯片 · ZeRO – solving the memory overhead issue of DP
🖼️ 第 19 页幻灯片 · ZeRO stage 1. optimizer state sharding
🖼️ 第 20 页幻灯片 · ZeRO stage 1. how it works
🖼️ 第 21 页幻灯片 · Comparing ZeRO stage 1 and naïve data parallel
🖼️ 第 22 页幻灯片 · ZeRO stage 2. the simple extension to gradient sharding
🖼️ 第 23 页幻灯片 · ZeRO stage 2. how it works
🖼️ 第 24 页幻灯片 · ZeRO stage 3 (aka FSDP) shard everything
🖼️ 第 25 页幻灯片 · ZeRO stage 3 (aka FSDP) how it works (baby version)
🖼️ 第 26 页幻灯片 · Actual picture of how FDSP / ZeRO stage 3 works
🖼️ 第 27 页幻灯片 · What’s the point?
🖼️ 第 28 页幻灯片 · ZeRO in practice: will it fit?
🖼️ 第 29 页幻灯片 · Issues remain with data parallel – compute scaling
🖼️ 第 30 页幻灯片 · Issues remain with data parallel – models don’t fit
🖼️ 第 31 页幻灯片 · Beyond data parallel – model parallelism
🖼️ 第 32 页幻灯片 · Layer-wise parallel
🖼️ 第 33 页幻灯片 · What’s wrong with layer-wise parallel
🖼️ 第 34 页幻灯片 · A solution: pipeline parallel
🖼️ 第 35 页幻灯片 · Why pipeline parallel?
🖼️ 第 36 页幻灯片 · Pipeline performance is highly dependent on batch size
🖼️ 第 37 页幻灯片 · Trading communication bandwidth for utilization
🖼️ 第 38 页幻灯片 · ‘Zero bubble’ pipelining
🖼️ 第 39 页幻灯片 · Model parallel along the width axes
🖼️ 第 40 页幻灯片 · Tensor parallel – GPUs have submatrices
🖼️ 第 41 页幻灯片 · Row vs Column tensor parallel
🖼️ 第 42 页幻灯片 · When do we tensor parallel?
🖼️ 第 43 页幻灯片 · Tensor parallel – pros and cons vs pipeline parallel
🖼️ 第 44 页幻灯片 · A final complexity – memory is dynamic!
🖼️ 第 45 页幻灯片 · A final complexity – activation memory
🖼️ 第 46 页幻灯片 · What’s the activation memory per layer?
🖼️ 第 47 页幻灯片 · Activation under tensor parallel
🖼️ 第 48 页幻灯片 · Making memory truly linear – sequence parallel
🖼️ 第 49 页幻灯片 · Making activation memory fully scale with more machines
🖼️ 第 50 页幻灯片 · Expert parallelism
🖼️ 第 51 页幻灯片 · Why EP?
🖼️ 第 52 页幻灯片 · Complexity – combining EP and others
🖼️ 第 53 页幻灯片 · Complexity: Decoupling attention / expert parallelism
🖼️ 第 54 页幻灯片 · Other parallelism strategies
🖼️ 第 55 页幻灯片 · Recap: LLM parallelism table
🖼️ 第 56 页幻灯片 · Model vs Tensor parallel (TPU book)
🖼️ 第 57 页幻灯片 · ‘3D (4D) parallelism’ – putting it all together
🖼️ 第 58 页幻灯片 · Example from Metagron’s current recommendations
🖼️ 第 59 页幻灯片 · Scaling strategies from Narayanan 2021
🖼️ 第 60 页幻灯片 · Careful ‘3D’ parallelism gives linear gains
🖼️ 第 61 页幻灯片 · Tensor parallel = 8 is often optimal
🖼️ 第 62 页幻灯片 · Activation recomputation can pay for itself (via memory)
🖼️ 第 63 页幻灯片 · Recent LMs – what do they do?
🖼️ 第 64 页幻灯片 · DeepSeek
🖼️ 第 65 页幻灯片 · Yi
🖼️ 第 66 页幻灯片 · Llama3 405B
🖼️ 第 67 页幻灯片 · Llama 3 405B
🖼️ 第 68 页幻灯片 · Gemma 2
🖼️ 第 69 页幻灯片 · Mixtral 8x22B
🖼️ 第 70 页幻灯片 · Nemotron 3 Super 120B-A12B
🖼️ 第 71 页幻灯片 · Qwen 3
🖼️ 第 72 页幻灯片 · Overview table of model parallelism
🖼️ 第 73 页幻灯片 · Recap for the whole lecture