本当は怖い情報科学

とあるHPC屋の趣味&実益ブログ

ChainerMN入門以前

この記事は,Chainer Advent Calendar 2017の13日目の記事です.

ChainerMNの入門については別途記事を書こうかと思っていますが, 今回は「入門以前」について書いてみたいと思います.誰が/何を目的としてChainerMNを導入すべきか, 導入に際して何が必要で/何に注意する必要があるか,などです.

ChainerMNとは

ChainerMNは,複数のGPU(もしくは計算機)を活用して,時間のかかる 深層学習の学習プロセスを高速化するためのChainerの追加パッケージです. 複数のGPU,複数の計算機というのは,主にネットワークで接続された 複数の計算機を指します.

なお,必ずしも1台の計算機であっても,内部で複数のプロセスを走らせることによって ChainerMNを使用することも可能です.

単に多数のGPUを同時に使うというだけなら,複数の異なるパラメーターでの 実験を同時に走らせること(パラメーターサーベイ)でも達成できます. ChainerMNは,パラメーターサーベイと何が違うのでしょうか?

パラメーターサーベイの場合,実験の結果が出るまでの時間(Time to solution)は1GPUの時と変わりません. もし,並行して試した多数のパラメーターが不要なものであったことがわかったら, 大きなGPU時間が無駄になってしまいます. また,ベイズ最適化など,実験の結果を見ながらハイパーパラメーターを徐々に最適化していく プロセスでは,パラメーターサーベイのようなやり方でGPUを多数同時に使うことは できません.

それに対し,ChainerMNでは,1つあたりの実験の時間を短くできるので, 1つ1つの実験の結果を見ながらパラメータを探索していくことができます. これにより,GPU時間をムダにすることなく多数のGPUを使って 研究開発時間を短縮できます.

注意事項

ChainerMNを使う上での注意事項は,大きくわけて2つあります.

第1点:速度を速くするには速いネットワークが必要

1つ目の重要な点は,適切なハードウェアを使うということです. 端的に言ってしまえば,ChainerMNで実験を効果的に高速化するためには 高速なネットワークを使う必要があります. 理想的には,Infinibandというスパコンで用いられるネットワークを用いることが 推奨されます.実際,Preferred Networkがブログで公開している実験では, Infiniband FDRという,1レーンあたり56Gbpsの速度を出せるネットワークを用いています.

現在のChainerMNは「データ並列・同期型」というアプローチを採用しているため, 通信が遅いと,全体の計算時間がそれに引っ張られて遅くなってしまいます. 最悪の場合,「2台のマシンで4GPUにしたのに,1台のマシンで2GPUのときより 遅くなった」ということになってしまいます.

現在一般に用いられているEthernetだと,データセンターでは10Gbps,家庭用だと 下手をすると1Gbpsのものもあります.このようなネットワークの場合, ダブルバッファリングや通信圧縮などのような技術を用いて,通信のボトルネックを 回避する工夫が必要になります.

現状 AWSのp3インスタンスでは,25Gbps Ethernetが提供されています. これであれば,10Gbps Ethernetよりは高速な通信が期待できます. しかし,ノード内ではNVLINKによるGPU間通信が提供されているため, 通常のChainerMNの使い方ではその利点を最大限に活かすことはできない可能性があります.

もし,近い将来に高速なネットワークを用いた複数台構成のクラスタの導入予定が ないのであれば,あえてChainerMNを用いずに,MultiprocessParallelUpdaterを用いるのも 1つの手です.

2点目:Large batchによる精度低下に注意する

データ同期型の並列化によって分散計算をするということは, いわゆるミニバッチサイズを大きくすることに相当します.一般的には, バッチサイズは大きすぎず小さすぎずが良いとされ,大きすぎるバッチサイズは 学習モデルの精度低下を招くとされています.

よって,自分のモデルがバッチサイズの増加に対してどのような振る舞いをするのかを 注意深く観察し,どの程度の精度低下が起こり,それがどの程度許容されるのかを 考えておく必要があります.

場合によっては,様々な論文で提供されている精度低下を防ぐテクニック()を 用いる必要があるかもしれません.

まとめ

・ChainerMNは,データ並列・同期型の並列・分散計算を提供するChainerの追加パッケージです ・ChainerMNの性能を引き出すには,GPUに加えて高速なネットワークが必要です(投資が必要です) ・場合によってはMultiprocessParallelUpdaterで十分な場合もあります ・Large Batchの罠に注意しましょう

