基于 PyTorch 的混合精度訓(xùn)練加速

姓名:唐易平

學(xué)號(hào):19121110448

轉(zhuǎn)載自:【PyTorch】唯快不破:基于Apex的混合精度加速

【嵌牛導(dǎo)讀】:介紹一下混合精度計(jì)算(Mixed Precision)腾么,并分享一款Nvidia開發(fā)的基于PyTorch的混合精度訓(xùn)練加速神器--Apex。

【嵌牛鼻子】:PyTorch侧蘸,混合精度訓(xùn)練

【嵌牛提問(wèn)】:Apex加速原理锄贷?如何使用板惑?

【嵌牛正文】:

理論部分:

為了充分理解混合精度的原理,以及API的使用,先補(bǔ)充一點(diǎn)基礎(chǔ)的理論知識(shí)篡石。

1. 什么是FP16概耻?

半精度浮點(diǎn)數(shù)是一種計(jì)算機(jī)使用的二進(jìn)制浮點(diǎn)數(shù)數(shù)據(jù)類型使套,使用2字節(jié)(16位)存儲(chǔ)。

FP16和FP32表示的范圍和精度對(duì)比??

其中鞠柄,sign位表示正負(fù)侦高,exponent位表示指數(shù)(2^{n-15+1(n=0)}),fraction表示的是分?jǐn)?shù)(\frac{m}{1024} )厌杜,其中當(dāng)指數(shù)為零的時(shí)候奉呛,下圖加號(hào)左邊為0,其他情況為1夯尽。

FP16的表示范例

2. 為什么需要FP16瞧壮?

1).?減少顯存占用

現(xiàn)在模型越來(lái)越大,當(dāng)你使用Bert這一類的預(yù)訓(xùn)練模型時(shí)呐萌,往往顯存就被模型及模型計(jì)算占去大半馁痴,當(dāng)想要使用更大的Batch Size的時(shí)候會(huì)顯得捉襟見肘。由于FP16的內(nèi)存占用只有FP32的一半肺孤,自然地就可以幫助訓(xùn)練過(guò)程節(jié)省一半的顯存空間罗晕。

2).?加快訓(xùn)練和推斷的計(jì)算

與普通的空間時(shí)間Trade-off的加速方法不同济欢,F(xiàn)P16除了能節(jié)約內(nèi)存,還能同時(shí)節(jié)省模型的訓(xùn)練時(shí)間小渊。在大部分的測(cè)試中法褥,基于FP16的加速方法能夠給模型訓(xùn)練帶來(lái)多一倍的加速體驗(yàn)。

3).?張量核心的普及

硬件的發(fā)展同樣也推動(dòng)著模型計(jì)算的加速酬屉,隨著Nvidia張量核心(Tensor Core)的普及半等,16bit計(jì)算也一步步走向成熟,低精度計(jì)算也是未來(lái)深度學(xué)習(xí)的一個(gè)重要趨勢(shì)呐萨,再不學(xué)習(xí)就out啦杀饵。

3. FP16帶來(lái)的問(wèn)題:量化誤差

1).?溢出錯(cuò)誤(Grad Overflow / Underflow)

由于FP16的動(dòng)態(tài)范圍(6×10^{-8}\sim65504 )比FP32的動(dòng)態(tài)范圍(1.4\times10^{-45}\sim1.7\times10^{38})要狹窄很多,因此在計(jì)算過(guò)程中很容易出現(xiàn)上溢出(Overflow谬擦,g>65504 )和下溢出(Underflow切距,g<6\times10^{-8})的錯(cuò)誤,溢出之后就會(huì)出現(xiàn)“Nan”的問(wèn)題惨远。

在深度學(xué)習(xí)中谜悟,由于激活函數(shù)的的梯度往往要比權(quán)重梯度小,更易出現(xiàn)下溢出的情況北秽。

下溢出問(wèn)題

2).?舍入誤差(Rounding Error)

舍入誤差指的是當(dāng)梯度過(guò)小葡幸,小于當(dāng)前區(qū)間內(nèi)的最小間隔時(shí),該次梯度更新可能會(huì)失敗贺氓,用一張圖清晰地表示:

舍入誤差

4. 解決問(wèn)題的辦法:混合精度訓(xùn)練+動(dòng)態(tài)損失放大

1).?混合精度訓(xùn)練(Mixed Precision)

混合精度訓(xùn)練的精髓在于“在內(nèi)存中用FP16做儲(chǔ)存和乘法從而加速計(jì)算蔚叨,用FP32做累加避免舍入誤差”÷庸椋混合精度訓(xùn)練的策略有效地緩解了舍入誤差的問(wèn)題缅叠。

2).?損失放大(Loss Scaling)

即使用了混合精度訓(xùn)練,還是會(huì)存在無(wú)法收斂的情況虏冻,原因是激活梯度的值太小肤粱,造成了下溢出(Underflow)。損失放大的思路是:

\cdot ?反向傳播前厨相,將損失變化(dLoss)手動(dòng)增大2k2k倍领曼,因此反向傳播時(shí)得到的中間變量(激活函數(shù)梯度)則不會(huì)溢出;

