最近在尝试用vLLM部署一个微调过的Qwen2.5-7B模型,单卡A100,开了tensor parallel=1,max_num_seqs设到了256。压测的时候发现QPS只能到10左右,GPU利用率一直在30%晃荡,显存倒是跑满了。我看别人都说7B能跑到30-50 QPS的,是不是我参数设置有问题?还是vLLM版本太旧?或者是不是我的prompt太长(平均1.5k tokens)导致的?有没有大佬能指点一下,该从哪里排查?感谢!
用vLLM部署7B模型,QPS上不去,GPU利用率才30%怎么回事?
全部回复
共 134 条平均1.5k tokens的prompt确实太长,batch打不满,建议把max_num_seqs调小到64试试,同时检查一下是否被prefill阶段卡住了。
看到你这个情况我第一反应就是prompt长度的问题,平均1.5k tokens确实太长了,vLLM在处理长上下文时prefill阶段的计算量会暴涨,而且显存占满说明大部分资源都耗在了KV cache上,真正做decode的算力反而没跑满。我之前用13B模型试过,同样单卡A100,short prompt随便能上40 QPS,但一旦把上下文拉到2k左右,直接掉到15不到。你可以试着把max_num_seqs调低一点,比如降到64或32,因为256这个值在长prompt场景下反而容易导致显存碎片和调度瓶颈。另外检查下vLLM版本,旧版本对长序列的优化确实不太好,建议升到0.4.2以上,它改进了prefix caching和chunked prefill,对长prompt有明显提升。还有个思路是看看是不是你微调后的模型用了特殊token或者padding方式导致vLLM的优化失效了,试着用官方Qwen2.5原始权重跑一下同样测试,排除模型本身的问题。最后记得看看压测工具是不是本身有瓶颈,比如并发连接数或者请求发送速率限制,有时候瓶颈不在服务端。
长prompt确实影响很大,1.5k token下显存都占满了,试试把max_num_seqs调小点看看能不能提上去。
看到这个GPU利用率30%但显存跑满的情况,大概率是显存带宽瓶颈了,而不是算力不够。你平均1.5k tokens的prompt确实偏长,vLLM在处理长序列时prefill阶段的计算量会暴涨,但decode阶段又很吃访存,导致整个推理过程被显存带宽卡住。我之前用8B模型也是类似情况,后来把max_num_seqs调低到64,同时开启--enable-prefix-caching(如果prompt有重复前缀的话),QPS反而提升了一倍。另外检查下vLLM版本,0.6.0之后对长序列的调度优化了不少,旧版本确实有调度器空转的问题。你还可以试试把block_size从默认16改成32,减少显存碎片,有时候能挤出一部分带宽。不过说实话,7B模型在长prompt场景下QPS 10已经算正常了,别人说的30-50多半是短prompt(几十tokens)加高并发跑出来的,别太迷信那个数字。
说实话你这个问题我上周也刚踩过坑,感觉核心瓶颈不在框架本身,而是prompt长度和显存分配的逻辑。1.5k tokens其实已经算长文本了,vLLM的prefill阶段会占用大量计算资源,而decode阶段又因为显存被KV cache占满导致batch size上不去,所以GPU利用率低是正常的。你可以试试把max_num_seqs调低到64或者32,同时把max_model_len缩小到2048甚至1024,这样显存压力会小很多,说不定QPS反而能提上来。另外检查一下vLLM版本,0.4.0之后的版本对长prompt的调度优化了不少,如果还在用0.2.x建议升级。还有个小技巧:压测的时候可以搭配--enable-prefix-caching,对重复性prompt会有奇效。至于别人说的30-50 QPS,大概率是短文本场景下的数据,默认prompt长度可能就几十个token,所以参考意义有限。
prompt长度1.5k确实是个关键点,vLLM的prefill阶段在这种长序列下会占很多时间,而且你max_num_seqs设到256,显存满了但GPU利用率低,可能是请求排队等待推理导致的。可以试试调低max_num_seqs到64或128,同时打开--enable-prefix-caching看看效果。另外检查下vLLM版本,0.4.x和0.5.x在调度策略上差别挺大的,升到0.6以上可能会改善。
prompt平均1.5k tokens确实是主要瓶颈,vLLM的prefill阶段会吃满算力但decode阶段又很闲,导致整体利用率上不去。你试试把max_num_seqs调小到64或者32,同时把--block-size改成32,这样能减少显存碎片,提高batch的吞吐效率。另外可以检查下是否开了--enable-chunked-prefill,这个对长prompt场景有奇效,能平衡prefill和decode阶段的负载。如果还不行,建议升级到vLLM 0.6.0以上版本,老版本对长序列的调度确实有点拉胯。
1.5k的prompt长度确实是关键瓶颈,vLLM的prefill阶段会占大量算力,你试试把max_num_seqs调到64以下,同时开一下--enable-chunked-prefill参数,应该能缓解GPU空转的问题。另外检查下你压测的并发请求数,如果并发不够高,单卡A100的算力也喂不饱,建议并发调到32以上再试。我这边用类似配置跑7B,prompt控制在1k左右时QPS能到25+,长prompt确实对吞吐影响很大。
A100单卡跑7B模型,GPU利用率只有30%确实不太正常。你提到的1.5k tokens平均长度很可能是瓶颈,vLLM在处理长序列时显存带宽会成为限制因素,可以试试把max_num_seqs调低到64或128,同时检查下prefill阶段是不是占用了太多时间。另外建议确认下vLLM版本是不是0.6.x以上,旧版本对长上下文支持确实差一些,还有看看是不是用了--enable-prefix-caching,这个对长prompt有优化效果。
prompt平均1.5k确实挺长的,vLLM处理长序列时prefill阶段占主导,GPU利用率上不去很正常,尤其是7B模型显存带宽容易成瓶颈。你可以试试把max_num_seqs调低一些比如64或128,同时开启--enable-chunked-prefill,应该能让利用率提起来。另外看看是不是用的vLLM 0.4.x版本,老版本调度确实差一些。
prompt太长确实是瓶颈,1.5k tokens会严重拖慢解码速度,试试压短到512看QPS能不能翻倍。
你这情况大概率是长prompt导致的,vLLM在prefill阶段的算力开销和prompt长度强相关,1.5k tokens会严重挤占decode阶段的budget。可以试试把max_num_seqs调低到32或64,同时开一下--enable-prefix-caching看看效果,另外确认下vLLM版本是不是0.6.0以上,老版本的调度策略在长序列下确实容易跑不满。
1.5k tokens的prompt确实挺长的,这很可能是瓶颈,vLLM在处理长序列时prefill阶段会吃掉大量算力,但decode阶段又喂不饱GPU。你可以试试把max_num_seqs调低到64或32,看看单batch的throughput有没有改善,同时检查下是不是因为显存被打满导致KV cache频繁eviction。另外建议更新到最新版vLLM,0.6.x之后对长序列的调度优化了不少。
prompt太长确实是瓶颈,1.5k tokens会显著拉低QPS,试试把max_num_seqs调低到128看看。
prompt长度确实是关键因素,1.5k tokens对7B模型来说prefill阶段开销很大,GPU利用率上不去很可能是因为大部分时间花在了计算attention上。建议你试下把max_num_seqs调低到64或32,同时检查下vLLM的版本,0.4.0之后对长序列有优化。另外可以看看输入输出的token比例,如果输出也长的话,decode阶段的显存瓶颈会更明显。
平均1.5k tokens太长啦,vLLM的prefill阶段会卡住,试试把max_num_seqs调低或者缩短prompt长度看看。
prompt长确实是关键瓶颈,1.5k tokens下7B模型的生成效率会被显存带宽卡住,vLLM的连续批处理优势很难发挥出来。你可以试试把max_num_seqs降到64或更低,同时检查一下是否开启了prefix caching,这个对长prompt场景帮助挺大的。另外确认下vLLM版本是不是0.6.x以上,老版本在长序列优化上有差距。如果你压测用的是固定长prompt,可以试试混合不同长度请求,看看利用率会不会上去。
你prompt太长会严重拖慢首token速度,试试把max_num_seqs调低到64,再开个prefix caching看看。
看到你说prompt平均1.5k tokens,这基本就是核心原因了。vLLM的prefill阶段对长上下文非常敏感,1.5k的输入会导致每次推理的prefill时间显著拉长,而decode阶段相对占比变小,GPU在prefill时利用率可能跑满,但decode时又因为batch size不够大而空闲,整体利用率就上不去。你max_num_seqs设到256,但实际能同时处理的序列数受显存和KV cache限制,长prompt下有效并发可能远低于这个数,QPS自然被卡住。
建议你先用短prompt(比如128 tokens)压测一下,看看QPS能到多少,如果恢复正常,那就是prompt长度的问题。另外可以检查一下vLLM的版本,0.4.x以后对长序列的调度有优化,如果还在用0.3.x可以考虑升级。还有个小技巧:试试调低max_num_seqs但提升max_model_len,或者启用enable_prefix_caching来复用公共前缀的KV cache(如果你的prompt有固定前缀),这两个改动对长prompt场景有奇效。最后,A100单卡跑7B长prompt做到30-50 QPS确实有难度,那个数据一般是短prompt+高并发场景下测出来的,别太焦虑。
prompt长度确实是关键瓶颈,1.5k tokens的平均长度下,prefill阶段的计算量会显著拉长TTFT,导致GPU在等待数据时利用率上不去。建议先试试把max_num_seqs调低到64左右,配合更短的prompt(比如256 tokens)看看QPS和利用率有没有改善。另外可以检查下vLLM版本,0.4.0之后的版本对长序列和continuous batching有优化,升级到最新版可能直接解决问题。你压测用的数据集长度分布是怎样的?如果长尾特别多,可以尝试用padding策略提前截断。