一行代碼讓訓練速度提升2倍,飛槳自動混合精度技術詳解

2021-01-10 開源中國

>> 訪問 PaddlePaddle 官網,了解更多相關內容。  

隨著生活節奏的加快,「等待」已經越來越成為人們希望遠離的事情。但是在深度學習領域,模型的參數、數據集的規模等等動輒就是以億為單位,甚至更大,因此當模型訓練成功之時,放一首張靚穎的「終於等到你」作為背景音樂實在是太應景了。

那如果現在向你推薦一款神器,可以實現訓練速度翻倍,訪存效率翻倍,你心動嗎?心動不如行動(這可不是電視直銷,別著急換頻道),來和我一起看看這款神器——基於PaddlePaddle核心框架的自動混合精度(Automatic Mixed Precision) 技術,簡稱飛槳 AMP 技術。

飛槳 AMP 技術僅僅通過一行代碼即可幫助用戶簡便快速的將單精度訓練的模型修改為自動混合精度訓練。同時通過黑白名單和動態 Loss Scaling 來保證訓練的穩定性,避免出現 INF 或者 NAN 問題。PaddlePaddle AMP 可以充分發揮新一代 NVIDIA GPU 中 Tensor Core 的計算性能優勢,ResNet50、Transformer 等模型的訓練速度與單精度訓練相比可以提升到 1.5~2.9 倍。

那麼它是怎麼實現的呢?我們先從什麼是自動混合精度技術講起。

什麼是自動混合精度技術

顧名思義,自動混合精度是一種自動將半精度和單精度混合使用,從而加速模型訓練的技術。其中單精度(Float Precision32,FP32)好理解,是計算機常用的一種數據類型。那么半精度是什麼呢?如圖 1 所示,半精度(Float Precision16,FP16)是一種相對較新的浮點類型,在計算機中使用 2 字節(16 位)存儲,在 IEEE 754-2008 中,它被稱作 binary16。與計算中常用的單精度和雙精度類型相比,Float16 更適於在精度要求不高的場景中使用。

不言而喻,在深度學習領域,如果使用 Float16 代替 Float32 來存儲數據,那麼開發者就可以訓練更大更複雜的模型,使用更大的 batch size。因此對於那些恨不得挖掘出 GPU 裡每一個電晶體全部潛力的科學家們怎麼能放過它呢?同時由於 NVIDIA 推出了具備 Tensor Core 技術的 Volta 及 Turing 架構 GPU,使半精度計算趨向成熟。在相同的 GPU 硬體上,Tensor Core 的半精度計算吞吐量是單精度的 8 倍。

但顯而易見,使用 Float16 肯定會同時帶來計算精度上的損失。但對深度學習訓練而言,並不是所有計算都要求很高的精度,一些局部的精度損失對最終訓練效果影響很微弱,僅需要某些特殊步驟保留 Float32 的計算精度即可。因此混合精度計算的需求應運而生。我們可以將訓練過程中一些對精度損失不敏感且能使用 Tensor Core 進行加速的運算使用半精度處理,最大限度的提升訪存和計算效率。

但是對每個具體模型,人工去設計和嘗試精度混合的方法,是非常繁瑣的,我們迫切需要一種更簡潔的方式,高效地實現混合精度的訓練。AMP,顧名思義,就是讓混合精度訓練自動化,因此使用簡單是它的重要特色。具體咋用,咱們往下看!

AMP 的使用方法

下面以 MNIST 為例介紹如何使用飛槳 AMP 技術。MNIST 網絡定義的代碼如下所示。其中 conv2d、batch_norm(bn)和 pool2d 的數據布局需要提前設置為'NHWC',這樣有利於加速混合精度訓練,並且 conv2d 的輸出通道數需要設置為 4 的倍數,以便使用 Tensor Core 技術加速。

