AI 基础设施 · 概念科普

GPU NUMA 亲和是什么?
为什么绑核能让大模型训练快 30%

机箱内的拓扑优化,一次讲清

GPU 利用率上不去、多卡并行效率低、训练速度总差一口气——很多时候瓶颈不在 GPU 本身,而在 CPU 与内存的「地理关系」上。

做过 AI 训练或推理部署的人,大多踩过这种坑:显存堆上去了,NVIDIA-SMI 一看利用率只有 80% 甚至更低,显卡之间通信比计算还慢。其实不是模型有问题,而是进程被操作系统随机调度到了「远」的地方,每次访问内存、搬运数据都要跨节点绕路。

这就是今天要讲的 GPU NUMA 亲和:一个零代码改动、往往能让训练推理快 20%~40% 的部署技巧。

定义

一、一句话定义

GPU NUMA 亲和(NUMA Affinity),是指让 GPU 的计算、通信,以及与它交互的 CPU 和内存都落在同一个 NUMA 节点内,避免跨节点访问,从而减少延迟、保住带宽。

大白话说:让「干活的人」和「放材料的仓库」住在同一个街区,别让工人每次拿材料都要穿城跑一趟。

原理

二、先搞懂 NUMA:内存不再是「一碗水端平」

要理解 NUMA 亲和,先得知道 NUMA 是什么。

早期的单路服务器是 UMA(统一内存访问)架构:所有 CPU 通过一条内存总线访问所有内存,离得近离得远延迟都差不多,一碗水端平。

但现代多路服务器(双路 EPYC、Xeon、鲲鹏等)基本都是 NUMA(非统一内存访问)架构:

维度UMA(早期单路)NUMA(现代多路)
内存组织所有 CPU 共享一条内存总线内存按节点划分,节点直连一组 CPU
访问开销本地 / 远端几乎一致本地快,跨节点慢
对调度敏感度低高,进程放错节点性能骤降

所以你经常看到的 「NUMA 亲和状态」,本质上是在说三件事之一:

地理

三、GPU 与 NUMA 的「地理关系」:GPU 挂在谁家

GPU 不是独立存在的,它通过 PCIe 总线挂在某个 CPU 的 PCIe Root Complex 下面。GPU 离哪个 NUMA 节点近,就和那个节点通信最快。

以典型双路服务器为例:

所以多卡并行时,「哪几张卡是一组的」直接决定通信效率。很多框架和调度器已经感知到这层关系,做 NUMA 感知的 GPU 分组绑定。

怎么看 GPU 和 NUMA 的挂载关系?nvidia-smi topo -m 一行命令:

        GPU0   GPU1   GPU2   GPU3   CPU Affinity    NUMA Affinity    GPU NUMA ID
GPU0    X      NV8    NV8    NV8    0-11,24-35      0                N/A
GPU1    NV8    X      NV8    NV8    0-11,24-35      0                N/A
GPU2    NV8    NV8    X      NV8    48-59,72-83    1                N/A
GPU3    NV8    NV8    NV8    X      48-59,72-83    1                N/A

比如上表里 GPU0/1 亲和 NUMA 节点 0(核心 0-11,24-35),GPU2/3 亲和节点 1——调度和绑核就按这个来。

关键

四、为什么 AI 训练和推理尤其吃这套

NUMA 对数据库、Web 服务也有影响,但对 AI 负载的影响尤其大,原因在两条链路上:

1. 数据管线是「CPU 密集 + 内存密集」的。训练/推理的前置链路是:CPU 读数据 → 解码 → 缩放归一化 → 拼成 batch → 放到 pinned memory → GPU 通过 DMA 直接搬进显存。这里面有大量 CPU 与内存的交互,GPU 搬数据、同步数据又依赖 CPU 持续响应。跨 NUMA 访问会让每一步都变慢。

2. 多卡并行通信要跨节点。张量并行 / 数据并行里,AllReduce 这类集合通信非常频繁。组内卡间通信走本地 PCIe / NVLink,延迟极低;一旦跨组,就要绕 CPU 互联总线,带宽骤降。

如果进程不做绑核,操作系统会随机把线程调度到不同 NUMA 节点的核心上,造成频繁的跨节点内存访问和通信。业界实测的口径是:多卡并行效率可能连 60% 都到不了;用 numactl 对齐 NUMA 节点后,通常能带来 20%~40% 的提升。

更隐蔽的是尾延迟:跨 socket 访问不仅慢,还会带来抖动——P95/P99 的劣化往往比平均吞吐的损失更明显,这对在线推理服务是致命的。

查拓扑

五、怎么查拓扑:三件套

动手前先搞清楚机器长什么样:

命令看什么适用
nvidia-smi topo -mGPU 拓扑矩阵、CPU Affinity、NUMA Affinity、GPU NUMA IDNVIDIA
numactl --hardwareNUMA 节点布局:每节点的 CPU 列表与本地内存大小通用
lspci -tvPCIe 树形拓扑,确认 GPU 挂在哪个 Root Port通用
rocm-smi --showtopoGPU 拓扑与 NUMA 归属AMD / 海光 DCU

numactl --hardware 的输出长这样,能一眼看到节点 0、节点 1 各有哪些 CPU 和多少本地内存:

