最近在把我们微调过的Qwen2.5-7B部署到内网服务器上,用vLLM跑的,开了gptq量化。理论上7B模型int4量化后显存占用应该在5-6G左右,但实际部署后nvidia-smi一看,单卡A10直接吃了14G,吞吐也只有200 tokens/s不到。我已经设置了max_model_len=4096,也开了continuous batching,但感觉没起到什么作用。怀疑是不是上下文预填充阶段太吃显存,还是量化版本选错了?求有经验的大佬指点一下,或者有没有什么工具能定位显存到底被什么占住了?提前感谢。
部署7B大模型到生产环境,显存占用比预想高很多怎么办?
全部回复
共 90 条显存大头其实在KV cache和预填充,试试用vllm的--kv-cache-dtype和--gpu-memory-utilization调一下。
vLLM的KV cache默认预留很大,试试--gpu-memory-utilization调低,显存占用能砍一半。
显存大头其实在KV cache和激活值,int4只压了权重,建议先关掉gptq用fp16跑下对比看显存差多少。
显存大头在KV cache和预填充,4096长度下7B能吃掉8G多,试试把max_model_len降到2048或开prefix caching。
你算的5-6G应该是纯模型权重,但vLLM跑起来显存大头在KV cache和中间激活值上,尤其prefill阶段会把整个序列的激活都塞进去,4096长度在7B上轻松吃掉2-3G,加上gptq反量化时的临时buffer,14G真不奇怪。我之前也踩过这坑,后来用vllm的--kv-cache-dtype和--gpu-memory-utilization调参,把利用率压到0.85,同时把max_num_seqs调小,显存立刻降了3G多,但代价是并发低了一些。你要真想定位,可以开vLLM的--verbose日志看KV cache分配情况,或者用nvidia-smi dmon实时盯显存曲线,能明显看到prefill峰值和decode稳态的区别。另外确认下你装的vLLM版本,0.4.x和0.5.x的显存管理策略差别挺大,新版本对连续批处理优化好很多,但量化算子有时候会额外申请workspace,你换个AWQ或者GPTQ的校准版本试试可能也有帮助。吞吐200不到确实偏低,但A10本身带宽就那样,7B int4能跑300多就算不错,你检查下是否开了--enable-prefix-caching,对长prompt场景提升很显著。
之前跑7B也踩过这坑,int4理论值跟实际差很多很正常,因为KV cache和CUDA context那部分开销没算进去,A10的14G里光模型权重就占了8G多。建议先用vllm --profile看下显存分配,或者开--gpu-memory-utilization 0.9试试,另外确认下是不是用的GPTQ模型本身没做exl2重打包,有些量化版本在vLLM里会额外膨胀。吞吐200确实低,检查下是不是没开--enable-prefix-caching,还有输入长度是不是普遍很长,预填充阶段会吃掉大量显存和算力。
14G这个数确实不太对劲,我怀疑你看到的可能是vLLM的显存预留机制在作怪,它默认会按照gpu_memory_utilization=0.9去预占显存,A10是24G,预留21G左右,但你实际只用了14G说明还有空间,只是nvidia-smi显示的分配量不代表实际峰值占用。你可以试试启动时加--gpu-memory-utilization 0.6,强制让它少抢一点,然后观察吞吐变化。另外你说的预填充阶段吃显存,这个确实存在,尤其max_model_len=4096时KV cache会按最大长度预分配,哪怕实际请求没到这么长,显存也被锁定了。我建议你先用vllm的--kv-cache-dtype fp8或者--quantization gptq参数确认下量化层真的生效,有时候模型加载时如果没匹配对配置,会退回到fp16推理,那7B模型直接吃掉14G就很正常了。还有个笨办法,写个小脚本用torch.cuda.memory_snapshot()跑一个请求,看每个tensor的显存占用,能直接定位是权重、KV cache还是激活值的问题。之前我部署13B量化模型也遇到过类似情况,最后发现是tokenizer的pad_token没设置好,导致每轮请求都重新分配了不必要的临时buffer,你检查下预处理那边有没有类似问题。
之前遇到过类似情况,大概率是KV cache吃满了,试试把gpu_memory_utilization调低点再配个--enable-chunked-prefill。
先看下vllm的日志里prefill占比,这吞吐量明显是显存碎片化导致batch没跑起来。
vLLM的KV cache默认预留很大,试试设--max-num-seqs和--gpu-memory-utilization,能帮你省出不少显存。
你算没算A10的带宽?7B int4跑200 tokens/s差不多是瓶颈了,想提吞吐得上量化+投机采样。
你这情况我上次也踩过,vLLM的显存大头其实在KV cache和CUDA graph的预留上,尤其max_model_len设了4096,峰值预填充阶段会把整段上下文一次性算完,显存自然飙上去。可以先看看/vllm的日志里KV cache实际分配了多少,或者用nvidia-smi dmon盯一下预填充和decode阶段的显存曲线,大概率是前者吃掉了大半。另外确认下GPTQ的group size是不是128,有些量化版本实际加载时反而会膨胀。真要压显存,试试把gpu_memory_utilization调低到0.7,再开--enable-prefix-caching,能省不少。