最近想把自己微调过的Qwen2.5-7B部署到公司服务器上做API服务,看了N种量化方案,但显存占用算来算去总是跟实际有出入。比如我按公式算INT4量化后大概5-6G显存,结果一跑起来直接OOM了。后来发现上下文长度和batch size也占显存,但不知道具体怎么估算。还有那种多卡部署的方案,用vLLM还是TGI好?有没有老哥分享下实际踩坑经验?我主要是做文本摘要,QPS要求不高但延迟要低,现在被显存和框架选择卡住了,求指点。
部署开源大模型到生产环境,显存到底怎么算才靠谱?
全部回复
共 172 条INT4跑7B模型记得把KV Cache和attention的显存也算进去,我吃过这亏。
显存计算确实容易翻车,INT4的7B模型本身大概4-5G没错,但上下文长度和batch size才是隐藏的大头,比如8k上下文加单条请求就得多吃2G左右。vLLM的PagedAttention对显存管理更优,尤其低延迟场景比TGI稳,我试过同样配置vLLM能多塞30%并发。建议先用vLLM的--max-model-len限制上下文,实测调低到4k能省不少显存,QPS不高的话batch size设1就行。另外多卡部署用张量并行比流水线并行延迟更低,但注意Qwen2.5的TP支持没bug,我踩过坑。
你这情况我太熟了,当初我部署Qwen2.5-7B也踩过一模一样的坑。INT4理论算下来是能塞进6G,但实际跑起来上下文长度和batch size才是吃显存的大头,尤其长文本摘要时,attention那块的缓存会线性暴涨,建议直接用vLLM的max-model-len参数显式卡住上下文,别让框架自动扩。另外你那个OOM很可能是因为框架默认预分配了KV cache,像vLLM里设--gpu-memory-utilization 0.85能留点余量。多卡方案的话,如果QPS要求不高但延迟敏感,TGI的流式响应比vLLM更稳,不过vLLM的PagedAttention在动态batch下显存利用率更高。我建议你先用小batch size(比如1-2)和512上下文长度跑通,再慢慢往上调,同时用nvidia-smi的波动日志看显存峰值,别光看静态占用。文本摘要场景其实4bit加1024上下文足够,剩下显存留给batch size做吞吐,延迟能压到200ms以内。
显存这块确实容易踩坑,我之前用Qwen2.5-7B也遇到过类似问题,INT4量化后理论值没问题,但实际跑起来上下文长度和batch size才是大头。建议你直接拿vLLM试一下,它对显存管理优化得不错,而且支持动态batch,延迟也能压下来。另外多卡部署的话,vLLM的tensor parallel挺省心的,TGI我试过在低QPS场景下显存占用更稳定,但延迟略高一点,你可以根据自己实际负载对比看看。
跟楼主情况差不多,我之前也是被显存计算坑过。关键是除了模型权重,kv cache和激活值占得真不少,尤其是上下文拉到4k以上,显存直接翻倍。建议直接用vLLM,它对显存管理比较智能,能动态分配,而且支持PagedAttention,长文本下比TGI省显存。延迟方面,vLLM的continuous batching也很适合低QPS场景,我们线上就是Qwen2.5-7B INT4配vLLM,4k上下文大概5.8G显存,稳得很。
说实话你遇到的情况太典型了,INT4算出来5-6G那是纯模型权重,根本没算KV Cache和中间激活值。Qwen2.5-7B的KV Cache在默认上下文长度下就能吃掉接近2G,你加上batch size后显存会非线性增长,尤其文本摘要场景长序列特别吃这个。建议你直接用vLLM,它自带PagedAttention能动态管理KV Cache,实测比TGI对显存利用率高不少,而且延迟控制得更好。另外你跑OOM很可能是没开连续批处理或者prefill阶段峰值显存没算进去,可以用vLLM的--max-model-len和--gpu-memory-utilization参数硬性卡一下,比如设0.9留点余量。如果QPS确实不高,试试单卡加量化到INT4再配合vLLM的--num-gpu-blocks限制,7B模型一般12G卡就能稳定跑起来。对了,你微调时用的LoRA还是全参?如果是LoRA,合并权重时记得留意下embedding层的显存碎片问题,这玩意儿经常被忽略。
这个坑我也踩过,INT4的公式确实容易忽略显存里的“隐形开销”。你算的5-6G可能只算了模型权重,但实际跑起来,KV Cache加上中间激活值会吃掉一大块,尤其是上下文长度拉到2048以上,batch size哪怕设成1,显存占用也能飙到8-9G。建议你直接用vLLM,它对PagedAttention优化得比较好,显存利用率高不少,而且支持动态batch,低延迟场景下比TGI更稳。我自己测过7B模型,INT4量化后用vLLM,64长度上下文、batch size=4,大概7.5G就能跑。多卡部署的话,vLLM的tensor parallelism也挺成熟,不过你QPS不高的话,单卡加量化可能更省事。另外,可以试试把模型切成4bit并做KV Cache的量化,能再省1-2G。显存计算有个土办法:权重显存+上下文长度2batch size*每层参数大小,再乘1.2的余量,基本八九不离十。
显存这坑我踩过,INT4理论值确实容易忽略kv cache的膨胀,特别上下文一长直接翻倍。建议用vLLM,它对连续批处理和显存管理优化得更好,而且支持paged attention,能动态分配显存。你7B模型跑摘要,batch size设到4-8,上下文撑死2K,实测10G左右显存基本稳了。多卡的话TGI的tensor parallelism更省显存,但vLLM的调度更灵活,低延迟场景我站vLLM。
显存这块我也踩过坑,INT4理论值确实容易忽略kv cache和中间激活层,特别是上下文长度一拉长,显存直接翻倍。建议用vLLM,它对显存管理更智能,支持PagedAttention动态分配,延迟也低;TGI虽然稳定但显存预占比较死。你可以先用vLLM的--max-model-len参数限制最大上下文,比如设成4096,然后再根据实际QPS试batch size,一般4-8就够用了。
INT4显存公式只是参考,batch size和上下文长度会吃掉额外2-3G,设小点就能跑起来。
显存估算确实容易翻车,INT4下模型权重大概5-6G,但KV Cache和激活值才是隐藏大户,单条长文本直接吃掉2-4G很正常。建议先用vLLM的--max-model-len限制最大长度,配合--gpu-memory-utilization 0.9预留余量,实测比TGI在低延迟场景更稳。如果QPS不高但要求响应快,单卡部署足够,多卡反而增加通信开销,不如开个PagedAttention省心。
INT4跑7B模型5-6G只是权重大小,实际部署时kv cache和中间激活才是吃显存的大头,尤其你上下文开个2k以上,batch size再堆一点,OOM太正常了。vLLM对显存管理确实更激进,不过TGI胜在稳定,文本摘要这种场景我倾向TGI,配合continuous batching能压延迟。建议先用vLLM的--max-model-len和--gpu-memory-utilization调参试试,直观感受下实际占用,别光信理论公式。
INT4实际跑起来显存会比公式多不少,建议按模型权重1.5倍预留,上下文长度影响最大。
显存大头确实在KV cache,推荐直接用vLLM,PagedAttention能省不少。
INT4跑7B模型显存确实得算上KV cache,建议先用vLLM测下实际占用再调batch size。
显存大头在KV cache,INT4推理batch size设小点就不会爆,我4卡用vLLM稳得很。
INT4算5-6G确实太乐观了,上下文和batch占用的显存经常被忽略,建议用vLLM实测下。
INT4算5-6G那个公式其实漏了kv cache和中间激活,尤其是上下文一长,显存直接起飞。我做对话模型时也踩过这坑,后来发现7B模型int4下,哪怕batch size=1,上下文到8k,kv cache就能吃掉2-3G,加上模型权重和碎片,实际得奔着8-9G去。你要延迟低的话,vLLM的PagedAttention对长上下文更友好,显存利用率明显比TGI高,但TGI的continuous batching在小batch下延迟更稳。多卡的话,推荐先试试vLLM自带的张量并行,开两个单卡实例比单卡双卡更灵活。另外微调后最好用AWQ或GPTQ重新量化,比直接转int4更适配模型。你文本摘要任务如果上下文不超过4k,其实用Qwen2.5-7B加vLLM单卡16G就够了,但记得把max_num_seqs调小,比如设1或2,能压住显存峰值。
INT4算完还要考虑KV Cache的占用,7B模型4k上下文大概多占1-2G,你设个8k直接翻倍,OOM太正常了。vLLM对长文本和动态batch优化好,延迟也低,建议优先试试,TGI更吃资源点。另外可以先把max_num_seqs调小,配合preemption策略,能省不少显存。文本摘要的话,FlashAttention记得开,能再挤点空间出来。
INT4算出来5-6G应该是只算了模型权重,没把KVCache和中间激活值算进去,比如7B模型上下文到4K时KVCache就能吃掉快2G,你要跑长文本的话显存预算至少得翻倍。vLLM和TGI我都试过,低延迟场景vLLM的PagedAttention更香,特别是有多卡时显存利用率高不少,但得注意它对Qwen的兼容性,TGI对中文模型反而更稳些。建议你直接用vLLM的--gpu-memory-utilization调到0.9,然后提前测一下最大seq_len下的显存峰值,别信那些纯理论公式。