文章的翻譯是在課程開始前夕準備的
跨多個高效能運算實例進行分散式訓練可以將現代深度神經網路在大量資料上的訓練時間從幾週縮短到幾小時甚至幾分鐘,從而使這種訓練技術在深度學習的實際用例中普及。使用者必須了解如何跨多個實例共享和同步數據,這反過來對擴展效率產生重大影響。此外,使用者還應該知道如何將在一個實例上執行的訓練腳本部署到多個實例。
在本文中,我們將討論使用開源深度學習程式庫 Apache MXNet 和分散式學習框架 Horovod 進行分散式學習的快速簡單的方法。我們將展示 Horovod 框架的效能優勢,並示範如何編寫 MXNet 訓練腳本以與 Horovod 一起分散式運作。
什麼是 Apache MXNet
– 用於建置、訓練和部署深度神經網路的開源深度學習框架。 MXNet 抽象化了與實現神經網路相關的複雜性,具有高效能和可擴展性,並為流行的程式語言提供 API,例如 , , , , , , 與其他人。
使用參數伺服器在 MXNet 中進行分散式訓練
使用參數伺服器方法。它使用一組參數伺服器從每個工作者收集梯度,執行聚合,並將更新後的梯度發送回工作者以進行下一次最佳化迭代。確定正確的伺服器與工作者的比例是有效擴充的關鍵。如果只有一個參數伺服器,它可能會成為計算的瓶頸。相反,如果使用太多伺服器,多對多關係會使所有網路連線飽和。
Horovod 是什麼
– Uber 開發的開源分散式深度學習框架。它使用高效的多 GPU 和多節點通訊技術(例如 NVIDIA 集體通訊庫 (NCCL) 和訊息傳遞介面 (MPI))在渦流之間分發和聚合模型參數。它優化了網路頻寬使用率,並且在運行深度神經網路模型時具有良好的擴展性。它目前支援幾種流行的機器學習框架,即 、Tensorflow、Keras 和 PyTorch。
MXNet 與 Horovod 集成
MXNet 透過 Horovod 中定義的分散式學習 API 與 Horovod 整合。 Horovod 通訊 API horovod.廣播(), horovod.allgather() и horovod.allreduce() 是使用 MXNet 引擎的非同步回呼實現的,作為其任務圖的一部分。因此,MXNet 引擎可以輕鬆處理通訊和運算之間的資料依賴關係,以避免同步造成的效能損失。 Horovod中定義的分散式最佳化器對象 horovod.分散式優化器 展開 優化 在 MXNet 中,以便它可以呼叫適當的 Horovod API 進行分散式參數更新。所有這些實施細節對最終用戶來說都是透明的。
快速啟動
您可以在 MacBook 上使用 MXNet 和 Horovod 快速開始在 MNIST 資料集上訓練小型捲積神經網路。
首先,從 PyPI 安裝 mxnet 和 horovod:
pip install mxnet
pip install horovod注意:如果您在 pip 安裝 horovod,你可能需要加入一個變數 MACOSX_DEPLOYMENT_TARGET=10.vv哪裡 vv – 這是您的 MacOS 版本,例如,對於 MacOSX Sierra,您需要寫入 MACOSX_DEPLOYMENT_TARGET=10.12 pip install horovod
然後安裝OpenMPI .
最後上傳測試腳本 mxnet_mnist.py 並在工作目錄中的 MacBook 終端機中執行以下命令:
mpirun -np 2 -H localhost:2 -bind-to none -map-by slot python mxnet_mnist.py這將在處理器的兩個核心上運行訓練。輸出如下:
INFO:root:Epoch[0] Batch [0-50] Speed: 2248.71 samples/sec accuracy=0.583640
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.89 samples/sec accuracy=0.882812
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.39 samples/sec accuracy=0.870000性能演示
在 50 個 GPU 上使用 1 個實例在 ImageNet 資料集上訓練 ResNet64-vXNUMX 模型時 p3.16x大 EC2,每個包含 AWS 雲端上的 8 個 NVIDIA Tesla V100 GPU,我們實現了 45000 張影像/秒(即每秒訓練的樣本數)的訓練吞吐量。訓練歷時 44 分鐘,經過 90 個 epoch,最佳準確率為 75.7%。
我們將其與 MXNet 的分散式訓練進行了比較,其方法分別是在 8、16、32 和 64 個 GPU 上使用參數伺服器,使用單一參數伺服器,伺服器與工作者的比例分別為 1:1 和 2:1。您可以在下面的圖 1 中看到結果。左側 y 軸上的長條表示每秒訓練的影像數量,右側 y 軸上的線表示擴展效率(即實際吞吐量與理想吞吐量的比率)。可以看到,伺服器數量的選擇影響著擴充效率。如果只有一個參數伺服器,則在 38 個 GPU 上擴充效率會下降到 64%。為了達到與 Horovod 相同的擴充效率,您需要將伺服器數量相對於工作者數量增加一倍。

