最近在搞一个内部知识库问答的demo,用的Qwen2-7B,用LoRA微调后想部署成API服务给测试组用。单卡A100 40G,用vLLM加载AWQ量化后的模型,跑单轮对话没问题,但一旦并发超过3个请求,或者输入上下文超过2K,就疯狂OOM报错。试过GPTQ和FP16,反而更吃显存。看网上说7B模型4bit量化后只需要8G显存,但我实测光权重就占了11G,KV cache一开再乘个4并发直接爆。想问下是我量化参数没设对(比如group_size、sym这些),还是说7B模型做服务端部署本来就得预留20G以上?另外,有没有办法在vLLM里动态调整KV cache的显存上限?求有实战经验的老哥指点一下,孩子已经被OOM折磨两天了。
部署7B模型微调API总OOM,是量化方案不对还是显存规划有问题?
全部回复
共 50 条你这情况我上周刚踩过坑,7B AWQ实际峰值就是比理论值高不少,正常留个16G才稳。group_size=128比64省显存但掉点精度,sym开不开影响不大。vLLM里设--kv-cache-dtype=fp8_e5m2能省一半,或者直接--max-num-seqs=2限制并发,比调KV上限实在。另外建议换flash-attn的BF16版本,有时候比量化还稳。
A100 40G跑7B还爆,大概率是KV cache的预留策略问题,vLLM默认会按最大并发和max_model_len预先分配显存,你试试--max-num-seqs改成4,--max-model-len压到2048,再把gpu_memory_utilization设到0.9,应该能缓解。另外AWQ的group_size最好用128,sym开不开影响不大,但权重11G说明你量化完没做weight packing,重新转一下格式能省不少。
还有你提的动态调整KV cache,vLLM其实支持--kv-cache-dtype和swap space,但并发上去还是会涨,不如直接限制max_model_len和max-num-seqs来得实在。我自己的经验是7B服务端至少留16-18G给权重和激活,剩下的再分给KV cache,别信8G那套说法,那是纯推理不加载tokenizer和CUDA context的理想值。
网上说的8G显存基本都是纯权重+单并发+短上下文的理想值,你实测11G权重其实正常,AWQ的group_size开到128、sym开true能压一点但有限,别太指望。vLLM里OOM主要还是KV cache的预分配策略,可以试试设--max-num-seqs和--gpu-memory-utilization,比如后者调到0.8,再配合--max-model-len把上下文限到2048,并发高时让vLLM自动排队而不是硬挤。你这场景其实更建议上量化+投机采样或者直接换Qwen2-1.5B做蒸馏,7B服务端部署给测试组真没必要死磕。
vLLM默认KV cache预留太多,试试--gpu-memory-utilization调低到0.6,4并发2K应该稳。
实测过类似配置,7B AWQ权重11G其实正常,官方宣传的8G是纯推理不跑微调服务的理想值,你还要算上CUDA context和fragmentation。KV cache别手动调上限,vLLM默认gpu_memory_utilization设0.9就够,你试试把--max-num-seqs降到2,或者给每个请求设max_tokens小一点,能缓解很多。另外LoRA微调后的模型合并回base再量化,比直接量化adapter权重省显存,你可以重新走一遍流程。
7B AWQ实际跑起来11G很正常,网上说的8G是纯权重不包含CUDA context和激活值,你按20G预留没毛病。vLLM里可以设置--kv-cache-dtype和--max-num-seqs,但更直接的是把--gpu-memory-utilization调到0.85以下,给临时峰值留点缓冲。你并发3个加2K上下文就爆,估计是max-model-len设太大,可以按实际最长输入+输出算一下,别让vLLM按默认4K预留。另外group_size=128和sym=True对显存影响不大,主要看量化后每层的内存布局,没必要太纠结这个。
8G显存是单次推理的静态值,服务端并发和KV cache才是大头,vLLM里设--kv-cache-dtype和--max-num-seqs能控制上限。
试试把max-num-seqs调小到4以下,vLLM默认预分配显存太激进了,KV cache设个4G上限就稳了。
实测过同款组合,A100 40G跑7B AWQ,并发3+2K上下文确实紧巴巴的,但问题多半不在量化参数,而是vLLM默认把KV cache预分配太狠了。你可以在启动命令里加--kv-cache-dtype fp8或者手动调--gpu-memory-utilization到0.8左右,再配合--max-num-seqs限制并发数,能压出不少空间。另外group_size和sym对显存影响其实很小,主要影响精度,建议先别折腾量化了。真要高并发,不如直接上Qwen2-1.5B或者把LoRA合并后转成FP8,比死磕7B舒服多了。
说实话7B部署到40G A100还能OOM基本不是量化的问题,AWQ 11G权重正常,你多半是没限制KV cache的预留显存。vLLM里设--kv-cache-dtype fp8或者--gpu-memory-utilization 0.7试试,别让它默认吃满。另外并发3个就爆有点不正常,你检查下是不是max-model-len设太大,比如默认8K但实际只用到2K,显存全被预留给长序列了。动态调整的话,最新vLLM支持--enable-prefix-caching,但没法实时改上限,只能改配置重启。
说实话你踩的坑我基本都踩过一遍,7B模型4bit量化后标称8G那是纯权重+单条短序列的理论值,实际部署光CUDA context、激活值、还有vLLM的paged memory这些杂七杂八加起来,40G卡上跑满并发就是很紧张。你测的11G权重其实挺正常的,group_size=128和sym=True是AWQ默认配置,别乱调,调小了反而显存涨得更快。KV cache这块儿才是大头,vLLM里有个--kv-cache-dtype和--max-num-seqs参数,但更直接的是设--gpu-memory-utilization,我实测0.85左右比较稳,再高就容易和权重抢显存,导致你这种偶发OOM。另外你输入2K+4并发就爆,大概率是max_model_len设太高了,把max_seq_len_to_capture调小,或者干脆限制单请求最大token数。我自己的方案是量化用AWQ不动,但把vLLM的--max-num-seqs设成4,--max-model-len设成2048,然后用--swap-space让部分旧KV cache落到CPU内存,虽然会慢一点但至少不崩。还有个偏门招,把LoRA合并回base模型再量化,比在adapter状态下部署省不少显存,你试试看是不是这个原因。最后提醒一句,别光看权重占用,nvidia-smi里那些non-volatile memory才是真实峰值,拿nvitop看每块内存分配会更清楚。
8G显存那个说法是纯推理单样本的理想值,你还要算上LoRA合并后的权重碎片和CUDA context,11G挺正常的。vLLM的KV cache确实能设,启动参数加--max-num-seqs和--gpu-memory-utilization,但建议你直接把并发降下来,或者上张4090组张量并行,A100 40G跑7B并发本来就很勉强。
另外你group_size设128的话,AWQ实际占用会比8G高不少,试试256或者关掉sym,但别指望质变。真要在40G上稳定服务,建议把max-model-len压到2048,再加个--enforce-eager,能省不少显存碎片。
8G显存那个说法太理想了,实际跑起来光CUDA context和碎片就得吃好几个G,你11G的权重已经算正常了。试试在vLLM里设--kv-cache-dtype=fp8,或者直接调--max-num-seqs限制并发数,比硬调KV cache上限靠谱。另外检查下AWQ的group size是不是128,如果用的32会明显增加显存占用。
网上说的8G显存基本都是纯权重或者单请求的理想值,实际部署要算上KV cache和运行时开销,你这4并发加2K上下文,20G起步真不夸张。我建议你试试在vLLM启动时用--kv-cache-dtype和--max-num-seqs参数手动控一下,或者干脆限制max-model-len到1K,把并发调到2,先稳定跑起来再说。gptq那套我用着也感觉冗余比awq大,group_size设128、sym开true算是比较省显存的配置了,可以确认下有没有生效。最后,如果测试组只是内部用,其实没必要上vLLM,fastapi加transformers的流式接口,配合显存回收,可能反而更稳。
实测过同配置,8G显存是纯权重不跑推理的理想值,实际部署预留15G起步才稳。vLLM里设gpu_memory_utilization=0.85,再给max_num_seqs限制并发试试。
7B AWQ实际跑起来显存占用比理论值高太正常了,你那个8G是纯权重理想值,没算激活和KV cache。我这边之前用4bit跑过类似的,把max-model-len砍到2048,gpu-memory-utilization设个0.85,并发就能稳在4路左右。另外group_size其实对显存影响不大,主要看KV cache那头,vLLM里可以用--kv-cache-dtype fp8试试,能省不少。你那个11G权重是不是因为seqlen设太大导致中间激活爆了?建议先看下nvidia-smi里到底是权重还是缓存占大头。
实测7B上生产至少得留16G,你那11G权重加并发KV cache肯定爆,vLLM里设gpu_memory_utilization到0.85试试。
实测过类似配置,7B AWQ权重加KV cache并发3个就得预留14G+,你开gpu_memory_utilization到0.9试试,不行就砍max_num_seqs。
调group_size不如直接看vLLM的--kv-cache-dtype,改成fp8能省不少,但长上下文还是得靠限制max-model-len。
这问题我太有同感了,之前用7B模型做服务也踩过一模一样的坑。先说结论:你光看权重11G其实挺正常,AWQ的4bit省的是权重的内存,但激活值、KV cache、还有vLLM的显存碎片化全得算进去,网上说8G那是纯推理不加并发和长上下文的理想值。我实测下来,7B模型要稳定服务并发,20G打底真不是夸张,A100 40G单卡其实刚好卡在及格线上。你那个group_size和sym设的多少?我试过group_size=128比64能省不少显存,但推理速度会略降,值得权衡一下。关于KV cache管理,vLLM有个--max-num-seqs参数可以限制同时处理的序列数,还有--gpu-memory-utilization(默认0.9)可以调低给KV cache留出更保守的空间,但代价是并发上限更低。不过你既然用了LoRA微调,建议检查下是不是微调时叠加的adapter权重也被加载进显存了,这个经常被忽略。另外OOM如果发生在请求高峰期,可以试试开vLLM的--enable-prefix-caching,对知识库这种重复前缀比较多的场景能省下不少KV cache。最后想问下你用的AWQ版本和校准数据集是啥?我之前换了个更贴合业务数据的校准集,量化后显存占用直接掉了1G多,这玩意儿还真不是随便跑跑就完事的。
8G显存是纯权重,你漏算了KV cache和激活,7B部署至少15G起步,vLLM设下gpu_memory_utilization试试。