LLM 推理 · 通信库与多网卡

大模型服务通信库详解:
NCCL / MPI / GLOO / UCX / NVSHMEM,以及 Kubernetes 多网卡实战配置

GPU 之间怎么「说话」、K8s 里怎么给容器插多块网卡,一次讲透

大模型为什么需要「通信库」?因为模型放不进一张卡。训练一个 70B 模型要几百张 GPU,推理一个长上下文也要 8 卡并行——GPU 与 GPU 之间每走一步都要交换数据:梯度、中间张量、KV Cache。谁来干这件事?就是通信库。

本文把大模型服务里最常见的通信库(NCCL、MPI、GLOO、UCX、NVSHMEM)逐个讲清楚,然后给出一套 Kubernetes 容器多网卡 + NCCL 通信库的实际配置示例,从 YAML 到验证命令全部可抄。

为什么需要通信库

一、先搞清楚:大模型服务到底需要哪些「通信」

1. 三种并行,三种通信模式

并行方式通信内容典型原语
数据并行(Data Parallel)每步训练后同步梯度AllReduce
张量并行(Tensor Parallel)每层矩阵分块后合并AllReduce / ReduceScatter + AllGather
流水线并行(Pipeline Parallel)相邻层之间传中间激活点对点 Send/Recv
专家并行(MoE)token 分发给不同专家All-to-All

2. 集合通信六种原语

大模型用得最多的是集合通信(Collective Communication):所有 GPU 一起参与的通信模式。

通信库就是把这些原语实现到极致:该走 NVLink 走 NVLink,该走 RDMA 走 RDMA,CPU 全程靠边站。

五大通信库

二、五大通信库逐个讲

1. NCCL:GPU 集合通信的「事实标准」

NVIDIA Collective Communications Library,英伟达官方出品,训练框架(PyTorch、DeepSeek 全家、Paddle)默认后端。

2. MPI:通用并行计算的「老大哥」

Message Passing Interface,HPC 领域三十年标准,代表实现是 OpenMPI、Intel MPI,以及英伟达的 HPC-X。

3. GLOO:PyTorch 自带的「备胎与调试器」

PyTorch 官方内置的分布式后端,与 NCCL 并列可选项。

4. UCX:通信库的「框架的框架」

Unified Communication X,定位不是某个应用通信库,而是底层传输统一抽象层:

5. NVSHMEM:把「远端内存」变成「自己的内存」

NVIDIA 对 OpenSHMEM 标准的 GPU 实现,单边、细粒度、对称内存通信。

6. 其他你可能会遇到的

7. 一张表对比

通信库定位面向硬件通信模式典型场景启动成本
NCCLGPU 集合通信事实标准NVIDIA GPU + NVLink/IB/RoCE集合通信(Ring/Tree)大模型训练/推理低,框架默认
MPI (HPC-X)通用并行计算标准CPU/GPU 皆可(CUDA-Aware)集合 + 点对点HPC 传统负载、多框架协同中
GLOOPyTorch 内置轻量后端CPU 优先,TCP/SHM集合通信小规模、调试、备胎最低
UCX底层传输统一框架IB/RoCE/SHM/TCP 全支持为上层提供传输HPC-X、OpenSHMEM 的底座透明,不直接感知
NVSHMEMGPU 版 OpenSHMEMNVIDIA GPU 对称内存单边细粒度 P2PMoE 路由、KV 搬运、GraphEngine中
选型

三、怎么选:一张决策树

Kubernetes 多网卡实战

四、Kubernetes 多网卡实际配置通信库示例(重点)

1. 为什么 Pod 必须「插多块网卡」

一台 8 卡 GPU 服务器,硬件上通常插了 8 块 200G/400G 网卡,每块网卡和 GPU 一一对等映射(GPU-NIC 亲和,走同一 PCIe root 或 NUMA node)。但默认情况下:

解法就是 Multus(meta-CNI)+ 高性能附加网络:让 Pod 里除了 eth0,还能挂上 8 个 RDMA/RoCE 网卡接口,NCCL 多通道并行。

2. 需要的组件栈

组件作用
MultusMeta-CNI,负责把「附加网络」一个个挂进 Pod 的网络命名空间
NetworkAttachmentDefinitionCRD,声明附加网络的类型、网卡、IPAM
RDMA CNI / SR-IOV CNI把宿主机网卡(VF 或整卡)注入 Pod
RDMA shared device plugin / sriov-device-plugin把 RDMA 设备(/dev/infiniband)作为可调度资源暴露给 K8s
NVIDIA Network Operator(可选)一键部署 OFED 驱动 + 上述全部组件,省事