import paddle.fluid as fluiddef MNIST(data, class_dim): conv1 = fluid.layers.conv2d(data, 16, 5, 1, act=None, data_format='NHWC') bn1 = fluid.layers.batch_norm(conv1, act='relu', data_layout='NHWC') pool1 = fluid.layers.pool2d(bn1, 2, 'max', 2, data_format='NHWC') conv2 = fluid.layers.conv2d(pool1, 64, 5, 1, act=None, data_format='NHWC') bn2 = fluid.layers.batch_norm(conv2, act='relu', data_layout='NHWC') pool2 = fluid.layers.pool2d(bn2, 2, 'max', 2, data_format='NHWC') fc1 = fluid.layers.fc(pool2, size=50, act='relu') fc2 = fluid.layers.fc(fc1, size=class_dim, act='softmax') return fc2

為了訓練 MNIST 網絡,還需要定義損失函數來更新權重參數,此處使用的優化損失函數是 SGDOptimizer。為了簡化說明,這裡省略了迭代訓練的相關代碼,僅體現損失函數及優化器定義相關的內容。

import paddle.fluid as fluidimport numpy as npdata = fluid.layers.data( name='image', shape=[None, 28, 28, 1], dtype='float32')label = fluid.layers.data(name='label', shape=[None, 1], dtype='int64')out = MNIST(data, class_dim=10)loss = fluid.layers.cross_entropy(input=out, label=label)avg_loss = fluid.layers.mean(loss)sgd = fluid.optimizer.SGDOptimizer(learning_rate=1e-3)sgd.minimize(avg_loss)

那麼如何將上面的示例改造成使用 AMP 訓練的方式呢?用戶僅需要使用飛槳提供的 AMP 函數 fluid.contrib.mixed_precision.decorate 將原來的優化器 SGDOptimizer 進行封裝,然後使用封裝後的優化器(mp_sgd)更新參數梯度,代碼如下所示:​​​​​​​

sgd = fluid.optimizer.SGDOptimizer(learning_rate=1e-3)mp_sgd = fluid.contrib.mixed_precision.decorator.decorate(sgd)mp_sgd.minimize(avg_loss)

如上即為最簡單的飛槳 AMP 功能使用方法。

但是大家可能有些疑問,模型是如何感知哪些算子(Op)需要被轉換呢?是不是還需要手工指定呢?算子那麼多,我怎麼知道哪個算子可以被轉換呢?別著急,PaddlePaddle已經幫你定製好了,這也是這門技術被稱為「自動」的原因之一,且請往下看!

黑白名單功能

為了讓開發者可以方便快捷的使用混合精度計算,PaddlePaddle的工程師們使用了大量模型在不同應用場景中反覆驗證,然後根據半精度數據類型計算的穩定性和加速效果,梳理出一系列適合轉換為半精度計算的算子,並將這些算子定義到了一份白名單文件中。同時對於一些經過驗證發現不適合轉換的算子,也就是使用半精度計算會導致數值不精確的算子將被記錄到黑名單文件中。此外一些對半精度計算沒有多少影響的算子歸類於灰名單。在使用 AMP 訓練過程中,系統會自動讀取黑白名單,從而感知到哪些算子需要被轉換為半精度計算。

對於某些特殊場景,如果開發者希望使用自定義的黑白名單,則可以使用 AutoMixedPrecisionLists 類設置,代碼示例如下所示。​​​​​​​

sgd = SGDOptimizer(learning_rate=1e-3)# 指定自定義的黑白名單,其中 list1 和 list2 為包含有算子名稱的列表amp_list = AutoMixedPrecisionLists(custom_white_list=list1,custom_black_list=list2)mp_sgd = fluid.contrib.mixed_precision.decorator.decorate(sgd, amp_list)mp_sgd.minimize(avg_loss)

那麼自動混合精度技術被稱為「自動」的原因之二呢?那就是下面的自動調整 Loss Scaling 功能。

自動調整 Loss Scaling

