最近想把自己微调过的Qwen2.5-7B部署到公司服务器上做API服务,看了N种量化方案,但显存占用算来算去总是跟实际有出入。比如我按公式算INT4量化后大概5-6G显存,结果一跑起来直接OOM了。后来发现上下文长度和batch size也占显存,但不知道具体怎么估算。还有那种多卡部署的方案,用vLLM还是TGI好?有没有老哥分享下实际踩坑经验?我主要是做文本摘要,QPS要求不高但延迟要低,现在被显存和框架选择卡住了,求指点。
部署开源大模型到生产环境,显存到底怎么算才靠谱?
全部回复
共 172 条说实话你这情况我太熟了,公式算出来的只是权重本身,漏掉的KV cache和中间激活才是杀手。我上次部署7B模型,SEQ长度撑到2048,batch size调成4,光KV cache就多吃掉2G多,你那个5-6G的估算肯定没算这些动态内存。建议你直接用vLLM,它自带PagedAttention能把KV cache管理得比较精细,而且能动态调整max seq len和max batch tokens,比TGI在显存控制上直观多了。另外文本摘要这个场景,QPS不高的话可以试试把模型量化到AWQ或者GPTQ 4bit,但注意别用动态量化,静态量化在低延迟下更稳。还有个坑是HuggingFace的tokenizer也会占显存,虽然不大但积少成多,你跑OOM可能还跟CUDA memory碎片有关,建议设下PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True再试。多卡的话优先考虑张量并行,vLLM支持TP分片,但7B规模其实单卡32G就能搞定,没必要上多卡徒增通信延迟。
你这情况太真实了,公式算出来的显存基本只覆盖权重,KV cache和激活值才是隐形杀手,尤其文本摘要输入输出都长,7B模型INT4实际跑起来8-9G都是常态。建议直接用vLLM,它对显存管理比TGI激进不少,而且支持continuous batching,你QPS不高但延迟敏感的话,把max_num_seqs调小点能压低首token延迟。另外多卡部署别用张量并行,7B模型单卡能塞下就别拆,跨卡通信延迟对低延迟场景很不划算。
显存这事儿我踩过一样的坑,光算权重没用,KV cache才是大头,尤其你摘要场景文本长,7B的INT4实际得按8-9G去留才稳。vLLM的话显存控制更细,PagedAttention能省不少,TGI上手快但长文本容易爆。建议直接上vLLM,开gpu-memory-utilization到0.9,batch设小点,延迟和显存都能兼顾,别迷信量化公式。
显存这块我踩过一样的坑,公式算的只是权重,KV cache才是大头,尤其你摘要场景上下文一长直接翻倍。建议用vLLM的--max-model-len限制上下文长度,再把gpu_memory_utilization设到0.9,实测比TGI省心很多。另外7B模型不用急着上多卡,单卡A10或者4090用AWQ量化基本够跑,延迟还更低。你QPS不高的话,干脆把batch size锁死1,还能再省一截。
别光看量化后的权重,你算算KV cache:7B模型每token大概要0.5-1MB,上下文2048就是1-2G,加上激活值,INT4稳定得8G起步。框架我推荐vLLM,PagedAttention对显存碎片处理得好,而且开--enable-prefix-caching能复用摘要的公共前缀,延迟直接降一半。多卡除非单卡塞不下,否则别上,通信开销在低QPS下不值当。
你这情况我建议直接上8G显存的卡,别卡着5-6G算。INT4权重确实5G左右,但vLLM默认预分配40%显存给KV cache,你上下文长的话直接爆。实测把--max-num-seqs调小,比如4,再配--block-size 16,
显存这坑我太懂了,INT4理论值跟实际跑起来差2-3G很正常,KV cache和激活值才是大头。你文本摘要场景的话,建议把max_length锁死在512或768,batch size固定1,这样显存能压下来不少,vLLM配PagedAttention对长上下文友好些,但TGI的continuous batching在低QPS下延迟更稳,可以都试试。另外多卡部署优先看张量并行而不是数据并行,Qwen2.5-7B两卡应该够,但记得把中间层的激活值也估算进去,别光盯着权重。
vLLM吃显存比想象中狠,你这场景直接上AWQ量化加8K上下文,batch设1保准稳。
显存估算这事儿我太有同感了,公式算出来的数永远只是“模型权重”的账,实际一跑全是隐藏开销。你那个INT4算5-6G,大概率是没算上KV cache和激活值,7B模型就算4bit,上下文拉到4K、batch size到8,KV cache轻轻松松吃掉2-3G,再加上CUDA context和碎片,OOM太正常了。建议你直接按“权重+1.5倍上下文长度×层数×隐藏维度×2字节”粗算KV cache,然后再加2G冗余,这个公式比网上那些花里胡哨的准得多。
至于vLLM和TGI,我两个都试过,文本摘要这种场景vLLM的continuous batching优势特别明显,延迟和吞吐都比TGI稳,但前提是你得把gpu_memory_utilization参数调好,别默认值0.9,我一般设0.7-0.75,留点余量给碎片和临时张量。TGI对HuggingFace生态兼容性更好,但长上下文下显存管理不如vLLM激进。
多卡部署的话,如果只是单卡放不下,优先看张量并行,vLLM对TP支持很成熟,不过要注意跨卡通信开销,小batch下可能反而比单卡慢。你QPS不高但延迟要低,我建议先试单卡INT4+4K上下文+静态batch=1,把显存压到极限,如果还是OOM再上双卡TP,别一上来就上多卡,调度复杂度翻倍。
最后提醒一下,你微调过的模型可能加了adapter,加载时记得把adapter的权重也计入显存,很多人栽在这。可以先写个脚本打印torch.cuda.max_memory_allocated看峰值,比猜靠谱多了。
显存这块儿我之前也算翻车过,INT4理论值只是模型权重,KV cache和activation才是大头,尤其你摘要场景上下文长的话,建议直接用vLLM的--kv-cache-dtype fp8或者EVA,能省不少,另外别迷信TGI,vLLM对Qwen系支持更稳,延迟也低一些。多卡的话优先张量并行,但注意7B其实单卡A10或者4090就够,先量化到AWQ再试,别一上来就INT4,精度掉太多反而影响摘要质量。
显存大头其实在KV cache,序列长度和并发一起来就暴涨,建议直接按峰值预留20%冗余再算。
我之前也踩过这个坑,公式算的只是权重显存,KV cache那块特别容易忽略,尤其是长文本摘要场景,8k上下文和2k差出来的显存能翻倍。建议你先用transformers的profile函数实测一下峰值,或者直接在vLLM里设个max-model-len跑个样例看看。框架的话我倾向vLLM,吞吐和显存控制比TGI稳不少,但你要低延迟的话,注意下continuous batching的batch size别调太大,实测对首token延迟影响挺明显的。
显存这块我踩过类似的坑,公式只算权重确实不够,KV cache才是大头,尤其长文本摘要动不动就2k+上下文。我后来直接用vLLM的--max-model-len和--gpu-memory-utilization参数调,先跑个压力测试看峰值再定batch,比手算靠谱。框架的话你这场景我站vLLM,TGI的continuous batching在低并发下延迟优势不明显,vLLM的paged attention省显存更实在。另外建议把微调过的模型先用AWQ量化试试,比GPTQ在7B上稳定不少,OOM多半是量化后精度损失导致激活值异常。
显存大头其实在KV cache,7B模型INT4权重才4G出头,但上下文一长直接翻倍,建议先按max_seq_len算下KV再考虑量化。
vLLM对低延迟场景更稳,TGI在长文本上吃点亏,但多卡记得开parallelism别让显存碎片化。
显存大头确实在KV cache和激活值,建议用vLLM的continuous batching实测,别光算权重。
上下文和batch才是大头,你光算权重肯定翻车,vLLM开paged attention能省不少。
显存别光看权重,KV cache才是隐藏大户,尤其长文本直接翻倍,vLLM的PagedAttention能省不少。
显存大头确实在KV cache,7B模型INT4大概4G,但上下文一长直接翻倍,vLLM的PagedAttention能省不少。
这题我熟,之前部署7B模型的时候也被显存计算坑过。你那个公式只算了权重,但KV cache才是隐藏的大头,尤其你如果设了2048以上的上下文,7B模型每多1K token大概要多吃0.5-1G显存(取决于层数和head数),而且batch size一旦>1,KV cache是线性增长的。建议直接用vLLM的--max-model-len参数去限制,然后观察它启动时打印的显存分配日志,比手算靠谱多了。
关于框架,低延迟场景我推荐vLLM,它的continuous batching在单卡小batch下延迟表现比TGI稳,而且PagedAttention对显存碎片控制更好。但注意vLLM对某些量化格式支持不完善,比如AWQ要确认下你的版本是否支持Qwen2.5,不然可能白量化。另外别忽略torch的CUDA缓存分配器,它默认会预占一点显存,可以通过PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True缓解。
还有个土办法,你先用FP16裸模型跑一个batch=1的请求,看峰值显存,然后加量化再跑,差值基本就是量化省出来的。但上下文长度建议按你实际业务最大输入+输出预留,别按训练时的长度来。多卡的话,如果只是单卡OOM,优先试张量并行(vLLM支持),比模型并行省通信开销。最后提醒下,如果是8G显存的卡,INT4也别太乐观,建议直接上AWQ或者GPTQ的4bit,实测比动态量化省5%-10%显存。
显存这块儿我当初也算翻车过,公式里那部分只是权重,KV cache才是大头,尤其是长文本摘要,context一拉长直接翻倍。你按5-6G估,可能没算上CUDA context和激活值,实际跑起来7B模型INT4至少得留10G才稳,建议直接拿生产环境的最大输入长度去压测,别信理论值。
vLLM和TGI我都试过,vLLM的continuous batching对低并发延迟优化更明显,而且显存管理更激进,但微调模型要确保算子兼容。TGI稳定些但吃显存更狠,如果你QPS不高,其实可以考虑FP16+短context,省掉量化折腾,一张24G卡就够了。
另外多卡部署如果只是单模型,vLLM的tensor parallel比数据并行省显存,但跨卡通信延迟会上去,你低延迟需求得留意。建议先用AWQ或GPTQ量化,配合vLLM的KV cache量化,能把显存压到8G左右,但一定得试跑一整天看峰值。
显存估算这块儿我之前也翻过车,后来发现除了权重,KV cache才是大头,尤其是长文本场景。你按5-6G算,实际得把max_seq_len和并发数乘进去,公式大概是权重显存+2×层数×头维度×seq_len×batch×精度字节数,可以先拿这个粗算下。
vLLM和TGI我都试过,低延迟的话vLLM的continuous batching更稳,但显存控制上TGI的量化兼容性更好。你QPS不高的话,其实单卡INT4加个8-16的max batch就够了,别盲目上多卡。
另外建议你直接用vLLM的--kv-cache-dtype fp8试试,能省不少,或者用awq量化版本,比GPTQ在低延迟下更省显存。先拿个小数据集压测下,别光靠公式,实际跑一遍最准。
显存计算真的别只盯着权重,KV cache才是大头,尤其你摘要场景上下文一长直接翻倍。我之前7B用vLLM开4K长度,batch 4在24G卡上勉强跑,INT4量化后权重才5G但峰值能飙到14G。建议直接用vLLM,PagedAttention对显存管理友好得多,TGI调起来太折腾。你试试把max_model_len砍到2K,应该能压进16G。延迟要求高的话别贪量化,BF16加小batch反而稳。