最近在折腾开源大模型部署,用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微调版,显存够但推理速度慢得离谱,正常吗?
全部回复
共 88 条你这瓶颈八成在CPU,vLLM默认prefill吃不满GPU,试试把gpu-memory-utilization调到0.95再开个--quantization awq。
4090单跑7B不至于这速度,检查下是不是CPU内存带宽卡了,加到30G试试。
GPU利用率才40%、CPU飙到80%,这明显是CPU端卡住了,重点查一下tokenizer或者预处理线程是不是没并行起来。vLLM有个--num-scheduler-steps和--tokenizer-pool-size可以调,另外LoRA适配器如果没合并进基座,每次推理都要额外算一遍,速度掉得厉害。batch size调大反而慢,通常是KV cache碎片或者调度器在等CPU喂数据,试试加--enable-chunked-prefill。FP16 OOM的话把--max-model-len降到2048、--gpu-memory-utilization给到0.9再试,7B单卡跑不到10 tokens/s肯定不正常。
GPU利用率才40%,CPU却80%,这明显是CPU侧卡住了,大概率是tokenizer或者数据预处理拖后腿。你试试把--max-model-len调小一点,默认可能拉满到32k,prefill阶段会吃不少资源。另外vLLM的int8量化在4090上其实不是最优解,可以试试AWQ或者GPTQ,速度会好很多。FP16 OOM可能是KV cache没控制好,加个--gpu-memory-utilization 0.9和限制batch试试。
CPU飙到80%而GPU只有40%利用率,这个信号挺关键的,说明瓶颈大概率不在显卡算力上,而是在数据预处理或者tokenizer那块。你有没有注意过输入输出的长度分布?如果prompt特别长(比如几千token的领域文档),vLLM的prefill阶段会吃掉大量时间,decode阶段自然就慢了。另外--max-model-len如果设得过大,KV cache会预留很多显存,虽然不直接拖速度,但可能挤占了本可以给更多并发序列的空间。int8量化在4090上其实有点尴尬,它没有像A100那种原生INT8支持,vLLM走的可能是weight-only量化,反量化开销在batch小的时候反而明显,batch调到4更慢可能就是这原因。可以先试试把--gpu-memory-utilization拉到0.9,同时用--enforce-eager关掉CUDA graph看看有没有变化,再对比一下纯FP16但限制max-model-len到2048能不能跑起来。7B模型正常decode在4090上应该能到40-60 tokens/s,10出头肯定不正常。
CPU飙到80%感觉是预处理卡住了,试试调大--max-num-batched-tokens看看。
10 tokens/s确实不太对劲,4090跑7B int8怎么也不该这么慢。你注意看GPU利用率才40%而CPU飙到80%,这个信号很明显了,瓶颈大概率不在显卡上,而是卡在CPU侧的数据预处理或者tokenizer上。vLLM的默认配置有时候会跟你的实际场景打架,比如max-num-seqs设太小会导致并发上不去,max-model-len开太大又会吃掉KV cache的调度空间,建议先把这两个参数贴出来看看。另外batch size调到4反而更慢,很可能是KV cache不够用了,vLLM在显存紧张时会频繁做block换入换出,反而拖累吞吐,你把gpu-memory-utilization拉到0.9左右试试。还有一点容易被忽略,LoRA微调后的模型如果没做merge再加载,vLLM要走LoRA adapter路径,那套实现效率比原生权重差不少,确认下你是直接加载的合并后模型还是挂adapter跑的。FP16 OOM也正常,7B权重就14G了,加上KV cache和CUDA context,24G确实够呛,int8是对的选择。
这个速度确实不太对劲,10 tokens/s对于7B模型在4090上跑int8来说偏慢了,正常应该能到40-60 tokens/s左右。你说的CPU飙到80%而GPU只有40%利用率,这个信号很明显——瓶颈很可能在CPU侧的数据预处理或者tokenizer上,而不是模型本身。vLLM虽然做了paged attention和连续批处理,但如果输入prompt很长或者并发请求的调度没配好,CPU光在那处理请求排队和采样就能拖死整个流程。建议先检查一下你的--max-num-seqs和--max-num-batched-tokens是不是设得太保守了,默认值有时候并不适合单卡场景。另外FP16 OOM这事,Qwen2.5-7B的权重加KV cache在24G上其实挺紧的,vLLM默认会预分配90%显存做KV cache pool,你可以试试把--gpu-memory-utilization降到0.85左右再跑FP16。还有个容易忽略的点是LoRA adapter有没有合并进基座模型,如果vLLM是动态加载LoRA的话会有额外开销,合并后重新导出再部署会快不少。batch size调大反而更慢也说明调度层面有问题,可能是KV cache不够导致频繁换入换出,把--max-model-len从默认的32768降到4096试试,你领域问答大概率用不到那么长的上下文。
GPU利用率才40%但CPU飙到80%,基本能确定是CPU侧卡住了,跟显存关系不大。你检查下是不是开了--enforce-eager或者关掉了CUDA graph,这俩一关吞吐直接砍半。另外LoRA权重如果没合并进基座,vLLM每次前向都要额外算adapter,batch越大越明显。建议先试--max-num-seqs 1跑单条看纯解码速度,再逐步放开,另外确认下tokenizer是不是每次都在CPU上重复加载。