最近在折腾把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到阿里云服务器,显存够但推理好慢怎么办?
全部回复
共 116 条V100跑int4的6B模型,3到5秒确实偏慢,但你先别急着换框架,我怀疑瓶颈在transformers的默认实现上——它没开KV cache或者用了动态padding,长文本输入时计算量会翻倍。你可以先检查一下是否把pad_token_id设对了,然后试试把input里的padding去掉,用左padding或者干脆截断到固定长度,这个对速度影响特别大。vLLM装不上就别死磕了,它对量化模型支持一般,而且你这任务吃的是单请求延迟,不是吞吐,vLLM的优势反而发挥不出来。flash attention可以装,但记得要匹配你transformers版本,不然会静默失效,装完看一眼日志里有没有提示启用成功。pytorch compile倒是值得试,但第一次运行会卡很久做图优化,你得有耐心等它编译完。另外你输出100到200tokens,生成阶段是逐token的,可以看看是不是采样参数里把top_p和temperature设太高导致每次都要重新算概率分布,调低一点能快不少。最后确认下你的CUDA和torch版本是不是太老,V100要发挥好得用cu118以上的环境,老版本对int4的算子优化很差。
试试开flash attention和torch.compile,能提升不少,另外检查下是不是没开混合精度。
V100跑int4的6B慢在解码阶段,3-5秒确实偏高了。你试试把max_seq_len设成2048,batch size先固定1,影响最大的是transformers的KV cache没开,加use_cache=True能快不少。flash attention在V100上支持不太好,但pytorch compile值得试,我上次编译后延迟降了30%。另外vLLM报错多半是版本冲突,直接装vllm==0.3.1配合transformers4.38试试,别用最新版。
我这边刚用vLLM跑通GLM3,发现输入2000tokens时prefill占了快一半时间,如果你不急着要流式输出,可以关掉流式模式,能省点开销。另外检查下你是不是用了CPU offload,V100显存够的话别开,会拖慢不少。还有个小技巧,把输入文本用tokenizer的max_length参数截断,别让模型自己算位置编码,能避免一些内存碎片问题。
你这情况我怀疑是量化后的算子没有走CUDA优化,试试把quantization换成bitsandbytes的nf4,别用官方默认的int4,有时候速度差两倍。另外注意阿里云ECS的CPU核数和内存带宽,如果CPU瓶颈的话,加载模型时设low_cpu_mem_usage=True,能减少内存拷贝时间。
2000 tokens输入在int4下3-5秒其实不算太离谱,但确实还有压榨空间。你试试把max_seq_len调小到实际需要的长度,默认2048会浪费不少计算。另外flash attention对长文本提升挺明显的,装个flash-attn再开use_flash_attention_2试试。vLLM值得再折腾一下,长文本场景paged attention收益很大,报错多半是cuda和torch版本对不上。
V100跑int4的6B模型3-5秒确实有点慢,不过你用的是transformers原生加载吧?那个推理路径没做continuous batching和paged attention,长输入场景下KV cache膨胀很拖速度。vLLM装不上建议换autodl或者直接用官方docker镜像,省得跟依赖打架。flash attention对V100支持有限,可以先试试把max_seq_len卡到实际需要的长度,别默认给太大,另外pytorch compile在V100上收益一般,不如先搞定量化推理引擎。
V100跑int4还3-5秒确实偏慢了,感觉瓶颈可能不在显存而是没吃到flash attention。你试试装flash-attn然后把加载参数里use_flash_attention_2打开,长文本场景提升挺明显的。另外2000 tokens输入其实不算短,建议看看是不是没开kv cache复用,batch里多次请求会快很多。vLLM报错的话把具体错误贴出来,多半是CUDA版本和vllm版本对不上,调好之后吞吐能翻好几倍。
试试用TensorRT-LLM或者llama.cpp的CUDA后端跑int4,比transformers快不少,vLLM报错可以贴出来看看。
vLLM装不上可以试试官方推荐的fastchat,配置简单很多,长文本推理提速明显。
int4在transformers下确实快不到哪去,量化反量化开销不小,而且V100对int4支持一般。你2000输入这个长度,瓶颈大概率在prefill阶段,试试调大max_seq_len同时把batch开起来,别一次只跑一条。vLLM报错的话可以先看是不是CUDA版本和torch对不上,装通了提速会很明显。flash attention在V100上只能上1代,收益有限,pytorch compile倒是值得试,不过编译时间得忍一下。
V100跑int4的ChatGLM3-6B,3-5秒其实不算特别离谱,但确实还有压榨空间。你注意下transformers加载int4默认走的是bitsandbytes,这个在推理时反量化开销不小,尤其你还是长输入,prefill阶段会明显拖慢。可以试试换成GPTQ或AWQ量化版本,配合AutoGPTQ或者vLLM的量化加载,速度通常能翻倍。
vLLM报错多半是CUDA和torch版本对不上,阿里云ECS的驱动有时候偏旧,建议先nvidia-smi看下CUDA版本,再按vLLM官方推荐的torch组合装,别直接pip install最新版。装好之后关键参数是gpu_memory_utilization和max_model_len,你2000进200出,max_model_len设4096就够,别开太大浪费显存。
flash attention在V100上支持有限,FA2基本是Ampere起步,V100只能用FA1,提升没那么夸张,但能开还是开着。pytorch compile对这类自回归生成收益一般,编译时间还长,不太建议折腾。
真正立竿见影的是batch和并发,如果你不是单请求延迟敏感,把多个总结任务攒一批一起推理,吞吐能上去很多。另外确认下你有没有开do_sample,采样比greedy慢不少,总结任务其实greedy就够用。
int4本来就慢,换vLLM或TensorRT-LLM提速明显,flash attention也值得开。
V100跑int4的ChatGLM3-6B单次3-5秒确实偏慢了,我之前在T4上试过类似的配置,大概也就2秒出头。你这个延迟我怀疑主要不是显存的问题,而是transformers那套默认的推理路径没做kv cache复用和continuous batching,每来一个请求都重新算一遍prefill。2000 tokens的输入在6B模型上prefill本身就挺吃时间的,尤其int4量化后反量化也有开销,V100对int4的支持其实并不算友好,它是靠fp16 tensor core吃饭的。vLLM报错的话可以看看是不是CUDA版本和torch对不上,它要求torch 2.1以上加CUDA 11.8或12.1,依赖冲突基本都出在这。装好之后把gpu_memory_utilization调到0.85左右,max_model_len设成4096,dtype用half,int4的话得走AWQ或者GPTQ权重,别直接用官方的量化checkpoint。flash attention在V100上支持有限,FA2主要吃Ampere及以后,V100只能用FA1,提升不大。pytorch compile可以试但编译时间挺久,长文本场景收益也就10%上下。其实你这个任务更适合换个思路,用vLLM或者TGI起服务,把请求攒一下做batch,吞吐能翻好几倍。
V100不支持flash attention 2,试试装xformers或者换A10;还有个坑是int4量化在V100上反而慢,换fp16可能更快。
V100跑int4的6B模型3-5秒其实不算离谱,但确实还有压榨空间。你max_seq_len如果默认拉满到8k,光KV cache就吃掉不少,长文本总结建议按实际长度截断,能省一截时间。vLLM值得再折腾一下,报错多半是CUDA和torch版本对不上,装之前先锁死版本,跑通之后吞吐提升很明显。flash attention对V100支持一般,别抱太大期望,倒是可以试试把batch调大做并发推理会更划算。
量化版本身就慢,换vLLM或TensorRT-LLM提速明显,长文本总结开flash attention也有用。
int4本身就会拖速度,试试换成fp16加flash attention,长文本场景提升挺明显的。