AI服务器GPU拓扑感知调度:NUMA与NVLink绑定实战

多卡训练时GPU利用率上不去、跨卡通信慢,很多时候不是GPU本身的问题,而是进程被调度到了错误的CPU和GPU组合上。
AI服务器GPU拓扑感知调度要做的,就是先看清物理连接关系,再让进程落在同一NUMA节点和高速互联范围内。

先读懂拓扑:GPU挂在哪颗CPU、哪条NVLink上

在动手绑定前,先用两条命令确认硬件拓扑。
登录服务器后执行:

nvidia-smi topo -m
lscpu | grep -E "NUMA|Socket|Core"

nvidia-smi topo -m 输出的矩阵里,NV# 表示GPU之间走NVLink,SYS 表示跨NUMA节点走PCIe和UPI,NODE 表示同一NUMA节点。
比如某张卡与GPU0显示 NV12,说明它们之间有12条NVLink链路,应尽量让通信频繁的进程落在这一组卡上。

再看 lscpu 输出的NUMA节点分布:每个NUMA节点对应一组CPU核心,GPU的PCIe总线通常挂在其一节点下。
用以下命令查看GPU的PCI总线与NUMA归属:

nvidia-smi --query-gpu=index,pci.bus_id --format=csv
cat /sys/bus/pci/devices/0000:3b:00.0/numa_node

把总线ID替换成你实际的GPU总线地址。
返回值如 0 表示该GPU位于NUMA节点0。
记录每张卡的NUMA节点,后面绑定进程时按这个对应关系来。

手动绑定:用taskset把进程锁在对应CPU核上

如果不用集群调度器,最简单的方式是 taskset。
假设GPU3挂在NUMA节点1,节点1的CPU核心范围是16-31,启动训练进程时绑定:

taskset -c 16-31 python train.py --gpus 3

同时用 CUDA_VISIBLE_DEVICES=3 限定进程只看到GPU3,避免框架自行选择其他卡:

CUDA_VISIBLE_DEVICES=3 taskset -c 16-31 python train.py

多进程训练(如PyTorch DDP)时,每个进程分别绑定到自己GPU所在NUMA节点的核心范围,不要把所有进程绑到同一组核上,否则会互相抢CPU。

集群环境:让Slurm按拓扑自动分配

如果使用Slurm管理GPU节点,可以在节点配置中启用拓扑感知。
在 slurm.conf 中确认包含:

SelectType=select/cons_tres
SelectTypeParameters=CR_Core_Memory
TaskPlugin=task/affinity,task/cgroup

提交作业时用 --gpus-per-task 和 --ntasks-per-node 让Slurm按GPU与CPU的亲和关系分配资源。
提交后检查作业实际绑定:

scontrol show job  | grep -i "cpu\|gpu"

如果发现进程仍跨NUMA节点,检查节点是否启用了 task/affinity 插件,以及GPU是否被正确识别到GRES中。

常见坑:绑定后性能反而下降

  • 绑错核心范围:不同型号服务器NUMA节点对应的核心编号不同,不能照搬示例,必须用 lscpu 实际确认。
  • 忽略超线程:lscpu 中同一物理核的两个逻辑CPU都绑给进程可能引发争抢,建议只绑物理核。
  • 只绑GPU不绑CPU:数据加载线程仍可能被调度到远端NUMA节点,造成内存访问延迟。
  • 容器内绑定失效:Docker默认不继承taskset设置,需加 --cpuset-cpus 参数,例如 docker run --cpuset-cpus="16-31" --gpus '"device=3"' ...。

验证绑定是否生效

进程启动后,用以下命令确认CPU亲和性:

taskset -cp 

输出应只包含目标核心范围。
再查看GPU进程与拓扑:

nvidia-smi topo -m
nvidia-smi --query-compute-apps=pid,gpu_bus_id --format=csv

对比进程绑定的CPU与GPU所在NUMA节点是否一致。
如果一致,说明拓扑感知调度生效。
可以进一步用 numastat -p 查看进程内存是否主要落在本地NUMA节点,Numa_hit 比例高说明本地访问正常。

拓扑感知调度不是一次性配置,换卡、换主板或升级驱动后都应重新核对拓扑。
建议把上述查询命令写成巡检脚本,在每次调整训练任务前跑一遍,避免凭经验绑定。

相关问题

问题1:nvidia-smi topo -m显示SYS,是否必须避免跨节点?
不一定。跨NUMA节点通信并非不可用,只是延迟更高。如果任务对通信不敏感,或GPU数量不足以在单节点内分配,可以接受SYS。但对AllReduce频繁的训练任务,优先选择NVLink和同NUMA组合。

问题2:容器里看不到GPU的NUMA信息怎么办?
容器默认只挂载部分设备节点。启动时加 --privileged 或显式挂载 /sys/bus/pci/devices 相关路径,也可以直接在宿主机上用 nvidia-smi topo -m 查看后,把绑定参数传给容器。

问题3:Slurm没有按拓扑分配,如何排查?
先确认 slurm.conf 中 TaskPlugin 包含 task/affinity,再检查节点GRES配置是否把GPU与NUMA节点关联。用 slurmd -C 查看节点上报的拓扑信息,若GPU未出现在GRES中,需要重启slurmd并检查 gres.conf。

分享到:
上一篇
AI服务器GPU驱动升级前先做这三项检查
下一篇
AI服务器GPU资源配额:容器与MIG的分配和限制实战
1
系统公告

关于香港云优质服务器IP地址更换的通知

尊敬的客户: 因原IP运营商大幅涨价,为避免成本转嫁至用户,我司决定更换IP服务商。本次更换后,您的续费价格将保持不变,且新IP网络质量与服务标准不受影响。新IP已分配至后台,即刻生效(更换的新IP都是香港原生IPv4)。 涉及 IP 段: 45.192.x.x 旧 IP 停用时间: 2026 年 12 月 1 日
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意