最近在用vLLM部署一个13B的模型到公司服务器上,单卡A100 80G跑起来倒是还行,但并发一上来就显存溢出,报OOM错误。我试了GPTQ量化到4bit,精度有点下降但还能忍,结果显存占用还是跑满。问了同事,有人推荐用Flash Attention,有人建议上多卡张量并行,但我搞不清楚这些方案到底怎么落地。有没有大佬分享一下实际部署中压显存的成熟套路?或者有没有什么简单的trick能先顶住小流量?感谢!
部署开源大模型到生产环境,显存总不够用怎么办?
全部回复
共 161 条Flash Attention确实能省不少显存,尤其是长文本场景下,vLLM本身就支持,你只需要在启动时加个--enable-flash-attn参数就行。多卡张量并行对13B模型来说性价比很高,两张A100切一下,每卡压力直接减半,vLLM用--tensor-parallel-size 2就能搞定。小流量临时顶一下的话,可以调低--max-num-batched-tokens或者限制最大并发数,虽然牺牲点吞吐,但至少不崩。另外检查下你的gpu_memory_utilization设置,默认0.9可以降到0.85给KV cache留点余量。
试试开vLLM的prefix caching和continuous batching,能省不少显存,小流量撑住没问题。
Flash attention 加 PagedAttention 能省不少显存,小流量先上 vLLM 的 continuous batching 试试。
试试把vLLM的max_num_batched_tokens调低点,小流量时能省不少显存。
Flash Attention确实值得先试,它主要是优化显存带宽利用率的,对单卡并发场景提升挺明显,vLLM原生就支持,改个参数就能开。张量并行的话,多卡部署对代码改动不小,而且小流量阶段可能有点杀鸡用牛刀,建议先调低max_num_batched_tokens或者开启continuous batching,能顶住一部分突发请求。另外如果精度还能再让一步,AWQ量化比GPTQ对显存占用更友好些,社区反馈部署问题少,可以对比着试试。
Flash Attention基本是必上的,能省不少显存而且几乎不影响精度,vLLM本身就支持,你查下启动参数加上--enable-flash-attn试试。多卡张量并行对13B模型性价比很高,两张A100切一下每卡只用扛6.5B,压力直接减半,vLLM配置--tensor-parallel-size 2就行。如果只是临时顶小流量,可以调低max-num-batched-tokens或者限制最大并发数,虽然吞吐会降但至少不崩。另外检查下vLLM的block-size,默认可能偏大,改成16或者8能省点显存碎片。
我也遇到过类似的问题,vLLM本身已经做了不少优化,但并发高的时候显存确实容易炸。建议你先试试调整max_num_batched_tokens和gpu_memory_utilization这两个参数,把利用率压到0.85左右给kv cache留点余量,小流量下能稳住。如果还想进一步省显存,Flash Attention确实有效,vLLM里已经集成了,开启后单卡吞吐能提不少,而且对精度没影响。至于张量并行,那是多卡方案,单卡动不了。
vLLM的continuous batching + PagedAttention才是关键,比单纯量化管用,建议先开起来试试。
先上Flash Attention,显存能省不少,再配个paged attention,小流量撑住没问题。
Flash Attention确实值得先加上,它能明显降低KV Cache的显存占用,vLLM里直接开就行,几乎零成本。另外你说的4bit量化精度下降,可以试试AWQ,同是4bit但通常比GPTQ稳一点,尤其对13B这种规模。如果并发还是顶不住,先限制一下最大序列长度和max_num_seqs,牺牲点吞吐换稳定,至少不会OOM崩掉。多卡张量并行是终极方案,但要注意通信开销,小流量没必要上。
先试试paged attention和continuous batching,vLLM里开起来能顶不少并发,再不行就砍max-seq-len。
Flash Attention确实该优先试,它主要是省显存带宽,13B在A100上能明显缓解长序列的OOM,而且基本无感。另外张量并行不是银弹,2卡的话通信开销不小,建议先看看你的并发瓶颈是显存还是算力。小流量的话可以试试把max_num_seqs调小,vLLM默认值偏大,配合continuous batching也能顶一阵。精度损失如果能忍,其实可以看下AWQ,比GPTQ在低bit下稳一点,显存占用还稍微低些。
这问题太真实了,我上周刚把13B从单卡挪到两卡张量并行,OOM直接没了,但通信开销得调好不然吞吐反而掉。Flash Attention能省不少显存,尤其是长上下文场景,建议跟量化一起上。小流量临时顶一下的话,可以试试把max_num_seqs调小,或者开continuous batching,虽然吞吐低点但至少不崩。
vLLM的PagedAttention其实已经比原生方案省显存了,但并发高时建议先调低max-num-seqs或限制最大并发数试试,小流量阶段能稳很多。Flash Attention确实能省些显存,主要靠重计算省激活值,13B单卡A100应该能明显改善。多卡张量并行是根治方案,但要注意通信开销,建议先看下NCCL配置和PCIe带宽,不然反而可能变慢。另外如果精度能接受,AWQ量化一般比GPTQ在推理时更快更稳,可以对比下。
说实话你这情况我太熟了,vLLM默认的KV cache策略在并发上来的时候特别容易爆,大概率不是模型权重占满,而是KV cache把剩余显存全吃了。你先试试在启动参数里加--max-num-seqs和--gpu-memory-utilization,把利用率卡在0.85左右,再限制一下单请求的最大生成长度,小流量场景下能立竿见影。Flash Attention确实是必须的,尤其是有长上下文请求的时候,它能把attention的显存复杂度从平方降到线性,但要注意vLLM版本要对上,老版本支持不好。张量并行这事情得看你的卡间互联,如果是PCIe而不是NVLink,通信开销会吃掉很多收益,13B模型两张卡勉强,四张卡反而可能更慢。还有个土办法,把并发降下来然后开continuous batching,vLLM本身就是这机制,但你得确认请求队列没打满,否则就是假并发。另外GPTQ 4bit我建议你换AWQ试试,同精度下AWQ的激活值分布保留更好,代码侧改一个quant_method就行,也许能省下更多显存给KV cache。如果只是临时顶一下小流量,干脆把max-model-len调小一半,很多生产场景其实根本用不到那么长的上下文。最后提醒一句,先看日志里OOM的具体栈,到底是权重还是KV cache,方向错了白折腾。
试试把max-num-seqs调小点,再开个continuous batching,小流量能稳住,大并发还是得上多卡张量并行。
Flash Attention和paged attention(vLLM内置)都要开,这俩能显著降低KV cache的碎片和显存峰值,比单纯量化效果明显。另外4bit精度损失如果接受不了,可以试试AWQ,同位数下通常比GPTQ稳一些。小流量顶不住的话,先检查一下max_num_seqs和gpu_memory_utilization这两个参数,把利用率设到0.9以上,batch size调小点。多卡张量并行确实是大并发下的正解,但记得用TP size=2起步,另外把模型切分后显存占用不只是线性减半,通信开销也要算进去。
看到你说GPTQ量化到4bit显存还是满,我猜瓶颈大概率不在权重,而在KV cache和激活值上。13B模型即使用4bit,单卡并发一上来,KV cache膨胀得特别快,A100 80G看着大,实际扛不住几十路并发。
我自己的经验是,先别急着上多卡,可以试试vLLM的continuous batching和PagedAttention,这两个是亲兄弟,能把显存利用率拉高不少,尤其是短请求多的场景。另外,把max_num_seqs调小一点,比如64或者32,牺牲一点吞吐换稳定,小流量阶段完全够用。
Flash Attention确实能省显存,但主要是省在长序列的注意力计算上,如果你业务里上下文长度普遍在1K-2K以内,提升有限,不如直接开vLLM的--enable-prefix-caching,对重复前缀的请求有奇效。
至于多卡张量并行,那是最后一步,因为要改模型加载方式和通信配置,而且13B模型在2卡A100上并行,收益不一定比调优单卡大,除非你并发目标定在100以上。
还有个歪招,把模型切一半放到CPU上,用Offload,vLLM支持这个,但延迟会涨,只适合对响应时间不敏感的内部工具。你先试试把GPTQ换回FP16,配合vLLM的--gpu-memory-utilization设为0.9,然后观察OOM是不是集中在长尾请求上,如果是,就加个请求长度限制,比什么都管用。
试试把max-num-seqs调小点,再配合continuous batching,小流量能顶住,大并发再上张量并行。
先上paged attention和continuous batching,vLLM自带,能顶不少小流量。再砍max-len和并发数,比换量化实在。