最近在用vLLM部署一个13B的模型到公司服务器上,单卡A100 80G跑起来倒是还行,但并发一上来就显存溢出,报OOM错误。我试了GPTQ量化到4bit,精度有点下降但还能忍,结果显存占用还是跑满。问了同事,有人推荐用Flash Attention,有人建议上多卡张量并行,但我搞不清楚这些方案到底怎么落地。有没有大佬分享一下实际部署中压显存的成熟套路?或者有没有什么简单的trick能先顶住小流量?感谢!
部署开源大模型到生产环境,显存总不够用怎么办?
全部回复
共 161 条说到这个我太有共鸣了,之前用vLLM部署7B模型也撞过同样的墙,并发一上来OOM跟吃饭一样频繁。你这情况其实可以分两步走,先别急着上多卡,把vLLM的gpu_memory_utilization参数调到0.85左右,再开一下--enable-prefix-caching,小流量下能明显缓解峰值压力。Flash Attention确实能省不少显存,但如果你用的是比较新的vLLM版本,它默认就已经在用了,不用额外配置,你检查下日志里有没有“Using FlashAttention”的提示。GPTQ 4bit精度下降其实还好,但如果你觉得推理质量不对劲,可以试试AWQ,有时候同是4bit但实际效果差异挺明显的,而且显存占用还能再低一丢丢。多卡张量并行是终极方案,但落地起来坑不少,比如需要改模型加载方式、调整通信配置,建议你先用单卡把量化、KV cache、max_num_seqs这些参数调优,把小流量撑稳了再考虑扩展。对了,你检查过paged attention的block大小吗?默认值有时候不是最优的,调小一点能减少碎片化浪费。实在不行还有个土办法,就是限制max_num_seqs,牺牲一点吞吐换稳定性,线上服务总比崩了强。
vLLM里开个--max-num-seqs限制并发batch大小能立刻缓解OOM,代价是吞吐量降一点,但至少不会崩。Flash attention是真有用,显存占用能少20%左右,vLLM现在直接支持,改个环境变量就行,建议先试试这个。张量并行的话要改模型加载方式和通信配置,13B在80G上单卡其实没必要,除非你同时跑多个任务。另外可以把KV cache的分配策略调成自适应,vLLM有参数控制,小流量下能省不少显存。
Flash Attention值得先试,它主要省的是KV Cache的显存,你这场景并发上来OOM大概率就是这块爆了,改动也不大,vLLM里直接开就行。张量并行是治本的路子,但得看你们服务器有没有多卡互联,NVLink没有的话通信开销反而拖慢速度。小流量顶一下的话,可以把max_num_seqs调小,再配合continuous batching,牺牲点吞吐换稳定,实测挺管用的。对了,你GPTQ量化后有没有检查过是不是某些层没转换成功,有时候显存没降下来是这原因。
Flash Attention其实是个不错的切入点,它主要省的是KV cache那块的显存,13B模型单卡并发吃紧的话,这个优化能明显缓解OOM,实现上vLLM里直接开就行不太费事。张量并行的话得看你的服务器有没有多卡互联,NVLink带宽够的话效果立竿见影,但要注意数据并行和pipeline parallel的取舍。小流量trick的话,可以试试把max_num_seqs调低,或者设个max_model_len限制输入长度,能临时顶一阵子。还有个思路是换用AWQ量化,比GPTQ在相同bit下通常保留更多精度,显存占用差不多。
先别急着上多卡,试下把max-num-seqs调小点,并发能压住一大截。
张量并行落地不难,vLLM里设个tensor-parallel-size就行,但记得先看下NVLink带宽。
Flash Attention确实该优先试,它能省不少显存,而且vLLM本身就支持,改下参数就行。另外你GPTQ量化后还跑满,大概率是max_num_seqs或者KV cache没调好,这两个参数比量化影响还大。我这边跑13B单卡一般把KV cache压到总显存一半左右,并发小流量能稳住。多卡张量并行是终极方案但配置麻烦,建议先看vLLM的官方文档里关于paged attention的说明,把swap空间也设一下,能救急。
并发上来OOM大概率是KV Cache爆了,先调低max-num-seqs或加--enable-chunked-prefill试试,能撑住小流量。
张量并行不复杂,vLLM里设个tensor-parallel-size就行,先顶住并发再想量化。
Flash Attention建议优先试,本质是优化attention计算的内存访问,几乎不损失精度,代码改动也小。张量并行要看你卡间带宽,A100 NVLink跑13B模型效果确实立竿见影,但配置起来有门槛。想快速先顶上小流量的话,可以试试把max_num_seqs调小,再配合continuous batching,能缓解不少OOM。另外检查下KV cache是不是没开PagedAttention,vLLM默认该开的,你确认下版本。反正这玩意儿是组合拳,光靠一个方案很难彻底解决。
先试试vLLM的continuous batching和PagedAttention,这俩能直接扛住并发,比单纯量化管用。
再不行就把max-num-seqs调低点,牺牲点吞吐换稳定,小流量够用了。
Flash Attention先安排上吧,它主要是省显存带宽,对长上下文提升很明显,而且vLLM本身已经支持了,改个参数就能开。多卡张量并行是正路,但要注意你的模型并行切分后每张卡都要装完整权重,13B在80G上其实可以试试2卡,显存压力瞬间小一半。另外你GPTQ量化后精度掉得厉害的话,可以换AWQ试试,同样的4bit下通常更稳,vLLM也原生支持。如果只想临时顶住小流量,把max_num_seqs调小一点,或者限制一下最大输入长度,能立刻减少OOM概率。
先试试vLLM开个--max-num-seqs限制并发,配合continuous batching能撑住小流量,OOM大概率是预分配显存炸了。
先砍max-batch-size和max-seq-len试试,小流量时把并发限死比啥都管用。
vLLM那个PagedAttention其实已经帮你把KV cache的碎片化问题处理得差不多了,OOM大概率不是显存不够,而是你给每个请求预留的max-model-len太长,实际用到的token远没那么多。建议先把max-num-seqs调小一点,比如8或者16,再配合--gpu-memory-utilization设到0.9,很多小流量场景直接就扛过去了。GPTQ 4bit在13B上精度损失其实可控,但如果你用AWQ或者近年出的那几个新量化方法,比如HQQ或者QuIP#,激活值分布保留得更好,显存还能再省一截。Flash Attention主要省的是计算和部分内存带宽,对峰值显存帮助有限,除非你开paged attention的v2版本,不然还是先从调度参数下手。多卡张量并行确实能把权重和KV cache摊到两张卡上,但你要注意all-reduce通信开销,A100的NVLink还好,如果是PCIe互联,并发高时延迟反而更明显。另外一个特别容易忽略的坑是,vLLM默认会对连续prompt做chunked prefill,如果你的输入长度波动很大,建议打开--enable-chunked-prefill,把长提示词拆开,减少临时显存峰值。最后说个土办法,把模型换成Mistral或者Yi的14B版本,结构上对KV cache做了分组共享,实测比13B的LLaMA在相同显存下能多塞30%的并发请求,精度也基本不掉。
vLLM的OOM很多时候是KV cache和并发线程没调好,可以先看看--max-num-seqs和--gpu-memory-utilization这两个参数,把利用率压到0.85左右,再配合continuous batching,小流量瞬间就稳了。Flash Attention确实能省不少显存,尤其长上下文场景,但得看你模型支不支持,13B的话直接上多卡张量并行更省心,A100 80G两张卡跑4bit基本能扛住几十路并发。另外精度下降如果不是特别敏感,试试AWQ,比GPTQ在同样4bit下能好一点,但别指望质变。先别急着上多卡,我踩过坑,多卡通信开销在小并发下反而更慢,不如先把batch和KV cache极限压榨一遍。
vLLM的PagedAttention其实已经帮你省了不少显存,但并发高时瓶颈经常在KV cache。可以先试试把max-num-seqs调小一点,比如从256降到64,小流量下响应速度反而更稳。另外GPTQ别用4bit,试试AWQ或者bitsandbytes的8bit,精度损失小很多,配合FlashAttention能再挤出一部分空间。多卡张量并行是治本的路子,但得先看看你数据并行和流水线并行的配置,别一上来就全上,调起来挺折腾的。
说实话你这个问题我太有共鸣了,之前我部署7B的时候也被OOM折磨过,后来发现光靠量化根本治标不治本。GPTQ降到4bit之后显存是省了,但KV cache那部分才是并发上来后的真正大头,你可以试试PagedAttention,vLLM本身就支持,它能把KV cache分块管理,相当于虚拟内存的思路,对提升吞吐立竿见影。另外Flash Attention确实该开,尤其长序列下能省不少显存,但它主要优化的是计算效率,对显存占用帮助有限,别指望它能解决OOM。多卡张量并行倒是正道,但13B在A100 80G上其实单卡就够推理,并行更多是为了扛并发,你不如先把vLLM的max-num-seqs调小,比如从默认的256降到32或64,再去把gpu-memory-utilization设成0.9,给KV cache留点余量。还有个笨办法,提前把输入长度截断或者用滑动窗口注意力,很多线上场景根本不需要完整上下文。最后建议你去看下vLLM的continuous batching,它能把请求动态拼batch,配合上面的参数,小流量顶住完全没问题。
试试把max-num-seqs调小点,再开个PagedAttention,小流量能稳住,等并发真上来了再上多卡。
Flash Attention对长上下文收益大,你这场景先看下vLLM的gpu_memory_utilization设到0.9没?
Flash Attention确实值得先试,它主要省的是KV cache那块显存,尤其长上下文场景效果立竿见影,vLLM里直接设--enable-flash-attn就行,基本零成本改动。但说实话,你这情况单卡80G跑13B并发一高就OOM,大概率不是attention的问题,而是请求队列和显存调度没调好,vLLM里--max-num-seqs和--gpu-memory-utilization这两个参数可以先压一压,比如把利用率从0.9降到0.85,给KV cache留点余量,小流量瞬间能顶住。至于多卡张量并行,那是另一条路,但A100 80G单卡其实已经够宽了,除非你要上70B级别,否则两张卡做PP(流水线并行)反而可能因为通信开销在低并发时更慢。GPTQ 4bit精度损失你还能忍的话,试试AWQ或者把量化粒度调成group size 128,有时候能再挤出来10%显存。另外一个小trick,如果业务允许,把max-model-len限制到2048或1024,很多场景根本用不到4K,能省一大块KV cache。最后建议你开个vLLM的--swap-space参数,把一部分KV cache换到CPU内存,虽然慢点但至少不崩,适合临时扛流量。
Flash Attention基本是必上的,能省不少显存还提速,你vLLM更新到最新版直接开就行,基本零成本。多卡张量并行的话,如果你们有2张A100,用vLLM的tensor-parallel-size=2配置一下,比单卡硬扛稳得多,但注意要开NCCL,网络带宽别太拉胯。至于4bit精度下降,可以试试AWQ,同是4bit但比GPTQ保留更多关键权重,效果会好点。如果只是临时顶小流量,先把max-num-seqs调小,比如默认256降到64,OOM概率会大幅下降,代价就是吞吐低些。