8
6

More than 5 years have passed since last update.

Azure Batch AI - Chainer MNをInfiniband / GPU付きノードで高速並列実行する!

Last updated at Posted at 2018-08-09

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とは?

qiitainfiniband.png

主に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を利用)とは異なる箇所があります。

  1. コンテナー:今回は開発チームが作成したInfiniband用のIntel MPIを使う準備をしているコンテナーを利用します。
  2. --comnunicator:Intel MPIはcuda awareでないため、non_cuda_awareオプションを利用します。
  3. 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>

結果をポータルから確認します。無事ジョブが終了しました!

image.png

リソースのお片付けも忘れずに!

前項と同じですが。。。

クラスターのノード関係

・クラスターのノード数を減らす(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

qiitaport.png

そしてそのIPとポート番号でSSHします。

qiitassh.png

Dockerが動いていることを確認し、中に入ります。

image.png

そして、Intel MPIのベンチマーク、pingpongをInfiniband上で流してみます。

image.png

ちなみに、Infinibandを使わないで同じベンチマークを流すと以下のようになります。

image.png

レイテンシーは数十倍、バンド幅も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

*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6