vLLM多实例共享GPU的启动内存竞态:Cisco DevNet工程师解释为何两个标志缺一不可
Cisco DevNet平台工程团队在将三个vLLM推理实例部署到同一张NVIDIA A10G上时,遇到了并发启动的内存竞态问题。他们解释了vLLM默认按启动时可见空闲内存分配KV缓存的机制如何导致多实例互相超卖,以及为什么仅用--kv-cache-memory固定缓存大小仍不够——还必须同时降低--gpu-memory-utilization目标,否则后续实例会因启动检查失败而无法上线。
时间切片(time-slicing)把GPU的计算时间分给多个实例,但不分割显存。Cisco DevNet平台工程团队在AWS g5.2xlarge实例上配置了每张NVIDIA A10G(约23 GiB显存)运行三个时间切片副本,用于其GPU学习实验室。这意味着三个学习者共享同一个显存池,彼此之间没有硬件隔离边界。A10G不支持MIG,所以无法做硬件级分区。
问题出在vLLM的启动逻辑上。每个vLLM实例在启动时,会根据当时看到的空闲显存来决定自己的KV缓存大小。当三个实例几乎同时启动时,每一个都认为自己独占大部分显存,各自申请一大块缓存——结果就是超卖。通常只有第一个实例能成功启动,其余两个报错:"No available memory for the cache blocks"。vLLM社区issue #10643记录了这个现象,但并未给出完整的多实例共存方案。
Cisco团队的修复需要两个标志配合,因为vLLM在启动时做了两个独立的内存决策。第一个是--kv-cache-memory 3120851354,把每个实例的KV缓存固定为2.91 GiB,不再从空闲内存中动态测量。没有了测量,就没有了竞态——三个实例不再争抢同一块尚未被占用的空间。
但仅固定KV缓存还不够。vLLM在启动时还有第二道检查:它会确认当前空闲显存是否覆盖自己设定的利用率目标(默认90%)。即使KV缓存已经固定,这道检查依然存在。以92%目标为例,当第一个实例已经占用显存后,第二个实例启动时发现空闲显存(17.96/22.06 GiB)低于所需(20.29 GiB),直接失败。
第二个标志--gpu-memory-utilization 0.30解决的就是这道检查。将利用率目标降到30%,意味着每个实例只需确认空闲显存覆盖约6.6 GiB即可启动。当三个实例的KV缓存合计约8.7 GiB加上模型权重后,剩余显存仍满足30%目标,所以后启动的实例能通过检查,与已驻留的同伴共存。
两个标志各自消除一个独立的失败路径:--kv-cache-memory消除分配竞态,--gpu-memory-utilization 0.30消除启动检查失败。缺少任何一个,三实例方案都无法稳定运行。配置完成后,三个vLLM引擎同时启动并完整跑通实验流程。
这一机制的适用范围不限于Cisco的学习实验室。任何在同一张GPU上并发启动多个vLLM实例的场景——多租户推理服务、CI流水线中的并行评估、开发环境共享——都会遇到同样的竞态。具体数值需要根据GPU显存总量、实例数量和模型大小重新计算,但"固定缓存消除竞态、降低利用率目标通过启动检查"这两步的逻辑是通用的。