最近在折腾开源大模型部署,用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这玩意儿对--max-model-len特别敏感,你如果设得比实际对话长度大很多,prefill阶段会白白算一堆padding,速度直接腰斩。另外4090跑7B int8在vLLM里本来也就20-30 tokens/s算正常,但10以下确实低了,你试试把--gpu-memory-utilization调到0.9以上,给KV cache多留点空间,有时候默认值0.8反而让显存碎片化严重。
还有一个坑是LoRA微调后的模型合并有问题,如果你直接加载adapter而不是合并权重,HuggingFace的加载流程会走慢速路径,这个在vLLM里特别明显。建议你确认下是不是用了--enable-lora并且显存里同时驻留了base权重和adapter,那样实际占用会比你以为的高不少。最后batch size调4变慢很可能是没开continuous batching,vLLM默认支持但得看你的版本,老版本可能要手动设--max-num-seqs,你试试调成8或者16,同时把--max-num-batched-tokens调低,有时候这两个参数互相打架反而拖慢。如果还不行,直接换llama.cpp跑一下同模型对比,能快速判断是vLLM配置问题还是硬件瓶颈。
说实话你这情况我太熟了,当时我拿3090跑7B也是这鬼样子,后来发现根本不是显存的事,是vLLM的prefill阶段在作妖。你试试把--max-model-len从默认的2048砍到512,还有--gpu-memory-utilization别拉满,留个0.85左右,这俩参数对短文本的批处理影响特别大。另外batch size不是越大越好,vLLM在显存充裕时反而会因为连续批次的调度开销拖慢单请求延迟,你试试batch size=1加上--enable-prefix-caching,有时候效果立竿见影。至于FP16 OOM,我怀疑你忘了开--swap-space,或者显存碎片化严重,试试重启服务前清一下缓存,或者用--enforce-eager关掉CUDA graph,虽然慢一点但能省不少显存。还有你CPU飙到80%这个信号很关键,八成是tokenizer或者自定义的post-processor在瓶颈上,检查下是不是用了慢速的纯Python正则,换成tiktoken或者预编译的re会快很多。最后说句实话,7B在4090上跑10 tokens/s不算离谱,但你要是想要20+,直接上AWQ量化配合--quantization awq,int8的vLLM优化其实很一般。你先按这个顺序试,大概率能找到瓶颈。
4090跑7B不至于这速度,看看是不是vLLM的prefill和decode没分开算,或者LoRA合并后KV cache没释放。
GPU利用率40%说明瓶颈不在显存,大概率是CPU喂数据跟不上,试试把max-model-len调小点或者换flash-attention。
这速度确实不正常,4090跑7B int8正常应该能到30-40 tokens/s。你CPU飙到80%大概率是vLLM的prefill和decode都在抢CPU资源,试试把--max-model-len调小到2048或者4096,--gpu-memory-utilization设成0.9以上,让KV cache吃满剩余显存。另外batch size不是越大越好,vLLM对动态batching支持很好,你手动调到4反而可能触发碎片化。FP16 OOM那个也怪,14G显存占用说明权重已经量化过,你换回FP16时是不是忘了把--load-format改回原版?先跑个官方benchmark排除模型本身问题吧。
4090跑7B不至于这么拉胯,我怀疑你vLLM的KV cache和prefill配置没对上,试试把--max-model-len降到4096或者2048看下,显存利用率能提上去不少。另外int8在vLLM里有时反而会触发dequantize的额外开销,不如直接上AWQ或GPTQ量化,FP16 OOM大概率是max-model-len设太长导致KV cache爆了。GPU利用率40%太异常,建议开--enable-prefix-caching并且把--gpu-memory-utilization调到0.9,同时用nvidia-smi dmon看下是不是PCIe带宽瓶颈——你CPU 80%可能是数据预处理卡住了。
这速度确实不太对,我3090跑7B FP16都有20+ token/s,你int8才10不到肯定有瓶颈。vLLM的gpu-memory-utilization建议设到0.9以上,max-model-len别超过2048试试,另外LoRA的adapter加载方式也可能影响显存碎片化。CPU飙到80%很可疑,看看是不是--dtype设置和量化格式不匹配导致算子走回CPU了。
你这速度确实不对劲,我同样4090跑Qwen2.5-7B的FP16,vLLM默认参数下也有20+ tokens/s,int8应该更快才对。建议先查下是不是vLLM版本和CUDA不匹配,或者换0.6.x的稳定版试试;另外CPU飙到80%很可能是因为tokenizer或prefill阶段在CPU上跑,试试把--max-model-len调到4096以下,--gpu-memory-utilization设0.9,再把--enforce-eager加上关掉CUDA graph看看。7B单卡不至于这么慢,我怀疑是量化后kernel没走对,你可以用--quantization awq配对应的AWQ权重试试,别用bitsandbytes的int8。
看到这个GPU利用率40%但CPU飙到80%的现象,我第一反应是数据预处理或者tokenizer那块卡住了,vLLM的prefill阶段对CPU的依赖比想象中高,你可以试试开--enable-prefix-caching或者把--max-num-batched-tokens调小一点,让GPU别等着CPU喂数据。另外你说batch size调4反而更慢,这挺反常的,如果显存还有余量,建议把--gpu-memory-utilization从默认的0.9往上调到0.95,同时关掉--enforce-eager试试,有时候CUDA graph的开销在小batch下反而拖后腿。至于FP16 OOM,我怀疑是KV cache默认配置没适配你的显存,--max-model-len如果设了8192以上,7B模型FP16的KV cache峰值会接近20G,加上权重基本就爆了,你可以先用--max-model-len 4096跑一下看能不能塞进去。说实话7B在4090上正常速度应该能到30-50 tokens/s,你这才10不到肯定有瓶颈,建议先用官方Qwen2.5-7B不微调的版本测个基线,排除是不是LoRA合并后模型结构出了问题。还有个隐蔽的坑,就是vLLM版本和CUDA版本不匹配会导致kernel选择异常,你试试升级到最新的vLLM 0.6.x或者干脆用TGI对比一下速度。最后如果所有参数都折腾遍了还是慢,可以看看是不是CPU内存带宽不够,LoRA微调后的模型如果embedding层被改大了,会明显增加CPU到GPU的传输量,这种情况可以考虑把模型转成safetensors格式并开启mmap预加载。
说实话这个速度确实不太正常,我自己的4090跑Qwen2.5-7B全精度FP16,vLLM默认参数下都能稳在25-30 tokens/s左右,你这个int8反而掉到10以内肯定有蹊跷。GPU利用率只有40%但CPU飙到80%,这明显是瓶颈不在显存带宽上,而是数据预处理或者采样环节卡住了,我怀疑是你--max-model-len设得太大导致KV cache预分配了过多显存,然后实际计算时又频繁做padding或者位置编码重算。另外LoRA微调过的模型如果合并权重没做干净,某些层可能还是浮点计算,跟int8量化后的张量混着跑,反而比全量化更慢。batch size增大反而变慢,这个问题我在别的模型上也遇到过,多半是vLLM的continuous batching策略没适配好你的输入长度分布,你可以试试把--block-size改成64,或者关掉--enable-prefix-caching看看。还有个小细节,你检查下是不是CPU上跑着tokenizer的并行预处理,比如--tokenizer-pool-size没设对,多进程轮询会吃满CPU。最后建议你跑一下vLLM自带的benchmark脚本,用同样的输入长度对比FP16和INT8的纯decode速度,如果INT8还是只有10,那可能就不是参数问题,而是你微调时某些算子不兼容量化导致的。
4090跑7B正常不该这么慢,CPU 80%像是数据预处理或tokenizer卡住了,试下加--enable-prefix-caching或把max-model-len调小点。
说实话你这情况我太熟了,之前我拿4090跑7B也撞过类似的墙。GPU利用率40%基本说明瓶颈不在显存,而在数据搬运和计算调度上,vLLM的continuous batching对这种低并发场景本来就不太友好,batch size上去反而增加了排队开销。你试试把--max-model-len砍到2048或者更短,这玩意儿默认值有时候会预留大量KV cache,实际用不到那么多反而拖慢速度。另外int8量化如果用的是AWQ或GPTQ,对Qwen2.5的支持不一定优化到位,换bitsandbytes的NF4试试,显存占用差不多但计算效率可能不一样。FP16 OOM那个,大概率是vLLM默认预分配了全部显存,加上CUDA context和KV cache,24G确实不够,你得显式设置--gpu-memory-utilization 0.85左右。不过话说回来,7B单卡20 tokens/s左右才正常,你现在个位数肯定不正常,但也没到离谱的程度,毕竟4090的算力瓶颈摆在那。最后建议你开一下--enable-prefix-caching,如果领域问答有很多重复提示词,这玩意儿能省一大截算力。要是还不行,直接上llama.cpp的gguf格式吧,CPU+GPU混合跑反而可能更快。
CPU都飙到80%了,明显是数据预处理或采样拖了后腿,试试把--max-model-len调小点或者换下prefill策略。
我上次也这样,最后发现是max-model-len设太长导致KV cache爆炸,调小点立刻起飞。
你试试把gpu-memory-utilization调到0.9,再把max-model-len砍到2048,速度能翻倍。
说实话你这个问题我踩过一模一样的坑,问题大概率不在显存,而在vLLM的prefill和decode阶段配置上。7B模型单卡跑10 tokens/s确实偏慢,我试过把max-model-len从默认改成2048,速度能上来不少,这参数会直接影响KV cache的分配策略。另外batch size调到4反而更慢,可能是你的输入序列长度波动太大,导致显存碎片化严重,建议把gpu-memory-utilization设到0.9以上试试。至于FP16 OOM,你检查下是不是max-model-len设置过长把KV cache撑爆了,我同样24G卡跑7B全精度开到4096长度就没问题。CPU飙到80%很可能是tokenizer或数据处理线程成了瓶颈,试试用--enable-prefix-caching和--disable-log-requests减少额外开销。
跑个nvidia-smi看看是不是跑在P2模式,4090功耗墙没解锁的话性能差好几倍。
batch size调大反而慢大概率是CPU瓶颈,试试把--max-model-len调低点省下显存给KV cache。
批处理反而更慢大概率是max-model-len太长导致显存碎片化,试试砍到2048并调低gpu-memory-utilization到0.9。
这速度确实不正常,我跑Qwen2.5-7B int8在4090上单卡大概能到25-30 tokens/s,batch size=4还能再涨点。你CPU飙到80%大概率是tokenizer或prefill阶段卡在CPU上了,试试把--max-model-len降到4096,然后--gpu-memory-utilization设到0.9,同时加--enforce-eager关掉CUDA graph看看。另外LoRA微调过的模型如果合并权重没做好,也可能导致vLLM某些算子走fallback路径,建议检查下adapter是否真的合并进base model了。
这个速度确实不太正常,我跑过类似配置,vLLM下7B量化版一般能到30-40 tokens/s。你试试把--gpu-memory-utilization调到0.9,然后--max-model-len设成4096看看,另外batch size在vLLM里不是手动调的,得靠continuous batching自动来,你手动设4反而可能触发padding浪费算力。CPU飙到80%有点可疑,检查下是不是数据预处理或tokenizer没走gpu侧。实在不行换llama.cpp跑下同模型对比下,能快速定位是vLLM配置问题还是微调后模型本身有坑。
感觉你这问题大概率不是模型本身慢,vLLM的gpu-memory-utilization如果调太低,显存没吃满,反而会因为频繁的显存分配和释放拖慢速度,建议直接怼到0.9试试。另外4090跑7B单卡本来就到不了那种飞起的速度,10 tok/s其实有点偏低但不算离谱,CPU飙到80%可能跟prefill阶段和tokenizer有关。batch size调到4变慢多半是没开continuous batching,或者max-num-seqs限制太小,你可以查下vllm的启动日志里有没有提示seq长度或block分配的问题。还有个小坑,int8量化如果用的是AWQ或GPTQ,记得把quantization参数对应上,不然vLLM会走错内核。