最近在折腾本地部署,用vLLM跑一个微调过的7B模型(Qwen2.5),显存占用大概14GB,但吞吐量一直上不去。我试过调max_model_len和gpu_memory_utilization,也开了flash_attn,但QPS只有20左右,比官方说的差好多。我看网上有人用同样的卡跑13B都能到50+,不知道是哪里配置有问题?还是说我的模型量化没做好?另外,我是用docker部署的,会不会有额外的性能损耗?求大佬指点一下排查方向,谢谢!
用vLLM部署7B模型,单卡A100推理速度只有20tokens/s正常吗?
全部回复
共 169 条20 tok/s对7B来说确实偏低了,我怀疑不是vLLM本身的问题,而是你微调后的模型有没有做weight转化(比如FP16转BF16或者AWQ),我在类似情况下降过一半吞吐。另外docker跑vLLM确实有轻微网络和显存分配开销,但不会差这么多,建议先裸机试一下排除容器因素。你能看下服务端的GPU利用率吗?如果没到95%以上,大概率是prefill和decode的batch大小没调好,试试把--max-num-seqs调大点,比如64或128。
这速度确实不太正常,我怀疑瓶颈不在vLLM本身,而是你docker里共享内存或者CPU分配的问题。之前我也遇到过类似情况,把--shm-size调大、限制NCCL的线程数之后,吞吐直接翻倍。另外你可以试试关掉flash_attn对比一下,有时候新版vLLM对特定模型微调后的兼容性反而会拖慢速度。还有一个思路是检查下QPS是不是被max_num_seqs卡住了,默认值可能太低,调高到256试试,比调max_model_len有效果多了。
20的吞吐确实偏低了,我拿A100跑Qwen2.5-7B不开量化都能到40+,你检查下是不是docker里显存没直通或者vLLM版本太旧了,之前有版本对2.5支持不好。另外你微调过的模型如果没做awq/gptq量化,单卡瓶颈可能卡在显存带宽上,试着把--enable-chunked-prefill加上,再把max_num_seqs调高到256试试。还有一个坑:如果输入长度普遍很长,prefill会占掉大量算力,你观察下首token延迟和总tokens数的比例,要是prefill占比高就得换continuous batching策略。
20 tokens/s确实有点不对劲,我之前用vLLM跑同尺寸模型A100怎么也有40+。你检查下是不是微调时padding或者attention mask没处理好,导致推理时计算量虚高?另外docker部署基本没损耗,但确认下是不是没开--enable-prefix-caching,这个对长prompt影响挺大的。
量化倒不是主因,FP16本身也够快。我怀疑你max_model_len设太大,显存被KV cache占满后batch size上不去,试试限制到2048再看吞吐。还有个小细节,vLLM版本更新到0.6.x了吗?老版本对Qwen2.5支持确实有性能bug。
要是还不行,直接对比下官方模型和你的微调版本,排除是不是模型结构被改动过。我上次就是自定义了个tokenizer导致推理慢了一半。
20确实偏低了,检查下是否真用上了flash attention,另外docker跑vLLM多少有点性能损耗,建议裸机对比下。
试试把--max-num-seqs调低,并发太高会严重拖慢单请求速度,我遇到过类似情况。
20的吞吐确实有点不对劲,我之前用vLLM跑7B的Qwen2.5,A100 40G上大概能到35-40 tokens/s,所以你的配置肯定还有优化空间。最大问题可能不是vLLM本身,而是你微调后的模型有没有合并LoRA权重?如果没合并,推理时动态加载adapter会额外吃显存和计算,这个开销被很多人忽略。另外你说的量化,如果用的是FP16原权重,那20就是正常偏慢,但如果你用AWQ或GPTQ量化到4bit还只有20,那就要看是不是tokenizer或者padding策略的问题了。docker基本没有性能损耗,除非你用了默认的网桥模式或者没开共享内存,这俩对吞吐影响极小,可以排除。我建议你先用官方未微调的Qwen2.5-7B跑个benchmark,把变量隔离出来,如果官方模型也低,那就是vLLM版本和CUDA环境的问题,换个0.6.x的稳定版试试。另外注意一下并发数,单条流式请求和非流式的QPS能差一倍,如果是单请求测试,20其实还算合理,得压测才能反映真实吞吐。最后可以看看是不是被max_model_len限制了,如果设成32K,prefill阶段的计算量会暴涨,实际生成阶段反而被拖慢,试试改回默认的2K再对比一下。
20的吞吐确实不太对劲,我拿同样配置跑Qwen2.5-7B一般能到40-50,你先看看是不是max_model_len设太大导致prefill占比过高,我调到4096之后提升很明显。另外docker本身损耗很小,但注意别让NUMA绑核或者共享内存限了,可以试试加--ipc=host。量化方面如果没做AWQ或GPTQ,单纯FP16也会拖速度,建议先用官方benchmark脚本跑个baseline排除模型本身的问题。
QPS 20确实偏低了,A100跑7B不至于这水平,建议先确认下是不是微调后模型权重没合并好。
docker本身损耗很小,重点查下vllm版本和CUDA版本匹配,另外看下是不是max_model_len设太大导致显存碎片化。
关注下是否开了continuous batching,并发请求数太低的话吞吐肯定上不去,我这边压到32并发才跑满。
20 tokens/s对于7B模型来说确实偏低,但先别急着怪vLLM,我怀疑你测的是首token延迟还是整体吞吐?如果是流式输出,首token慢和续写速度是两码事。另外你提到显存占用14GB,但A100有40GB,有没有试过把gpu_memory_utilization调到0.9以上?vLLM默认会预留一部分KV cache,如果留太少反而会频繁触发重新计算。还有你用的Qwen2.5是原生BF16还是做了AWQ/GPTQ量化?我之前遇到过类似情况,模型没量化时显存吃紧,但量化后速度反而提升不明显,因为vLLM对某些量化格式的支持效率不高。docker的话,只要不是用--shm-size默认值(1MB)导致共享内存不够,一般性能损耗可以忽略,但你可以用--ipc=host试试。最后建议你开一下vllm的--verbose日志,看看是不是有rejected请求或者preemption计数,我之前发现某次微调模型的padding token设置不对,导致每次请求都多算很多无效token。如果还不行,可以直接在HF上对比跑一下官方原版Qwen2.5-7B,排除是模型结构改动带来的影响。
20 tokens/s确实偏低了,我拿A100跑7B一般能到40-50,你这明显没吃满。建议先看下是不是微调后模型结构有改动,vLLM对自定义算子支持不好,另外确认下是不是用了最新版本,老版本对Qwen2.5优化不行。docker的话影响不大,主要还是看显存带宽有没有被限制,可以nvidia-smi看下GPU利用率是不是一直在跳。
20的QPS确实偏低了,先看下是不是微调后权重格式有问题,或者试试把docker的共享内存调大点。
这速度不对,我跑7B都能到40+,你查下vLLM版本和CUDA版本匹配不,还有是不是被CPU瓶颈卡住了。
20的QPS对7B来说确实偏低了,我怀疑你docker里是不是没开共享内存或者没绑核,容器化部署对vLLM的页缓存和CUDA图影响挺明显的。另外你确认下是不是真用到了flash attention,有时候编译版本不对会静默回退,跑个nvidia-smi看看GPU利用率是不是一直在90%以上,如果忽高忽低大概率是CPU预处理瓶颈。量化这块先别管,FP16的7B在A100上正常都能到30+,建议你直接裸机跑一次对比,排除环境因素再调。
这速度确实不太对,先看下是不是微调后padding和EOS设置影响了推理,另外docker跑vLLM记得开共享内存。
20 tokens/s确实不正常,我怀疑你vLLM版本是不是太旧了,之前我遇到过类似问题,升级到0.6.x之后吞吐直接翻倍。另外你调了gpu_memory_utilization但有没有注意过KV cache的剩余空间?如果max_model_len设得太大,实际推理时KV cache占不满但预分配内存又卡着,反而拖慢速度。还有你说的量化,如果只是FP16跑7B这显存占用看着没问题,但如果是没校准过的AWQ或者GPTQ,有时反而因为反量化开销导致吞吐下降,你可以试试用bitsandbytes的NF4对比一下。docker确实会有小损耗,但主要在网络和磁盘IO上,纯算力影响不到5%,大概率不是主因。我建议你先用vLLM自带的benchmark脚本跑一下官方模型,排除微调模型本身算子融合的问题,再检查一下是不是用了异步调度,有时候默认的continuous batching参数对短并发场景不友好。还有个小细节,确认下你是不是在容器里绑定了所有CPU核,vLLM的tokenization和调度线程如果被限制了,即使GPU空闲也会卡在CPU瓶颈上。
docker跑vllm性能损耗很小,先查下是不是微调模型本身没做kv cache复用,再试试把gpu_memory_utilization调到0.9看看。
20的吞吐确实有点不对劲,我之前用vLLM跑同尺寸模型,A100基本能到30-40,你先看看是不是max_model_len设太小了,批处理上不去。另外docker跑vLLM我实测性能损耗不大,倒是有可能你微调后的模型没做weight-only量化,FP16和INT8差距能到两倍。还有个容易忽略的点,检查下vLLM版本,0.6.x和0.4.x的调度逻辑差很多,换新版本说不定直接翻倍。
20 tokens/s确实偏低了,我之前用vLLM跑同尺寸模型,A100一般能到40左右。你检查下是不是微调后的模型没合并adapter,或者rope scaling设置和max_model_len不匹配,这两个坑容易让prefill变慢。docker本身损耗很小,基本可以忽略,重点还是看vllm的启动日志里有没有提示算子fallback到非优化版本。另外量化的话,如果用了AWQ或GPTQ,注意下group size和zero point是否影响吞吐,我遇到过量化格式不匹配导致推理速度骤降的情况。
你这20 tokens/s确实不太正常,我拿A100跑Qwen2.5-7B不带量化都能稳定在40-60之间。先别急着怀疑量化,大概率是max_model_len设太大导致KV cache吃满显存,或者并发数没调对,试试把--max-num-seqs设成64或者128。另外docker的损耗可以忽略不计,但记得检查下是不是没用上H20的显存带宽,A100 40G和80G版本性能差距也挺明显的。还有个坑:微调过的模型如果加了额外adapter,vLLM加载时要确认是merge后的权重,否则推理路径会慢很多。
先确认下是不是docker的共享内存设太小了,我之前加--shm-size直接翻倍。另外20的QPS如果单请求不带并发测的,那确实正常。