最近在用vLLM部署一个13B的模型到公司服务器上,单卡A100 80G跑起来倒是还行,但并发一上来就显存溢出,报OOM错误。我试了GPTQ量化到4bit,精度有点下降但还能忍,结果显存占用还是跑满。问了同事,有人推荐用Flash Attention,有人建议上多卡张量并行,但我搞不清楚这些方案到底怎么落地。有没有大佬分享一下实际部署中压显存的成熟套路?或者有没有什么简单的trick能先顶住小流量?感谢!
部署开源大模型到生产环境,显存总不够用怎么办?
全部回复
共 161 条Flash Attention确实该上,它主要省的是中间激活值的内存,13B模型在长序列下这块占用很夸张,装了之后吞吐能明显改善。张量并行是另一个维度,两张A100跑起来比单卡稳得多,但要注意通信开销,最好用NVLink连接。如果想先顶小流量,可以试试把max_num_seqs调小,再配合continuous batching,vLLM里这两个参数对显存峰值影响很大。GPTQ 4bit精度损失你还能接受的话,不如看看AWQ,同是4bit但量化后激活值分布更友好,OOM概率会低一些。
这题我太有感触了,上个月刚用vLLM部署过7B模型,单卡也卡在显存瓶颈上。你提到GPTQ降4bit还跑满,我怀疑问题不在权重,而在KV Cache的预留策略上,vLLM默认会按最大并发预分配显存,小流量时特别浪费。建议你先把--gpu-memory-utilization调到0.85以下,再配合--max-num-seqs限制并发数,比如先压到16,这样能立刻缓解OOM。Flash Attention确实能省不少显存,因为它不存完整的注意力矩阵,但你要确认vLLM版本是否已经内置了它,新版其实默认就开了,不用单独配置。多卡张量并行是治本方案,但13B模型用2张A100的话,通信开销也不小,建议先用单卡把batch size和max-seq-len调好,比如把max-model-len从默认的4096砍到2048,很多场景下影响不大。另外一个小trick是开--enable-prefix-caching,如果你们有固定系统提示词,缓存命中后显存占用能掉一大截。如果流量再涨,建议研究一下PagedAttention的vLLM新版本,它比手动调参省心多了。最后提醒一句,先确认你们用的是最新vLLM,老版本对显存管理差很多。
vLLM本身已经集成了Flash Attention,建议先确认下是不是没开对版本,另外GPTQ 4bit之后显存还跑满的话,检查下是不是max-model-len设太大或者并发时的prefill和decode混在一起调度的问题。想快速顶住小流量,可以试试把KV cache的预留比例调小一点,或者限制一下最大并发数,虽然会牺牲点吞吐,但至少不OOM。多卡张量并行是治本的路子,不过要记得把模型切分和通信优化一起做,不然跨卡通信反而会让延迟变高。
Flash Attention确实是刚需,它能大幅减少KV Cache的显存占用,配合vLLM的PagedAttention效果立竿见影。你先把vLLM升级到最新版,开启--enable-prefix-caching,再试试把max-model-len调低点,很多场景下根本不需要那么长上下文。另外4bit量化后还爆显存的话,多半是并发数没控制好,用--max-num-seqs限制一下单卡并发,比盲目上多卡更稳。小流量期可以先开个--gpu-memory-utilization 0.9,把剩余显存全给KV cache,能多扛不少请求。
vLLM本身已经集成了Flash Attention,你只需要确认下版本和启动参数,这块基本是默认开启的,不用额外折腾。显存吃满更可能是kv cache和max_num_seqs的配置问题,把max_num_seqs调小到32甚至16,单并发延迟会涨一点但能立刻缓解OOM。张量并行是治本的路子,但两张A100跑13B有点浪费,不如直接上量化加投机采样,小流量下能把吞吐拉起来。另外可以试试把模型切到CPU offload几层,虽然慢但至少不崩,适合临时顶一下。
显存这块儿我踩过不少坑,说几个实际能用的。GPTQ 4bit已经压了权重,但OOM往往出在KV cache上,尤其并发一高,每个请求的KV都要占显存,你试着把vLLM的gpu_memory_utilization调低到0.85,留点余量给调度,别让它默认吃满。Flash Attention确实能省显存,但vLLM里其实默认就集成了,你得确认下是不是没开对版本,或者换用PagedAttention的块大小,小一点的块能减少碎片化。多卡张量并行不是简单堆卡,13B模型用2张A100的话,通信开销不小,小流量下可能反而变慢,不如先用单卡把max_num_seqs限制到8或者4,配合continuous batching,牺牲点吞吐换稳定。还有个土办法,把模型拆成半精度加NF4混合,或者用AWQ替代GPTQ,有时候在同样4bit下AWQ的显存峰值会更平滑。最后,如果只是临时顶小流量,可以考虑用bitsandbytes的8bit加载到CPU offload,把部分层放内存,虽然慢但至少不OOM。你试过把输入序列长度上限砍一半吗?有时候是长尾请求把显存顶爆的。
试试KV Cache量化加PagedAttention,vLLM里直接开这两个参数能省不少,小流量够用。
建议先砍max-seq-len和并发数,再上张量并行,Flash Attention是锦上添花别指望解决OOM。
vLLM本身已经集成了PagedAttention,理论上显存利用率应该比原生方案高不少,你确认下是不是没用对——比如max_num_seqs和gpu_memory_utilization这两个参数得手动调,默认值有时候很保守。我之前部署7B模型时把gpu_memory_utilization拉到0.95,并发直接翻了一倍。Flash Attention确实能省显存,但本质是优化attention计算,对长上下文场景特别有效,你如果主要是短对话,收益可能没那么明显。多卡张量并行是个正解,尤其是你单卡已经跑满的情况下,但要注意张量并行的通信开销,最好用NVLink连接的卡,否则速度可能不升反降。至于GPTQ 4bit还爆显存,我怀疑你加载时是不是没指定quantized_model参数,或者KV cache仍然以fp16存的,这部分可以单独量化成int8,能省不少。有个临时trick可以先顶着——把max_num_seqs调到16以下,同时限制最大输入长度,比如截断到1024 tokens,虽然会牺牲一点效果,但小流量测试肯定够用了。另外你查下是不是有显存碎片问题,vLLM有个--enable-chunked-prefill选项,打开后对高并发场景的显存利用率提升挺明显的,值得试试。
vLLM本身已经集成了PagedAttention,你如果没开--enable-prefix-caching的话可以先试试,小流量下命中缓存能省不少显存。另外OOM不一定全是权重占的,KV cache才是大头,建议先把--max-num-seqs调小,比如8甚至4,再配个--gpu-memory-utilization到0.9,先稳住别崩。Flash Attention主要是省显存+提速,但要配合--kv-cache-dtype fp8这类选项才明显,而且A100上得用Hopper架构的优化才有效果。多卡张量并行确实能分摊单卡压力,但你要注意通信开销,13B模型其实两卡80G就够,先把tp-size=2跑起来看吞吐再调。最后4bit GPTQ建议用--quantization gptq配合--dtype float16,别在vLLM里再额外转精度,容易踩坑。
我们组之前在70B上踩过同样的坑,你提到的GPTQ其实对13B收益有限,不如试下AWQ,同是4bit但激活值感知量化,精度损失会小一截。Flash Attention主要省的是中间激活的显存,跟量化不冲突,vLLM里直接开--enable-flash-attn就行,能多撑20%左右的并发。多卡张量并行不是简单堆卡,要改模型加载方式和调度策略,小流量阶段先用--max-num-seqs限制并发数,配合--gpu-memory-utilization调到0.9,能应急顶一阵。另外检查下是否开了--enforce-eager,有时候关掉CUDA graph反而能省点碎片显存。
vLLM本身支持paged attention,你说的Flash Attention其实是另一码事,主要省的是计算时间不是显存。我建议先开下--enable-prefix-caching,把共享前缀的请求缓存住,小流量下能明显降峰值。另外4bit GPTQ建议用AWQ或者GPTQ-Marlin内核,显存能再挤出来一点。真不行就上两张A100做张量并行,但注意13B模型2卡TP通信开销不小,小并发反而可能变慢。
vLLM的PagedAttention其实已经帮你把KV Cache管理得不错了,OOM大概率不是显存总容量的问题,而是峰值瞬间的碎片化。你可以先看一眼vLLM的日志,确认是不是max-model-len设太大导致预设的KV Cache空间被提前占满,试着把--max-num-seqs调小一点,比如从默认的256降到64,小流量下能立刻缓解。至于Flash Attention,它主要省的是计算时的中间显存,对KV Cache这种常驻占用帮助有限,但如果你用的是H100这种卡,开了能提升吞吐,间接减少排队等待带来的并发堆积,也算曲线救国。GPTQ 4bit精度掉得厉害的话,可以试试AWQ,对敏感层保护得更好,实测13B模型在A100上能省出差不多10G,而且不用改代码,transformers直接加载。多卡张量并行确实是最稳的路子,但要注意vLLM里TP的通信开销,两张A100互联带宽不够的话,可能并发没上去延迟先翻了倍,最好先查一下服务器是不是NVLink。还有个野路子,如果模型支持streaming输出,把--disable-custom-all-reduce打开,再配合response长度上限,能把短连接场景下的显存峰值压不少。最后,排障时记得开--enable-memory-profiling,看看实际峰值到底卡在哪一步,有时候是prefill阶段炸的,那就要考虑拆成chunked prefill了。
实在不行先砍max_num_seqs和max_model_len,很多场景下并发高都是因为序列长度把KV cache撑爆了,vLLM里这两个参数压一压能立刻见效。Flash Attention确实得开,省显存的同时还能提点速度,基本零成本改动。GPTQ到4bit还不够的话,可以看看AWQ,同精度下一般比GPTQ稳一点,但最好用你们业务数据跑一遍评测再定。多卡张量并行是正道,不过你得先把模型切成多卡推理,vLLM里设个tensor_parallel_size就行,但注意卡间通信带宽得够,不然延迟反而上去。小流量阶段先把单卡榨干,把vLLM的continuous batching调好,比盲目上多卡实在。
这问题太真实了,vLLM吃显存确实猛。你GPTQ量化后还跑满,大概率是max-num-seqs和gpu-memory-utilization没调好,先试试把gpu-memory-utilization设到0.9,再把max-num-seqs砍到64甚至32,小流量能立刻稳住。Flash Attention值得装,几行代码的事,长上下文下能省不少显存,但对你这个场景帮助可能没想象中大。真想彻底解并发问题,还是得上张量并行,两张A100把tensor-parallel-size设成2,显存直接翻倍,不过要记得把模型重新分片加载,vLLM里加个参数就行。
其实你这情况挺典型的,13B单卡A100并发一高就爆显存,光靠量化确实治标不治本。我之前试过把max_num_seqs调小,比如从256降到64,配合vLLM的continuous batching,小流量下能明显缓解OOM,先撑住上线再说。Flash Attention主要是省KV cache的显存,对长上下文和并发帮助很大,但得确认你模型架构支持,落地成本不高。张量并行的话,如果只有一张卡就别折腾了,真要多卡,注意张量并行维度要能被卡数整除,而且通信开销不小,最好先拿两张卡测下吞吐再决定。另外你也可以看看PagedAttention的开关,vLLM里默认开着,但有时候显存碎片反而更严重,手动调下gpu_memory_utilization到0.85,给CPU留点swap空间,说不定能挤出来几个GB。
说实话你同事提的这两个方向都是对的,但得先搞清楚瓶颈到底在哪儿。vLLM本身已经用了PagedAttention,如果你没开--enable-chunked-prefill,长prompt的显存碎片化会特别严重,建议先把这个参数加上试试,很多时候比量化管用。
关于Flash Attention,它主要是省了attention矩阵的显存,对长序列提升明显,但如果你并发高、单序列不长,收益其实有限。真正的关键在KV cache——13B模型就算4bit,单请求的KV也占不少,并发32时光缓存就可能吃掉30G+。你可以用vLLM的--max-num-seqs和--max-model-len调小一点,比如限制最大序列长度到2048,再配合--gpu-memory-utilization设成0.9,让缓存尽量塞满但不爆。
多卡张量并行确实是最稳的解法,两张A100跑TP=2,显存翻倍,但要注意通信开销,建议用NVLink连接。还有个土办法:如果业务能接受,把输入prompt做截断,或者用--multi-step-streaming减少中间态,都能缓一口气。
最后提个容易忽略的点:检查下你的HuggingFace模型是不是带了不必要的embedding头,比如lm_head的权重和tie-word的情况,有些模型能省1-2G。我上次就是被这个坑了,删除后直接降了10%占用。小流量的话,先限个并发数,配合上述参数调优,撑到加卡应该没问题。
量化到4bit还OOM的话,先看看是不是max_model_len开太大了,vLLM默认的KV cache预分配很激进,调小gpu_memory_utilization到0.85左右试试。Flash Attention主要是省计算不是省显存,真正压显存还是得靠KV cache量化或者PagedAttention那块。多卡张量并行落地其实不难,vLLM加个tensor_parallel_size=2就行,但卡间通信会有额外开销,小流量场景性价比不高。临时顶一下的话可以限制并发数或者开enable_prefix_caching,能省不少重复的KV。
13B单卡80G并发上来还OOM,瓶颈大概率在KV cache而不是权重,先试试调小max_num_seqs和gpu_memory_utilization,把block_size设成16也能省不少。Flash Attention值得开,vLLM基本自带,多卡张量并行落地其实就加个tensor_parallel_size参数,别想太复杂。真要顶小流量,先把max_model_len压到实际需要的长度,很多人默认开满纯属浪费。
vLLM的gpu_memory_utilization调低点,再开enable_prefix_caching,小流量基本能稳住。
13B单卡A100还OOM,八成是KV cache没控住,不是模型权重的问题。vLLM启动时把gpu_memory_utilization调低点,比如0.85,再限制max_num_seqs和max_model_len,小流量基本能稳住。量化对权重有用,但并发上来KV cache才是吃显存的大头,可以试试开enable_prefix_caching。张量并行落地没那么玄乎,vLLM加个tensor_parallel_size=2就能跑,前提是机器有多卡。