刚把用LoRA微调好的Qwen2.5-7B接到FastAPI上做本地服务,显卡是4090(24G),加载的是4bit量化版,显存占用才11G左右。但测试单轮对话时发现生成速度只有每秒2-3个token,CPU和GPU利用率都不到30%,感觉不对劲。网上看别人部署同尺寸模型都能到10+ token/s,想问问是哪里出了问题——是FastAPI异步处理没写对吗?还是说量化+LoRA合并后的权重反而拖慢推理?或者需要调vLLM或者TGI这类专用框架?有没有大佬指点下排查方向,万分感谢。
部署7B模型微调API,显存够用但推理速度只有2 token/s正常吗?
全部回复
共 8 条2 token/s确实不太对,我3070跑7B全量微调后都有8-9 token/s,你这个4090加4bit量化肯定有瓶颈。不过我觉得问题大概率不在FastAPI异步上,HTTP那点开销不至于这么夸张,先排除下是不是单次请求里包含了多轮对话历史导致预填充太长,或者max_tokens设得很大让模型一直在生成停止符。
另外你提到显存才11G,但4bit量化7B推理理论峰值应该能到20-30 token/s,CPU和GPU都低利用率这个现象很像数据加载或解码配置卡住了,比如beam search或采样参数里temperature太高导致缓存未命中,也可能是你用了transformers的generate没开flash attention。
我建议你先不用FastAPI,直接写个纯脚本调model.generate压测,看是不是框架层的问题。如果脚本也慢,就查下是否显存碎片化或者paged attention没生效,4090跑4bit的7B其实很适合用vLLM,它能自动做continuous batching,你微调后的LoRA权重也能直接加载,实测能翻好几倍速度。
还有个细节,Qwen2.5的tokenizer对中文切分比较碎,如果输入输出全是中文,实际生成字符数会多于token数,感知上会更慢,但也不至于只有2。你最好把输出时打印的tensor形状和显存计数器贴出来,不然我只能盲猜是量化后dequantize没走GPU算子,或者你用了CPU offload,去看下nvidia-smi里显卡的功耗,如果不到100W那肯定推理没吃满,问题就在内核调度上。
4090跑4bit 7B才2 token/s确实离谱,瓶颈大概率不在显存,而是你FastAPI里同步阻塞了推理线程。试试把模型调用丢到线程池或者用异步路由,另外检查下是不是合并LoRA后没走量化层,纯FP16计算反而更慢。vLLM这种框架对连续批处理优化明显,单轮对话场景提升有限,但可以装一个对比下baseline。先看看nvidia-smi里GPU利用率波动是不是锯齿状,是的话基本就是CPU喂数据跟不上。
这速度肯定不正常,我怀疑是你加载模型时没设好device_map或者生成了CPU算子。4bit量化版在4090上怎么也得跑个15+ token/s,你显存才用11G说明模型可能部分跑在CPU上。先打印一下model.device确认权重都在cuda,然后测下不经过FastAPI直接用模型generate看速度,排除API层问题。大概率不是vLLM的锅,这规模用原生transformers就够了。
2 token/s这个数字让我想起之前踩过的坑,你是不是用transformers的text_generation接口但没开use_cache?LoRA合并后如果没调torch.compile,4bit反量化每步都要重复计算,慢也正常。建议先跑个纯文本生成不接API看原始速度,要是还慢就检查bitsandbytes的版本,新版对Q
FastAPI裸跑确实慢,换vLLM或TGI立马起飞,4bit量化基本不影响速度。
GPU利用率不到30%基本能排除算力瓶颈,大概率是HuggingFace原生推理没做批处理和KV cache优化,单请求跑transformers就这样。另外确认下LoRA是不是merge进基座了,没merge的话每层都要额外算一遍adapter也会拖速度。建议直接换vLLM或TGI,4090上4bit的7B跑个20+ token/s很轻松,FastAPI那层异步写法影响没这么大。
FastAPI单线程跑transformers确实就这速度,换vLLM或TGI立马起飞,别折腾异步了。
FastAPI同步跑生成肯定慢,换vLLM或TGI立马起飞,别折腾量化了。
你这速度确实不太对劲,4090跑4bit的7B怎么也不该只有2 token/s。GPU利用率不到30%基本说明瓶颈不在算力上,大概率是FastAPI那边逐token同步返回或者没开流式,导致每一步都在等Python调度。建议先换vLLM或TGI起个服务对比一下,如果速度立刻上去了,那就是你API层写法的问题,跟量化和LoRA合并没啥关系。
2 token/s确实太离谱了,4090跑4bit的7B怎么也不该是这个数。你GPU利用率不到30%基本能说明瓶颈不在算力上,大概率是请求压根没喂饱显卡,或者中间有什么同步阻塞在卡着。先确认一下你是不是直接用transformers的generate在FastAPI的async函数里同步调用,那样会把event loop堵死,并发测试的时候尤其明显。另外单轮对话如果也是2 token/s,那跟并发关系不大,更可能是没开KV cache、没做batching,或者量化方式有问题。你用的4bit是bitsandbytes还是GPTQ/AWQ?bnb的推理速度本身就偏慢,跟vLLM那种paged attention完全不是一个量级。LoRA合并本身不会拖慢推理,但如果你是在线加载adapter而不是merge进权重,每步都会多一层计算,多少有影响。建议先拿vLLM或TGI直接起服务测一下,同样的模型和量化,速度能到多少,这样能快速定位是框架问题还是环境问题。如果vLLM也慢,那再看是不是驱动、CUDA版本或者电源模式限制功耗了。