最近在试着用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 条说实话7B模型用LoRA在两张3090上跑,batch size设4确实有点猛了,尤其是序列长度如果超过1024的话,单卡24G其实挺吃紧的。你提到的bitsandbytes量化成4bit,这个操作本身会省不少显存,但要注意加载的时候得把模型显存分配方式和设备映射调对,比如用device_map="auto"配合load_in_4bit=True,不然还是容易炸。gradient checkpointing肯定要开的,Hugging Face的Trainer里直接设gradient_checkpointing=True就行,但记得要同时调用model.gradient_checkpointing_enable(),不然有时候不生效。另外你试试把优化器状态用bitsandbytes.optim.Adam8bit或者干脆用SGD,能省不少显存。dataloader那边建议先设batch size为1跑通流程,然后再慢慢往上加,同时注意padding策略别搞成max_length那种暴力填充,用longest会更省。多卡的话,用accelerate库的device_map="auto"会自动分配层到两张卡上,但显存碎片问题还是得靠torch.cuda.empty_cache()手动清一清。最后检查下是不是后台有其他进程占着显存,有时候pytorch的缓存没清干净也会导致误报OOM。
batch size 4对7B模型确实偏大,先降到1,再开gradient checkpointing试试。
batch size 4确实大了,7B模型单卡24G开4bit也不够,试试设成1加gradient accumulation。
7B用两张3090按理够,试试gradient checkpointing加batch size降到1,4bit量化可能没生效。
batch size 4对7B模型确实偏大了,试试gradient checkpointing加batch size 1,大概率能跑起来。
7B模型用LoRA加batch size 4确实有点大,试着调成1或2,再把gradient checkpointing打开,显存能省不少。
7B用4bit量化两张3090跑batch size 4应该没问题,检查下是不是token长度没限制或者gradient checkpointing没开。
两张3090跑7B LoRA肯定够,batch size 4不算大,先检查下是不是没开gradient checkpointing。
一张3090跑7B全参肯定炸,但两张24G用LoRA按理说够用。你batch size设4的话单卡确实有点紧,建议先降到1试试,同时确认一下是不是加载了没量化的基座模型。
gradient checkpointing可以直接在Trainer里设gradient_checkpointing_enabled=True,能省不少显存;另外bitsandbytes的4bit要配合load_in_4bit=True和bnb_4bit_compute_dtype=torch.float16一起用,否则默认可能还是半精加载。
还有个小坑:有些repo的tokenizer会自动补长到模型最大长度,如果没设置padding策略也会吃显存,检查一下dataloader里有没有collate_fn限制一下。
两张3090跑7B LoRA按理说是够的,batch size=4确实偏大了,LoRA微调时可以先试试batch size=1或者2,配合gradient accumulation把总batch堆上去。bitsandbytes 4bit量化后还炸的话,可能是你加载模型时没把device_map设成auto,或者transformers版本太旧导致量化没生效。gradient checkpointing直接在Trainer里设gradient_checkpointing_enabled=True就行,能省不少显存,另外关掉model的use_cache也能腾出空间。
两张3090跑7B LoRA按理说是够的,batch size设4确实偏大了,先调到1或者2试试,同时把gradient checkpointing打开——在Trainer里设gradient_checkpointing=True就行,能省不少显存。bitsandbytes 4bit量化如果还炸,可能是没正确启用bnb_4bit_compute_dtype或者load_in_4bit=True,建议检查一下加载代码。另外Hugging Face Trainer默认会缓存中间激活,你可以手动关掉remove_unused_columns=False,或者用deepspeed stage 2把优化器状态分到多卡,这样双卡压力小很多。别怀疑人生,这问题我当初也折腾了一周,调参顺序对了就能跑。
7B加LoRA两张3090按理说够用,试试gradient checkpointing和更小的batch size,4确实偏大了。
我之前也遇到过类似问题,后来换了方案。
7B模型用两张3090跑LoRA按理说够了,但batch size=4确实有点激进,建议先改成1试试。gradient checkpointing在transformers里直接设model.gradient_checkpointing_enable()就行,能省不少显存。另外检查下是不是加载了完整模型没量化成功,bitsandbytes的4bit配置有时候会因为依赖版本不对而失效。
7B模型用两张3090按理说是够的,问题很可能出在dataloader的batch size和模型加载方式上。batch size设4对7B来说确实偏大,可以先降到1试试,同时用gradient accumulation来模拟更大batch。量化4bit如果还炸,检查一下是不是没有把模型整体放到device_map='auto',或者没开启gradient checkpointing——在Trainer里直接设gradient_checkpointing=True就行,能省不少显存。另外,Hugging Face的Trainer默认会加载全精度,记得在BitsAndBytesConfig里明确指定4bit参数。
老实说,7B模型在两张3090上跑LoRA按理说不会这么惨,我猜你可能是直接在加载完整模型的时候被显存吃了,因为LLaMA的权重本身就有13G左右,加上优化器状态和梯度,单卡放不下就会爆。batch size设4其实不算离谱,但关键是你要先确认模型有没有被正确量化——bitsandbytes的4bit虽然能压到6-7G,但有些版本在加载时如果不指定load_in_4bit=True和bnb_4bit_compute_dtype,它还是会默认用float16跑,那就等于没省。另外gradient checkpointing真的是救命神器,你在Trainer里设gradient_checkpointing_enabled=True,能省差不多30%的显存,代价只是慢一点点。还有个容易被忽略的点是,Hugging Face的Trainer默认会缓存所有中间激活值,你手动把per_device_train_batch_size降到1,配合gradient accumulation多步累加,两张卡跑4的等效batch完全没问题。多卡的话记得用device_map="auto"让accelerate自动分配,别手动塞,否则可能一张卡撑死另一张闲着。最后检查下dataloader的num_workers,设太高也会吃显存,建议先调到2试试。
7B模型用两张3090理论上完全够,问题可能出在加载方式上——试试load_in_4bit=True配合bnb_4bit_compute_dtype=torch.float16,同时把device_map="auto"加上让模型自动分到多卡。batch size设4不算大,但dataloader里如果num_workers设太高也会导致显存预分配,可以调成0或2看看。gradient checkpointing直接用model.gradient_checkpointing_enable()就行,能省不少显存,但记得在TrainingArguments里把gradient_checkpointing=True也打开。另外Hugging Face Trainer默认会加载优化器状态,可以试试optim="adamw_8bit"或者paged_adamw_8bit,能省掉优化器占的那块显存。
batch size 4确实大了,3090跑7B模型用1试试,再开gradient checkpointing和4bit量化应该能稳住。
7B模型用两张3090跑LoRA按理说是够的,但24G显存其实挺容易爆,尤其是加载原模型权重的时候就占了快14G,再加上梯度、优化器状态和中间激活值,batch size=4确实有点激进。我建议你先试试把batch size降到1,然后用gradient accumulation模拟更大的batch,这个在Trainer里直接设per_device_train_batch_size=1和gradient_accumulation_steps=4就行。关于bitsandbytes的4bit量化,你得确认加载模型时用了load_in_4bit=True并且设置了bnb_4bit_compute_dtype=torch.float16,不然默认用float32还是会炸。gradient checkpointing在Trainer里加一句--gradient_checkpointing_enable就能开,能省不少显存,代价是训练会慢一些。另外,Hugging Face的Trainer默认会缓存一些中间变量,你可以试着手动设置remove_unused_columns=False和datacollator的padding策略,有时候这些默认参数会多占用显存。多卡的话建议用device_map="auto"配合accelerate来切分模型,两张3090跑7B其实挺轻松的。别怀疑人生,这种问题我当初也折腾了好久,一步步排查就行。
24G单卡跑7B全参微调确实勉强,但LoRA+4bit按理说能撑住。建议先检查下bitsandbytes的load_in_4bit=True和bnb_4bit_compute_dtype=torch.float16有没有设全,以及模型加载时加个device_map="auto"让它自动分配到两张卡上。batch size设4对7B来说其实不算大,但dataloader里如果开了pin_memory=True也可能额外占显存,可以关掉试试。gradient checkpointing在Trainer里直接设--gradient_checkpointing 1就行,另外把fp16=True打开也能省不少。