最近在搞一个内部用的智能客服,选了个7B的模型,用vLLM部署在单张A100上。离线测试时感觉还好,一上线并发一上来,响应时间直接奔着10秒去了,用户狂吐槽。我试了调低max_num_batched_tokens和换量化,效果不明显。想问下大家,有没有比较成熟的方案或者参数调优经验?比如是否一定要上多卡推理?或者有没有轻量级的替代框架?另外,是不是我的batch设置有问题?求指点,谢谢!
部署7B模型到生产环境,推理速度慢得离谱,请问怎么优化?
全部回复
共 164 条我之前也踩过类似的坑,A100单卡跑7B其实瓶颈往往不在显存,而在prefill和decode的调度上。试试把vLLM的continuous batching打开,然后重点调一下gpu_memory_utilization,别让它默认只用到80%多,留一点给KV cache反而能扛更高并发。另外如果业务允许,把max_model_len砍到2048或者更短,响应时间能降一大截,毕竟客服场景问题通常不会太长。多卡暂时没必要,先看看是不是prompt太长导致的,我上次就是被这个坑了。
我之前也踩过类似的坑,单卡A100跑7B理论上不该那么慢,先查一下是不是vLLM的continuous batching没生效,把max_num_seqs调大点试试,有时候默认值太小反而会卡。另外你这10秒是首token延迟还是总时长?如果是首token慢,问题多半在prefill阶段,可以试试把模型切成AWQ或者GPTQ的4bit,显存占用降下来之后吞吐会好不少。多卡的话其实不太建议直接上,除非并发特别高,不然通信开销可能比单卡还亏,可以先看看是不是prompt太长导致显存碎片化,用vLLM的--enable-chunked-prefill选项能缓解。
单张A100跑7B还这么慢,八成是并发把prefill撑爆了,试试把max_num_seqs调小点,再开个continuous batching看看。
先查下并发时的kv cache和prefill占比,瓶颈多半在调度,试试把max_num_seqs调小到8-16。
单张A100跑7B不至于这么拉,看看是不是显存碎片或CPU offload在拖后腿。
先查下并发时显存是不是爆了,vLLM对长上下文和并发很敏感,把max_num_seqs调小试试,我上次调完从8秒降到3秒。
先查下并发时显存有没有被打满,vLLM的continuous batching参数调过没?之前我们调完这个延迟直接降了60%。
并发一上来就10秒,大概率是max_num_seqs太小导致排队严重,试试调到64以上顺便开continuous batching。
并发一上来10秒确实离谱,先查下是不是max_num_seqs太小堵住了,这参数比batch_tokens影响大多了。
单卡A100跑7B理论不至于这德行,要不试试把vLLM的continuous batching版本升到最新,老版本坑挺多的。
先查下输入输出长度是不是卡在prefill上了,7B单卡A100吞吐不该这么拉胯。
看到你说离线测试和线上并发差距这么大,我第一反应是这大概率不是模型本身的问题,而是vLLM的调度和显存管理在真实负载下没吃透。单张A100跑7B理论上吞吐量应该很能打,10秒的响应时间说明你的batch可能根本没堆起来,或者max_num_batched_tokens设得太保守导致GPU利用率极低,建议先看下vLLM的监控面板里GPU显存占用和每秒请求数,确认是不是在空转。
我之前遇到过类似情况,最后发现是输入输出的token长度分布太极端,长尾请求把prefill阶段拖垮了,后来用continuous batching配合动态超时,把长请求拆成流式输出,响应时间直接降了一半。你调低max_num_batched_tokens没效果,反而可能限制了并发能力,试试把它调大,同时把--max-model-len设成实际业务的最大长度而不是模型默认值,能省不少显存来装更多batch。
至于量化,如果你用的AWQ或GPTQ,注意下是否真的在推理时启用了,有些版本会默默回退到FP16。多卡不是必须的,但如果你实在调不动,可以考虑把模型切到2卡用张量并行,A100的NVLink带宽足够,延迟不会增加太多。另外轻量框架的话,可以试试llama.cpp的server模式,虽然吞吐不如vLLM,但延迟稳定性在某些场景反而更好。
还有个容易忽略的点,你的并发请求是不是都带超长的system prompt?如果把系统提示词单独做prompt caching,或者用vLLM的prefix caching功能,能省掉大量重复计算,我在类似场景实测能提升30%以上的有效吞吐。最后建议你压测时用真实的对话轮次数据,别用纯单轮短文本,不然测出来的参数跟生产完全对不上。
我之前也踩过类似的坑,单张A100跑7B理论上够,但并发一上来瓶颈往往在显存带宽和调度上。你试试把max_num_seqs调到64以上,同时开continuous batching,vLLM默认参数偏保守。另外别急着上多卡,先检查下是不是prefill阶段卡住了,把--enable-chunked-prefill打开,响应能降不少。如果还不行,可以看看PagedAttention的block大小,调成16或32有时有奇效。
单张A100跑7B按理说不该这么拉胯,先查下是不是并发时显存被打满导致swap了,看下vLLM的日志里有没有kv cache不足的警告。之前我遇到过类似情况,把--max-num-seqs调小到32左右,同时开continuous batching反而比硬堆batch效果好很多。另外如果你们的对话长度普遍长,试试--enable-prefix-caching,对客服这种高频相似问题提速挺明显的。多卡不一定必要,但要是并发超过50,建议还是拆成两个实例负载均衡,比单卡硬扛稳定。
响应慢先看并发和吞吐吧,vLLM默认配置不一定适合你场景,试试调大连续批处理窗口。
之前跑7B也遇到过类似问题,后来发现瓶颈往往不在vLLM本身,而是并发请求的prompt长度差异太大导致batch里padding浪费严重。试试把max_num_seqs调低到16-32,同时给每个请求设个最大token上限,效果可能比调batch tokens更直接。另外如果A100是40G版,可以开一下continuous batching的细节日志,看看实际吞吐卡在哪个环节。单卡跑7B理论上不该这么慢,建议先排查下是不是显存碎片化或者CPU offload被意外触发了。真要上多卡的话,tensor parallel至少能翻倍吞吐,但代价是额外显存带宽开销,先看看单卡瓶颈在哪再决定吧。
单张A100跑7B还这么慢,大概率不是vLLM的问题,你先看看是不是并发请求把显存吃满了导致频繁swap,或者max_num_seqs设太小了。我之前遇到类似情况,把max_num_seqs调到128、启用continuous batching后延迟直接砍半。另外你可以试试把模型切成4bit的AWQ量化,精度损失不大但吞吐能涨一截,多卡其实没必要,先单卡把参数吃透再说。你那边上线时的QPS大概是多少?如果一直有长尾请求,也可以考虑给vLLM加个前缀缓存(prefix caching),对客服这种重复问题效果特别明显。
单张A100跑7B理论上不该这么拉胯,建议先看下是不是并发请求把显存带宽打满了,vLLM的continuous batching对短对话场景提升很大,但长上下文会吃显存。你试过把max_num_seqs调小到64甚至32吗?另外响应10秒不太像纯推理瓶颈,确认下是不是prefill阶段卡住了,可以开vLLM的metrics看下TTFT和TPOT分别多少。我之前遇到过类似情况,最后发现是prompt里塞了太多历史消息,把上下文长度砍到2K以内,延迟直接降了70%。如果还是不行,再考虑下用FP8或者AWQ量化,A100对这两种支持都不错。
我之前也踩过类似的坑,单张A100跑7B其实瓶颈往往不在显存,而是卡在vLLM的continuous batching调度上。建议先看看服务端的首token延迟和吞吐曲线,如果并发一高就崩,大概率是max_num_seqs设太大了导致争抢,试着降到32甚至16,同时把max_model_len砍到你能接受的极限(比如2K),效果可能立竿见影。另外量化别用GPTQ,换AWQ或者FP8试试,配合vLLM的chunked prefill,体感能快不少。多卡不一定必要,但如果你非要上,tensor parallel=2比pipeline parallel好用,不过单卡调优空间其实挺大的。你目前用的vLLM版本是多少?新版0.6.x对调度器改了很多,升级一下说不定就解决了。
我之前也踩过类似的坑,单张A100跑7B按理说算力是够的,但并发一上来响应时间飙升,问题往往不在模型本身,而在vLLM的调度策略和显存管理上。你调max_num_batched_tokens没效果,可能是因为这个参数在低并发时影响不大,真正卡你的是连续批处理(continuous batching)的等待队列——vLLM默认会等够一批token才做推理,并发一高,等待时间就叠加了。建议你把vLLM升级到最新版,然后重点看--max-num-seqs(默认256)和--gpu-memory-utilization(默认0.9),试试把max-num-seqs降到64或128,同时把gpu-memory-utilization调到0.95,让显存多留给KV cache,这样单请求的排队延迟会明显下降。另外,你提到的量化,如果用的是AWQ或GPTQ,在7B上对A100来说收益不大,反而可能因为反量化开销拖慢速度,不如试试FP8或者直接BF16配合更小的batch。轻量替代框架的话,其实不用换,vLLM就是目前最成熟的,但可以看看TensorRT-LLM,它对A100优化更激进,不过配置起来很折腾。最后,多卡不是必须,除非你要上更大的并发(比如100+同时在线),单卡A100只要调好参数,7B做到2-3秒响应是没问题的。你现在的batch设置具体是多少?如果方便的话贴一下vLLM的启动命令,我可以帮你看看是不是--max-model-len设太大了,那个也会拖累性能。
你查过input长度没?并发上来时padding浪费太多算力也会拖慢,试试把max_model_len设小点。
vLLM的continuous batching吃显存,A100上7B不该这么慢,先看下是不是CPU offload或者磁盘swap在作怪。
我之前也踩过类似的坑,单卡A100跑7B其实瓶颈往往不在显存,而在连续批处理和调度上。你可以看看是不是max_num_seqs设得太保守,适当调大并发窗口,配合vLLM的continuous batching能明显提升吞吐。另外,试试把模型切成4bit(比如GPTQ或AWQ),虽然单token延迟可能没降多少,但能塞进更大的batch,整体响应会好很多。多卡暂时不急,先把vLLM的版本升到最新,老版本调度问题挺多的。你那个10秒是首token还是完整回复?如果是首token慢,可能得看看prefill的优化,比如用下chunked prefill。