最近在跟着教程用VLLM部署Qwen2.5-7B-Instruct做API服务,我显卡是4090 24G。之前用AutoModel直接加载推理,开bf16大概占14G左右,跑得很顺畅。但换成VLLM的LLM(model=path)之后,启动就报CUDA OOM,试了加--gpu-memory-utilization 0.8也没用,看日志好像是把KV cache和权重全塞进去了?不太理解为什么VLLM显存占用反而比原生推理高这么多,是哪里没配对吗?比如需要手动指定max-model-len或者把tensor parallel关掉?求有经验的朋友指点一下,网上搜了一圈都是讲A100的,我这种消费级卡是不是更适合用ollama之类的?
VLLM部署Qwen2.5-7B报错显存不足,但用Transformers却没事?
全部回复
共 10 条把max-model-len调小试试,默认可能按模型最大长度预分配KV cache了,4090吃不住。
试试把max-model-len调小点,vllm默认拉满上下文,KV cache吃显存很凶。
VLLM默认会预分配90%显存做KV cache,你4090 24G的话它上来就吃掉21G多,加上权重自然就爆了。试试--gpu-memory-utilization 0.85配合--max-model-len 4096,别用默认的32k,那个KV cache预留太狠。另外--enforce-eager也能省点,不过会慢一些,先跑起来再说。
vLLM默认会把gpu_memory_utilization按0.9来预分配,24G卡上它一上来就按这个比例把KV cache池子占满,所以启动阶段就容易OOM,跟transformers那种按需分配完全不是一个逻辑。你可以先把max-model-len压到4096甚至2048,再把gpu-memory-utilization降到0.7左右试试,一般就能起来了。另外7B模型单卡没必要开tensor parallel,确认下没多余参数。我之前在3090上也遇到过,调小这两个值就正常了。
这情况挺典型的,VLLM启动时默认会按你给的gpu-memory-utilization去预分配KV cache,0.8在24G上就是19G多,加上7B的bf16权重差不多15G,一上来就爆了。你原生Transformers跑14G是因为它只加载权重加少量激活,KV cache是随生成动态增长的,不会一次性吃满。VLLM为了吞吐会提前把cache block池子建好,所以显得“更费显存”。可以试试把gpu-memory-utilization降到0.6左右,同时显式设max-model-len,比如4096甚至2048,这样KV cache池子会小很多。另外enforce-eager也能省一点,不过会牺牲些速度。4090单卡跑7B其实够用,关键就是别让VLLM默认把剩余显存全吃掉,它那个预分配逻辑对消费卡不太友好。
这个现象其实挺常见的,不是你哪里配错了。vLLM默认会按gpu_memory_utilization把绝大部分显存拿来做KV cache预分配,你给0.8它也会先把这部分池子占住,再加上权重本身,24G确实容易爆。Transformers那边是懒加载KV cache,用到多少占多少,所以看起来省。你可以先试试把max_model_len压到4096甚至2048,KV cache是按这个长度乘以并发数预留的,默认值往往特别大。另外Qwen2.5-7B的权重在vLLM里是14G出头,但加上cuda graph和activation peak,启动阶段很容易顶到20G以上。还有个坑是4090没有NVLink,如果误开了tensor parallel反而更糟,单卡就保持tp=1。建议用gpu_memory_utilization 0.9配合enforce_eager,先确认能起来再逐步调。实在不行换0.6.3以上版本,新版对KV cache的分配策略有优化。
VLLM默认会按gpu-memory-utilization把大部分显存预留给KV cache,0.8在24G上大概吃掉19G,加上权重和激活就爆了。你试试把gpu-memory-utilization降到0.6左右,同时max-model-len设小一点比如4096,这两个参数对显存影响最大。Transformers是动态分配,VLLM是预分配,所以看起来占用高很多,其实预留的那部分不一定真用完。
VLLM默认会把gpu-memory-utilization当成0.9来预分配,你24G卡它一上来就按21G多去规划KV cache,权重加载完剩下的空间不够自然就OOM了。而且它跟Transformers最大的区别是VLLM会预先按max-model-len(默认可能是模型config里的32768)把KV cache的显存池一次划出来,不是按你实际请求长度动态要的。你试试显式加max-model-len=4096或8192,再把gpu-memory-utilization压到0.7左右,通常就能起来了。另外enforce-eager也能省一点,不过会影响吞吐。4090跑7B其实挺宽裕的,问题基本都出在那个默认的KV cache预分配上,不是权重本身。顺便问下你用的vllm版本是哪个,0.6之后对这块的处理好像有调整。
这个思路不错,收藏了。
VLLM那套显存管理跟Transformers完全不是一个思路,它默认会把gpu-memory-utilization乘出来的显存拿去做KV cache池,权重加载完剩下的全预分配掉了,所以你看日志会觉得“怎么全塞进去了”。4090跑7B其实够,但Qwen2.5默认max-model-len可能是32768,KV cache按这个长度预分配就很吓人,你试试显式加max-model-len=8192或者4096,立马能起来。另外bf16下7B权重约15G,VLLM还要留激活和CUDA graph的开销,0.8利用率等于只给19G左右,扣掉权重剩给KV cache的就很少了,启动阶段检查可能直接判不够。tensor parallel单卡不用管,默认就是1,不用关。还有个坑是enforce-eager可以关掉CUDA graph省点显存,消费级卡上挺管用的,可以先加上试试能不能过启动。真不行就把gpu-memory-utilization降到0.7再配小max-model-len,我这边类似配置就是这么跑起来的。