使用 Apache MXNet 和 Horovod 進行分散式學習

文章的翻譯是在課程開始前夕準備的 “大數據上的工業機器學習”

在多個高效能運算實例上進行分散式訓練可以將現代深度神經網路對大量資料的訓練時間從幾週縮短到幾小時甚至幾分鐘,使得這種訓練技術在深度學習的實際應用中普遍存在。 使用者必須了解如何跨多個實例共享和同步數據,這反過來對擴展效率產生重大影響。 此外,使用者還應該知道如何將在單一實例上執行的訓練腳本部署到多個實例。

在本文中,我們將討論使用開放深度學習函式庫 Apache MXNet 和 Horovod 分散式學習框架來快速輕鬆地進行分散式學習的方法。 我們將清楚地展示 Horovod 框架的效能優勢,並示範如何編寫 MXNet 訓練腳本,使其以分散式方式與 Horovod 一起工作。

什麼是 Apache MXNet

阿帕奇MXNet 是一個開源深度學習框架,用於創建、訓練和部署深度神經網路。 MXNet 抽象化了與實現神經網路相關的複雜性,具有高效能和可擴展性,並為流行的程式語言(例如 蟒蛇, C + +中, Clojure的, Java的, 朱莉婭, R, 斯卡拉 與其他人。

使用參數伺服器在 MXNet 中進行分散式訓練

MXNet 中的標準分散式學習模組 使用參數伺服器方法。 它使用一組參數伺服器從每個工作人員收集梯度,執行聚合,並將更新的梯度發送回工作人員以進行下一次最佳化迭代。 確定伺服器與工作人員的正確比例是有效擴充的關鍵。 如果只有一個參數伺服器,它可能會成為計算的瓶頸。 相反,如果使用太多伺服器,多對多通訊可能會堵塞所有網路連線。

什麼是霍羅沃德

霍羅沃德 是 Uber 開發的開放式分散式深度學習架構。 它利用高效的跨 GPU 和跨節點技術,例如 NVIDIA 集體通訊庫 (NCCL) 和訊息傳遞介面 (MPI),跨 vorec 分發和聚合模型參數。 它優化了網路頻寬的使用,並且在使用深度神經網路模型時可以很好地擴展。 目前支援幾種流行的機器學習框架,即 MX網、Tensorflow、Keras 和 PyTorch。

MXNet 和 Horovod 集成

MXNet 透過 Horovod 中定義的分散式學習 API 與 Horovod 整合。 Horovod 通訊 API horovod.broadcast(), 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 安裝霍羅沃德也許你需要加入一個變量 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 個實例的 1 個 GPU 上的 ImageNet 資料集上訓練 ResNet64-vXNUMX 模型時 p3.16x大 EC2,每個在AWS雲上包含8個NVIDIA Tesla V100 GPU,我們實現了45000張影像/秒的訓練吞吐量(即每秒訓練的樣本數)。 44 個 epoch 後,訓練在 90 分鐘內完成,最佳準確率為 75.7%。

我們將其與MXNet 的分散式訓練方法進行了比較,該方法在8、16、32 和64 個GPU 上使用參數伺服器,單一參數伺服器和伺服器與工作執行緒的比例分別為1:1 和2:1 。 您可以在下面的圖 1 中看到結果。 左側 y 軸上的長條代表每秒訓練的影像數量,線條反映右側 y 軸上的縮放效率(即實際吞吐量與理想吞吐量的比率)。 可以看到,伺服器數量的選擇會影響擴充效率。 如果只有一台參數伺服器,則在 38 個 GPU 上,擴充效率會下降到 64%。 為了實現與 Horovod 相同的擴充效率,您需要將相對於工作人員數量的伺服器數量增加一倍。

使用 Apache MXNet 和 Horovod 進行分散式學習
圖 1. 使用 MXNet 與 Horovod 和參數伺服器進行分散式學習的比較

在下面的表 1 中,我們比較了在 64 個 GPU 上執行實驗時每個執行個體的最終成本。 將 MXNet 與 Horovod 結合使用可以以最低的成本提供最佳的吞吐量。

使用 Apache MXNet 和 Horovod 進行分散式學習
表 1.Horovod 和 Parameter Server 之間的成本比較(伺服器與工作人員比率為 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。 您也可以使用 亞馬遜深度學習 AMI,其中這些庫已預先安裝。

步驟2

將使用 Horovod API 的功能新增至您的 MXNet 訓練腳本。 以下基於 MXNet Gluon API 的腳本可以用作簡單的範本。 如果您已經有相應的訓練腳本,則需要粗體行。 以下是使用 Horovod 學習時需要做出的一些關鍵更改:

  • 根據本地 Horovod 等級(第 8 行)設定上下文,以了解訓練是在正確的圖形核心上執行的。
  • 將初始參數從一個工作執行緒傳遞給所有工作執行緒(第 18 行),以確保所有工作執行緒以相同的初始參數開始。
  • 創建霍羅沃德 分散式最佳化器 (第25行)以分散式方式更新參數。

若要取得完整腳本,請參閱 Horovod-MXNet 範例 MNIST и 影像網.

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 個 GPU,叢集中總共有 16 個 GPU。 隨機梯度下降 (SGD) 優化器將與以下超參數一起使用:

  • 小批量大小:256
  • 學習率:0.1
  • 動量:0.9
  • 重量衰減:0.0001

當我們從一個GPU 擴展到64 個GPU 時,我們根據GPU 的數量線性縮放訓練速率(從0,1 個GPU 的1 到6,4 個GPU 的64),同時將每個GPU 的圖像數量保持在256 個(來自一批GPU)。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 和深度學習,請前往安裝頁面 MXNe首先建置 MXNet。 我們也強烈建議您閱讀這篇文章 60 分鐘內完成 MXNet開始。

如果您已經使用過 MXNet 並想嘗試使用 Horovod 進行分散式學習,那麼請查看 Horovod安裝頁面,從 MXNet 建置它並遵循範例 MNIST影像網.

*成本計算依據 每小時費率 適用於 EC2 執行個體的 AWS

了解有關課程的更多信息 “大數據上的工業機器學習”

來源: www.habr.com

添加評論