想象你是一家高档餐厅的总厨,晚高峰突然来了两千桌客人,每桌都要同一道招牌菜。你一个人守着一个灶台,就算手艺再好,一晚上也出不了几十份。于是你向老板申请加灶台、加厨师。可老板提醒你:多人协作不是简单地复制你,得有章法。有人提议:让四个厨师各拿一份同款菜谱,各自用不同的食材做完整的菜,做完后碰头统一改良菜谱;有人说:这道菜太复杂,干脆把菜谱按工序拆开,酱汁、主料、摆盘各归专人;还有人建议:把厨房改成流水线,洗切、烹炒、装盘分成三段,盘子一盘接一盘地传。这三条路,正是多 GPU 训练世界的三种并行策略:数据并行、模型并行与流水线并行。理解了这场厨房改造,你就理解了 AI 大规模训练的核心组织方式。
掌握多 GPU 并行策略,是每一位大模型从业者的基本功,直接决定训练的速度、成本与团队能否把模型“喂饱”。
可视化演示
展示数据并行(AllReduce梯度同步)、模型并行(层内张量切分)、流水线并行(stage划分与气泡)三大策略的原理与通信模式,三模式切换理解并行方案选型。
本节配有交互动效(进入视口后自动加载,约 3KB)。
'+C1+'
并行训练逻辑
主厨先算了一笔账:单灶台一晚上最多出 200 份菜,而订单有 2000 份。多开几个灶台看似简单,但厨房不是人越多越快——统一下单、食材协调、出菜检验这些环节,都必须所有厨师同步等待,无法并行。这几段“开不了小灶”的时间,直接决定了整晚能出多少桌菜。
训练深度学习模型同样如此。训练过程可以理解为“试做菜”:前向传播是照着菜谱试做一道菜,反向传播是试吃后倒推每一步哪里出了问题,给出调整建议,优化器再修改菜谱。单张 GPU 算力再强,面对大模型的海量参数与海量数据,试做周期也会拉长到数周甚至数月。多 GPU 并行就是把大任务拆成小块,但无论怎么拆,都受一条铁律约束:可并行的部分能随 GPU 数线性加速,不可并行的部分会成为天花板。
这条铁律叫 Amdahl 定律。设串行时间占比为 f,GPU 数为 N,加速比 S 为:
所以,主厨不是盲目加灶台,而是先找出哪些环节没法并行——比如开菜单、对账。GPU 集群也一样,拿到一台多卡机器,第一步永远是量化串行瓶颈在哪,再决定用什么并行策略。
- 串行时间占比 f初始化、模型同步、控制逻辑等无法并行的部分占总训练时间的比例,f 越接近 1,并行收益越小。
- 并行部分均摊剩下的 \(1-f\) 时间可以被 N 张卡瓜分,卡越多这一项越小,但永远不会变成零。
- 加速比 S单卡总耗时与并行后总耗时的比值,极限是 \(1/f\)。分母里每一项都大于零,所以 S 永远追不上 N。
数据并行原理
老板拍板的第一套方案:四个厨师各拿一本同款菜谱,从四堆不同的食材中各取一份,各自完整地做一道菜。每隔一段时间,四人围坐在一起,把刚才试吃的心得汇总平均——“盐少了”“火候过了”——统一修订菜谱,再继续做下一批。每轮改进都建立在四份经验之上,学习效率翻了四倍。
这就是数据并行(Data Parallel)。每张 GPU 上都存放一份完整的模型副本,各自读取不同的 mini-batch 数据,独立完成前向与反向传播,算出各自的梯度;随后通过 All-Reduce(一种把所有卡的梯度汇总后再发给每一张卡的集体通信操作)把梯度求平均,用平均梯度统一更新模型权重。相当于把 batch size 放大了 N 倍,训练效果和用超大 batch 在单卡上训练近似等价。
数据并行实现简单、扩展性好,是最常用的并行方式,但短板是通信:每轮更新都要把全部梯度汇总一次,模型越大,同步通信量越大。假设模型大小为 M 字节、卡间带宽为 B 字节/秒,每轮同步时间近似为:
四名厨师各自做菜的时间可以完全重叠,但“碰头开会”的时间没法重叠。菜谱越厚(模型越大),开会越久——当模型大到一定程度,每轮同步的通信开销就会吞噬所有加速收益,逼着团队寻找第二种方案。
- 模型大小 M模型全部参数占用的字节数。比如 70 亿参数用 FP16 存储,约 \(1.4 \times 10^{10}\) 字节 = 14GB,M 越大同步越久。
- 系数 2梯度同步要先把所有卡的梯度规约求和,再把结果广播回每张卡,通信总量相当于两趟全量模型大小。
- 带宽 BGPU 间互连的等效带宽(如 NVLink、InfiniBand)。带宽越高,同步越快,这也是数据并行对硬件互联敏感的原因。
模型并行原理
第二种方案:招牌菜实在太复杂,一本菜谱两百页,没人能完整背下来。主厨把菜谱按工序拆成四份——酱汁部、主料部、摆盘部、出品部——每个厨师只精通一块。做一道菜时,半成品必须依次经过每位厨师的手:我做完酱汁递给你,你调好主料再递给他。
这就是模型并行(Model Parallel)。它把网络结构本身拆开,分给多张 GPU 共同承载。拆法有两大类:层间并行把不同层分给不同 GPU,激活值逐层串行传递,这是流水线并行的雏形;层内并行也叫张量并行(Tensor Parallel),把同一层里的权重矩阵切开,多卡合力算一个层。大型 Transformer 模型更常用张量并行,因为单层的矩阵乘太大了。
具体做法是:一个大矩阵乘 \(Y = XW\),把权重按输出维度切成 P 块,每张卡只算自己那块 \(XW_i\),最后通过一次 All-Reduce 把结果聚合起来。公式写作:
拆菜谱让每位厨师只背五十页,但每道工序之间都要“递一次菜”。如果递菜通道太窄(网络带宽低),频繁的层内通信就会拖慢节奏——这才有了下一节流水线并行,用更少的通信承担切模型的任务。
- 输入 X同一份激活值被广播到参与张量并行的所有 GPU,各卡共享同一输入。
- 权重分片 W_i把权重矩阵按输出维度切成 P 块,每张卡只保存并计算一块,内存压力降为原来的 \(1/P\)。
- 聚合运算 ⊕各卡把局部结果拼接后求和,得到与单卡完全等价的输出 Y。这一步 All-Reduce 就是模型并行的主要通信成本。
流水线并行原理
老板又提出第三种方案:既然菜谱已按工序拆好,不如把厨房改成流水线——洗切、烹炒、装盘三段接力。传统做法是一次只传一个托盘,那么启动时装盘工得空等,收尾时洗切工得空等,这些“空转”就是气泡。聪明的做法是同时送多个托盘,让各段始终有活干。
流水线并行(Pipeline Parallel)是层间模型并行的工程化升级。它把模型按层分成 P 个阶段,每个阶段放在一张或一组 GPU 上;训练数据被切成 M 个微批量(micro-batch),像托盘一样依次流经各阶段,前向传播和反向传播可以交错进行。以 1F1B 调度为例,每个阶段在算完一个微批次的前向后,立刻算下一个微批次的反向,避免长时间闲置。
衡量流水线效率的核心指标是气泡占比:把 M 个微批量送进 P 段流水线,总时间相当于 \(M + P - 1\) 个时间段,其中开头 P-1 段在“填充”、结尾 P-1 段在“排空”,空闲占比为:
流水线让“传菜”从频繁的手递手变成流水线上的托盘滑动——只在相邻阶段传递一次激活值,通信频率比张量并行低得多。只要托盘足够多,各段厨师就能像齿轮一样咬合转动,气泡被挤到最小。
- 阶段数 P模型按层切成的段数。12 层网络分 3 段,P=3,每段放 4 层。
- 微批量数 M一个大的训练批次被切成 M 个微批量依次进入流水线。M 越大,流水线越“满”,空档越少。
- 气泡占比填充期和排空期的空闲时段占整个周期的比例。当 M 远大于 P 时,近似为 \((P-1)/M\),所以实践中 M 通常取 P 的 4 到 8 倍。
混合并行策略
真正的大宴会厨房从来不止一套方案:十几个灶台同时开火炒菜(数据并行),每个灶台上又有几位厨师各管一道工序(模型并行),同时备菜、炒菜、装盘之间形成流水线(流水线并行)。三种协作方式拧成一股绳,这就是混合并行。
现代大模型训练几乎都在用混合并行。以 Megatron 系列框架为例,训练 LLM 时会同时启用数据并行、流水线并行和张量并行,构成“3D 并行”:数据并行扩大每轮吃下的数据量、提升吞吐;流水线并行把模型纵向切成多段、降低单卡显存压力;张量并行把每段内的层再横向切开、进一步分摊显存并提升单层计算并行度。三种并行度之间存在简单的乘法关系:总 GPU 数等于三者之积。
就像大厨房里有人管全局出餐节奏、有人管具体灶台、有人管切配——3D 并行把 GPU 编排成一支分工明确的“后厨团队”。但这支团队能不能高效运转,最终还得看传菜通道(通信网络)是否够宽。
- 数据并行度 N_DP模型被完整复制的份数,决定每轮能处理多少数据,对应吞吐量。
- 流水线并行度 N_PP模型纵向切成多少段,决定模型在“深度”方向被摊薄多少。
- 张量并行度 N_TP每段内部把权重横切成多少片,决定模型在“宽度”方向被摊薄多少。
通信开销平衡
主厨最怕的不是做菜慢,而是“空转等菜”:灶台五分钟能炒完一道菜,传菜生却要八分钟才把食材送到,厨师只能干等。协作厨房的效率,不取决于做菜最快的环节,而取决于“做菜 + 传菜”整条链路。
多 GPU 训练同理。每次迭代的实际耗时等于计算时间加通信时间(两者若能重叠,则取较大者)。三种并行策略的通信特征差异很大:数据并行每轮传全量梯度,通信量正比于模型大小;张量并行每层都要聚合一次激活值,通信频繁但对单次传输量要求不大;流水线并行只在阶段边界传激活值,通信频率低、单次量也不大,代价是气泡。带宽越高、拓扑越优,通信占比就越低。
工程上用一个简洁的效率指标来评估配置是否合理:设计算时间为 \(T_{\text{compute}}\),通信时间为 \(T_{\text{comm}}\),效率 \(\eta\) 定义为计算时间占总时间比例:
好的厨师长会在“做菜”和“传菜”之间找平衡:传菜通道窄,就减少频繁传菜,少用张量并行、多用流水线;厨师手速慢,就增加灶台,多用数据并行。集群拓扑与模型结构,共同决定最优策略。
- 计算时间 T_computeGPU 真正做矩阵乘、卷积等算子的时间,它是“做菜”本身。
- 通信时间 T_comm梯度或激活值在卡间传输、同步等待的时间,对应“传菜与开会”。
- 效率 η理想情况下通信无限快,\(\eta \to 1\);通信占比越高,\(\eta\) 越小,加速比越差。
方案选型实践
要不要把后厨改造成流水线?主厨会先回答三个问题:菜谱多厚(模型大小)?一天多少桌(数据量)?后厨多大、走廊多宽(GPU 数量与互联)?没有放之四海皆准的答案,只有算完账后的最优解。
选型第一步永远是从显存算起:模型能不能装进单卡?混合精度训练下,每个参数大约需要 16 字节显存:参数本身 4 字节、梯度 4 字节、Adam 优化器状态 8 字节。模型并行(TP × PP)可以把这部分占用按比例摊薄;数据并行不省显存,只是把数据分批。若模型单卡放得下并且想加速,用数据并行;单卡放不下,先切模型;切分粒度过细导致通信爆炸,再上流水线。
第二步看网络拓扑:节点内多卡通常有 NVLink(数百 GB/s),适合张量并行;节点间用 InfiniBand 光缆(约 400Gb/s),适合数据并行与流水线并行。第三步做小规模实测,用性能分析工具定位 GPU 空闲率与通信占比,再迭代配置。单卡显存估算公式如下:
账算清楚了,主厨才敢拍板:这几张灶台、这条动线、这套分工,今晚能否接住两千桌订单。选型没有银弹,只有基于模型规模、数据量与硬件拓扑三者的综合权衡。
- 参数量 Ψ模型总参数个数。一个 100 亿参数模型,\(\Psi = 10^{10}\)。
- 16 字节每参数混合精度训练的经验值,由参数 4B + 梯度 4B + Adam 状态 8B 组成。
- 除以模型并行度只有 TP 和 PP 能把参数与状态分片到多卡,所以分母是它们的乘积;DP 不减显存。
- 激活值 M_activation前向传播的临时存储,可以用激活重计算(把中间结果丢弃、反向时再算一遍)换取显存。
AI 应用场景
大语言模型预训练中的 3D 并行
阶段:模型训练
解决的问题:单卡放不下千亿参数,训练数据动辄数万亿 token,纯靠单机训练需要数月甚至数年。传统串行训练在工程上完全不可行。
具体案例:某团队用 256 张 A100 训练 70B 参数模型,按 DP=32、PP=4、TP=2 配置 3D 并行,配合 ZeRO 优化器状态分片,把预计 90 天的训练周期压缩到约 20 天。训练时数据并行负责扩大吞吐,流水线并行纵向切分模型,张量并行横向切分超大权重层,通信与计算大量重叠。
多卡推理服务中的张量并行
阶段:推理部署
解决的问题:模型权重超过单卡显存,无法直接加载;或单卡推理吞吐不足,难以满足在线服务的延迟要求。用数据并行推理又不解决单卡显存瓶颈。
具体案例:某公司部署 175B 模型时,用 8 张 A100 做张量并行:权重矩阵按输出维切成 8 份,请求逐层流经所有 GPU,每层计算一次 All-Reduce 聚合,单请求延迟控制在 300ms 内,吞吐达到单卡的 6 倍以上。
中小团队多卡微调的并行选型
阶段:模型微调
解决的问题:团队只有 8 张 24GB 显卡,7B 模型用 FP16 加载需要 14GB,加上激活与优化器状态,单卡勉强能跑但 batch 极小、训练极慢。盲目上数据并行又会因为同步通信吃掉收益。
具体案例:算法团队先用显存公式估算:7B 参数 ×16 字节 ≈ 112GB,除以 PP=2、TP=1 后每卡约 56GB,仍超 24GB;于是改用 ZeRO-3 把优化器状态与梯度也分片,配合 PP=2 流水线微调,最终每卡占用 18GB,batch size 扩大 8 倍,微调时间从 40 小时降到 9 小时。
Python 演示
# Multi-GPU parallelism simulator# Compare data / model / pipeline parallel with simple metrics# All units: model in GB, bandwidth in Gbps, time in seconds def data_parallel(model_gb, batch_time_s, gpu_count, bandwidth_gbps): # Data parallel: each GPU holds full model copy, sync gradients every step compute = batch_time_s / gpu_count sync_time = 2.0 * model_gb / bandwidth_gbps total = compute + sync_time efficiency = compute / total return total, efficiency def pipeline_parallel(stage_count, micro_batches): # Pipeline parallel: bubble ratio formula bubble = (stage_count - 1) / (micro_batches + stage_count - 1) return bubble, 1.0 - bubble def model_parallel(layer_groups, model_gb, bandwidth_gbps): # Layer-wise model parallel: activations pass between GPU groups comm_time = layer_groups * model_gb / bandwidth_gbps return comm_time def main(): print("=== Data Parallel (8 GPUs, 14GB model, 40Gbps) ===") total, eff = data_parallel(14, 100, 8, 40) print("total: %.4fs, efficiency: %.2f%%" % (total, eff * 100)) print("\n=== Pipeline Parallel (4 stages, 8 micro-batches) ===") bubble, util = pipeline_parallel(4, 8) print("bubble: %.2f%%, utilization: %.2f%%" % (bubble * 100, util * 100)) print("\n=== Model Parallel (3 groups, 40Gbps) ===") comm = model_parallel(3, 14, 40) print("comm time per step: %.4fs" % comm) if __name__ == "__main__": main()
def data_parallel(model_gb, batch_time_s, gpu_count, bandwidth_gbps):定义数据并行模拟函数,输入模型大小、单卡计算耗时、GPU 数和带宽。compute = batch_time_s / gpu_count理想情况下计算时间随卡数线性下降,这是“多灶台各炒各菜”的收益。sync_time = 2.0 * model_gb / bandwidth_gbps每次同步梯度要传两遍全量模型,对应公式里的 \(2M/B\)。efficiency = compute / total效率等于计算时间占总时间的比例,通信越重效率越低。def pipeline_parallel(stage_count, micro_batches):定义流水线并行模拟,直接套用气泡公式。bubble = (stage_count - 1) / (micro_batches + stage_count - 1)气泡占比公式,阶段越多气泡越大、微批越多气泡越小。comm_time = layer_groups * model_gb / bandwidth_gbps层间模型并行的通信按阶段边界估算,层越深通信链越长。
常见误区
误区我买了 16 张卡,训练速度应该就是单卡的 16 倍,多卡并行是线性加速的。
正解Amdahl 定律和通信开销决定了不可能线性扩展。模型同步、梯度聚合、负载不均、流水线气泡都会拖后腿。就像厨房里加了 16 个厨师,但传菜通道只有一条,大家反而会挤在一起等菜。16 卡能跑出 10 倍以上加速已经算优秀配置。
为何常见:直觉上“人多力量大”,忽略了协作本身有成本;厂商宣传也常只展示理想加速比。
误区把 100 层网络分给 4 张卡,每张放 25 层,就是完美的模型并行方案。
正解这只是“层间并行”,它的通信只发生在相邻阶段,但会引入气泡。另一种“层内张量并行”是把同一层的权重矩阵切开,多卡协同算一层,通信发生得更频繁。不同切法的显存收益和通信压力完全不同,不能一概而论,就像拆菜谱不是简单撕几页纸,而是要把前后工序的衔接都设计好。
为何常见:教程多用“网络层拆到不同设备”的示意图,让大家误以为切层是唯一方式。
误区流水线是接力传递数据,只有相邻阶段之间有联系,所以几乎不花通信时间。
正解流水线并行确实比张量并行通信频率低,但每相邻阶段之间都要跨设备传递激活值,通信量正比于阶段边界的张量大小;再加上启动与收尾的气泡,流水线的效率并非 100%。真实系统中,流水线通信与数据并行梯度同步往往同时存在。
为何常见:“接力”的比喻容易让人只想到物理传递,忽略了数据量大小和起停等待的时间成本。
误区数据并行、模型并行、流水线并行是三个互斥的选项,训练时按需三选一就行。
正解现代大模型训练几乎都是“混合并行”:用数据并行扩大吞吐,用流水线并行纵向切分,用张量并行横向切分,三者组合成 3D 并行。就像大宴会厨房里,多个灶台同时开火、每台灶台又有分工、整体还有流水线,三种协作方式同时存在。
为何常见:教材为了讲清原理通常分开介绍,导致读者把“独立概念”误解为“互斥方案”。
误区数据并行把数据分到多张卡上,所以每张卡的显存压力也变小了,可以训练更大的模型。
正解数据并行要求每张卡保存一份完整模型副本、梯度与优化器状态,单卡显存压力与单卡训练完全相同;它只扩大数据处理能力,不解决“模型放不下”的问题。想要省显存,必须靠模型并行或 ZeRO 这类优化器状态分片技术。
为何常见:“把数据分给多卡”的字面理解让人误以为显存也被分摊了,实际被分摊的是数据而不是模型。
面试题
Q1. 数据并行的核心思想是什么?
- A.把模型参数切成多份分给各卡
- B.每卡持有完整模型,各自吃不同数据← 正确答案
- C.把训练数据按时间顺序分段发送
- D.用流水线接力方式处理小批量
答案:B。数据并行让每张卡持有一份完整模型副本,各自用不同 mini-batch 计算梯度,再同步平均。A 是模型并行,C 是数据流切分,D 是流水线并行,都不符合数据并行定义。
Q2. 数据并行每轮训练结束后,GPU 之间同步的是什么?
- A.损失函数的具体取值
- B.当前批次输入数据
- C.更新参数的梯度← 正确答案
- D.各层前向输出
答案:C。每张卡算出的梯度是“各自的改进建议”,必须 All-Reduce 求平均后用平均梯度更新参数,才能保证所有卡模型一致。损失值不参与同步,输入和输出本来就是各卡独立持有的。
Q3. 流水线并行中“气泡”指的是什么?
- A.显存为通信开辟的缓冲区
- B.启动与收尾阶段的空闲时间← 正确答案
- C.数据传输导致的额外开销
- D.打印调试信息造成的乱码
答案:B。气泡是流水线开始填充和结束排空时,部分阶段无数据可算的空闲时间。它不来自数据传输本身,也不是显存或调试问题。气泡占比公式 \((P-1)/(M+P-1)\) 专门用于量化它。
Q4. 关于三种并行的通信量,下列说法正确的是?
- A.数据并行通信量随模型变大而变大← 正确答案
- B.张量并行通信量总是最小的
- C.流水线并行通信量最大
- D.数据并行通信量与模型无关
答案:A。数据并行每轮同步全量梯度,通信量正比于模型大小,所以 A 对、D 错。通信量大小取决于具体配置而非策略本身,B、C 都是绝对化表述,不成立。
Q5. 给定 32 张 GPU,TP=2,PP=4,DP 最大可取多少?
- A.DP 设置为 2 张
- B.DP 设置为 4 张← 正确答案
- C.DP 设置为 8 张
- D.DP 设置为 16 张
答案:B。3D 并行满足 DP × PP × TP = 总卡数,代入 32 = DP × 4 × 2,解得 DP = 4。这是 3D 并行最基本的乘法关系,超卖卡数配置不会生效。
Q6. 混合精度训练下,一个 10 亿参数的模型,参数加梯度加优化器状态大约需要多少显存?
- A.大约需要 4 GB
- B.大约需要 8 GB
- C.大约需要 16 GB← 正确答案
- D.大约需要 32 GB
答案:C。混合精度下每参数约 16 字节(参数 4B + 梯度 4B + Adam 状态 8B),10 亿参数就是 \(10^9 \times 16\) 字节 ≈ 16GB。这是方案选型时“模型放不放得下”的核心估算依据。
Q7. 模型并行主要解决什么问题?
- A.单卡显存放不下整个模型← 正确答案
- B.训练数据总量太大
- C.集群网络带宽不够
- D.数据标注质量太差
答案:A。模型并行把权重、梯度、优化器状态分摊到多卡,解决显存瓶颈。数据量大靠数据并行,带宽不足靠减少通信的流水线或通信压缩,标注质量与并行策略无关。
Q8. 以下哪些方式可以减小流水线并行中的气泡占比?
- A.增大 micro-batch 数量← 正确答案
- B.减小 micro-batch 数量
- C.减少流水线阶段数← 正确答案
- D.增加流水线阶段数
答案:AC。气泡公式 \((P-1)/(M+P-1)\) 中,增大微批量数 M 会稀释气泡,减少阶段数 P 会直接降低气泡;反之,减小 M 或增加 P 都会让气泡更严重。
Q9. 关于数据并行,下列说法正确的有?
- A.每卡保存完整的模型副本← 正确答案
- B.各卡输入数据相互独立← 正确答案
- C.各卡权重完全不一致
- D.每次更新前先同步梯度← 正确答案
答案:ABD。数据并行中每卡存完整模型(A 对)、吃不同批次数据(B 对)、每轮用平均梯度统一更新(D 对)。为保证训练收敛,各卡权重必须保持一致,C 错误。
Q10. 一个模型参数占 18GB,激活占 8GB,单卡 24GB,用纯数据并行训练会出现什么问题?
- A.显存足够可以直接训练
- B.每卡复制模型后显存溢出← 正确答案
- C.通信开销为零所以一定更快
- D.梯度同步不需要任何带宽
答案:B。数据并行每卡都要放完整模型副本,18 + 8 = 26GB 已超过 24GB 单卡容量,必然显存溢出。A 忽略复制开销,C、D 忽略梯度同步通信,都不符合数据并行特征。