最近在折腾开源大模型部署,用LoRA微调了一个Qwen2.5-7B的领域问答模型。机器是4090 24G,vLLM加载int8量化后显存占用大概14G,按理说很宽裕,但实际推理时速度只有不到10 tokens/s,batch size调到4反而更慢。我以为是量化精度问题,换回FP16又直接OOM(虽然理论上24G应该能塞下)。查了日志也没报错,就是GPU利用率只有40%左右,CPU却飙到80%。是不是我的vLLM参数没调对?比如--max-model-len或--gpu-memory-utilization设置不合理?还是说7B模型在单卡上本来就是这个速度?求有经验的大佬指点一下,或者有没有更合适的部署框架推荐(比如TGI或llama.cpp)?
部署Qwen2.5-7B微调版,显存够但推理速度慢得离谱,正常吗?
全部回复
共 73 条看到这个GPU利用率40%但CPU飙到80%的现象,我第一反应是你可能被数据预处理或者采样器卡住了。vLLM虽然快,但如果你用的是动态padding或者没有把prompt提前padding到固定长度,CPU端tokenize和padding的负担会直接把生成速度拖垮,特别是batch size调大后,CPU瓶颈会更明显。另外你说FP16直接OOM,这个很可疑——24G跑7B fp16理论只要14G左右,除非你的max-model-len设得特别大,把KV cache撑爆了,建议你检查下实际序列长度和--max-model-len的比值,别盲目设成32768。还有个坑是LoRA微调后合并权重时,如果没把adapter正确融合进base model,vLLM加载时可能会走一遍额外的偏置计算,也会拖慢推理。我自己的经验是,单卡4090跑7B int8,正常应该在25-40 tokens/s,你那个速度确实不正常。建议先试试--gpu-memory-utilization设成0.85,然后关掉--enable-prefix-caching,再看下--max-num-batched-tokens是不是设太小了。如果还不行,可以开个--verbose看下vLLM到底在等什么,或者直接换transformers + flash-attention跑一遍对比下,排除是模型本身问题还是框架问题。
说实话这个速度不太正常,我同样4090跑Qwen2.5-7B的AWQ量化,vLLM默认参数下能到25-30 tokens/s。你GPU利用率才40%大概率是卡在CPU那边了,检查下是不是磁盘IO或者数据预处理瓶颈,另外--max-model-len设太大会导致显存碎片化,建议改成2048或4096试试,还有--gpu-memory-utilization设到0.85以上,给KV cache留足空间。
还有个坑是LoRA微调后的模型合并权重时容易残留一些原始参数,导致vLLM的连续性优化失效,你试试用--enforce-eager关掉CUDA graph看看会不会有改善。batch size变大反而变慢很可能是prefill阶段计算量上去了但显存带宽不够,7B在单卡上确实比13B吃紧,但也不至于这么拉胯,优先排查数据加载和量化格式吧。
4090跑7B差不多就这速度,但CPU80%明显不对劲,检查下是不是vLLM的tokenizer在抢线程。
4090跑7B不至于这么拉,查下vLLM的--max-model-len是不是设太大导致KV cache爆炸了。
这速度不对劲,试试把gpu-memory-utilization调到0.9,再把batch size降回1看下。
这速度确实不太对劲,我拿同样配置跑过7B的对话模型,vLLM默认参数下基本能到25-30 tokens/s,你那个batch size变大反而变慢挺像CPU瓶颈的。检查下是不是数据预处理或者tokenizer在CPU上卡住了,还有--max-model-len如果设太大,prefill阶段会吃掉不少算力。另外FP16 OOM有点怪,24G跑7B按理说绰绰有余,会不会是显存碎片化或者vLLM缓存分配策略保守了,试试把--gpu-memory-utilization调到0.9看看。
看到这个速度我第一反应就是vLLM的prefill阶段在作祟,你试试把--max-model-len从默认的2048调低到512或1024,很多领域问答场景根本用不到长上下文,这个参数会直接影响KV cache的分配策略,我遇到过类似情况,调完后速度直接翻倍。另外GPU利用率只有40%但CPU飙高,很可能瓶颈在数据预处理和tokenizer上,LoRA微调后的模型如果加了额外的special token,vLLM的tokenizer并行度会下降,你可以试试用--tokenizer-pool-size和--tokenizer-workers强制多进程。至于FP16 OOM的问题,4090虽然显存够,但vLLM默认会保留一些显存给CUDA context和碎片,建议显式设置--gpu-memory-utilization=0.92,同时确认下是不是开了--enable-prefix-caching,这个功能在7B模型上经常因为前缀缓存命中率低反而拖慢速度。还有个小细节,你的batch size调到4更慢,可能是vLLM的continuous batching对短请求不友好,试试保持batch size为1但增加--max-num-seqs到8,让调度器自己决定怎么并发。我自己的经验是7B在4090上单条生成200字左右,正常应该能跑25-35 tokens/s,你这个速度明显是配置问题而不是模型本身的上限。
如果调完这些还是慢,可以看一眼显存里是不是有残留的CUDA context没释放,用nvidia-smi对比下加载前后的空闲显存,有时候vLLM在量化模式下会额外申请一块内存做反量化缓冲,我上次就是被这个坑了。最后建议你跑个不带LoRA的基座模型对比一下,如果基座速度正常,那问题就出在LoRA合并时的权重格式上,有些微调框架导出的adapter会强制模型走slow path,试试用merge_and_unload重新导出一次。
看到GPU利用率40%但CPU 80%这个组合,基本可以断定瓶颈在数据预处理或采样器上,vLLM默认的continuous batching对LoRA权重加载也有额外开销,建议试试把--max-num-seqs调低到8以内,同时关掉--enable-prefix-caching看能不能缓解。
量化到int8反而比FP16慢的情况我也遇到过,7B在4090上正常应该能跑20-30 tokens/s,你这速度明显偏低,可以检查下是不是微调后的权重没有正确合并导致额外计算,或者直接看下nvidia-smi里的功耗是否跑满。
另外4090的24G跑FP16的7B理论上是够的,但vLLM会把KV cache和激活值都算进去,建议显存利用率设到0.9,max-model-len按你实际最长输入设,别用默认的8192,我之前调完这几个参数速度直接翻倍。
这速度肯定不正常,我之前用vLLM跑同尺寸模型,int8下至少能到30-40 tokens/s。你CPU飙到80%大概率是prefill阶段卡在tokenization或者数据预处理上了,试试把--max-model-len砍到2048,然后--gpu-memory-utilization设0.9,还有注意下是不是LoRA合并后没做weight转换导致kernel没走对。另外batch size调4反而慢可能是显存碎片化严重,可以先看下nvidia-smi是不是有内存碎片,或者干脆换AWQ量化试试。
GPU利用率才40%说明瓶颈压根不在显存,vLLM的prefill和decode阶段吃的是算力和带宽,7B在4090上单卡跑满也就这水平,10 tokens/s不算离谱。你试试把max-model-len调小到2048,再关掉gpu-memory-utilization让它自动分配,batch size开1反而可能更快。另外看下是不是CPU在做tokenizer或采样拖了后腿,把num_cpu_workers调低或者直接换成异步模式。
CPU飙到80%这个现象挺关键的,你查下是不是vLLM的tokenizer或prefill阶段在CPU上跑了,尤其LoRA加载后会有额外的adapter权重处理,建议试试把--cpu-offload-gb设为0,再手动把--gpu-memory-utilization调到0.9看看。另外7B在4090上FP16理论能跑但峰值显存容易爆,int8下10 tok/s确实偏慢,正常应该能到20+,你可以先不加载LoRA测一下基座速度,排除是不是微调权重带来的额外开销。
你这速度明显不正常,4090跑7B哪怕不量化,vLLM也能轻松上40-50 tokens/s。瓶颈大概率在CPU,数据预处理和tokenizer是单线程的,你开个--tokenizer-parallelism试试,另外--max-model-len别给太长,2048就够用,太长会浪费显存和计算。至于FP16 OOM,可能是KV cache预留不够,--gpu-memory-utilization调到0.9试试,别用默认值。
这速度确实不太正常,我拿同样配置跑过7B,vLLM+int8一般能到30-40 tokens/s。GPU利用率卡在40%八成是CPU成了瓶颈,先试试把--max-model-len砍到2048,再把--gpu-memory-utilization设到0.9,然后看下是不是数据加载或tokenizer那边卡住了。另外batch size在vLLM里不是简单调大就快,有时反而影响continuous batching效率,建议固定1先测纯生成速度。至于FP16 OOM,可能是KV cache默认预留太多,得显式限一下--max-num-seqs。
看到GPU利用率40%但CPU飙到80%,大概率是数据预处理或采样器那边卡住了,试试把--max-model-len调小到4096,再把--gpu-memory-utilization设到0.9看看。另外4090跑7B int8理论上应该能到30-40 tokens/s,你这速度确实不正常,vLLM版本换到最新版或者试试--enable-prefix-caching,有时候旧版本对LoRA支持有bug。batch size变小反而快的话,可能显存碎片化严重,加个--swap-space=4强制内存交换试试,不过最好还是检查下是不是微调后的模型加载时把adapter权重重复加载了。
这速度确实不太正常,我跑过类似的7B模型,vLLM下int8单卡轻松能到30-40 tokens/s。你GPU利用率才40%说明瓶颈不在显存,大概率是CPU在疯狂做tokenizer或prefill,看看是不是--max-model-len设太大导致KV cache预分配过多,然后batch size调大反而拖慢,可能是prefill阶段计算量上去了但decode没跟上。建议试试把--gpu-memory-utilization调到0.9,同时限制--max-num-seqs,另外确认下是不是开了--enable-prefix-caching但数据里没有可复用的前缀。如果还不行,直接换llama.cpp或者exllamav2跑下FP16,对比下速度就知道是不是vLLM的调度问题了。
4090跑7B int8这速度肯定不正常,CPU飙高八成是prefill没走对,检查下vllm的--max-num-batched-tokens和--enable-prefix-caching。
这速度肯定不正常,7B哪怕FP16在4090上也不该只有10 tokens/s。你试试把gpu-memory-utilization设到0.9,max-model-len砍到2048,另外vLLM版本换到0.6以上,老版本对量化支持有坑。还有,CPU飙到80%八成是tokenizer和prefill阶段卡了,你检查下是不是没开--enable-prefix-caching,LoRA微调过的模型前缀缓存能省不少事。
我遇到过类似情况,最后发现是vLLM的--swap-space默认值太高,跟量化后的显存管理冲突了。另外你batch size调大反而慢,很可能是max-num-seqs没跟着调,默认值太小导致排队,试试手动设成64,顺便关掉--enforce-eager,别用图模式,有时CUDAGraph跟int8量化不兼容。如果还不行,直接看下nvidia-smi的功耗,要是没跑满300W,那就是kernel没吃满,换transformers原生推理对比下就清楚了。
其实单卡推理7B不至于这么拉胯,我之前跑Qwen2.5-7B AWQ量化,vLLM能到25-30 tokens/s。你换int8可能不如AWQ或GPTQ优化得好,建议试试--quantization awq配对应的权重。另外确认下是不是CPU
这速度确实不太正常,我跑过差不多的配置,7B int8在4090上单条prompt通常能到25-30 tokens/s。你GPU利用率才40%说明瓶颈根本不在显存,大概率是CPU忙着做tokenize或者prefill阶段的数据处理,vLLM参数倒不是主因。建议先检查一下是不是LoRA合并后模型文件碎片化太严重,或者试试把--max-model-len砍到2048,再把--gpu-memory-utilization调到0.9,batch size别硬上,7B这规模单卡本来就吃不满。另外FP16 OOM有点怪,24G按理说够,你确认下是不是有别的进程占了显存。
你这情况我太熟了,之前部署别的7B模型也踩过同样的坑。CPU飙到80%基本能说明问题不在显存,而是数据预处理和tokenizer那块在拖后腿,vLLM的prefill阶段如果没走对,CPU就会变成瓶颈。你可以试试把--max-model-len调低到4096或者2048,很多时候默认值会预留太多KV cache空间,反而让显存碎片化严重,batch size越大越容易触发这种情况。另外--gpu-memory-utilization别设太高,0.85到0.9就够,留点余量给CUDA context和临时张量,不然容易隐性OOM。至于FP16直接爆掉,我怀疑是你微调时的LoRA权重合并出了问题,导致模型实际参数量比预期大,或者中间激活值没被正确释放,建议用torch.cuda.max_memory_allocated打一下峰值看看。单卡4090跑7B满血FP16理论上是能塞下的,vLLM官方benchmark大概能有20-30 tokens/s,你这才不到10肯定不正常,但也不完全是参数问题——你试试不用量化,直接FP16但把--max-num-seqs限制在2,看速度会不会上去。还有个野路子,把vLLM换成llama.cpp的GGUF格式跑一下,有时候那种场景下反而更快,能帮你定位是框架问题还是模型本身的问题。
你这个问题我前两天刚踩过坑,vLLM在4090上跑7B其实很吃参数,--gpu-memory-utilization别拉满,留个1-2G给CUDA context,不然会频繁触发内存交换。另外CPU飙到80%大概率是tokenizer或者prefill阶段没吃满GPU,试试把--max-num-batched-tokens调小到2048,batch size先别动。还有你确认下是不是用了flash attention,没开的话速度差好几倍。
看到你这个情况我第一反应是vLLM的prefill阶段和decode阶段没分开看,10 tokens/s如果是在长上下文场景下其实挺正常的,7B模型单卡本来也就这个量级。不过GPU利用率40%确实不对劲,你这配置跑满的话至少能到20+ tokens/s。我猜问题可能出在--max-model-len上,如果设得太大会导致KV cache预留过多显存,虽然显示14G占用但实际可用计算资源被挤占了,试试设成2048或4096再看。另外LoRA微调过的模型合并权重后有时候会引入额外计算开销,你有试过直接用原版Qwen2.5-7B对比速度吗?batch size调慢那个现象我遇到过,可能是预填充阶段CPU在跑tokenizer或者数据预处理,你试试加--enable-prefix-caching或者把--cpu-offload-gb设成0,还有注意vLLM版本,0.4.0之后对量化模型支持差异很大。最后问下你用的什么量化方式,GPTQ和AWQ在vLLM里的实现效率差别挺大的,如果用的是AutoGPTQ做int8,那速度慢还真不奇怪。