系统工程 · 并行训练
学习舱 / 系统工程 / 并行训练

并行训练:DP / ZeRO / FSDP / TP / PP

整理中 深度 · 应用 更新 2026-09-22

前置 预训练全流程

并行训练:DP / ZeRO / FSDP / TP / PP

一句话定位:单卡装不下训练状态时,并行训练把「权重、梯度、优化器状态」三样大件切开分给一群显卡——ZeRO/FSDP 切训练状态、张量并行切层内、流水线并行切层间。前置:预训练 → SFT → RLHF 全流程——「约 16 字节/参数」的显存口诀在那篇建立,本篇全部账目从它出发。

先看一本装不下的账

流程篇给过显存口诀:混合精度训练时每个参数要占约 16 字节——权重 2、梯度 2、优化器状态 12。拿 7B 模型一算就是 100 GiB 出头,单卡(80 GB 档)装不下;100B 模型更是要 1.5 TiB,任何单卡都免谈。

显卡不够,那就把训练摊到一群显卡上。

但「摊」的方式决定成败:切得不对,显卡之间互相等待的时间比干活还长。

切什么、怎么切、通信代价是什么,就是本篇要回答的问题。

答案是一族按「切什么」分级的技术:DP 复制一切不切;ZeRO/FSDP 竖切训练状态(优化器 → 梯度 → 权重逐级切);TP 把层横切成片;PP 把层分段接龙。切得对,一百张卡像一张大卡一样干活。先看全景:

切什么:三种切法对三样大件 DP / ZeRO / FSDP 不动模型结构 切的是训练状态: 优化器 → 梯度 → 权重 (ZeRO-1/2/3 逐级切) TP 张量并行 把一层的大矩阵 横切成几片 每层都要全组通信 PP 流水线并行 把层分段 段与段像流水线接龙 只在段边界传一次激活 通信代价排序:ZeRO-1/2 ≈ 普通数据并行(免费省显存)→ ZeRO-3 加约 50% → TP 每层都通信(最密)→ PP 最稀疏但有气泡 部署铁律:TP 放机内(NVLink 快),PP 跨机(扛得住慢网络),ZeRO/DP 随处放 实战常是组合拳:机内 TP + 跨机 PP + 全局 ZeRO——三条切法各占一个维度,互不冲突 读法:先问「装不装得下」(选 ZeRO 级别),再问「通信怎么排」(选 TP/PP 组合)

图:并行训练全景——ZeRO 竖切训练状态、TP 横切层内、PP 层间接龙;通信代价决定部署位置(TP 机内、PP 跨机)

渐进拆解:从复制到切分

三种切法落到显卡上各是什么形状、通信发生在哪,先看一张结构图:

三根切分轴:DP 复制整份、TP 切层内、PP 按层切段 DP 数据并行 复制一切不切 卡 1卡 2卡 N 整份模型整份模型整份模型 …… 每步同步一次梯度显存毫无节省它给出通信基准线 把一层的大矩阵横切成 N 片,N 张卡各算一片: 片 1 · 卡 1片 2 · 卡 2片 3 · 卡 3片 N · 卡 N 每层都要全组通信(前向 2 次、反向 2 次)→ 放机内(NVLink 快) 按层分组切段,数据像流水线一样流过: 段 1 · 卡 1段 2 · 卡 2 第 1–8 层第 9–16 层 …… 只在段边界传激活量最小,扛得住慢网络→ 跨机 三根轴各切各的、互不冲突——实战常是机内 TP + 跨机 PP + 全局 ZeRO 的组合

图:三根切分轴各切什么、通信发生在哪——DP 整份复制只同步梯度,TP 切层内须放机内,PP 按层切段可跨机

DP:最朴素的摊法,复制一切

数据并行是起点(PyTorch 里的实现叫 DDP,下文两个名字混用):每张卡放一份完整模型,各吃各的数据批次,每步结束互相同步一次梯度(求平均)。它简单、通信规整,但显存毫无节省——每卡都是全量三样大件,装不下的模型它也无能为力。DP 的价值在于给出通信的基准线:之后所有花招都拿来跟它比。从零预训练篇讲的「放大到集群的三件工程」,第一件就是它——本篇是那条放大路径的完整展开。

ZeRO 与 FSDP:三样大件逐级切

