HorovodRunner:Horovodによる分散ディープラーニング
Horovod と HorovodRunner は非推奨になりました。 15.4 LTS ML より後のリリースには、このパッケージはプリインストールされません。 分散ディープラーニングの場合、Databricks では、PyTorch による分散トレーニングに TorchDistributor を使用するか、TensorFlow による分散トレーニングに tf.distribute.Strategy
API を使用することをお勧めします。
HorovodRunner を使用して機械学習モデルの分散トレーニングを実行し、Databricks で Horovod トレーニング ジョブを Spark ジョブとして起動する方法について説明します。
HorovodRunnerとは何ですか?
HorovodRunner は、 Horovod フレームワークを使用して Databricks 上で分散ディープラーニングワークロードを実行するための汎用 API です。 Horovod を Spark の バリアモードと統合することで、Databricks は Spark で長時間実行されるディープラーニングトレーニングジョブの安定性を高めることができます。 HorovodRunnerは、Python フックを持つディープラーニング トレーニング コードを含むHorovod メソッドを取ります。HorovodRunner は、メソッドをドライバーにピクルス化し、Spark ワーカーに配布します。 Horovod MPI ジョブは、バリア実行モードを使用して Spark ジョブとして埋め込まれます。 最初のエグゼキューターは、BarrierTaskContext
を使用してすべてのタスクエグゼキューターのIPアドレスを収集し、mpirun
を使用して Horovod ジョブをトリガーします。 各Python MPIプロセスは、pickle化されたユーザープログラムをロードし、逆シリアル化して実行します。
HorovodRunner による分散トレーニング
HorovodRunner を使用すると、Horovod トレーニング ジョブを Spark ジョブとして起動できます。 HorovodRunner API は、表に示されているメソッドをサポートしています。 詳細については、 HorovodRunner API のドキュメントを参照してください。
メソッドとシグネチャー | 説明 |
---|---|
| HorovodRunnerのインスタンスを作成します。 |
** |
|
HorovodRunner を使用して分散トレーニング プログラムを開発する一般的なアプローチは次のとおりです。
- ノード数で初期化された
HorovodRunner
インスタンスを作成します。 - Horovod の使用方法で説明されている方法に従って Horovod トレーニング方法を定義し、メソッド内にインポートステートメントを追加してください。
- トレーニング方法を
HorovodRunner
インスタンスに渡します。
例えば:
hr = HorovodRunner(np=2)
def train():
import tensorflow as tf
hvd.init()
hr.run(train)
ドライバーで HorovodRunner を n
サブプロセスのみで実行するには、 hr = HorovodRunner(np=-n)
を使用します。 たとえば、ドライバー ノードに 4 つの GPU がある場合、最大 4``n
を選択できます。パラメーター np
の詳細については、 HorovodRunner API のドキュメントを参照してください。 サブプロセスごとに 1 つの GPU をピン留めする方法の詳細については、 Horovod 使用ガイドを参照してください。
よくあるエラーは、TensorFlow オブジェクトが見つからない、またはピクルス化できないというものです。 これは、ライブラリのインポートステートメントが他のエグゼキューターに配布されていない場合に発生します。 この問題を回避するには、すべてのインポートステートメント ( import tensorflow as tf
など) を Horovod トレーニングメソッドの先頭と、Horovod トレーニングメソッドで呼び出される他のユーザー定義関数 の両方に 含めます。
Horovod TimelineでHorovodのトレーニングを録画
Horovodには、 Horovod Timelineと呼ばれる、その活動のタイムラインを記録する機能があります。
Horovod Timeline は、パフォーマンスに大きな影響を与えます。 Inception3 のスループットは、Horovod Timeline を有効にすると ~40% 低下する可能性があります。 HorovodRunner ジョブを高速化するには、Horovod Timeline を使用しないでください。
トレーニングの進行中は、Horovodタイムラインを表示することはできません。
Horovod Timeline を記録するには、 HOROVOD_TIMELINE
環境変数をタイムライン ファイルを保存する場所に設定します。 Databricks では、タイムライン ファイルを簡単に取得できるように、共有ストレージ上の場所を使用することをお勧めします。 たとえば、次のようにDBFSローカル ファイル APIsを使用できます。
timeline_dir = "/dbfs/ml/horovod-timeline/%s" % uuid.uuid4()
os.makedirs(timeline_dir)
os.environ['HOROVOD_TIMELINE'] = timeline_dir + "/horovod_timeline.json"
hr = HorovodRunner(np=4)
hr.run(run_training_horovod, params=params)
次に、トレーニング関数の先頭と末尾にタイムライン固有のコードを追加します。 次のサンプル ノートブックには、トレーニングの進行状況を表示するための回避策として使用できるサンプル コードが含まれています。
Horovodタイムラインサンプルノートブック
タイムライン ファイルをダウンロードするには、 Databricks CLI を使用し、Chrome ブラウザーの chrome://tracing
機能を使用して表示します。 例えば:
開発ワークフロー
これらは、単一ノードのディープラーニング コードを分散トレーニングに移行するための一般的な手順です。 このセクションの「例: HorovodRunnerを使用して分散ディープラーニングに移行する」では、これらの手順を説明しています。
-
単一ノードコードを準備します。 TensorFlow、Keras、または PyTorch を使用してシングルノードコードを準備してテストします。
-
HorovodRunnerへの移行: 「Horovod の使用法」の指示に従って、 Horovod を使用してコードを移行し、ドライバーでテストします。
- Horovodを初期化するための
hvd.init()
を追加します。 - このプロセスで使用するサーバー GPU を
config.gpu_options.visible_device_list
を使用してピン留めします。 プロセスごとに 1 つの GPU の一般的なセットアップでは、これをローカル ランクに設定できます。 その場合、サーバー上の最初のプロセスに最初のGPUが割り当てられ、2番目のプロセスには2番目のGPUが割り当てられます。 - データセットのシャードを含めます。 このデータセット演算子は、各ワーカーが一意のサブセットを読み取ることができるため、分散トレーニングを実行するときに非常に便利です。
- ワーカーの数によって学習率をスケーリングします。 同期分散トレーニングの有効なバッチ サイズは、ワーカーの数によってスケーリングされます。 学習率を上げると、バッチサイズの増加が補われます。
- オプティマイザを
hvd.DistributedOptimizer
で包みます。 分散オプティマイザは、勾配計算を元のオプティマイザに委任し、allreduce または allgather を使用して勾配を平均化し、平均化された勾配を適用します。 hvd.BroadcastGlobalVariablesHook(0)
を追加して、ランク 0 から他のすべてのプロセスに初期変数の状態をブロードキャストします。これは、トレーニングがランダムな重みで開始されるとき、またはチェックポイントから復元されるときに、すべてのワーカーの一貫した初期化を確保するために必要です。 または、MonitoredTrainingSession
を使用していない場合は、グローバル変数が初期化された後にhvd.broadcast_global_variables
操作を実行できます。- チェックポイントをワーカー 0 にのみ保存するようにコードを変更して、他のワーカーがチェックポイントを破損しないようにします。
- Horovodを初期化するための
-
HorovodRunnerへの移行: HorovodRunner は、Python 関数を呼び出すことによって Horovod トレーニングジョブを実行します。 メインのトレーニング手順を 1 つの Python 関数にラップする必要があります。 その後、HorovodRunner をローカル モードと分散モードでテストできます。
ディープラーニングライブラリを更新する
TensorFlow、Keras、または PyTorch をアップグレードまたはダウングレードする場合は、新しくインストールしたライブラリに対してコンパイルされるように Horovod を再インストールする必要があります。 たとえば、TensorFlowをアップグレードする場合、DatabricksTensorFlowのインストール手順のinitスクリプトを使用し、その末尾に次のTensorFlow固有のHorovodインストールコードを追加することをお勧めします。Horovodのインストール手順を参照して、PyTorchやその他のライブラリのアップグレードやダウングレードなど、さまざまな組み合わせで作業します。
add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt update
# Using the same compiler that TensorFlow was built to compile Horovod
apt install g++-7 -y
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60
HOROVOD_GPU_ALLREDUCE=NCCL HOROVOD_CUDA_HOME=/usr/local/cuda pip install horovod==0.18.1 --force-reinstall --no-deps --no-cache-dir
例: HorovodRunner を使用した分散型ディープラーニングへの移行
次の例は、 MNIST データセットに基づいており、単一ノードのディープラーニング プログラムを HorovodRunnerを使用して分散ディープラーニングに移行する方法を示しています。
制限
- ワークスペース ファイルを操作する場合、
np
が 1 より大きい値に設定され、ノートブックが他の相対ファイルからインポートされると、HorovodRunner は機能しません。HorovodRunner
の代わりに Horovod.spark を使用することを検討してください。 WARNING: Open MPI accepted a TCP connection from what appears to be a another Open MPI process but cannot find a corresponding process entry for that peer
のようなエラーが発生した場合は、クラスター内のノード間のネットワーク通信に問題があることを示しています。このエラーを解決するには、トレーニング コードに次のスニペットを追加して、プライマリ ネットワーク インターフェイスを使用します。
import os
os.environ["OMPI_MCA_btl_tcp_if_include"]="eth0"
os.environ["NCCL_SOCKET_IFNAME"]="eth0"