最近在折腾把ChatGLM3-6B部署到阿里云ECS上,用的是V100(16G显存),按理说6B模型应该跑得动。我用的官方transformers+quantization加载的int4版本,单次推理大概要3-5秒才出结果,感觉比网上说的慢不少。试过vLLM框架,但装了一堆依赖报错,参数也不知道怎么调。现在主要跑一些长文本总结任务,输入大概2000tokens左右,输出100-200tokens。有没有大佬指点下,是我加载方式不对,还是需要改点batch size或者max_seq_len?还有哪些加速技巧可以试试,比如flash attention或者pytorch compile?先谢过各位了。
部署ChatGLM3-6B到阿里云服务器,显存够但推理好慢怎么办?
全部回复
共 96 条V100跑int4的6B模型3-5秒确实偏慢,我试过同样配置用transformers加载时把device_map设成"auto"能好一些,另外可以试试把torch compile打开,尤其是长文本场景下提升挺明显的。flash attention也建议加上,对长序列推理帮助很大,不过得注意下你的CUDA版本够不够。vLLM确实坑多,我后来换用text-generation-inference省心很多,配置也直观。你那个max_seq_len设了多少?如果设得太大而实际用不到也会拖速度。
V100跑int4的6B模型3-5秒确实偏慢了,我猜瓶颈可能在数据搬运和CPU预处理上。你试试把max_seq_len设到2048或者更低,另外记得关掉eval模式里的梯度计算,能省点显存带宽。Flash Attention对长文本挺管用的,装上后能快个30%左右,不过得先确认CUDA版本兼容。PyTorch compile的话,我自己的经验是第一次编译会慢,但后续推理确实有提升,你可以先跑一次热热身再测速度。
长文本试试把max_seq_len调小点,或者开flash attention,速度能快不少。
试试开flash attention,再配合torch.compile,速度能提不少,我这么调完快了一倍多。
我之前也遇到过类似的情况,int4加载其实对速度提升有限,瓶颈往往在解码阶段,尤其是长文本输入,attention计算量占大头。你试试把max_seq_len调成跟实际输入长度接近,别用默认的2048,能省不少显存带宽。另外flash attention在V100上可能有点尴尬,这卡是Volta架构,有些优化不兼容,装了反而可能报错,不如先试试pytorch 2.0自带的compile,配合torch.compile模式,有时能带来30%-50%的提速。vLLM那个依赖确实难装,我折腾了半天最后发现是CUDA版本和pytorch版本对不上,你如果非要试,建议直接上官方docker镜像,别自己配环境。还有个土办法,把输入切块分段处理,虽然逻辑复杂点,但实测比一次性灌进去快不少,尤其你这种2000tokens的场景。你输出才100-200,可以考虑用beam search改成greedy,采样开销能降一截。
这情况我熟,V100跑int4的6B不至于这么慢,大概率是max_seq_len没跟上输入长度,默认值太小导致padding和计算浪费严重。你试试把max_seq_len设成2048或者更高,同时留意下是否开了torch的gradient checkpointing,那个在推理时反而拖慢速度。flash attention对V100支持一般,不如先把transformers版本升到4.35以上,官方对GLM的优化都在更新的版本里。另外,如果只是做单条长文本总结,batch size不用动,但建议关闭量化直接用fp16试试,有时候int4的kernel在V100上反而没优化好。
试试换下transformers版本或者直接上flask+vllm,你这输入长度确实卡在瓶颈上了。
V100跑int4的6B确实不该这么慢,你先确认下是不是加载时没走GPU,nvidia-smi看看显存占用和利用率。长文本场景建议把max_seq_len设到2048以上,batch size先固定1,重点开一下flash attention,能明显降延迟。另外vLLM报错大概率是版本不匹配,可以试试官方推荐的transformers版本组合,别直接用最新的。pytorch compile对这种生成任务提升有限,先别折腾。
你这配置跑int4还3-5秒确实偏慢了,我自己的4090上同模型大概1秒内。先试试关掉quantization直接fp16加载,V100对int4支持其实不太友好,反而可能拖慢速度。长文本场景把max_seq_len设到2048就够,batch size保持1别动,重点检查下是不是CPU在做tokenize和padding,把input_ids直接放GPU上能省不少时间。flash attention在V100上没戏,但torch.compile可以试,记得用mode=reduce-overhead,能提个30%左右。
V100跑int4的6B模型3-5秒其实不算离谱,尤其你输入2000tokens的时候,预填充阶段的计算量摆在那。我怀疑你瓶颈不在显存,而在CPU和GPU之间的数据传输,还有transformers默认的贪心解码效率太低。你可以试试把quantization改成bitsandbytes的8bit,有时候int4的kernel在V100上反而不如8bit优化得好,因为V100对int8有Tensor Core加持。
另外vLLM报错多半是CUDA版本和flash attention不匹配,你直接装最新版的vLLM,然后设置--max-model-len 4096,--gpu-memory-utilization 0.9,别用默认参数。flash attention在V100上其实收益有限,它主要对A100/H100优化明显,但pytorch compile值得试,不过记得关闭动态shape,把max_seq_len固定好。
还有个土办法,长文本总结任务你可以把输入切块,分多次调用,每次只喂500tokens,结果拼起来,虽然代码麻烦点但速度能快一倍。最后检查下是不是没开torch.backends.cudnn.benchmark,这个对固定shape的推理影响很大,能省不少时间。
int4加载本身就慢,而且长文本场景下transformers的attention计算是硬伤,3-5秒真不算离谱。你试试把max_seq_len卡到2048,batch size设1,然后开flash attention,显存够的话直接换bf16说不定都比int4快。vLLM那个报错八成是版本冲突,建议直接看官方文档的docker镜像,省得折腾依赖。另外pytorch compile对这模型提升有限,别抱太大期望。
试试开一下torch.compile和flash-attn,长文本生成速度能提不少,vLLM报错大概率是版本问题。
我也踩过一样的坑,int4加载本身就有额外开销,V100虽然显存够但算力其实一般。建议你先试试把max_seq_len调到和你实际输入输出差不多就行,别给太长,再开flash attention,能快不少。另外pytorch compile对GLM支持还可以,能白嫖一点速度。vLLM那个依赖问题我懂,实在不行就放弃,用transformers加个量化参数也行。
16G显存跑6B int4其实有点浪费,你试试fp16原版加载,有时候反而比int4快,因为省去了反量化步骤。长文本任务瓶颈大概率在prefill阶段,你可以把输入切段处理,或者试试把batch size设成1,别让显存碎片化。还有,检查下是不是CPU线程数没拉满,ECS默认配置经常卡这个。
我怀疑你慢在tokenization和生成参数上,2000输入的话,单次prefill本来就要1-2秒,别太指望flash attention能翻天。你试试把beam search换成greedy,或者把top_p调低点,输出速度能明显提升。另外检查下是不是没开混合精度,fp16能省一半计算时间,但记得加个torch.cuda.amp.autocast。
这配置跑int4应该不至于这么慢,3-5秒确实不太正常。我怀疑你加载的时候是不是没把模型放到GPU上,transformers默认可能跑在CPU了,或者量化后还在用float16的权重计算,那速度肯定上不去。你可以先检查下nvidia-smi看显存有没有占满,再确认下model.device是不是cuda。
另外长文本场景下,flash attention的提升会很明显,尤其是2000tokens输入,普通attention的复杂度是平方级的。你试试把model.config里use_flash_attention_2设为True,或者直接装flash-attn库,能快不少。vLLM那个其实对ChatGLM支持不算太好,依赖冲突是常态,别死磕了。
还有个思路,你输出才100-200tokens,可以试试把max_new_tokens设小一点,然后开一下torch.compile,虽然首次编译会慢,但后续推理能提升30%左右。如果还不行,就换用GPTQ或者AWQ量化,比transformers自带的int4快很多。最后确认下你是不是用的单卡V100,老架构对某些新算子支持不好,可能也是瓶颈。
试试把max_seq_len调小点,2000输入没必要开太大,再开flash attention能快不少。
你这情况我上周刚遇到过,int4加载慢很正常,试试把quantization换成bitsandbytes的8bit,配合torch.compile能快不少。vLLM对ChatGLM支持确实有点拉胯,别死磕它,不如直接看下transformers的官方文档里那个attention实现开关,记得有flash_attention_2的选项。另外你输入2000tokens确实偏长,max_seq_len别设太大,512或1024就够,否则KV cache会拖慢速度。还有个笨办法,把批处理拆小点,一次跑一条但开多线程,实测比硬顶大batch稳。
V100跑int4的6B这个速度确实有点不对劲,我猜大概率是max_seq_len没调好,2000 token输入会触发动态padding导致显存碎片化,试试把max_seq_len设成2048或者2560固定值。另外你直接上pytorch compile加flash attention,V100虽然不支持flash-attn2但老版flash attention 1还是能用的,编译一次后面推理能快个30%左右。vLLM那个报错多半是CUDA版本和torch对不上,其实官方有对应的docker镜像,拉下来直接跑能省不少事。
int4加载本身就慢,试试bf16+flash attention,速度能翻倍,vLLM别折腾了。
V100跑int4的6B,3-5秒确实偏慢了,我怀疑瓶颈不在显存而在内存带宽和算子优化上。你试试开torch.compile应该能提个20%左右,另外把max_seq_len从默认调低到和你输入输出匹配的长度,能省不少显存和计算。flash attention在V100上可能没太大提升,因为是老架构了,不如花点时间把vLLM的报错贴出来,社区里应该有人踩过同样的坑。
V100跑int4的6B确实不该这么慢,你这3-5秒大概率是卡在长文本的prefill阶段了。试试把max_seq_len调到和你输入长度接近的值,别用默认的2048或者更大,能省不少显存带宽。另外flash attention对长文本提升很明显,transformers现在直接传attn_implementation="flash_attention_2"就行,不用改代码。vLLM那个报错可能是版本问题,实在搞不定就用官方自带的cli_demo,配合torch.compile也能压到2秒内。