ZeRO(DeepSpeed 提出)的观察是:三样大件不必都放全量——优化器状态最臃肿(占 12 字节/参数)却最「机械」(只是统计量),先切它;梯度其次;权重最后。三级切法:

  1. ZeRO-1 切优化器状态:每卡只留自己负责那份参数的优化器状态。
  2. ZeRO-2 加切梯度:每卡只保留自己那份参数对应的梯度。
  3. ZeRO-3 加切权重:前向要用某层时临时从别卡借齐,用完即还。

妙处在通信账:普通 DP 同步梯度用的 all-reduce(全员归约平均),内部本就等价于「各卡归约出自己那片 + 再全员同步」两步;ZeRO-1/2 恰好只要其中一半产物——每卡只留自己分片的份,总通信量与 DP 完全相同,显存等于白省;ZeRO-3 因为要多跑「借权重」的临时同步,通信约加 50%。拿 7B 模型实算(8 卡、混合精度):

级别切什么通信代价每卡显存
DP(基线)不切基准106 GiB
ZeRO-1优化器状态与 DP 相同36 GiB
ZeRO-2加切梯度与 DP 相同25 GiB
ZeRO-3加切权重约加 50%13 GiB

ZeRO-3 把「装不下」直接变成「装得下还有富余」。

FSDP:ZeRO-3 的工程化落地。 FSDP(全分片数据并行)是 PyTorch 原生的 ZeRO-3 实现:把权重、梯度、优化器状态全部分片,前向/反向进行到某层时临时 all-gather(全员汇聚)出该层完整权重,用完立刻丢弃只留自己的分片。对使用者它是个开关(包一层 API 即得),因此成为学术界与开源训练的默认起点;代价与 ZeRO-3 一致——那 50% 的额外通信,以及「借还」带来的调度复杂度。

TP:把一层切成片,通信最密集

先补一个名词:激活值指前向过程留下的中间结果(反向算梯度要用),它随 batch 与序列长线性涨,长上下文下能压过参数本身——本篇的 16 字节口诀不含它。

ZeRO 系省的是「训练状态」,可单层如果还是太大(注意力与 FFN 的大矩阵乘),就得动模型本身:张量并行(TP)把每层的大矩阵按行列切成 N 片,N 张卡各算一片,每层算完互相汇总一次。切法有讲究:权重矩阵按列切、各卡独立算完再拼接结果,可以少一次同步——Megatron-LM 的经典设计就是把注意力的投影与 FFN 的两段矩阵交替按列/行切,让一整层只在头尾各同步一次。

收益是每卡的权重与激活都变成 1/N;代价是每一层的前向与反向都要全组通信(经典实现每层前向两次、反向两次 all-reduce)——通信次数与层数成正比,且必须等最慢的卡。所以 TP 的铁律是放在机内(NVLink 是服务器机内显卡间的高速互联,带宽远高于跨机网络),跨机跑 TP 会被网络拖垮。

激活太占时的标准解法是激活重计算:前向不留中间结果、反向时重算,用约三成的额外计算换显存——它与并行正交:并行切开「三样大件」,重计算管「临时开销」,两者叠加使用。

PP:把层分段接龙,通信最稀疏

流水线并行(PP)换了个切法:按层分组,前 8 层给 1 号卡、接着 8 层给 2 号卡……数据像流水线一样流过。通信只在段与段的交界处发生(传一次激活),量最小、也扛得住慢网络——适合跨机。

代价是流水线空泡:流水线刚启动时下游没事干、收尾时上游没事干,这些空转就是气泡。气泡率 = (段数−1) ÷ (micro-batch 数 + 段数−1),把全局批次拆成越多份 micro-batch(填流水线的小份数),气泡越薄——8 段流水线下的三档实算:

  • micro-batch 8:气泡率 46.7%
  • micro-batch 32:气泡率 17.9%
  • micro-batch 64:气泡率 9.9%

但 micro-batch 变小会让矩阵乘变矮、单步计算效率下降,与气泡率存在权衡;主流的 1F1B 调度(前向反向交错排布)压的是在飞激活的显存占用,气泡率与上式相同。

大白话:DP 是「每个司机开一辆整车」;ZeRO 是「停车紧张,把备胎、工具箱、油桶分开放各家车库」;TP 是「一辆车的引擎太大,四个人合力装」;PP 是「一条装配线,每人负责几道工序」。

选型决策树:给定模型与集群,三问定方案

实战里的决策路径是固定的,画成树:

