最近在折腾本地部署Qwen2.5 7B(int4量化版),用的vllm框架,服务器是两张RTX 4090(24G),设置了max_num_seqs=64和gpu_memory_utilization=0.9。刚开始跑几个请求还挺正常,但连续处理几十个prompt之后,显存就慢慢涨到46G然后直接OOM了。查了vllm的文档说是有动态显存管理的,但感觉没生效。我试过调低max_num_batched_tokens到2048,也没用。是不是我哪里设置不对?还是7B模型本身在长文本多并发下就是容易爆显存?求大佬们指点一下排查思路或者有没有其他轻量部署方案推荐。
用vllm部署Qwen2.5 7B,显存一直涨到OOM,是代码有问题吗?
全部回复
共 159 条试试把gpu_memory_utilization降到0.8,再开个--enforce-eager参数,能省不少显存。
试试把gpu_memory_utilization调低到0.85,或者限制请求并发数,vllm的显存回收有时确实不灵敏。
说实话这个情况我去年也踩过类似的坑,vllm那个“动态显存管理”其实更多是针对推理时的缓存复用,对量化模型的长文本场景反而容易出问题。感觉你max_num_seqs设到64对7B模型有点太激进了,尤其是int4量化版虽然模型体积小了,但kv cache的显存占用是按序列长度和并发数线性增长的,64个序列同时跑的话每个序列只要超过1k tokens,光cache就能吃掉20多G。我建议你先试试把gpu_memory_utilization降到0.75左右,同时把max_num_seqs砍到16甚至8,看OOM能不能缓解。另外vllm有个隐藏参数enable_prefix_caching建议打开,它对重复前缀的prompt能省不少缓存。如果还是爆的话,不如换成TGI框架或者直接用Transformers+FlashAttention自己写个简单推理脚本,反而更可控。顺便问一下,你那些prompt的平均长度大概多少?如果是长文档处理的话,可能需要考虑用StreamingLLM那种滑动窗口策略。
试试加个--swap-space参数或者调低gpu_memory_utilization,我也踩过这坑。
显存持续上涨到OOM,很可能是vllm的prefix caching和显存碎片导致的,int4量化下动态显存管理对长序列释放不一定及时。可以试试把gpu_memory_utilization降到0.8,再加个--swap-space 16参数允许部分层换到CPU,或者换TGI框架部署,它对显存回收更激进。另外确认下是不是prompt长度不统一,vllm对变长batch的显存预分配容易超支。
调低gpu_memory_utilization到0.8试试,或者换AWQ量化版,vllm对int4支持有时不太稳。
显存持续上涨到OOM确实挺让人头疼的,之前我跑类似模型也遇到过。建议你检查下vllm的--max-model-len有没有设置,默认可能跟模型支持的最大长度有关,长文本并发下累积的缓存会撑爆显存。另外可以试试把gpu_memory_utilization降到0.8左右,给动态管理留点缓冲,或者直接限定max_num_seqs更小比如32,先看单个请求会不会涨。如果还是不行,换ExLlamaV2或者llama.cpp试试,int4下它们的显存控制更激进一些。
这种情况我遇到过,很有可能是vllm在连续请求时没有及时释放历史KV cache,尤其是长文本场景下,显存碎片化累积会导致OOM。可以试试把max_num_batched_tokens再调低到1024,同时设置enable_prefix_caching=True来复用公共前缀的cache。另外检查下vllm版本,0.6.0之后对动态显存管理有优化,升级说不定能解决。如果还不行,可以考虑切到llama.cpp配合llama-server,同样是int4量化,显存占用更可控。
说实话我也遇到过类似的问题,vllm那个动态显存管理在长上下文场景下确实不太靠谱,尤其是Qwen2.5 7B这种模型,即便量化了,kv cache的膨胀速度也很夸张。你设了gpu_memory_utilization=0.9,但vllm会预留一部分给预填充和调度,实际可用显存可能比你以为的少很多。建议你试试把max_num_seqs调低到32甚至16,同时gpu_memory_utilization降到0.8看看,有时留点余量反而能避免触发碎片化OOM。另外检查一下你的prompt是不是特别长,7B模型在4090上跑2048 tokens的并发,双卡分摊后每张卡也扛不住太多请求。如果只是做轻量推理,可以考虑换sglang或者llama.cpp,它们对显存控制更死,不会像vllm那样偷偷预留buffer。或者实在不行就上4bit AWQ量化,配合exllamav2内核,单卡24G跑个4k上下文还是挺稳的。
试试把gpu_memory_utilization降到0.8,再开个--swap-space参数,说不定能缓解。
你这情况我遇到过类似的,vllm的显存管理对量化模型有时确实抽风,尤其连续请求时碎片会累积。建议先把gpu_memory_utilization降到0.7试下,然后检查下是否开了enable_prefix_caching,这个吃显存挺狠的。另外7B int4在双卡上其实可以跑vllm+AWQ,我换成这个之后稳多了,显存基本不抖。
vllm的显存管理确实不是百分百智能,尤其是Qwen2.5这种模型在int4下可能因为attention层计算临时缓存导致峰值显存飙升。你试试把gpu_memory_utilization调到0.75,同时限制一下每个请求的最大生成长度,连续压力测试时搞个冷启动清理缓存的脚本。另外检查下vllm版本,老版本的显存回收机制是有bug的,升级到最新版可能直接解决问题。
试试把gpu_memory_utilization降到0.85,或者关掉prompt caching看看效果。
这情况我也遇到过,本质上是vllm的显存预分配机制在作祟,gpu_memory_utilization设0.9其实已经很高了,但动态释放不一定及时。你可以试试加上--enforce-eager模式,绕过CUDA graph的缓存累积,虽然推理会慢一点,但能阻止显存持续膨胀。另外int4量化版有些算子对vllm兼容性一般,建议切到awq或gptq量化试试,或者先用llama.cpp跑一下看是不是模型本身的问题。
试试把gpu_memory_utilization降到0.8,再加个--enforce-eager参数看看。
试试把gpu_memory_utilization降到0.85,然后关掉动态显存,手动指定max_num_seqs=32。
你这情况我遇到过类似的,其实vllm在高并发长上下文时显存回收确实会滞后,特别是int4量化下显存碎片化容易累积。可以试试把gpu_memory_utilization降到0.8,或者显式设置--swap-space来启用CPU offload,再把max_num_seqs改小到32看看。另外如果对延迟不敏感,用TGI或者ExLlamaV2的量化推理可能更稳定些,对显存控制更保守。
我也是vllm的重度用户,之前部署Qwen2.5 7B(int4)也遇到过类似问题。你设的gpu_memory_utilization=0.9其实有点高了,两张4090总共48G,但vllm的显存管理并不是完全动态的,它会预分配一个固定大小的KV cache池。你连续处理几十个prompt,如果每个prompt的生成长度差异很大,预分配的缓存很容易被占满,然后触发OOM。我建议你把gpu_memory_utilization降到0.8试试,同时max_num_seqs可以改到32,让每个请求留更多余量。另外,你用的是int4量化版对吧?注意Qwen2.5的int4版本如果用了AWQ或GPTQ,vllm对某些量化格式的显存释放可能不如fp16稳定。如果还不行,可以试试给每个请求加个max_tokens限制,比如512,防止个别长文本把池子撑爆。轻量方案的话,考虑用llama.cpp配合KoboldCPP,纯CPU+GPU混合推理,对4090的双卡利用率更可控,但吞吐量会比vllm低一些。
说实话你这配置已经很豪华了,两张4090跑7B的int4按理说应该是轻轻松松的。我怀疑问题可能不是出在显存总量上,而是vllm的显存管理策略跟你的使用场景有点冲突。你设了gpu_memory_utilization=0.9,但vllm默认会预分配一部分显存给KV cache,如果max_num_seqs设得高,同时每个seq的上下文长度又参差不齐,它可能会一次性申请大量显存用于缓存,而实际用到的只是其中一部分,导致剩余可用显存越来越碎片化,最后就算总量没到46G也可能因为分配不到连续块而OOM。
我之前用vllm跑Mistral也遇到过类似情况,后来把gpu_memory_utilization降到0.8,同时把max_num_seqs砍到32,再配合--block-size 8(调小缓存块大小),显存增长就平滑多了。你可以试试看,不过注意block-size太小会影响吞吐,得平衡一下。另外,如果你主要是做长文本推理,可以检查下prompt里是不是有些特别长的上下文没被截断,有时候一条超长请求会一次性吃掉大量缓存。
如果实在调不好,换个方案也行。7B的int4模型用exLlamaV2或者llama.cpp跑效果也挺稳,前者对显存控制更精细,后者甚至能支持CPU+GPU混合推理,爆显存了还能兜底。
我最近也遇到过类似情况,感觉vllm的显存回收有时候确实会滞后,尤其是连续高并发的时候。你试试把gpu_memory_utilization降到0.8或者0.85,给显存留点缓冲空间,另外可以加个--enforce-eager参数禁用CUDA图优化,虽然慢点但能避免显存碎片化。还有就是检查一下prompt长度是不是参差不齐,vllm对动态batch的显存分配有时候会预留过多。如果还不行,换text-generation-webui或者exllamav2跑量化模型可能更稳。