最近在搞一个内部知识库问答的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,是量化方案不对还是显存规划有问题?
全部回复
共 65 条8G显存那个说法太理想了,实际跑服务还得算上CUDA context和调度开销。你试试在vLLM里设--kv-cache-dtype=fp8_e5m2,能省不少,再配合--max-num-seqs把并发限制调小点,先跑通再往上加。另外group_size=128和sym=True对内存影响不大,主要是激活值和中间buffer在吃显存。
我上次用7B也踩过这坑,最后把max-model-len压到2048,并发砍到2才稳住。你那个2K上下文爆掉,八成是prefill阶段临时张量没释放干净,可以在vLLM里开--enable-prefix-caching试试,对重复问句的缓存效果挺明显的。
最好还是先盯一下nvidia-smi看是哪个阶段峰值涨上去的,别光盯着权重占用。
说实话你这个问题我太有共鸣了,之前用7B模型做服务端也踩过一模一样的坑。你看到的“4bit只要8G显存”那是纯权重不跑推理的理想值,实测光是激活值、临时buffer和CUDA context就能吃掉好几个G,再加上你开了并发和长上下文,OOM太正常了。我后来排查发现,vLLM默认的KV cache预留比例是90%,虽然看着很激进,但实际分配是按最大序列长度乘并发数来算的,你设个max-num-seqs=3再把max-model-len缩到2048,可能比调量化参数管用得多。group_size和sym对显存影响其实很小,主要影响精度,AWQ你至少把group_size设128,sym开true,不然量化损失会大。另外你试试vLLM的--kv-cache-dtype fp8,A100支持的话能省不少,但得看你的CUDA版本。要是还爆,干脆给每个请求单独一个进程池,用FastAPI挂多worker,虽然慢点但稳定,内部demo够用了。
7B模型AWQ光权重11G其实挺正常的,8G那是纯理论值没算上额外开销和CUDA context。你试试在vLLM启动参数里设--max-num-seqs 2或者调低--gpu-memory-utilization到0.7,能缓解不少。另外KV cache确实得按最大并发预留,动态调整目前只能靠这个百分比参数,没法单请求动态分配。你要是非得上4并发,建议换8B以下或者直接上量化到2bit试试,不过质量会掉。
说实话你这个问题我上周刚踩过,7B量化后8G显存是纯权重+单请求的理想值,实际部署光CUDA context和激活就得吃掉5-6G,4并发直接超20G很正常。建议先试下vLLM的--kv-cache-dtype fp8,能省不少,再把--max-num-seqs调小到2,配合--gpu-memory-utilization 0.85,至少能稳一点。另外group_size设128比64更省显存,sym开不开对vLLM影响不大,但AWQ的packing方式确实比GPTQ稳。你不如直接上量化+分块KV cache,或者干脆换Qwen2-7B-Instruct的AWQ官方权重,社区调好的参数比自己瞎折腾强。
同款配置踩过坑,A100 40G跑7B AWQ本来就不是8G能解决的,网上那个数字是纯权重不跑推理的实验室数据,你实测11G才是真实情况。group_size和sym对显存影响其实不大,主要差别在推理速度,真正吃显存的是激活值和KV cache,4并发加2K上下文这俩加起来轻松破15G。建议先查一下vLLM的gpu_memory_utilization参数,默认0.9太激进了,直接设成0.7给KV cache留点余量,OOM会明显减少。另外可以试试把max_num_seqs调小到2,配合连续批处理,感觉你现在的瓶颈是显存碎片化而不是总容量不够。动态调整KV cache上限vLLM有--kv-cache-dtype和--max-num-batched-tokens参数,但得先确认你用的版本支持,我试过0.4.2版本里改这两个值能缓解,但并发高了还是会抖。最后建议如果测试组不是必须实时响应,干脆部署时限制最大并发数,或者把输入截断到1.5K,比折腾量化实在多了。
说实话你这个情况我踩过一模一样的坑,7B量化后光权重确实不止8G,还得算上激活值和临时buffer,网上那些数字都是纯理论值。我后来发现group_size设128比32省显存但掉点精度,sym开不开倒影响不大,你可以先试group_size=128+AWQ。vLLM里可以设--kv-cache-dtype和--max-num-seqs来限制并发,但更关键的是把--gpu-memory-utilization调到0.85,给前向计算留点余量。另外建议你查下是不是max-model-len设太高了,默认可能吃掉大量KV cache预算,砍到2048试试,反正demo阶段长上下文需求不多。
8G那是纯权重的理论值,实际部署KV cache和并发都得算进去,你这配置至少得留16G给推理。
vLLM里设gpu_memory_utilization到0.85,再调下max_num_seqs,能把并发OOM缓解不少。
你这情况太典型了,7B量化后权重8G是理论值,实际得算上act order和KV cache,vLLM默认会预留显存池,并发一上来直接炸很正常。我试过把gpu_memory_utilization调到0.85,再配合--max-num-seqs限制并发,能缓解不少,但上下文一长还是得砍max-model-len。建议你直接看下vLLM的--kv-cache-dtype,换成fp8能省一小块,但别指望质变,7B服务端部署预留20G真不夸张。
说实话你这情况我太熟了,之前用7B模型做rag服务也踩过一模一样的坑,光看权重占用确实容易误判,但实际跑起来才知道kv cache才是大头,尤其并发一上来,显存直接成指数级消耗。你那个4bit后8G显存的说法,多半是纯推理、单并发、短上下文的理想值,跟生产环境完全是两码事,建议直接按20G预算来规划。量化参数那块,group_size设128、sym开不开其实对显存影响不大,主要影响的是精度,你OOM的根源还是显存分配没做隔离。vLLM里有个gpu_memory_utilization参数,可以手动调低,比如设成0.85,然后配合max_num_seqs和max_model_len一起限制,别让模型把显存全占了,给kv cache留点余地。另外你提到并发3个就爆,我怀疑是max_num_seqs默认值开太大了,vLLM为了吞吐会一次性预留所有序列的kv cache,这比你想的吃显存多了。还有个野路子,如果你测试组只是内部用,可以试试把vLLM的continuous batching关掉,或者干脆用fastapi自己包一层推理逻辑,手动控制并发数,虽然吞吐低点但稳。最后问下,你AWQ的calibration数据集是用的官方默认还是自己根据知识库语料重新做的?这个对量化后的实际占用和显存碎片也有影响,我之前换了校准集后OOM频率明显少了。
8G显存那个说法是纯推理单batch的纸面数据,你还要算上LoRA adapter、激活值和KV cache,7B部署服务端预留20G以上是常态,别被那些测评忽悠了。group_size设128、sym开True能压一点,但治标不治本。vLLM里可以设--kv-cache-dtype和--max-num-seqs,或者干脆用--gpu-memory-utilization限制到0.85,留出余量给并发。另外建议你查一下是不是多轮对话历史没截断,2K上下文对7B来说确实容易爆,加个prompt长度裁剪比调量化更见效。
这问题我前段时间正好踩过一模一样的坑,A100 40G跑7B AWQ,单请求看着内存占用才12G左右,结果一压并发直接给你表演原地爆炸。网上说的8G显存基本是纯权重+单轮推理的理想值,根本没算KV cache和激活值,实际部署4并发加2K上下文,20G往上才是常态。你那个group_size设128还是32,sym开不开,对显存影响其实没想象中大,主要大头还是vLLM默认会给每个request预留最大context长度的KV cache,你试下在启动参数里加--max-model-len 4096或者更低,再配上--gpu-memory-utilization 0.85,能把显存上限锁死。另外动态调整KV cache目前vLLM没有直接暴露API,但你可以用--kv-cache-dtype fp8试试,或者干脆把调度策略改成--swap-space小一点,让部分KV缓存走CPU。还有个野路子,把并发限制改成3,但每个请求的max_tokens调低,实测对测试组来说响应体量够用就行。最后提醒下,LoRA微调过的模型注意看下adapter权重有没有被vLLM正确加载,有时候adapter没生效,模型实际还是全量计算,显存直接翻倍。
这问题我当初调7B的时候也踩过一模一样的坑,当时甚至怀疑是显卡坏了。先说结论,你看到网上说的8G显存跑4bit大概率是纯推理、单并发、短上下文的极限数据,实际部署到服务端,尤其带LoRA合并权重之后,峰值显存真的得按20G往上规划,这点你实测很准。量化参数group_size和sym确实会影响显存占用,但更关键的是vLLM的KV cache默认会预分配大量显存,你并发一上来它直接吃满,建议先检查一下--kv-cache-dtype和--max-num-seqs这些参数,别让它自动分配。还有个土办法,把vLLM的gpu_memory_utilization调低到0.7左右,留出余量给动态调度,但会牺牲一点吞吐。另外你试过AWQ的--zero-point和--group-size组合没,我后来发现用128的group_size加sym=True能比默认的256省出大概1.5G,虽然推理速度稍微慢点。最后,如果测试组只是内部用,不如直接限制max-input-length和max-concurrency,或者干脆换Qwen2-1.5B的量化版,7B做并发服务确实有点勉强了。
说实话你这个问题我去年也踩过一模一样的坑,A100 40G跑7B量化后并发一高就OOM,最后发现根本不是量化方案的问题,是vLLM默认把KV cache预留得太狠了。你那个11G权重其实正常,AWQ的group_size=128和sym=True基本就是最优解了,换参数省不出几个G,关键是vLLM的gpu_memory_utilization参数,默认0.9直接给KV cache留了太多,我调到0.75然后配合--max-num-seqs 4,并发3到4个就没再爆过。另外你说2K上下文就挂,大概率是--max-model-len设太高了,vLLM会按最大长度预分配KV cache,你把它改成2048甚至1024,能省出一大块显存。不过动态调整KV cache上限这功能vLLM目前还没做,只能靠调启动参数或者用--swap-space把一部分换到CPU内存,但那样会拖慢速度。还有个小技巧,如果你用AWQ,可以试试--quantization awq_marlin,这个kernel比默认的省显存还快一点,我实测能多撑一个并发。最后还是得说,7B做服务端预留15到20G是常态,别信网上那些8G跑7B的截图,那都是单请求单轮demo,生产环境完全两个世界。
你这情况我上周刚踩过坑,7B AWQ实际吃显存确实比理论值高不少,因为除了权重还有激活值和KV cache的额外开销。建议先把gpu_memory_utilization调到0.9,然后vLLM里设--max-num-seqs 4和--max-model-len 2048,把并发和上下文长度锁死再测。另外group_size别用128,换成64能再压一点,但效果有限,说实话7B做服务端想稳并发,20G预留是底线。
如果你非要在40G卡上跑,试试把KV cache换成PagedAttention的默认策略,或者用--kv-cache-dtype fp8,能省不少。不过我最后是直接换4bit的Qwen2-7B-Instruct量化版,配合vLLM的continuous batching,3并发加2K上下文才算稳住。
40G都爆说明不是量化问题,vLLM里--kv-cache-dtype选fp8能省一半,再把gpu_memory_utilization调到0.9试试。
7B模型4bit量化后8G显存那个说法太理想了,实际跑服务还得算上KV cache和推理框架的开销,11G权重加并发爆掉很正常。你试试vLLM的--kv-cache-dtype和--max-num-seqs参数,把并发数限制到2,再把KV cache预留调小点,能缓解一些。另外group_size别用128,改成64能省点显存,但精度会有轻微损失,得自己权衡。
说实话你这情况挺典型的,7B量化后权重8G是纯理论值,实际加载还有额外开销,加上KV cache和激活值,20G打底真不夸张。我建议你先把vLLM的gpu_memory_utilization调到0.85,然后手动设max_num_seqs限制并发,比死磕量化参数实在。另外group_size别乱调,128是主流,sym=True能省点显存但效果略降,你这个场景优先保稳定吧。
巧了,最近我也在折腾7B部署,不过用的是8卡3090,印象里AWQ 4bit的权重应该在4.5G左右,你光权重占11G肯定不正常,八成是量化时group_size没调对或者校准数据集太小导致某些层没压下去。另外vLLM默认会预分配大概90%的显存给KV cache,40G卡上就是36G,你并发一高或者上下文一长,它跟权重抢显存可不就炸了——试试--kv-cache-dtype fp8或者手动调低gpu_memory_utilization到0.7,给torch和cuda context留点余量。说到上下文2K就爆,检查下是不是prompt里带了太多历史消息没做截断,LoRA微调后模型对长上下文的attention计算开销会明显涨,建议把max-model-len限制在2048以内,再用vLLM的continuous batching配合--max-num-seqs做动态调度。group_size我倒建议直接128别动,sym开true会稳一点,但核心问题还是你显存规划太紧了——7B服务端部署想稳跑8并发+4K上下文,40G卡真得预留25G以上,不然就得上PagedAttention的--enable-prefix-caching或者考虑把模型切成两半用tensor parallel。动态调KV cache上限vLLM目前没有运行时接口,只能启动前定好,不过可以试试--swap-space加CPU offload来兜底,虽然慢点但不会OOM。你实测过量化后每token的显存占用吗?我怀疑你KV cache是按fp16算的,AWQ下可以开fp8缓存能省一半,官方文档里有示例,改一行config就行。
说实话你这情况我遇到过,7B量化后8G显存是纯权重理论值,实际跑服务还得算上激活值和KV cache,尤其LoRA微调过的模型,中间层状态会额外吃不少。我自己试下来,40G卡给7B留个24G左右才稳,剩下留给动态KV cache,vLLM里用--kv-cache-dtype和--gpu-memory-utilization调个0.85,再配个max-num-seqs限制并发,基本能缓过来。另外你group_size设128的话,显存会比256多占一点但推理速度更快,看你取舍了。
感觉你主要卡在并发和长上下文同时压上来了,KV cache这玩意是跟序列长度和并发数线性增长的,40G卡其实很尴尬,跑7B加长上下文就是会爆。我一般用AWQ配vllm的--max-model-len强制砍到2048,再设--max-num-seqs=4,同时把--swap-space设小点,这样虽然会丢点长文本能力,但至少不会动不动OOM。你那个11G权重我看挺正常的,别信网上那些极限数字,人家可能用的纯推理没带微调层。
量化方案本身问题不大,AWQ在7B上比GPTQ稳多了,但你这OOM更像是vLLM的显存分配策略没
8G那个是纯权重占用,你把激活和KV cache算上肯定不止,我跑过类似配置,实际预留20G以上才稳。你试试在vLLM里设--kv-cache-dtype fp8,或者手动限制--max-num-seqs和--max-model-len,别让KV cache无限涨,另外group_size调128通常能压一点显存,但别指望质变。好奇你LoRA合入后有没有重新量化,没做的话权重碎片化也挺吃显存的。