最近在搞一个内部用的智能客服,选了个7B的模型,用vLLM部署在单张A100上。离线测试时感觉还好,一上线并发一上来,响应时间直接奔着10秒去了,用户狂吐槽。我试了调低max_num_batched_tokens和换量化,效果不明显。想问下大家,有没有比较成熟的方案或者参数调优经验?比如是否一定要上多卡推理?或者有没有轻量级的替代框架?另外,是不是我的batch设置有问题?求指点,谢谢!
部署7B模型到生产环境,推理速度慢得离谱,请问怎么优化?
全部回复
共 164 条并发一上来响应飙到10秒,这情况我也遇到过,vLLM默认的调度策略对7B模型其实不太友好。你可以试下把max_num_seqs设到16或32,再把block_size调大点比如64,能明显减少显存碎片和调度开销。另外单卡A100跑7B其实够用,但得看你的QPS,要是并发超过几十,上多卡做tensor parallel还是更稳,毕竟吞吐能翻倍。量化的话,AWQ比GPTQ在推理速度上更友好,而且精度损失小,不妨试试。
单卡A100跑7B模型并发一上去响应飙到10秒,这情况挺常见的,vLLM对显存管理其实还有优化空间。建议你试试把max_num_seqs(不是那个batched_tokens)设小一点,比如32或者16,另外检查一下vLLM版本是不是最新的,老版本有些调度问题。如果并发量实在大,上多卡用tensor parallelism确实能线性提升吞吐,单卡扛不住的。另外可以看看是不是prompt太长导致的prefill阶段瓶颈,把系统提示词压短也能缓解不少。
vLLM本身不慢,你大概率是并发策略没调好,试试把max_num_seqs设到256以上。
试试调大vLLM的max_num_seqs,再配合FlashAttention,单卡A100撑7B不至于10秒那么夸张。
实测单卡A100跑7B模型,并发上来后瓶颈主要在显存带宽和batch size的平衡上。建议先检查下vLLM的调度策略,把max_num_seqs适当调小(比如从默认256降到64或32),同时开启--enable-chunked-prefill选项,能明显减少首token延迟。另外如果业务场景允许,试试用FP8量化或者AWQ,推理速度能提升30%以上。多卡方案成本高,不如先压榨单卡性能,或者考虑用更轻量的推理框架如TensorRT-LLM,它的动态批处理优化比vLLM更激进。
试试调大dynamic batch的等待时间,或者换FlashAttention,单卡也能压到2秒内。
单张A100跑7B并发一高就崩到10秒,这个我太熟了,vLLM默认的调度策略其实对burst请求挺不友好的。建议你先看看是不是prefill阶段占太多显存,试着把max_num_seqs设小一点,比如8或16,或者调低gpu_memory_utilization到0.85左右,给KV cache多留点余量。另外如果业务允许,上FP8或AWQ量化能直接省一半显存带宽,延迟会好看很多。多卡的话其实不是必须,但如果你并发超过20路,单卡确实扛不住,可以试试Tensor Parallel加两张卡。
老实说7B在A100上单卡推理跑成这样确实不太正常,vLLM的continuous batching按理说对并发支持挺好的,你要不先看看是不是请求长度差别太大导致显存碎片化?我之前也遇到过类似情况,后来把max_num_seqs调到64、开启--enable-prefix-caching,响应降到了2-3秒。另外如果对精度要求不高,可以试试FP8或AWQ量化,效果比GPTQ明显。多卡的话暂时不用上,先排查下是不是batch策略或者HuggingFace tokenizer的预处理拖了后腿。
可以试试张量并行切分到两张A100上,结合vLLM的continuous batching,延迟能降不少。
先查下并发时GPU利用率,大概率是prefill和decode抢资源,试试把max_num_seqs调小点。
之前跑7B也踩过这坑,单卡A100并发一上来vLLM的continuous batching反而容易卡在调度上。你试试把max_num_seqs调小到16-32,同时开--enable-chunked-prefill,前缀缓存命中率能上来不少。另外别急着上多卡,先看下是不是显存带宽瓶颈,可以试试FP8或者AWQ量化,我这边延迟能从10秒压到3秒左右。还有个思路是换llama.cpp的server模式,对并发控制更细,就是吞吐上限低些。
单张A100跑7B其实算力是够的,问题大概率出在并发调度和显存带宽上,vLLM的continuous batching对短请求优化很好,但你们客服场景如果句子长、历史对话多,prefill阶段会卡住整批请求。先看看是不是max_model_len设太大了,把显存都占满导致KV cache不够用,可以试试把max_num_seqs调小到16或者32,同时开一下--enable-chunked-prefill,这个对长prompt的并发提升特别明显。量化的话别用GPTQ,AWQ或者FP8在A100上更稳,但说实话7B模型量化后质量下降在客服场景可能感知不强。另外你提到10秒响应,我怀疑是不是有用户请求里带了超长上下文,比如把整个聊天记录都塞进去了,可以加个prompt压缩或者截断逻辑,把历史轮次限制在10轮以内。如果这些都试了还不行,再考虑多卡,但其实单卡A100理论上能支撑50左右的并发,除非你们同时在线数超过这个量级。框架的话别换,vLLM已经是目前最优解了,你可以重点看看服务端的流式输出有没有开,有时候是客户端傻等完整response才渲染,体感上会慢一倍。最后建议你监控下GPU利用率,如果不到80%说明调度没吃满,可以试着调高--max-parallel-load-workers,或者用Ray在单机内多进程跑两个vLLM实例做负载均衡。
vLLM默认的continuous batching对并发场景其实挺吃显存调度的,你那个max_num_batched_tokens调低反而可能限制了吞吐。建议查一下是不是卡在prefill阶段,试试把--enable-chunked-prefill打开,或者调高--max-num-seqs看看。另外单卡A100跑7B理论上不该这么慢,检查下是不是CPU绑核或者GPU利用率没上去,多卡其实不是必须的。
并发一上来慢多半是prefill和decode混跑互相挤占,试试把max_num_seqs调小点或拆成两个实例分开处理。
我之前也踩过这坑,后来加了APC缓存命中率上来了,延迟直接砍半,你可以先看看token复用情况。
单张A100跑7B其实算力是够的,问题大概率出在并发调度和显存管理上,10秒延迟明显不正常。你试试把max_num_seqs调小点,比如8或16,同时打开vLLM的continuous batching,再给模型加个prompt cache,首token延迟能掉一大截。另外别急着上多卡,可以先看下是不是prefill阶段卡住了,用--enable-chunked-prefill参数能缓解长提示词阻塞。如果还不行,换TGI或者TensorRT-LLM对比下,有时候框架对特定模型的算子优化差异挺大的。
先查下p99延迟和吞吐曲线,瓶颈可能在prefill而非decode,试下chunked prefill加continuous batching。
之前跑7B也遇到过类似情况,后来发现瓶颈多半不在模型本身而在vLLM的调度上,你试试把max_num_seqs调小一点、同时加大max_model_len,有时候反而能提升吞吐。另外A100单卡跑7B其实够用,但并发高的话建议开一下continuous batching的开关,或者看看是不是显卡利用率没跑满,用nvidia-smi监控下。多卡不一定必要,先检查下是不是输入输出token长度分布太极端,长尾请求会拖慢整体延迟。
碰到过类似的情况,当时也是被并发搞到怀疑人生。你提到调低max_num_batched_tokens没用,我猜瓶颈可能不在batching本身,而是卡在了prefill阶段——尤其是长prompt的用户提问,prefill算力消耗会直接吃掉大量显存带宽,导致后续decode被堵住。建议你先把vLLM的日志打开,看看平均每请求的prefill和decode耗时分别多少,如果prefill占比超过一半,那问题就很明确了。
关于单卡还是多卡,其实不一定非要上多卡,A100单卡跑7B理论上能做到几百token每秒的decode速度,但并发一旦超过某个阈值,显存带宽就是硬瓶颈。可以试试把vLLM的continuous batching参数调得更激进一些,比如把max_num_seqs设到256以上,同时配合--enable-chunked-prefill,让prefill和decode交错执行,这样能显著提升吞吐。另外,你提到换量化效果不明显,估计是用的GPTQ或者AWQ,但没配合kv cache量化,建议试试FP8的kv cache,能省不少显存,间接提高并发容量。
还有个容易忽略的点,你的输入输出长度是不是被tokenizer限制得太死?如果用户问题平均200字,但你的max_model_len设到了4096,那每个请求都会预留大量padding空间,相当于白烧算力。我当时的做法是统计线上真实数据,把max_model_len砍到实际需求的1.5倍,响应时间直接降了40%。轻量级框架的话,可以看看TensorRT-LLM,虽然配置麻烦点,但优化过的prefill路径确实比vLLM快一截,尤其在低并发场景下。
最后问一下,你现在的qps大概是多少?如果就几十的并发,那大概率是配置问题,如果上百了,那可能真得考虑张量并行或者换更小的模型了。
之前也踩过类似的坑,单卡A100跑7B其实瓶颈往往不在显存,而是vLLM的调度和prefill/decode阶段没分开优化。你试试把max_num_seqs调大(比如64),同时开enable_chunked_prefill,对并发提升很明显。另外别迷信量化,AWQ或GPTQ在低并发下还行,高并发反而增加延迟,直接上FP16配合continuous batching更稳。如果还不行,建议看下是不是prompt太长,把历史消息截断到2K以内,响应能快一半。多卡暂时不急,先把单卡压榨干净再说。
你这情况我太理解了,单张A100跑7B理论上算力是够的,但vLLM的吞吐和延迟是两码事,离线测的是吞吐,上线看的是P99延迟。我怀疑你瓶颈不在显存,而在CPU和GPU之间的数据传输,尤其并发上来以后,prefill阶段会把batch撑爆,导致每个请求都得排队等decode。你可以试试把max_num_seqs调小,比如压到32甚至16,配合max_model_len也一起降,别让vLLM自作主张分配太多连续内存。量化的话,AWQ或GPTQ在7B上收益不大,不如直接上FP8,如果卡支持的话,能省不少显存带宽。另外,如果内部客服场景对延迟要求高,可以考虑把模型切到2卡用张量并行,A100的NVLink速度很快,单卡变双卡延迟能砍掉一大截。真要不想动硬件,换LightLLM或者SGLang试试,有时候框架的调度策略差异比参数调优更明显。你现在的batch_size是动态的吗?可以观察下vLLM的日志,看平均每批请求数是不是一直在高位。