最近在试着用LoRA微调一个7B的Llama模型,任务挺简单的,就是给客服对话做情感分类。我用的是一张4090(24G显存),batch size设到4就直接OOM了,换成1倒是能跑,但训练慢得离谱,而且loss下降特别不稳定。已经试过gradient checkpointing和混合精度训练,感觉效果有限。看网上有人说可以用DeepSpeed ZeRO或者量化到4bit,但不知道怎么配置才不崩。想问问有经验的老哥,显存不够的情况下,怎么平衡速度和效果?另外,有没有推荐的库或者trick,能让我这张卡撑住微调?先谢过了!
自己用PyTorch微调Llama,显存总爆掉,有什么省钱又实用的技巧吗?
全部回复
共 157 条4090跑7B LoRA其实很够用了,你试试把batch size固定成1,然后梯度累积设成8或16,效果跟batch 4差不多,loss还稳。4bit量化建议直接上bitsandbytes,配peft的prepare_model_for_kbit_training,能省一半显存,速度损失也就10%左右。另外留意下是不是序列长度太长,客服对话一般512就够,别让tokenizer默认拉满2048,那才是爆显存的隐形杀手。
试试QLoRA加4bit NF4量化,batch size开2,再把序列长度砍到256,基本能稳住。
4090跑7B用bitsandbytes配peft就行,别硬刚全量微调,效果差不了太多。
24G跑7B说实话挺极限的,你试试unsloth这个库,它对LoRA的内存优化做得特别好,同样batch size能比原生省一半多。另外把序列长度砍到256甚至128,情感分类根本不需要长上下文,效果不会掉多少。量化到4bit的话建议用bitsandbytes的NF4,配合peft的prepare_model_for_kbit_training,基本能稳定跑起来。loss不稳大概率是学习率太高,降到1e-4左右再看看。
24G跑7B LoRA还OOM,大概率不是显存不够,是你在backbone上挂太多可训练参数了。试试target_modules只选q_proj和v_proj,别动全部线性层,参数量直接砍半还多。另外batch size=1不是不行,但要把gradient accumulation设到8甚至16,等效batch size上去了loss自然稳,就是多等几轮。4bit量化建议用bitsandbytes的NF4,配合peft的prepare_model_for_kbit_training,注意要把lm_head的dtype保持fp16,不然推理时输出会崩。DeepSpeed ZeRO2在这张卡上其实没必要,单卡ZeRO3反而会慢,不如直接开torch.compile加flash attention,省显存的同时还能提速度。还有个冷门技巧,把输入序列截断到256,客服对话本来就不长,情感分类用不着完整上下文,显存占用能再降三分之一。最后实在不行就换QLoRA+NF4,微调效果和LoRA差距很小,但显存占用能压到6G以内,你还能把batch size拉到8。
你这情况跟我上个月一模一样,4090跑7B用LoRA还爆显存,感觉主要吃亏在序列长度和batch size的平衡上。建议试试把max_seq_len砍到512,客服对话一般够用了,显存能省一大截。另外ZeRO-3配4bit量化确实能救急,但别指望速度,我实测吞吐会掉一半,不过至少能塞进batch size 8。还有个土办法,用PEFT的gradient accumulation配合batch size 1,把accumulation steps调到8,loss稳定性会好很多。要是还嫌慢,把优化器换成AdamW 8bit,省下来的显存能多塞几层梯度。
有没有更详细的教程推荐?
24G跑7B LoRA其实不用上ZeRO,试试把batch size降到1然后梯度累积开个8步,效果和batch size 4差不多,loss不稳定多半是学习率没跟着调。4bit量化建议用bitsandbytes的NF4,配合peft库的LoRA,显存能压到10G以内,速度反而比混合精度快。另外把序列长度裁到256,客服对话一般用不了那么长,能省不少显存。还有个小技巧,把optimizer换成8bit AdamW,省下来的显存可以塞进更大的batch。你试试这几个组合,应该能稳下来。
4090跑7B LoRA爆显存挺正常的,你试试把batch size固定成1,但梯度累积设到8,效果和batch size 4差不多,显存还能稳住。4bit量化用bitsandbytes的NF4格式,配QLoRA,基本能压到10G以内,速度损失不大。另外把序列长度截到128,客服对话一般没多长,省下的显存能开大batch。loss不稳的话,建议先冻结embedding层,只训attention和FFN,稳定很多。
你这情况我太熟了,24G跑7B LoRA正常得不行,试试把batch size固定到1然后梯度累积开个8,效果跟batch 4差不多还省显存。4bit量化是必须的,用bitsandbytes配peft库,QLoRA那套配置直接抄官方文档就行,基本不会崩。要是还嫌慢,可以把序列长度截到256,客服对话一般用不了太长,速度能提一截。另外loss不稳大概率是学习率太高,降到1e-4试试,比折腾显存管用。
说实话你这配置跑7B LoRA确实有点极限,但也不是完全没救。试试把LoRA的rank降到8甚至4,再配合8bit的bitsandbytes量化,显存能省下一大截,速度牺牲也不大。另外batch size别硬刚,用梯度累积到4的效果其实差不多,但显存压力小很多。
我自己的经验是,把序列长度砍到512(客服对话一般够用了),再加上paged optimizer,24G勉强能跑起来。DeepSpeed ZeRO Stage 2配offload optimizer也挺稳的,就是配置容易翻车,建议直接抄HF的官方示例。
顺便问下,你loss不稳定是不是学习率调太高了?7B模型用LoRA的话,lr设到1e-4到3e-4之间比较安全,太大了容易震荡。
试试QLoRA配4bit normalized,24G跑7B batch8没问题,速度损失能接受。
我直接上bitsandbytes的4bit加paged optimizer,OOM基本绝迹,loss也稳多了。
试试点8bit加载加paged_adamw,LoRA放全模块,24G跑7B batch 4完全够。
同款配置,我之前也卡在这。试试把LoRA的target modules从全部线性层改成只微调q_proj和v_proj,参数量能砍一半,效果基本不掉。另外batch size不用硬撑到4,gradient accumulation设成8,实际batch size还是4,显存压力小很多。4bit量化建议直接上bitsandbytes,配置很简单,配合peft库的prepare_model_for_kbit_training,基本不会崩,就是训练速度会慢个20%左右,但省下的显存足够你开更大的batch,整体算下来反而更快。还有个小技巧,把optimizer换成AdamW 8bit,能再省2-3G。
4bit量化加LoRA基本是24G卡的极限玩法了,batch size开1配梯度累积到8效果能稳不少。
试试PEFT库的QLoRA,一步到位省心,4090跑7B绰绰有余。
4090跑7B其实卡在中间档位,我试过把LoRA的r降到8再加4bit量化,batch size能上到8,速度反而比之前快。你那个loss不稳大概率是学习率太高,试试调低到1e-4左右,顺便把warmup steps拉长点。另外DeepSpeed ZeRO2在这任务上有点杀鸡用牛刀,真不如直接上QLoRA,配置少还省心。
24G跑7B LoRA其实挺宽裕的,问题多半出在数据加载和优化器状态上。试试把batch size降到1然后开梯度累积,步数不变但显存压力小很多,loss不稳可以调高学习率warmup比例。4bit量化用bitsandbytes配peft的prepare_model_for_kbit_training就行,记得把llama的tokenizer的padding设成left,不然训练时attention mask会乱。另外把优化器换成AdamW8bit能省不少显存,我以前用这个组合在3090上微调过13B都没爆。
24G跑7B LoRA还爆显存,大概率是序列长度或者attention缓存吃太狠了,试试把max length砍到512,大多数客服对话根本用不到长上下文。另外paged optimizers和unsloth的kernel能省不少显存,我上次用unsloth把batch size翻倍还没OOM,loss也稳很多。4bit QLoRA确实是个路子,但记得用NF4格式别用FP4,效果差距挺明显。你要是懒得折腾,直接上Hugging Face的TRL库配好DeepSpeed ZeRO-3,它会自动处理层卸载,基本无脑跑。
24G跑7B LoRA还OOM,大概率是序列长度或者attention计算吃太狠了,可以试试把max_seq_len砍到512,再配合gradient accumulation把有效batch size提上去,loss会稳很多。4bit量化用bitsandbytes其实挺稳的,加上peft的LoRA配置,基本能把显存压在10G以内,速度也不会太拉胯。另外可以看看unsloth这个库,专门优化了微调显存占用,有时候比手动调ZeRO省心多了。你要是试过这些还不行,可以检查下是不是dataloader里把不用的字段也塞进GPU了,那个坑我踩过。
你这配置跑7B LoRA确实有点极限,但24G不该这么惨。我怀疑你batch size=4爆显存不只是模型本身的问题,很可能你加载的时候没开4bit,或者LoRA的target modules选得太多了。试试bitsandbytes的4bit量化加载,配合peft的LoRA,能把基座模型压到6G左右,这样你batch size至少能回到8,甚至16。另外你提到loss不稳定,大概率是学习率太高,LoRA微调一般用1e-4到3e-4之间,别超过5e-4,你换成1e-4再配上warmup steps试试。还有个小技巧,用gradient accumulation模拟大batch,但注意accumulation step别设太大,不然等效batch太大反而影响收敛。Deepspeed ZeRO Offload在单卡上其实收益不大,反而拖慢速度,不如专注在量化+LoRA参数瘦身上。最后推荐你装一下unsloth,它对Llama微调做了显存和速度优化,我试过同样配置能省30%显存,速度还快一截。要是还不行,你就把序列长度从默认512砍到256,客服对话一般没那么长,这个改动对显存影响立竿见影。
24G跑7B LoRA其实挺宽裕的,你这OOM八成是seq length或者attention计算吃太狠。试试把max length砍到512,再加个gradient accumulation,batch size直接设1,步数不变但显存压力小很多。另外4bit的话用bitsandbytes配peft的prepare_model_for_kbit_training,比你自己手搓量化稳,loss不稳定多半是学习率太高,调到1e-4以下再看看。