最近在试着把Qwen2.5 32B部署到公司的一台A100(80G)上做推理服务。按照官方文档配了vLLM,结果一加载模型就报OOM,看了下日志说是显存不够分配。我理解32B全精度肯定不行,所以试了AWQ 4bit量化版,但启动时还是卡在显存分配上。有人说是vLLM的KV cache默认开太大了,也有人建议用FlashAttention或者调低max_num_seqs。我这边服务QPS要求不高,主要是想把它先跑起来做内部demo。想问问大家,除了换小模型或者多卡,还有没有其他配置方法能把这个模型塞进单卡?比如调整vLLM的gpu_memory_utilization或者改用动态批处理?先谢谢了!
用vLLM部署Qwen2.5 32B时显存爆炸,求大佬指点优化方向
全部回复
共 139 条调低gpu_memory_utilization到0.85试试,同时把max_num_seqs设成8,应该能跑起来。
看到这个情况我挺有共鸣的,之前我搞Qwen2.5 14B的时候也翻过车。你提到的AWQ 4bit按理说显存应该够,问题很可能出在vLLM默认的显存预留策略上:它会把剩余显存全塞给KV cache,但实际模型权重加上量化后的中间激活值可能就占了50G左右,剩下的30G给KV cache反而会因为碎片化或预留不足报错。建议先把gpu_memory_utilization调到0.7甚至0.6试一下,强制给KV cache留出余量,同时max_num_seqs改成32或更低,我试过从默认256降到16,显存占用能降5-6G。另外FlashAttention确实能省点显存,但主要对长文本场景更有效,短demo可能提升不大。如果还不行,可以试试用vLLM的--swap-space参数把部分KV cache放到CPU内存,不过会牺牲一些速度。其实你QPS不高的话,也可以考虑用TGI或者Transformers+FP16+动态批处理,不用vLLM那套预分配机制,但得牺牲点吞吐。最后提一嘴,检查下CUDA版本和vLLM的兼容性,我之前踩过坑,版本不对会导致显存分配异常。
试试把gpu_memory_utilization降到0.7,再配合flash_attn,我这64G卡就是这么跑起来的。
试过把gpu_memory_utilization调到0.85左右吗?我之前跑13B模型遇到类似问题,调低这个参数加上开启FlashAttention,直接就把显存占用压下来了。你QPS要求不高的话,可以把max_num_seqs设成16甚至更低,这样KV cache占用会小很多。另外AWQ 4bit按理说应该能塞下,可能你vLLM版本太旧了,试试更新到最新版。
调低gpu_memory_utilization到0.85再试,配合关闭多余的KV cache预分配,应该能跑起来。
遇到同样的问题,A100 80G跑32B量化版确实容易卡在显存边界上,尤其vLLM默认的KV cache预留策略比较激进。我建议你试试把gpu_memory_utilization调到0.85甚至0.8,别用默认的0.9,这个参数能强制让vLLM少占点显存给模型权重留空间。另外max_num_seqs直接改成8或者16,对demo来说够用了,能大幅降低KV cache开销。FlashAttention肯定要开的,它在vLLM里叫--enable-flash-attention,能省不少显存。还有个技巧是把--max-model-len改小,比如4096或者2048,如果你们内部demo不要求特别长的上下文,这一步很管用。实在不行可以试试vLLM的--enforce-eager模式,虽然推理慢一点但能绕开CUDA graph的显存预分配。顺便问一下,你AWQ版本用的是AutoAWQ还是GPTQ的量化?不同量化工具对内存占用也有影响。
显存爆炸大概率是KV Cache占太多了,A100 80G跑4bit版32B理论够用,你可以试试把gpu_memory_utilization调到0.85或0.9,然后max_num_seqs设成16或32,别让vLLM默认预分配太多。另外开FlashAttention应该能省点,我这边跑同款模型时还关了连续批处理(disable_continuous_batching=True)才稳进去,QPS低的话影响不大。
我之前也遇到过类似的情况,gpu_memory_utilization这个参数确实管用,我一般直接设到0.85或者0.9,能省出不少显存。另外max_num_seqs调小一点也很关键,比如先设成8或者16试试,反正你QPS不高,影响不大。还有如果你能用上FlashAttention的话,显存占用会更友好一些。先别急着上多卡,先把这几个参数调一调,大概率能跑起来。
看到你描述的情况,我第一反应是gpu_memory_utilization这个参数确实值得调一波。vLLM默认会预留大概90%的显存给模型和KV cache,但32B的AWQ 4bit模型本身也得占16-18G左右,再加上KV cache的预留,80G其实有点紧。你可以试试设成0.8甚至0.75,给系统留点余量,避免分配时直接爆掉。
另外max_num_seqs这个参数也很关键,你QPS不高的话直接拉到1或者2就行,这样KV cache占用的显存会大幅下降。我上次在48G卡上跑13B模型时,靠这两个参数直接从OOM变成稳如狗。
FlashAttention确实能省点显存,但它主要优化的是计算速度和长序列场景,对你这32B模型的内存压力帮助有限。不如试试调整max_model_len,如果你们demo用不到长上下文,比如把4096改成2048,KV cache大小直接减半。
还有个骚操作是vLLM的--enable-prefix-caching,如果你的请求里有很多重复的前缀,它能共享KV cache。不过纯demo场景可能用处不大。
最后提醒一下,AWQ 4bit版本本身已经压缩得很厉害了,如果还爆显存,看看是不是下载的量化版本有问题,比如有些社区版的AWQ权重可能会额外占用内存。去官方ModelScope或HuggingFace重新拉一份权重试试。
试过把gpu_memory_utilization调到0.85甚至0.8没?你那个AWQ 4bit按理说显存应该够的,主要卡点可能是vLLM默认的KV cache预分配太大。可以把max_num_seqs设成16或者8,再配合--max-model-len 4096限制下上下文长度,应该能塞进去。另外注意下vLLM版本,之前有bug会导致显存泄漏,升级到0.6.3以上试试。
调低gpu_memory_utilization到0.85,再把max_num_seqs设成8,我这样跑过32B AWQ没爆。
试过把gpu_memory_utilization调到0.85甚至0.8吗?我跑同尺寸模型时发现默认0.9太激进,改低后立竿见影。另外max_num_seqs先设成1或者2看看,demo阶段没必要开并行。如果还不行,可以试试把kv cache的预留比例再压一压,vLLM的--kv-cache-dtype fp8也能省不少显存。不过你用的AWQ版本确定是vLLM原生支持的吗?有些第三方量化格式可能不兼容导致额外开销。
看到你提到用AWQ 4bit还爆显存,我猜可能不是模型权重的问题,因为4bit 32B大概就16-18G,剩下60G给KV cache和overhead按理说够的。vLLM默认的gpu_memory_utilization是0.9,但A100 80G实际可用的显存可能因为驱动或cuda版本有点缩水,我一般会先设到0.8试试,然后慢慢往上调。另一个容易忽略的点是max_num_seqs,demo场景下你设成1或者2就够了,默认的256真的会瞬间吃掉几十G给KV cache。还有你可以试试在启动时加上--enforce-eager,跳过图编译阶段的显存预分配,虽然推理速度会慢一点,但能省下不少临时显存。FlashAttention肯定要开的,vLLM现在默认就支持,但如果你用的版本比较旧,手动指定一下--kv-cache-dtype fp8_e5m2也能压缩cache大小。最后检查一下你用的AWQ模型是不是真的做了4bit量化,有时候huggingface上有些模型名字带AWQ但实际没转成功,可以用transformers加载看看权重类型。要是这些都不行,我还有个歪招:把max_model_len设成4096甚至2048,短文本demo完全够用,能砍掉大半KV cache占用。
我也遇到过类似问题,当时把gpu_memory_utilization调到0.85左右就解决了,默认0.9确实容易爆。另外max_num_seqs设成16甚至8对demo影响不大,但能省不少显存。如果你用AWQ的话,记得确认下vLLM版本是不是支持最新量化格式,我上次就是版本不匹配导致加载异常。
调低gpu_memory_utilization到0.85,配合flash-attention,我这32B单卡80G就能启动。
这问题我上周刚折腾过,A100 80G跑32B量化版按理说空间是够的,大概率是vLLM默认把KV cache预分配得太狠了。你可以试试把gpu_memory_utilization调到0.85甚至0.8,给模型权重和临时buffer留点余量,别让vLLM一上来就把显存吃满。另外max_num_seqs别用默认的256,改成32或者16试试,这个参数直接影响KV cache的总大小,对demo场景完全够用。如果你用的是AWQ版本,记得在vLLM里指定quantization=awq,有时候没显式声明会走回全精度加载。还有个小技巧,启动时加个--enforce-eager能跳过图编译阶段,虽然推理会慢一点但内存占用能降不少。要是还不行,可以检查下vLLM版本,我换到0.5.3后显存分配比之前版本合理多了。
试试把gpu_memory_utilization调到0.85,再配合动态批处理,应该能塞进去。
试试把gpu_memory_utilization调到0.85以下,同时限制max_num_seqs为8,应该能稳住。
同款问题,我之前部署Qwen2.5 32B AWQ时也踩过这个坑。建议你把gpu_memory_utilization调到0.85左右,同时把max_num_seqs设小一点,比如8或16,这样能省不少显存。另外如果QPS要求不高,可以试试把KV cache的prefill分配比例调低,vLLM官方文档里有相关参数。我这么调完后A100 80G单卡勉强能跑起来,虽然并发低但demo完全够用。
试试把gpu_memory_utilization调到0.85,同时限制max_num_seqs到8,应该能塞进去。