最近在试着用LoRA微调一个7B的底座模型(做代码生成),单卡A100 40G,用的transformers+peft。batch size设成1,gradient accumulation调到8,序列长度512,按理说显存应该够,但跑不到两步就OOM。我看日志里显存占用一直在涨,怀疑是不是保存中间激活或者优化器状态的问题?另外我用了fp16=True但没开gradient checkpointing,会不会是这里的原因?求有经验的大佬指点一下,或者有没有推荐的稳定配置组合?先谢过了。
LoRA微调7B模型显存总爆,是batch size问题还是我配置错了?
全部回复
共 72 条显存一直涨大概率不是batch size的事,bs=1还能OOM基本就是激活值和优化器状态没管住。fp16配上没开gradient checkpointing,7B模型512长度下激活能吃掉不少,建议先把gradient checkpointing打开试试。另外LoRA虽然冻结了底模,但embedding和lm head的梯度还是会算,可以把这两部分也设成requires_grad=False,能省一截。还不行就看看是不是数据里有些超长样本没截断,被pad到特别大。
没开gradient checkpointing基本必炸,7B激活值很吃显存,先开上再试试。
没开gradient checkpointing基本就是元凶,7B模型fp16下光激活值就能吃不少,序列512虽然不长但代码任务token密度高。另外peft默认可能把优化器状态也算了进去,你试试gradient_checkpointing_enable()加上,bs=1、ga=8应该能稳。还爆的话把optim改成adafactor或者8bit adam,显存能再降一截。
没开gradient checkpointing基本就是元凶,7B激活值512长度很吃显存。先把它打开,再把batch size压到1试试。
没开gradient checkpointing基本就是主因,7B模型512长度就算bs=1,中间激活也能吃掉二三十G。另外fp16配transformers有时候会有隐式上转,建议换成bf16,A100原生支持还更省心。优化器状态的话LoRA本身只存adapter参数,那部分开销不大,但Adam的exp_avg还是按全参走的,记得确认下是不是只传了LoRA参数进去。显存一直涨通常就是激活没释放,先把checkpointing打开再跑一遍看看。
没开gradient checkpointing基本就是主因,512长度下7B激活值很吃显存,先开了再试。
没开gradient checkpointing基本必爆,先把这个打开,序列512激活值可不小。
你这个问题大概率不在batch size上,bs=1+ga=8在A100 40G上跑7B LoRA,只要序列没超太多,显存其实是够的。日志里显存一直涨、跑两步就OOM,更像是激活没被释放,gradient checkpointing没开就是关键嫌疑,512长度下7B的中间激活能吃掉一二十G。fp16本身不省激活,只是把权重和部分计算降了精度,优化器状态在LoRA里占比很小,因为你只训练低秩矩阵。建议先把gradient checkpointing打开,再把use_cache关掉,这两步通常能救回来。另外确认下peft版本和target_modules,如果误把q_proj、k_proj、v_proj、o_proj全加上,可训练参数会翻好几倍,显存也会跟着涨。还有个坑是transformers的fp16配某些peft版本会有隐式fp32上转,试试bf16,A100原生支持,数值还更稳。如果还OOM,可以把序列先降到256验证一下,能跑通就说明是激活问题,不是配置写错了。
显存一直涨大概率是没开gradient checkpointing,7B模型512长度就算bs=1,中间激活也能吃掉不少。fp16配checkpointing基本是标配,再顺手把optimizer换成paged_adamw_8bit能省一截。另外确认下peft的target_modules别把qkv全挂上,挂太多可训练参数显存也顶不住。
没开gradient checkpointing是主因,7B激活占大头,先开上再降到256长度试试。
没开梯度检查点肯定炸,7B激活值不小,先把它打开再试。
不开gradient checkpointing肯定炸,512长度激活值不小,先把它打开再试。