gradient_accumulation_steps的含义
在微调大模型时,会有一个gradient_accumulation_steps参数
training_args = SFTConfig(# gradient_checkpointing=True, # 启用梯度检查点以降低显存# gradient_checkpointing_kwargs={'use_reentrant': False},per_device_train_batch_size=4,learning_rate=3e-5,gradient_accumulation_steps=2,bf16=True,save_strategy='no',num_train_epochs=10,log_level='debug',output_dir="output",max_length=4096, # 在这里设置序列长度
)
底层代码给的解释如下:
gradient_accumulation_steps (`int`, *optional*, defaults to 1):Number of updates steps to accumulate the gradients for, before performing a backward/update pass.<Tip warning={true}>When using gradient accumulation, one step is counted as one step with backward pass. Therefore, logging,evaluation, save will be conducted every `gradient_accumulation_steps * xxx_step` training examples.</Tip> 翻译成中文
gradient_accumulation_steps 的作用是在硬件如GPU内存有限、无法容纳较大批量(batch_size)时,模拟更大批量的训练效果。
详细的解释:
1、核心概念:随机梯度下降(SGD)与批量(Batch Size)
在训练深度学习模型时,我们通常不会一次使用整个数据集来计算梯度(这计算量太大),也不会一次只用一个样本(这噪音太大)。而是折中地使用一个小批量(Mini-batch) 的数据。
per_device_train_batch_size=4: 这个参数定义了物理批量大小(Physical Batch Size)。意思是,GPU每次最多只能同时处理并前向传播(forward)和反向传播(backward)4个样本。
在得到这4个样本的梯度后,优化器(如Adam)就会立即用这个梯度来更新模型权重。
2、 问题:小批量可能不稳定
有时候,per_device_train_batch_size 被迫设置得很小(比如这里的4),因为模型很大或者序列很长(max_length=4096),导致显存(VRAM)不够用。但是,太小的批量会带来两个问题:
1)训练不稳定: 基于仅仅4个样本计算出的梯度方向可能噪音很大,不能很好地代表整个数据集的真实梯度方向,导致训练过程震荡,难以收敛。
2)性能下降: 在某些任务上,使用较大的批量训练出的模型最终性能会更好。
3、解决方案:梯度累积(Gradient Accumulation)
gradient_accumulation_steps 就是为了解决上述问题而设计的。它让在不增加显存占用的情况下,模拟一个更大批量的训练效果。
gradient_accumulation_steps=2: 这个参数的意思是“累积2步”。
4、它是如何工作的呢?
结合per_device_train_batch_size=4, gradient_accumulation_steps=2来看:
第一步:模型正常处理第一批4个样本,进行前向传播和反向传播,计算出梯度1。但是优化器不会立即更新权重,而是将梯度1累积(加总)到一个缓冲区;
第二步:模型处理下一批4个样本,再次进行前向传播和反向传播,计算出梯度2。同样,这个梯度2也会被累积到一个缓冲区;
第三步:更新权重。现在已经累积了2(步)*4(批量大小)=8个样本的梯度,此时,优化器才会使用这个累积后的平均梯度(总和除以步数,以保持梯度数值范围稳定)来一次性更新模型权重;
第四步:清空缓冲区。权重更新后,梯度累积缓冲区被清零,为下一个累积周期做准备。
从效果上看,模型行为就像是使用了一个大小为8(4*2)的批量在进行训练,但显存占用始终只相当于处理4个样本的量。
欢迎点赞关注,你的支持是我持续输出的动力!