最近在试着用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 size 4差不多,loss也能稳下来。4bit量化强烈推荐,用bitsandbytes加载模型时直接load_in_4bit=True,配合peft的LoRA,显存能压到10G以内,速度反而比半精度快。至于DeepSpeed ZeRO,单卡上收益不大,配置还容易出幺蛾子,不如直接上QLoRA,省心很多。另外把序列长度截到256,对情感分类这种任务完全够用,还能再省一截显存。
换个思路,你既然只是分类任务,干嘛非要用7B,试试Llama-3-8B的4bit加adaptor,或者干脆用2B的模型,效果差不了太多但训练快好几倍。如果非要7B,把optimizer换成AdamW 8bit(bitsandbytes里那个),显存能省2-3G,配合梯度累积,batch size 1也能跑得飞起。还有个trick,把输入文本padding到固定长度而不是max_length,能避免动态shape带来的显存碎片。另外,loss不稳定大概率是学习率太高,降到1e-4以下试试,比折腾显存配置更有效。
顺带说个冷门的,你把PyTorch的allocator
4090跑7B LoRA其实瓶颈不在显存总量,而是activation峰值,你可以试试把LoRA的target modules换成只微调q_proj和v_proj,参数少一半但任务简单的话效果差不了太多。另外batch size=1的时候把gradient accumulation调到8,loss不稳大概率是学习率太高,降到1e-4配个warmup会好很多。至于4bit,直接上bitsandbytes的nf4配置,加个peft的prepare_model_for_kbit_training,基本不会崩,速度损失也能接受。
你这情况太典型了,LoRA其实不太吃ZeRO,直接上QLoRA配4bit的NF4量化,加载时用bitsandbytes库,显存能压到10G以内,batch size放到8都没问题。另外把target_modules选成全部linear层,别只改qkv,收敛会稳很多。损失不稳定大概率是学习率太高,试试1e-4加个warmup,或者用paged_adamw优化器,能省不少事。还有个小技巧,把序列长度裁到128,情感分类用不着长上下文,训练速度直接翻倍。
试试QLoRA加4bit量化,显存直接砍半,batch size能拉到8,速度反而比之前快。
说实话你这个情况跟我上个月几乎一模一样,24G卡跑7B LoRA,batch size 4直接把我整破防了。后来我试了QLoRA,就是那个bitsandbytes的4bit量化,配合peft库,batch size能开到8甚至16,显存占用直接砍半还多,而且效果跟全精度比真的差不了多少,情感分类这种任务完全够用。不过有个坑,就是4bit下训练速度会慢一点,但总比OOM强。你要是想试试DeepSpeed ZeRO,建议直接上ZeRO-3加offload,但配置起来有点麻烦,CPU offload之后训练速度会肉眼可见地拖慢,除非你内存很大。另一个我觉得特别实用的trick是调大梯度累积步数,batch size=1然后把gradient_accumulation_steps设成8或者16,这样等效batch size能上去,loss曲线会稳很多,虽然单步还是慢,但整体收敛反而快。还有个小建议,把输入序列长度截断一下,客服对话一般没那么长,512或者768就够用了,别让padding浪费显存。最后你要是想省事,直接去huggingface看下trl库的SFTTrainer,它内置了打包和4bit支持,配置个几行代码就能跑,比我手动折腾稳定多了。对了你loss不稳定的话,检查下learning rate是不是太高了,LoRA一般1e-4到3e-4就行,高了真的会抖。
LoRA加4bit量化是正解,用bitsandbytes库配peft,batch size能开到8,速度还稳得很。
试试QLoRA配4bit,直接上16的batch,loss稳的一批,速度还比你现在快。
4090跑7B LoRA其实瓶颈不在显存总量,而在你同时加载了完整base model和梯度状态。试试把batch size固定成1,但用gradient accumulation把有效batch提到8或16,loss会稳很多,速度反而可能比硬塞大batch更快。4bit量化建议直接上bitsandbytes的NF4,配合peft的prepare_model_for_kbit_training,显存能压到10G左右,不过记得关掉gradient checkpointing,不然会拖慢速度。另外你情感分类这种简单任务,其实可以只冻住前几层,只训最后的几层,效果几乎不变但省一半显存。我之前用类似配置训过6B模型,峰值大概12G,你可以试试看。
4090跑7B LoRA用4bit量化加ZeRO Offload,batch开2稳得很,你试试bitsandbytes加peft的配置。
这题我太熟了,4090跑7B LoRA其实挺尴尬的,24G说大不大说小不小。你batch size 4爆掉正常,LoRA虽然省了主干显存,但激活值照样吃满,试试gradient accumulation加batch size 1,步数不变但显存压力小很多,loss不稳定可以调高learning rate warmup步数,或者用AdamW的betas参数。4bit量化建议直接上bitsandbytes的NF4,配合peft库的prepare_model_for_kbit_training,基本能省一半显存,但注意量化后收敛会慢一点,我一般把LoRA rank设到16,alpha设32,效果跟全精度差不了太多。DeepSpeed ZeRO Stage 2配offload optimizer到CPU也挺管用,但单卡上提升有限,ZeRO3反而可能更慢,不如直接换QLoRA方案,实测13B模型都能在24G上跑。还有个冷门技巧,你把输入序列截断到512,客服对话一般没那么长,显存直接降一个量级,实在不行就换Mistral 7B,结构更高效,微调资源需求比Llama低不少。最后,如果loss老跳,试着冻结embedding层,只训attention和FFN,稳定性会好很多。
4090跑7B LoRA其实不用硬刚batch size,试试8bit或4bit量化加LoRA,显存能省一半还多,我用bitsandbytes配peft跑过,batch size 8没问题。你loss不稳定大概率是学习率太高,降到1e-4到5e-5之间,再配合warmup steps会稳很多。DeepSpeed ZeRO 2在这场景下反而容易炸,不如直接开offload到CPU,虽然慢点但至少不OOM。另外建议把序列长度截到256,客服对话一般够用,能再省一笔显存。
你这情况我太熟了,24G卡上LoRA跑7B,batch size 4本来就悬,关键看你对序列长度有没有控制。试试把max length砍到512甚至256,显存能省出一大截,再配合gradient accumulation,效果比硬撑大batch稳定多了。至于ZeRO和4bit,其实不用太怕,直接上bitsandbytes的4bit量化做QLoRA,加载时设好bnb配置,再把ZeRO开到stage 2,基本不会崩,速度损失也就两成左右。还有个小trick,把optimizer换成AdamW 8bit或者Lion,能再抠出几G显存,亲测有效。
24G跑7B的LoRA其实挺宽裕的,问题大概率出在数据加载和梯度累积的配合上。你现在batch size=1,试试梯度累积设成8甚至16,等效batch size大了loss会稳很多,速度虽然没提升但收敛步数能少一大截。4bit量化强烈建议试下bitsandbytes的NF4,配合peft的LoRA,显存占用能压到8G以内,这样batch size直接拉回4,训练速度反而比现在更快。另外你提到loss不稳定,除了batch size,检查下学习率是不是太高了,LoRA一般用1e-4到3e-4,AdamW的weight decay也别忘了。DeepSpeed ZeRO其实没必要上,单卡场景收益不大,还容易跟PyTorch版本打架。还有个冷门技巧,把输入序列截断到512或者256,客服对话一般用不到太长上下文,这能省不少激活显存。要是还嫌慢,可以用unsloth这个库,专门优化了LoRA的前向传播,显存占用和速度都比原生实现好不少。
QLoRA直接上吧,4bit量化加NF4格式,7B模型能压到6G左右,4090跑batch size 4稳得很。你那个loss不稳大概率是学习率太高,LoRA建议设1e-4到3e-4,再配合warmup steps。另外可以试试PEFT库里的gradient accumulation,等效batch大一点但显存不变,速度比单卡硬扛快不少。还有个小技巧,把序列长度截到256,客服对话一般用不了那么长,省下的显存能换更长的训练步数。
你这个问题我太有同感了,之前用3090试的时候也是被OOM折磨得不行。我后来发现其实不用上DeepSpeed,直接把LoRA的target modules换成只调q和v,再加个8bit的bitsandbytes量化,batch size能稳在8,速度反而比之前瞎调快不少。另外你loss不稳定可能是学习率太高,试试把lr降到1e-4以下,再配合warmup steps拉长一点,会平滑很多。要是还嫌慢,可以看看unsloth这个库,它对Llama做了专门优化,显存占用能再降个30%左右。
试试4bit QLoRA加paged optimizer,batch size开2,稳得很,速度也没慢太多。
或者干脆用Unsloth,配置少一半显存,loss曲线比你现在好看多了。
试试点8bit优化器加ZeRO Offload,batch size能翻倍,loss不稳就调低学习率加warmup。
或者直接上QLoRA,4bit加双卡张量并行,24G跑7B绰绰有余,速度还比梯度检查点快。
4090跑7B LoRA其实挺够用的,你试试把LoRA的rank降到8或者4,再配合4bit量化(用bitsandbytes那个load_in_4bit就行),显存能压到10G左右,batch size拉到8都没问题。另外loss不稳大概率是学习率太高,建议调到1e-4以下,或者加个warmup步骤。DeepSpeed ZeRO其实没必要上,单卡场景收益不大,还容易出配置问题。要是还嫌慢,可以试试梯度累积,等效batch size调大一点,比硬撑batch size稳多了。
试过QLoRA没?4bit加双卡offload能压到10G以内,batch直接拉8,loss稳得很。
你这情况跟我上个月一模一样,24G跑7B LoRA就是卡在临界点上。我最后是上了QLoRA加4bit量化,用bitsandbytes配peft,直接把batch size拉到8,速度比之前1还快。另外注意把gradient accumulation设成2,loss不稳基本能解决,但记得把学习率调低点,3e-4左右比较稳。还有个偏方是冻结embedding层,能省不少显存,效果影响其实很小。你试试把attention的dropout关了,也能挤出一点空间。