GPU集群架构:典型硬件拓扑与调度系统简介

分布式训练任务的中断,往往并非源于代码逻辑本身,而是源于底层硬件拓扑与调度系统之间的“错配”。理解集群的物理连接方式与资源管理策略,是分析任务中断根因的第一道门槛。本节聚焦两类核心硬件互联(NVLink与InfiniBand)和两类主流调度系统(Slurm与K8s),帮助您建立从“一张显卡”到“整柜集群”的完整视图。

3.1 典型硬件拓扑:从单机到跨节点

GPU服务器内部与服务器之间,存在两种截然不同的通信路径。混淆这两条路径,是许多网络超时中断的根源。

3.1.1 节点内互联:NVLink与NVSwitch

NVLink是NVIDIA推出的高带宽、低延迟点对点互联总线,用于GPU与GPU、GPU与CPU之间的直连。在8卡DGX或HGX服务器中,通常采用全连接(All-to-All)或NVSwitch两种拓扑:

  • 全连接拓扑:每块GPU通过NVLink直接与其他GPU相连(如A100 4卡全连接),适合小规模张量并行。
  • NVSwitch拓扑:引入独立交换芯片,实现8卡或更多GPU之间的无阻塞全互联。任何两块GPU之间的通信带宽一致,无需经过PCIe交换机。

NVLink的典型带宽为:A100单链路50GB/s(双向),H100单链路90GB/s(双向)。在8卡H800服务器中,每块GPU通常拥有8条NVLink链路,总双向带宽可达900GB/s。若训练任务中使用了张量并行(如Megatron-LM的TP=8),则节点内通信必须走NVLink,否则性能会断崖式下降。

排查提示:若日志中出现“NVLink Error”或“Xid 79”等错误,往往意味着GPU间NVLink链路不稳定或接触不良。此时应检查nvidia-smi nvlink -s命令输出的链路状态,确认所有链路处于Active状态。

3.1.2 跨节点互联:InfiniBand与RoCE

当模型规模超出单机显存,需要多机并行时,节点间通信依赖高速网络。目前主流方案是InfiniBand(IB)和RoCE(RDMA over Converged Ethernet)。

InfiniBand采用专用交换机和网卡(HCA),提供RDMA(远程直接内存访问)能力,延迟低至微秒级。常见速率为HDR(200Gb/s)、NDR(400Gb/s)。在训练集群中,IB网络通常采用胖树(Fat-Tree)或Torus拓扑,保证任意两个节点间的带宽接近线速。

RoCE则运行在以太网上,分为RoCEv1(L2)和RoCEv2(L3)。RoCEv2需要配置流控(PFC)和ECMP,对交换机缓冲要求较高,否则容易出现丢包导致训练中断。

特性NVLinkInfiniBandRoCEv2
通信范围节点内(GPU-GPU)跨节点(服务器间)跨节点(服务器间)
典型带宽50-100GB/s/链路200-400Gb/s/端口100-400Gb/s/端口
延迟亚微秒级1-3微秒2-5微秒(依赖交换机)
协议专有协议RDMARDMA over Ethernet
主要用途张量并行、数据并行梯度同步数据并行、流水线并行跨节点通信低成本跨节点通信
故障表现Xid错误、链路降速IB丢包、端口DownPFC死锁、ECMP哈希不均
典型GPU集群硬件拓扑(2节点示例) 计算节点 1(8×GPU) GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 NVSwitch (节点内互联) IB HCA 计算节点 2(8×GPU) GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 NVSwitch (节点内互联) IB HCA InfiniBand 交换机(Fat-Tree) 跨节点通信:NCCL / RCCL 使用 图例与关键路径 NVLink(节点内,GPU-GPU,带宽900GB/s) InfiniBand(跨节点,HCA-HCA,带宽200-400Gb/s) GPU计算卡 IB网卡(HCA) NVSwitch

3.2 调度系统:谁来决定任务跑在哪

调度系统负责分配GPU资源、排队任务、监控作业状态。不同调度系统对任务中断的处理方式截然不同,理解其差异有助于快速定位“任务为何被杀”或“为何卡在排队中”。

3.2.1 Slurm:传统HPC作业调度

Slurm(Simple Linux Utility for Resource Management)是学术与超算中心最常用的调度器。它采用分区(Partition)+ 作业(Job)模型,用户通过sbatch或srun提交作业,由slurmctld统一调度。

关键概念:

  • Partition:节点分组,如gpu-a100、gpu-h800,不同分区可设置不同QoS与优先级。
  • Job Step:一个作业内可包含多个步骤(如数据加载、训练、评估)。
  • 资源限制:通过--gres=gpu:8申请GPU数量,--nodes=2申请节点数。
# 提交一个使用2节点、每节点8卡的任务
srun -p gpu-h800 --nodes=2 --gres=gpu:8 --ntasks-per-node=8 \
     --cpus-per-task=16 --time=48:00:00 \
     python train.py --config configs/llama2_70b.yaml

