混合精度是如何加速大模型训练的?

混合精度是如何加速大模型训练的?

基础知识回顾

float-32

在深度学习中,通常使用float-32 精度的数值训练模型,其中pytorch默认的也是float-32。
float32,也就是32位单精度浮点数,表示一个浮点数需要使用32位二进制数来表示。其中,这32位按照特定的规则分为了不同的部分,用于表示符号、指数和尾数,具体如下:

  1. 符号位(sign bit):占用1个二进制位(bit),用于表示该浮点数的正负性,0表示正数,1表示负数。
  2. 指数位(exponent bit):占用8个二进制位(bit),用于表示指数部分,包括指数的符号和大小。
  3. 尾数位(mantissa bit):占用23个二进制位(bit),用于表示尾数部分,即小数部分。

根据IEEE 754标准,32位单精度浮点数的格式为S EEEEEEEE MMMMMMMMMMMMMMMMMMMMM,其中S表示符号位,EEEEEEEE表示指数位,MMMMMMMMMMMMMMMMMMMMMM表示尾数位。这种格式的表示范围是从约-3.4×1038到约3.4×1038之间的浮点数,并且精度达到6-7位有效数字。
计算方式如下:
在这里插入图片描述

在通常的科学计算中,都是以float-64精度(也就是double)计算的,它用来表示数值的位数更多,精度更大,损失更小,在深度学习中为什么我们很少用float-64而是去采用?

  1. 因为使用float32,可以节省更多的内存,可以设置更大的batchsize。
  2. 模型训练速度更快,更快的得到实验结果。

从float-32 到float-16

在这里插入图片描述

下面是各个精度的对比:
在这里插入图片描述

在训练中,我们从float-64到float32往往不会造成很大的损失,但是当我们从32转到16位,就会造成训练不稳定,无法收敛。主要是由于数值精度不够,造成了数值的上溢或者下溢。
具体如下所示:
在这里插入图片描述

32为的最大数值是:340,282,000,000,000,000,000,000,000,000,000,000,000
16位则是:
65504

混合精度计算

在这里插入图片描述

  1. 首先把32位参数转化为16位,进行forward pass然后计算各个参数对loss的gradients。
  2. 通过16位 weight得到16位的gradients。
  3. 然后把16位的gradients转换成32位。
  4. 把32位gradients与lr相乘得到移动的步伐
  5. 32位原始参数-步伐得到新的32位参数。

实验
在这里插入图片描述
这里我们发现,混合精度的在测试集上面的表现要比32还高,原因可能与batch小一点是一个道理,引入了一些误差,起到了正则化的效果。

bfloat16

在这里插入图片描述
与传统float16格式相比,Bfloat16扩展了动态范围,但代价是降低了精度。
扩展的动态范围帮助bfloat16表示非常大和非常小的数字,使其更适合可能遇到大范围值的深度学习应用程序。但是,较低的精度可能会影响某些计算的准确性,或者在某些情况下导致舍入误差。但在大多数深度学习应用中,这种降低的精度对建模性能的影响微乎其微。
虽然bfloat16最初是为tpu开发的,但这种格式现在也被一些NVIDIA gpu所支持,从NV的一部分A100 Tensor Core gpu开始.

实验:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PyTorch AMP(Automatic Mixed Precision)是一种用于深度学习模型训练加速技术,它可以将低精度的计算操作与高精度的计算操作混合使用,从而在保持模型精度的同时提高训练速度和减少显存占用。具体来说,PyTorch AMP 使用了 NVIDIA Apex 库中的混合精度训练技术,将一些计算操作转换为 FP16(半精度浮点数)格式,从而减少计算和存储的需求。 实现 PyTorch AMP 混合精度训练的步骤如下: 1. 引入必要的库和模块: ```python import torch from torch.cuda.amp import autocast, GradScaler ``` 2. 定义模型和优化器: ```python model = MyModel() optimizer = torch.optim.SGD(model.parameters(), lr=1e-3) ``` 3. 定义混合精度训练相关的参数: ```python scaler = GradScaler() ``` 4. 在训练过程中使用 autocast 和 GradScaler 完成混合精度训练: ```python for data, target in train_loader: # 将数据和目标值转换为合适的类型 data, target = data.to(device), target.to(device) # 使用 autocast 进行前向计算和反向传播 with autocast(): output = model(data) loss = loss_function(output, target) # 使用 GradScaler 进行梯度缩放和反向传播 scaler.scale(loss).backward() scaler.step(optimizer) scaler.update() # 清空梯度 optimizer.zero_grad() ``` 在上面的代码中,autocast 用于自动将一些计算操作转换为 FP16 格式,从而提高训练速度;GradScaler 用于梯度缩放和反向传播,确保在低精度的计算下仍能保持模型精度。 需要注意的是,不是所有的计算操作都能够使用 FP16 格式,一些数值较大的计算操作可能会出现溢出等问题。因此,在使用 PyTorch AMP 进行混合精度训练时,需要仔细选择转换的计算操作,并且进行必要的检查和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HanZee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值