3、多卡推理系统架构:多卡服务器拓扑、PCIe/NVLink/NVSwitch、CPU-GPU通信
3.1 多卡服务器的物理拓扑层次
多卡推理服务器的性能不仅取决于单张GPU的算力,更取决于GPU之间以及GPU与CPU之间的数据搬运能力。理解物理拓扑是定位负载不均问题的第一步。一台典型的8卡服务器(如NVIDIA DGX系列或主流AI服务器)内部存在三个层次的互连:CPU-GPU互连(PCIe或CXL)、GPU-GPU直接互连(NVLink/NVSwitch)、以及CPU-内存-网卡的系统互连。下图展示了一个典型的双路CPU + 8卡GPU的服务器拓扑结构:
从上图可以看到,GPU 0~3 挂在 CPU 0 的 PCIe 域下,GPU 4~7 挂在 CPU 1 的 PCIe 域下。所有 GPU 通过 NVLink 连接到 NVSwitch,形成全互联的 NVLink 域。这种拓扑决定了:同域内 GPU 通信走 PCIe 或 NVLink,跨域通信必须经过 CPU 间的 UPI/QPI 链路,延迟和带宽差异巨大。
3.2 三种互连方式的性能对比
理解三种互连方式的带宽和延迟差异,是判断推理负载是否受通信瓶颈制约的基础。下表给出了典型 8 卡 A100/H100 服务器上的实测参考值:
| 互连方式 | 单向带宽 | 延迟(P2P) | 典型场景 |
|---|---|---|---|
| PCIe Gen4 x16 | 32 GB/s | ~1.5 μs | CPU-GPU 数据传输、跨域 GPU 通信 |
| NVLink 3.0(单链路) | 50 GB/s | ~0.5 μs | 同域 GPU 点对点通信 |
| NVSwitch 全互联 | 600 GB/s(聚合) | ~0.8 μs | 8 卡全对全通信(All-to-All) |
3.3 CPU-GPU 通信路径与 NUMA 感知
CPU 与 GPU 之间的通信路径并非对称。每个 GPU 在物理上更靠近某一个 CPU 的 PCIe Root Complex,这种亲缘关系称为 NUMA 节点亲和性。当 GPU 需要从 CPU 侧读取数据(如推理请求的输入张量、KV Cache 的初始值)时,数据路径如下:
- CPU 应用程序将输入数据写入 页锁定内存(Pinned Memory),避免操作系统换页导致 DMA 失败。
- 数据通过 PCIe 控制器从 CPU 内存搬运到 GPU 显存(H2D 拷贝)。
- GPU 完成推理后,结果通过反向路径写回 CPU 内存(D2H 拷贝)。
如果 GPU 与 CPU 不在同一 NUMA 节点,数据必须经过 UPI/QPI 跨 CPU 传输,额外增加约 200~400 ns 延迟,且占用 CPU 间带宽。在推理服务中,请求预处理(Tokenization、Padding)和后处理(Sampling、Logits 处理)通常由 CPU 完成,这些操作产生的数据搬运频率极高,NUMA 错配会显著拉长单次请求的端到端延迟。
# 检查 GPU 的 NUMA 亲和性(Linux)
# 查看每个 GPU 对应的 PCIe 总线地址
nvidia-smi --query-gpu=index,pci.bus_id --format=csv
# 查看 PCIe 设备所在的 NUMA 节点
cat /sys/bus/pci/devices/0000:3b:00.0/numa_node
# 推荐:使用 nvidia-smi 的拓扑矩阵
nvidia-smi topo -m
执行 nvidia-smi topo -m 后,输出矩阵中 NV# 表示 NVLink 连接,PIX 表示同一 PCIe 交换机下,PXB 表示经过 PCIe 桥,SYS 表示需要经过 CPU 间互连。例如:
GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7
GPU0 X NV1 NV1 NV2 SYS SYS SYS SYS
GPU1 NV1 X NV2 NV1 SYS SYS SYS SYS
GPU2 NV1 NV2 X NV1 SYS SYS SYS SYS
GPU3 NV2 NV1 NV1 X SYS SYS SYS SYS
GPU4 SYS SYS SYS SYS X NV1 NV1 NV2
GPU5 SYS SYS SYS SYS NV1 X NV2 NV1
GPU6 SYS SYS SYS SYS NV1 NV2 X NV1
GPU7 SYS SYS SYS SYS NV2 NV1 NV1 X
上例中,GPU0~3 与 GPU4~7 之间全部是 SYS,意味着跨组通信必须走 CPU 间的 UPI 链路,带宽骤降至 PCIe 水平且延迟翻倍。如果推理框架将张量并行组跨组放置,性能将严重劣化。
3.4 实际案例:8 卡服务器上的推理部署拓扑选择
假设我们要部署一个 70B 参数的 LLM,采用张量并行(TP=4)+ 流水线并行(PP=2)的混合并行策略。70B 模型权重约 140 GB(FP16),单张 A100 80GB 无法容纳,必须使用 TP=4 将权重切分到 4 张 GPU 上。此时有两种拓扑选择:
方案 B(不推荐):TP 组跨域放置(如 GPU0、GPU1、GPU4、GPU5),PP 组在同域内。
方案 A 中,TP 组内每层 Transformer 的 AllReduce 走 NVLink,带宽 600 GB/s,通信耗时极短;PP 组之间传输的是激活值(每层约几 MB),频率低,即使走 PCIe 影响也可控。方案 B 中,TP 组内每次 AllReduce 都要经过 UPI 链路,通信耗时增加 10 倍以上,GPU 利用率将出现明显的“锯齿状”波动——计算等待通信,整体吞吐下降 30%~50%。
torch.distributed 默认按 GPU 序号分配 rank,如果直接使用 --nproc-per-node=8 启动 TP=4 的推理,框架可能将 rank 0~3 和 rank 4~7 分别作为两个 TP 组,这恰好是跨 NVSwitch 域的——性能反而不如同域内 TP=4 + 跨域 PP=2 的组合。务必通过 NCCL_P2P_LEVEL 和 NCCL_TOPO_DUMP_FILE 检查实际通信路径。
3.5 拓扑感知的部署检查清单
- 第一步:运行
nvidia-smi topo -m获取 GPU 间互连矩阵,标记 NVLink 域和 PCIe 域。 - 第二步:确认每个 GPU 的 NUMA 亲和性,记录
numa_node值。 - 第三步:根据模型并行策略,将通信最频繁的并行组(TP 组)放置在 NVLink 域内。
- 第四步:设置环境变量
NCCL_P2P_LEVEL=NV强制 NCCL 仅使用 NVLink 做 P2P,避免意外走 PCIe。 - 第五步:使用
nsys profile或ncu抓取通信耗时,验证 AllReduce 是否达到 NVLink 带宽。