3. 前置条件

4. 第一步:定义附加网络(NetworkAttachmentDefinition)

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: rdma-net
  namespace: default
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "name": "rdma-net",
      "type": "rdma",
      "pkey": "0xffff",
      "linkState": "up",
      "mtu": 9000
    }

说明:RDMA CNI 把宿主机网卡直接放进 Pod(不占 IP,走 RoCE 的 GID/pkey 寻址),所以通常不需要 IPAM 块;若是 SR-IOV + 独立 IP 的方案,则在 config 里加 ipam 或交给 sriov-cni 的 ipam 段。

5. 第二步:StatefulSet 声明「多网卡 + RDMA 资源 + NCCL 环境变量」

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: llm-trainer
spec:
  serviceName: llm-trainer
  replicas: 1
  selector:
    matchLabels: { app: llm-trainer }
  template:
    metadata:
      labels: { app: llm-trainer }
      annotations:
        # 挂 8 个 RDMA 附加网络:net1 ~ net8 对应 8 块 RoCE 网卡
        k8s.v1.cni.cncf.io/networks: >-
          [{"name":"rdma-net","interface":"net1"},
           {"name":"rdma-net","interface":"net2"},
           {"name":"rdma-net","interface":"net3"},
           {"name":"rdma-net","interface":"net4"},
           {"name":"rdma-net","interface":"net5"},
           {"name":"rdma-net","interface":"net6"},
           {"name":"rdma-net","interface":"net7"},
           {"name":"rdma-net","interface":"net8"}]
    spec:
      containers:
      - name: trainer
        image: nvcr.io/nvidia/pytorch:24.10-py3
        resources:
          limits:
            nvidia.com/gpu: 8
            rdma/shared: 8   # RDMA device plugin 暴露的资源,注入 /dev/infiniband
        env:
        # 控制面/数据面分离:TCP socket 只走默认网卡 eth0
        - name: NCCL_SOCKET_IFNAME
          value: eth0
        # 显式指定全部 8 块 HCA,让 NCCL 开满 channel
        - name: NCCL_IB_HCA
          value: mlx5_0,mlx5_1,mlx5_2,mlx5_3,mlx5_4,mlx5_5,mlx5_6,mlx5_7
        # 保持 RDMA 传输开启(RoCE 场景不能设成 1)
        - name: NCCL_IB_DISABLE
          value: "0"
        - name: NCCL_P2P_LEVEL
          value: PXB   # 允许同一 PCIe 交换机下的 P2P
        - name: NCCL_MIN_NCHANNELS
          value: "8"
        - name: NCCL_MAX_NCHANNELS
          value: "32"
        - name: NCCL_DEBUG
          value: INFO
        # 无损网络参数,RoCE 建议开启超时重试
        - name: NCCL_IB_TIMEOUT
          value: "22"
        - name: NCCL_IB_RETRY_CNT
          value: "7"
        command: ["/bin/bash", "-c"]
        args:
        - |
          torchrun --nnodes=8 --nproc-per-node=8 --rdzv-endpoint=trainer-0 \
            train.py

要点拆解:

6. 第三步:NCCL 关键环境变量速查

变量作用多网卡建议
NCCL_SOCKET_IFNAMETCP 回退/控制路径用的网卡固定为管理网卡 eth0
NCCL_IB_HCA指定 RDMA 网卡列表(逗号分隔或 mlx5_* 通配)显式列出全部 HCA,或留空让 NCCL 自动探测
NCCL_IB_DISABLE0=开启 RDMA;1=禁用(退化为 TCP)RoCE 场景必须 0
NCCL_P2P_LEVELP2P 允许的拓扑级别(PXB/NVL/SYS 等)按机内拓扑放开,避免误禁用 NVLink
NCCL_MIN/MAX_NCHANNELS通道数(多网卡并行度)8 卡 8 网卡建议 ≥8
NCCL_DEBUG日志级别:INFO 输出拓扑与选用的网卡排查时 INFO,稳定后 WARN
NCCL_IB_TIMEOUT / NCCL_IB_RETRY_CNT无损网络重试参数RoCE 建议 22/7

7. 第四步:进容器验证(能不能跑满,一测便知)

