最近在试着用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 条gradient checkpointing开了吗?batch size改1再试试,两张卡用device_map=auto应该能塞下。
试试把batch size降到1,开gradient checkpointing,4bit量化下大概率能跑起来。
24G两张3090跑7B LoRA按理说是够的,问题大概率出在加载基座模型时没开4bit,或者dataloader的num_workers和batch size叠加导致峰值显存爆了。我建议你先用单卡、batch size=1、gradient checkpointing打开再试,4bit用bitsandbytes的load_in_4bit=True,同时把prepare_model_for_kbit_training加上。Trainer里注意关掉fp16如果用的是3090(Ampere支持但有时会额外吃显存),另外gradient_accumulation_steps可以补batch size。分到两卡反而可能因为LoRA的适配器同步问题更吃显存,先单卡调通再说。
3090单卡24G跑7B加LoRA其实够用,但你这batch size=4直接怼上去肯定炸,先把gradient checkpointing开起来,能省不少显存。另外bitsandbytes那个4bit量化,加载模型时要确保模型参数和optimizer状态都放在CPU上,不然还是会爆。我之前用Trainer时发现它默认会计算梯度,如果你不用验证集评估,记得把evaluation_strategy设成no,还能省点显存。你试试把batch size降到1,加上gradient accumulation凑成4,应该就能跑了。
7B模型光加载fp16权重就要14G,两张3090单卡跑其实没问题,但batch size=4加上LoRA的激活值,24G确实有点悬。你先试试gradient checkpointing,Trainer里设gradient_checkpointing=True就行,另外per_device_train_batch_size改成1,梯度累积设8,显存瞬间就下来了。bitsandbytes那个4bit其实挺吃显存碎片,不如直接8bit加LoRA稳定。还有,检查下是不是Hugging Face默认把torch_dtype设成fp32了,手动指定torch_dtype=torch.float16能省一半。
7B模型用LoRA按理说24G是够的,但你是不是忘了把模型也转成半精度?FP16和BF16能省一半显存,再配合gradient checkpointing基本能压下来。另外batch size=4在两张卡上其实还好,但建议先用batch size=1跑通再慢慢加,有时候是dataloader的num_workers开太多把显存碎片化了。bitsandbytes如果还是炸,检查下是不是没给模型设置device_map="auto",让它自动分配多卡。Trainer里有个gradient_accumulation_steps参数,实际batch size不变的情况下能显著降低峰值显存,可以试试。
先开gradient checkpointing,batch size降到1,3090跑7B+LoRA 4bit稳的。
gradient checkpointing必开,再用8bit优化器,batch size1起步慢慢加。
两张3090跑7B按理说够的,你先试试batch size降到1,再把gradient checkpointing开了,大概率能稳。
7B模型光权重就要14G,两张3090单卡24G肯定够,但你这batch size=4配合LoRA的adapters权重,前向和反传峰值很容易飙到20G+,炸很正常。先把batch size降到1试试,然后gradient checkpointing直接在Trainer里设gradient_checkpointing=True就行,显存能砍一半。另外bitsandbytes的4bit要确保加载时load_in_4bit=True和device_map="auto"同时用,只量化不切分照样爆。建议先单卡跑通小batch再上多卡,多卡还要处理accelerate的显存分配策略,不然两张卡负载不均可能还是OOM。
7B模型加载本身就占不少显存,两张3090单卡跑LoRA其实是够的,但batch size=4在24G上确实有点激进,尤其你没开gradient checkpointing的话。建议先降到1试试,然后把gradient_checkpointing=True加上,这个能省不少显存。bitsandbytes的4bit量化要注意得配最新的transformers版本,老版本容易有兼容问题,而且量化后加载模型那段代码得按官方示例来写。另外Trainer里有个predict_with_generate选项很吃显存,还有eval_strategy="steps"的话评估时也会额外占显存,建议先关掉评估只跑训练看看还炸不炸。
加载7B模型本身就要占14G左右,3090单卡24G理论上够,但你batch size=4加上LoRA的adaptor权重,前向激活值很容易爆掉。建议先把batch size降到1,开gradient checkpointing(Trainer里设gradient_checkpointing=True就行),再配合8bit或4bit量化,应该能稳。另外记得把torch.cuda.empty_cache()加在验证循环前,有时候显存碎片也会导致OOM。我自己的经验是,两张3090最好用device_map="auto"让accelerate自动分卡,别手动塞到单卡。
7B模型光权重加载就要14G+,两张3090单卡24G确实够,但你这batch size=4再算上激活值,单卡肯定爆。先把batch size降到1试试,gradient checkpointing在Trainer里直接设gradient_checkpointing=True就行,但记得同时把model.gradient_checkpointing_enable()调上。4bit量化如果还炸,大概率是bitsandbytes版本和CUDA版本不匹配,换个0.39版本试试。另外dataloader的num_workers别开太高,有时候CPU内存也会拖后腿。
加载7B用两张3090其实挺充裕的,问题大概率出在加载阶段没走量化或offload,先试试把model用device_map="auto"配合bitsandbytes的4bit,同时把batch size降到1看看能不能跑通。gradient checkpointing确实该开,在TrainingArguments里设gradient_checkpointing=True就行,但记得同时把model.gradient_checkpointing_enable()也调一下,不然有时不生效。另外Hugging Face Trainer默认会算eval loss,如果没设eval_strategy="no"可能白占显存,还有dataloader的num_workers别太高,不然CPU内存也容易爆。我之前在单张4090上跑7B,batch size 1加gradient accumulation也能凑合,你两张卡其实可以试试用FSDP或deepspeed zero2,但先别急着上,把基础设置理顺再说。
7B模型用LoRA按理说两张3090是够的,但你这batch size=4确实有点猛,尤其序列长度一上来,激活值直接吃满。先把batch size降到1,开gradient checkpointing(model.gradient_checkpointing_enable()),再把梯度累积步数调上去,基本能解决。还有,别信那些直接4bit的教程,bitsandbytes的NF4要配合双卡offload才行,单卡硬上照样炸。另外Trainer默认的eval accumulation和mixed precision设置确实容易踩坑,建议显式关掉评估或者把评估batch也调小。
讲真双3090跑7B LoRA完全够,问题大概率出在加载模型时没走device_map="auto",或者4bit量化配置里漏了nf4和compute_dtype。batch size 4对7B来说有点激进,先降到1加梯度累积,再把gradient checkpointing打开,Trainer里设gradient_checkpointing=True就行。另外看看是不是Hugging Face默认把eval也塞进显存了,用predict_with_generate=False能省不少。我上次就是这么救回来的,你先试这仨,不行再聊。
4bit加载不是终点,LoRA也要开gradient checkpointing,batch size先降到1试试。
3090两张跑7B没问题,关键是Trainer里fp16和gradient_accumulation_steps要配好。
说实话7B全量加载光权重就要14G左右,两张3090单卡24G理论上是够的,但你把batch size设4再加上LoRA的adapter和梯度,峰值轻松破20G,炸很正常。我建议你先用单卡跑,batch size降到1,然后开gradient checkpointing,这个在Trainer里直接设gradient_checkpointing=True就行,代价是慢一点但显存能省不少。bitsandbytes那个4bit如果你用的是最新的transformers和peft库,加载时记得把device_map设成auto,不然模型还是会在第一张卡上爆。另外dataloader的num_workers别开太多,有时候CPU内存交换也会干扰CUDA。还有个容易忽略的点,你检查下是不是把evaluation也同时跑了,如果验证集也进显存,那肯定不够。我自己的经验是7B模型用两张3090,batch size最多也就2,配合gradient checkpointing和8bit优化器才稳。你要是还炸,建议先跑个纯推理看显存占用,再一步步加训练组件,这样能定位到底是哪一步爆的。别怀疑人生,这坑我踩了俩礼拜才摸清楚。
说实话这配置跑7B LoRA真不是显存不够的问题,我单张4090都能塞下4bit量化后的模型,你两张3090还炸大概率是代码细节没到位。先说最简单的,dataloader的batch size设4确实偏激进,但更关键的是你加载模型时有没有把model.to('cuda')放在量化之后,顺序反了会导致中间变量直接撑爆显存。Hugging Face Trainer里有个很坑的默认项是predict_with_generate,它会额外缓存推理图,建议显式设成False。gradient checkpointing直接model.gradient_checkpointing_enable()就行,但记得同时把batch size调大一点,不然反而影响吞吐。另外你试试加载时加device_map='auto',配合accelerate库能自动分层到两张卡,比手动分配省心多了。最后检查下bitsandbytes是不是用的4bit的nf4类型,有时候默认的fp4会莫名多占显存。我经验是7B模型全参数微调24G都能跑,LoRA不该炸,你一步步排查下加载顺序和Trainer参数,基本能解决。
7B模型用LoRA按理说两张3090完全够,问题大概率出在加载基座模型时没开低精度,fp16或bf16必须显式设置,不然默认float32直接爆。batch size 4不算大,但建议先试1,同时把gradient checkpointing打开,能省不少显存。bitsandbytes如果还炸,检查下是不是transformer版本太新跟它不兼容,换个旧版本或者直接用load_in_8bit试试。Trainer里记得关掉eval时的梯度和缓存,不然推理阶段也会占显存。
24G双卡跑7B LoRA按理说真够,但你batch size=4确实偏大,我单卡3090开4bit都只敢设1。gradient checkpointing在Trainer里直接传gradient_checkpointing=True就行,能省不少显存,但会慢点。另外检查下是不是加载模型时没把模型放到device_map="auto",这玩意儿能自动分配多卡,不然全挤在一张卡上必炸。bitsandbytes如果还爆,试试加载时加个load_in_8bit,有时候4bit反而因为反量化操作更吃显存。