Skip to content

Instantly share code, notes, and snippets.

@keisukefukuda
Last active August 4, 2019 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keisukefukuda/a260d00c62c53811272ff83daf400dee to your computer and use it in GitHub Desktop.
Save keisukefukuda/a260d00c62c53811272ff83daf400dee to your computer and use it in GitHub Desktop.
How to run ChainerMN application on TSUBAME3

TSUBAME3上でのChainerMNアプリケーションの実行方法の説明

ChainerMNプログラムを分散環境で動かすには、動かしたいプログラムとデータに加えて、2つのファイルを用意します。

  • 動かしたいアプリケーションを起動するジョブスクリプト(ここでは例として以下のjob_mnist.sh)
  • 補助ファイル run.sh

ジョブスクリプトの内容は、走らせたいジョブの処理の内容に従って細かく変更を加えていきます。 補助ファイルは、最初に作成したあとは基本的に変更の必要はありません

まず、Chainerのインストールを行います。インタラクティブジョブを起動し、以下のコマンドを打ち込みます

xxxxx@login0:~> GROUP="自分のグループ名"
xxxxx@login0:~> qrsh -g $GROUP -l s_gpu=1 -l h_rt=1:00:00
xxxxx@r8i6n8:~> . /etc/profile.d/modules.sh
xxxxx@r8i6n8:~> module load python/3.6.5
xxxxx@r8i6n8:~> module load cuda/9.2.148
xxxxx@r8i6n8:~> module load openmpi/2.1.2-opa10.9
xxxxx@r8i6n8:~> pip install mpi4py cupy-cuda92==6.2.0 chainer==6.2.0
xxxxx@r8i6n8:~> python -c 'import chainer; chainer.print_runtime_info()'
Platform: Linux-4.4.121-92.85-default-x86_64-with-SuSE-12-x86_64
Chainer: 6.2.0
NumPy: 1.17.0
CuPy:
  CuPy Version          : 6.2.0
  CUDA Root             : /apps/t3/sles12sp2/cuda/9.2.148
  CUDA Build Version    : 9020
  CUDA Driver Version   : 10000
  CUDA Runtime Version  : 9020
  cuDNN Build Version   : 7402
  cuDNN Version         : 7402
  NCCL Build Version    : 2402
  NCCL Runtime Version  : 2402
iDeep: Not Available

注意事項

  • 環境は、特段の理由がない限り、CUDA 9.2, Open MPI 2.1.2 が推奨されます。
  • Chainerのバージョンは、6.2.0 を推奨します。また、明示的にインストールするバージョンを指定したほうが安全です
  • CuPYは、cupy-cuda92 というバイナリインストールを用いるのが推奨です。単にcupyと指定するとソースからのビルドになりますが、その場合、NCCLとCuDNNを自分でインストールしてした上でビルドする必要が出てきます。

次に、テストとしてMNISTを並列学習するジョブを投入してみます。以下の job_mnist.shrun.sh の2つのファイルを用意して、実行権限を付与します

xxxxx@login0:~> vi job_mnist.sh
xxxxx@login0:~> chmod +x job_mnist.sh

xxxxx@login0:~> vi run.sh
xxxxx@login0:~> chmod +x run.sh

ジョブを投入します。

xxxxx@login0:~> qrsh -g $GROUP -l s_gpu=4 -l h_rt=1:00:00 ./job_mnist.sh
Sat Aug  3 21:37:25 JST 2019
Platform: Linux-4.4.121-92.85-default-x86_64-with-SuSE-12-x86_64
Chainer: 6.2.0
NumPy: 1.17.0
CuPy:
  CuPy Version          : 6.2.0
  CUDA Root             : /apps/t3/sles12sp2/cuda/9.2.148
  CUDA Build Version    : 9020
  CUDA Driver Version   : 10000
  CUDA Runtime Version  : 9020
  cuDNN Build Version   : 7402
  cuDNN Version         : 7402
  NCCL Build Version    : 2402
  NCCL Runtime Version  : 2402
