最近想把自己微调过的Qwen2.5-7B部署到公司服务器上做API服务,看了N种量化方案,但显存占用算来算去总是跟实际有出入。比如我按公式算INT4量化后大概5-6G显存,结果一跑起来直接OOM了。后来发现上下文长度和batch size也占显存,但不知道具体怎么估算。还有那种多卡部署的方案,用vLLM还是TGI好?有没有老哥分享下实际踩坑经验?我主要是做文本摘要,QPS要求不高但延迟要低,现在被显存和框架选择卡住了,求指点。
部署开源大模型到生产环境,显存到底怎么算才靠谱?
全部回复
共 172 条显存计算别只盯着权重,KV cache那部分才是大头,尤其是长文本场景,7B模型INT4权重也就4G多,但上下文拉到8K,batch塞个8,轻松再加3-4G。建议直接用vLLM,它自带显存预估工具,跑之前先用小batch测一遍峰值,比你手算靠谱多了。另外多卡的话优先考虑单卡能塞下的量化档位,实在不行再上张卡,TGI和vLLM我体感差距不大,但vLLM的continuous batching对低延迟更友好。
显存这账真不能只按权重算,KV cache那部分才是隐藏大头,7B模型INT4权重大概5G没错,但上下文拉到4K、batch到8,KV cache轻松吃2-3G。你做摘要延迟敏感的话,vLLM的continuous batching比TGI稳不少,显存预留建议直接按权重的1.5倍来估。另外多卡的话,张量并行比流水线并行省显存,但小模型上通信开销可能反噬延迟,建议先单卡压测看看实际峰值再定。
显存估算这事我踩过好几次坑,核心问题是你那公式只算了权重,没算KV cache和激活值。7B模型INT4权重确实5G左右,但上下文一拉长,KV cache直接指数级膨胀,比如8K长度下可能多出2-3G,再加上batch size和中间激活,实际峰值轻松到10G+。建议你用transformers的profile工具先跑一遍真实输入长度下的显存峰值,别光靠理论公式。框架的话,延迟敏感用vLLM更稳,它的continuous batching对短文本摘要这种场景优化得很到位,TGI在长上下文和量化支持上稍好但延迟抖动大一点。另外多卡部署别用张量并行,7B模型用pipeline并行反而更省显存,因为每张卡只存一部分层。还有个冷门技巧,把输入序列截断到512以内,摘要任务基本不影响效果,但显存能省一半。最后提醒下,记得给CUDA缓存留15%余量,不然OOM会出现在你最意想不到的时候。
显存公式只算权重坑死人,KV cache和激活值才是大头,vLLM的PagedAttention能省不少,建议先拿官方文档的估算器跑一遍。
显存这块我踩过一样的坑,光看权重大小没用,KV cache才是大头,尤其你摘要场景上下文长的话轻松吃掉2-3G。建议直接用vLLM,它有个--max-model-len参数可以限制KV cache,配合continuous batching能把显存利用率拉满。另外7B模型单卡搞不定就上4-bit AWQ量化,实测比GPTQ省显存且速度更快,但记得给CUDA graph留1G余量。低延迟的话别开太长的max-len,能压到2048就够用。
公式算的只是权重占用的显存,KVCache和激活值才是隐藏的大头,你那个5-6G估计只算了权重,实际跑起来上下文一长直接翻倍很正常。文本摘要场景的话,建议直接把max_length限制在1024或2048,然后拿vLLM的continuous batching试一下,它对KVCache的显存管理比TGI更灵活,OOM概率低不少。另外batch size这块,QPS不高就别贪多,设成1或者2就够,延迟反而更稳,显存也能省下来。多卡部署的话,如果只有两张卡,优先考虑张量并行而不是流水线并行,vLLM对TP的支持更成熟,TGI偶尔会有通信瓶颈。最后提醒一句,INT4量化后实际占用还得看模型结构里有没有额外的embedding层或者特殊算子,建议你直接拿真实数据压测一轮,用nvidia-smi监控峰值显存,比任何公式都靠谱。
显存大头其实在KV cache,公式别只算权重,按max_seq_len×batch再乘2倍预留才稳。
显存这块我太有感触了,公式算出来的数基本就是个下限,实际跑起来KV cache和激活值才是大头。我之前用7B模型开2048上下文,batch size调到8,INT4量化后看nvidia-smi直接飙到11G,后来才发现KV cache占得比权重还狠,尤其你如果用了长文本摘要,这块得按序列长度和层数单独算,别光看模型体积。
vLLM和TGI我最后选了vLLM,主要是它对continuous batching的支持更成熟,延迟控制比TGI稳,但前提是你得把gpu_memory_utilization设到0.9以上,不然它默认只给你留一点缓存空间,照样OOM。还有个坑是PagedAttention虽然省显存,但如果你QPS不高、并发少,反而可能因为调度开销增加延迟,得自己压测调参。
多卡的话我建议先试试张量并行,两卡跑7B其实很宽裕,但要注意通信开销,如果服务器是PCIe互联而不是NVLink,延迟会明显上去。你延迟要求低的话,不如单卡把batch压到1-2,用FP16或BF16反而比量化更稳,INT4在小batch下速度优势不明显,还容易掉精度。最后提醒一句,显存计算一定要把CUDA context和torch本身的开销算进去,那个固定占几百MB到1G,很多人漏了这个。
显存算错太正常了,我之前也被坑过,光看权重大小没用,KV cache那部分才是大头,而且会随着并发和输入长度动态涨。文本摘要这种场景,建议直接上vLLM,PagedAttention对显存管理比TGI省心很多,延迟也更稳。另外你那个INT4估算,最好把7B的中间激活值也考虑进去,实测峰值能到8G左右,留个20%余量才安全。
显存这块我之前也栽过跟头,你按模型权重算INT4那5-6G其实没错,但漏了KV cache和激活值。文本摘要要是输入输出都长,KV cache轻松吃掉2-3G,加上CUDA context和碎片,7B模型实际至少得预留12G才稳。我后来直接用nvtop盯着看,发现batch size哪怕从1调到2,显存都能多涨1.5G,所以低延迟场景干脆固定batch=1,用continuous batching交给vLLM去调度。
框架的话,我两个都试过,TGI在长上下文下更省显存,但vLLM的吞吐和社区活跃度确实更好,你QPS不高的话其实TGI更稳,配置简单不容易出幺蛾子。不过有个坑是TGI的量化格式支持不如vLLM全,你如果微调过可能得转成GPTQ或AWQ,这点建议提前验证。
多卡方案如果不是特别大的模型,真没必要,单卡A10或者4090跑7B+INT4+短上下文完全够,多卡反而引入通信开销,延迟会变差。建议你先用vLLM的--max-model-len参数限制最大生成长度,比如设2048,再把gpu_memory_utilization调到0.9,这样能榨干显存又不OOM。还有个偏方,用--enforce-eager模式跳过CUDA graph的预分配,能省1G左右,代价是首token延迟稍微高一点,但对你摘要场景影响不大。
显存算错基本都栽在KV cache和激活值上,我上次测7B的INT4,光把上下文撑到8K就吃掉快2G,你这文本摘要场景建议直接按“模型权重+序列长度×隐藏层数×2×精度”粗调,别信那些简化公式。vLLM对连续请求的吞吐优化更明显,但你要是延迟敏感、并发又不高,TGI的continuous batching反而更容易控延迟,我两个都试过,踩坑后留了TGI。另外多卡部署别光看显存总和,跨卡通信开销和显存碎片也得算进去,最好先用小batch压测一下实际峰值再定配置。
显存这块儿我当初也栽过跟头,公式算的只是权重,KV cache和激活值才是隐藏大坑。你文本摘要场景建议直接上vLLM,PagedAttention对长上下文友好很多,TGI调度开销略大。另外INT4实际占用建议按权重+2G基础预留,再按sequence长度乘个0.5-1G/K tokens粗估,QPS不高的话单卡A10足够。
显存这块我之前也算翻过车,除了模型权重,KV cache才是隐藏大头,尤其你文本摘要输入长的话,7B模型INT4实际吃个10G不奇怪。建议直接拿vLLM的--max-model-len和--gpu-memory-utilization参数压测,比手动算靠谱。多卡的话vLLM对Qwen支持更省心,TGI调起来麻烦点但吞吐上限高,延迟敏感就单卡+短上下文优化吧。
显存估算别只看权重,KV cache和激活值才是大头,建议先按max_lenbatch2G算预留。
vLLM对低延迟更友好,但显存得按峰值算,建议把max_seq_len和batch留30%余量。
显存大头其实是KV cache,用vLLM开paged attention能省不少,测下峰值再定batch。
显存这块我之前也栽过跟头,公式算的只是权重,实际还得把KV cache和激活值算进去,上下文一长直接翻倍。你试试用vLLM的估算工具,或者先跑个小batch压测一下,比手算靠谱。框架的话,延迟敏感选vLLM,TGI现在功能全但调度开销大点,文本摘要这种场景vLLM够用了。多卡部署记得开张量并行,但7B模型单卡其实能塞下,先确认下是不是量化后精度损失导致输出变长,白占显存。
公式算的只是权重占用量,KV cache才是隐形杀手,7B模型上下文开到4K加上batch 8,INT4也得预留2-3G。建议直接用vLLM,它对PagedAttention优化得更好,显存利用率比TGI高不少,而且QPS要求不高的话可以调低max-num-seqs限制并发。另外多卡部署别图省事用张量并行,7B模型单卡跑不动就上AWQ量化,实测在A10上延迟能压到50ms以内。
这题我熟,上个月刚踩完坑。你算显存光看权重是不行的,KV cache才是大头,尤其你摘要场景文本长,7B模型INT4下光KV cache就可能吃掉2-3G,加上激活值那些,建议直接按权重1.5倍再加上下文长度乘个系数来估。框架的话我建议vLLM,TGI的continuous batching在低并发下优势不明显,vLLM的PagedAttention对长文本友好很多,OOM概率低。另外你延迟敏感的话,可以试试把max batch size调小,牺牲点吞吐换稳定。
显存这块儿我当初也栽过跟头,光按权重量算必翻车。你那个5-6G应该是只算了模型权重,但实际跑起来KV cache才是隐形大户,特别是文本摘要这种长上下文场景,7B模型就算INT4,seq len拉到2K以上,KV cache轻松吃掉2-3G,再加上激活值和框架预留的buffer,OOM太正常了。我建议你直接按“权重显存 + 1.5倍上下文长度×层数×隐藏维度×2字节×batch size”这个粗算方式去估,INT4的话权重按4.5G算,然后上下文每1K tokens大概多占0.7-1G,这样留出30%冗余基本就稳了。至于vLLM和TGI,你这延迟敏感但QPS不高的情况,我反而推荐vLLM,虽然它吃显存比TGI更猛,但PagedAttention对KV cache的利用率高很多,而且可以开--max-num-seqs限制并发,把显存大头控制在KV cache上。多卡的话别用张量并行,7B用TP纯属浪费带宽,直接单卡跑INT4,如果实在放不下就上AWQ或GPTQ的4bit,比FP16省一半还多。还有个小坑,vLLM默认会预分配全部显存,记得设--gpu-memory-utilization 0.85,不然就算模型放得下,空闲显存也会被它霸占导致其他服务崩。