# 1) 看 RDMA 设备是否注入
ibv_devinfo -d mlx5_0 | grep -E "state|port"

# 2) 看多网卡是否都在
ip addr show | grep -E "^[0-9]+:"

# 3) 通信库压测(8 卡单机 or 多机)
mpirun -np 8 all_reduce_perf -b 128M -e 8G -f 2 -g 8
# 或单机版
all_reduce_perf -b 128M -e 8G -f 2 -g 8

# 4) 看 NCCL 到底用了哪些网卡
# 启动时加 NCCL_DEBUG=INFO,关注日志里的 NET/IB 行:
#   "NET/IB : 8 HCA(s) selected"  → 8 块网卡全部参与,达标

诊断口诀:看到 NCCL_DEBUG=INFO 里 NET/IB : N HCA(s) selected,N 等于物理网卡数,就算成功;如果只显示 1 块,多半是 NCCL_IB_HCA 没放开或设备注入不全。

常见坑

五、常见坑与排查

  1. 容器里看不到 /dev/infiniband:device plugin 没装或没声明 rdma/shared 资源;确认节点 kubectl describe node | grep rdma
  2. NCCL 走 TCP 不走 RDMA:NCCL_IB_DISABLE=0、HCA 可见、RoCE 交换机无损配置齐全(PFC/ECN),三者缺一不可
  3. 多网卡但带宽只有一块卡的水平:NCCL_IB_HCA 被限制、NCCL_MAX_NCHANNELS 太小,或 Multus 只挂了一块附加网卡
  4. 网卡名漂移(eth0↔ens3):用 NCCL_SOCKET_IFNAME 固定,别依赖动态名
  5. 跨机性能骤降:检查 GPU-NIC 是否跨 NUMA/PCIe root,对等映射错位会损失 30%+ 带宽
  6. 容器启动报 permission:RDMA 设备注入 + 必要的 privileged/CAP 配置,用 Network Operator 统一管理
  7. NCCL 版本太老:多 HCA、Symmetric Memory 等特性需要较新版本,训练镜像尽量用 NGC 基础镜像(自带调优后的 NCCL)
落地要点

六、落地设计要点(八条)

  1. 先验收再扩容:新集群必须跑 nccl-tests all_reduce_perf 全量验收,记录每机带宽基线
  2. 网卡与 GPU 对等映射:部署前核对 PCIe 拓扑,确保 8 卡对 8 网卡、NUMA 亲和,错位补不回来
  3. 控制面与数据面分离:管理流量走 eth0,训练流量走 RDMA 多网卡,NCCL_SOCKET_IFNAME 指对
  4. 环境变量写进镜像/StatefulSet:别靠人肉 export,配置即代码,NCCL_DEBUG 先用 INFO 灰度
  5. 无损网络是前提:RoCE 不配 PFC/ECN,带宽越高丢包越惨,NCCL 重试参数兜底(TIMEOUT=22)
  6. 多网卡要测聚合带宽:单卡打满不代表 8 卡打满,all_reduce_perf -g 8 看的是多通道聚合
  7. 镜像选 NGC 基础镜像:自带调优 NCCL + 驱动兼容性验证,省掉一半玄学问题
  8. 监控与告警:NCCL 报错(超时/断连)直接挂到训练告警,跑大任务前先跑 10 分钟小规模验证
总结

七、写在最后

通信库是大模型分布式系统的「隐形基础设施」:你看到的 90% 训练卡在「通信瓶颈」,答案往往不在算力,而在网卡有没有被 NCCL 用满。选型记住一句话:训练/推理主力 NCCL,HPC 兼容 MPI,底层传输 UCX,细粒度点对点 NVSHMEM,调试备胎 GLOO;落地记住一句话:K8s 里用 Multus 插网卡、device plugin 注入设备、NCCL 环境变量把多通道开满——三件事做对,8×400G 的硬件才真正属于你的模型。

关于向量云:大模型部署,把基础设施的复杂性留给我们

通信库调优、多网卡配置、集群验收,都是持续的基础设施工程。向量云(南京)科技有限公司依托字节跳动火山方舟官方授权,专注大模型应用落地:

向量云能力说明
官方授权接入火山方舟官方 API 与官方 Key 直连
低折扣 Token专属折扣价,用量越大越划算
独享接入点独立接入点,缓存与配额不被公共池挤占
缓存隔离降本上下文缓存红利稳定落袋
计费灵活按量计费、即用即扣、注册充值 10 元起
协议兼容OpenAI 兼容协议,业务代码几乎零改动

