Skip to content

集合通信原语与库:从 MPI 到 NCCL 的通信域与算法 ​

大模型训练 60% 以上的时间可能花在通信上。通信这件事被抽象成一组原语(broadcast、all-reduce、all-gather……),而 MPI、NCCL 这些库负责把这些原语在具体硬件上跑出最高带宽。本文讲清"原语是什么、各搬多少数据、库怎么选",与本站 MPI 实战系列 和 通信账 互补。

1. 通信域:所有通信的前提 ​

通信不是"随便两台机器互传",而是在预先建立的进程组(communicator)内进行:

MPI_COMM_WORLD = {rank0, rank1, ..., rankN-1}   # 全局通信域
子通信域 = 按需划分的子组(如每个节点一组)
  • rank:通信域内进程的唯一编号,是寻址方式;
  • 通信域决定谁能跟谁通信、用哪条路径——这是集合通信库的起点,NCCL 里对应 ncclComm。

2. 原语分类:点对点 vs 集合 ​

类别原语语义数据量(单 rank)
点对点Send / Recv一对一直连单条消息
集合Broadcast1 个 rank 发给所有 rank收 1 份
集合Scatter根 rank 分发不同数据收 1/N 份
集合Gather收集所有 rank 的数据到根发 1/N 份
集合All-Gather收集后再广播给所有人发 1/N、收 N 份
集合Reduce所有 rank 归约到根(sum/max)发 1 份
集合All-Reduce归约后结果广播给所有人发 1 份、收 1 份
集合All-to-All每人发 N-1 份不同数据发 (N-1)/N 份

判断:大模型训练里最核心的是 All-Reduce(梯度同步) 和 All-Gather(ZeRO/TP 权重聚合);MoE 的路由通信是 All-to-All。不同负载用不同原语,带宽账完全不同。

3. 每个原语搬多少数据(N 卡、消息 M) ​

原语总传输量(理论)说明
BroadcastN×M根广播给 N 个 rank
All-Gather(N-1)×M每人贡献 M/N,汇聚成 M 再分发
All-Reduce(ring)2(N-1)/N × M归约+广播合一路径
All-to-All(N-1)/N × M每人发 N-1 份

结论:同样一条消息,All-Reduce 比 All-Gather 省一半左右的总流量——这也是 ZeRO 训练 里"用 All-Reduce 而非 Gather+广播"的量化理由。

4. MPI 与 NCCL:两类库的定位差异 ​

MPINCCL
出身HPC 通用消息传递标准GPU 集合通信专用
覆盖点对点+集合+进程管理集合通信为主
硬件感知传统网络为主拓扑感知(rail/ring/tree 自动选)
典型场景科学计算、CPU 集群多卡 GPU 训练/推理
是否管 GPU通过 CUDA-aware 支持原生 GPU 内存

判断:GPU 大模型训练首选 NCCL(拓扑感知、带宽最高);CPU/混合 HPC 负载用 MPI。两者不是替代关系,是分工关系——很多集群里 MPI 做启动与数据面、NCCL 做 GPU 集合通信。

5. NCCL 的架构:拓扑感知的算法选择 ​

ncclComm(通信域)
   ├── 拓扑探测(PCIe/NVLink/IB 位置)
   ├── 算法选择:ring / tree / (NVLS 全互联)
   └── 通道优化:多通道并行、rail 对齐、SHARP 卸载
  • ring:带宽最高,默认算法(见 通信账);
  • tree:延迟低,适合大 N(见 集合通信拓扑);
  • NVLS:NVLink 全互联下用"一次全交换",比 ring 更优。

这就是为什么同样的卡,NCCL 能比手写 MPI 快一倍:它探测拓扑后选最优算法,而不是固定一种跑法。

6. 可复算 Python:原语流量对比 ​

python
def collective_traffic(kind, n, msg_mb):
    """各集合通信原语的总传输量(MB,理论近似)"""
    m = msg_mb
    return {
        "broadcast": n * m,
        "all_gather": (n - 1) * m,
        "all_reduce": 2 * (n - 1) / n * m,
        "all_to_all": (n - 1) / n * m,
    }[kind]

collective_traffic("all_reduce", n=8, msg_mb=140e3)
# ≈ 245,000 MB;对比 all_gather 980,000 MB → 省 75%

7. 交付清单 ​

  1. 先确认负载用哪个原语:梯度同步→All-Reduce,权重聚合→All-Gather,MoE 路由→All-to-All;
  2. GPU 训练直接走 NCCL,别用 MPI 包办 GPU 集合通信;
  3. 用 nccl-tests 测每个原语的 busbw(见 nccl-test),与模型对比;
  4. 拓扑不感知时(如跨节点未对齐 rail),优先排查 NCCL 环境变量与拓扑(见 IB 三面分离)。

本文为本站整理思考后撰写,用于知识库学习交流;具体版本号与实测数据以现场为准。

AI-HPC 智算超算专家 · Contact: openaihpc@gmail.com