“把几乎全部请求都交给GPU”——这是第一轮请求路由基准测试给出的答案:最快的策略把12个请求里的11个分给了GPU。但作者没有停在这里,他追问了一个更有用的问题:选择性把部分请求卸载到CPU,能不能比全部压在GPU上更快完成?
![]()
这个引擎叫mini-vllm-rs,是作者用Rust在Candle之上为macOS构建的单节点LLM推理引擎,可以让CPU与Metal GPU两个后端并发运行,并在两者之间按整条请求进行路由。实验用的是量化版Qwen2.5 0.5B模型、F32激活,跑在Apple M2上。
先看两个后端的差距在哪
对一个512输入、128输出的请求,隔离环境下的后端剖析显示:CPU最大的劣势出现在长且未命中缓存的提示词预填充(prefill)阶段。即便GPU手上已有活,为了避开CPU预填充,等GPU也可能是划算的。而如果前缀已经预热,这部分开销大部分会消失,剩下的只是解码(decode)阶段较小的劣势——这个劣势,GPU的积压任务量有可能把它抵消掉。
两个后端各自拥有调度器和KV缓存,请求一旦选定后端就留在那里。作者向两边的缓存都预置了约512个token的前缀,每个被测请求使用相同的516个token提示词,并精确生成128个token。两边都预热,等于给CPU一个避开昂贵预填充的机会。
对比的两组是:强制全部走GPU,以及混合路由——路由器根据预估的待处理任务和新增任务在CPU与Metal之间选择。两组调度器设置相同,每个后端最多4个活跃请求,请求间隔50毫秒到达、不等待先前响应,每组都从全新服务器和预置缓存开始,各跑3次。
第7个和第8个请求之间发生了什么
路由器的打分把预填充和解码分开计价:剩余预填充token数除以预填充速率,加上剩余解码token预算除以解码速率。总量包含已有工作和新到请求。解码工作用每个已有请求未用完的max_new_tokens预算加新请求的完整预算来近似,因此路由器并不预测实际输出长度或提前停止。速率来自隔离环境的后端剖析,所以这是一个基于工作量的排序,而不是对批处理完成时间的精确预测。
诊断日志把边界画得很清楚。两个候选后端都为这个516 token的提示词报告了496 token的可复用前缀,于是空闲的CPU只需计入20个预估预填充token和128 token的解码预算,得分为20/73 + 128/45 = 3.118秒。
到第7个请求时,GPU已有4个活跃请求和2个排队请求,每个排队提示词同样带着496 token的缓存估计,各剩20个预填充token。算上新请求,GPU的预估预填充工作是2×20 + 20 = 60个token;解码预算为256(排队)+ 496(活跃)+ 128(新到)= 880个token。得分60/2551 + 880/293 = 3.027秒,仍低于CPU。光看GPU槽位被占满,还不足以支持卸载。
约50毫秒后,第8个请求到达路由器。此时第7个请求已加入GPU队列,活跃请求公布的剩余解码预算下降了8个token。算上新请求,GPU的预估预填充变成80个token,合计解码预算为384(排队)+ 488(活跃)+ 128(新到)= 1000个token,得分升到3.444秒,超过了空闲CPU不变的3.118秒,路由器于是选择了CPU。预热前缀让预填充工作量保持很小,累积的解码工作把天平压了过去。
这里还有一段插曲:在帮忙整理早前基准数据时,AI发现了一个记账错误——排队请求丢失了缓存折扣,导致GPU预填充工作量被高估。作者修掉它并重跑了基准,第一次CPU分配从第7个请求挪到了第8个请求,这里的容量结果用的是修正后的运行。排队请求现在会保留路由时的缓存估计,尽管缓存驱逐可能让这些估计过期。输出长度估计仍未完成;作为对照,SGLang的调度器用可调的new_token_ratio缩放剩余token预算,来估计运行中请求未来的KV缓存需求,这是一种启发式而非精确的输出长度预测。
实际效果
第8个请求被卸载后,完成得远早于混合批次结束。CPU可以在GPU继续服务其分配请求的同时开始有效工作,整个批次也结束得更早。3次运行的平均完成时间从11.47秒降到10.35秒,降幅9.8%。混合路由在三次运行中分别把0个、1个、6个请求分给CPU。
更长的GPU积压里,收益继续存在。48个请求的批次中,每次运行CPU只分到6个请求,平均完成时间从68.43秒降到60.88秒,聚合输出吞吐提升12.4%。
延迟收益并不均匀。8请求场景下中位数TTFT改善,但p95 TTFT上升了3.5%;48请求的长积压下,中位数和p95 TTFT都改善,中位数和p95端到端延迟也改善。选择性卸载提升了容量,但不保证每一项延迟指标都赢。
下一步的基线检查是GPU并发度扫描,因为这些收益是对着固定的4活跃请求GPU配置测出来的。持续到达和不同的缓存命中率,将进一步检验这个结论能走多远。
这轮实验改变的东西很明确:第一轮基准指出了该往哪看——CPU的劣势在解码阶段远小于预填充阶段;后续实验证明,预热前缀加上GPU积压,可以让选择性CPU卸载变得有用。后端速度本身并不决定放置,路由器还必须把已经排队的工作、以及缓存复用能省掉的预填充算进去。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.