接入方式:注册后获取官方 API Key,把 base_url 指向向量云接入点即可直接调用火山方舟官方模型。

获取 API Key:https://ark.tokenrize.cn/ · 火山方舟官方 API 与 Key 直连,注册即用

一句话总结:训练/推理主力 NCCL,HPC 兼容 MPI,底层传输 UCX,细粒度点对点 NVSHMEM,调试备胎 GLOO——选对通信库、插满多网卡,大模型分布式性能才能真正兑现。

关于向量云
向量云(南京)科技有限公司

面向大模型应用落地的技术服务型企业,依托字节跳动火山方舟能力,为合作方提供低折扣模型 Token、可独立部署的运营支撑平台及全链路运营支持。

火山方舟官方授权 官方 API Key 独享接入点 缓存隔离降本 低折扣 Token 即用即扣 · 不设账期

常见问题(FAQ)

火山方舟官方 API 与官方 Key 直连 · 向量云 · 大模型服务通信库

Q1. 大模型服务里的「通信库」是什么?

A. 通信库是负责 GPU 之间、机器之间数据交换的软件层。大模型分布式训练/推理中,梯度同步(AllReduce)、张量合并、KV Cache 搬运都要跨卡跨机,通信库把这些通信原语高效实现(走 NVLink、RDMA,绕开 CPU)。最常用的就是 NCCL,此外还有 MPI、GLOO、UCX、NVSHMEM 等。

Q2. NCCL 和 MPI 有什么区别?

A. NCCL 是英伟达面向 GPU 设计的集合通信库,全程不落 CPU 内存,直接走 NVLink/PCIe P2P 和 RDMA,是大模型训练的事实标准;MPI 是通用并行计算标准,出身 CPU 生态,CUDA-Aware MPI(如 HPC-X)才支持 GPU 缓冲直通。HPC 传统负载用 MPI 多,大模型训练用 NCCL 多。

Q3. GLOO 什么时候用?

A. GLOO 是 PyTorch 内置的轻量后端,走 TCP/共享内存,启动快、调试友好。适合小模型、CPU 环境、快速验证,以及 NCCL 连不上时的兜底。大规模 GPU 训练性能拼不过 NCCL,不适合打主力。

Q4. NVSHMEM 和 NCCL 的本质差别是什么?

A. NCCL 是「注册窗口、按需通信」的集合通信,通信仍由 CPU 发起;NVSHMEM 是「全局对称堆、统一寻址」——所有 GPU 共享同一虚拟地址空间,kernel 内线程可以直接 put/get 远端 GPU 内存,单边、细粒度、零拷贝,适合 MoE 路由、KV Cache 搬运这类点对点场景。

Q5. Kubernetes 里 Pod 为什么需要多网卡?怎么配?

A. 默认 Pod 只有一个 eth0(管理/默认网络),而 8 卡服务器通常有 8 块 400G 网卡且与 GPU 对等映射,只挂一块网卡等于浪费 7/8 带宽。用 Multus(meta-CNI)通过 k8s.v1.cni.cncf.io/networks 注解把附加网络(RDMA/SR-IOV)挂进 Pod,再配 RDMA device plugin 注入 /dev/infiniband 资源即可。

Q6. 多网卡场景要配哪些 NCCL 环境变量?

A. 核心四件套:NCCL_SOCKET_IFNAME(控制面网卡,如 eth0)、NCCL_IB_HCA(全部 RDMA 网卡列表)、NCCL_IB_DISABLE=0(保持 RDMA)、NCCL_DEBUG(排查用 INFO)。加分项:NCCL_P2P_LEVEL(机内 P2P 拓扑级别)、NCCL_MIN/MAX_NCHANNELS(通道数)、NCCL_IB_TIMEOUT/RETRY_CNT(RoCE 重试)。

Q7. 容器里 NCCL 走不通 RDMA 怎么排查?

A. 三步:① 容器内 ibv_devinfo 确认 /dev/infiniband 注入;② 确认 NCCL_IB_DISABLE=0 且 NCCL_IB_HCA 指定正确网卡;③ 开 NCCL_DEBUG=INFO 看日志中 NET/IB : N HCA(s) selected——N 应等于物理网卡数。还有前置条件:RoCE 交换机必须配好无损网络(PFC/ECN)。