圖 1. 使用 MXNet 與 Horovod 和參數伺服器進行分散式訓練的比較
在下表 1 中,我們比較了在 64 個 GPU 上執行實驗時每個執行個體的最終成本。將 MXNet 與 Horovod 結合使用可以以最低的成本提供最佳的吞吐量。

表 1. Horovod 與伺服器與工作者比例為 2:1 的參數伺服器之間的成本比較。
復現步驟
在接下來的步驟中,我們將展示如何使用 MXNet 和 Horovod 重現分散式訓練結果。要了解有關使用 MXNet 進行分散式學習的更多信息,請閱讀 .
步驟1
建立一個包含 MXNet 版本 1.4.0 或更高版本以及 Horovod 版本 0.16.0 或更高版本的同構實例集群,以使用分散式訓練。您還需要安裝 GPU 訓練所需的程式庫。對於我們的實例,我們選擇了 Ubuntu 16.04 Linux使用 GPU 驅動程式 396.44、CUDA 9.2、cuDNN 函式庫 7.2.1、NCCL 通訊器 2.2.13 和 OpenMPI 3.1.1。您也可以使用 ,這些庫已經預先安裝。
步驟2
將使用 Horovod API 的功能新增至您的 MXNet 訓練腳本。以下基於 MXNet Gluon API 的腳本可以作為簡單的範本。如果您已經有相應的訓練腳本,則需要使用粗體行。以下是使用 Horovod 學習時需要進行的一些關鍵更改:
- 設定上下文以匹配本地 Horovod 排名(第 8 行),以確保在正確的 GPU 核心上進行訓練。
- 將初始參數從一個工作者傳遞到所有工作者(第 18 行),以確保所有工作者都以相同的初始參數啟動。
- 創建 Horovod 分散式最佳化器 (第 25 行)以分散式方式更新參數。
完整腳本請參考Horovod-MXNet範例 и .
1 import mxnet as mx
2 import horovod.mxnet as hvd
3
4 # Horovod: initialize Horovod
5 hvd.init()
6
7 # Horovod: pin a GPU to be used to local rank
8 context = mx.gpu(hvd.local_rank())
9
10 # Build model
11 model = ...
12
13 # Initialize parameters
14 model.initialize(initializer, ctx=context)
15 params = model.collect_params()
16
17 # Horovod: broadcast parameters
18 hvd.broadcast_parameters(params, root_rank=0)
19
20 # Create optimizer
21 optimizer_params = ...
22 opt = mx.optimizer.create('sgd', **optimizer_params)
23
24 # Horovod: wrap optimizer with DistributedOptimizer
25 opt = hvd.DistributedOptimizer(opt)
26
27 # Create trainer and loss function
28 trainer = mx.gluon.Trainer(params, opt, kvstore=None)
29 loss_fn = ...
30
31 # Train model
32 for epoch in range(num_epoch):
33 ...步驟3
登入其中一個工作人員,使用 MPI 指令執行分散式訓練。在此範例中,分散式訓練在 4 個實例上運行,每個實例有 16 個 GPU,叢集中總共有 XNUMX 個 GPU。隨機梯度下降(SGD)優化器將與以下超參數一起使用:
- 小批量大小:256
- 學習率:0.1
- 動量:0.9
- 權重衰減:0.0001
當我們從一個 GPU 擴展到 64 個 GPU 時,我們根據 GPU 的數量線性擴展訓練速度(從 0,1 個 GPU 的 1 到 6,4 個 GPU 的 64),同時保持每個 GPU 的圖像數量為 256(從 256 個 GPU 的一批 1 張圖像到 16 個 GPU 的一批 384 張圖像)。隨著 GPU 數量的增加,權重衰減和動量參數也改變了。我們在前向傳遞中使用 float64 資料類型進行混合精度訓練,在梯度中使用 float16 資料類型,以加快 NVIDIA Tesla GPU 支援的 float32 運算。
$ mpirun -np 16
-H server1:4,server2:4,server3:4,server4:4
-bind-to none -map-by slot
-mca pml ob1 -mca btl ^openib
python mxnet_imagenet_resnet50.py結論
在本文中,我們研究了使用 Apache MXNet 和 Horovod 進行分散式模型訓練的可擴展方法。與使用 ResNet50-v1 模型訓練的 ImageNet 資料集上的參數伺服器方法相比,我們展示了可擴展性和成本效益。我們還包括了您可以採取的步驟來修改現有腳本以使用 Horovod 執行多實例訓練。
如果您剛開始使用 MXNet 和深度學習,請前往安裝頁面 ,首先建置 MXNet。我們也強烈建議您閱讀這篇文章 開始吧。
如果您已經使用過 MXNet 並想嘗試使用 Horovod 進行分散式學習,請查看 ,使用 MXNet 編譯並按照範例進行操作 或 .
*費用計算依據 適用於 EC2 執行個體的 AWS
了解有關課程的更多信息
來源: www.habr.com
