最近在试着把Llama 3.1 8B量化版(4bit)部署到我自己的单卡RTX 4090(24G显存)上,显存占用大概14G左右,按理说应该能跑得动。但实际用的时候,生成一个200tokens的回复,要等20多秒,实时交互体验太差了。
我用的框架是vLLM,batch size设成1,max tokens设了2048,没有开流式输出。有没有大佬指点一下:
1. 是不是量化方式不对?我用的GPTQ 4bit,换成AWQ会不会快一点?
2. 或者是不是vLLM参数没调对?比如要开prefix caching或者调大block size?
3. 有人说FlashAttention必须配A100才有效,4090用了白搭?
求真实踩坑经验,不想折腾完发现是硬件天花板。
部署7B大模型到服务器,显存够但推理速度慢得离谱,咋优化?
全部回复
共 161 条4090跑4bit的8B还这么慢,大概率不是量化格式的锅,GPTQ和AWQ在这档位差距真没那么大。你试试把vLLM的--gpu-memory-utilization调到0.9以上,让它把KV cache吃满,顺便把--max-num-seqs调成16,单batch反而容易让显存带宽闲置。另外FlashAttention必须开,不开的话长序列注意力这块能吃掉一半时间。流式输出其实不影响生成总时长,但能让你首token延迟体感好很多,建议开起来配合--enable-prefix-caching,如果对话重复前缀多,能省不少计算。我上次调完这些,同样4090跑7B,速度能翻一倍以上。
4090带8B也不可能这么慢,先看看是不是没走GPU吧,nvidia-smi盯着点。
你这速度明显不正常,vLLM默认配置跑8B不至于这样,试试开个流式输出看首token延迟?
我也踩过类似的坑,4090跑7B/8B这个级别按说真不该这么慢。你vLLM里batch size=1本身就是延迟最大的配置,它默认会预留很多显存做KV cache,但单请求时反而增加了调度开销,不如试试把gpu_memory_utilization调高到0.9,并且加上--enable-prefix-caching,至少长对话场景能明显提速。
关于量化,GPTQ和AWQ在4bit下速度差距没那么玄乎,但AWQ对激活值敏感度更低,有些模型上首token延迟会好一点。不过我更怀疑是vLLM的block size问题,默认16对短序列还行,你max tokens=2048但实际生成200,block size调成32或64能减少内存碎片,稍微提升吞吐。
FlashAttention那个选项必须得开,不开的话attention计算是纯访存瓶颈,4090的算力根本用不上。另外你确认一下是不是没开continuous batching?虽然batch=1,但vLLM的调度器默认可能还是走动态batching路径,加个--max-num-seqs 2或4会有差别。
最后建议你直接测一下单token延迟,如果首token要1秒以上那就不是解码慢,而是prefill阶段卡住了,可以试着把max-model-len调小到1024,避免预填充时做太多无用计算。还有一个土办法,关掉vLLM换llama.cpp试试,有时候后端实现差异比量化方式影响还大。
4090跑8B这个速度确实不正常,我同卡跑Qwen2.5 7B AWQ大概能到40-50 tok/s。你可以先试试把max_tokens调小点,然后开下流式输出看首token延迟,如果首token也慢大概率是量化或显存碎片问题。另外GPTQ换AWQ在有些模型上能快个20%,但更关键的是vLLM的gpu_memory_utilization要设到0.9以上,否则显存利用率太低调度开销大。FlashAttention记得开,不过你显存没爆的话影响可能没前面几个因素大。
你这情况大概率是vLLM没吃满,试试把max-tokens调小点,再加个prefix caching,速度能翻倍。
4090跑4bit不至于这么慢,检查下是不是没开flash-attention,那玩意儿不开等于白买卡了。
你这情况我太熟了,4090跑8B按理说应该飞起,20秒确实离谱。先别急着换AWQ,GPTQ和AWQ在4bit下速度差距没那么大,瓶颈大概率不在量化格式上。我怀疑是你vLLM的显存利用率没调好,试试把gpu-memory-utilization调到0.9以上,让vLLM能多占点显存做KV cache,不然它默认可能只用了50%左右。另外max tokens设2048但实际只生成200,这会导致预填充阶段一次性算太多,建议把max-model-len调低到和实际生成长度匹配,或者干脆开流式输出,至少首token速度会快很多,体感上就没那么煎熬。FlashAttention倒是必须开的,vLLM一般默认启用,但确认下你的CUDA版本和vLLM版本匹配,旧版本对Ada架构优化不好。还有个容易忽略的点,你用的模型是Llama 3.1的话,建议看看有没有对应的FlashInfer后端,有时候比默认的PagedAttention快20%以上。最后,如果只是个人用,试试把batch size设为1同时开continuous batching,vLLM对单请求的调度其实有额外开销,稍微调一下调度策略就能改善。
你这配置跑这速度确实不对劲,试试加--enable-prefix-caching再关掉Eager模式,可能立竿见影。
4090跑4bit 8B这速度确实不对劲,我猜你vLLM里没开--enable-chunked-prefill?这个对长prompt影响挺大的。另外GPTQ和AWQ在这种小batch下差距真不大,重点还是看显存带宽有没有吃满,建议用nvidia-smi盯一下GPU利用率,如果只有30%左右那大概率是CPU在拖后腿。还有别用默认的block size,手动调到16试试,最后流式输出最好还是开着,体感会快很多。
4090跑8B 4bit这个速度确实不正常,我怀疑卡在vLLM的prefill阶段了。你可以试试把max model len调低到1024,或者开一下chunked prefill,200 token要20秒说明计算没吃满,大概率是显存换入换出在拖后腿。
GPTQ换AWQ提升有限,不如看看是不是quantization参数没对齐,比如group size调成128会快不少。另外FlashAttention必须开,不开的话长序列下的显存带宽会直接卡死,vLLM默认应该开了但你可以确认下日志。
还有个容易忽略的点:你机器CPU内存够不够?vLLM的KV cache如果没放显存而是落到内存,速度也会崩。我上次就是被swap给坑了,最后强制pin memory才解决。
4090跑8B这个速度确实不正常,我怀疑不是量化的问题,GPTQ和AWQ在这种场景下差距没那么大。你试试把vLLM的gpu_memory_utilization调高到0.9,再开一下enable_prefix_caching,有时候默认参数吃不满带宽。另外别用流式输出这个点很关键,vLLM在非流式模式下会等完整生成完才返回,体感上就慢了一大截,实际吞吐可能没那么差。
4090跑8B量化这个速度确实不正常,我怀疑不是量化的问题,GPTQ和AWQ在这类场景下差距没那么大。你试试把max tokens调低点,或者改一下vLLM的gpu_memory_utilization,有时候显存没吃满会影响调度效率。另外流式输出虽然不提升速度但能改善体感,可以先开起来看看。FlashAttention最好还是开上,尤其长序列生成的时候效果挺明显的。
你这延迟不对劲,先试试开流式输出,体感能好一半,顺便把block size调大点。
4090跑4bit的8B模型,20秒200token确实不太正常,我怀疑你压根没吃到显存带宽的红利。vLLM默认的KV cache策略对单batch不友好,建议把block size调大试试,或者直接换TGI对比下。
另外GPTQ的4bit在低延迟场景确实不如AWQ,尤其你max tokens还设了2048,KV cache分配太保守了,建议开流式输出,首token延迟会明显改善。FlashAttention必须要开,不然注意力计算浪费太多时间。
我自己的经验是,单卡部署这种模型,不如直接上llama.cpp的MMap模式,显存和内存混合加载反而更快,你试过吗?
4090跑4bit的8B不应该是这个速度,20秒200token明显不对劲。你先确认下是不是vLLM的gpu_memory_utilization设太低了,导致KV cache被反复换出,建议直接拉到0.9试试。另外别开prefix caching,单轮对话用不上反而浪费显存,block size默认就行。FlashAttention也得确认编译时开了,没开的话性能差好几倍,跑个python -c "import vllm; print(vllm.__version__)"看下版本,新版默认是开的。
顺便说下AWQ和GPTQ在你这场景下差距不大,瓶颈不在量化格式,先把运行配置调对了再说。我之前也遇到过类似情况,最后发现是pytorch和CUDA版本不匹配,重装后速度直接翻倍。你不如先跑个官方benchmark脚本对比下,排除环境问题再折腾其他。
4090跑4bit的8B不至于这么慢,20秒200token明显不对劲。你试试关掉vLLM的continuous batching,或者直接换transformers原生推理跑一下,排除是框架调度的问题。另外GPTQ和AWQ在这卡上差别真不大,瓶颈大概率不在量化格式,先查下是不是GPU没吃满,看看功耗和利用率再说。
4090跑4bit量化8B应该不至于这么拉,20秒200token肯定不正常。你试试把vLLM的--gpu-memory-utilization调到0.9,再开--enable-prefix-caching,这两个对单卡延迟影响挺大的。另外GPTQ和AWQ在推理速度上差别真不大,除非你模型本身是AWQ格式的,不然别折腾量化方式了,问题八成出在vLLM的调度上。
4090跑8B量化版这个速度确实不正常,我怀疑瓶颈不在显存,而在vLLM的调度策略上。你试试把max_num_seqs改成1,然后关掉continuous batching,这样能减少排队延迟,另外block size调成16或者32对短序列生成有奇效。FlashAttention肯定要开,但更重要的是你的GPU利用率,可以看一下nvidia-smi,如果利用率一直在50%以下,大概率是数据搬运卡在CPU和GPU之间了。量化方式上,GPTQ和AWQ在4bit下速度差异真没那么大,除非你用的是老版本GPTQ,建议升级到最新版exllamakernels。还有个容易忽略的点,你max tokens设2048但实际只生成200,vLLM会预分配KV cache,建议把max_tokens调到256试试,说不定能快一倍。最后,流式输出一定要开,虽然看起来只是交互体验问题,但不开流式会导致vLLM把整个序列生成完才返回,内部优化空间会小很多。
4090跑8B这个速度确实不正常,vLLM默认配置下应该能到50 tokens/s以上。建议先开流式输出看看首token延迟,如果首token也卡那就不是解码瓶颈而是prefill阶段的问题。GPTQ和AWQ在这个规模上差距其实不大,更可能是你max tokens设太高导致KV cache预分配占了资源,试着把block size调到16或32。另外确认下是不是没开FlashAttention,vLLM新版默认应该自动启用,但老版本得手动指定。我之前遇到过类似情况,最后发现是CUDA版本和vLLM不匹配导致的,重装对应版本直接快了三倍。
我也遇到过类似情况,4090跑4bit的8B按理说不该这么慢。你试试把max tokens调低点,或者换一下vLLM的调度策略,有时候默认配置对单请求很不友好。GPTQ和AWQ速度差别其实不大,瓶颈更多在显存带宽和kernel优化上,建议先用官方benchmark脚本跑一下排除参数问题。另外FlashAttention不开的话,长序列确实会慢很多,你确认下是不是被什么编译选项给关了?
4090跑4bit 8B这速度确实不对劲,先试试开流式输出,体感能快一半。
vLLM默认配置应该能跑满,检查下是不是CPU offload或者GPU利用率没上去。