最近在搞一个法律问答的LoRA微调,基座是Qwen2-7B,用的单卡A100 40G。微调完导出int8量化后,用vLLM部署,结果一启动就报显存不足,峰值直接冲到38G+。我明明已经开了--quantization awq,加载时也设了low_cpu_mem_usage=True,怎么还是这么离谱?
部署7B大模型微调后显存爆了,求大佬看看我的量化配置对不对
全部回复
共 65 条看到你这个问题我第一反应是查了下vLLM的版本,这玩意儿对量化格式的支持差异还挺大的。你指定--quantization awq但有没有确认过模型权重文件里真的包含了AWQ的量化参数?我之前踩过坑,基座模型微调完直接导出int8,但实际存储的scale和zero-point还是fp16的格式,vLLM启动时就会按AWQ去解析,结果内存占用反而比纯fp16还高。可以试试先跑一下model.safetensors的索引文件,看看有没有quantization_config字段,没有的话建议重新用AutoAWQ做量化,别直接用torch的int8接口。另外low_cpu_mem_usage=True只管CPU侧加载,跟GPU显存占用关系不大,真正吃显存的是vLLM的KV cache和页调度,你试试把--gpu-memory-utilization调低到0.8,或者--max-model-len限制到2048,很多情况下是上下文长度没限制住导致预分配显存爆炸。还有个思路,A100 40G跑7B全量其实不紧张,但你微调完的LoRA权重如果没合并回基座,vLLM是不认adapter的,它会把整个模型重新加载一遍,这时候显存反而比纯基座更高。最后建议直接看下nvidia-smi的进程状态,确认是不是有多个进程残留占着显存没释放,这种问题经常是环境没清干净。
试试把gpu_memory_utilization调低到0.8,另外确认下是不是加载了fp16的adapter权重在int8基座上,混着跑显存肯定炸。
量化参数和LoRA权重类型不匹配挺常见的,先检查下配置文件里torch_dtype是不是float16,A100跑7B其实没必要上int8,直接bf16部署反而更稳。
量化配置没问题,但vLLM的AWQ得用对应Qwen2的预量化权重,自己转的经常爆显存。
你这配置看着像是AWQ的权重加载了,但vLLM默认会额外给KV cache预留显存,38G有可能是缓存占了大头。试试启动时加个--max-model-len调低点,或者--gpu-memory-utilization设成0.85,把缓存限制住。另外确认下你导出的int8是不是真的AWQ格式,如果只是普通量化,vLLM不认,还是会按原始FP16加载,那显存肯定爆。我之前也踩过这坑,检查下模型目录里的config.json里有没有quantization_config字段。
这配置看着没啥大问题,但AWQ量化后vLLM的显存占用本来就比GPTQ高不少,尤其你还有LoRA权重没合并。试试先合并LoRA再量化,或者换--quantization gptq,38G峰值基本能压到30G以内。另外low_cpu_mem_usage只管加载不管推理,真正吃显存的是KV cache,你得看下--max-model-len是不是设太高了,默认4096的话直接砍到2048试试。
这配置看着没问题,但vLLM对AWQ支持有时会静默回退到FP16,建议看下启动日志里量化是否真正生效了。
说实话我第一反应是你可能压根没加载对量化权重。AWQ量化不是光靠--quantization awq就能生效的,你得先确认模型路径下真的有awq的权重文件,比如index.json里写了quant_method字段,不然vLLM会默默回退到fp16加载,那显存肯定直接起飞。我之前就踩过这个坑,用GPTQ导出的模型忘了改配置,结果显存占用比原来还高。
另外你提到微调完再导出int8,这个流程本身也有点问题。LoRA微调后的模型权重和量化是两码事,如果你是在微调前的基座上做的AWQ量化,然后直接加载微调后的checkpoint,那量化参数和微调权重就对不上了,推理时等于又走了高精度路径。建议你检查一下是不是在导出时用了merge_and_unload,把LoRA合并进量化模型里,而不是单独加载adapter。
还有low_cpu_mem_usage这个参数其实只影响CPU侧的内存拷贝,对GPU显存没直接帮助。你真正该看的是vLLM的--max-model-len和--gpu-memory-utilization,默认情况下vLLM会预留40%显存做KV cache,你峰值38G很可能就是这预留加上模型本身占用的结果。试着把gpu-memory-utilization调到0.85,max-model-len砍到4096,应该立刻能降下来。
最后问一句,你量化时用的校准集是法律文本还是通用语料?AWQ对校准数据敏感,如果校准集和法律问答分布差太远,量化后权重偏差大,vLLM可能会开启额外的显存冗余来保证精度,这也会推高占用。我之前用领域数据重新校准一次,显存直接少了6个G。
这配置看着有点矛盾啊,你微调用的是LoRA,但导出int8时如果直接对整个模型做量化,LoRA适配器权重可能没被正确合并进去,导致推理时实际加载的还是未量化的原始权重。另外AWQ和int8是两码事,vLLM里--quantization awq对应的是AWQ格式的权重,如果你只是用了transformers的int8量化,那这个参数根本不生效。建议先确认下导出的模型是不是真的AWQ格式,或者试试直接用GPTQ量化再部署,A100对这两种支持都不错。
感觉问题可能出在AWQ量化后的权重类型和vLLM的兼容性上,你导出时用的量化算法和加载时的--quantization awq不一定匹配,建议先确认下模型保存时的config里quantization_config字段。另外low_cpu_mem_usage只管CPU加载阶段,和GPU峰值没什么关系,显存大头很可能被KV cache和激活占掉了,试试调低gpu_memory_utilization或者max_num_seqs。我之前用7B模型时也遇到过类似情况,最后发现是tokenizer里padding导致的额外开销,可以检查下输入长度设置。
看到你这个情况我第一反应是检查一下vLLM的gpu_memory_utilization参数,默认是0.9,A100 40G的话相当于预留36G给模型和KV cache,你峰值38G可能就是这玩意儿搞的鬼。另外你说用了awq量化,但vLLM对AWQ的支持其实挺吃显存的,因为它会把权重解压到fp16做计算,实际省的是显存带宽而不是显存占用,这点很多人容易误解。我之前跑13B的模型用awq,峰值比fp16还高,后来换成gptq或者直接用fp16配kv cache的量化策略才压下来。还有个思路是检查一下你的LoRA是不是合并进基座了,如果没合并,vLLM加载的时候会额外多占一份适配器权重,这个很容易被忽视。你可以先试试把gpu_memory_utilization调到0.7,然后看下nvidia-smi里有没有其他进程占显存,比如之前的微调进程没杀干净。如果还不行,考虑用bitsandbytes的nf4量化,虽然慢一点但部署时显存占用确实低很多,特别是长上下文场景。最后提醒下,Qwen2-7B的attention计算对显存峰值影响很大,你可以把max_num_seqs调小到8或者16,这个参数比量化配置更直接影响启动时的显存分配。
int8和awq是两条路,你这等于没量化,gptq模型配--quantization gptq试试,能压到20G出头。
检查下vLLM版本,老版本对awq支持有坑,换0.4.2+再看,另外gpu_memory_utilization设个0.9试试。
vLLM的KV cache默认会预分配很大一块显存,你38G里可能大半都是它占的,可以试试设--max-num-seqs小一点或者--gpu-memory-utilization降到0.7。另外你微调后直接导出AWQ,有没有确认过量化后的模型结构和原版Qwen2的config完全对齐?有些LoRA权重会残留在量化过程里导致张量尺寸不匹配,vLLM加载时就会疯狂吃显存。我之前碰到过类似情况,后来是先合并LoRA再量化就正常了。
量化配置没问题,但vLLM对AWQ显存优化有限,试试把gpu_memory_utilization调到0.8以下。
vLLM对AWQ的算子优化和HF加载不是一回事,你这配置大概率压根没走量化内核,直接用BF16硬扛了。
说实话我看到这个配置第一反应是awq和int8这俩是不是搞混了,--quantization awq是权重4bit量化,但你前面又写“导出int8量化”,vLLM里这俩走的是完全不同的代码路径,混着来很容易出问题。而且awq量化需要你在微调前或者微调后用专门的校准数据集跑一遍,不是简单导出就完事,校准不充分的话显存占用反而会虚高。
另外low_cpu_mem_usage=True这个参数主要是省CPU内存的,跟GPU显存关系不大,别指望它能帮你压峰值。我怀疑你实际加载的还是fp16版本,因为如果awq真的生效,7B模型在4bit下显存应该能压在8-10G左右,加上KV cache和激活值也不至于到38G。
你不如先检查一下模型路径里有没有真正的awq格式文件,比如model.safetensors是不是4bit的权重,或者直接用lmdeploy的auto_awq跑一遍看看能不能正常启动。还有个坑是vLLM的awq版本跟transformers的量化版本要匹配,不匹配会静默回退到fp16,你可以在启动日志里搜“awq”关键字确认下有没有加载成功。
如果实在不行,先用bitsandbytes的4bit加载试试,那个虽然慢点但显存控制稳定,至少能先跑通业务。另外检查下你的LoRA适配器是不是也量化了,有时候微调权重没合并回基座,推理时两个模型同时驻留显存,那才是真正的隐形杀手。
这问题我之前踩过类似的坑,你导出int8但部署时指定awq,这俩对不上啊。vLLM的awq需要的是awq格式的权重,不是随便int8量化完就能用的,得用对应的量化脚本重新导出。另外low_cpu_mem_usage只管加载,跟显存峰值关系不大。
建议先确认下你导出时用的量化方法,如果用的bitsandbytes,那vLLM得配--quantization bitsandbytes才行。如果真想用awq,得走autoawq重新量化一遍。还有个思路,7B模型int8理论上3-4G权重,39G显存肯定不是权重的问题,大概率是KV cache加激活值没控制好,试试调低max-model-len或者加--gpu-memory-utilization 0.85。
说实话我看到你这个配置第一反应是awq和int8是不是搞混了,你命令行写的--quantization awq但导出的又是int8量化,这俩不是一回事啊。AWQ是4bit权重量化,你如果模型文件本身是8bit的,那vLLM加载时可能根本没走AWQ的kernel,反而把原始权重全塞进显存,峰值自然就炸了。
另外low_cpu_mem_usage那个参数主要管的是CPU内存和加载过程中的临时缓存,跟GPU显存占用关系不大,你开不开它都不影响推理时的显存布局。我建议你先把量化格式统一一下,要么重新用AWQ脚本跑一遍4bit导出,要么就用vLLM原生的--dtype float16配合--max-model-len限制一下上下文长度,7B模型即使fp16也要14G左右权重,加上KV cache和激活,40G卡其实够呛。
还有一个容易踩的坑是vLLM默认会给每个序列预留最大长度的KV cache,你如果没设--gpu-memory-utilization,它可能直接按90%显存去分配,38G就是这么来的。试试设成0.7或者0.8,再配合--enforce-eager关闭图模式,能省不少显存。另外你LoRA微调完的adapter权重有没有合并回基座?如果没合并,部署时得额外加载adapter,那部分显存开销也很可观。
我上次跑类似场景是直接改用GPTQ的4bit,AWQ在某些卡上兼容性确实有点迷,vLLM对GPTQ的支持更成熟一些。你可以先用transformers加载测试一下纯推理的显存占用,排除vLLM本身的调度问题,再回头调部署参数。
vLLM对AWQ支持得挑版本,而且int8导出后权重格式对不对得先确认下,我之前踩过这坑。
你量化配置看着没问题,但vLLM的AWQ得配对应模型权重,光靠参数指定没用,得用llm-awq那个仓库重新转一下。
这配置看着像awq的weights没生效,vLLM对int8和awq的加载逻辑不一样,你命令行里--quantization awq但模型本身是int8导出的,它可能还是按fp16去预分配了KV cache。建议先确认下导出的权重格式是不是真正awq的,或者干脆换成gptq试试,另外把--max-model-len调低到4k看看,38G明显是预分配太狠了。