为何增大gradient_accumulation_steps会引发GPU显存不足问题?
梯度累加导致显存不足的原因及解决办法
核心原因
梯度累加是模拟大批次训练,但它不会降低单步显存占用,反而会因保留中间数据和累加梯度导致显存上升:
- 中间张量与计算图未及时释放:PyTorch默认会保留前向传播的所有中间张量用于反向传播。当
gradient_accumulation_steps=2时,每完成一次小批次(batch size=8)的反向传播后,不会立即清空计算图和中间张量——要等2次累加完成才更新参数,相当于显存里同时存了2份小批次的中间数据,总占用自然比单批次更高。 - 梯度张量的额外存储:每次小批次反向传播后,梯度会被累加并存储在显存中,直到累加步数完成才更新参数,这会额外占用显存存放累加的梯度值。
- 隐性配置冲突:如果调整累加步数时不小心改动了其他参数(比如关闭了自动混合精度,或启用了其他显存密集型功能),也可能触发显存不足。
解决办法
- 匹配小批次大小与累加步数:把
per_device_train_batch_size降到4,搭配gradient_accumulation_steps=2,总有效batch size还是8,显存占用会和原来单批次8的情况接近。 - 开启梯度检查点:在模型初始化时添加
model.gradient_checkpointing_enable(),它会通过重新计算部分中间张量来减少显存占用,是梯度累加场景的常用优化手段。 - 冻结无关参数:如果用了PEFT(比如LoRA),确保只训练LoRA参数、冻结主模型权重,能大幅降低显存开销。
- 启用半精度训练:在Trainer参数里设置
fp16=True或bf16=True,半精度计算能显著减少张量的显存占用。
你的训练脚本
""" Goal: making HF training script for model (e.g., llama v2) using raw text of informal and formal mathematics (unpaired data). Inspiration: - ref: SO accelerate + trainer: https://stackoverflow.com/questions/76675018/how-does-one-use-accelerate-with-the-hugging-face-hf-trainer - ref: The unreasonable effectiveness of few-shot learning for machine translation https://arxiv.org/abs/2302.01398 - ref: colab: https://colab.research.google.com/drive/1io951Ex17-6OUaogCo7OiR-eXga_oUOH?usp=sharing - ref: SO on collate: https://stackoverflow.com/questions/76879872/how-to-use-huggingface-hf-trainer-train-with-custom-collate-function/76929999#76929999 Looks very useful especially for peft: - peft https://github.com/huggingface/trl/blob/main/examples/scripts/sft_trainer.py python trl/examples/scripts/sft_trainer.py \ --model_name meta一一嚅ese--_O号parEXTest争取白日夹尝试,保留原文代码内容不变
内容的提问来源于stack exchange,提问作者Charlie Parker
相关产品推荐
相关产品推荐