ありがとうございました!

Travis CIのテストをローカルで走らせる

Travis CIは、Githubリポジトリにあるコードの継続的インテグレーションをサポートしてくれるツールです。 公開リポジトリであれば無料で利用できるため、プロジェクトで利用されていると思います。

.travis.yml というファイルをリポジトリに置くことによって Travis CIの挙動を制御することができますが、テスト動作をテストするためにはリポジトリへ push を行う必要があるため、 細かい挙動の調整を繰り返し行うのは時間のかかる作業です。

そこで、loci というソフトウェアを使って、ローカルにセットアップしたVagrantとDockerを使って Travis CIの挙動をローカルで再現する環境を作ってみました。

全体の構成

今回は、私の作業環境であるMacbook上での作業です。その上にVagrantを使ってUbuntuの仮想環境を構築し、その仮想環境の中でさらにDockerを動かしてTravis相当のCIを走らせます。

VagrantとDockerを設定する

まず、Virtualboxを用いてVagrant環境を構築します。Virtualbox, Vagrantが何かということと、それらのインストール方法は他に譲ります。

まず、Travis CIのコンテナ環境と同じUbuntu Trustyのboxイメージをダウンロードしてきます。適当な場所に作業ディレクトリを作って作業します

$ vagrant box add travis https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box

次に、その boxを使って仮想マシンを作成します

$ vagrant init ubuntu/trusty64

# Vagrantの仮想マシンにログイン
$ vagrant ssh

Go言語とLociの導入

作成した仮想マシン上にGo言語の環境を構築してからLockをインストールします。Go言語の1.7以降が必要ですが、Ubuntuのパッケージに含まれているのは古いバージョンなので、手動で導入することにします。下記のWebサイトに従ってインストールを行いました。

How to Install Go 1.8 on Ubuntu 16.04 & 14.04 | TecAdmin

ここでは、Go言語自体のインストールパスを GOROOT 、goプログラムのパスを GOPATHとしています。

次に、仮想マシン上にLociをインストールします。これは、githubの説明に従って go get を走らせるだけです。

$ go get github.com/jkawamoto/lock

動作を確認しておきましょう。

$ ${GOPATH}/bin/lock --version
Loci version 0.5.2

Dockerの導入

UbuntuのパッケージにあるDockerではなく、Docker-CEを自分で導入します。

Get Docker CE for Ubuntu | Docker Documentation

起動用シェルスクリプトの構築

以下のように起動スクリプトを作成しました。VagrantをインストールしたディレクトリをVAGRANT_PATHとして、以下のように起動します。また、VAGRANT_PATHの1つ上のディレクトリがプロジェクトのディレクトリであることを仮定しています。

$ env VAGRANT_PATH=~/.mpienv/vagrant bash run-local-travis.sh

ポイントとしては、

  • vagrant sshでSSHの設定を取り出してSSH接続をおこなうこと
  • DOCKER_API_VERSION変数を設定すること
  • Dockerの構築に使うイメージをubuntu/trustyにすること(Lociのデフォルトだと Ubuntu 16を使おうとするので、パッケージ等がTravisと異なるためにエラーになるケースが有る)

といったあたりです。

gist.github.com

HPDC'17

HPDC'17が開催されています(私は参加していません)。

Programを眺めた感じ、個人的には以下の論文が面白そうです。

  • “CuMF_SGD: Parallelized Stochastic Gradient Descent for Matrix Factorization on GPUs” Xie, Tan, Fong, Liang
  • LetGo: A Lightweight Continuous Framework for HPC Applications Under Failures Fang, Guan, Debardeleben, Pattabiraman, Ripeanu
  • “Towards a More Complete Understanding of SDC Propagation” Calhoun, Snir, Olson, Gropp
  • “Diagnosing Machine Learning Pipelines with Fine-grained Lineage” Zhang, Sparks, Franklin
  • “COS: A Parallel Performance Model for Dynamic Variations in Processor Speed, Memory Speed, and Thread Concurrency” Li, Leon, Cameron
  • “Explaining Wide Area Data Transfer Performance” Liu, Balaprakash, Kettimuthu, Foster
  • “Machine and Application Aware Partitioning for Adaptive Mesh Refinement Applications” Fernando, Sundar, Duplyakin
【広告】