最近在做一个小项目,把微调过的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?
全部回复
共 56 条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并发就炸多半是它没限制住批处理上限。
你这情况我前两天刚踩过一模一样的坑,问题大概率不是显存总量不够,而是vLLM默认给每个序列预留的KV cache太大,并发一上来就把剩余空间挤爆了。AWQ应该没问题,但你可以试试把--max-num-seqs显式设成2或3,别依赖默认的批处理逻辑。另外--gpu-memory-utilization 0.9其实还是会给权重和激活留太多余量,不如直接砍到0.85然后配合--swap-space 0跑一下看日志里的KV cache分配情况,我这么调完并发就稳了。
vLLM的批处理没生效大概率是--max-num-seqs没设,默认值可能只有1,并发请求全被卡成串行还占着显存。把--max-num-seqs调到16或32试试,另外--gpu-memory-utilization可以再降一点到0.85,留点余量给碎片化分配,AWQ本身没问题,先别怀疑量化。
碰到过类似的,不过我是7B上两台T4跑的。vLLM的批处理有时候看--max-num-seqs而不是并发数,你试试把这个参数调低到2-3,同时把--max-num-batched-tokens设个2048看看。另外AWQ在A10上反而可能更吃显存,因为反量化有额外开销,换GPTQ或者直接FP16试下,有时候解量化临时buffer就是压垮骆驼的最后一根稻草。
试试把max-num-seqs拉低到1看还崩不崩,大概率是vLLM预分配太激进,跟AWQ关系不大。
遇到过一模一样的坑,vLLM那个批处理看着设了8,但实际要等请求攒够才触发,并发一冲上来KV Cache直接爆了。你可以试试把--max-num-seqs调小到2-3,或者开--enable-prefix-caching,能省不少显存。另外AWQ 4bit按理说应该够,但A10上如果用了--dtype float16而不是auto,量化权重可能会被强制转回fp16,显存反而更大,建议检查下实际加载的精度。
你这情况我太熟了,之前部署7B的时候也卡在OOM上差点通宵。vLLM的批处理其实默认是开启的,但问题往往出在KV Cache预留上,你光调--gpu-memory-utilization没用,得看它实际给KV Cache分了多少,有时候模型权重和激活值算下来,剩余空间根本不够塞满8个并发请求的KV Cache。建议直接开个终端盯一下nvidia-smi,看OOM瞬间显存是不是被缓存占满了,而不是模型本身。另外AWQ虽然省显存,但你要是微调过模型,量化校准可能没跟上,导致某些层精度崩了触发额外显存开销,这个坑我踩过。还有个骚操作,把--max-num-batched-tokens也显式设一下,别只依赖--max-model-len,这两个参数会互相挤占。最后实在不行就把并发降到4,或者干脆用--enable-chunked-prefill试试,把长prompt拆开处理,显存压力会小很多。你现在的日志里有没有什么“GPU memory usage exceeded”之类的具体数字?贴出来可能更好判断。
看到你这个情况我第一反应是vLLM的preemption机制可能没按预期走,3-4个并发就爆显存不太正常。你试试把--max-num-seqs显式设成4或者更小,有时候默认值会跟--max-model-len的计算逻辑打架,导致实际batch里塞了太多序列。另外KV Cache的调优确实不是光靠--gpu-memory-utilization就能解决的,vLLM在长上下文场景下会预分配大量缓存,建议你查一下/tmp或者$VLLM_CACHE里是不是有旧的模型权重缓存文件占用空间,我之前遇到过类似问题就是被这个坑了。AWQ量化本身没问题,但你要确认一下服务器上CUDA版本和vLLM的flash attention后端是不是匹配,A10上如果用了不兼容的kernel,显存碎片化会特别严重。还有个思路是直接抓一下OOM时的nvidia-smi快照,看是模型权重占大头还是KV Cache峰值爆了,这能帮你定位到底是调度问题还是内存管理问题。最后实在不行就开--enable-chunked-prefill试试,虽然会牺牲一点吞吐,但能把显存峰值压下来不少。