文章作者:Rakshith Vasudev 和 John Lockman - HPC AI Innovation Lab,2019年 10 月
簡介
Horovod 是一種分散式深度學習架構,可加速如 Tensorflow、Keras、Pytorch 和 MXNet 等不同深度學習架構的訓練。此技術的開發目的為協助輕鬆建立分散式深度學習專案,並透過 TensorFlow 加快專案速度。Horovod 支援平行化的訓練程序。同時支援資料平行處理和模型平行處理。在執行使用 horovod 的神經網路訓練工作時,這些常見的秘訣可用來除錯與改進效能。
描述名稱
本文以 CheXNet 作為範例參考。CheXNet 是利用 DenseNet 的人工智慧放射師助理模型,可從提供的胸部 X 光影像中識別多達 14 種病理特性。
- 在嘗試偵錯效能問題時,正確的環境設定可節省大量的時間。請確定正在使用中的深度學習架構 GPU 版本。在此範例中,我們會使用 anaconda 的 tensorflow-gpu 封裝。
-
透過將 horovodrun 或 mpirun 搭配繫結參數使用,可改善效能。理想情況下,控制 GPU 的程序應繫結至最接近的 CPU 插槽。在 Dell EMC PowerEdge C4140 上,最佳選項是 --map-by socket。不需要指定其他繫結選項。
這看起來會類似:
mpirun --map-by socket -np x python pyfile.py - -pyoptions
- 工作應設定為在一個 GPU 上僅運作一個 MPI 程序。如果處理程序的數量多於 GPU,這些程序可能會爭搶運算資源,且無法以良好的效能執行工作。在上述範例中,x 應與使用的 GPU 數目相同。
-
若要設定在每個 GPU 上運行一個程序,請使用 tensorflow 的 ConfigProto(),如下所示:
config.gpu_options.visible_device_list=str(hvd.local_size())
-
若要檢查使用 GPU 的程序數量,以及 GPU 的記憶體消耗量,可以使用 watch nvidia-smi。這也能讓您查看耗電量。
圖 1:nvidia-smi 命令輸出的螢幕擷取畫面,顯示記憶體、電源和 GPU 使用率。
- 如果已正確設定資料管道,且 mpirun 參數正確,則當模型訓練開始時,GPU 使用率應會持續超過 90%。使用率偶爾降至 10-25% 是可接受的,但應不常發生。
- 設定批次大小,限制為幾乎填滿 GPU 記憶體,因此不會超出記憶體需求。請務必考慮學習速率擴充的實現方式。學習速率擴充是一個概念,隨著 GPU 數目增加,學習速率也必須以 GPU 的數量正比成倍增加。如此一來,模型即可有效融合。透過在 GPU 上配置可能出現的影像最大數量,即可減少 i/o 作業的數量,且不會影響機型融合效率。請注意,在嘗試改善分散式工作負荷設定的模型融合時,學習速率擴充並非一定是最佳的解決方案。
若要檢查是否需要學習速率擴充:
a) 在分散式訓練模式中嘗試使用與不使用不需學習速率擴充來訓練模型。
b) 如果不使用學習速率擴充的模型效能優於使用學習速率擴充的模型,便代表不需要學習速率擴充。
特別是在融合訓練時,不一定需要符合每批次可能出現的影像最大數量。資料科學家通常必須能根據使用案例,來判斷批次大小與融合 (無論是否使用學習速率擴充) 的取捨。
相同地,您也可以使用「watch nvidia-smi」查看 GPU 的記憶體耗用。 在本案例研究中並未使用學習速率擴充,因為在使用 AUC 值與 64 的本地最小批次大小時,能產生效能更高的模型。使用學習速率擴充時,通常會發生此白皮書所述的 epoch 暖機狀況。
-
使用 horovod timeline 和 nvprof 分析您的工作,以檢視可能遇到的瓶頸。 瓶頸很可能是下列其中一項所導致:
a) 未妥善設定 Tf 資料管道,導致加速器閒置時花費大量時間準備資料。若要解決此問題,必須修正 tf 管道。
請閱讀本文,以取得如何設定 tf 資料管道的資訊。
b) 通訊可能沒有使用正確的架構,請確認您使用的是 InfiniBand,若要檢查架構,請在執行 mpirun 時包含 –x NCCL_DEBUG=INFO,如下所示:
mpirun -np 8 --map-by socket -x NCCL_DEBUG=INFO python $HOME/models/chexnet/chexnet.py --batch_size=128 --epochs=15
或使用horovodrun,其中包含 –x binding。
- 若要妥善實作分散式方法,GPU 必須能有效地彼此溝通。如果通訊效率低落,就會造成通訊瓶頸。若要檢查 GPU 是否正在以最佳方式進行通訊,請使用以下程序:
首先,如本文 8b 所述,透過使用 -x binding 瞭解 GPU 的通訊方法
若 GPU 能彼此通訊:
1) 在節點內的最佳方式看起來會類似於:
gpu002:1299562:1299573 [0] NCCL INFO Ring 00 : 0[0] -> 1[1] via P2P/IPC
2) 在節點外的最佳方式看起來會類似於:
gpu028:149460:149495 [0] NCCL INFO Ring 01 : 16 -> 0 [send] via NET/IB/0
gpu009:164181:164216 [0] NCCL INFO Ring 01 : 12 -> 8 [receive] via NET/IB/0
gpu009:164181:164216 [0] NCCL INFO Ring 01 : 4 -> 8 [receive] via NET/IB/0
分散化深度學習工作有時可能很困難,特別是當使用的節點/GPU 數量無法有效地轉化成對應的效能時。為確保能透過加速器的投資獲得最大效益,請務必實作下列最佳實務:
- 已使用正確的繫結選項,
- 評估多程序是否不會浪費 GPU 的記憶體,
- 使用現代的管道方法,
- 分析以瞭解在工作執行時,GPU 是否至少有 80% 的時間在使用中,
- 使用最新的 CUDA 相關程式庫