最近在折腾本地部署,用vLLM跑一个微调过的7B模型(Qwen2.5),显存占用大概14GB,但吞吐量一直上不去。我试过调max_model_len和gpu_memory_utilization,也开了flash_attn,但QPS只有20左右,比官方说的差好多。我看网上有人用同样的卡跑13B都能到50+,不知道是哪里配置有问题?还是说我的模型量化没做好?另外,我是用docker部署的,会不会有额外的性能损耗?求大佬指点一下排查方向,谢谢!
用vLLM部署7B模型,单卡A100推理速度只有20tokens/s正常吗?
全部回复
共 170 条20的吞吐确实不太对劲,我怀疑你docker里没把共享内存和NUMA绑对,之前我遇到过类似问题,加了--shm-size和--cpuset-cpus后性能直接翻倍。另外你确认下vLLM版本是不是太旧了,新版本对Qwen2.5的PagedAttention优化很明显。量化的话,如果只是PTQ没做AWQ/GPTQ,7B在A100上跑20也算正常,但官方benchmark通常用连续请求测的,你单流测QPS会低不少。可以先试试禁用docker裸跑对比一下,排除容器开销。
docker跑vllm性能损耗很小,重点查下是不是量化精度和prefill阶段没调好,20确实偏低。
试试把--max-num-seqs调大点,或者换awq量化看看,A100跑7B这速度不对劲。
20的吞吐确实偏低,我怀疑你docker里没开共享内存或者宿主机CPU限频了,vLLM的调度线程被卡住很影响生成。另外Qwen2.5对张量并行挺敏感的,单卡跑7B其实不需要,但你可以试试把max_num_seqs调高到256,别让它默认按batch=1跑。量化的话,AWQ比GPTQ在A100上更稳,不过你这显存占用14G看着像没量化,先确认下模型是不是FP16加载的。还有个坑,vLLM版本太旧对2.5支持不好,换个0.6.3以上版本可能直接翻倍。
20 tokens/s对于7B来说确实偏低,我拿A100跑Qwen2.5-7B一般能到40-60,但你得先确认是不是被微调后的权重结构拖累了。有些LoRA或全量微调会改变attention的shape,导致vLLM的paged attention没法走最优路径,你可以试试用官方原版模型对比一下,如果原版速度正常那就是权重问题。另外你说的docker损耗基本可以忽略,但记得检查下容器里是不是没开共享内存或者CPU绑核,vLLM的调度线程有时候会被容器限制住。量化这块,如果用的FP16没转AWQ或GPTQ,那显存占用14GB也算正常,但吞吐上不去可能跟prefill和decode的混合请求比例有关——如果并发请求里长prompt多,QPS会被prefill拖死。还有个容易忽略的点,vLLM的版本迭代很快,老版本对Qwen2.5的支持有bug,建议升到0.6.3以上。你试着把--max-num-seqs调小到8,同时固定--max-model-len为2048看下,有时候默认配置会预留太多KV cache导致实际batch变小。最后,如果20是单请求的流式输出速度,那很正常,但你说QPS,那肯定是并发没调好,记得用vLLM的异步接口或者加个代理层做并发控制。
20的QPS对7B来说确实低了,我怀疑是微调后模型结构变了导致vLLM没走优化路径,试试加--enable-prefix-caching看下。
Docker网络模式如果是bridge会有性能损耗,建议换host模式再测,另外确认下是不是被CPU瓶颈卡住了。
20的吞吐确实有点离谱了,我拿A100跑Qwen2.5-7B没量化都能到40+,你这明显不止是配置问题。先确认下是不是微调后模型结构有改动导致vLLM没走优化路径,另外docker本身损耗很小,但记得检查下是不是没开--tensor-parallel-size或者CPU内存交换到GPU了。max_model_len别调太大,设成训练时的最大长度就行,否则会浪费显存做KV cache。你试试用官方原版模型不加微调权重跑一下,如果速度正常那就是你merge权重时出了问题。
20的吞吐确实低了点,不过先别急着怪量化,Qwen2.5的7B在A100上跑出这数儿,大概率是max_model_len设太大导致显存碎片化,或者并发数没调起来。你可以试试把--max-num-seqs开到64,然后关掉--enable-prefix-caching看看,这俩对吞吐影响挺明显的。docker本身损耗可以忽略,但记得检查下容器里是不是绑了CPU的NUMA节点,有时候这玩意儿比GPU还拖后腿。另外你确认下是不是用了官方推荐的gptq或awq版本,fp16跑7B确实容易卡在内存带宽上。
20的吞吐确实偏低了,我怀疑瓶颈不在vLLM本身,而是你的微调模型可能没做weight only量化,FP16跑7B在A100上理论应该能到40+。你试试用--quantization awq或者gptq重新加载下,另外确认下是不是docker里没开共享内存,默认/dev/shm太小会导致KV cache分配卡顿。还有个小细节,max_model_len别调太大,2048就够了,超过这个值对吞吐影响很明显。
20的吞吐确实偏低,我怀疑瓶颈不在模型本身,而是docker里共享内存或CPU内存带宽没调好,试试加--shm-size和--ulimit memlock试试。另外你确认下vLLM版本,0.4以后对Qwen2.5的支持优化差别很大,旧版可能没吃到speculative decoding的红利。量化的话,如果显存没满就别急着上AWQ,INT8有时反而因为反量化开销拖慢速度。还有一个容易忽略的点,检查下输入输出的batch size是不是太小了,动态batching没生效的话,单请求延迟会被拉满。
查下是不是gpu_memory_utilization给太低了,留点余量给KV cache试试,docker确实会有点损耗但影响不大。
20的QPS对7B确实偏低,先确认下是不是微调后模型结构变了导致vLLM没走优化路径。
20的QPS对7B来说确实偏低了,我怀疑瓶颈不在vLLM本身,而是你docker的共享内存或者网络桥接模式在作怪,可以试试加--shm-size=8g和--network=host对比下。另外你检查过微调后的模型是否真的被vLLM正确加载了?如果用的是merge后的全量权重而不是LoRA adapter,有时会触发不同的算子路径。量化方面其实影响不大,除非你用了AWQ或GPTQ,不然FP16下A100跑7B理论吞吐应该比你现在高不少。建议先跑个官方unsloth的benchmark脚本,排除模型本身的问题,再看是不是CPU绑核或者NUMA设置了。
20 tokens/s对7B来说确实偏低了,不过先别急着怪量化,你检查过vLLM的版本和CUDA版本匹配吗?我之前遇到过类似问题,换成最新版vLLM后吞吐直接翻倍。另外,docker部署理论上损耗很小,但要注意是不是默认用了CPU做张量并行,或者显存被其他进程占了。你试试把max_num_seqs调大点,比如64或128,有时候这个参数对吞吐影响特别大。还有,微调过的模型如果加了额外的padding或特殊token,也可能拖慢速度,可以对比一下原版Qwen的跑分。
20 tokens/s对于7B模型来说确实偏低了,我怀疑你docker里的vLLM版本和宿主机驱动没对齐,特别是CUDA runtime和NCCL库,有时候容器里默认的libnccl版本和A100的驱动不匹配会直接砍半吞吐。另外你确认下是不是真的跑在A100上而不是被调度到别的卡了,nvidia-smi看一下容器内外的GPU-Util和温度,有时候供电限制也会导致频率上不去。量化这块我倒觉得不是主因,FP16跑7B本来就不该这么慢,除非你没开continuous batching,或者max_num_seqs设得太小导致请求排队。还有个容易忽略的点,Qwen2.5的attention用的是GQA,vLLM旧版本对GQA支持有性能bug,你试试升级到0.6.x以上或者用最新的nightly版,我遇到过类似情况,更新后直接从20跳到45。另外官方说的50+通常是用shareGPT数据集测的,平均输入输出长度在1000 tokens左右,你如果是短文本高并发测的,QPS掉到20也正常,因为调度开销占比变大了。最后docker性能损耗基本可以忽略,但记得用--gpus all和--ipc=host,否则共享内存太小会在prefill阶段卡IO。
你这吞吐确实不对劲,先看看是不是max_model_len设太大导致显存碎片化,我遇到过类似情况调小后直接翻倍。
20 tokens/s对7B来说确实偏低,但A100 40G和80G的差距也挺大,你确认下是不是跑在40G版本上?另外docker本身损耗很小,但别把CPU和内存限制设太死,vLLM的调度线程挺吃资源的。还有个坑是微调模型如果没合并LoRA权重,推理时会有额外开销,你检查下模型文件是不是完整导出。可以试试开--enable-prefix-caching,长对话场景下提升明显。
20的吞吐确实偏低了,我拿同款卡跑7B的Qwen2.5一般能到40以上。你docker挂载时记得加--shm-size参数,默认64M会严重影响vLLM的显存管理,另外检查下是不是微调时padding到了奇怪的长度,导致实际计算量虚高。还有你用的什么精度?FP16的话建议直接用默认的continuous batching策略,别手动调max_model_len,有时候反而会触发碎片化。
20的吞吐确实有点不对劲,我猜多半是max_model_len设太大了导致显存碎片化,或者gpu_memory_utilization给的余量太多,vLLM没吃满显存。你可以先看下nvidia-smi在跑的时候显存是不是真的用满了,如果只有14GB/80GB那肯定有问题。docker的话一般没大性能损耗,除非你没加--gpus all或者容器里驱动和宿主机版本不匹配。另外你那个“微调过的模型”如果没合并adapter,推理时基座+LoRA的overhead也会拖慢速度,建议先拿原版Qwen2.5-7B跑个baseline对比下。量化这块,FP16其实就够快了,除非你用了bitsandbytes的4bit反而会变慢,先别急着量化。
20 tokens/s对于7B模型来说确实偏低了,但先别急着怀疑量化,Qwen2.5在vLLM里默认走的是bf16,你如果没显式加--quantization awq或者gptq,那跟量化关系不大。我怀疑你docker的共享内存和NUMA绑定有问题,vLLM对内存带宽特别敏感,容器默认的shm-size只有64M,这会影响page cache命中率,建议加--shm-size=10g再试试。另外你max_model_len和gpu_memory_utilization具体调了多少?如果留了太多KV cache余量,实际batch size会被卡得很小,A100跑7B理论上至少能塞进32并发,你QPS才20很可能是不小心设了max_num_seqs=1。还有个小坑,flash_attn在vLLM里默认就是开的,你手动指定版本如果和编译的cuda版本不匹配反而会回退到xformers,可以从日志里确认一下实际用的attention后端。最后问一句,你测速的时候是不是用了流式输出?流式响应会把首token延迟也算进QPS里,如果真是这个原因,那20这个数字倒不算离谱。
20 tokens/s对于7B模型确实偏低了,我怀疑你docker里没开共享内存或者NCCL环境变量没配好,这玩意儿对vLLM影响挺大的。我之前用官方镜像也踩过坑,建议你直接宿主机跑一次对比下,排除容器开销。另外Qwen2.5的7B本身对flash_attn版本很敏感,你确认下是不是用的最新版,老版本会有明显性能回退。量化这块如果只是FP16,那瓶颈大概率不在显存带宽,反而是prefill长度没限制导致的,试试把max_num_seqs调小点看有没有变化。
20tokens/s这个数字确实有点不对劲,我拿同样配置跑过Qwen2.5-7B,A100单卡基本能稳定在40-60之间,所以你的瓶颈大概率不是模型本身。你先确认一下vLLM版本,太老的版本对qwen系列支持不好,特别是那批带GQA的模型,老版本会退化成MHA导致显存带宽翻倍消耗,速度直接腰斩。另外你说量化没做好,但QPS和量化关系不大,除非你用的是FP16以下精度,否则主要看显存带宽是否打满,建议用nvidia-smi看看GPU利用率是不是接近100%,如果只有50%左右,多半是数据加载或prefill阶段卡住了。docker确实会有性能损耗,但一般不超过5%,除非你用了macvlan或iptables规则,所以这不是主因。我怀疑你max_model_len调太高了,比如设成32k,那prefill阶段计算量暴涨,导致首token延迟拖垮整体吞吐,建议先用4k跑一遍对比。还有个小坑,vLLM的continuous batching对并发请求数很敏感,如果你用单条流式测试,QPS肯定上不去,得用并发脚本压测才行。最后查一下你的微调是否引入了额外算子,比如自定义attention或lora融合,这会让vLLM的优化失效,直接走fallback路径,速度掉得厉害。你不如先跑个原版qwen2.5-7b对比,如果原版也慢,那就是环境问题,如果原版快,那就是你微调后的模型结构有改动。