三问选型:从「装得下吗」开始 第一问:状态装得下吗 16 字节/参数 × 参数量 ÷ 卡数 装得下 → DP 阶梯 DDP → 紧了 ZeRO-1/2 → FSDP 装不下 → 动模型 进第二问 第二问:单层装得下吗 一层的大矩阵 × 激活 单层也装不下 → 机内 TP NVLink 域内 8 卡常见上限 装得下 → 看第三问 需要跨机规模吗 第三问:跨机吗 跨机维度交给 PP 组合拳:机内 TP + 跨机 PP + 全局 ZeRO——三个维度各切各的;经验次序:工程侵入越深的手段越靠后上场 先 ZeRO/FSDP(开关级),再 TP(要机内带宽与切分改造),最后 PP(引入调度与气泡)

图:并行选型决策树——先问训练状态装不装得下(DDP/ZeRO 阶梯),再问单层装不装得下(机内 TP),最后按拓扑定跨机(PP);实战常是三维组合拳

技术定义:DP 每卡持完整训练状态、按步同步梯度;ZeRO-1/2/3 依次分片优化器状态、梯度、权重,前两级通信量与 DP 持平、第三级约增 50%;FSDP 为 ZeRO-3 的 PyTorch 原生实现;TP 按矩阵行列切分层内计算,每层前向与反向需全组通信;PP 按层分段,仅段边界传输激活。大规模训练常以「机内 TP + 跨机 PP + 全局 ZeRO」三维组合部署。

动手:算分片账、气泡账与通信账

三笔账支撑本篇全部决策,都可实算验证:

P = 7.1e9                     # 7B 参数
N = 8                         # 8 卡
# 混合精度显存口诀:权重 2 + 梯度 2 + 优化器 12 = 16 字节/参数
ddp = 16 * P / 2**30
z1 = (2 + 2 + 12/N) * P / 2**30      # ZeRO-1:切优化器
z2 = (2 + 2/N + 12/N) * P / 2**30    # ZeRO-2:加切梯度
z3 = (2/N + 2/N + 12/N) * P / 2**30  # ZeRO-3:加切权重
print(f"DDP {ddp:.0f} GiB → Z1 {z1:.0f} → Z2 {z2:.0f} → Z3 {z3:.0f}")
# 实算输出:DDP 106 GiB → Z1 36 → Z2 25 → Z3 13

p_stages, m_micro = 8, 32
bubble = (p_stages - 1) / (m_micro + p_stages - 1)
print(f"PP 气泡率: {bubble:.1%}")       # 实算输出:17.9%

# 第三笔:TP 每层的通信对象 = batch × 序列长 × 隐藏维 × 精度字节
act = 4 * 4096 * 3584 * 2 / 2**20
print(f"TP 每层通信对象 ≈ {act:.0f} MiB")   # 实算输出:112 MiB

账本读法:

  • 第一笔账回答「切到哪一级够用」——80 GB 卡装 7B 全量训练装不下(106 GiB),ZeRO-1 就够了(36 GiB);70B 模型 8 卡即使 ZeRO-3 训练状态也要约 130 GiB/卡,还需加卡或叠加手段。
  • 第二笔账回答「PP 的空转有多疼」——micro-batch 数是免费的气泡阀,拆批前先看这行公式。
  • 第三笔是通信量的估算口径:TP 每层的通信对象是激活张量(batch × 序列长 × 隐藏维 × 精度字节),层数越多通信越频繁;PP 只传段边界的同尺寸张量——这就是「TP 扛不住慢网络、PP 扛得住」的量化根源,也是自测第一题的答案骨架。

边界与取舍

什么时候 TP 不如 PP? 判据是「通信发生在哪、网络扛不扛得住」。TP 的通信在每层的前向与反向都要发生(经典实现各两次),次数与层数成正比,对带宽和延迟都敏感——跨机(以太网/InfiniBand 跨节点)跑 TP,通信等待会吞掉并行收益;PP 的通信只在段边界一次一段,量小且可流水掩盖,慢网络只影响交界瞬间。

所以:单机 8 卡能装下 → TP 优先(机内带宽富余);必须跨机 → PP 承担跨机维度,TP 退回机内。通信量的估算口径见动手一节的第三笔账——先算 TP 的每层激活张量与层数的乘积,再对照机内/跨机带宽,答案自然出来。

什么时候不用并行? 单卡或单机能装下(LoRA 微调、7B 以下全参)——并行只添乱;推理场景——本篇是训练侧的切分,推理侧的省法(KV Cache、分页)在推理优化篇。另外并行不改变「训练什么」:数据配比、损失设计这些流程篇的事,并行一概不碰——它只回答「怎么在有限的卡上把它训起来」。

