Dynamic Trainingが発表されました #reinvent

re:Invent 2018におけるMonday Night LiveでDynamic Trainingが発表されました!

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、大阪DI部の大澤です。

現在開催中のre:Invent 2018におけるMonday Night Liveで Dynamic Training が発表されました!

※2018/11/28に実際に試した内容を追記しました。

概要

Dynamic TrainingはEC2上におけるディープラーニングのためのOSSです。Dynamic Trainingを利用することで、モデルの学習中に学習用インスタンス(Worker)を増減させることが出来ます。

  • 対応フレームワーク: Apache MXNet
  • EC2 リザーブドインスタンスとEC2 オンデマンドインスタンスに対応

特にリザーブドインスタンスに対して有用でAWSの公式ブログでは次のように述べられています。

DT enables practitioners to better utilize their organization’s pool of Amazon EC2 Reserved Instances. Practitioners can pull Reserved Instances into the training job when available, and release instances back to the Reserved Instances pool when instances are required for other, more critical applications, all while allowing the training job to continue without interruption. The following diagram shows the DT process using the Reserved Instances pool.

ジョブやアプリケーションの重要度に応じて、リザーブドインスタンスを柔軟に使い分けることが出来ます。また、モデルの学習ジョブのWorkerインスタンスを増減させることによって、学習ジョブが中断されることもありません!非常に便利です。

Dynamic Training はOSSであり、既に以下のリポジトリで公開されています。

リポジトリ内にはDynamic Trainingを試せるCloudFormationのテンプレートとやり方も書かれています。その説明に従うことで試すことが出来るようです。

やってみる

dynamic-training-with-apache-mxnet-on-awsリポジトリにCloudFormationのテンプレートとやり方が載っているため、早速試してみたいと思います。
※東京リージョンではエラーが発生して上手くいかなかったため、今回はバージニア北部リージョンで試しました。

スタックの作成と分散学習の開始

CloudFormationのテンプレートからスタックを作成

Dynamic Trainingのリポジトリにテンプレートがあるので、それを元にスタックを作成します。

CloudFormationデザイナーでテンプレートを見てみるとこんな感じの構成です。

スタックを作成する際には幾つかのパラメータを設定する必要があります。

  • StackName: スタックの名前
  • EFSFileSystemId: 使用するEFSのID(空白のままにしていると、自動で作られる)
  • EnableElasticTraining: ElasticTrainingを有効化するかどうか(True)
  • ImageType: どのイメージを使うか(Ubuntu)
  • InstanceType: 使用するインスタンスタイプ
  • KeyName: 使用するssh-keyを選択
  • PrepareDataScriptPath: スクリプトの配置場所(今回はデフォルト値のままにする)
  • SSHLocation: マスターノードにアクセスするIPアドレス(自PCのIPアドレス)

あとは、必要に応じて項目を設定し、スタックを作成します。10分弱位でスタックの作成は完了します。

マスターノードにssh接続

設定と学習処理の開始を行うために、マスターノードのEC2インスタンスに接続が必要です。

ssh-add -K ~/your_key_file.pem
ssh -o ServerAliveInterval=60 -A ubuntu@IP_ADDRESS_OF_MASTER
マスターノードの見つけ方

スタックの作成が完了したら、 Resources タブの中から MasterAutoScalingGroup を見つけて、そのAutoScalingGroupの詳細を開きます。Instances タブを開いて一覧に表示されたインスタンスがマスターノードのEC2インスタンスです。

データ準備用スクリプトの配置

共有ボリュームとして使用するEFS上にprepare-data.pyを置いておくことで、workerは起動時にその処理を実行します。今回は画像分類用にCIFAR-10のデータセットを取得する処理をダウンロードし、共有ボリュームに配置します。

curl -o /myEFSvolume/prepare-data.py https://raw.githubusercontent.com/awslabs/dynamic-training-with-apache-mxnet-on-aws/master/prepare-data.py

※ダウンロードに失敗していた場合はworkerインスタンスを追加しようとするまで気づけないので、ダウンロードしたファイルの中身を確認することをお勧めします。

パスの追加

LD_LIBRARY_PATHcuda-9.2 のパスを追加します。

export LD_LIBRARY_PATH=/usr/local/cuda-9.2/lib64:$LD_LIBRARY_PATH

