AllReduce 让一组进程各持一份数据,归约(求和/取最大等)后使所有进程拿到相同结果——它是数据并行训练中梯度同步的通信核心,Ring AllReduce 以带宽最优的方式实现它。
AllReduce 集合通信
语义:Reduce 与 Broadcast 的合一
AllReduce = Reduce + Broadcast: 个进程各持等长向量,先按归约算子(SUM、MAX 等)合成一份全局结果,再让每个进程都持有它。与其他集合操作对照(API 层面见 torch.distributed 通信原语):
| 操作 | 语义 | 结果落在谁手里 |
|---|---|---|
| Broadcast | 根节点数据发往所有进程 | 全体 |
| Reduce | 归约到根节点 | 仅根 |
| AllReduce | Reduce + Broadcast 合一 | 全体 |
| ReduceScatter | 归约后按分片散布 | 每进程一个分片 |
| AllGather | 各进程数据拼接后分发 | 全体 |
关键分解:AllReduce = ReduceScatter + AllGather。Ring AllReduce 的两阶段正源于此。
朴素实现与主节点瓶颈
最直接的做法:选 GPU0 当主节点,先 Reduce 再 Broadcast。以 3 GPU、SUM 为例(本地值分别为 ):
- GPU1、GPU2 把数据发给 GPU0,GPU0 求和得
- GPU0 广播 ,三卡全部持有
问题不在步数而在带宽:设每卡数据量 ,主节点需接收 、再发送 ,全部压在一张网卡上; 越大主节点越是热点,其余链路却大量闲置。通信量随 线性增长,加卡无法摊薄。
Ring AllReduce
两阶段流程
张卡排成环,数据切成 个分片,每步每卡只沿环发送一个分片():
Scatter-Reduce(N−1 步):沿环发送分片并逐份累加
GPU0 ─▶ GPU1 ─▶ GPU2 ─▶ … ─▶ GPU0
结束时:每卡恰好完整归约出一个分片
AllGather(N−1 步):沿环转发已完整的分片
GPU0 ─▶ GPU1 ─▶ GPU2 ─▶ … ─▶ GPU0
结束时:每卡持有完整归约结果任一时刻每卡只发一份、收一份, 条链路全速并行,不存在主节点。
通信量推导
- Scatter-Reduce: 步 × 每步每卡发送 ,每卡共发送
- AllGather:同样 步,再发送
合计每卡发送量:
直觉:结果人人要有一份,每卡至少得”送出自己的 、收回别人的 “,理论下界即 ——Ring 恰好达到该下界,故称带宽最优(bandwidth-optimal);且发送量随 增大趋近常数 。
| 维度 | 朴素主节点 | Ring |
|---|---|---|
| 单卡最大发送量 | (root 独担) | (均摊) |
| 瓶颈 | root 网卡带宽 | 无 |
| 随 变化 | 线性恶化 | 趋近 |
| 采用者 | — | NCCL、DDP、DeepSpeed |
带宽最优与延迟的取舍
总时间近似:
( 为每步启动延迟, 为链路带宽)。大 时带宽项主导,Ring 占优;小 时 步的延迟项主导。NCCL 因此内置 Ring、Tree(双二叉树,关键路径 )等多套实现,按消息大小与实际拓扑(NVLink、PCIe、InfiniBand)自动选择或混合,使用者无需感知。
DDP 梯度同步中的地位
数据并行(见 分布式训练总览)的核心通信需求只有一条:每步 backward 结束后各副本梯度求平均。DDP 的 Reducer 把梯度组织成桶(bucket,默认 25 MB),按参数逆序分桶使先就绪的梯度先通信——桶一满即异步发起 all-reduce,与剩余反向计算重叠;归约结果除以 world_size 得平均梯度,随后各进程执行相同的 torch.optim 更新,参数保持一致。
import torch
import torch.distributed as dist
g = torch.ones(4, device="cuda") * dist.get_rank()
dist.all_reduce(g, op=dist.ReduceOp.SUM) # 所有进程得到同一份求和结果
g /= dist.get_world_size() # DDP 语义:取平均进程组由 torchrun 拉起。更大规模的 Megatron/DeepSpeed 训练里,梯度与参数分片的底层通信原语仍然是 AllReduce 及其组成部分 ReduceScatter/AllGather。
应用场景
| 场景 | AllReduce 的角色 |
|---|---|
| DDP 训练 | 梯度求平均,保持副本一致 |
| 混合并行的数据并行维度 | ZeRO/Megatron 梯度同步 |
| 多卡推理/特征 | 汇总各卡输出(logits、embedding) |
| 全局统计 | 跨进程聚合 loss、accuracy |