Slurm中任务中断的常见原因包括:

  • 超时被杀:--time设置过短,作业到达时间上限后Slurm发送SIGTERM,若未优雅退出则SIGKILL。
  • 节点故障:节点宕机或GPU异常,Slurm会将作业置为FAILED或NODE_FAIL。
  • 抢占:高优先级作业到来时,低优先级作业可能被抢占(Preempt)。
避坑提醒:Slurm默认不会自动重启失败作业。若训练任务因节点故障中断,需要依赖外部机制(如--requeue标志或自研看门狗脚本)实现自动恢复。务必在提交脚本中设置--requeue,并让训练代码支持断点续训。

3.2.2 Kubernetes:云原生容器调度

K8s将GPU作为可调度的扩展资源(nvidia.com/gpu),通过Device Plugin插件上报GPU数量。与Slurm不同,K8s以Pod为最小调度单位,支持容器化训练任务。

在K8s中运行分布式训练,通常使用以下方式:

  • Job / CronJob:适用于单任务或定时任务。
  • MPI Operator:为MPI风格分布式训练提供CRD(自定义资源),自动创建Worker与Launcher。
  • PyTorchJob / TFJob:来自Kubeflow,专门管理PyTorch或TensorFlow的PS/Worker架构。
# PyTorchJob 示例(Kubeflow)
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
  name: pytorch-simple
spec:
  pytorchReplicaSpecs:
    Master:
      replicas: 1
      template:
        spec:
          containers:
          - name: pytorch
            image: pytorch/pytorch:2.1.0-cuda12.1
            command: ["python", "-m", "torch.distributed.run", "--nproc_per_node=8", "train.py"]
            resources:
              limits:
                nvidia.com/gpu: "8"
    Worker:
      replicas: 2
      template:
        spec:
          containers:
          - name: pytorch
            image: pytorch/pytorch:2.1.0-cuda12.1
            command: ["python", "-m", "torch.distributed.run", "--nproc_per_node=8", "train.py"]
            resources:
              limits:
                nvidia.com/gpu: "8"

K8s任务中断的典型场景:

  • OOMKilled:容器内存超限被cgroup杀掉。
  • 节点压力驱逐:节点磁盘或内存不足,kubelet触发Eviction。
  • GPU异常:Device Plugin上报的GPU不健康,调度器不会将Pod调度到该节点。
  • 抢占与优先级:PriorityClass低的Pod可能被高优先级Pod抢占。

3.3 调度系统与硬件拓扑的交互:NCCL的视角

NCCL(NVIDIA Collective Communications Library)是分布式训练中负责GPU间通信的核心库。它需要感知底层拓扑才能选择最优通信路径。当调度系统分配的节点或GPU位置与NCCL的预期不符时,就会出现性能骤降甚至通信超时。

NCCL通过拓扑探测构建通信树:

  1. 启动时调用ncclTopoDetect,读取PCIe、NVLink、IB链路信息。
  2. 根据GPU所在NUMA节点、NVLink连接关系,构建intra-node与inter-node通信图。
  3. 选择Ring或Tree算法进行AllReduce。

若调度系统将任务分散到不同机柜的节点,而节点间IB带宽不足,NCCL可能回退到TCP/IP通信,导致训练速度骤降。此时可通过设置环境变量强制指定网卡:

export NCCL_IB_DISABLE=0
export NCCL_IB_HCA=mlx5_0,mlx5_1
export NCCL_SOCKET_IFNAME=ib0
export NCCL_DEBUG=INFO   # 打印实际使用的通信路径
案例复盘:某团队在K8s上启动64卡训练任务,发现AllReduce耗时从预期的2ms暴涨至80ms。通过NCCL_DEBUG=INFO日志发现,NCCL将通信路径识别为“TCP/IP”,而非“IB”。原因是Pod未设置hostNetwork: true,导致容器内无法访问IB网卡设备。修复方法:在Pod spec中增加hostNetwork: true并挂载/dev/infiniband设备。

3.4 常见误区与避坑清单

误区后果正确做法
认为NVLink与IB可以混用跨节点通信误走NVLink(实际不可达),导致初始化失败明确区分节点内/跨节点通信,NCCL会自动选择,但需确保IB网卡驱动正常
Slurm作业不设置--requeue节点故障后作业直接失败,无自动恢复添加--requeue,并实现checkpoint保存
K8s Pod未暴露IB设备NCCL回退到TCP,性能暴跌使用hostNetwork或SRIOV设备插件
忽略NUMA亲和性GPU跨NUMA访问内存,延迟增加30%以上使用nvidia-smi topo -m检查,设置CPU绑核
所有节点使用同一IB子网但未配置路由跨子网通信失败,任务挂起检查ibstatus,确保子网管理器(SM)运行正常

3.5 本节小结