最近在折腾本地部署,用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预分配策略导致的。我之前用H800跑13B也遇到过类似,明明nvidia-smi看着还剩20G,一启动就OOM,后来发现是vLLM默认会为每个序列预留很大的KV cache空间,你要是max_num_seqs调太低反而会触发保守分配,建议直接换1.0.2版本试试,新版本有时候对多卡通信有bug。另外你提到FP16,7B模型光权重就要14G,但加上激活值和CUDA context,实际峰值轻松破20G,单卡肯定不够,双卡的话得确保张量并行设置正确,别让vLLM自动把模型塞进一张卡。还有一个坑是4090的驱动和CUDA版本不匹配,vLLM某些算子会申请额外显存做临时buffer,你可以试试环境变量设置VLLM_NO_DEPRECATION_WARNING或者PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True,强制PyTorch的显存分配器用可扩展段模式,能救回来不少碎片。量化方面,如果不用GPTQ或AWQ,纯FP16本来就吃紧,建议先用llama.cpp的Q4_K_M跑通流程,确认代码没问题再回头折腾vLLM,毕竟后者对显存的控制没那么透明。你检查过是不是有其它python进程隐式占用了CUDA context吗?比如Jupyter内核或者监控脚本,有时候光看nvidia-smi的进程列表根本发现不了那种常驻的显存占用。
显存碎片化也会导致OOM,试试把pytorch的缓存清一下或者换旧版vLLM看看。
清完显存只撑半分钟大概率是KV Cache预分配爆了,设个max_model_len限制下序列长度试试。
vLLM跑7B按理说14G是够的,但4090的显存分配很迷,你试试加--gpu-memory-utilization 0.9,别让它默认吃满。另外看看是不是pytorch缓存了显存没释放,torch.cuda.empty_cache()之后再看nvidia-smi,有时候那个“其他进程”就是你自己之前的残留。量化倒不是关键,FP16本身没问题,我更怀疑是vLLM版本和CUDA 12.4的兼容坑,换0.6.3或者0.5.5试试,新版经常有显存碎片bug。
这问题我上周刚踩过一模一样的坑,也是双4090跑7B,最后发现是vLLM默认把张量并行开成2了,但两张卡之间通信走PCIe,显存碎片化严重的时候反而比单卡更容易爆。你试试启动参数里明确加tensor-parallel-size 1,然后max-model-len调小到4096,我这么改完直接从OOM变成占用17G左右稳跑。另外量化方式别用FP16了,换AWQ或者GPTQ的4bit版本,显存能压到9G,省下的空间全给KV cache,半分钟崩大概率是prefill阶段峰值显存超了,不是稳态占用问题。你nvidia-smi里看到其他进程占显存,记得用fuser -v /dev/nvidia*查一下是不是有残留的python进程,我上次就是有个僵尸进程吃了3G没发现。vLLM版本的话,0.6.3之前有个bug会在多卡时重复分配KV cache,升级到0.6.6或者直接装最新版能解决。你先试单卡+tensor-parallel-size 1+4bit量化,这组合我目前最稳。
上次我也踩过这坑,最后发现是vLLM的默认prefill内存分配太激进,跟max_num_seqs关系不大。你试试设个--gpu-memory-utilization 0.85,再把--max-model-len砍到4096,应该能稳。另外4090双卡的话,记得检查下NVLink是不是被别的进程占着,有时候驱动bug会导致跨卡通信直接吞显存。量化先别换,FP16没问题,多半是配置问题。
这问题我上周刚遇到过,折腾了两天才发现是vLLM默认给每个序列预留的KV Cache太激进,加上PagedAttention的显存碎片化,实际占用比理论值高不少。你可以试试在启动参数里显式加上--gpu-memory-utilization 0.85,别让它自动探测,另外确认下是不是用了最新版vLLM,0.6.x有个已知的显存泄漏bug,回退到0.5.5就稳了。还有个坑是两张卡之间通信也要吃显存,可以先设--tensor-parallel-size 1纯单卡跑通再考虑多卡。
显存看着够不等于vLLM预分配不吃紧,试试加--gpu-memory-utilization 0.9,再不行就换transformers原生跑下排除版本坑。
我之前也踩过这坑,7B用FP16按理说够,但vLLM默认会预分配显存,而且它内部还要给调度和CUDA context留余量,实际占用比你想的高得多。你试过设gpu_memory_utilization=0.9吗?这参数比max_num_seqs管用。另外别用太新的版本,0.6.x有些分支确实有显存泄漏的issue,换个稳定版比如0.6.3试试。单卡跑的话记得把tensor_parallel_size设成1,不然它默认可能还是去探测双卡然后分配失败。
4090的24G跑7B其实很吃紧,你要不试试AWQ量化或者把KV Cache比例调低点?
我之前也踩过类似的坑,不过不是vLLM,是拿transformers直接怼的。你提到全清空显存也只撑了半分钟,这个细节很关键,我怀疑不是显存总量的问题,而是显存碎片化或者内存映射炸了,尤其是两张卡之间通信如果走NVLink还好,走PCIe的话,vLLM默认会做张量并行,每张卡要预留一部分activation空间,实际可用比你想的要小得多。另外你说“量化方式不对”,但7B FP16其实不用量化也该够,除非你加载的是带对话模板的完整版,那权重会略大一点。建议你先把vLLM的日志里那行显存分配计算贴出来,看看它自己预估的KV Cache和峰值预留是多少,我之前发现vLLM有个版本默认给每个序列留了2048个token的KV,max_num_seqs调低了反而触发它自动扩大单序列空间,结果更吃显存。还有个土办法,先只加载单卡,把gpu_memory_utilization设到0.7,甚至0.6,别让它自动探测,试试能不能跑通,如果这样还OOM,那可能就是驱动或CUDA版本和vLLM的P2P通信库冲突了,换旧一版的vLLM或者关掉并行试试。你用的vLLM版本号是多少?我之前升到0.6.3就有这个毛病,回退到0.5.4就没事了。
显存碎片化了解一下,先清干净进程再设个CUDA_VISIBLE_DEVICES=0试试,我之前也卡这。
我之前也卡在这过,排查下来是vLLM默认给每个序列预留的显存太多了,尤其max_num_seqs调低反而触发碎片化。你试试把gpu_memory_utilization设到0.9,再加--enforce-eager关掉CUDA graph,我这么搞就稳了。另外4090的驱动和CUDA版本也得对得上,vLLM新版对12.4以下支持有点迷。你量化是用的FP16还是AWQ?如果只是精度问题,换GPTQ可能直接省一半显存。
我之前也遇到过类似的坑,后来发现是vLLM默认会为每个序列预留不少显存,就算调低max_num_seqs,如果并发请求数没限制住,照样给你吃满。你试试把--gpu-memory-utilization设到0.7以下,再配个--max-model-len小一点(比如2048),应该能缓解。另外4090的驱动和CUDA版本也得留意,太新的vLLM有时候会对特定架构有隐性兼容问题,我换回0.6.x就稳了。你那个“只撑半分钟”的情况,像是加载权重时临时峰值爆了,可以先不开KV Cache跑一次看基础占用。
我之前也踩过类似的坑,7B fp16权重确实就14G左右,但vLLM启动时还会预留一大块显存做激活和CUDA graph,尤其默认gpu_memory_utilization是0.9,两张卡各吃满90%你算算就超了。你说的显存被其他进程占了一部分我建议再仔细查查,nvidia-smi有时候显示不全,用nvitop或者fuser -v /dev/nvidia*看看是不是有残留的python进程没杀干净,这种情况特别常见。另外vLLM的版本确实有影响,0.6.x某些版本在tensor parallel下KV cache分配算得偏激进,可以试试降到0.5.4或者把gpu_memory_utilization压到0.8、max_model_len设小一点。还有个容易忽略的点是Qwen2.5的tokenizer配置,如果你没传trust_remote_code或者dtype没显式指定float16,它可能默认走了fp32加载,那显存直接翻倍。单卡都崩的话基本可以排除TP通信问题,重点看加载精度和显存预留策略。建议先跑个最小复现,把enforce_eager打开关掉CUDA graph,看还崩不崩,这样能快速定位是图捕获吃显存还是权重加载的问题。
vLLM默认gpu_memory_utilization是0.9,你调成0.8试试,我之前也卡这半天。
vLLM默认会预分配90%的显存做KV Cache,你两张卡加起来看似48G,但它可能只认单卡或者TP没配好,直接按一张卡的90%去抢,那肯定爆。先试试加--gpu-memory-utilization 0.8,再确认下tensor-parallel-size是不是设成2了。另外Qwen2.5的GQA本身不省预分配那部分,别被误导。我之前也卡这,后来发现是dtype没指定,默认走了fp32,你检查下有没有加--dtype half。
你这情况我前段时间也踩过,一模一样的两张4090跑Qwen2.5-7B,nvidia-smi看着显存够但就是OOM,折腾了一整天才找到原因。vLLM默认会预分配一大块显存给KV Cache,gpu_memory_utilization这个参数默认是0.9,两张卡各吃90%你算算还剩多少给模型权重。而且它还有个坑是你看着nvidia-smi显示被别的进程占了,其实可能是vLLM自己上一轮没退干净留下的僵尸进程,清一下再启动会好很多。建议先把gpu_memory_utilization调到0.85左右试试,再配合max_model_len收小一点,别让它按模型最大长度去预分配。另外你提到换GQA、调max_num_seqs都没用,那大概率不是这些参数的事,先看看启动日志里它到底想分配多少显存,那个数字经常比你以为的大不少。FP16的7B权重确实14G左右,但vLLM加载时会有额外开销,加上graph capture那些,单卡24G其实挺紧的。实在不行用AWQ或者GPTQ量化跑,4bit的话一张卡就绰绰有余了。
vLLM默认会预分配90%显存,启动崩不一定是真OOM,先调gpu_memory_utilization试试。