最近在做一个小项目,把微调过的Qwen2.5-7B接到公司内部知识库问答上。本地测试一切正常,但推到服务器上就出问题了——用的是A10(24G显存),模型加载完占18G左右,按理说还有富余。结果只要并发一上来(大概3-4个请求),直接就CUDA OOM。我用的vLLM,加了--max-model-len 4096,并发数设的8,但日志显示实际批处理好像没生效?另外默认的KV Cache是不是没自动调优?试过把--gpu-memory-utilization调到0.9,还是不行。有没有大佬遇到过类似情况,是量化精度选错了(目前用的AWQ),还是并发控制参数根本就没奏效?求指点,孩子快被线上事故逼疯了。
部署Qwen2.5-7B到生产环境,显存明明够却一直OOM?
全部回复
共 49 条vLLM的KV cache不吃满显存就是没生效,试试把gpu-memory-utilization调到0.95,再关掉AWQ换GPTQ看看。
我之前跑Qwen2.5-7B也踩过类似的坑,问题大概率不在量化精度上,AWQ本身吃显存就比GPTQ还稳一点,你那个18G占用其实是模型权重加部分KV cache的混合体,A10的24G看着够,但vLLM的默认paged attention预热时会把剩下显存全拿去建KV cache池,并发一上来每个请求还要额外buffer,OOM就很自然了。你试过gpu-memory-utilization调高反而更糟,因为0.9意味着vLLM会激进地预留18G给模型,剩下的6G根本撑不住多序列的KV cache增长。建议你检查一下vllm启动日志里实际分配的KV cache blocks数量,然后显式用--kv-cache-dtype fp8或者--enable-chunked-prefill,后者能把长prompt拆开处理,大幅降低瞬时峰值。另外并发数8在A10上太乐观了,你那种知识库问答场景,每个请求的输入长度可能都不短,试试把并发降到4,同时把--max-num-seqs调成4,让vLLM别一次性塞太多batch。还有个隐藏问题,你微调后是否有把pad token和eos token正确设置?如果某个请求的input长度超过max-model-len的4096,vLLM会直接拒绝而不是截断,但日志里可能只显示WARNING,你最好抓一下请求长度分布。最后怀疑你本地测试用的是单卡且没有真实并发,而服务器上可能还跑着别的进程占显存,nvidia-smi看一眼是不是真有其他残留程序。
之前跑Qwen2.5-7B也踩过这坑,A10上18G看着够,但vLLM默认会给每个序列预留一大块KV cache,并发一多直接爆。你试试把--max-num-seqs显式设成4,再配--enable-chunked-prefill,我这么调完压测就没再OOM过。另外AWQ这精度没问题,问题大概率在max-model-len和实际输入长度不匹配,你查下是不是请求里带了超长历史记录。
我之前调Qwen系列也遇到过类似坑,表面看显存够用,但vLLM的KV cache是预分配的,不是按需增长,你--max-model-len 4096加上去之后,它默认会按这个长度给每个序列预留空间,并发一多,预留的总量直接把剩余显存吃爆了。你试过调--gpu-memory-utilization到0.9,但问题可能在于这个参数控制的是总显存使用上限,而KV cache的预分配策略没变,所以还是会在高并发时把显存占满。建议你查一下vLLM的--max-num-seqs,把它降到2或3,同时把--max-model-len调小到2048看看,这俩参数是实际控制并发批处理窗口的,不是靠并发数8那个设置。另外AWQ量化在A10上没问题,但量化后的模型如果微调时没对齐校准集,推理时可能产生额外显存碎片,你可以试下换回FP16,看OOM是否消失。还有个偏方,启动时加--disable-log-requests能减少少量内存,但根本还是要把KV cache的预留算明白。你先跑个nvidia-smi看下OOM瞬间显存分配,基本能确认是不是cache预分配的问题。
我之前跑7B也遇到过类似的坑,看着显存够但一并发就炸,大概率不是AWQ的锅,而是vLLM的KV Cache策略问题。你设了max-model-len 4096,但实际prefill阶段会按最大可能长度预分配,而且并发8时每个sequence都占独立缓存,18G是模型权重,剩余6G可能只够2-3个并发序列的KV空间。建议把gpu-memory-utilization调到0.95试试,同时显式设置--max-num-seqs 4,强制限制批处理大小,看日志里实际batch size是不是一直没超过1。另外确认下你的AWQ是不是用的safetensors格式,如果是从GPTQ转换过来的,可能量化参数没对齐导致显存碎片化。还有个冷门技巧,vLLM里--enable-prefix-caching对知识库场景极有效,能省掉大量重复前缀的KV计算,我开了以后并发直接翻倍。如果还不行就换用--kv-cache-dtype fp8(A10支持),能再挤出一部分空间。生产环境建议把tensor-parallel-size设1,避免多卡通信开销反而拖慢。你那边日志里有没有提示“Number of blocks”相关的信息?那个数字能直接看出缓存块够不够。
这问题我踩过类似的坑,A10跑7B理论够但vLLM默认会预分配整卡KVCache,你设了max-model-len但并发上去每个序列的KV还是会动态撑爆。试试把gpu-memory-utilization降到0.7,然后显式加--max-num-seqs 4限死batch,另外AWQ的量化粒度也可能导致显存碎片化,换个GPTQ或FP8对比下。
感觉你八成是撞上vLLM的pre-allocated KV cache坑了,--gpu-memory-utilization 0.9这参数看着是给了90%显存,但实际上它默认会按最大并发数预留KV cache,A10上18G权重加9成显存预留,3-4个请求直接把剩余空间撑爆了。建议试试把--max-num-seqs降到4甚至2,然后开--enable-chunked-prefill,让KV cache按需分配而不是一口气吃满。AWQ在7B上一般没问题,但你可以先关掉量化跑一下原生FP16,排除是量化kernel和vLLM版本兼容性问题——之前我遇到过量化模型在某个vLLM版本下显存计算直接翻倍。另外看一眼vllm serve的启动日志里实际KV cache大小,如果它显示比预期大很多,基本就是预分配策略没调对。
之前跑7B也遇到过类似情况,后来发现是vLLM的KV cache分配策略太激进,你试着把gpu-memory-utilization降到0.8再配个--max-num-seqs 2,把并发请求排个队,比硬扛批处理稳得多。另外AWQ在低并发下没问题,但一旦batch size上来,反量化那部分也会吃显存,建议换GPTQ或者直接FP16试试,虽然显存占用高一点但能避免这种诡异OOM。还有个小坑,微调过的模型如果用了PAD token,vLLM可能没自动处理,导致每批都按最大长度补全,你可以看下日志里实际sequence length是不是都顶到4096了。
检查下vLLM的--max-num-seqs,3-4并发就炸多半是它没限制住批处理上限。