前言
训练时显存占用分析
模型权重参数
fp32 精度显存占用:4A 混合精度下显存占用(bf16/fp16):2A
优化器状态与梯度
以SGD为例,其计算公式为:
以 Momentum-SGD 为例,其计算公式为:
以 Adam 为例,其计算公式为:
SGD:优化器状态:0, 梯度:4A Momentum-SGD:优化器状态:4A,梯度:4A Adam:优化器状态:8A,梯度:4A
激活值
训练时显存不足怎么办?
去掉compute_metrics:有些代码会在输出层后计算rouge分等,这个会输出一个batch_size*vocab_size*seq_len 的一个大向量,非常占显存。 采用bf16/fp16进行混合精度训练:现在大模型基本上都采用 bf16 来进行训练,但是如v100这些机器不支持,可以采用fp16进行训练。显存占用能够降低一倍。 Flash attention:不仅能够降低显存,更能提高训练速度。 降低你的batch size:如上文所述,batch size 与模型每层的激活状态所占显存呈正相关,降低batch size 能够很大程度上降低这部分显存占用。 采用梯度累积:global batch size = batch size * 梯度累积,如果降低 batch size 后想保持你的 global batch size 不变,可以适当提高梯度累积值。 选择合适的上下文长度:如上文所述,上下文长度与激活状态所占显存呈正相关,因此可以通过适当降低上下文长度来降低显存占用。 DeepSpeed Zero:显存占用从高到低为:Zero 1 > Zero 2 > Zero 2 + offload > zero 3 > zero 3 + offload,推荐最多试到 Zero2 + offload。 选择更小的基座模型:在满足需求的情况下,尽量选择更小的基座模型。
Lora:能跑全参就别跑 Lora 或 Qlora,一方面是麻烦,另一方面的确是效果差点。 Qlora:Qlora 的速度比lora慢,但所需显存更少,实在没资源可以试试。 Megatron-LM:可以采用流水线并行和张量并行,使用比较麻烦,适合喜欢折腾的同学。 Pai-Megatron-LM:Megatron-LM 的衍生,支持 Qwen 的sft和pt,坑比较多,爱折腾可以试试。 激活检查点:不推荐,非常耗时。在反向传播时重新计算深度神经网络的中间值。用时间(重新计算这些值两次的时间成本)来换空间(提前存储这些值的内存成本)。
最后
参考
【1】https://zhuanlan.zhihu.com/p/31558973
