最近在尝试用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 条prompt太长确实影响大,1.5k tokens的TTFT和显存占用都会拖垮吞吐,建议先缩短压测序列长度对比下。
这大概率是prefill和decode阶段混在一起导致的,1.5k的prompt长度对7B来说prefill计算量不小,而vLLM默认调度策略可能让GPU在prefill时吃满、decode时又闲着,整体利用率就被拉低了。你可以试试把max_num_seqs调小到64左右,同时打开--enable-chunked-prefill,让prefill和decode交错执行,QPS应该能有明显提升。另外确认下你的vLLM版本是不是0.6以上的,老版本对长prompt的优化确实差不少。我这边之前也是类似配置,调完这些之后7B能稳定到25+,虽然离30-50还有点距离,但至少利用率能到60%以上了。
prompt长度影响很大,1.5k tokens会显著拉低吞吐,建议先把max_num_seqs调回64试试,另外检查下vLLM版本有没有开continuous batching。
显存跑满但算力闲置,大概率是显存分配给了KV cache和中间激活,但实际计算没打满。1.5k的prompt长度对7B来说确实偏长,prefill阶段占比太高,decode阶段又串行,可以试试把max_num_seqs调低到64看看,有时候并发太高反而增加调度开销。另外检查下vLLM版本,0.4.x和0.5.x的调度策略差异挺大的,我之前升级后同样配置QPS直接翻倍。如果还不行,建议用--enable-chunked-prefill,能把长prompt拆开处理,对你这场景应该有效。
这情况我遇到过,先别急着怀疑版本,你prompt平均1.5k tokens确实是个大坑,prefill阶段计算量爆炸,但decode又吃不满算力,所以利用率看着就低。试试把max_num_seqs调小到64或32,给每个请求多留点并行空间,同时开下continuous batching的日志看下实际调度情况。另外确认下是不是显存都花在KV cache上了,如果seq长度波动大,建议用vLLM的chunked prefill,能把prefill和decode混起来,QPS能明显涨。我这边7B模型压测,prompt缩短到500token后,利用率能到60%+,你可以先拿短prompt做对照实验。
看到你这个情况我第一反应是prompt长度嫌疑最大,1.5k tokens的输入会让prefill阶段吃掉大量显存和算力,decode阶段反而被压缩了,可以试试把平均长度降到500以内对比一下。另外max_num_seqs=256在长上下文下未必是好事,batch太大反而会加剧显存碎片,可以调小到64或128看看。vLLM版本也值得查一下,老版本对Qwen2.5的attention优化不到位,建议直接升到最新版,顺便确认下是不是没开--enable-prefix-caching。我之前跑类似模型时遇到过同样问题,最后发现是压测工具发请求太密集导致CPU成了瓶颈,你可以在服务端看下CPU有没有打满。
你这个prompt长度确实是个大坑,1.5k tokens意味着prefill占了绝大部分算力,decode阶段根本吃不满GPU,QPS自然上不去。建议先看看vLLM的server端日志,确认是不是卡在prefill上,可以把max_num_seqs调低到64试试,给decode留更多batch空间。另外确认下是不是开了continuous batching,老版本没这个特性的话性能会差很多。还有个小技巧,压测的时候用固定短prompt对比一下,如果QPS能翻倍,那问题就锁定在长上下文上了。
显存跑满但利用率低,大概率是显存带宽瓶颈,A100跑7B本来就有这个特性,尤其是长prompt场景。你可以试试把max_num_seqs调低到64或32,减少并发batch,有时候反而能提升单batch效率。另外检查下vLLM版本,0.4以后的版本对连续批处理优化差别挺大,老版本确实容易吃不满GPU。1.5k的prompt长度影响确实不小,但10 QPS还是偏低,建议用ncu或者nsys抓一下kernel时间,看看是不是卡在prefill阶段了。
你这prompt长度影响挺大的,1.5k tokens的prefill会吃掉大量算力,试试把max_num_seqs调低点或者用chunked prefill。
显存跑满但算力闲着,这典型是卡在显存带宽或者KV cache的分配逻辑上了。你试试把max_num_seqs调小到64甚至32,有时候并发太高反而让vLLM的调度器频繁做preemption,开销全耗在管理上。另外1.5k的prompt确实是个大问题,7B模型这长度下prefill阶段的计算量很夸张,而decode阶段又太短,导致GPU流水线一直断断续续的。你可以用vLLM自带的benchmark脚本,分别测一下固定输入输出长度比如512+128和1024+512,看看QPS差距有多大,这样能直接确认是不是长度影响的。还有个小细节,确认下你的vLLM是不是开了continuous batching,老版本这功能默认没启用,性能差好几倍。另外A100上建议把dtype换成FP16或者BF16,别用默认的FP32,显存带宽利用率能上来不少。最后检查下你的压测工具是不是多线程发的请求,单线程发的话网络延迟也容易把吞吐卡死。
显存跑满但算力闲置,大概率是显存带宽卡脖子了,1.5k的prompt长度确实会让prefill阶段占比过高,试试把max_num_seqs调低到64甚至32,同时打开--enable-prefix-caching看看能不能复用历史KV cache。另外检查下是不是输出长度也很长,decode阶段吞吐上不去QPS自然就难看,可以先用固定短输出压测排除变量。
prompt长确实影响很大,1.5k tokens的TTFT和显存占用都上去了,试试把max_num_seqs调低点或者换短prompt压测对比下。
prompt太长确实会拖垮qps,试试把max_num_seqs调低到64,同时开下continuous batching看看。
这题我熟,之前部署Qwen2.5-7B也遇到过一模一样的现象。你提到prompt平均1.5k tokens,这基本就是主因了——prefill阶段计算量太大,但decode又很快,导致GPU在等待请求排队时摸鱼。建议先把max_num_seqs降到64试试,同时检查一下是否开了continuous batching的开关,vLLM老版本对长prompt的调度优化差别挺大的。另外你压测用的什么工具?如果是单线程发请求,也会把QPS卡在10左右,换个并发工具可能直接就翻倍了。
你的显存跑满但GPU利用率低,大概率是prefill阶段卡住了,1.5k的prompt对7B来说batch内计算量挺吃紧的,试试把max_num_seqs降到64左右,同时开--enable-prefix-caching看下有没有改善。另外确认下vLLM版本,0.4以上对连续批处理调度优化差距挺大的,老版本QPS上不去很正常。也可以看看是不是输出长度限制设太低导致频繁调度,把max_tokens调大点对比下。
prompt长度影响很大,1.5k tokens的prefill阶段会吃掉大量算力,试试把max_num_seqs调低到64看下。
显存跑满但利用率低大概率是显存带宽瓶颈,换个短prompt压测对比下就能定位问题。
prompt长度确实是个关键变量,1.5k tokens会让prefill阶段占比很高,而vLLM的continuous batching对长序列的吞吐优化有限,建议先试试把max_num_seqs调小到64或128,同时对比下固定短prompt的压测结果。另外可以看下vLLM的server日志里有没有调度等待或block管理器报错,老版本对长上下文支持确实有性能坑,升级到最新版顺便开下--enable-chunked-prefill试试。我这边之前遇到过类似情况,最后发现是output长度设太长导致显存被预留,实际计算没跑满,你可以把max_tokens调低再测一轮。
平均1.5k的prompt确实会拖后腿,decode阶段还好,prefill占用的算力被拉高了,QPS自然上不去。建议先看看首token延迟和TTFT,如果这个很高,基本就是prefill瓶颈。另外max_num_seqs=256可能太大了,超过并发后请求排队反而浪费显存,试试调低到64或者128,同时把--max-model-len设成跟实际长度匹配,别让显存被padding占满。我上次用2.7版本遇到类似情况,升级到最新版后调度效率明显改善,你也可以试试。还有个小技巧,压测时用固定长度且短一点的输入(比如256 tokens),对比一下QPS,能快速定位是不是长文本引起的。
这个瓶颈大概率卡在显存带宽上了,1.5k的prompt会让prefill阶段占比很高,而A100的算力在decode阶段喂不饱。你可以先试试把max_num_seqs降到32左右,再开一下--enable-chunked-prefill,看看QPS有没有变化。另外如果方便的话,用nvidia-smi dmon盯一下GPU的SM利用率和显存读写速度,如果SM不高但显存带宽打满,那基本就是长prompt的锅了。
prompt长确实吃显存带宽,1.5k tokens这吞吐正常,试试把max_num_seqs调低点看延迟换吞吐。