背景
在大模型的运行过程中,CPU负责任务下发,NPU负责任务执行。在现网问题中,我们可以将大多数问题总结为两类模型,分别为DeviceBound模型、HostBound模型:
DeviceBound模型:如果Device上Task执行速度比Host下发慢,则Device上Task调度开销和算子执行时间成为瓶颈,这种模型通常称为Device Bound模型,如图1所示。Device Bound的模型,Task的下发开销会被已下发Task的执行时间掩盖起来。
图1:DeviceBound模型
Hostbound模型:如果Device上Task执行速度比Host下发快,则Host调度开销成为瓶颈,这种模型通常被称为Host Bound模型,如图2所示。Host Bound的模型,Task的下发开销不能完全被已下发Task的执行时间掩盖,Device执行时序上存在间歇的空闲状态。
图2:HostBound模型
而影响Task下发的原因有很多种,例如:
同一进程在不同CPU核间切换引起的上下文切换,导致Task下发变慢;
系统或其它不相关进程与业务进程运行在同一 CPU核上导致的资源抢占,导致Task下发变慢;
NPU相关中断、系统中断(执行为微妙级但一秒内可能发生上万次,且优先级高于普通进程)与业务进程抢占同一 CPU核资源,导致Task下发变慢(其中NPU相关中断包含但不局限于sq_send_trigger_irq、cq_update_irq、dev_*_sq_task等)。
在vLLM理中,以Qwen3 32B模型推理为例,CPU在Host侧的执行时间组成如下图所示:
图3:Host侧时延开销组成部分
其中在绑核前,Host侧的端到端耗时开销为20.4ms,其主要组成包含如下几个部分:
ACLGraph replay操作:ACLGraph将主模型入图后的整图进行下发操作,这一部分耗时不多仅占约300us以内。
ACLGraph中的attention元数据更新操作:即_update_attn_fia_params调用,在FullGraph模式下,attention的参数(如seq_len,query_start_loc)是动态的,每次forward都会变化。但是graph在capture时记录的是固定参数,replay的时候是需要提前更新的,在_update_attn_fia_params通过一个For循环对模型的每一层Attention都进行参数更新。这一部分耗时开销和模型层数强相关。
Rejection_sampler操作:在有投机模型(MTP/Eagle3)存在的场景下,rejection_sampler是投机解码的核心组件,用于决定哪些drafter tokens被接受,处理被拒绝的tokens,管理bonus token机制,保障输出分布与主模型一致。
Eagle3投机模型执行:在这一阶段需要对投机模型进行数据准备,投机模型Foward(当前阶段投机模型未入图,是eager单算子模式),以及投机模型后处理(compute logits ……)相关的一些操作,由于没有入图当前这部分执行时延很长。
PrepareInput操作:在异步调度场景下,可以提前把下一个Token的Input准备过程执行起来,这个开销是框架侧带来的固定时延开销。
由于进程抢占,还有中断等因素,导致这一过程整体执行过长,那么绑核操作的核心思路,就是尽可能的排除干扰,来加速Host侧的执行开销。由于Qwen3 32B 主模型在NPU侧执行时间只有12.8ms,加上投机模型的执行时间只有16ms左右,小于Host侧的执行时延20.4ms,导致投机模型部分存在较大的空泡,后续需要降低host侧执行时间,减少下发慢带来的空泡问题。
图4:NPU侧的执行时延较短无法掩盖
Host侧的时延开销导致投机模型执行存在空泡
解决方案
为避免非业务进程、中断等抢占业务进程的CPU核资源,减少进程迁移带来的性能损失,根据业务特征,合理利用CPU核资源,将业务进程、非业务进程、中断等分别进行绑核操作,详细操作如下图所示:
图5:A+K机器绑核策略
线程及中断介绍
推理框架线程
VLLM::EngineCore:负责调度和组batch操作,整个推理期间仅存在一个VLLM::EngineCore线程;
VLLM::Worker_TP:每个DIE创建一个Worker线程,负责模型的执行等相关操作。
PTA线程
acl_thread:PTA创建,负载算子下发,每个DIE创建一个acl_thread线程;
release_thread:PTA创建,负责资源释放,每个DIE创建一个release_thread线程。
中断
sq_send_trigger_irq:Host侧算子进入下发队列完成中断,每个DIE创建一个sq_send_trigger_irq线程;
cq_update_irq:算子执行下发操作完成中断,每个DIE创建一个cq_update_irq线程;
dev_*_sq_task:驱动中断,每个DIE创建一个dev_*_sq_task线程。
绑核机制介绍
当前使用Atlas 800I A3 A+K机器(8卡),共包含320个CPU核心,分为8个NUMA,将每个DIE的核心线程(VLLM::Worker_TP、acl_thread、release_thread)及中断(sq_send_trigger_irq、cq_update_irq、dev_*_sq_task)分配与不同NUMA内的固定CPU核进行绑定,避免线程间冲突抢占、冲突导致的性能劣化。例如:第0个DIE的sq_send_trigger_irq中断与CPU0+20*0进行绑定,第1个DIE的sq_send_trigger_irq中断与CPU 0+20*1进行绑定,依次类推。
绑核后收益
CPU执行时间从20.4ms降低到了14.6ms,性能提升28%,TPOT从8.48ms降低到7.2ms,性能优化17.78%。
图6:绑核后host侧执行时延降低
在大模型推理落地过程中,性能瓶颈并非全部来源于硬件算力与模型本身,Host侧CPU调度低效引发的HostBound问题,是极易被忽略但影响极大的性能短板。本文分享的细粒度CPU绑核方法,通过线程与中断精细化隔离、CPU核心专属绑定的轻量化优化方式,填补了Host侧性能短板,抹平NPU推理空泡,通过MindStudio工具,结合Qwen3 32B模型落地验证,充分证明该方案低成本、高收益、可复用的特性。
MindStudio-Insight:https://gitcode.com/Ascend/msinsight