\cdot 反向傳播后蛮穿,將權(quán)重梯度縮2k2k倍庶骄,恢復(fù)正常值。


Apex的新API:Automatic Mixed Precision (AMP)

曾經(jīng)的Apex混合精度訓(xùn)練的api仍然需要手動(dòng)half模型已經(jīng)輸入的數(shù)據(jù)践磅,比較麻煩单刁,現(xiàn)在新的api只需要三行代碼即可無(wú)痛使用:

from apex import amp

model, optimizer = amp.initialize(model, optimizer, opt_level="O1")# 這里是“歐一”,不是“零一”

with amp.scale_loss(loss, optimizer) as scaled_loss:

? ?????? scaled_loss.backward()

1.opt_level

其中只有一個(gè)opt_level需要用戶自行配置:

\cdot ?O0:純FP32訓(xùn)練府适,可以作為accuracy的baseline羔飞;

\cdot ?O1:混合精度訓(xùn)練(推薦使用)肺樟,根據(jù)黑白名單自動(dòng)決定使用FP16(GEMM, 卷積)還是FP32(Softmax)進(jìn)行計(jì)算。

\cdot ?O2:“幾乎FP16”混合精度訓(xùn)練逻淌,不存在黑白名單么伯,除了Batch norm,幾乎都是用FP16計(jì)算卡儒。

\cdot ?O3:純FP16訓(xùn)練田柔,很不穩(wěn)定,但是可以作為speed的baseline骨望;

2.動(dòng)態(tài)損失放大(Dynamic Loss Scaling)

AMP默認(rèn)使用動(dòng)態(tài)損失放大硬爆,為了充分利用FP16的范圍,緩解舍入誤差锦募,盡量使用最高的放大倍數(shù)(2^{24})摆屯,如果產(chǎn)生了上溢出(Overflow),則跳過(guò)參數(shù)更新糠亩,縮小放大倍數(shù)使其不溢出,在一定步數(shù)后(比如2000步)會(huì)再嘗試使用大的scale來(lái)充分利用FP16的范圍:

AMP中動(dòng)態(tài)損失放大的策略

干貨:踩過(guò)的那些坑

\cdot ?判斷你的GPU是否支持FP16:構(gòu)擁有Tensor Core的GPU(2080Ti准验、Titan赎线、Tesla等),不支持的(Pascal系列)就不建議折騰了糊饱。

\cdot ?常數(shù)的范圍:為了保證計(jì)算不溢出垂寥,首先要保證人為設(shè)定的常數(shù)(包括調(diào)用的源碼中的)不溢出,如各種epsilon另锋,INF等滞项。

\cdot ?Dimension最好是8的倍數(shù):Nvidia官方文檔表示,維度都是8的倍數(shù)的時(shí)候夭坪,性能最好文判。

\cdot ?涉及到sum的操作要小心,很容易溢出室梅,類似Softmax的操作建議用官方API戏仓,并定義成layer寫在模型初始化里。

\cdot ?模型書寫要規(guī)范:自定義的Layer寫在模型初始化函數(shù)里亡鼠,graph計(jì)算寫在forward里赏殃。

\cdot ?某些不常用的函數(shù),在使用前需要注冊(cè):amp.register_float_function(torch, 'sigmoid')

\cdot ?某些函數(shù)(如einsum)暫不支持FP16加速间涵,建議不要用的太heavy仁热。

\cdot ?需要操作模型參數(shù)的模塊(類似EMA),要使用AMP封裝后的model勾哩。

\cdot ?需要操作梯度的模塊必須在optimizer的step里抗蠢,不然AMP不能判斷grad是否為Nan根盒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市物蝙,隨后出現(xiàn)的幾起案子炎滞,更是在濱河造成了極大的恐慌,老刑警劉巖诬乞,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件册赛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡震嫉,警方通過(guò)查閱死者的電腦和手機(jī)森瘪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)票堵,“玉大人扼睬,你說(shuō)我怎么就攤上這事°彩疲” “怎么了窗宇?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)特纤。 經(jīng)常有香客問(wèn)我军俊,道長(zhǎng),這世上最難降的妖魔是什么捧存? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任粪躬,我火速辦了婚禮,結(jié)果婚禮上昔穴,老公的妹妹穿的比我還像新娘镰官。我一直安慰自己,他們只是感情好吗货,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布泳唠。 她就那樣靜靜地躺著,像睡著了一般卿操。 火紅的嫁衣襯著肌膚如雪警检。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天害淤,我揣著相機(jī)與錄音扇雕,去河邊找鬼。 笑死窥摄,一個(gè)胖子當(dāng)著我的面吹牛镶奉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼哨苛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鸽凶!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起建峭,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤玻侥,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后亿蒸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凑兰,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年边锁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姑食。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茅坛,死狀恐怖音半,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贡蓖,我是刑警寧澤曹鸠,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站摩梧,受9級(jí)特大地震影響物延,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仅父,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浑吟。 院中可真熱鬧笙纤,春花似錦、人聲如沸组力。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)燎字。三九已至腥椒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間候衍,已是汗流浹背笼蛛。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛉鹿,地道東北人滨砍。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親惋戏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子领追,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容