Data Parallelism
数据并行(Data Parallelism, DP) 是最基础的分布式训练策略:在多个 GPU 上各放一份完整的模型副本,将训练数据切成不同子集分发给各 GPU,每个 GPU 独立做前向和反向,最后通过 梯度全归约(gradient all-reduce) 同步梯度。
核心思路
- 每个 GPU(称为一个 rank)持有模型的完整拷贝
- 一个 mini-batch 被均匀切成 份( 为 GPU 数),每个 rank 处理一份
- 前向和反向计算完全独立,无需通信
- 反向完成后,所有 rank 通过 all-reduce 对梯度取平均
- 各 rank 用相同的平均梯度更新参数,保证参数始终一致
通信只发生在梯度同步阶段,通信量与模型参数量成正比,与数据量无关。
存在的问题:显存瓶颈
朴素 DP 要求每个 GPU 都放得下完整的模型参数、梯度和优化器状态。当模型增大到数十亿参数时,单卡显存不足以容纳这些数据。
ZeRO 优化
ZeRO(Zero Redundancy Optimizer) 通过消除跨 rank 的冗余存储来缓解显存问题,分三个级别:
| 级别 | 切分内容 | 显存节省 | 额外通信 |
|---|---|---|---|
| ZeRO-1 | 优化器状态 | 约 4× | 少量 |
| ZeRO-2 | 优化器状态 + 梯度 | 约 8× | 中等 |
| ZeRO-3 | 优化器状态 + 梯度 + 参数 | 最大 | 需要 all-gather 参数 |
ZeRO-3 的理念是”切分为了存储”——参数被分片存放,计算前临时通过 all-gather 聚合完整参数,计算后再释放。
FSDP:PyTorch 的 ZeRO 实现
FSDP(Fully Sharded Data Parallelism) 是 PyTorch 对 ZeRO-3 的原生实现,有两个版本:
- FSDP1:把一个模块的所有参数压平成一个
FlatParameter,然后对这个大张量做切分。粒度粗,通信可能冗余(计算 时也要聚合 )。 - FSDP2:用
DTensor对每个参数独立切分。粒度更细,按需通信,更容易与计算做 overlap,也支持 per-parameter 元数据管理和 native LoRA。
两者的关键区别:
| 维度 | FSDP1 | FSDP2 |
|---|---|---|
| 切分粒度 | 模块级(FlatParameter) | 参数级(DTensor) |
| 通信精度 | 聚合整个模块的参数 | 只聚合当前需要的参数 |
| 组合性 | 较差 | 可与 TP、PP 嵌套 |
DP 与 TP 的本质区别
- DP 切分为了存储:每个 rank 存一份参数分片,计算前必须先 all-gather 出完整参数。
- TP 切分为了计算:每个 rank 只存且只算参数的一部分,计算直接在分片上进行。
两者通常组合使用:节点内用 TP 切分大层,节点间用 FSDP2 做数据并行扩展。
相关页面
- FSDP 深入详解见 fsdp
- AllReduce 等集合通信原语见 allreduce
- LLM 并行策略总览见 llm-parallelism
- 节点内层级切分见 tensor-parallelism
- 在 RL 系统中的应用见 阅读导览 第四章
Comments