最近在折腾本地部署Qwen2.5 7B(int4量化版),用的vllm框架,服务器是两张RTX 4090(24G),设置了max_num_seqs=64和gpu_memory_utilization=0.9。刚开始跑几个请求还挺正常,但连续处理几十个prompt之后,显存就慢慢涨到46G然后直接OOM了。查了vllm的文档说是有动态显存管理的,但感觉没生效。我试过调低max_num_batched_tokens到2048,也没用。是不是我哪里设置不对?还是7B模型本身在长文本多并发下就是容易爆显存?求大佬们指点一下排查思路或者有没有其他轻量部署方案推荐。
用vllm部署Qwen2.5 7B,显存一直涨到OOM,是代码有问题吗?
全部回复
共 168 条vllm的动态显存管理其实主要针对KV cache做分页,但有个坑是如果请求的prompt长度差异特别大,block碎片化会很严重,尤其你max_num_seqs开到64,长尾请求一多,预留的block回收不及时就会一路涨。我之前用A100跑Qwen2.5 7B int4也遇到过类似情况,后来把enable_prefix_caching关了反而稳了不少,那个功能在混合长度请求下容易吃显存。你可以先试试gpu_memory_utilization降到0.85,再配合max_model_len设个合理上限,别让它默认吃满模型支持的32k。另外两张4090是走tensor parallel还是各跑各的?如果是TP=2,通信缓冲也会占一部分,OOM不一定全是KV cache的锅。排查的话建议开VLLM_LOGGING_LEVEL=DEBUG看每步的block使用率,或者直接上prometheus抓gpu_cache_usage_perc这个指标,比瞎调参数有用。真要轻量方案,7B int4这种规模其实用llama.cpp的server模式更省心,并发不高的话显存能压到8G以内,就是吞吐比vllm差一截。
我之前也碰到过类似情况,后来发现是vllm的block管理在长prompt混短prompt时碎片化比较严重,显存看着就像只涨不降。你可以试试开enforce_eager或者把swap_space调大点,让KV cache能换出去。另外两张4090跑int4的7B按理说绰绰有余,gpu_memory_utilization=0.9其实有点激进,降到0.85反而更稳。如果还不行就换个思路,用SGLang或者llama.cpp的server模式,并发不高的话显存控制比vllm温和不少。
int4量化加vllm这个组合我也踩过坑,显存缓慢上涨大概率不是代码问题,而是KV cache碎片化加上prefix caching没清干净。你可以先试试把enable_prefix_caching关掉,再把max_num_seqs降到16看看曲线还涨不涨。另外两张4090之间如果没有NVLink,张量并行通信开销也会让调度变慢,间接把显存拖爆。
你gpu_memory_utilization设0.9其实挺激进的,两张卡各占90%本来就容易一叠加就崩。我之前跑7B int4也遇到过类似情况,后来把max_num_seqs降到32、gpu_memory_utilization调到0.85就稳多了。vllm那个动态管理主要管KV cache,长文本多并发下cache膨胀很快,不是真的能无限回收。建议你先把并发压下来试试,另外看看是不是有请求一直没释放导致cache越堆越多。
我之前也遇到过类似问题,后来换了方案。
有没有更详细的教程推荐?
有没有更详细的教程推荐?
你观察到的显存缓慢上涨更像是请求结束后KV cache没及时释放,vllm的gpu_memory_utilization只是预分配上限,不代表运行中不会继续占。可以先用nvidia-smi盯着跑,看是step级别涨还是请求间累积,再开--enable-prefix-caching试试,长prompt复用能省不少。另外int4量化在4090上要确认kernel走的是不是marlin,有些量化格式会额外吃显存。两张卡如果没开tensor-parallel,默认单卡扛全部KV,46G爆掉就不奇怪了。