最近在试着用LoRA微调一个7B的Llama模型,任务挺简单的,就是给客服对话做情感分类。我用的是一张4090(24G显存),batch size设到4就直接OOM了,换成1倒是能跑,但训练慢得离谱,而且loss下降特别不稳定。已经试过gradient checkpointing和混合精度训练,感觉效果有限。看网上有人说可以用DeepSpeed ZeRO或者量化到4bit,但不知道怎么配置才不崩。想问问有经验的老哥,显存不够的情况下,怎么平衡速度和效果?另外,有没有推荐的库或者trick,能让我这张卡撑住微调?先谢过了!
自己用PyTorch微调Llama,显存总爆掉,有什么省钱又实用的技巧吗?
全部回复
共 167 条4bit量化加QLoRA基本是你这张卡的最优解,bitsandbytes配好load_in_4bit和nf4,7B模型显存能压到10G以内,batch size开到8都不虚。loss不稳多半是学习率太高,LoRA一般1e-4到2e-4就够了,再配合warmup会稳很多。DeepSpeed ZeRO在单卡上收益不大,别折腾了,省下的精力不如多调调数据质量。
4090跑7B的LoRA按理说不至于batch size 4就炸,我怀疑你是不是把LoRA的target modules设得太全了,q k v o全加上去显存占用会涨不少。情感分类这种任务其实只挂q和v两个投影层就够了,效果差不了多少但显存能省一截。还有你说的loss不稳定,batch size等于1的时候梯度噪声本来就大,可以试试梯度累积,比如accumulate 8步等效batch 8,显存几乎不涨。QLoRA确实值得上,bitsandbytes的4bit量化配bnb_4bit_compute_dtype用bf16,7B模型加载完大概只占5G左右,剩下的全留给激活值和优化器状态。DeepSpeed ZeRO我劝你先别折腾,单卡场景下ZeRO-2和3对LoRA的收益有限,配置错了反而各种崩,不如把peft和transformers版本对齐来得实在。另外检查一下是不是没开flash attention,4090支持得挺好,长序列下能省不少显存和计算。分类任务序列一般不长,把max_length卡到256以内,速度能明显提上来。
试试QLoRA加bitsandbytes的4bit量化,配合gradient accumulation把有效batch拉上去,速度能接受。
4090跑7B还OOM,大概率是LoRA的target modules设少了,只挂q和v的话可训练参数不多但激活值照样占显存。试试把batch size压到1,再开梯度累积凑等效batch,loss不稳多半是累积步数没跟着调。4bit量化直接用bitsandbytes的load_in_4bit配QLoRA,配置不难,peft文档里就有现成例子,比DeepSpeed省心多了。
我之前也遇到过类似问题,后来换了方案。
学到了,感谢分享!
4090跑7B LoRA其实不算太紧张,但你batch size 4就OOM,八成是LoRA的target modules设得太宽了,比如q_proj k_proj v_proj o_proj全挂上,再加上mlp层,显存蹭蹭涨。客服情感分类这种任务,只挂q和v两个投影层试试,效果通常够用,显存能省不少。gradient checkpointing确实能降显存但会拖慢速度,配合小batch的话不如试试gradient accumulation,batch设1但累积8步,等效batch size上去了,loss稳定性也会好很多。4bit量化推荐直接上bitsandbytes的QLoRA,peft库里现成的配置,load_in_4bit加bnb_4bit_compute_dtype设成bfloat16,基本照着官方example改就行,别自己瞎配DeepSpeed ZeRO,单卡用不上还容易崩。另外检查一下是不是把optimizer设成adamw了,换成adafactor或者8bit的adamw,优化器状态能省一大块显存。max_length也别设太长,客服对话截到256或512就够,padding策略用max_length而不是longest,避免变长序列浪费。这套下来24G应该能跑batch 4到8,速度也还能接受。