分散学習スクリプトの配置

分散学習用の処理が書かれたスクリプトを共有ボリュームへコピーします。今回は画像分類用のサンプルのスクリプトを使用します。

cp /home/ubuntu/.local/lib/python3.6/site-packages/mxnet/tools/launch.py /myEFSvolume

分散学習開始

では、画像分類用の分散学習を実行します。

まず、GPUの数を確認します。

echo $DEEPLEARNING_WORKER_GPU_COUNT

GPUの数が0であれば、下のスクリプトから --gpu パラメータを削除して実行します。GPUの数が1以上であれば下のスクリプトをそのまま実行します。

TRAINING_CMD="python /home/ubuntu/.local/lib/python3.6/site-packages/image-classification-example/train_cifar10.py --gpus $(seq -s , 0 1 $(($DEEPLEARNING_WORKER_GPU_COUNT - 1))) --network resnet --num-layers 50 --kv-store dist_device_sync"
/myEFSvolume/launch.py -n $DEEPLEARNING_WORKERS_COUNT -H $DEEPLEARNING_WORKERS_PATH --elastic-training-enabled True python /home/ubuntu/.local/lib/python3.6/site-packages/image-classification-example/train_cifar10.py --gpus $(seq -s , 0 1 $(($DEEPLEARNING_WORKER_GPU_COUNT - 1))) --network resnet --num-layers 50 --kv-store dist_device_sync

実行すると大量のログが出てくるんですが、以下のような内容が書かれていれば問題無いようです。

2018-11-16 22:46:47,496 INFO Created worker host file /myEFSvolume/host_worker
2018-11-16 22:46:47,518 INFO Created worker host log file /myEFSvolume/host_worker_log
2018-11-16 22:46:47,525 INFO Launching server node at ip: 10.0.0.25
2018-11-16 22:46:47,533 INFO Launching server node at ip: 10.0.1.207
2018-11-16 22:46:47,533 INFO Launching worker node at ip: 10.0.0.25
2018-11-16 22:46:47,536 INFO Launching worker node at ip: 10.0.1.207

今回学習させたモデルは50層のResNetのMXNet実装です。学習時のパラメータなどの詳細についてはリポジトリの説明をご参照ください。

ワーカーインスタンスの追加

stackename-aws-dl-cfn-worker-ec2-launch-templateという名前のEC2の起動テンプレートを元にインスタンスを作成するだけで、起動後にワーカーインスタンスとして自動的に登録されます。

起動直後はこのような感じでログが出てきます。

2018-11-28 03:57:43,357 INFO Prepare data success file /myEFSvolume/prepare_data_success_10.0.1.149 not found yet.

インスタンスの起動が完了し、初期化処理が終了すると、以下のようなログが出てワーカーインスタンスへの追加は完了となります。

2018-11-28 04:00:24,747 INFO Found prepare data success file:/myEFSvolume/prepare_data_success_10.0.1.149. Adding privateip:10.0.1.149 to current_valid_elastic_worker
2018-11-28 04:00:24,754 INFO Added host:10.0.1.149 to new worker host

ワーカーインスタンスの削除

まず、以下のようなタグを持ったインスタンスが削除可能なインスタンスです。

`tag:<STACK-NAME>-aws-dl-cfn-elastic-worker : All values`

※マスターノードと最初に起動したワーカーノードは削除できません。そもそもそれらのインスタンスにはタグが付いていませんが、誤って削除しないように気をつけましょう。

ワーカーインスタンスの削除も簡単で上のタグを消すだけです。

タグを削除すると、次のようなログが流れて自動的にワーカーインスタンスの登録が外れて、インスタンスが終了します。

2018-11-28 04:09:12,930 INFO Got removing tag for host:10.0.1.149 indtanceId:i-08899549f221a8655
2018-11-28 04:09:18,241 INFO Terminating instance Ids: i-08899549f221a8

さいごに

Dynamic Trainingはモデルの学習状態やリザーブドインスタンスの需要に応じて、柔軟に学習用インスタンスの数を変化させることができます! また、AWSの公式ブログによると、MXNet以外のフレームワークへの対応やスポットインスタンスへの対応などが予定されているそうです。今後の展開も楽しみです!

お読みくださりありがとうございました〜!