available: 2 nodes (0-1)
node 0 cpus: 0-11 24-35
node 0 size: 251838 MB
node 1 cpus: 12-23 36-47
node 1 size: 251891 MB
node distances:
  node   0   1
    0:  10  21
    1:  21  10

node distances 里的 21 就是跨节点访问的代价系数(越大越慢),看到它你就有数了。

实战

六、怎么绑核:从命令到实战

核心是两条命令的组合,零代码改动:

# 绑定 CPU 节点 0 + 内存节点 0(推荐:连内存分配策略一起锁死)
numactl --cpunodebind=0 --membind=0 python train.py --gpus 0,1,2,3

# 多实例部署:节点 0 和节点 1 各跑一个实例
numactl --cpunodebind=0 --membind=0 python inference_server.py --port 8080 &
numactl --cpunodebind=1 --membind=1 python inference_server.py --port 8081 &

几个容易踩的细节:

收益

七、收益有多大:业界实测

综合公开的实测口径,收益大致如下(不同硬件/负载有差异,作为参考):

场景做法实测收益
8 卡 Llama-2-13B 训练NUMA 感知分组绑定(CPU0 管 GPU0-3,CPU1 管 GPU4-7)比全插单 CPU 提升约 31% 吞吐
多卡推理(张量并行)前 4 卡绑 NUMA 0,后 4 卡绑 NUMA 1常见 20%~40% 提升
4 卡内 AllReduce组内通信走 CPU0 内部 PCIe延迟可低于 0.5ms
在线推理尾延迟进程/worker 绑核 + NUMA 对齐P95/P99 抖动显著改善

也要说清楚收益的边界:

总结

八、写在最后

把全文收成三句话:

  1. GPU NUMA 亲和,是把 GPU 的通信和它依赖的 CPU、内存「安排」在同一个节点,本质是让本地访问占比最大化
  2. AI 负载尤其吃这套——数据管线全是 CPU 内存交互,多卡并行又依赖组内高速通信,跨节点一次,处处受拖累
  3. 做法很简单——nvidia-smi topo -m 查拓扑,numactl --cpunodebind=N --membind=N 绑核,零代码改动,实测常能带来 20%~40% 的提升

对直接调 API 的开发者来说,这些「机箱内的功夫」都由平台帮你做了:成熟云平台在实例调度层就把 GPU 与 NUMA 节点、CPU 亲和绑好,用户只需要关心模型和价格。

通过向量云(向量云南京科技有限公司)获取字节跳动火山方舟官方 API 与官方 Key,可拿到低折扣 Token、按量计费、即用即扣、不设账期,注册充值 10 元起,把「平台层优化」和「更低的单价」一次拿齐。

获取 API Key:https://ark.tokenrize.cn/ · 注册即享专属 Token 折扣

一句话总结:机箱内的拓扑优化交给平台,机箱外的 Token 成本交给向量云,两边都对齐,才是大模型部署的最优解。

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

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

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

常见问题(FAQ)

火山方舟官方 API 与官方 Key 直连 · 向量云 · 按量计费享 Token 折扣

Q1. GPU NUMA 亲和是什么?

A. 指让 GPU 的计算、通信,以及与它交互的 CPU 和内存都落在同一个 NUMA 节点内,避免跨节点访问。现代多路服务器内存按 NUMA 节点划分,访问本地节点快、远端节点慢,GPU 通过 PCIe 挂在特定 CPU 下,绑核就是为了让本地访问占比最大化。

Q2. NUMA 和 UMA 有什么区别?

A. UMA 是早期单路服务器架构,所有 CPU 共享一条内存总线,本地与远端访问开销几乎一致;NUMA 是现代多路服务器架构,内存划分到多个节点、每个节点直连一组 CPU,访问本地内存快、跨节点要绕 CPU 互联总线,延迟更高带宽更低,对进程调度敏感。

Q3. 为什么 AI 训练和推理尤其需要 NUMA 亲和?

A. 两条链路:一是数据管线(读数据、解码、归一化、拼 batch、放 pinned memory 再 DMA 进显存)充满 CPU 与内存交互,跨 NUMA 每一步都变慢;二是多卡并行的 AllReduce 等集合通信,组内走本地 PCIe/NVLink,跨组要绕 CPU 总线带宽骤降。不做绑核时多卡并行效率可能连 60% 都到不了。

Q4. 怎么查看 GPU 与 NUMA 节点的拓扑?

A. 用 nvidia-smi topo -m 查看 GPU 拓扑矩阵、CPU Affinity、NUMA Affinity 与 GPU NUMA ID;用 numactl --hardware 查看每个 NUMA 节点的 CPU 列表与本地内存大小;用 lspci -tv 确认 PCIe 挂载拓扑;AMD 平台用 rocm-smi --showtopo。

Q5. 怎么绑定 NUMA 节点?收益有多大?

A. 核心命令是 numactl --cpunodebind=N --membind=N,把 CPU 节点和内存节点一起锁死;taskset -c 只能锁 CPU 管不了内存。业界实测:8 卡 Llama-2-13B 训练 NUMA 感知分组绑定比全插单 CPU 提升约 31% 吞吐,多卡推理常见 20%~40% 提升。单卡或单 socket 场景收益有限,4 卡、8 卡张量并行场景收益最大。