刚接触大模型部署,用的两张4090(24G),准备跑Qwen2.5-7B做API服务。看文档说7B模型int8量化大概8G显存,加上KV cache预留几G应该够。但实际用vLLM启动,--gpu-memory-utilization设成0.9,单卡直接吃了22G+,而且第二张卡完全没利用起来(我明明设了tensor-parallel-size=2)。另外推理速度也只有20 tokens/s左右,看别人的benchmark能到40+。想问问是我参数设置的问题吗?还是说KV cache默认开太大了?另外,vLLM和SGLang在长上下文场景下哪个更稳一点?有点迷茫,求指点。
vLLM部署Qwen2.5-7B,显存占用比预期高很多,正常吗?
全部回复
共 66 条显存占用高大概率是vLLM预分配了整卡显存,TP=2没生效可能和模型格式有关,试试加--enforce-eager。
实不相瞒我前几天刚踩过类似的坑,你这显存占用大概率是vLLM默认给每个request预留了很大的KV cache空间,而且7B模型就算int8实际权重也得9-10G,再加上CUDA graph和碎片,单卡22G真不算离谱。第二卡没用起来的话,检查下启动命令里有没有加--enforce-eager,还有环境变量CUDA_VISIBLE_DEVICES是不是只看到了单卡。速度20 tokens/s确实偏低,但tensor parallel在4090这种卡上因为NVLink带宽不够,有时候反而会拖慢,你可以试试单卡跑对比下。长上下文我体感SGLang在显存控制和调度上更稳一点,但vLLM生态成熟,如果你主要做短对话其实差别不大。
你这个问题我当初也踩过,先说结论:显存占用高大概率是正常的。vLLM默认会预分配KV cache,而且你设了0.9的利用率,它基本会把能用的显存都吃满,22G+不算离谱。真正的问题在tensor-parallel-size=2没生效——你得确认模型权重路径下有没有分布式的索引文件,或者启动日志里有没有报“rank”相关的警告,很多时候是两张卡之间通信没建立起来,导致第二张卡空转。另外20 tokens/s这个速度,如果是没开continuous batching且并发低,其实也说得过去,benchmark那种40+通常是高并发+prefill和decode分离优化过的结果,你可以试试加--max-num-seqs和--enable-prefix-caching。至于SGLang和vLLM,长上下文下SGLang的radix attention确实更省显存,但vLLM胜在生态稳,真要选我建议你先拿自己数据跑个压力测试,别光看benchmark。最后检查一下CUDA_VISIBLE_DEVICES是不是只设了一张卡,这个坑我遇到过两次。
22G是预先把权重和KV cache全塞进去了,TP=2要看下模型是否真的支持,速度瓶颈大概率在数据并行没生效。
你这情况挺典型的,vLLM默认会把gpu-memory-utilization当成显存池上限来预分配,不是按实际用量慢慢涨,所以你设0.9它两张卡各吃22G左右是符合预期的,并不是真的用满了。第二张卡没被利用,多半是tensor-parallel-size没生效,检查一下启动日志里有没有TP=2的字样,有些版本对--tensor-parallel-size的位置或者和环境变量冲突会静默忽略。速度只有20 tokens/s,如果batch size是1,那TP=2反而可能因为通信开销拖慢,单卡跑7B int8在4090上本来就能到40+,你可以先试试TP=1对比一下。KV cache那块,vLLM是按block预分配的,gpu-memory-utilization给太高就会把剩余显存全吃掉,实际并发不高的话调到0.7到0.8更合适。至于vLLM和SGLang,长上下文下SGLang的RadixAttention对前缀复用确实更友好,但vLLM生态和稳定性更成熟,看你更在意吞吐还是省心。
gpu-memory-utilization=0.9就是会预分配90%显存,跟你模型实际占多少没关系,vLLM是先把KV cache池子占满再说的,所以22G很正常。第二张卡没用上可能是tp没生效,看看日志里有没有报tensor parallel相关的东西,两张4090没有NVLink走PCIe通信也会拖速度。20 tokens/s确实偏低,不过4090跑7B如果没开chunked prefill、batch又小的话也差不多这数。长上下文我这边体感SGLang的radix cache更省显存一些,但vLLM生态更成熟,看你更在意哪头了。