GPU 之间怎么「说话」、K8s 里怎么给容器插多块网卡,一次讲透
大模型为什么需要「通信库」?因为模型放不进一张卡。训练一个 70B 模型要几百张 GPU,推理一个长上下文也要 8 卡并行——GPU 与 GPU 之间每走一步都要交换数据:梯度、中间张量、KV Cache。谁来干这件事?就是通信库。
本文把大模型服务里最常见的通信库(NCCL、MPI、GLOO、UCX、NVSHMEM)逐个讲清楚,然后给出一套 Kubernetes 容器多网卡 + NCCL 通信库的实际配置示例,从 YAML 到验证命令全部可抄。
| 并行方式 | 通信内容 | 典型原语 |
|---|---|---|
| 数据并行(Data Parallel) | 每步训练后同步梯度 | AllReduce |
| 张量并行(Tensor Parallel) | 每层矩阵分块后合并 | AllReduce / ReduceScatter + AllGather |
| 流水线并行(Pipeline Parallel) | 相邻层之间传中间激活 | 点对点 Send/Recv |
| 专家并行(MoE) | token 分发给不同专家 | All-to-All |
大模型用得最多的是集合通信(Collective Communication):所有 GPU 一起参与的通信模式。
通信库就是把这些原语实现到极致:该走 NVLink 走 NVLink,该走 RDMA 走 RDMA,CPU 全程靠边站。
NVIDIA Collective Communications Library,英伟达官方出品,训练框架(PyTorch、DeepSeek 全家、Paddle)默认后端。
nccl-tests(all_reduce_perf、all_gather_perf)是集群验收的标配Message Passing Interface,HPC 领域三十年标准,代表实现是 OpenMPI、Intel MPI,以及英伟达的 HPC-X。
MPI_Allreduce 也能跑出接近 NCCL 的性能PyTorch 官方内置的分布式后端,与 NCCL 并列可选项。
Unified Communication X,定位不是某个应用通信库,而是底层传输统一抽象层:
NVIDIA 对 OpenSHMEM 标准的 GPU 实现,单边、细粒度、对称内存通信。
put/get 远端 GPU 内存,不需要对方 CPU 参与,更不需要显式收发配对| 通信库 | 定位 | 面向硬件 | 通信模式 | 典型场景 | 启动成本 |
|---|---|---|---|---|---|
| NCCL | GPU 集合通信事实标准 | NVIDIA GPU + NVLink/IB/RoCE | 集合通信(Ring/Tree) | 大模型训练/推理 | 低,框架默认 |
| MPI (HPC-X) | 通用并行计算标准 | CPU/GPU 皆可(CUDA-Aware) | 集合 + 点对点 | HPC 传统负载、多框架协同 | 中 |
| GLOO | PyTorch 内置轻量后端 | CPU 优先,TCP/SHM | 集合通信 | 小规模、调试、备胎 | 最低 |
| UCX | 底层传输统一框架 | IB/RoCE/SHM/TCP 全支持 | 为上层提供传输 | HPC-X、OpenSHMEM 的底座 | 透明,不直接感知 |
| NVSHMEM | GPU 版 OpenSHMEM | NVIDIA GPU 对称内存 | 单边细粒度 P2P | MoE 路由、KV 搬运、GraphEngine | 中 |
一台 8 卡 GPU 服务器,硬件上通常插了 8 块 200G/400G 网卡,每块网卡和 GPU 一一对等映射(GPU-NIC 亲和,走同一 PCIe root 或 NUMA node)。但默认情况下:
解法就是 Multus(meta-CNI)+ 高性能附加网络:让 Pod 里除了 eth0,还能挂上 8 个 RDMA/RoCE 网卡接口,NCCL 多通道并行。
| 组件 | 作用 |
|---|---|
| Multus | Meta-CNI,负责把「附加网络」一个个挂进 Pod 的网络命名空间 |
| NetworkAttachmentDefinition | CRD,声明附加网络的类型、网卡、IPAM |
| RDMA CNI / SR-IOV CNI | 把宿主机网卡(VF 或整卡)注入 Pod |
| RDMA shared device plugin / sriov-device-plugin | 把 RDMA 设备(/dev/infiniband)作为可调度资源暴露给 K8s |
| NVIDIA Network Operator(可选) | 一键部署 OFED 驱动 + 上述全部组件,省事 |
ibv_devinfo 能看到网卡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 段。
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
要点拆解:
k8s.v1.cni.cncf.io/networks:Multus 的核心入口,每个附加网络对应 Pod 里的一块网卡(net1~net8)。8 卡 8 网卡,正好对上 GPU-NIC 对等映射rdma/shared:由 RDMA shared device plugin 提供,声明后 K8s 把宿主机的 /dev/infiniband 设备注入容器| 变量 | 作用 | 多网卡建议 |
|---|---|---|
NCCL_SOCKET_IFNAME | TCP 回退/控制路径用的网卡 | 固定为管理网卡 eth0 |
NCCL_IB_HCA | 指定 RDMA 网卡列表(逗号分隔或 mlx5_* 通配) | 显式列出全部 HCA,或留空让 NCCL 自动探测 |
NCCL_IB_DISABLE | 0=开启 RDMA;1=禁用(退化为 TCP) | RoCE 场景必须 0 |
NCCL_P2P_LEVEL | P2P 允许的拓扑级别(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 |
# 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 没放开或设备注入不全。
rdma/shared 资源;确认节点 kubectl describe node | grep rdmaNCCL_IB_DISABLE=0、HCA 可见、RoCE 交换机无损配置齐全(PFC/ECN),三者缺一不可NCCL_IB_HCA 被限制、NCCL_MAX_NCHANNELS 太小,或 Multus 只挂了一块附加网卡NCCL_SOCKET_IFNAME 固定,别依赖动态名nccl-tests all_reduce_perf 全量验收,记录每机带宽基线NCCL_SOCKET_IFNAME 指对all_reduce_perf -g 8 看的是多通道聚合通信库是大模型分布式系统的「隐形基础设施」:你看到的 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 直连 · 向量云 · 大模型服务通信库
A. 通信库是负责 GPU 之间、机器之间数据交换的软件层。大模型分布式训练/推理中,梯度同步(AllReduce)、张量合并、KV Cache 搬运都要跨卡跨机,通信库把这些通信原语高效实现(走 NVLink、RDMA,绕开 CPU)。最常用的就是 NCCL,此外还有 MPI、GLOO、UCX、NVSHMEM 等。
A. NCCL 是英伟达面向 GPU 设计的集合通信库,全程不落 CPU 内存,直接走 NVLink/PCIe P2P 和 RDMA,是大模型训练的事实标准;MPI 是通用并行计算标准,出身 CPU 生态,CUDA-Aware MPI(如 HPC-X)才支持 GPU 缓冲直通。HPC 传统负载用 MPI 多,大模型训练用 NCCL 多。
A. GLOO 是 PyTorch 内置的轻量后端,走 TCP/共享内存,启动快、调试友好。适合小模型、CPU 环境、快速验证,以及 NCCL 连不上时的兜底。大规模 GPU 训练性能拼不过 NCCL,不适合打主力。
A. NCCL 是「注册窗口、按需通信」的集合通信,通信仍由 CPU 发起;NVSHMEM 是「全局对称堆、统一寻址」——所有 GPU 共享同一虚拟地址空间,kernel 内线程可以直接 put/get 远端 GPU 内存,单边、细粒度、零拷贝,适合 MoE 路由、KV Cache 搬运这类点对点场景。
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 资源即可。
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 重试)。
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)。