Mixed-precision(混合精度训练)

混合精度训练

最近刚好在做相关工作,所以花点时间对混合精度进行模型训练进行一下理解与总结.详细数据请参考百度与nvidia联合放在arxiv上的论文:https://arxiv.org/pdf/1710.03740.pdf

概述

深度学习模型的计算任务分为训练和推理.训练往往是放在云端或者超算集群中,利用GPU强大的浮点计算能力,来完成网络模型参数的学习过程.一般来说训练时,计算资源往往非常充足,基本上受限于显存资源/多节点扩展/通讯库效率的问题.相对于训练过程,推理往往被应用于终端设备,如手机,计算资源/功耗都收到严格的限制,为了解决这样的问题,提出了很多不同的方法来减少模型的大小以及所需的计算资源/存储资源.模型压缩除了剪枝以外,还有一个方法就是降低模型参数的数值精度.随着网络深度的加大,带来的参数数量也呈现指数级增长,如何将最终学习好的网络模型塞入到终端设备有限的空间中是目前很多性能优良的网络真正应用到日常生活中的一大阻碍.
本文主要讨论如何降低模型训练时的数值精度来加速训练过程.现在的模型训练过程基本上使用单精度和双精度,如果网络模型很大,那么受限于显存空间(最新的volta 100是16G),batch size就会非常小.Batch size太小容易导致网络学习过程不稳定,影响模型的精度,详细的关于batch size对网络模型训练的影响分析会在其他文章中介绍.

混合精度解释

百度这篇文章主要是利用cuda中原生支持的fp16数据类型,也就是所谓的半精度, nvidia的GPU其实在很早的架构就提供了这个精度的数值表示,只是没有提供专门的硬件计算单元. fp16所占用的空间是单精度的一半,双精度的1/4.在此之前,其实也有很多做模型量化研究的文章,但是或多或少都会影响模型最终的训练精度,所以并不使用.百度和NVIDIA的这次合作解决了这个问题,即降低了模型训练的显存占用,也保证了模型最终的精度.由于使用到更大的batch size模型最终学习的到参数泛化能力更强,个别网络甚至于获得更高的精度.混合精度的概念就是针对使用fp16进行模型的训练过程,同时保证和fp32同样的精度所提出的,也可以认为是使用到trick. 后面会了解到,nvidia为了加速训练过程,在最新的架构中还增加了特殊的fp16矩阵运算单元.

FP32 MASTER COPY OF WEIGHTS

意思是使用fp16进行训练,同时有一份fp32的参数主副本用于参数更新.那么实现上其实就很简单,只需要在每次迭代之前,将每个layer或者op的参数输入都确保是从fp32拉取到的,然后转换成fp16输入;而最后将计算得到梯度,则是更新到fp32的主副本上面.这样做的好处在于可以避免两种情况下的溢出,第一次就是当梯度特别小,超出fp16表达范围后,就变成了0,进而导致参数无法学习.另外一种情况就是梯度特别大,同样超出fp16可表达的最大值,那么更新后进一步导致参数不正确.而如果将更新到fp32的主副本,那么更新采用fp32,即使再小的梯度,也能够表示.

Loss Scaling

这个操作原理是借助求导的连式法则,通过放大loss,进而放大整个反向传播过程的参数梯度,最后在更新时候再缩放回来.这个参数可以固定,也可以根据网络的学习的状态自适应的进行调整.

BN处理

其实在实现前面两个之后我们会发现有些操作还是没法正常训练,因为一些中间结果超出了fp32所表达发范围,那么针对这样的操作,我们则需要单独进行处理,直接使用fp32的参数,将计算过程强制使用fp32.

以上是论文所提到的两个主要trick, 来避免由于梯度过大或者过小导致的信息丢失而影响精度.另外还对单纯使用fP16进行模型训练,分析了个别网络无法学习或者出现模型精度下降的原因.

这次先整理到这,后续会持续更新....

你可能感兴趣的:(深度学习)