最近想把自己微调过的Qwen2.5-7B部署到公司服务器上做API服务,看了N种量化方案,但显存占用算来算去总是跟实际有出入。比如我按公式算INT4量化后大概5-6G显存,结果一跑起来直接OOM了。后来发现上下文长度和batch size也占显存,但不知道具体怎么估算。还有那种多卡部署的方案,用vLLM还是TGI好?有没有老哥分享下实际踩坑经验?我主要是做文本摘要,QPS要求不高但延迟要低,现在被显存和框架选择卡住了,求指点。
部署开源大模型到生产环境,显存到底怎么算才靠谱?
全部回复
共 172 条这个坑我也踩过,光看模型权重确实容易乐观,实际跑起来kv cache才是吞显存的大户,尤其是文本摘要这种长序列任务,随便塞几条长文本进去显存就炸了。我建议你算的时候直接按公式:显存 ≈ 模型参数显存 + 1.2到1.5倍的序列长度×层数×头数×2字节(如果是fp16),再乘上batch size,这样基本不会翻车。INT4的5-6G只能算权重的静态占用,动态部分没算进去。vLLM和TGI我都试过,vLLM的paged attention在长上下文场景下显存利用率高不少,特别适合你这种延迟敏感但QPS不高的需求,而且它支持prefix caching,对摘要任务重复prompt的场景能省不少计算。不过部署时记得把gpu_memory_utilization设到0.9左右,留点余量给框架本身。另外你如果只跑单卡,可以考虑先试下llama.cpp的量化版,虽然吞吐不如vLLM,但延迟控制得极好,对单请求场景很友好。
这个坑我当初也踩过,公式算出来只是模型权重本身,实际跑起来KV Cache才是大头,尤其是长文本摘要场景,上下文一长直接翻倍。你如果是7B模型做INT4,建议先按每token大约2MB来估算KV Cache,比如4K上下文就额外多8G左右,加上权重5-6G,batch size再乘个系数,OOM就合理了。vLLM和TGI我都试过,vLLM对显存管理更激进,支持PagedAttention动态分配,延迟控制也不错,但初次部署配置多些;TGI更无脑,稳定但显存占用略高。你QPS不高的话,单卡用vLLM加动态batch应该够了,记得设max_num_seqs别太大。另外多卡部署如果数据并行,显存翻倍但速度提升有限,不如试试张量并行,不过7B模型单卡跑其实更省心。
显存这块儿最坑的就是KV cache,7B模型INT4权重确实能压到5G左右,但上下文一拉到4K以上,batch size稍微开大点,KV cache直接吃掉好几个G,峰值很容易超10G。建议你直接用vLLM,它那个PagedAttention对显存管理更灵活,实测同样负载比TGI省15%左右显存。另外多卡部署别单纯按模型大小切分,把KV cache也考虑进去,不然第二张卡很容易空转。文本摘要延迟敏感的话,优先用FP16配vLLM的continuous batching,吞吐和延迟平衡得最好。
显存算错太正常了,模型权重只是基础,KV cache和激活值才是隐藏的大头,尤其上下文拉长后增长贼快。我之前用7B模型,INT4量化后weights大概4G多,但加上8K上下文和32的batch,实测要9-10G才稳,所以建议直接按权重两倍去预留。框架的话,低延迟优先vLLM,它对continuous batching优化得更好,TGI在长文本上偶发显存碎片问题,当然你这场景QPS不高,单卡A10或4090其实就够,别一上来就想着多卡,跨卡通信延迟反而拖累首token。
显存这块我当初也踩过一模一样的坑,INT4的理论值算的是权重,压根没把KV cache算进去。你7B模型就算4bit量化,光是默认的2048上下文长度,KV cache就得额外吃1-2G,再把batch size提到8或者16,OOM太正常了。建议你直接拿实际输入输出长度去估算,比如平均输入512输出256,那KV cache大概就是层数头数维度序列总长2字节,这个公式比网上那些笼统的准多了。另外多卡部署的话,我个人更推荐vLLM,它对连续批处理和PagedAttention的优化做得更彻底,延迟稳定性比TGI好,尤其你QPS不高但要求低延迟,vLLM的调度机制会更友好。不过要注意vLLM对量化格式支持有差异,AWQ和GPTQ没问题,但有些新出的量化方案可能不支持,这点得先确认。最后提个建议,你如果只是做文本摘要,其实可以试试把max_length限制在1024以内,显存能省出一大截,很多场景根本用不到那么长的上下文。
显存真别只算权重,KV cache和激活值才是大头,我4张A10跑7B都翻过车。
显存算错八成是没把KV cache和激活值算进去,7B模型INT4权重确实5G左右,但上下文一拉长直接翻倍。我建议你直接拿实际输入长度去vLLM的github看它的显存估算公式,比那些通用教程准多了。低延迟的话vLLM比TGI稳,尤其你QPS不高,把max_num_seqs调小点能省不少显存。多卡反而麻烦,先单卡把量化级别降到AWQ或GPTQ的4bit,再用--gpu-memory-utilization参数手动限制到90%试试。
显存这玩意儿确实坑,我上次部署7B也翻车了。你那个5-6G的算法,大概率只算了权重没算KV cache,序列一长直接爆。文本摘要还好,把max_length限制在2K以内,再设个gpu_memory_utilization参数给vLLM留个15%余量,基本能稳住。框架我推荐vLLM,TGI对连续请求的调度没它灵活,延迟高一点点但吞吐稳。还有个小技巧,用flash-attention能省不少显存,记得编译时加上。
显存这块真不能光看权重,KV cache才是隐形杀手,尤其你文本摘要场景seq len一上来直接翻倍。我上次7B跑INT4,开2048上下文和32batch,实测8G卡直接爆,后来降到16batch才稳。vLLM的话吃显存但吞吐好,TGI相对省一点,你延迟敏感的话还是优先把batch压小,再考虑框架,另外记得开continuous batching。
显存大头其实在KV cache,batch1也得按2-4G预留,vLLM的PagedAttention能省不少。
你这情况太典型了,公式算的只是权重本身,KV cache那部分才是隐藏的大头。7B模型INT4权重确实5G左右,但上下文一拉长,比如2048长度加batch 4,KV cache轻松吃掉2-3G,再加上激活值和CUDA context,OOM太正常了。建议直接用vLLM,它的PagedAttention能动态管理KV cache,比TGI在显存利用率上强不少,尤其是你这种低QPS但延迟敏感的场景,vLLM的continuous batching反而更稳。另外多卡部署别用张量并行,7B模型单卡不够就用NVLink连接的两卡,但注意通信开销,实测下来batch小的时候张量并行收益很低,不如直接上量化加KV cache量化,比如AWQ配合KV cache INT8,能再省15%左右显存。最后给你个土办法,先设个保守的max_model_len和max_num_seqs,跑个压测脚本看监控,逐步调参,比任何公式都靠谱。
显存算错太正常了,公式只算权重忽略KV cache和中间激活,OOM才怪。我刚部署那会儿也栽过,后来直接按权重+序列长度×层数×2算KV,再留20%余量才稳。你延迟敏感的话建议vLLM,PagedAttention对KV cache友好很多,TGI更适合高吞吐;另外QPS不高别上多卡,单卡A10或4090配AWQ量化完全够用。
显存这玩意儿确实得按峰值算,上下文长度和batch size经常被忽略,我之前跑13B模型开2048上下文加动态batch,直接比预估多了3个G。文本摘要这种场景其实vLLM够用,TGI优势在多模态和细粒度控制上,延迟敏感的话建议把KV cache量化打开,能省不少。另外多卡部署别贪张数,7B模型两张卡通信开销反而可能拖慢速度,单卡能塞下就尽量单卡。
显存这个坑我也踩过,光算权重确实不够,KV cache才是大头,尤其文本摘要要长上下文,7B模型INT4下8K长度加batch 4至少得再留4-6G。vLLM的PagedAttention能省不少,但OOM时先看下max_seq_len和gpu_memory_utilization设置,别拉满。延迟敏感的话TGI的continuous batching也够用,但调参更玄学,建议先用vLLM默认配置跑个压测,再按实际吞吐去调显存预留。
这题我熟,之前部署7B也踩过同样的坑。计算显存得把KV cache和激活值算进去,你按模型权重算当然会OOM,建议直接用transformers的get_memory_footprint或者跑个小batch实测一下。另外vLLM在低延迟场景下比TGI更稳,尤其是连续批处理这块,我们线上压测过,P95能低个30%。不过你QPS不高的话,其实单卡加个量化也够用,多卡反而增加维护成本。
显存这块我踩过一样的坑,你漏算了KV cache和CUDA context的开销,7B模型INT4裸权重确实5G出头,但seq len到2048、batch size给4的话,KV cache直接吃2-3G。建议直接用vLLM,PagedAttention能省至少30%显存,而且连续批处理对低延迟很友好,TGI现在优势不大了。另外多卡的话优先张量并行,别用流水线并行,7B规模用两张卡勉强够,但注意通信开销。你QPS不高的话,其实可以试试单卡加长上下文截断,比如max_len限制到1536,能稳不少。
显存这玩意儿光算权重真不行,KV cache和激活值才是隐形杀手,尤其你文本摘要场景输入输出都不短,建议直接按max_seq_len和batch=1先算,再乘个1.5的冗余系数。vLLM这块比TGI省心不少,PagedAttention对长上下文友好,但记得开--max-model-len别让默认值坑了。另外INT4建议试下AWQ或GPTQ,动态量化有时候会莫名爆显存。
你这情况太典型了,光按模型权重算显存必然翻车,KV cache才是隐藏大头。我建议先用vLLM的--max-model-len和--gpu-memory-utilization参数跑个基准,把吞吐和延迟实测数据拉出来再调,别光靠公式。多卡的话优先vLLM,tensor parallel比TGI省心,尤其你文本摘要场景对延迟敏感,vLLM的continuous batching能明显压低首token延迟。另外7B模型用INT4有点激进,试试AWQ或GPTQ的4bit但保留一半attention精度,显存能省但效果不掉太多。
显存大头其实在KV cache,特别是长文本摘要,建议用vLLM开continuous batching,实际测下来比公式靠谱。
显存这块我当初也栽过跟头,公式算出来的只是权重占用量,KV cache那部分才是隐藏大头。你文本摘要场景如果输入长文档,序列长度直接决定KV cache膨胀速度,建议用transformers的profile工具实测一下,比手算靠谱多了。
vLLM和TGI我最后选了vLLM,主要看中它的continuous batching,低延迟场景下比TGI的调度更稳。不过vLLM对量化格式支持有坑,AWQ和GPTQ的kernel优化程度不一样,你Qwen2.5-7B建议直接用官方AWQ版本,省得自己转格式时候踩算子兼容的雷。
多卡部署的话,别迷信张量并行,7B模型单卡16G其实能塞下INT4,但如果你要留余量给长上下文,就得上双卡,这时候通信开销反而比显存更敏感,得看你们服务器是NVLink还是PCIe。另外有个野路子:把prompt压缩一下,摘要任务对前文做截断或摘要级refine,能砍掉一半KV cache,我实测延迟降了30%。