7.1 数据并行:为什么简单复制就能加速
数据并行(Data Parallelism)是分布式训练中最基本也最常用的策略。它的思路直观且有效:在多张 GPU 上各放一份完整的模型副本,每张卡处理不同的数据子集,然后同步梯度。
7.1.1 基本原理
数据并行的工作流程如下:
将训练数据划分为 $K$ 份($K$ 为 GPU 数量)
每张 GPU 持有一份完整的模型副本
每张 GPU 用分到的数据子集独立计算前向传播和反向传播
所有 GPU 同步梯度(通常取平均)
每张 GPU 用同步后的梯度更新自己的模型参数
由于每张 GPU 上的梯度来自不同的数据,同步后的平均梯度等价于在更大批次上计算的梯度。因此数据并行本质上是通过增加有效批次大小来加速训练。
7.1.2 为什么简单复制就能工作
数据并行能够正确地加速训练,根本原因在于随机梯度下降的数学性质:
梯度的期望不依赖于它是在一个大批次上计算的,还是在多个小批次上分别计算后取平均。数学上:
K1∑k=1K∇θL(Bk)≈∇θL(B1∪B2∪⋯∪BK)
这保证了多 GPU 的训练结果与单个大批次训练在数学上是等价的。
7.1.3 通信开销与优化
数据并行的主要瓶颈是梯度同步的通信开销。每个训练步都需要在 $K$ 张 GPU 之间交换所有参数的梯度。
AllReduce 是最常用的梯度同步算法。高效的 AllReduce 实现(如 Ring AllReduce)将通信量从 $O(K)$ 降低到 $O(1)$(与 GPU 数量无关),使数据并行能够扩展到数百甚至数千张 GPU。
PyTorch 的 DistributedDataParallel(DDP)是工程实践中最常用的数据并行实现,它还通过梯度桶化(将多个参数的梯度打包通信)和计算-通信重叠(在计算后续层梯度的同时通信前面层的梯度)进一步优化了效率。
7.1.4 数据并行的局限
数据并行要求每张 GPU 能容纳一份完整的模型——包括参数、梯度和优化器状态。对于 70B 参数的模型(如 Llama 2-70B),仅模型参数就需要约 140 GB(FP16),加上梯度和 Adam 优化器状态则需要约 560 GB——远超单卡显存。
这个显存限制正是 ZeRO 优化和模型并行技术诞生的直接动因。
最后更新于
