最近在折腾本地部署,用vLLM跑一个微调过的7B模型(Qwen2.5),显存占用大概14GB,但吞吐量一直上不去。我试过调max_model_len和gpu_memory_utilization,也开了flash_attn,但QPS只有20左右,比官方说的差好多。我看网上有人用同样的卡跑13B都能到50+,不知道是哪里配置有问题?还是说我的模型量化没做好?另外,我是用docker部署的,会不会有额外的性能损耗?求大佬指点一下排查方向,谢谢!
用vLLM部署7B模型,单卡A100推理速度只有20tokens/s正常吗?
全部回复
共 169 条同问,最近也卡在这个问题上了。我也是Qwen2.5 7B,不过用的不是A100是4090,吞吐量比你高点有限,大概30出头,但看别人跑同样的模型能到50+,心里确实不平衡。
我这边排查了一圈,有几个点你可以试试看。首先docker确实可能有影响,我对比过裸机和docker,同样配置下docker大概会损失5%-10%的性能,主要是网络和GPU驱动间的overhead,不过影响不至于差这么多。
然后你提到量化,这很关键。7B模型如果没量化,A100跑20确实偏低但也不是完全离谱。你可以检查下模型是不是真的加载了量化版本,比如用AWQ或者GPTQ。我试过用bitsandbytes的4bit,吞吐能翻倍,不过精度会有点损失。vLLM对量化支持得挺好,可以看看是不是加载时忘了指定quantization参数。
另外max_model_len也别调太小,我之前设成2048反而比4096慢,后来发现是因为频繁触发prefill。你试试设成4096或者8192,有时候反而更顺。还有gpu_memory_utilization别超过0.9,留点显存给kv cache,不然容易OOM然后降速。
调度策略也值得看看,vLLM默认用round-robin,你试试换成prefill-aware或者把max_num_batched_tokens设大点。不过这个得结合你的实际请求长度来调,建议用wrk或者locust压测一下长尾场景。
最后,确认下flash_attn是不是真的生效了,可以看日志里有没有类似“Using FlashAttention”的提示,有时候版本不匹配会静默降级到普通attention,那个速度差很多。
以上都是我踩坑踩出来的,不一定全对,但方向应该没问题。你要是找到其他原因也告诉我一声,一起进步。
20 tokens/s对于7B模型在A100上确实偏低了,但也不至于离谱到完全不能接受——得看你具体怎么跑的。vLLM的吞吐瓶颈很多时候不在模型本身,而在prefill和decode阶段的调度策略。
首先,QPS 20这个数据如果是包含prefill时间的端到端吞吐,那大概率是batch size没喂上去。vLLM默认是continuous batching没错,但如果你实际请求的并发数不够高(比如单线程压测),那它根本触发不了batching优化,等于退化成串行推理。你试试用vllm.entrypoints.openai.api_server启动后用benchmarks/benchmark_serving.py多路并发压一下,看峰值QPS能不能拉到50+。
其次,Qwen2.5的7B原生支持GQA,但如果你微调时改动了attention结构(比如用了LoRA),vLLM的PagedAttention可能没完全对齐,导致显存碎片化严重。你检查下/tmp/vllm/vllm_engine_*.log里有没有kv_cache size的warning,如果cache利用率低于70%,那gpu_memory_utilization设再高也没用。
docker性能损耗这块,我建议直接nvidia-smi dmon跑一下看GPU利用率。如果GPU-Util卡在30%以下,那大概率是CPU喂数据的速度跟不上——检查下vllm的max_num_batched_tokens是不是设得太保守,或者你用了--enable-prefix-caching但请求无前缀复用,白占调度开销。
最后,13B跑到50+的那个案例,我怀疑要么是对方用了FP8或INT4量化(A100不支持原生FP8,得靠triton手写kernel),要么就是用了更高的并发+更短的输入输出。你确认一下自己测试时的input/output长度,如果平均生成512 tokens,那20 t/s其实不算差。建议先拿官方vLLM benchmark的默认参数跑个baseline再排查。
同问,最近也在折腾vLLM部署,不过是8B的模型,A100 40G,跑下来也差不多20多tokens/s,一直怀疑是不是自己哪里没调对。看到你说13B能跑到50+,我也有点懵……不过仔细想想,会不会跟量化关系挺大的?我试过FP16和INT4,INT4确实能快一截,但也没到翻倍的程度。你有试过AWQ或者GPTQ量化吗?我看官方文档说vLLM对这两种量化支持得比较好,吞吐能提升不少。
另外docker那个点我也有同样的困惑。之前看过一些讨论,说docker的网络模式和共享内存设置会影响性能,尤其是--shm-size,如果设太小,模型加载和推理时可能会卡在内存分配上。你docker跑的时候有没有加--ipc=host或者调大shm-size?我试过从默认64M改成8G,体感上吞吐确实稳了一点,但不确定是不是心理作用。
还有就是你max_model_len设了多少?如果设太大,虽然能加载长序列,但会浪费显存,导致batch size上不去,vLLM的continuous batching效果就出不来。我自己的经验是尽量压到实际需要的长度,比如4096或8192,同时gpu_memory_utilization留个0.9左右,别太满。另外flash_attn版本也很关键,旧版本可能兼容性有问题,建议确认下vLLM和flash_attn的版本对不对得上。
最后问下,你那个模型是微调过的,会不会是模型架构上有什么改动,导致vLLM的优化用不上?比如自定义了attention或者加了额外的层?我之前试过一个加了lora的模型,吞吐就比原版低了不少。希望你能排查出来,回头也分享下经验!
docker确实会有网络和内核开销,建议裸机对比一下,另外检查下vLLM版本和CUDA版本是否匹配。
20的tokens/s对7B来说确实偏低了,我猜主要瓶颈可能在docker的网络和内存映射上,可以试试直接宿主机跑一下排除这个干扰。另外你说的13B能到50+,那个大概率是用了FP8或者INT4量化,你的模型如果还是BF16/FP16,单卡A100跑7B这个速度其实也算正常范围。建议先检查下vLLM的日志里有没有显存碎片化提示,或者试试把max_model_len设小一点,比如2048,看单batch延迟有没有改善。
说实话20 tokens/s对于7B模型在A100上确实偏低了,我怀疑问题可能出在几个地方。你提到开了flash_attn,但vLLM的版本和CUDA环境有没有对齐?有时候老版本vLLM搭配新驱动反而会触发bug。另外Qwen2.5的7B本身用fp16推理的话,单卡A100理论吞吐应该能到80-100 tokens/s左右,建议先检查一下是不是模型文件本身有损坏或者微调时混入了奇怪的算子。docker倒不一定有太大性能损耗,除非你绑定的CPU核心数或者内存限制太紧,导致数据预处理卡IO。还有个小细节,如果用了vLLM的continuous batching但没调好max_num_seqs,默认值可能太低,你可以试试把这个参数提到256以上。最后建议用nvidia-smi确认一下显卡是不是跑在PCIe 3.0或者被降频了,A100被限速的情况还挺常见的。
20的tokens/s对于7B确实偏低了,我猜可能是docker的显存分配和vLLM的page管理有冲突,建议试试不用docker直接跑一次对比下。另外你那个gpu_memory_utilization调了多少?如果设得太高反而会让vLLM频繁做显存交换,可以降到0.85左右看看。还有Qwen2.5的7B本身对prefill阶段比较敏感,max_model_len设得太大会拖慢首token延迟,可以先用1024测试一下基准性能。
试试把batch size调到32以上再测,单条推理vLLM的优势发挥不出来。
检查下vLLM版本和CUDA环境,旧版对Qwen2.5支持不好,建议升到0.6.0以上试试。
20的QPS对于7B模型来说确实偏低,我怀疑不是vLLM本身的问题,而是docker的网卡或内存带宽被限制了,可以试试裸机跑一下对比。另外你确认下是不是用了flash_attn的官方版本,有的魔改版反而会降速,而且Qwen2.5对batch size比较敏感,单条请求跑满显存反而效率低。如果模型没量化,可以试试AWQ或GPTQ,A100上4-bit推理能快不少,不过要记得同步调整下采样参数。
20的qps对于7B确实偏低了,我估计问题大概率出在docker的网络和内核参数上,vLLM对容器环境挺敏感的,建议先裸机跑一下排除环境干扰。另外你微调过的模型会不会是fp16没对齐?可以检查下模型加载时的精度设置,有时候混了int4就会拖慢。还有你max_model_len调到多少了?设太大对短序列推理会有负优化,试试调成2048看看有没有改善。
QPS 20确实偏低了,检查下vLLM版本和CUDA版本匹配吗?我升到0.6.0后吞吐明显提升。
20的QPS确实偏低了,我自己的经验是7B在A100上合理区间至少40+。你可以先确认下是不是batch size设得太小,vLLM默认的调度策略对连续请求的优势很大,单条压测看不出真实性能。另外docker的网络和共享内存配置也可能有影响,建议加上--shm-size=8g试试。还有别忘了检查下量化精度,FP16和INT4的吞吐差挺多的。
这速度确实不太正常,A100单卡跑7B模型理论上应该能到40-50 tokens/s甚至更高才对。我猜问题可能出在模型加载方式上,你用的Qwen2.5是不是没做GPTQ或AWQ量化?如果直接FP16跑的话显存占用14GB其实偏高了,vLLM对量化模型的支持很好,建议试试4bit量化,吞吐能翻倍。另外docker的网络模式会影响显存带宽,可以对比下宿主机直接跑的情况,我遇到过docker默认bridge模式导致推理掉速的情况。还有个小细节,vLLM的调度参数里有个--num-scheduler-steps,默认值可能不适合你的场景,调小一点能减少调度开销。如果你用的模型长度比较长(比如8K以上),max_model_len设太大会浪费显存,可以按实际输入长度动态调整。最后建议用vLLM的benchmark脚本跑个标准测试,排除模型本身的问题。
20 tokens/s确实偏低,我怀疑问题出在docker上,容器化部署对显存和通信开销影响挺大的,建议你直接在宿主机上跑一次对比下。另外qwen2.5的7B官方推荐用fp16或者int8量化,你检查下模型加载时是不是默认用了fp32?还有vLLM的调度参数里block_size调成16或者32试试,有时候默认值反而拖后腿。
单卡A100跑7B只有20tokens/s确实偏低了,vLLM按理说对Qwen2.5的优化应该不错。我猜问题可能出在max_model_len设得太保守,或者gpu_memory_utilization留了太多余量,导致实际batch size上不去——vLLM吞吐量很大程度依赖连续批处理,你可以试试把max_model_len设到4096以上,同时把gpu_memory_utilization拉到0.95,让显存尽量吃满。另外,你提到模型是微调过的,如果微调时用了自定义的tokenizer或者对注意力结构有改动,可能会影响vLLM的缓存策略,建议检查一下config.json里有没有不兼容的配置。量化方面,如果是FP16跑20tokens/s那肯定不对劲,但如果是4bit量化后还这个速度,那可能跟量化方式有关,比如GPTQ在vLLM里有时会有额外的解码开销。Docker倒是影响不大,除非你绑定了CPU核心数或者没开共享内存,可以试试在宿主机上直接跑一次对比。最后,官方说的50+ tokens/s通常是针对原始LLaMA或者ChatGLM这类模型,Qwen2.5的架构稍复杂,加上你的是微调版,不一定能直接对标,但至少应该能到35-40才对。
20 tokens/s对于7B模型在单卡A100上确实偏低了,我怀疑问题可能出在docker的网络或共享内存配置上,试试加--shm-size参数看看会不会改善。另外你提到开了flash_attn但没提tensor_parallel,单卡其实可以试试调整调度策略,vLLM的--max-num-batched-tokens设低点有时反而能提高吞吐。还有量化方面,如果只是FP16,7B的推理瓶颈通常不在显存而是计算带宽,可以检查下NVIDIA驱动和docker的GPU直通是否正常。
20 tokens/s确实偏低了,我猜可能是gpu_memory_utilization设得太保守,或者batch_size没调对,vLLM在小batch下吞吐会明显偏低。另外docker网络模式如果用了bridge,可能会影响显存分配效率,试试加--network host看看有没有改善。量化的话,7B模型用fp16应该就够了,不用急着上量化。
20的吞吐确实偏低了,我跑7B的Qwen2.5在A100上不开量化也能到40+。建议先检查下vLLM版本,0.6以上对Qwen系列支持更好,另外docker挂载时注意把共享内存调大,默认64M容易成瓶颈。还有如果用了AWQ或GPTQ量化,记得确认下校准数据集跟你的微调数据分布是否一致,否则反而会掉速。
20的QPS对7B来说确实偏低了,我猜可能是max_model_len设得太高导致显存碎片化,或者gpu_memory_utilization没留够余量给kv cache。docker的话性能损耗其实很小,除非你网络或者存储挂载有问题。建议先裸机跑一下排除docker因素,另外检查下模型是不是用了FP16,如果是int4量化反而可能因为反量化开销拖慢速度。