最近在搞一个法律问答的LoRA微调,基座是Qwen2-7B-Instruct,微调用的是4bit QLoRA,跑完测试集效果还行。但部署到生产环境时发现推理速度比原版慢了好多——原来大概25 token/s,现在只有12 token/s,显存占用倒是没爆(大概14GB/24GB)。我试过关掉微调权重直接用原版,速度就恢复正常。
目前用的是vLLM加载,gptq量化,max_model_len调到4096。想问问大家:这种情况是不是因为LoRA权重在推理时动态合并导致的额外开销?还是说量化对微调后的权重不友好?有没有什么部署技巧能兼顾速度和效果?真诚求教,谢谢。
部署7B模型微调后推理变慢一半,是量化问题还是显存瓶颈?
全部回复
共 29 条试试用 vLLM 的 LoRA 适配器直接加载,别在推理时动态合并权重,那个 merge 过程每步都要算,确实会拖速度。另外 4bit QLoRA 训完的权重再走 GPTQ 量化,精度损失叠加可能让 kernel 走 fallback 路径,效率自然掉。我之前类似配置换成 AWQ 或者直接 FP16 推理,速度能回来不少。
你这个问题我也踩过坑,基本可以确定是LoRA权重没合并就直接上vLLM导致的。vLLM的gptq量化加载的是你合并前的基座权重,而LoRA adapter是在推理时动态挂上去算的,每层都要额外做一次低秩矩阵乘法,7B模型几十层下来开销相当可观,速度掉一半很正常。另外还有个隐藏问题:4bit QLoRA训练完的adapter如果直接merge进gptq量化权重,精度损失会比较大,因为量化误差和LoRA增量叠加了,所以很多人发现效果和速度两头不讨好。建议你先把LoRA merge回fp16基座,然后用GPTQ或AWQ重新量化一遍再部署,这样vLLM就能走纯量化推理路径,速度应该能回到20+ token/s。如果不想重新量化,也可以试试用vLLM的LoRA支持但开enable_lora并限制max_lora_rank,不过增益有限。实在追求速度的话,考虑换AWQ量化,对微调权重的友好度比gptq好一些。
你这个问题其实挺典型的,我也踩过类似的坑。先排除一个可能性:你关掉LoRA权重就恢复正常,说明瓶颈大概率不在vLLM本身,而是LoRA合并到基座后带来的额外计算图变化。4bit QLoRA训练完的权重在推理时如果还是走动态合并路径,每次forward都要做一次adapter的矩阵乘加,7B模型在4096长度下这个开销确实能吃掉将近一半吞吐。而且gptq量化对LoRA微调后的权重分布不一定友好,量化误差会让某些层的激活值范围变大,vLLM可能被迫回退到更慢的kernel。你可以试试把LoRA权重离线合并进基座再用gptq重新量化一遍,或者换成AWQ量化,对微调权重的鲁棒性通常好一些。另外检查下vLLM的enable_lora参数是不是开着,如果只是为了部署单任务,合并后直接关掉LoRA加载能省不少调度开销。还有一个容易忽略的点是max_model_len设4096但实际请求平均长度可能短很多,KV cache预分配策略也会影响速度,试试调小block_size或者开chunked prefill。
我之前也踩过类似的坑,QLoRA训完的权重直接拿vLLM跑确实会慢,尤其是LoRA没合并的时候。你试试先把LoRA merge到基座模型里,再重新量化一遍,别用训练时的4bit权重直接推。另外gptq对微调后权重的校准挺敏感的,推荐换成awq或者fp8试试。14G显存其实挺宽裕的,max_model_len也可以适当降一点。
你提到关掉LoRA权重速度就正常,那基本能锁定是合并那步在拖后腿。vLLM如果没提前把LoRA merge进基座权重,每次forward都要额外算一遍低秩矩阵,7B模型上这个开销挺明显的。建议部署前先做merge_and_unload导出完整权重,再重新量化成GPTQ,别在推理时动态挂LoRA。另外4bit QLoRA微调后的权重直接走GPTQ,量化误差可能比原版大,可以对比下AWQ或者FP8看速度掉得是不是一样。
试试把LoRA权重合并回基座再重新量化,动态合并确实会拖速度,vLLM也不一定吃得消。
你这个情况大概率不是显存瓶颈,14GB/24GB还有不少余量呢。我怀疑问题出在LoRA权重合并这块——你用vLLM加载gptq量化的基座,再挂LoRA adapter的时候,它可能每次forward都要做动态合并或者额外的矩阵运算,这个开销在7B模型上确实能拖慢一倍。而且4bit QLoRA微调出来的adapter,跟gptq量化的基座权重合并时,精度对齐也可能有坑,vLLM内部未必走的是最优路径。建议你试试用peft先把LoRA merge进基座,再重新做gptq量化导出成一个完整的量化模型,这样推理时就没有adapter的动态开销了。另外max_model_len 4096如果实际请求没这么长,也可以调小一点,KV cache能省一些调度开销。如果效果掉得不多,直接merge后量化部署应该是目前最稳的方案。
试试把LoRA权重合并进基座再量化,动态合并确实会拖速度。
你这个问题挺典型的,我之前也踩过。QLoRA微调后权重分布变了,再用gptq量化精度损失会放大,vLLM里LoRA动态合并确实会拖速度。可以试试把LoRA权重合并进基座后重新量化导出,或者直接用AWQ替代gptq,对微调后权重更友好些。另外max_model_len降到2048先测测,有时候KV cache开销比你想的大。