NUMA 节点(Non-Uniform Memory Access)
NUMA = 非均匀内存访问,是多 CPU 服务器的一种内存架构设计。
核心思想
在多颗物理 CPU 的服务器上,内存被分成多块,每块内存"直连"一颗 CPU:
┌─────────────────────┐ ┌─────────────────────┐
│ CPU 0 (核心0-31) │ │ CPU 1 (核心32-63) │
│ │ │ │
│ 本地内存 (NUMA 0) │◄────►│ 本地内存 (NUMA 1) │
│ ~快速访问 │ QPI │ ~快速访问 │
└─────────────────────┘ └─────────────────────┘为什么叫"非均匀"?
| 访问类型 | 延迟 |
|---|---|
| CPU 0 访问 NUMA 0 的内存(本地) | 低延迟 ✅ |
| CPU 0 访问 NUMA 1 的内存(远端) | 高延迟 ❌(需跨 QPI/UPI 总线) |
两颗 CPU 访问内存的速度不一样,取决于内存在哪个 NUMA 节点 —— 这就是"非均匀"的含义。
对应你的机器
NUMA Node 0: CPU 核心 0-31, 64-95 + GPU 0~3
NUMA Node 1: CPU 核心 32-63, 96-127 + GPU 4~7PCIe 总线也是挂在某颗 CPU 下面的,因此 GPU 也有 NUMA 亲和性:
- GPU 0-3 的 PCIe 通道连接在 CPU 0 下,CPU 0 传数据到这些 GPU 走本地总线,很快
- 如果用 CPU 1 的核心去操作 GPU 0-3,数据需要先跨 NUMA 到 CPU 0,再到 GPU,多一跳延迟
实际编程建议
如果只用 GPU 6、7(它们属于 NUMA 1),则:
- 数据加载、预处理的线程应绑定到 CPU 32-63
- 用
numactl --cpunodebind=1 --membind=1 python train.py来绑定进程到 NUMA 1
对于大模型推理(你机器上跑的 sglang),NUMA 不匹配会导致 CPU→GPU 的数据传输(如 tokenize 结果、KV cache 搬运)出现额外延迟。