最近在折腾本地部署,想用vLLM跑一个70B的模型(比如Llama 2 70B),手头是8张3090(24GB)。按道理8*24=192GB显存,应该够吧?但实际启动时老是OOM,查了资料发现可能跟张量并行和流水线并行的切分方式有关。我试了tensor-parallel-size=8,结果每张卡显存直接冲到22GB,推理速度也慢得离谱。想问下各位,这种情况是不是应该用pipeline-parallel配合tensor-parallel?或者量化后跑int8/4?还有,如果只用4张卡,是不是反而更稳?求具体参数参考,谢谢!
请教大佬们,8卡3090部署70B模型怎么切分才能不爆显存?
全部回复
共 137 条说实话你这个问题我上周刚踩完坑,8卡3090跑70B其实不是显存总量不够,是KV cache和激活值把内存撑爆了。tensor-parallel-size=8时每张卡要存完整模型权重分片,但通信开销巨大,3090的PCIe带宽根本喂不饱,速度慢很正常。我最后是用tensor-parallel-size=4 + pipeline-parallel-size=2跑的,显存占用稳定在20GB左右,推理速度比纯TP8快了一倍多。另外强烈建议开fp16混合精度,但别用int8,3090的int8加速其实一般,量化后精度损失在长文本生成时特别明显。如果你只是自己玩,4卡TP4跑70B其实更舒服,显存余量足,还能开大点的max-model-len,我试过把序列长度拉到4096都不OOM。最后记得设--gpu-memory-utilization 0.92,别用默认的0.9,这2%的余量有时候就是压死骆驼的最后一根稻草。
我之前也踩过这坑,8卡全上TP反而因为跨卡通信瓶颈拖慢速度。建议试试TP=4+PP=2,每张卡大概12GB左右,留足KV cache余量。另外int8量化其实很稳,vLLM对AWQ支持挺好,基本不掉点。4卡跑的话TP=4其实够用,但batch size要调小点,不然显存还是会爆。
8卡全上tensor parallel=8的话,每张卡除了权重还要塞激活值和KV cache,22GB已经很极限了,速度慢大概率是通信开销把算力吃掉了。我建议试试TP=4+PP=2,把层切一半,显存压力小很多,吞吐反而能上来。量化的话int8在70B上掉点不明显,但AWQ或GPTQ对显存释放挺明显的,4卡跑int4其实也行,就是batch size别开太大。你vLLM版本更新到最新了吗?老版本对PP支持有点坑,容易OOM误报。
8卡3090跑70B其实卡在KV cache和中间激活上,纯tensor parallel=8确实容易爆,我建议先试tensor parallel=4加pipeline parallel=2,把每张卡的负载降下来。另外int8量化基本无损,能省不少显存,4卡跑的话速度反而可能比8卡更稳定,因为通信开销小很多。你可以先看看显存具体被谁占了,用nvidia-smi监控一下再调。
8卡3090跑70B理论显存够但实际卡在KV cache和激活值上,TP=8时通信开销太大反而拖慢速度。我之前试过TP=4+PP=2,配合AWQ量化到4bit,每卡占用稳定在17GB左右,吞吐比纯TP=8高不少。另外建议把vLLM的gpu-memory-utilization调到0.9,并关掉--enforce-eager减少CUDA graph显存占用。4卡确实更稳,但batch size得压到16以下,不然照样爆。你试过用--max-model-len限制序列长度吗?有时候默认4096都能吃掉好几GB。
8卡全上TP=8的话,通信开销确实会吃掉不少带宽,而且KV cache和激活值也容易挤爆,试试TP=4+PP=2的组合,每张卡压力小很多。量化的话建议直接上AWQ或GPTQ的int4,70B大概能压到40GB出头,8卡跑起来余量很充足。如果只插4张卡,int4下其实也够,但速度肯定不如8卡并行,得看你更在意吞吐还是单请求延迟。另外记得开vLLM的gpu-memory-utilization参数,默认值有时候会预留太多显存。
8卡全上tensor parallel确实容易撞墙,Llama 2 70B光权重就要140GB,加上激活和KV cache,24GB卡单张能剩的空间不多。我之前试过TP=8+PP=2,把层切成两段,每段4卡并行,能跑起来但吞吐还是不行,后来干脆换GPTQ 4bit量化,单卡负载直接降到12GB左右,速度反而比硬撑fp16快。你不如先上4卡TP=4+int8,稳得很,8卡留给更大模型或者长上下文用。另外注意vLLM的gpu_memory_utilization要调到0.9以上,不然默认0.8会白白浪费几GB。
试试4卡tensor并行+量化int4,8卡通信开销太大反而慢,我这么跑70B稳得很。
这问题我踩过坑,8卡3090跑70B光上TP=8确实会卡在KV cache上,22GB基本就是峰值了。建议TP=4+PP=2,或者直接TP=8但把KV cache比例调小到0.3以下,能缓解不少。量化的话int8挺稳的,AWQ或GPTQ都行,速度比FP16快,就是偶尔会有精度损失。4卡跑的话显存确实宽裕,但吞吐量会掉一大截,看你更看重延迟还是并发。另外记得把vLLM的gpu_memory_utilization设到0.9以上,默认值太保守了。
8卡3090跑70B其实瓶颈不在显存总量,而在单卡24G的碎片化和通信开销。我之前试过TP=8,加载时确实会飙到22G+,但推理慢主要是因为张量并行跨卡通信太频繁,尤其batch小的时候。建议你试试TP=4+PP=2,把KV cache和激活值分摊一下,显存能压到18G左右。量化的话int8基本无损,AWQ或GPTQ都行,4bit会牺牲点精度但速度提升明显。4张卡反而更稳是真的,因为通信拓扑简单,我最后就是TP=4跑70B,吞吐比8卡还高,你可以先排除一下是不是PCIe带宽瓶颈。
说实话8卡3090跑70B主要卡在KV cache和中间激活值上,tensor-parallel=8时每卡22GB已经很接近极限了,建议加个--max-model-len把序列长度压到2048试试,能省不少显存。另外纯TP通信开销太大,换成TP=4+PP=2会稳很多,吞吐反而可能更高。量化的话AWQ 4bit最省心,显存直接砍半,但注意vLLM对Llama 2的AWQ支持得比较成熟,GPTQ偶尔会报错。只用4卡的话如果模型权重复制两份做数据并行,每份TP=4跑int8其实也能用,不过batch size就得调小。我这边是TP=4+PP=2+AWQ,8卡跑70B稳定在18GB左右,速度比全TP快不少,你可以参考下。
8卡全上tensor parallel其实不是最优解,3090的NVLink带宽只有600GB/s,跨卡通信开销太大,尤其70B这种大模型,all-reduce的时间可能比计算还久。我试过TP=8跑13B都明显掉速,70B直接卡成PPT很正常。你不如试试TP=4加PP=2,把模型沿层切两半,每半4卡张量并行,这样每张卡的KV cache和激活值压力小很多,显存占用大概能压到18GB左右,吞吐反而上去了。不过PP会有气泡问题,batch size得调大点才能弥补,建议把max-num-seqs调到32以上。量化的话,int8用AWQ或GPTQ都行,显存直接砍半,但3090是安培架构,int8的gemm没有专门加速,推理速度提升有限,int4倒是快,但质量损失看任务,代码生成和数学推理掉点挺明显的。另外你问4卡是不是更稳,其实不一定,4卡跑70B必须量化,fp16的话激活内存就爆了,除非你开offload,但那样速度更惨。我现在的方案是TP=4加PP=2,再用bitsandbytes加载8bit,跑起来显存峰值17.5GB,生成速度大概25 tokens/s,你可以参考下。还有个小坑,vLLM的cache块大小记得调低,默认16会多占不少显存,改成8能省出1GB多。最后建议你先把模型用safetensors格式转换一次,有时候checkpoint碎片太多也会导致临时显存峰值。
8卡3090跑70B,TP=8确实容易卡在通信瓶颈上,而且KV cache稍微一涨就爆。我建议你先试试TP=4+PP=2,把vLLM的gpu-memory-utilization调到0.9,然后开启--enable-chunked-prefill,这样能缓解不少。量化的话,AWQ或GPTQ的4bit在3090上效果不错,显存能压到16G左右,推理速度反而可能比FP16更快。至于4卡,虽然显存总量小了,但通信开销更低,如果并发请求不多,确实更稳定,你可以先跑个benchmark对比下延迟再决定。
试试4卡TP+2卡PP,量化到int8,vLLM开下内存预留参数,应该能稳。
你这情况我太熟了,8卡3090跑70B光上TP=8确实容易爆,因为每层权重和KV cache的通信开销会吃掉不少显存。建议试试TP=4 + PP=2,把vLLM的流水线并行开起来,显存压力会小很多,速度反而可能更快。另外int8量化基本是必须的,AWQ或者GPTQ都行,4bit的话推理质量有点损失但显存余量很大。只用4卡不是不行,但batch size稍微大点就卡死,不如8卡切分灵活。你启动的时候记得设--gpu-memory-utilization 0.9,别让vLLM默认吃满。
说实话你这个问题我踩过一模一样的坑,8卡3090跑70B理论显存够,但实际瓶颈根本不在总容量,而在KV cache和activation峰值。tensor-parallel-size=8的话每张卡要同步通信,3090的PCIe带宽撑不住,反而比4卡慢不少。我建议你先试试tensor-parallel-size=4加pipeline-parallel-size=2,这样每张卡大概占14-16GB,留出足够余量给推理时的临时张量。另外量化真的很有必要,int8下显存直接砍半,我跑Llama 2 70B用AWQ量化后4卡TP=4也就勉强20GB以内,速度比8卡全精度快两三倍。你如果坚持8卡,记得把gpu-memory-utilization调到0.9,还有max-model-len别设太高,2048就够,不然KV cache会爆炸。最后问下你用的什么推理框架?我之前试过vLLM 0.3版本有显存泄漏的bug,升级到0.4后OOM问题基本消失了。
试试tp=4加pp=2,8卡全用但别硬上tp8,通信开销太大反而拖慢。
量化到int8能稳不少,显存余量也大,速度损失其实可接受。
说实话8卡3090跑70B这个事儿我折腾过挺久,你的问题大概率不是显存总量不够,而是KV cache和中间激活值在作祟。TP=8的时候每张卡要同步通信,3090的NVLink带宽本来就不算强,速度慢太正常了,我建议你试试TP=4+PP=2的组合,把模型层数切成两半,每半用4卡张量并行,这样通信压力小一半,显存占用也能压到18GB左右。另外别忽略vLLM的gpu-memory-utilization参数,我实测设成0.9比默认值稳很多,但你要是开量化,int8下TP=8反而可能因为反量化开销更慢,不如直接FP16+TP=4。至于只上4张卡,显存确实够(70B权重就要140GB,4卡才96GB绝对不够),所以别考虑这个方向。还有个坑是max-model-len别设太高,4096和8192的显存占用差距巨大,你要是跑长文本,建议开--enable-chunked-prefill,能省不少碎片空间。最后提醒下,检查下是不是CUDA版本和vLLM不匹配导致显存没释放干净,我上次就是这问题白折腾了两天。
说实话你这情况我太熟了,刚折腾完70B的时候也是这么过来的。8卡3090跑70B理论显存够,但vLLM对KV cache和中间激活值的管理比你想象得激进,tensor-parallel-size=8看着合理,实际通信开销大,每张卡还得留出冗余空间,OOM很正常。我建议你先试试TP=4+PP=2的组合,这样每张卡压力小很多,而且3090的NVLink带宽也扛得住。另外量化基本是必选项了,int8跑起来显存能压到15G左右,速度反而比fp16快,int4的话质量损失有点明显,除非你只是玩玩。至于用4张卡,我个人觉得更稳,因为3090的PCIe互联在8卡时瓶颈太严重,4卡反而吞吐更高,不过得看你的模型并行度需求。最后提醒下,启动参数里gpu-memory-utilization别拉满,留个10%给CUDA context和碎片,不然照样爆。
说实话8卡3090跑70B全精度就是卡在显存墙上了,光权重就140GB,加上KV cache和激活值,192GB看着够但实际很紧。我建议你直接上int4量化,比如GPTQ或者AWQ,这样单卡能塞下,tensor-parallel-size设4就行,8卡反而通信开销太大拖慢速度。另外pipeline-parallel虽然省显存,但3090的PCIe带宽会成瓶颈,除非你用NVLink否则不推荐。我自己的经验是4卡int4跑70B最稳,显存占用大概12GB每卡,速度还能接受。
另外你提到只用4张卡会不会更稳,答案是肯定的,因为张量并行超过4张后,AllReduce通信时间会吃掉大部分算力提升。但如果你非要8卡全用,可以试试tensor-parallel-size=4加pipeline-parallel-size=2,同时把KV cache的gpu_memory_utilization调到0.85,再开--enforce-eager避免CUDA graph额外占显存。我这么配过,能跑起来,但延迟还是比4卡高不少。