CPU 绑定#

从 vllm-ascend v0.18.0rc1 开始,CPU 绑定在基于 ARM 的昇腾服务器上默认启用。

通常您无需手动配置。 仅当您想禁用它或明确默认行为时,才设置 enable_cpu_binding

CPU 绑定的优势#

CPU 绑定改进了配备昇腾 NPU 的多插槽 ARM 服务器的主机端调度。它旨在解决三个常见的主机端推理性能问题:

  • 降低跨 NUMA 流量。 工作进程更靠近为其活跃 NPU 选择的 CPU 和内存资源,从而减少远程 NUMA 访问。

  • 降低线程抢占带来的上下文切换开销。 关键运行时线程在稳定的 CPU 范围内运行,减少了调度器移动和繁忙主机上的 CPU 争用。

  • 更好的延迟稳定性和多工作进程隔离。 独立的工作进程避免共享相同的 CPU/NUMA 资源,这有助于减少尾延迟抖动,并使多 NPU 服务期间的吞吐量更具可预测性。

此功能是一项主机端性能优化。它不会改变模型执行逻辑或数值输出。 当内存迁移支持不可用时,CPU 亲和性仍然有效,但内存局部性可能会变差,延迟或吞吐量可能会下降。

使用方法#

在线服务#

默认行为:

vllm serve Qwen/Qwen2.5-7B-Instruct

禁用 CPU 绑定:

vllm serve Qwen/Qwen2.5-7B-Instruct \
  --additional-config '{"enable_cpu_binding": false}'

离线推理#

默认行为:

from vllm import LLM

llm = LLM(model="Qwen/Qwen2.5-7B-Instruct")

禁用 CPU 绑定:

from vllm import LLM

llm = LLM(
    model="Qwen/Qwen2.5-7B-Instruct",
    additional_config={"enable_cpu_binding": False},
)

前提条件#

官方 vllm-ascend 镜像在 v0.18.0rc1 及更早版本中已包含 util-linuxprocps / procps-ng从 v0.18.0rc1 开始,官方镜像还包含了 numactl

如果您未使用官方镜像,请手动安装主机工具:

# Ubuntu/Debian
sudo apt-get install -y util-linux numactl procps

# RHEL/CentOS/Alma/Rocky
sudo yum install -y util-linux numactl procps-ng

# openEuler
sudo dnf install -y util-linux numactl procps-ng

没有 numactl / migratepages,vLLM Ascend 仅跳过内存迁移。 工作进程和运行时线程仍会被绑定,但已放置在远程 NUMA 节点上的页面不会被迁移,这可能会降低局部性并导致延迟或吞吐量下降。

为获得最佳局部性,请使用在各 NUMA 节点间均匀分布的 cpuset。不平衡的 cpuset 可能会降低 CPU 绑定的局部性优势。

在昇腾 950 上,CPU 绑定使用 npu-smi info -t topo 中的 NPU 到 CPU 亲和性来选择工作进程的亲和性 NUMA 节点。每个工作进程主进程被绑定到该 NUMA 节点的一个 CPU 簇。簇大小由 lscpuThread(s) per core 决定:当值为 1 时为 8 个 CPU,当值为 2 时为 16 个 CPU。昇腾 950 还会将主机的 uvb_poll_window_thread 线程绑定到 NUMA0 上除 CPU0 之外的 CPU,并受当前 cpuset 约束。在 Docker 部署中,创建容器时添加 --pid=host,以便 vLLM Ascend 可以发现并绑定这些主机线程。当 migratepages 可用时,昇腾 950 仍然可以迁移内存页面,但它不会单独绑定 ACL/release 线程,也不应用 IRQ 绑定。

对于 IRQ 绑定,进程还需要读取 /proc/interrupts 和写入 /proc/irq/*/smp_affinity 的权限。如果 irqbalance 正在运行且进程可以使用 systemctl,vLLM Ascend 会在应用 IRQ 亲和性之前停止它。在 systemctl 不可用的容器中,当 IRQ 亲和性很重要时,请在主机上停止 irqbalance

昇腾 950 不应用 IRQ 绑定。在昇腾 950 上运行时,日志包含 [irq] IRQ binding skipped on Ascend 950.,并且此功能不会写入任何 /proc/irq/*/smp_affinity 文件。

昇腾 950 的分配日志使用 worker=[...] 而不是 acl=[...]release=[...],因为在此设备类型上 ACL/release 线程不会被单独绑定。当找到并绑定 UVB 轮询线程时,日志还会报告它们的线程 ID 和 CPU 池:

Ascend 950 NPU0: worker=[...]
[cpu_bind_ascend_950] uvb_poll_window_thread tids=[...] cpus=[...]

在主机上,当您需要稳定的 IRQ 亲和性时,请在启动 vLLM 之前停止 irqbalance

sudo systemctl stop irqbalance

在 vLLM 服务退出后,如果主机应恢复到默认的 IRQ 平衡策略,请重新启动它:

sudo systemctl start irqbalance

故障排除#

消息

含义

操作

CPU binding skipped: non-ARM CPU detected.

CPU 绑定仅在 ARM 上运行。

在 x86_64 上无需操作。

Can not get running npu info.

未找到正在运行的 NPU,或者 ASCEND_RT_VISIBLE_DEVICES 过滤掉了所有 NPU。

检查可见的 NPU ID 和 npu-smi info

Insufficient CPUs for binding...

可用 CPU 数量少于角色拆分所需。具有 IRQ 绑定的设备每个逻辑 NPU 至少需要 5 个 CPU。昇腾 950 每个工作进程需要一个完整的簇。

扩展 cpuset 或减少可见的 NPU。

NPU topo affinity not found...

拓扑亲和性不可用。

在昇腾 950 上,工作进程 CPU 绑定被跳过。在其他拓扑亲和性设备上,vLLM Ascend 回退到 global_slice。当期望拓扑亲和性时,请检查 npu-smi info -t topo

uvb_poll_window_thread not found... --pid=host

昇腾 950 无法看到主机的 UVB 轮询线程。

使用 --pid=host 重新创建 Docker 容器,然后重启 vLLM。

failed to bind uvb_poll_window_thread... --pid=host

Ascend 950 发现了一个 UVB 轮询线程,但未能绑定该线程。

检查权限,如果在 Docker 中运行,请使用 --pid=host 重新创建 Docker 容器。

The 'migratepages' command is not available...

内存迁移被跳过,但 CPU 线程绑定仍会继续执行。

如果 NUMA 局部性或性能受到影响,请安装 numactl

[irq] IRQ binding skipped on Ascend 950.

Ascend 950 不使用 IRQ 绑定步骤。

无需操作。工作进程主绑定和内存迁移仍会继续执行。

Bind cpus failed in rank...

绑定步骤失败,该 rank 的 CPU 绑定被跳过。

检查 tasksetlscpunpu-smi、cpuset 大小以及 /proc/irq 的权限。