最近在用vLLM部署Qwen2.5-7B-Instruct,显存是24G的4090。单卡部署,开了--max-model-len 8192,--gpu-memory-utilization 0.9,平时单请求没问题,延迟30ms左右。但一上并发(比如20个请求同时进来),显存直接飙到23.5G然后OOM,进程崩了。
vLLM部署Qwen2.5-7B,并发一高就OOM,是我显存分配姿势不对吗?
全部回复
共 74 条这配置单请求30ms挺正常的,但并发20个直接OOM基本不是显存分配姿势问题,是KV cache的预分配没跟上。你试试把--max-num-seqs调小点,比如8或者12,同时确认下--max-model-len是不是真需要8192,7B模型跑8192上下文本身KV cache就吃不少。另外vLLM的--gpu-memory-utilization是指峰值占用,不代表它不会临时再申请,我上次也遇到类似情况,后来发现是并发请求的序列长度波动太大,峰值超出预留了。建议开个--enable-prefix-caching或者限制下最大输入长度,应该能缓解。
你这配置单看没啥毛病,但20并发对7B来说KV cache膨胀得很快,8K长度下每个请求的显存占用比想象中高不少。建议把gpu-memory-utilization降到0.85留点余量,或者直接加--enforce-eager把图模式关了试试,有时候能省下不少碎片显存。另外可以看看是不是max-num-seqs没设,默认值可能偏大,手动限个8-12会稳很多。我之前跑同模型也踩过这坑,最后是砍了并发上限才稳住的。
24G跑7B按理说挺宽裕的,但你这OOM八成是max-model-len和并发请求的KV cache叠加导致的。试试把--max-model-len降到4096,或者用--enable-prefix-caching看看,我这边之前跑13B也遇到过类似情况,后来发现是prefill阶段显存峰值被顶爆了。另外可以加个--max-num-seqs限制一下同时处理的序列数,vLLM默认会很激进地塞请求,20并发全挤进来单卡确实容易炸。最后建议开个--swap-space给CPUoffload留点缓冲,虽然慢点但至少不崩。
这问题我也踩过坑,24G跑7B看着挺宽裕,但并发一上来KV cache的分配跟你预期的完全不是一回事。你试试把--max-num-seqs调小一点,比如8或者12,vLLM默认会按最大并发预留显存,20个请求全塞进去肯定爆。另外--gpu-memory-utilization 0.9其实留的余量不够,降到0.85再配合--max-num-seqs,应该能稳很多。我之前这样调完,同样负载下显存峰值能压到20G以内。
20并发直接崩?试试把max-num-seqs调小点,或者开个prefix caching,能省不少显存。
看到这个我第一反应是你把--max-model-len设到8192其实挺激进的,Qwen2.5-7B的KV cache在长上下文下占得比想象中多,20并发等于瞬间要维护20份独立的长序列缓存,显存肯定扛不住。我之前用8B模型跑类似并发,发现vLLM的prefill阶段和decode阶段显存分配策略不一样,你看到的30ms单请求延迟可能掩盖了峰值内存波动,建议你试试把max-model-len降到4096,或者干脆用--enforce-eager模式把CUDA graph关掉,有时候能省出几个G来。另外你确认过--max-num-seqs这个参数吗?默认值好像会随着并发自动调,如果没限制的话vLLM会尝试把20个请求全部塞进显存,而不是排队,这时候即使gpu-memory-utilization设0.9也可能因为KV cache预留不足而OOM。我自己的经验是24G卡跑7B模型,并发想稳到20,得把utilization降到0.75左右,然后配合--max-num-seqs 8,让多余的请求在CPU侧排队,虽然延迟会高点但至少不崩。还有个细节,你有没有看vLLM的日志里peak memory和KV cache size的具体数字?我怀疑你实际KV cache预留远大于理论值,因为没开--kv-cache-dtype fp8,默认fp16在长序列下非常浪费。最后问下,你用的是vLLM哪个版本?0.6.x和0.7.x在显存管理上差挺多的,我之前升级到最新版之后同样配置OOM频率低了不少。
这个参数组合其实挺典型的,问题大概率出在--gpu-memory-utilization 0.9上,vLLM会预先把KV cache占满,并发一来请求排队直接撑爆。可以试试把利用率降到0.7左右,同时把--max-num-seqs限制到8或16,让请求排队而不是硬挤。另外如果业务允许,开一下--enable-chunked-prefill也能缓解峰值显存压力,我这边实测同样场景能稳不少。
20并发就OOM确实不太像显存分配的问题,更像是vLLM的KV cache预留机制在跟你抢空间。你设了0.9的利用率,但Qwen2.5-7B的KV cache是按最大序列长度动态扩容的,8192长度下每个请求的KV cache峰值会远高于你单请求测试时的实际占用,20个并发瞬间就把剩余显存吃满了。我之前用A6000 48G跑类似模型也踩过坑,后来把max-model-len降到4096,同时给gpu-memory-utilization留到0.85才稳。不过你延迟才30ms,说明模型本身跑得挺快,瓶颈明显在KV cache的预留上。可以试试加--max-num-seqs参数限制同时处理的序列数,比如设成8,让vLLM自己排队,或者干脆关掉continuous batching的某些特性看能不能缓解。另外确认下你用的vLLM版本,0.4.x和0.5.x的显存管理策略差挺多的,新版对低并发场景优化更好。还有个思路是开启--swap-space,把部分KV cache交换到CPU内存,虽然会慢些但至少不会崩。你这种情况我觉得先看下vLLM启动时的日志,它会打印预估的KV cache大小,算一下20并发是否已经超出物理显存余量,如果超了就得从序列长度或者并发数下手,单纯调利用率是治标不治本。
看到这个情况我第一反应是max-model-len设得有点激进了,8K上下文对7B模型来说KV cache占用非常可观,20并发等于瞬间要准备20份完整的KV cache。你可以把max-model-len降到4K试试,或者直接看下vLLM日志里KV cache的预留大小,我怀疑你实际可用显存被这部分吃掉了大半。另外--gpu-memory-utilization 0.9这个值虽然给了90%额度,但vLLM在并发时会动态分配显存池,如果预分配不足就容易触发OOM,不如试试调成0.95并加上--enforce-eager关闭图模式,能省一部分显存。还有个细节是Qwen2.5的模型权重本身有FP16和FP8两种格式,如果你用的是原生FP16加载,7B权重大概占用14G,剩下10G左右其实很紧张。我之前拿同样配置跑过类似模型,最后是开了--max-num-seqs 8限制同时处理的序列数才稳住,虽然吞吐会降但至少不崩。你那边有没有开--use-v2-block-manager?这个选项对显存碎片化有一定帮助,但也会增加内存开销,属于取舍问题。最后建议你看下OOM前nvidia-smi的输出,确认是纯显存爆了还是cuda context分配失败,有时候是vLLM内部的内存池和PyTorch的caching allocator冲突导致的假OOM。
试试把max-num-seqs调小点,默认256太高了,20并发根本用不上那么多。
20并发对7B来说挺正常的,试试把max-num-seqs调低点,或者开prefix-caching能省不少显存。
这配置并发20爆显存不冤,7B模型KV cache占大头,建议把gpu-memory-utilization降到0.8再配合max-num-seqs限制下。
OOM基本都是KV cache和并发请求数不对等导致的,你只调了max-model-len但没限制max-num-seqs,20并发全挤进来时vLLM会按峰值预分配显存。试试把max-num-seqs设成8或12,再配个max-num-batched-tokens限制单批总量,应该能压住。另外24G跑7B其实余量不大,0.9的utilization有点激进,可以降到0.85留点buffer,顺便看看是不是paged attention没生效——如果用的老版本vLLM,建议升到0.6.x以上。
试试调低gpu-memory-utilization到0.85,再开enable-chunked-prefill,并发20个8k上下文太吃显存了。
试试把gpu-memory-utilization降到0.85,并发20个请求KV cache涨得比想象中快,留点余量给碎片。