AMP 技術在提升訪存和計算效率的同時,伴隨的副作用也是很明顯的。那就是由於半精度數據類型的精度範圍與轉換前的單精度相比過窄,導致容易產生 INF 和 NAN 問題。為了避免此類問題,AMP 技術實現了自動調整 Loss Scaling 功能,即在 AMP 訓練過程中,為了避免精度下溢,每訓練一定數量批次的數據,就將 Loss 放大指定倍數。如果 Loss 在放大過程中發生上溢,則可以再縮小一定倍數,確保整個訓練過程中,梯度可以正常收斂。

fluid.contrib.mixed_precision.decorate 函數攜帶了自動調整 Loss Scaling 功能相關的參數,這些參數都帶有默認值,如下面代碼所示。這些默認值都是經過飛槳工程師多次驗證後定義的。通常情況下,用戶可以直接使用,無需重新設置。​​​​​​​

sgd = SGDOptimizer(learning_rate=1e-3)mp_sgd = fluid.contrib.mixed_precision.decorator.decorate(sgd, init_loss_scaling=2**15, incr_every_n_steps=2000, use_dynamic_loss_scaling=True)mp_sgd.minimize(avg_loss)

多卡 GPU 訓練的優化

在新發布的PaddlePaddle核心框架 1.7 版本上,AMP 技術深度優化了多卡 GPU 訓練。如圖 2 所示,在優化之前的參數梯度更新過程中,梯度計算時雖然使用的是半精度數據類型,但是不同 GPU 卡之間的梯度傳輸數據類型仍為單精度。

為了降低 GPU 多卡之間的梯度傳輸帶寬,我們將梯度傳輸這個過程提到 Cast 操作之前,而每個 GPU 卡在得到對應的半精度梯度後再執行 Cast 操作,將其轉變為單精度類型,如圖 3 所示。這一優化在訓練網絡複雜度較大的模型時,對減少帶寬佔用方面非常有效,如多卡訓練 BERT-Large 模型。

訓練性能對比(AMP VS FP32)

飛槳 AMP 技術在 ResNet50、Transformer 等模型上訓練速度相對於 FP32 訓練來說有非常大的優勢,下面以 ResNet50 模型為例,從下圖中可以看出,ResNet50 的 AMP 訓練相對與 FP32 訓練,單卡加速比可達 2.9 倍,八卡加速比可達 2.8 倍。

相關資料

​​​​​​​>> 訪問 PaddlePaddle 官網,了解更多相關內容。  

