最近在搞一个内部工具的对话接口,用VLLM部署了Qwen2.5 7B,单次调用挺流畅的,但并发一上到10个请求左右就开始频繁OOM,直接Kill进程。我看配置里设了max_num_seqs=256,gpu_memory_utilization也调到了0.8,还是顶不住。是不是我模型加载方式不对?还是需要换量化版本?或者得拆成多个副本?求有经验的老哥指点一下,预算有限暂时上不了A100,就一张3090。
VLLM部署Qwen2.5 7B,并发一高就OOM怎么办?
全部回复
共 160 条3090也就24G显存,跑7B全精度本来就很吃紧,max_num_seqs别拉那么高,10并发的话调到32-64试试,prefill和decode阶段显存占用差很多。另外建议直接上AWQ或GPTQ量化,4bit下显存能省一半,vllm对量化支持也成熟,基本无损。还有你gpu_memory_utilization=0.8是不是给KV cache留的空间不够,可以试着降到0.75给模型腾点余量,别让vllm自己爆掉。如果还不行就只能拆两个进程各占一半显存,不过调度会麻烦点。
max_num_seqs调低点试试,256太高了,3090撑不住,先压到32看看。
3090跑7B量化加长上下文容易爆显存,试试awq或gptq,能顶不少并发。
3090显存扛7B并发本来就很紧,max_num_seqs拉到256其实是个坑,显存会按这个预分配,建议先压到32试试,配合gpu_memory_utilization=0.9看OOM还出现不。另外你确认下是不是KV cache吃爆了,可以开--enable-prefix-caching或者把--swap-space调小点。实在不行就上AWQ或GPTQ的4bit量化,画质损失不大但显存能省一半,单卡撑10并发基本够用。如果还卡,拆两个vllm实例各绑4个卡上进程,比一个实例硬扛稳得多。
3090跑7B并发10就炸很正常,max_num_seqs调低点试试,256太高了,先压到64看稳不稳。
3090就24G显存,跑7B满血版并发10个确实太勉强了,max_num_seqs设256反而容易让显存碎片化,试试降到32或64,同时把gpu_memory_utilization调到0.9看看。另外优先上AWQ或GPTQ的4bit量化,显存占用能砍一半,速度损失不大,比拆多副本省心。我之前用类似配置跑14B量化都没这么容易OOM,你查下是不是kv cache没单独设上限,vllm的--kv-cache-dtype和--max-model-len也得一起调。
max_num_seqs设256在3090上有点太激进了,24G显存跑7B本身就不宽裕,建议先压到32或者64试试,OOM很多时候是显存碎片化而不是真不够。另外量化可以试试AWQ或者GPTQ的4bit,显存占用直接砍半,精度损失对这种内部工具影响不大。要是并发还上不去,拆两个副本配合负载均衡可能比硬扛单卡更省心,vLLM本身多实例部署也不算麻烦。
3090跑7B并发10个就OOM,这事儿我太熟了,max_num_seqs=256在单卡上其实是个陷阱,它代表的是“理论上限”而不是“安全值”,VLLM会按这个值预分配KV cache,你设这么高等于把显存全押在batch上,但Qwen2.5 7B的attention头数多,实际每个序列的KV开销比想象中大不少。建议先把max_num_seqs砍到32甚至16试试,同时把gpu_memory_utilization降到0.7,留出一点余量给碎片和激活值,别信那个0.8,HBM分配不是线性的。另外我猜你没开--enable-chunked-prefill,这个对长prompt并发特别关键,不开的话每个请求的prefill阶段会一次性吃满显存,开了能切成小块调度,实测能顶住3倍并发。量化的话,AWQ 4bit在这个卡上性价比最高,但注意别用GPTQ,VLLM对AWQ的kernel优化更成熟,掉点也少。要是还不行,就干脆--max-model-len砍到4096,内部工具对话用不着8192,这一下能省一半KV cache。最后提醒一句,3090的24G其实很尴尬,真要稳定20并发,还是得考虑两张卡tensor parallel,但既然预算有限,先把上面几个参数调了,大概率能救回来。
3090跑7B本来显存就吃紧,你max_num_seqs开到256其实是个坑,vllm的调度器会按这个预分配KV cache,并发一高直接撑爆。建议先压到32甚至16试试,配合gpu_memory_utilization调到0.9,很多情况下瓶颈根本不是模型权重,而是KV cache的预留策略。
另外你确认一下是不是用的AWQ/GPTQ量化版?fp16的7B光权重就占14G,3090剩不下多少给推理。如果没量化,赶紧换个4bit的,效果基本不掉,显存占用能砍一半,并发能力直接翻倍不止。还有个小技巧,把--max-model-len调低,比如4096或者2048,如果你实际输入输出没这么长,能省出大量显存给并发用。
至于拆多副本,同一张卡上跑多个vllm实例反而会互相争显存,不如单实例调优。真要拆就得上多卡或者换卡,预算有限的话建议先试量化+调参,大概率能解决。另外检查下是不是有内存泄漏,长时间跑完看显存是否回落,不行就定时重启下服务。
max_num_seqs调低点试试,256太高了,3090上20左右就够,再配awq量化稳很多。
3090上跑7B还要撑10并发确实有点为难它,max_num_seqs=256这个值基本形同虚设,显存根本吃不下。建议先把并发压到4-6试试,或者用AWQ量化版,显存占用能砍掉快一半,实测吞吐反而更高。另外检查下vLLM的block大小,默认16可能太激进,调成8能省不少缓存。
max_num_seqs调太高了,3090跑7B并发10就OOM正常,改成32试试,再不行上AWQ量化。
试试把max_num_seqs降到64,加--swap-space 8,3090显存就这么点,量化加多副本更实际。
3090上跑7B本来显存就紧,max_num_seqs=256这个值说实话有点激进,实际并发10路的时候prefill和decode争显存很容易爆,建议先压到32试试。另外gpu_memory_utilization调到0.8其实给KV cache留的空间不够,7B的fp16权重就占14G左右,3090才24G,你算算剩下的。量化的话AWQ或GPTQ的4bit能省一半权重显存,但vllm对量化版本的支持有时候会有坑,得看下你用的版本兼容性。还有个思路是拆成两个副本各占一半显存,配合负载均衡,但单卡多实例调度开销也得考虑。建议先把max_num_seqs调小,同时把--swap-space开起来,实在不行再上量化。
3090跑7B并发10确实难顶,试试awq量化加max_num_seqs调到64,显存预留别超0.7。
max_num_seqs设这么高反而容易爆,先砍到32看下,再不行就换4bit量化。
3090跑7B还开max_num_seqs=256,这参数给A100都嫌激进,vLLM的调度器是按最大序列数预分配显存的,你设这么高等于把KV cache撑爆了。我建议先把max_num_seqs砍到32甚至16,同时把gpu_memory_utilization降到0.7以下,给torch和CUDA context留点缓冲,不然并发一高显存碎片化直接OOM。另外检查下是不是用了默认的continuous batching策略,换成preemption模式(比如swap)能让显存不够时自动溢出到CPU,虽然慢点但至少不kill进程。量化版本确实能救急,AWQ或GPTQ的4bit大概能把KV cache省一半,但7B在3090上跑4bit精度损失还能接受,内部工具够用。单副本拆多卡没必要,3090就24G,拆了反而增加通信开销,不如直接上量化加低并发,实测能顶住20个请求。最后看下vLLM版本,0.6.x之后有paged attention优化,老版本内存管理差很多,升级一下可能就解决了。
3090跑7B并发10个就OOM,这情况太典型了,问题多半不在max_num_seqs,而是KV cache和显存碎片打架。你gpu_memory_utilization设0.8,但VLLM默认会给每个序列预留最大长度对应的KV cache,如果输入输出长度设得长,比如4K甚至8K,那10个请求的显存占用直接爆炸。建议先把max_model_len砍到2048试试,同时把max_num_seqs降到32左右,别贪多。
另外这卡是24G显存对吧,跑7B其实量化版挺划算的,AWQ或者GPTQ的4bit能把模型压到5G上下,剩下的空间全给KV cache,并发翻倍都不慌。不过纯FP16的话,7B光权重就14G,再算上激活和KV,0.8利用率确实有点悬,你可以用nvidia-smi盯着看OOM前显存到底涨到哪一步。
还有个偏方是开VLLM的--enable-prefix-caching,如果内部工具请求里有固定系统提示词,缓存命中后能省不少计算和显存。至于拆多副本,3090单卡折腾多进程反而容易触发PCIe带宽瓶颈,不如先试试调整--swap-space,把部分KV换到内存,虽然慢点但至少不崩。
最后问一下,你用的VLLM版本是0.6还是0.7?新版本对连续批处理和显存碎片优化差别挺大的,有次我升级完同样配置OOM直接消失。要是还不行,就看看是不是输入输出长度分布太极端,偶尔有个超长请求把显存峰值拉爆了,那得从业务侧限流。
说实话你这个配置我太熟了,之前用4090跑Qwen2.5 7B也踩过一模一样的坑。max_num_seqs=256在3090上基本是个摆设,因为显存带宽和容量根本喂不动那么多并发序列,实际跑起来可能十几个请求就把KV cache撑爆了。我建议你先别急着上量化,把max_num_seqs降到32或者16试试,同时把gpu_memory_utilization调到0.9,给KV cache留更多空间,VLLM对连续批处理的调度很敏感,这个参数往往比量化影响更大。另外注意一下你的prompt长度,7B模型如果输入输出都长,每个序列占的显存会指数级上涨,10个并发炸掉很正常,可以试试把max_model_len设小一点,比如4096,内部工具够用了。如果还不行,再考虑AWQ或者GPTQ的4bit量化,3090上跑4bit的7B能用一半显存换来接近原版的精度,但注意量化后要重新测一下并发上限,别直接照搬原版的配置。拆多个副本其实不太建议,VLLM单卡多副本会互相抢占显存,调度开销反而可能加剧OOM,除非你把请求分发到不同端口。最后给你个土办法,在代码里加个信号量限制同时处理的请求数,比如最多6个,超过就排队,比让VLLM自己崩溃强多了。
3090上跑7B还开256的max_num_seqs,这配置确实有点激进了,显存主要被KV cache吃掉了,并发一高直接爆很正常。可以试试把max_num_seqs降到32或者64,然后配合--enable-chunked-prefill,调度压力会小很多。另外量化建议直接上AWQ或者GPTQ的4bit版本,显存占用能砍一半,速度损失体感不大,但并发能力明显提升。我之前也是这卡,跑Qwen2.5 7B,量化后并发20个都没再OOM过,你可以先试这个组合。
3090就24G显存,跑7B还得塞KV cache,max_num_seqs=256太激进了,实际并发10个就爆挺正常。先把这个值砍到32或者64试试,配合gpu_memory_utilization降到0.6左右,给推理留点余量。另外Qwen2.5 7B有AWQ量化版,显存占用能少一半,3090上跑int4基本无感,比拆多副本省事多了。我之前用类似配置,峰值并发能撑到20+,你可以先调这两个参数看效果。
要是还不行,就得考虑把vllm的--enable-prefix-caching打开,长对话场景能省不少显存。你那个对话接口如果是多轮,前缀复用很关键,否则每次请求都重新算一遍KV cache,3090再大也扛不住。还有个小坑,确认下是不是用了flash-attention,vllm默认对3090是支持的,但有时候编译版本不对会退化到慢速模式,显存占用直接翻倍。
3090就16G显存,跑7B还得塞KV cache,max_num_seqs=256这个数设得太激进了,实际并发根本吃不满。试试把max_num_seqs砍到32或者16,gpu_memory_utilization调到0.9,OOM大概率能缓解。另外你这场景是内部工具的话,干脆用AWQ或者GPTQ量化版,4bit精度损失基本感知不到,显存占用直接砍一半。实在不行就起两个vllm实例,每个绑一半显存,用负载均衡分流,比换卡省钱多了。
3090跑7B并发10个就OOM,这情况我太熟了。max_num_seqs=256这个值其实是个上限,不是说你设了它就会占满,但vllm的显存预分配策略是按你设的max_num_seqs来预留KV cache的,7B模型在3090上即便gpu_memory_utilization=0.8,留给KV cache的空间也就15G左右,256个seq的KV cache算下来轻轻松松就爆了。你可以先试试把max_num_seqs降到32或者64,同时把--max-model-len也调低点,比如4096或2048,这样每个seq占用的KV cache会小很多,并发10个应该能稳住。要是还不行,那就上AWQ或GPTQ的4bit量化版,3090跑4bit的7B大概显存占用能砍到6-7G,KV cache能多出不少余量,而且速度损失不大。另外别急着拆多副本,3090单卡拆两个反而会互相抢显存,不如单卡把batch size控制住。最后检查下是不是模型加载时用了--dtype auto,有时候默认fp16会额外吃显存,换成--dtype bfloat16能省一点。我这边之前用4090跑7B也是这么调过来的,先压seq数再考虑量化,基本能解决。