最近在试着微调一个7B的LLM,用的LoRA,单张4090(24G)。一开始以为LoRA显存占用会很小,结果实际跑起来batch size开到2就OOM了,序列长度也就1024。查了挺多资料,有人说用DeepSpeed ZeRO-3能把优化器状态分片,也有人说直接上两张卡用FSDP更省事。
PyTorch跑大模型总爆显存,换DeepSpeed还是直接上多卡?
全部回复
共 23 条单张4090跑7B LoRA还爆显存,其实挺常见的,问题不一定在优化器状态,而是中间激活值和KV cache在作祟。我之前试过把batch size压到1,序列长度砍到512,勉强能跑起来,但loss波动特别大,效果也不理想。DeepSpeed ZeRO-3确实能把优化器状态和梯度分片,但单卡场景下收益有限,它更多是为多机多卡设计的,单卡上反而可能因为通信开销拖慢速度。FSDP倒是更贴近你的需求,两张卡就能把参数、梯度和优化器状态全部分片,而且PyTorch原生支持,配置起来比DeepSpeed直观很多,就是得注意把模型先load到CPU再wrap,不然照样OOM。不过说实话,如果你的目标是微调而不是从头训练,与其折腾这些分布式方案,不如先把LoRA的rank降到8或者4,同时用gradient checkpointing把激活值重新计算,这俩组合拳往往能省出好几G显存。另外你序列长度1024的话,可以检查下attention是不是用了flash-attention,这个优化对显存和速度的提升都特别明显。要是还不行,那就上两张4090跑FSDP吧,但记得sharding策略选full shard,别用gradient shard,后者反而更吃显存。最后问一句,你的LoRA是只挂在attention层还是也挂了MLP层?有时候挂载层数太多也会让显存涨得厉害。
4090就跑7B还是有点勉强,建议先查下是不是activation占大头,把gradient checkpointing开了再说。
单卡24G跑7B LoRA开2就爆,多半是context长度问题,DeepSpeed对单卡提升有限,不如直接上双卡FSDP省心。
单卡24G跑7B LoRA确实紧,ZeRO-3分片优化器状态挺对症,但FSDP用起来更省心。
4090跑7B LoRA本来就很极限,ZeRO-3分片能救,但不如直接两张卡FSDP省心。
4090跑7B LoRA爆显存太正常了,先查下是不是梯度检查点没开,这比换框架省事多了。
双卡FSDP确实更省心,但先查下是不是LoRA没开gradient checkpointing,那个省显存立竿见影。
说实话LoRA在7B上batch=2还爆显存,大概率是没开gradient checkpointing,这玩意儿能直接砍掉一大半激活内存。我之前在3090上跑13B的QLoRA,开了之后batch=4都稳得很,你先试试这个再决定上不上DeepSpeed。至于ZeRO-3和FSDP,单卡其实都用不上,多卡的话FSDP确实更省心,PyTorch原生支持不用改代码,DeepSpeed配置调起来反而容易踩坑。不过两张4090互联带宽一般,跑7B可能通信开销比计算还大,不如先优化一下数据加载和显存碎片。
4090上LoRA跑7B,batch size开到2就爆其实挺正常的,24G看着大但光权重加激活就吃掉不少。我个人建议先别急着上多卡,DeepSpeed ZeRO-3在这种单机场景下配置起来有点折腾,反而FSDP跟PyTorch原生集成更好调,两张卡就能把显存压力摊掉一大半。不过你序列长度才1024的话,也可以试试把gradient checkpointing开了,再把LoRA的r值压到8,大概率能塞下batch size 4。要是之后真要多卡,记得留意下通信开销,NVLink和PCIe的差距在微调时能明显感觉到。
说实话7B+LoRA在24G上爆显存有点不太正常,你检查下是不是梯度检查点没开,或者transformer库版本太老导致activation没释放。我之前用QLoRA加4bit量化,同样配置能塞下batch size 4,序列长度还是2048。DeepSpeed和FSDP在这个规模都显得有点重,单卡先把bitsandbytes和gradient checkpointing调好,大概率能解决。真要上多卡的话,FSDP配置起来比DeepSpeed省心不少,而且PyTorch原生支持,不用改太多代码逻辑。不过你序列长度才1024就爆,感觉还是哪里没优化到位,建议先看看是不是把padding开得太大了。
说实话24G跑7B的LoRA,batch size开到2确实有点紧,但OOM可能不光是显存总量的问题,序列长度和梯度检查点开关影响也很大。我试过把gradient_checkpointing打开,再配合ZeRO-3,单卡能勉强塞下batch size 4,不过速度会慢不少。如果你手头能借到第二张卡,我个人更推荐FSDP,配置起来比DeepSpeed简单,而且不用调一堆stage相关的参数,省下的时间够你多跑几次实验了。
4090跑7B LoRA确实紧,建议先查下是不是activation峰值爆了,ZeRO-3比FSDP配置省心点。
单卡24G开batch2就炸,多半是梯度检查点没开,FSDP要改的地方比DeepSpeed多不少。
说实话LoRA在7B上batch size只能开到2确实有点反常,我怀疑你没开gradient checkpointing,那个能省掉一大半激活显存,24G跑7B+LoRA正常来说batch size 4到8应该没问题。DeepSpeed ZeRO-3和FSDP本质都是把优化器状态、梯度甚至参数分片到多卡上,但单卡场景下ZeRO-3反而会因为通信开销拖慢速度,而且配置起来坑挺多,比如要处理find_unused_parameters和offload的兼容性。如果你手头能租到第二张4090,我建议直接上FSDP,PyTorch原生支持,代码改动就两三行,而且对LoRA这种参数高效微调特别友好,因为冻结的base model参数本来就不需要梯度,FSDP能直接跳过它们的分片。不过两张卡之间如果是PCIe而不是NVLink,通信带宽可能成瓶颈,序列长度1024的话影响不大,但你要是以后试长文本就得注意了。还有个思路是换QDoRA或者AdaLoRA这种更省显存的变体,但说实话提升有限,不如先把gradient_checkpointing=True打开,然后把per_device_train_batch_size降成1,用梯度累积来模拟大batch,我这么跑过13B都能稳在24G内。最后提醒一句,如果只是微调而不是从头训练,ZeRO-3的offload到CPU反而容易让显存碎片化,FSDP的CPU_offload参数倒是更干净利落。
LoRA吃显存主要在激活值,24G跑7B确实紧张,先试试gradient checkpointing说不定就够了。
我之前也遇到过这情况,LoRA本身省的是可学习参数,但激活值那块还是照单全收,24G其实很紧张。DeepSpeed ZeRO-3对单卡其实没啥用,它主要是跨卡分片,你这情况不如先把batch size降到1,再开gradient checkpointing,能省不少。另外如果真要上多卡,FSDP确实比ZeRO-3配置简单,但两张4090互联带宽不够的话,通信开销可能比收益还大,得先看看你的主板支不支持PCle 5.0。
说实话24G跑7B LoRA还爆显存,多半不是容量不够,是峰值显存没控住。LoRA虽然只训练适配器,但反向传播时激活值才是大头,序列长度1024加batch 2,光激活就能吃掉10多个G,加上基座模型权重和梯度,4090确实紧巴巴。
我建议你先别急着上多卡,把gradient checkpointing开了,这个能省掉一大半激活显存,代价就是慢个20%左右。如果还不行,再看看是不是把padding都去掉,用动态batch或者更短的序列,7B模型其实塞得下batch 4到8。DeepSpeed ZeRO-3在这场景下有点杀鸡用牛刀,它主要是为了省模型权重和优化器状态,LoRA本来就没多少可训练参数,收益不大。
真要换方案,我反而觉得FSDP更顺手,尤其你如果只有两张卡,PyTorch原生支持,配置起来比DeepSpeed那堆config文件省心多了。不过FSDP也会增加通信开销,两张卡互联如果是PCIe不是NVLink,速度可能会让你有点难受。
我自己试过单卡4090跑13B全量微调(用QLoRA),关键是得把bitsandbytes的4bit量化开起来,再加个paged optimizer,显存能压到16G以内。你如果只是LoRA,其实可以试试把基座模型量化到8bit,哪怕4bit,显存立刻宽裕很多,精度损失在微调场景下基本看不出来。
还有个容易忽略的点,检查下你的优化器是不是AdamW,它的二阶矩会额外占一份和模型同尺寸的显存。换成Adafactor或者SGD,能省不少。不过如果你已经用了LoRA,优化器状态只针对低秩矩阵,那这个就不是主要瓶颈了。
总之我倾向先做减法:开gradient checkpointing,量化基座,清掉冗余参数,大概率单卡就能跑起来。多卡是最后手段,除非你确定要调更大的模型或者更长的序列,不然折腾分布式反而拖慢实验迭代速度。
其实LoRA省的是可训练参数,但激活值和中途的中间变量还是照常算的,7B模型序列1024单卡batch2爆掉挺正常。我之前也拿4090试过,后来发现把gradient checkpointing开了,batch size能翻一倍还不止,代价就是多跑点时间但总比OOM强。至于ZeRO-3和FSDP,单卡上ZeRO其实帮不上太大忙,它主要是跨卡分片才有效果,你如果真想上两张卡,FSDP配置起来确实更顺手,而且跟LoRA兼容性也更好。建议先试试关掉缓存、开checkpointing,再决定要不要加卡,毕竟多卡调试也有成本。
其实LoRA省的是可训练参数,但7B模型的反向传播激活值还是得全量存,24G卡跑1024长度确实吃紧。我试过ZeRO-3配LoRA,offload到CPU能勉强塞下batch 4,但速度掉得惨烈,一步要等半天。如果预算允许,两张4090跑FSDP会舒服很多,代码改动也小,PyTorch原生支持总比调DeepSpeed配置省心。不过单卡的话,除了ZeRO,你也可以试试gradient checkpointing加混合精度,先把batch 1跑通再慢慢优化。
顺便说个坑,DeepSpeed和LoRA的peft库偶尔会版本冲突,报错起来挺玄学的。要是你主要图省事,直接FSDP+CPU offload,至少报错好查,社区案例也多。另外序列长度1024对7B来说不算短了,真不行就把max_len砍到512,显存直接少一半,很多任务微调其实够用。
我倒是好奇你用的什么优化器,AdamW的state占大头,要是换Adafactor能省不少。不过话说回来,单卡24G跑7B LoRA本来就有点极限,很多人最后都切到Qwen1.5-4B或者Mistral-7B的4bit量化了,效果差不太多但显存舒服太多。你要是
我最近也卡在类似的问题上,单卡24G跑7B LoRA,batch size稍微大点就爆,后来发现其实光靠LoRA省的那点显存根本不够看,真正吃显存的是激活值和梯度。我自己试下来,DeepSpeed ZeRO-3对单卡场景其实帮助有限,它主要是省优化器状态和参数分片,但你batch size本来就小,激活值那部分还是得硬扛。FSDP倒是更直接,不过两张卡的话你得考虑通信开销,数据并行加FSDP混合用可能更稳。我最后是手动算了算显存预算,把batch size压到1,梯度累积加到8,再加个gradient checkpointing,居然就稳住了,虽然慢点但至少不OOM。你要是追求省事,直接上两卡FSDP确实比折腾DeepSpeed配置简单,不过记得把CPU offload关掉,不然速度会很难看。另外你序列长度1024其实不算长,如果还想加长,可能得考虑序列并行或者干脆换更小的基座模型。
4090跑7B LoRA爆显存大概率是激活值没省,开个gradient checkpointing试试,比上卡快多了。
说实话LoRA省的是可训练参数,但激活值和中途的中间变量该占还是占,24G跑7B序列1024想上batch 2确实有点紧。我之前也卡在这,后来把gradient checkpointing开了,再加个ZeRO-3(其实单卡也能用)就稳住了,batch能到4。FSDP的话如果你没有双卡互联特别快(比如NVLink),通信开销反而可能让你更难受,不如先把单卡榨干再说。另外你可以试试把bf16换成fp8混合精度,显存能再挤出来一点,不过得看你的卡和库支持情况。