相關焦點

  • GTC大會飛槳專家演講實錄:簡單易用的飛槳分布式訓練功能升級
    在一小時的演講中,百度主任研發架構師董大祥圍繞飛槳框架新版本的大規模訓練與應用展開,介紹了大規模分布式訓練的功能、性能、以及在產業中的實踐。以下為演講實錄部分:飛槳的這次改動中主要是對並行訓練API進行了全面更新,使代碼變得更加簡潔,也更方便調試,另外也對並行訓練的策略進行了進一步的升級,可以適用於更大規模的模型參數。
  • 基於複數神經網絡首發量子機器學習開發工具 「量槳」,飛槳布局...
    除此之外,聯邦學習、強化學習、圖神經網絡等前沿技術也再次升級,為開發者提供強大的前沿開發工具組件,有力支持更多開發需求。從開發、訓練到部署,飛槳開源深度學習平臺為開發者帶來開發全流程體驗的提升。在開發方面,除了提升動態圖和高層API的能力外,飛槳還在圖像和語音領域新增3個端到端開發套件。
  • 百度飛槳PaddleCV全景圖曝光 視覺技術能力三方面重磅更新
    PaddleDetection模塊種類與性能全面提升,YOLOv3大幅增強,精度提升4.3%,訓練提速40%,推理提速21%;人臉檢測模型BlazeFace新增NAS版本,體積壓縮3倍,推理速度提速122%;新增IoU損失函數類型,精度再提升1%,不增加預測耗時。
  • 137% YOLOv3加速、10倍搜索性能提升!這樣的驚喜,最新版PaddleSlim...
    飛槳PaddleSlimV1.0項目地址:https://github.com/PaddlePaddle/PaddleSlim一、定製YOLO蒸餾方案,刷新COCO檢測任務精度模型蒸餾是將複雜網絡中的有用信息提取出來,遷移到一個更小的網絡中去,從而達到節省計算資源的目的。
  • 性能領先,即訓即用,快速部署,飛槳首次揭秘伺服器端推理庫
    子圖集成TensorRT加快GPU推理速度Paddle Inference採用子圖的形式集成TensorRT,針對GPU推理場景,TensorRT可對一些子圖進行優化,包括OP的橫向和縱向融合,過濾冗餘的OP,並為OP自動選擇最優的kernel,加快推理速度。
  • 32分鐘訓練神經機器翻譯,速度提升45倍
    然而如果我們從一開始就考慮降低模型訓練時間,那麼很多概念都能迅速驗證。在 Facebook 開發者的試驗中,他們採用了低精度和大批量等一系列加速訓練方法,並成功地將需要 24 小時訓練的 NMT 降低到 32 分鐘。該項目相關的分布式訓練代碼已開源。
  • 基於飛槳PaddlePaddle的多種圖像分類預訓練模型強勢發布
    當前飛槳分類模型庫提供了VGG11,VGG13,VGG16以及VGG19四個網絡結構預訓練模型。當前飛槳分類模型庫提供的InceptionV4由於採用了label_smoothing與mixup混合訓練的方式,將論文的指標提高了近0.8個點,成為目前開源最好的InceptonV4的預訓練模型。
  • AI質檢又出"神仙模型" 百度飛槳 PP-YOLO更準、更快、體積更小
    工業視覺、自動駕駛、安防、新零售等我們身邊熟知的各行各業都需要目標檢測技術,由於其很好的平衡了標註成本、檢測精度和速度等,成為當前智能製造產業升級浪潮中被商業化應用最為廣泛的AI技術之一。而實際生產環境對檢測算法的精度、速度、體積等要求往往十分苛刻。
  • PyTorch 1.6 發布:原生支持自動混合精度訓練並進入穩定階段 - OS...
    部分更新亮點包括: 原生支持自動混合精度訓練(automatic mixed-precision training),並已進入穩定階段 為 tensor-aware 增加對 TensorPipe 的原生支持 在前端 API 增加了對 complex tensor 的支持 新的分析工具提供了張量級的內存消耗信息 針對分布式數據並行訓練和遠程過程調用的多項改進和新功能此外,從該版本起,新功能的狀態將分為三種
  • RestNet50預訓練模型top1近80%,基於飛槳PaddlePaddle的多種圖像...
    這個預訓練模型已經開源,其訓練代碼不久將會發布。當前飛槳分類模型庫提供的InceptionV4由於採用了label_smoothing與mixup混合訓練的方式,將論文的指標提高了近0.8個點,成為目前開源最好的InceptonV4的預訓練模型。
  • 精度45.9%,推理速度72.9FPS,百度飛槳推出工業級目標檢測模型 PP...
    允中 發自 凹非寺量子位 編輯 | 公眾號 QbitAI工業視覺、自動駕駛、安防、新零售等我們身邊熟知的各行各業都需要目標檢測技術,由於其很好的平衡了標註成本、檢測精度和速度等,成為當前智能製造產業升級浪潮中被商業化應用最為廣泛的AI技術之一
  • TensorFlow 2.4來了:上線對分布式訓練和混合精度的新功能支持
    TensorFlow 2.4 的更新包括對於分布式訓練和混合精度的新功能支持,對 NumPy API 子集的試驗性支持以及一些用於監測性能瓶頸的新工具。Keras 更新混合精度在 TensorFlow 2.4 中,Keras 混合精度 API 已經脫離試驗階段,成為穩定的 API。
  • PyTorch 源碼解讀之 torch.cuda.amp: 自動混合精度詳解
    也在 2018 年提出一個 PyTorch 拓展 apex,來支持模型參數自動混合精度訓練。自動混合精度(Automatic Mixed Precision, AMP)訓練,是在訓練一個數值精度 FP32 的模型,一部分算子的操作時,數值精度為 FP16,其餘算子的操作精度是 FP32,而具體哪些算子用 FP16,哪些用 FP32,不需要用戶關心,amp 自動給它們都安排好了。
  • 百度飛槳躍居世界第二、國內第一!看中國AI領頭雁百度的開源進擊之路
    近日,權威科技媒體通過分析GitHub上的開源項目數據集GitHubArchive,得出2020和2019年度全球深度學習框架排名榜單,其中,百度飛槳PaddlePaddle均力壓谷歌TensorFlow,緊隨Facebook PyTorch之後,其搶眼的數據表現意味著在開發者積極貢獻代碼和項目、社區活躍、代碼迭代速度上一直保持著強勁的競爭力,已經成為了國內第一、世界第二的深度學習開源框架
  • PyTorch1.6:新增自動混合精度訓練、Windows版開發維護權移交微軟
    新版本增加了一個 amp 子模塊,支持本地自動混合精度訓練。Facebook 還表示,微軟已擴大了對 PyTorch 社區的參與,現在擁有 PyTorch 在 Windows 上的開發和維護所有權。相比於以往的 PyTorch 版本,本次即將發布的 PyTorch 1.6 有哪些吸引人的地方呢?
  • 飛槳上線萬能轉換小工具,教你玩轉TensorFlow、Caffe等模型遷移
    百度推出飛槳(PaddlePaddle)後,不少開發者開始轉向國內的深度學習框架。但是從代碼的轉移談何容易,之前的工作重寫一遍不太現實,成千上萬行代碼的手工轉換等於是在做一次二次開發。現在,有個好消息:無論Caffe、TensorFlow、ONNX都可以輕鬆遷移到飛槳平臺上。
  • 精度45.9%,推理速度72.9FPS,百度飛槳推出工業級目標檢測模型
    允中 發自 凹非寺量子位 編輯 | 公眾號 QbitAI工業視覺、自動駕駛、安防、新零售等我們身邊熟知的各行各業都需要目標檢測技術,由於其很好的平衡了標註成本、檢測精度和速度等,成為當前智能製造產業升級浪潮中被商業化應用最為廣泛的AI技術之一。
  • 重磅發布開源框架、生物計算平臺螺旋槳,百度飛槳交了年終成績單
    本屆峰會,百度飛槳帶來八大全新發布與升級,有支持前沿技術探索和應用的生物計算平臺 PaddleHelix 螺旋槳,開發更加便捷的飛槳開源框架 2.0 RC 版,端雲協同的 AI 集成開發環境 BML CodeLab,支持更強大分布式訓練的業界首個通用異構參數伺服器架構,開源算法庫增至 200+,飛槳企業版 EasyDL 智能數據服務升級,飛槳硬體生態路線圖以及攜手全球開發者開啟
  • Google AI地標檢索識別競賽雙料獲勝方案|飛槳PaddlePaddle開源
    ,然後在 GLD v2(Google LandMark Dataset V2)上進行訓練。這些模型及訓練方法都已經在飛槳的 Github 圖像分類項目中開源 [7]。此外,比賽過程中還基於 Npairs Loss[9],以及將 index 集合的 80 萬張圖像聚類後加入訓練,學習更多種不同維度的特徵,提升整個系統的泛化能力。所有訓練檢索特徵的代碼也已經在飛槳的 Github 度量學習項目中開源 [10]。
  • 百度飛槳發布工業級圖像分割利器PaddleSeg
    機器之心發布機器之心編輯部近日,飛槳官方發布了工業級圖像分割模型庫 PaddleSeg,給開發者帶來誠意滿滿的三重超值驚喜:①一次性開源 15 個官方支持的圖像分割領域主流模型,大禮包帶來大滿足。②多卡訓練速度比對標產品快兩倍,工業級部署能力,時間節省超痛快。