最近在用vLLM部署Qwen2.5-7B做内部demo,单卡A100 80G,模型用AWQ 4bit量化。平时单路请求挺流畅,但压测时并发到8左右,显存直接涨满然后OOM,日志里有“CUDA out of memory”。我已经设置了--max-model-len 8192,也开了--gpu-memory-utilization 0.9,但感觉还是不够稳。看了下nvidia-smi,好像KV cache占得特别凶,但我没手动调--max-num-seqs,这个是不是关键?还是说AWQ量化后显存占用模型本身还是太大,应该换成GPTQ或者干脆上8bit?另外,vLLM是不是对动态batch的显存预留机制有什么坑?求有经验的大佬指点下排查方向,或者分享下你们生产环境的类似配置。先谢过。
vLLM部署Qwen2.5-7B,并发一高就OOM,是量化问题还是我参数没调对?
全部回复
共 76 条max-num-seqs不调的话默认会疯狂塞请求,KV cache当然爆,先限到4试试。AWQ本身没问题,主要是batch策略要吃显存。
我之前跑7B模型也踩过类似的坑,你这个问题大概率不是量化格式的锅,AWQ 4bit在A100上吃显存已经很小了,瓶颈基本都在KV cache上。--max-model-len 8192这个值其实挺保守的,但并发一上来,每个sequence的KV cache是线性增长的,8个并发每个假设平均2000 token,那总量就是8倍,哪怕模型权重只占10G,KV cache也能轻松吃掉20-30G,再加上你设了gpu-memory-utilization 0.9,vLLM会预分配这90%显存做KV cache池,一旦动态batch里请求长度分布不均,很容易就把池子挤爆。--max-num-seqs确实很关键,它控制了单次batch能塞多少序列,你默认值应该是256,建议直接降到4或8,配合--max-model-len再收紧一点,比如4096,这样每个seq的KV cache上限就锁死了,OOM概率会小很多。另外--swap-space也可以设个8或16,让vLLM把部分KV cache换到CPU内存,虽然会慢一点,但压测时至少不崩。至于GPTQ或8bit,除非你显存实在不够,不然没必要换,AWQ在vLLM里兼容性已经挺成熟了,问题基本都在调度参数上。对了,你压测用的是固定长度还是随机长度?如果是随机长文本,那还得考虑加--enable-prefix-caching,能省不少重复前缀的KV cache。
我之前也踩过类似的坑,问题大概率不在AWQ本身,而是--max-num-seqs没限制住并发batch大小。vLLM默认会根据显存自动调batch,但并发一高它容易把KV cache撑爆,你试试手动设成4或者8,配合--max-model-len降一点,应该能缓解。另外A100 80G跑7B量化模型理论上是够的,OOM更多是调度策略问题,不是模型大小问题。不过你如果还想压榨显存,可以看看--kv-cache-dtype是不是能设成fp8,效果比换GPTQ明显。
max-num-seqs确实得调,8并发不高但KV cache会爆,先限到4试试。
我之前也踩过这坑,开个--max-num-seqs 2配合量化就稳了,别全指望显存利用率。
说实话我觉得max-num-seqs大概率是关键,vLLM默认会按并发请求数动态分配KV cache,你不限制batch大小,它就会在并发高的时候疯狂预分配,8并发直接把KV cache撑爆很正常。AWQ 4bit模型本身也就占个5-6G,不至于OOM。建议先把这个参数压到2或4试试,再把gpu-memory-utilization降到0.85留点余量。另外可以开下--enable-prefix-caching,对内部demo的重复请求帮助挺大的,能省不少缓存。
你这个问题我上周刚踩过,--max-num-seqs确实很关键,默认值好像会按显存动态调,但并发一高它会把KV cache撑爆,建议手动设个8或者16试试。另外AWQ 4bit的显存占用其实比GPTQ还低一点,模型本身不是瓶颈,问题基本出在vLLM的调度策略上。顺便问下,你压测的时候有没有看/tmp里的日志,有时候会提示具体是哪个seq超了限制,比nvidia-smi直观多了。
说实话我觉得你大概率不是量化精度的问题,AWQ 4bit在7B上模型权重也就4G多,A100 80G完全扛得住。关键还是vLLM的KV cache调度,--max-num-seqs不设的话默认是256,这玩意儿会预分配大量显存给可能到达的序列,并发一高直接爆掉。你可以试着把它压到16或者32,同时把--max-model-len再降一点,比如4096,内部demo用8192确实有点奢侈。另外--gpu-memory-utilization 0.9看着合理,但vLLM实际是预留了这部分给KV cache和激活值,如果模型本身占得少,剩下的全被cache预占了,所以OOM更像是我说的这个原因,不是量化格式的问题。GPTQ和AWQ在显存占用上差别不大,换8bit反而会更吃显存,不建议。还有个点,vLLM对动态batching的显存分配确实偏保守,你可以试试--enable-prefix-caching看能不能省点,再不行就开--swap-space把部分cache挪到CPU。先调--max-num-seqs吧,这个影响最直接,大概率能解决。
max-num-seqs确实得调,8并发对7B来说太激进了,降到4试试,KV cache能省一大截。
说实话你这配置单路流畅是肯定的,A100 80G跑AWQ 4bit的7B模型模型权重才占4-5G,大头全在KV cache和激活值上。--max-num-seqs确实很关键,vLLM默认会按并发数动态分配,但压测到8时它会一次性把预留的显存全吃满,尤其你设了0.9的利用率,等于给KV cache留了很大空间但没限制batch上限,直接爆掉不奇怪。建议先把这个参数调到4或6试试,配合--max-model-len再缩到4096,很多场景下根本用不到8K上下文。另外AWQ和GPTQ在显存占用上差别真不大,主要看kernel优化,没必要急着换量化方案。不过你开了0.9利用率又没设--swap-space,vLLM会优先用显存做swap,一旦并发波动就可能瞬间冲高,我遇到过类似情况,加了--swap-space 8之后稳很多。还有个坑是动态batch请求长度差异大时,vLLM会把所有seq都pad到max-model-len,建议你压测时固定一下输入长度,或者开--enable-prefix-caching看看能不能缓解碎片化。最后提醒下,nvidia-smi里看到的KV cache占用是峰值,不代表平均值,建议用--tokenizer-pool-size和--limit-mm-per-prompt先做一个保守的并发上限,别迷信0.9这个数字。
max-num-seqs确实值得先调一下,8并发不算高,但vLLM默认会按显存余量拼命塞batch,KV cache膨胀起来比模型权重还快,你试试把它压到4或者6,再配合--max-model-len看会不会稳住。量化本身不是主要问题,AWQ 4bit在7B上已经很省了,GPTQ和8bit差距不大,换模型不如先看调度参数。另外你开0.9利用率其实留了10%余量,但A100上KV cache分配是动态的,建议用--kv-cache-dtype fp8试试能不能降峰值,这招在长上下文场景挺管用。还有个思路,压测时把并发请求的prompt长度控制一下,如果输入太长,8192的max-len会很快吃满缓存,OOM就更容易触发。
并发8就爆显存大概率不是量化精度问题,max-num-seqs不调的话默认会疯狂塞请求,你试试手动限到4或2看看。
这问题我也踩过坑,max-num-seqs不调的话默认值挺保守的,并发一高请求全挤进来,KV cache直接爆掉,建议先按并发数×2去设这个参数试试。AWQ本身显存占用比GPTQ小,但4bit在长上下文下KV cache才是大头,你max-model-len 8192其实不小了,可以算下每个seq大概吃多少显存。另外gpu-memory-utilization 0.9留的10%余量对动态batch来说可能确实不够,试试0.95,但得盯着点别把激活值也挤爆。你压测的时候看下vllm的日志里有没有提示“max_num_seqs”相关警告,那个比nvidia-smi直观多了。
max-num-seqs确实是关键,8并发下默认值会导致KV cache暴涨,手动调小到4试试。
--max-num-seqs确实得手动设一下,vLLM默认会按显存余量尽量多塞请求,并发一高KV cache就把显存吃满了,我之前跑13B模型也踩过这坑。AWQ 4bit本身占用不大,问题大概率出在调度策略上,你可以试着降到8或者4看看,再把--max-num-batched-tokens也限一下。另外动态batching本身就会放大显存波动,建议压测时观察下KV cache的峰值,别光看模型权重占了多少。
AWQ不是主因,先调--max-num-seqs把并发上限压住,KV cache才是吃显存的大头。
你这个情况大概率不是量化方式的问题,AWQ 4bit在A100上跑7B模型本身占不了多少显存,权重撑死也就5G左右,真正吃显存的是KV cache。vLLM默认的max-num-seqs其实挺激进的,你不手动限制它就会按显存上限去尽量多塞请求,并发一上来KV cache直接爆炸。我建议先把--max-num-seqs压到4或者6试试,同时把--max-model-len从8192降到你实际业务需要的长度,比如4096甚至2048,这两个参数对KV cache影响特别大。另外你可以开--enable-prefix-caching,如果内部demo有大量重复的系统prompt,能省不少显存。gpu-memory-utilization 0.9其实偏高,留点余量给CUDA context和临时buffer会更稳,0.85左右比较舒服。换GPTQ或者8bit没必要,方向错了,先把并发和序列长度这两个闸门收紧再说。