最近在试着用LoRA微调7B的LLaMA模型,机器是两张3090(24G),按说应该能跑吧?但一加载模型就报CUDA out of memory。
我参考了几个GitHub仓库,有的说用bitsandbytes量化成4bit就行,但我试了还是炸。是不是我dataloader的batch size设太大了(设了4)?还是说需要把模型分到多卡?
另外,我看很多人直接用Hugging Face的Trainer,是不是里面有些默认参数会爆显存?有没有什么通用的显存优化trick,比如gradient checkpointing到底该咋开?
求各位大佬指点,真的有点怀疑人生了……
用PyTorch微调LLaMA,总是OOM,是我显存不够还是代码有问题?
全部回复
共 170 条两张3090跑7B LoRA理论上完全够,问题大概率出在加载基座模型时没走量化或者没开device_map,试试load_in_4bit=True加上device_map="auto",batch size降到1先跑通再说。gradient checkpointing直接在TrainingArguments里设gradient_checkpointing=True就行,但记得同时把model.gradient_checkpointing_enable()调了,不然不生效。另外你参考的仓库如果版本旧,transformers和peft的API变化挺大的,建议直接看官方文档的例子,别死磕GitHub上的老代码。
7B模型光fp16权重就14G了,两张3090单卡24G看着够,但激活值、梯度、优化器状态全堆一起肯定炸。batch size 4确实偏大,先调到1试试,然后gradient checkpointing在Trainer里直接传gradient_checkpointing=True就行,效果立竿见影。4bit量化还炸的话,八成是bitsandbytes版本和CUDA不匹配,或者你加载时没设device_map="auto"。另外optimizer用AdamW的话8G显存就没了,换paged_adamw_8bit能省不少。
梯度累积开一下,batch size先降到1试试,4bit加载后记得把torch_dtype设成float16,大概率能稳。
先开gradient checkpointing,再把batch size降到1试试,两张3090跑7B LoRA绝对够用。
两卡3090跑7B LoRA理论上够的,问题大概率出在加载基座模型时没开device_map='auto',模型默认全塞进单卡显存里了。batch size=4确实偏大,尤其序列长度长的时候,建议先降到1试试,同时把gradient_checkpointing打开,能省不少显存。bitsandbytes那块注意版本匹配,老版本和transformers新接口容易冲突,报错不一定是显存真不够。我一般习惯用peft库自带的prepare_model_for_kbit_training,它会自动处理一些显存优化,比手动折腾省心。
7B模型用LoRA按理说3090单卡就能跑,你八成是卡在加载基座模型时没开低精度,直接用fp32硬扛了。先把load_in_4bit=True加上,然后torch_dtype=torch.float16,这两个缺一不可。batch size 4在24G上确实有点激进,先调到1试试,dataloader里num_workers也别开太高,有时候CPU内存爆了也会连带显存报错。gradient checkpointing就在TrainingArguments里设gradient_checkpointing=True,但注意要同时设per_device_train_batch_size小一点,不然反而更慢。Trainer里还有个关键参数是optim="adamw_torch_fused",能省不少显存,或者直接用adafactor,不过效果略降。
7B用LoRA两张3090理论上完全够,问题大概率出在加载基座模型时没开低精度,先试试torch_dtype=torch.float16,这步能省一半显存。batch size=4不算大,但配合LoRA最好把gradient_checkpointing打开,直接model.gradient_checkpointing_enable()就行。另外bitsandbytes别只量化模型,要确保加载的时候也把device_map设成auto,不然还是会往一张卡上塞。还有个小坑,Trainer默认会计算eval损失,如果你没设evaluation_strategy,它可能偷偷把验证集也加载进显存,设成“no”能省不少。我上次就是卡在这,折腾了两天最后发现是模型并行没写对,试试把model.parallelize()换成accelerate库的dispatch,应该能稳。
之前跑7B也遇到过差不多的情况,两张3090其实够用,但关键得先把模型塞进显存再谈训练。你batch size=4有点乐观了,LoRA虽然省显存,但加载基座模型本身就要吃掉近14G,加上梯度和优化器状态,24G单卡肯定顶不住。建议先用4bit量化加载,然后batch size降到1或2,开gradient checkpointing,再把梯度累积步数调大点,比如8到16,这样效果差不多但显存压力小很多。另外Hugging Face Trainer里有个gradient_checkpointing=True和optim="adafactor",这两个组合能省不少,你可以试试。如果还炸,就把模型放到device_map="auto",让accelerate自动分到两张卡上,但记得用torch.distributed初始化,不然多卡反而更慢。
两卡24G跑7B LoRA按理够的,先试试gradient checkpointing加batch size调到1,不行再看是不是transformers版本坑。
-
24G双卡跑7B其实够用,但batch size=4确实大了,先调到1试试,顺便把gradient checkpointing开起来。
-
我也遇到过这破事,八成是Trainer默认的batch size和gradient accumulation叠加导致显存爆炸,手动设小点就行。
说实话,7B模型在两张3090上用LoRA理论上是够的,但你batch size=4确实有点激进,尤其是序列长度一上来,激活值直接爆炸。我建议先把batch size降到1,然后用gradient accumulation把有效batch size补回来,这样显存压力会小很多。
另外你说的bitsandbytes 4bit,我猜你可能是加载的时候没把模型转成torch.float16,或者没设置device_map="auto",导致量化后的层还是占着全精度显存。可以试试先model.half()再包LoRA,很多人栽在这。
Trainer那边确实有坑,比如默认的eval_steps和logging_steps可能会触发额外的显存分配,但最关键的还是gradient_checkpointing_enable()要放在prepare_model_for_kbit_training之后,这两者顺序搞反了等于白开。我自己跑的时候还习惯把optim设成paged_adamw_8bit,能省不少优化器状态。
还有个小技巧,如果还是OOM,看看是不是torch.cuda.empty_cache()没在训练循环里定期调用,有时候碎片化内存也会导致明明看起来够却报错。实在不行就分到两卡上,用accelerate的device_map把不同层放在不同GPU,但LoRA本身不重,通常不是瓶颈。
最后想问下你用的peft版本,之前有些老版本和transformers的兼容性问题会导致显存泄漏,升级到最新的peft和transformers说不定就解决了。别怀疑人生,这问题八成是配置细节,不是硬件不够。
7B模型光加载fp16权重就要14G显存,3090单卡24G按理说够,但你batch size=4还开LoRA,梯度+优化器状态一叠加肯定爆。先试试gradient checkpointing,那个能省不少,Trainer里直接设gradient_checkpointing=True就行。另外dataloader的batch size降到1或2,用梯度累积模拟大batch,别硬扛。双卡的话记得用device_map="auto"加accelerate,不然模型不会自动分到两张卡上。bitsandbytes那个坑挺多的,版本不匹配容易出幺蛾子,建议先不用它,把能省的显存都省了再试。
batch size先调到1试试,gradient checkpointing加上,4bit还炸多半是显存碎片化。
3090两张跑7B用LoRA按理够,4bit还炸就是batch size和seq len的问题,先砍到1加梯度累积试试。
7B上3090单卡都够,多半是trainer默认gradient checkpointing没开,batch size砍到1试试。
说实话两张3090跑7B LoRA完全够用,问题大概率出在加载基座模型时没开4bit,或者dataloader的num_workers和pin_memory把显存挤爆了。你可以试试先只加载模型不跑训练,看峰值显存多少,排除是不是加载阶段就炸了。另外Trainer里gradient_checkpointing=True和per_device_train_batch_size=1是最基本的,LoRA的target_modules别忘了设,不然照样满参反传。我之前用同样配置跑13B都稳,batch size 4确实偏大,先降到1试试,不行再上gradient accumulation。
4bit+gradient checkpointing基本能跑,batch size先砍到1试试,另外记得关掉Trainer里的gradient accumulation默认值。
7B全参微调两张3090本来就很极限,LoRA虽然省了梯度但激活值照样吃显存,batch size=4确实偏大。gradient checkpointing在Trainer里直接传gradient_checkpointing=True就行,但记得同时把optimizer改成AdamW的8bit版本,能省好几G。还有个容易踩的坑是max_length别设太长,512和1024的显存差距巨大。我上次用单卡24G跑7B,batch size=1+gradient checkpointing+4bit量化,峰值能压到14G左右,你可以参考这个配置调调。
24G双卡跑7B LoRA按理说是够的,问题多半出在加载基座模型时没开4bit,或者dataloader的num_workers把CPU内存吃满了。你先试试load_in_4bit=True+bnb_4bit_compute_dtype=float16,然后gradient_checkpointing_enable(),batch size先降到1,能跑通再往上加。Trainer默认会开gradient accumulation,可能等效batch size比你以为的大很多,检查下args里的per_device_train_batch_size和gradient_accumulation_steps。另外记得把model并行或者device_map="auto"加上,两张卡能分着放就分着放,别让单卡扛全部。
7B模型光fp16权重就要14G,两张3090单卡24G看着够,但LoRA训练时优化器状态和激活值才是大头,batch size=4在7B上确实太激进了,先降到1试试。另外gradient checkpointing一定要开,Trainer里设gradient_checkpointing=True就行,显存能省一半。bitsandbytes 4bit加载没问题,但训练时如果你还用了prepare_model_for_kbit_training,记得把gradient_checkpointing也开着,不然照样炸。还有个小技巧,把torch.cuda.empty_cache()加在每个epoch结束,偶尔能救急。你试试batch size=1加gradient checkpointing,应该能稳跑。