最近在折腾本地部署,用vLLM跑Qwen2.5-7B,服务器是两张RTX 4090(24G*2)。按说7B模型用FP16推理大概14G显存,加上KV Cache也够吧?但一启动就报CUDA OOM,试了调低max_num_seqs、换GQA,甚至只加载单卡,还是崩。后来看nvidia-smi发现显存被其他进程占了一部分,但就算全清空也只撑了半分钟。是不是我量化方式不对?或者vLLM版本太新有bug?求指点,卡在第一步好难受。
部署7B大模型到服务器,显存明明够却报OOM,有老哥遇到过吗?
全部回复
共 178 条我之前也踩过类似的坑,而且跟你配置几乎一样,双4090跑7B按理说绰绰有余。你查过vLLM的日志没?有时候它默认会为每个进程预留一部分显存作为缓存池,就算你设置max_num_seqs很低,它还是会按最大并发去预分配,这个值藏在config里可能没生效。另外你提到单卡也崩,我怀疑是不是CUDA版本和PyTorch的显存碎片化问题,特别是刚启动那半分钟,可能是在做权重初始化时临时申请了大块连续内存,被碎片卡住了。量化方式的话,FP16本身没问题,但你可以试试用AWQ或GPTQ的4bit版本,显存占用直接砍半,还能顺便拉长KV Cache长度。还有个小细节,你检查过NCCL环境变量吗?多卡时P2P通信会额外占显存,设个NCCL_P2P_DISABLE=1说不定就过了。版本太新确实有概率踩bug,我后来从0.6.0回退到0.5.4就稳了,你可以两个都试下,别在一个树上吊死。实在不行就开--gpu-memory-utilization参数,强制把利用率压到0.8以下,虽然浪费点性能但至少能跑起来。
试试把vLLM降到0.6.x,之前我也在这版本踩过坑,新版本对多卡显存管理有点迷。
4090虽然显存大但vLLM默认会预分配不少显存,加上CUDA context和碎片,实际可用可能比你想的少很多。我之前跑7B也遇到过类似情况,后来把gpu_memory_utilization调到0.85,再配合--max-model-len限制一下长度就好了。你试试用最新版vLLM,老版本对Qwen的KV cache复用确实有坑。另外建议先跑个纯transformers的加载测试,排除是推理框架的问题还是模型本身的问题。
这问题我前几天刚踩过,vLLM默认会预先分配整个显存池,就算模型+KV Cache没满,它也会把剩下的显存全占了,所以其他进程一占就崩。你先试试设--gpu-memory-utilization 0.9,再配合--max-model-len调小点,比如4096,能省不少。另外4090的双卡要开--tensor-parallel-size 2,但注意GQA头数在Qwen2.5上可能和TP不兼容,单卡反而稳。我最后是换成AWQ量化过的4bit权重,显存瞬间降到8G左右,跑起来还更快,你可以试试。
楼上说的对,不过我再补个坑:vLLM 0.6之后有个默认开启的PD分离特性,会额外吃掉一块显存做预填充,你查一下日志里有没有“prefill”相关分配,直接关掉能省好几G。还有,你清空显存后只撑半分钟,大概率是模型加载完初始化KV Cache时又涨了一波,建议把--swap-space设成0,禁用磁盘交换。我上次遇到类似情况,最后发现是驱动版本太老导致内存映射失败,升级到550+就没事了。量化方式倒不是重点,先跑通FP16再说。
遇到过一次,别光看模型大小,7B的激活值
我之前也卡在这过,后来发现是vLLM默认给每个request预留的显存太大了,把--gpu-memory-utilization调到0.85,再配合--max-num-seqs小一点,立马就稳了。另外你这张卡上是不是还跑着别的服务?哪怕占了1G,vLLM的预分配机制也会直接炸。量化的话,7B其实没必要上AWQ,FP16够用,但记得把KV Cache类型改成fp8试试,能省不少。版本建议别追新,0.6.3左右比较稳,新版有阵子确实有显存泄漏的issue。
显存碎片化了吧,试试docker里跑,或者换awq量化看看,vLLM新版对显存管理挺敏感的。
显存碎片化+多卡负载不均吧,试试PEFT加载或者把block_size调小点,vLLM新版对7B兼容性确实有坑。
我之前也遇到过类似情况,后来发现是vLLM默认会提前申请一部分显存做torch缓存,虽然nvidia-smi看着空闲,但实际可用被缩水了。你可以试试设一下VLLM_USE_CPU_OFFLOAD或者直接改gpu_memory_utilization参数,把利用率调低到0.8看看。另外Qwen2.5-7B的GQA配置其实挺吃KV Cache的,建议用AQLM或者GPTQ量化到4bit再跑,显存压力会小很多。版本的话我这边0.6.3稳定,太新的确实容易有兼容问题。
遇到过一模一样的情况,最后发现是vLLM默认会预分配显存给KV Cache,就算你设了max_num_seqs,它也会按最高配置预留,实际占用比你想的多不少。你可以试试把gpu_memory_utilization调到0.6以下,或者干脆用--kv-cache-dtype fp8看看能不能压下来。另外两张卡的话,得确认下是不是没设tensor-parallel-size,默认可能只加载一张卡,反而把另一张卡的空闲显存浪费了。我后来换回transformers原生推理,虽然慢点但至少不崩,你先跑通再优化吧。
显存碎片化了吧,先看下nvidia-smi里有没有别的进程占着,或者试试P2P通信关掉。之前遇到过类似,换老版本vLLM直接好了。
显存碎片化或者vLLM预分配策略的问题,试试把gpu_memory_utilization调低到0.8,强制走单卡看下日志。
可能是vLLM默认预分配了90%显存,加上CUDA context和碎片,14G模型实际要20G+,调低利用率试试。
试试把vLLM降到0.6.x,新版对多卡显存分配确实有坑,我上周也栽这了。
老哥这问题我前几天刚踩过坑,最后发现是vLLM默认给每个request预留的KV cache空间太激进,加上paged attention的显存碎片化,实际占用比理论值高不少。你可以试试在启动参数里显式指定--kv-cache-dtype fp8,或者干脆用--max-model-len 8192把序列长度砍半,这两招能立刻腾出几个G。另外4090的驱动和CUDA版本如果跟vLLM不匹配,它有时候会错误地探测显存,建议用docker镜像跑,官方打包好的环境能避开很多玄学问题。还有个小细节,你检查下是不是有另一个进程占了共享显存,nvidia-smi看到的占用率和torch实际能分配的显存不是一回事,用torch.cuda.mem_get_info()看真实可用数最靠谱。要是还崩,直接降到vLLM 0.4.2老版本,新版本对7B这种小模型反而优化得不好,我换回老版本后就没再OOM过。实在不行就换AWQ量化跑INT4,显存直接省一半还快不少。
试试把gpu_memory_utilization调到0.85,vLLM默认会预留不少显存,7B加长上下文真不够吃。
这问题我踩过坑,大概率不是量化的事,vLLM默认会预分配显存,加上CUDA context和碎片,实际占用能到20G往上。试试把gpu_memory_utilization调到0.8以下,再开个--enforce-eager关掉图模式,能省不少。另外两张卡的话记得显存要均匀分布,别全堆在卡0上。版本太新确实容易有坑,我退回0.6.3才稳。
先看看是不是CPU内存和GPU内存映射的问题,vLLM默认会预留不少显存,试着把gpu_memory_utilization调低到0.8试试。
也可能是CUDA版本和PyTorch不匹配,我之前遇到过类似情况,换个旧版vLLM就好了。
vLLM跑7B其实比你想象中吃显存,除了权重,CUDA context、KV cache、中间激活都会占,4090虽然24G但单卡跑满seq len很容易爆。你试试把--gpu-memory-utilization设到0.8,再限制max-model-len到4096,大概率能救回来。另外别用最新版vLLM,0.6.x有些版本确实有显存碎片问题,降到0.5.5稳定很多。如果还不行,检查下是不是P2P通信占了shared memory,双卡环境经常有这种坑。
我之前也卡这过,后来发现是vLLM的默认torch.compile和4090的驱动版本有冲突,换成2.4.2旧版直接好了。另外你试过把tensor_parallel_size设成1然后手动塞到单卡跑吗?两张卡通信开销有时反而让显存碎片化更严重。量化到AWQ应该能压到10G内,但7B模型对精度损失其实挺敏感的,不推荐一上来就动这个。先查下显存是不是被别的API服务占着没释放,我上次就是有个僵尸Python进程挂着。
我之前也遇到过类似情况,后来发现是vLLM默认会预分配一部分显存给CUDA context和torch缓存,看着空闲其实被占了,试试设一下gpu_memory_utilization=0.9,或者换成--max-model-len小一点,比如4096。另外4090之间NVLink带宽不够的话,多卡反而更吃显存,先单卡+--tensor-parallel-size 1排除下。如果还崩,换个旧版vLLM比如0.4.2,新版对多卡调度确实有改动,我上次就是降版本解决的。
vLLM对显存的预分配很激进,默认会按最大并发预留KV cache,7B模型实际占用经常到20G+,两张卡还得考虑通信开销。建议先试试把gpu_memory_utilization调到0.8以下,或者直接换transformers原生推理排除软件因素。另外检查下CUDA版本和vLLM是否匹配,我之前遇到过版本新旧混用导致的分配异常。