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進行模型訓練,分析了個別網絡無法學習或者出現模型精度下降的原因.

這次先整理到這,後續會持續更新....

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章