Data Parallelism

数据并行在多个 worker 上复制模型,把不同 mini-batch 分片交给各 worker 计算,再同步梯度以保持参数一致。

DDP 流程

  1. 每个进程持有一份模型副本。
  2. DistributedSampler 切分数据。
  3. 每个进程独立 forward/backward。
  4. 梯度通过 collective communication 聚合。
  5. 各进程执行一致的 optimizer step。

边界

  • 纯 DDP 仍在每张卡复制完整模型和优化器状态。
  • ZeRO / FSDP 进一步切分训练状态。
  • 梯度累积减少同步频率但增加更新延迟,不自动解决模型单卡放不下。
  • Ray 可以启动和组织 worker,但不替代 DDP/ZeRO 的梯度与状态切分算法。

通信为何成为瓶颈

1
2
3
4
5
每卡独立 forward/backward
→ all-reduce 梯度
→ 等待最慢 worker
→ 同步 optimizer step
→ 下一批数据

计算量增加并不必然带来线性加速:小 batch、网络带宽不足、数据加载抖动或 straggler 都会让同步等待占比上升。梯度累积可以减少 all-reduce 次数,却会增加单次更新延迟和显存压力。

选型边界

模型单卡放得下且 batch 可扩展时先用 DDP;模型状态放不下再看 ZeRO / FSDP;序列或激活主导时转向 checkpoint、sequence parallel 或减少 micro-batch。DP 解决“不同数据”,不解决张量内部如何切分。

all-reduce 在数学上做了什么

假设两个 worker 分别看到 batch b0b1,得到梯度 g0g1。DDP 的同步通常把它们聚合成 (g0+g1)/2,然后每个 worker 对相同参数执行同一 optimizer step;这等价于一个更大的 batch(忽略随机性、loss reduction 和数值顺序差异)。如果某 rank 少了一个有效 token 却仍按固定 batch 平均,梯度尺度就会偏掉,因此 token-level loss 的有效计数也要参与同步。

通信并非只发生一次。梯度 bucket 会在 backward 的不同阶段异步 all-reduce,但最慢 rank、数据加载抖动和网络拥塞仍会形成同步墙。用 profiler 看 step time 时,把 compute、通信、data wait 和 overlap 分开;GPU utilization 低并不必然是算子慢,也可能是某个 worker 在等最慢样本。

DP 和其他并行的分工

DP 复制模型、切分数据;TP 切分一个矩阵的输入/输出维,PP 把层切到不同设备,ZeRO/FSDP 切分训练状态。它们可以组合,但每层都会增加不同的 collective。若模型单卡放不下,纯 DP 无法解决;若模型放得下但 batch 很小,增加 DP worker 只会让通信比例变大。选型先由显存账本和目标 batch 决定,再用拓扑感知的通信基准确认线性扩展是否成立。

一个最小回归应固定随机种子、global batch、loss reduction 和数据顺序,在 1 卡与多卡上比较若干 step 的参数/梯度差异;差异过大时先查 sampler、drop_last、梯度累积和混合精度,而不是立即怀疑模型非确定性。