分布式训练沿数据、张量、流水线三个正交维度切分计算与状态;选型的核心问题只有一个——模型与优化器状态撞上哪一级显存墙,就需要在哪一级引入切分。

并行的三个维度

维度切分对象通信模式通信量级适用互联
数据并行 DP批次数据梯度 AllReduce每步约等于参数量单机/跨机皆可
张量并行 TP层内权重矩阵每层前向/反向各 2 次 AllReduce极高,逐层触发仅 NVLink 机内
流水线并行 PP层间 stage点对点 send/recv低,仅边界激活适合跨机慢互联

三个维度正交,可叠加组合;先数据并行、再模型并行是成本从低到高的引入顺序。

数据并行谱系:从 DataParallel 到 FSDP

演进主线:PyTorch 1.0 引入 torch.distributed 与 DDP → 1.10 torchrun 取代 launch 脚本 → 1.11 FSDP → 2.x 以 DTensor 为基座提供原生张量并行 API。

nn.DataParallel:已弃用

nn.DataParallel(DP)是单进程多线程方案:受 GIL 与线程同步拖累,每步还要 scatter 输入、replicate 模型、gather 输出,单卡 0 号 GPU 成为带宽与显存热点,且完全不支持模型并行。官方文档明确不推荐——任何场景都应改用 DDP,迁移成本仅几行代码。

DDP:全量副本 + 梯度同步

DDP 为每张 GPU 启动独立进程,各持完整模型副本,仅在 backward 时按 bucket 重叠执行梯度 AllReduce,数学上严格等价于对全批数据做单次梯度下降:

import torch
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
 
dist.init_process_group("nccl")  # rank/world_size 由 torchrun 注入环境变量
model = DDP(model.to(torch.cuda.current_device()))
# DataLoader 须配 DistributedSampler 切分数据,见 [[Dataset 与 DataLoader]]

进程组与集合通信 API 见 torch.distributed 通信原语;多机训练用 torchrun 拉起,不要手写 mp.spawn。

显存墙与 ZeRO / FSDP

DDP 的隐性代价:每卡冗余存放全量参数、梯度、优化器状态。以混合精度 + Adam 训练 7.5B 模型为例——fp16 参数 15 GB + fp16 梯度 15 GB + 优化器状态(fp32 副本 + 一二阶动量)90 GB,合计约 120 GB,单张 80 GB 卡必然 OOM,此即显存墙。

ZeRO(DeepSpeed)按阶段消除冗余,FSDP 是同一分片思想(源自 ZeRO-3/FairScale)的 PyTorch 原生实现:

切分内容ZeRO 术语FSDP 对应
仅优化器状态ZeRO-1—
+ 梯度ZeRO-2SHARD_GRAD_OP
+ 参数ZeRO-3FULL_SHARD,静态显存约 ÷ N

代价:前向/反向需 all-gather 临时聚合完整参数、梯度再 reduce-scatter 回分片,通信量约为 DDP 的 1.5 倍,须靠预取与通信/计算重叠掩盖。权重分片后保存与加载不能再用普通 state_dict,参见 大模型检查点。

模型并行与流水线并行

张量并行(TP) 将单层权重矩阵按行/列切到多卡,典型如 Megatron 按注意力 head 切分 QKV 投影。每层前后向各引入 2 次 AllReduce,通信量随层数线性增长,因此几乎只部署在 NVLink 互联的单机内部。

流水线并行(PP) 将模型按层切成连续 stage,micro-batch 在 stage 间流水执行。空闲气泡占比为 ( 为 stage 数、 为 micro-batch 数),靠增大 与 1F1B 调度压低。只传边界激活,通信量小,适合跨机。

3D 混合并行:机内 TP + 机间 PP + 外层再套数据并行/FSDP,是 Megatron-LM 与 DeepSpeed 训练百亿至万亿参数模型的标准拓扑;MoE 模型还叠加专家并行(EP)。

通信后端

后端适用场景
NCCLNVIDIA GPU 单机/多机,默认首选
GlooCPU 训练、调试与回退
MPIHPC 集群(需源码编译)

按模型规模选型

以单卡 80 GB 为粗略标尺(先配合 torch.cuda 与混合精度 的 AMP、激活重计算、梯度累积把单卡余量榨干,再谈分布式):

模型规模推荐方案
参数 + 优化器状态单卡放得下(约 ≤2B)DDP
单卡放不下、单层放得下(约 3–30B)FSDP FULL_SHARD 或 ZeRO-3
单层也放不下 / MoE(>30B)TP + PP + DP/FSDP(Megatron / DeepSpeed)
快速实验、多后端切换Accelerate 一套代码切换 DDP/FSDP/DeepSpeed

决策顺序:先压单卡,再 DDP 水平扩展,跨过显存墙才引入分片;TP/PP 的工程与通信调试成本远高于 FSDP,非必要不启用。