Azure Batch AI - AzureでGPU/マルチノードでディープラーニング計算を簡単に行う!(Chainer MN編)
https://qiita.com/YoshiakiOi/items/2f143e62bcf5d7daa8e9 に続いて、Batch AIを使っていきます。
今回はChainer MNのジョブを、AzureのInfiniband付き(もちろんGPUも!)ノードで並列実行していきます!
Batch AIとは?
前項参照。
https://qiita.com/YoshiakiOi/items/2f143e62bcf5d7daa8e9
ディープラーニングの学習を、オンデマンドでたくさんGPU付きノードを並べたクラスターを作成して、簡単に並列実行できるようにする、Microsoft Azureの1製品。
今回はInfinibandを利用して、より高速に実行できる環境を作っていきます。
Infinibandとは?
主にHPC (High Performance Computing、大量の計算資源を利用して、大量・高速なコンピューティングを行う分野)で利用される、低待機時間・広帯域な通信規格。
MPIをInfiniband経由で実行すると、ノード間通信が高速になり、ノードを並列に並べたときにスケールするようになります(もちろんコードによりますが)。
MicrosoftのAzureでは、クラウドから一部の仮想マシンでInfinibandを利用することができます。
注意点
AzureでMPIからInfinibandを利用するには、2018年現在、Intel MPI、Platform MPI、MS MPIを利用する必要があります。本稿では、Intel MPIを利用して、Chainer MNを実行します。
(参考)
[Azure Antenna] HPCだけじゃないDeep Learningでも使える ハイパフォーマンスAzureインフラ ~ HPC and Deep Learning on Azure ~
https://www.slideshare.net/ShuichiGojuki/hpc-on-azure21
Chainer MN on Azure GPU/Infiniband Nodes
Batch AI上ではありませんが、Chainer MNをAzureのGPU/Infinibandノードで実行すると、ノード数を増やしてもスケールする(ノードを増やした分だけ線形的に実行時間が短くなる)ことが、発表されています。
####(参考)
de:code 2018 Online AI05 AI ChainerMN on Microsoft Azure で大規模分散深層学習
https://info.microsoft.com/JA-CNTNT-eBook-decode18Online-MGC0002650_01Registration-ForminBody.html
Batch AIは、Azureの上記のような高性能なインフラをなるべく簡単にディープラーニングに利用するためのPaaS型のコンピューティングソリューションです。
Batch AIでInfinibandを利用して、Chainer MNのMNISTジョブを実行する
ここからは、以下のマイクロソフト社のBatch AI開発チームが作成しているGithubレポジトリを参考に、ジョブを実行していきます。前稿と同じく、AzureポータルのCloud Shellから実行します。
途中までは前回と同じ作業になります。
リソースグループとワークスペースの作成
az group create -n batchai.recipes -l eastus
az batchai workspace create -g batchai.recipes -n recipe_workspace -l eastus
*各コマンド(az batchai ***)の詳細なオプションの説明
https://docs.microsoft.com/en-us/cli/azure/batchai?view=azure-cli-latest
ストレージの準備
*データやアウトプット先をAzure Filesにしてしまうと、せっかくInfinibandで高速化してもストレージがネックになってしまうので、BlobまたはNFSなど別のオプションにしましょう。
こちらも前回と同じように準備します。ただし、今回は後から使うjobprep.shというスクリプトをtrain_mnist.pyと一緒にダウンロード、アップロードしておきます。
az storage account create -n <storage account name> --sku Standard_LRS -g batchai.recipes -l eastus
az storage container create -n scripts --account-name <storage account name>
az storage container create -n result --account-name <storage account name>
az storage share create -n logs --account-name <storage account name>
wget https://raw.githubusercontent.com/chainer/chainermn/v1.3.0/examples/mnist/train_mnist.py
wget https://raw.githubusercontent.com/Azure/BatchAI/master/recipes/Chainer/Chainer-GPU-Distributed-Infiniband/jobprep.sh
az storage blob upload -f train_mnist.py -n chainer/train_mnist.py --account-name <storage account name> --container scripts
az storage blob upload -f jobprep.sh -n chainer/jobprep.sh --account-name <storage account name> --container scripts
クラスターの作成とジョブの投入
クラスターの作成も流れは前回と同じですが、今回はInfinibandが付いているNC24Rシリーズを選択します。(Azureでは、仮想マシンのシリーズ名の最後にRが付いているものがInfiniband付きになります。今回はTesla K80が4枚載った、Infiniband付きシリーズのNC24Rにしていますが、例えばP100/V100のNC24R v2/v3)を利用することでより高速に実行できます。
注意点
Batch AIのデフォルトのクオータ(リソース制限)ではNCシリーズの仮想コアの上限値は24コアのため、NC24Rを2台(48仮想コア)並べようとするとエラーになります。サポートリクエストを上げて、クオータを上げて貰う必要があります。
クラスターを作成します。
az batchai cluster create -n nc24r -g batchai.recipes -w recipe_workspace -s Standard_NC24r -t 2 --generate-ssh-keys
前回と同じく、ジョブ管理の箱であるExperimentを作成します。
az batchai experiment create -g batchai.recipes -w recipe_workspace -n chainer_experiment
次にカレントディレクトリにjob.jsonを以下のように作成します。いくつか前回(OpenMPIを利用)とは異なる箇所があります。
- コンテナー:今回は開発チームが作成したInfiniband用のIntel MPIを使う準備をしているコンテナーを利用します。
- --comnunicator:Intel MPIはcuda awareでないため、non_cuda_awareオプションを利用します。
- jobPreparationオプション:jobPraparationはコンテナー内で、コード(ここではtrain_mnist.py)を実行する前に流すスクリプトを設定するオプションです。ここでは、jobprep.shを流し、Intel MPIをインストールしています。
< >
は適宜変更してください。
{
"$schema": "https://raw.githubusercontent.com/Azure/BatchAI/master/schemas/2018-05-01/job.json",
"properties": {
"nodeCount": 2,
"chainerSettings": {
"pythonScriptFilePath": "$AZ_BATCHAI_JOB_MOUNT_ROOT/scripts/chainer/train_mnist.py",
"commandLineArgs": "-g --communicator non_cuda_aware -o $AZ_BATCHAI_OUTPUT_MODEL",
"processCount": 8
},
"jobPreparation": {
"commandLine": "bash $AZ_BATCHAI_JOB_MOUNT_ROOT/scripts/chainer/jobprep.sh"
},
"stdOutErrPathPrefix": "$AZ_BATCHAI_JOB_MOUNT_ROOT/logs",
"mountVolumes": {
"azureFileShares": [
{
"azureFileUrl": "https://<AZURE_BATCHAI_STORAGE_ACCOUNT>.file.core.windows.net/logs",
"relativeMountPath": "logs"
}
],
"azureBlobFileSystems" :[
{
"accountName": "<Storage Account Name>",
"containerName": "scripts",
"credentials": {
"accountKey": "<Storage Account Key>"
},
"relativeMountPath": "scripts"
},
{
"accountName": "<Storage Account Name>",
"containerName":"result",
"credentials": {
"accountKey": "<Storage Account Key>"
},
"relativeMountPath": "result"
}
]
},
"outputDirectories": [{
"id": "MODEL",
"pathPrefix": "$AZ_BATCHAI_JOB_MOUNT_ROOT/result"
}],
"containerSettings": {
"imageSourceRegistry": {
"image": "batchaitraining/chainermn:IntelMPI"
}
}
}
}
あとは、前回と同じくジョブを実行します。
az batchai job create -n distributed_chainer_ib -c nc24r -g batchai.recipes -w recipe_workspace -e chainer_experiment -f job.json --storage-account-name <storage account name>
結果をポータルから確認します。無事ジョブが終了しました!
リソースのお片付けも忘れずに!
前項と同じですが。。。
クラスターのノード関係
・クラスターのノード数を減らす(0ノードにする)
az batchai cluster resize -n nc6 -g batchai.recipes -w recipe_workspace -t 0
・クラスターを削除する
az batchai cluster delete -n nc6 -g batchai.recipes -w recipe_workspace
・クラスターを自動スケールする(最小0ノード、最大10ノードの例)
az batchai cluster auto-scale -n nc6 -g batchai.recipes -w recipe_workspace --min 0 --max 10
####リソースグループごと削除する
すべて削除する場合は、リソースグループごと削除します。
az group delete -n batchai.recipes -y
(おまけ)Intel MPIのベンチマークをノードに入って実行してみます!
実際にBatch AIのノードに入って、コンテナー上からIntel MPIのベンチマークを実行してみます。
補足:Batch AIのネットワークについて
Azureの仮想マシンは、すべて仮想ネットワークという閉じたネットワークに属すようデプロイされます。Batch AIは仮想マシン(仮想マシンスケールセット)がデプロイされる部分が隠蔽されていますが、このことには変わりはありません。ユーザーが作成した仮想ネットワーク(正確にはサブネット)にBatch AIのクラスターをデプロイすることもできますが、通常は10.0.0.0/*の仮想ネットワーク(サブネット)にデプロイされ、10.0.0.4から順番にプライベートIPが割り振られます。そしてDockerは--net=hostで起動されているため、ホストのネットワークインターフェースを共有します。
また、外部からアクセスする際は、パブリックIPを持ったロードバランサー経由(ポート転送)でSSHでアクセスすることになります。
SSHで外部からアクセスするために、ロードバランサーのIPアドレスとポート転送しているポートを調べます。
az batchai cluster node list -c nc24r -g batchai.recipes -w recipe_workspace
そしてそのIPとポート番号でSSHします。
Dockerが動いていることを確認し、中に入ります。
そして、Intel MPIのベンチマーク、pingpongをInfiniband上で流してみます。
ちなみに、Infinibandを使わないで同じベンチマークを流すと以下のようになります。
レイテンシーは数十倍、バンド幅も10倍以上変わってくるのが見えますね。
今回はMNISTでかつ2ノードなので、Open MPI版と大きく結果が変わらないかもしれませんが、ノード数が増え、かつ通信量が大きくなるようなジョブの場合、速度が全く変わってきます。
以上、今回はChainer MNをBatch AIを使って、簡単にInfinibandとGPUを使って高速・並列に実行してみました。
参考資料
(公式)Azure Document
https://docs.microsoft.com/ja-jp/azure/batch-ai/
(公式)Github Batch AI
https://github.com/Azure/BatchAI
*ドキュメントよりもGithubのほうが内容が充実しており、各フレームワークのレシピ(例)が揃っています。
(手前味噌ですが)Deep Learning Lab MeetUp (2018年6月27日) 学習編資料
https://www.slideshare.net/ssuser147cbc/deep-learning-lab-meetup-azurebatch-ai
*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。