坏味道预警:把并行度当性能旋钮猛拧。 卡越多不等于越快——TP 超过机内卡数、PP 段数超过 micro-batch 数、ZeRO-3 用在小模型上,都是「通信与空转吃掉收益」的典型。每次加并行度前,先用动手段的两笔账算一遍:显存是否真不够、气泡率是否可控。

自测

合上文章先自己答,再展开对照:

什么时候 TP 不如 PP?通信量怎么估?

判据是通信模式对网络的敏感度。TP 的通信发生在每一层的前向与反向(每层全组汇总),次数与层数成正比,对带宽与延迟双重敏感——跨机跑 TP 时慢网络会吞掉并行收益,所以跨机场景 TP 不如 PP:PP 只在段边界传一次激活,量小且可被流水掩盖,天然适合跨机。通信量估算口径:TP 每层的通信对象是激活张量 = batch × 序列长 × 隐藏维 × 精度字节(如 4×4096×3584 bf16 约 112 MiB),总通信 ≈ 每层激活 × 层数 × 前向与反向的通信次数;PP 只算各段边界的一次传递。决策顺序:先看模型单层/整层能否装进机内——能装下优先机内 TP;跨机需求用 PP 承担,TP 退守 NVLink 域内。

ZeRO 三级各切什么?为什么说前两级「通信免费」?

ZeRO-1 切优化器状态(12 字节/参数的大头)、ZeRO-2 加切梯度、ZeRO-3 加切权重——逐级把三样大件分片到各卡。前两级「通信免费」的原因:普通 DP 同步梯度用的 all-reduce 原语,内部本来就等价于「reduce-scatter(各卡归约出自己那片)+ all-gather(再全员同步)」两步——ZeRO-1/2 恰好只需要其中一半的产物(每卡只留自己分片的梯度/优化器状态),总通信量与 DP 完全持平,显存省了通信没多付。ZeRO-3 则要额外跑「前向/反向临时借齐权重」的 all-gather,通信约加 50%——免费午餐到这一级为止(7B 模型 8 卡实算:DP 106 GiB → ZeRO-1/2/3 每卡 36/25/13 GiB)。

PP 的流水线气泡怎么算、怎么压?

气泡来自流水线的启动与收尾:第一批数据还没流到最后一段、最后一批已经离开前几段,中间的空转就是气泡。公式:气泡率 = (段数−1) ÷ (micro-batch 数 + 段数−1)。压法是把全局批次拆成更多 micro-batch 来填流水线——8 段流水线下,micro-batch 从 8 提到 32、64,气泡率从 46.7% 降到 17.9%、9.9%(实算);但 micro-batch 变小会降低每步的计算效率(矩阵乘变矮),与气泡率存在权衡,工程上取两者平衡点。主流的 1F1B 调度(前向反向交错)还能进一步压在飞激活的显存占用(气泡率不变),思路同源:让每张卡手里始终有活。

参考与延伸

  • Rajbhandari 等《ZeRO: Memory Optimizations Toward Training Trillion Parameter Models》(2020):三级分片与通信量分析的原论文 — arxiv.org/abs/1910.02054
  • PyTorch 官方教程《Getting Started with FSDP》:FSDP 与 ZeRO-3 的对应关系及使用 — pytorch.org/tutorials/intermediate/FSDP_tutorial.html
  • Shoeybi 等《Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism》(2019):TP 的工业标准实现 — arxiv.org/abs/1909.08053
  • Huang 等《GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism》(2019):流水线并行与 micro-batch 填充的奠基论文 — arxiv.org/abs/1811.06965
  • DeepSpeed 官方文档:ZeRO 配置与三级开关 — www.deepspeed.ai

下一站:GPU Kernel 入门:Triton / FlashAttention——并行训练把活分给一群卡,每张卡上的活怎么跑得快,轮到 GPU 内核出场:FlashAttention 省的不是计算而是搬运。

本节点大纲与自测题(4 个子点 · 3 问)

大纲

  • 数据并行与 ZeRO 1/2/3 各切什么、通信代价
  • FSDP 的工程化落地
  • 张量并行与流水线并行的适用边界
  • 选择决策树:给定模型大小和集群怎么选

自测——答不上来就是缺口

  • 什么时候 TP 不如 PP?通信量怎么估?
  • ZeRO 三级各切什么?为什么说前两级「通信免费」?
  • PP 的流水线气泡怎么算、怎么压?