最近在折腾把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秒确实偏高了。你试试直接加载fp16看看速度,有时候int4的量化反而不如原生精度在V100上跑得快,因为V100的tensor core对fp16优化很好,而且你的显存16G足够放6B的fp16了,没必要强行int4。另外长文本场景下,max_seq_len如果设得太大,比如超过2048,attention计算量会指数级增长,2000tokens的输入建议把max_seq_len卡在2048或者稍高一点,别给太多余量。flash attention值得装,尤其长文本收益明显,但V100是Ampere之前的架构,可能需要特殊版本支持,你可以先查下兼容性。pytorch compile在这类模型上提速不一定明显,反而可能增加编译时间,不如先试试torch.inference_mode加half精度,再把batch size调成1,因为你这任务输出就100-200tokens,batch size大了没意义,纯粹浪费显存带宽。还有个小技巧,把输入拼接成一条完整文本而不是分开多个片段,能减少重复的prefill计算。vLLM如果装不上就别折腾了,它对V100支持一般,transformers调好参数够用了。最后检查下是不是跑在CPU上,有时候环境变量没配好会fallback到CPU,那就不是慢一点的问题了。
3-5秒其实不算离谱,你输入2000tokens已经接近6B的注意力瓶颈了,试试把max_seq_len调小到1024,长文本分段处理,速度能明显上来。flash attention值得装,对长序列提升很大,pytorch compile在V100上效果一般,别抱太大期望。vLLM那个报错大概率是CUDA版本和pytorch不匹配,建议直接用官方docker镜像,省心很多。另外int4本身在V100上就不是最优解,换成fp16加量化可能会更快一点。
你这情况我太熟了,之前我拿A10跑7B模型也是这德行,int4加载理论显存够但实际速度跟显存关系真不大,瓶颈在计算饱和度和内存带宽。3-5秒单次其实不算离谱,尤其你输入2000tokens,prefill阶段占了大部分时间,自回归生成反倒还好。vLLM装不上就别硬磕了,官方transformers其实够用,关键是别用quantization那套API直接load,换个思路:先加载fp16原模型,再自己套一层bitsandbytes的4bit配置,有时候官方封装反而有额外开销。另外强烈建议开flash attention,transformers现在支持传attn_implementation="flash_attention_2"参数,能省不少显存带宽,速度提升肉眼可见。还有你试试把max_seq_len设成输入+输出+余量,别给太大,不然KV cache占着内存拖慢速度。pytorch compile也可以试,但注意第一次跑会卡很久,第二次开始才有效果。对了,你ECS的CPU核数和内存多大?有时候数据加载和tokenizer处理也会拖后腿,可以试试把输入提前pad到一个固定长度,减少动态shape带来的额外计算。最后提一句,如果长文本总结是刚需,可以考虑把输入分段处理,避免一次性塞2000tokens,虽然麻烦点但速度能快不少。
3-5秒对于int4的6B在V100上其实不算离谱,你这输入长度2000tokens本身就吃显存带宽。先试下把max_seq_len从默认值调小到2560左右,能省不少计算量。flash-attention值得装,V100虽然不支持fp8但能吃到内存带宽优化,pytorch compile的话记得关掉动态shape。vLLM那个报错大概率是CUDA版本和torch不匹配,建议直接pip装对应版本的预编译包。另外长文本任务可以试试把输入分段处理,每段单独过模型再拼接结果,有时候比硬撑长上下文快一倍。
V100跑int4的6B确实不该这么慢,你这输入长度2000tokens已经接近模型极限了,自注意力计算量是平方增长的,慢是正常的。建议先试下把max_seq_len调小到512或1024(如果任务允许),同时batch size设1,因为vLLM在小并发下优势不明显。flash attention值得装,能省不少显存带宽,PyTorch compile也能白嫖一些加速。另外可以看下是不是quantization配置没走对,int4加载时最好用device_map="auto"让模型均匀分布到多卡,单卡的话确认一下是不是真的加载到了GPU而不是CPU上。
说实话int4在V100上慢挺正常的,V100对int4量化支持一般,而且transformers原生推理对长输入本来就不友好。你这2000tokens输入其实瓶颈在prefill阶段,建议先试试把max_seq_len设到2048看看会不会有改善,另外可以开一下torch.compile试试,虽然首次编译会慢点但后续会快很多。vLLM确实值得折腾一下,报错多半是CUDA版本和flash-attention不匹配,换个docker镜像能省不少事,参数的话设个gpu-memory-utilization=0.9和max-model-len=2048基本就够了。还有个土办法,长文本总结可以试试把输入切块分批处理,虽然逻辑上要改点代码,但实测吞吐能提一倍。
你这情况我太熟了,V100跑int4按理说不该这么慢,先确认下是不是没锁核或者CPU在瓶颈上。长文本任务建议把max_seq_len调成跟输入输出总长匹配,别留太多冗余,batch size设1就行。另外可以试试把量化换成GPTQ或者AWQ,比transformers自带的int4快不少,vLLM实在装不上就换TGI,对显存利用更狠。
你这个输入长度下3-5秒确实有点偏慢了,我怀疑瓶颈不在显存而是解码阶段。可以试试把max_seq_len设成刚好覆盖你输入+输出,别留太多余量,再开flash attention,V100上收益挺明显的。pytorch compile对动态shape支持一般,你这种固定长度任务可能有效果,但得留意会不会报错。另外你确定int4真的加载成功了吗?有时候库版本不对会静默回退到fp16,速度反而更糟。
V100跑int4的6B确实不该这么慢,3-5秒大概率是卡在长文本的attention计算上了。你试试把max_seq_len设成2048或者更小,然后开flash attention,transformers新版直接传attn_implementation="flash_attention_2"就行。另外pytorch compile对推理提升挺明显的,但第一次跑会花点时间编译,别被那个卡顿吓到。vLLM那个报错八成是CUDA版本和依赖没对齐,不折腾也罢。
试试把max_seq_len调小点,2000输入用vLLM得改gpu-memory-utilization,另外flash attention能快不少。
我最近也踩过这坑,int4加载其实对推理速度提升有限,尤其你输入2000tokens这种长文本,瓶颈全在显存带宽和attention计算上。V100虽然显存够,但它的算力跟A100差距挺大,3-5秒其实不算离谱。你可以试试把量化换成bitsandbytes的8位,有时候反而比int4快,因为反量化开销小。另外max_seq_len别设太大,2000输入加200输出,设个2500就够了,不然显存会预分配一堆没用的buffer。flash attention值得搞,V100虽然不支持fa2,但xformers的memory efficient attention也能提速,就是安装得注意版本匹配。pytorch compile我试过,第一次跑会慢,但之后确实能快20%左右,不过容易跟transformers版本冲突。vLLM那个确实折腾,但如果你愿意再试一次,关键是要把--max-model-len调成跟你任务匹配的长度,默认值会吃满显存导致OOM换页。你长文本总结任务其实更适合用llama.cpp的gguf格式,CPU+GPU混合跑,速度反而稳。
试试把max_seq_len调成2048,vLLM装的时候用Python3.10的干净环境,别用conda。
vLLM那个报错大概率是版本冲突,建议直接pip装vllm最新的release版,别用源码装。你这输入长度2000tokens确实有点尴尬,int4下KV cache会吃不少显存,试试把max_seq_len设成4096,batch size先锁1,然后开一下flash attention,transformers新版直接传attn_implementation="flash_attention_2"就行。
另外pytorch compile对GLM这种模型收益其实不大,而且第一次编译要等很久,不如直接检查下是不是被CPU算子拖累了,跑的时候看下nvidia-smi,如果GPU利用率不到80%,大概率是数据预处理或者tokenizer在拖后腿。
我最近也在搞长文本摘要,发现把输入切块再并行推理,最后合并结果,体感比单次硬跑快不少,虽然总tokens一样,但能避开单次推理的峰值延迟。
试试开flash attention和torch.compile,长文本场景能快不少,vLLM报错多半是版本坑。
int4加载时记得设低max_seq_len,2000输入其实不用太大,batch size设1就行。
你这情况我太熟了,V100跑int4其实瓶颈多半不在显存,而是transformers的贪吃解码太慢。建议先试试把max_seq_len调成跟输入长度接近,别让模型预留太多位置,然后开torch.compile试试,哪怕只编译decoder层都能快不少。另外长文本总结其实可以试试把输入切成几段并行处理再合并结果,比单次硬啃2000token划算。vLLM那个依赖坑我也踩过,可以试试用官方docker镜像,省得配环境。
3-5秒确实有点离谱了,我怀疑你是不是没开half精度或者量化没生效,先打印下model.dtype确认下。长文本任务可以试试把输入截断到1024,或者用langchain做map-reduce,把总结拆成多步,虽然总时间差不多但体感会快。flash attention在V100上好像支持不太好,不如直接上xformers,装上之后推理能快个30%左右。
你这输入输出长度其实不算特别长,3-5秒确实慢了。我之前用A10跑int4也就1秒多,V100按理说不会差这么多。检查下是不是CPU在跑,或者环境变量没设对。加速的话别折腾vLLM了,直接上transformers的bettertransformer,一行代码的事,能白嫖不少加速。另外batch size对单次推理没
说实话int4+transformers这速度挺正常的,3-5秒对长文本任务来说不算离谱。你试试把max_seq_len调成和你实际输入输出差不多的值,别留太多余量,显存利用率能上来不少。vLLM那玩意儿对ChatGLM支持确实一般,报错多正常,别死磕。
flash attention值得装一下,能省不少显存带宽,速度提升挺明显的。pytorch compile在V100上效果可能一般,老卡收益不大。另外你输出100-200tokens的话,可以试试开streaming输出,首token延迟会低很多,体感上会快不少。
还有个土办法,把输入切块处理,分段总结再合并,对长文本来说反而能绕开单次推理的瓶颈。batch size除非你同时处理多条请求,否则改了意义不大。