iDeep: Not Available
r1i7n6 2 all.q@r1i7n6 <NULL>
r2i3n1 2 all.q@r2i3n1 <NULL>
r8i6n8 2 all.q@r8i6n8 <NULL>
r2i4n8 2 all.q@r2i4n8 <NULL>
==========================================
Num process (COMM_WORLD): 4
Using GPUs
Using pure_nccl communicator
Num unit: 1000
Num Minibatch-size: 100
Num epoch: 2
==========================================
--------------------------------------------------------------------------
A process has executed an operation involving a call to the
"fork()" system call to create a child process.  Open MPI is currently
operating in a condition that could result in memory corruption or
other system errors; your job may hang, crash, or produce silent
data corruption.  The use of fork() (or system() or other calls that
create child processes) is strongly discouraged.

The process that invoked fork was:

  Local host:          [[19872,1],0] (PID 21643)

If you are *absolutely sure* that your application will successfully
and correctly survive a call to fork(), you may disable this warning
by setting the mpi_warn_on_fork MCA parameter to 0.
--------------------------------------------------------------------------
epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.289679    0.118232              0.915267       0.9628                    4.36749
2           0.0913869   0.0768252             0.972          0.9755                    5.81177

出力された結果を見て、正しく実行されたかどうか確認しましょう。

  • 冒頭に chainer.print_runtime_info() の結果が出力されているので、ライブラリが正しく読み込まれていることを確認します
  • -l s_gpu=4 という指定をしましたので、合計4プロセスで実行されます。 出力のNum process (COMM_WORLD): 4 と一致していることを確認します。
  • コミュニケーターとして pure_nccl communicator が使われていることを確認します
  • MNISTが正しく学習できていることを確認します (注: なお、MNISTは計算負荷が軽いので、複数GPU実行ではむしろ遅くなるケースが多いです)

以上でChainerMNプログラムを分散学習できました

#!/bin/sh
#$ -cwd
. /etc/profile.d/modules.sh
module load python/3.6.5
module load cuda/9.2.148
module load openmpi/2.1.2-opa10.9
# ジョブのはじめに、常にバージョン情報や日時等の情報を出力しておくのは良い習慣です
date
python -c 'import chainer; chainer.print_runtime_info()'
cat $PE_HOSTFILE
# OMP_NUM_THREADSは、OpenCVをChainerから(直接・間接的に)使う場合に性能に影響します。
# 特段の理由がなければ 1 にしておくのが無難です
export OMP_NUM_THREADS=1
# PPN: ノードあたりのプロセス数です。
# 使うキューによって変動します。Chainerを使う場合は、基本的にホストあたりのGPU数にします
# s_gpu のとき: 1
# f_node のとき: 4
export PPN=1
echo PPN=$PPN
# 総プロセス数を計算で求めます
NP=$(expr $PPN \* $NHOSTS)
echo NHOSTS=$NHOSTS
echo NP=$NP
# MNISTを実行します
# 1行目は、基本的には変更する必要はなく、2行目を自分のアプリケーションに従って変更します。
# コツ:
# * ChainerMNのコミュニケーターは、 pure_nccl を利用しましょう。
# * データの出力先となるディレクトリ名には、$JOB_ID をつけておくのがおすすめです
mpiexec -npernode $PPN -n $NP -x LD_LIBRARY_PATH $HOME/run.sh \
python train_mnist.py -g --communicator='pure_nccl' -e 2 -o result.$JOB_ID
#!/bin/sh
# 分散環境においてPythonスクリプトを実行するための補助ファイルです。
# これを $HOME/run.sh という名前で保存します
# (保存先とファイル名は任意ですが、変更する場合は job_mnist.sh の中のファイル名も変更してください)
. /etc/profile.d/modules.sh
module load python/3.6.5
module load cuda/9.2.148
module load openmpi/2.1.2-opa10.9
"$@"
@keisuke-umezawa
Copy link

pip install --user mpi4py cupy-cuda92==6.2.0 chainer==6.2.0

の必要がありそう。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment