DNN推論用ライブラリ「Menoh」リリースについて

Shintarou Okada
エンジニア

2018-06-21 11:41:46

Python以外も使いたくないですか?  特にDeepLearning界隈で.

Menoh開発者の岡田です.この記事ではMenohの紹介と開発に至った動機について説明します.

Menohのレポジトリ: https://github.com/pfnet-research/menoh

Menoh(メノウ)は学習済みのDNNモデルをONNX形式から読み込んで動作させる推論専用のライブラリです.実装はC++で書きましたが,C言語のインターフェースを持たせて,他の言語用からもその機能を呼び出しやすくしてあります.リリース時点でC++版ラッパーとC#版ラッパー,Haskell版ラッパーがあり,Ruby版ラッパーとNodeJS版ラッパー,Java(JVM)版ラッパーが開発中です.バックエンドにはIntelの開発しているMKL-DNNを採用し,GPUが無くてもIntel CPUが使える環境で高速にモデルの推論が可能になっています.Menohを使えばChainerで学習したモデルをPython以外の言語で実装したアプリケーションに瞬時にデプロイすることが可能です.

ところでなぜDeepLearning界隈で覇権を握ったのがPythonであって,Rubyじゃなかったんでしょう? Rは? Perlは? C++は? プログラミング言語は数多くありますが,どの言語も今のPythonのように広くDL用学習フレームワークを記述するために利用される可能性はありました(もちろん言語ごとに用途の向き不向きがあって,可能性の大小はあったにせよ).我々の宇宙ではPythonが覇権を握りましたが,どこか別の宇宙ではLispが覇権を握ることもきっとあったでしょう.とは言え,我々は我々の宇宙に生きるしかなく,今日そのディープなんとかを実装するには甘美な()や{}やbeginendから離れて空虚なインデントでブロックを記述する必要があります.このことについて,なんと悲しいことかと手放しに言い切れれば良かったんですが,皆さんご存知の通り,Pythonは良い言語です.

そう,Pythonは良い言語です.豊富なライブラリ,特にNumpyが使えること,動的型付けであること,GC機能が搭載されていること――どれもがDNNを実装したり学習させたりするコードを試行錯誤しながら書くという作業をやりやすくしてくれます.もちろんChainerはPythonで記述されており,改造・拡張しやすいDNN学習フレームワークとなっています.ChainerはそのDefine-by-Runという魔法によってすばらしく使いやすい.このDefine-by-Runをもっと別の言語で実装することも出来たと思いますが,コードはより複雑に,その作業はもっと苦痛の伴うものになっていたでしょう.明らかにChainerの使い勝手の良さの一端はPythonという言語そのものが担っています.

我々にとって,DNNについて研究する作業というのは地獄ではありません.Pythonの使い勝手の良さに裏打ちされたChainerがあるからです.手軽にDNNモデルを記述して学習を回せる.素晴らしいことです.地獄なのは学習したDNNモデルをデプロイする作業です.

地獄というのは言いすぎかもしれません.Pythonがデプロイ先の環境で使えるならChainerをそのまま使えばよく,首尾貫徹して苦痛はどこにも(少なくともデプロイ作業には)ありません.でもPythonが使えない環境はどうでしょうか.研究室の外に出ると,セキュリティや計算資源的な問題などでPythonが使えない環境や,分野によっては別の言語が覇権を握っていてPythonではそこにある資産を利用できない状況というのは山ほどあります(例えば,Web界隈では今でもRubyに根強い人気があります).現在でもDLフレームワークの中には設計がデプロイまで意識されたものや,Pythonを使わずにCやC++などでDNNを記述できるものもありますが,大掛かりだったり,あまりに実装が剥き身すぎて使いづらかったりします.現状はDNNの学習については広く知見が行き渡っているのと比べて,まだまだDNNのデプロイについては発展途上であると言えます.

ただ学習したモデルを自分のアプリケーションに組み込みたいだけなのにそれがなかなか難しい.

以上が私がMenohの開発を始めた動機です.

MenohはPFNが社内で定められた20%ルールの下でのプロジェクトの成果です.20%ルールとは「PFNメンバーは公式にアサインされたタスクとは別に20%の時間を各自の好きなタスクやプロジェクトに充てても良い」というもので,Menohプロジェクト以外にも様々な個人やチームのプロジェクトや勉強会が進行しています.

MenohはChainer Advent Calendar 2017で開発した「Instant」というライブラリが元になっています.20%の時間を使って,Instantの機能を拡充していく中で,設計の助言をしてくれたり,他の言語のラッパーを書いてくれたりするメンバーが現れて,そうした自発的に協力してくれたメンバー達のお陰でInstantはMenohに名前を変えて実験的なプロダクトとしてpfn-researchにてリリースするに至りました.これからも20%の時間を使って開発は継続していく予定なので,ぜひ利用してもらって,バグや要望等あればどんどんIssueに投げていただければと思います.

オープンソースの深層学習フレームワーク Chainer アマゾン ウェブ サービスが公式にサポート

Shingo Omura

2018-06-01 12:02:14

深層学習フレームワークの Chainer は、アマゾン ウェブ サービス(AWS) の協力により、多数の AWS アプリケーションで利用できるようになりました。Chainerは、ニューラルネットワークを簡単に扱える Pythonのフレームワークですが、AWSと組み合わせる事で、マルチ GPU やマルチサーバーにおける Chainer の並外れたスケーリング能力を最大限活用できます。Chainer の非常に優れたスケーリング能力については、ImageNet-1K を利用した ResNet50 の学習を、それまで最速とされた Facebook の記録より4倍速い15分で完了した事により実証済みです。

Chainer のマルチ GPU とマルチサーバーのスケーリングにより、必要時に必要量の計算資源を提供するというクラウドの利点を有効活用できます。Chainer の比類なき並列計算能力と AWS のオンデマンド型クラウド資源を併用すれば、費用を最小限に抑えながら、ハードウェアの制約がある環境下と比べて、非常に短時間で複雑な深層学習モデルの学習が可能になります。

Chainer は、AWS 深層学習 AMI(AMI)ですでに利用可能となっていますが、Chainerが最新の CloudFormation スクリプトをリリースした事により、一度に複数のChainer AMIを容易にデプロイできるようになりました。また、ChainerはAWS上で32 GPUまでのスケーリング効率95%を達成する事を確認済みで、これはニューラルネットワークの学習を最大30倍高速化できる事を意味します。

データの前処理やハイパーパラメータの調整、ならびにニューラルネットワークのデプロイといった作業の簡素化を目的として、Chainer は Amazon SageMaker でもサポートされるようになりました。Amazon SageMaker は、開発者やデータサイエンティストが、機械学習モデルをあらゆる規模で、迅速かつ簡単に構築、トレーニング、デプロイできるようにする完全マネージド型プラットフォームです。SageMaker で Chainer を使用すれば、SageMaker が持つデプロイ上の利点に加え、並列化により速度が向上します。

上記に加えて、Chainer は AWS Greengrass でもサポートされるようになりました。AWS Greengrass は、接続されたデバイスでローカルのコンピューティング、メッセージング、データキャッシュ、同期、ML 推論機能を安全な方法で実行できるようにするソフトウェアです。Amazon SageMaker と組み合わせる事で、SageMaker でのモデル学習時や、AWS Greengrass でIoTデバイスへ直接デプロイする際に、Chainer の利便性とスピードを活用できます。

Chainer チームは AWS による今回のリリースを大変うれしく思うと同時に、進化し続ける深層学習技術のさらなる発展に貢献する事を目指します。

AWS CloudFormationを使ったChainerMNの実行

Shingo Omura

2018-06-01 11:58:13

※本記事はChainer Blogの日本語訳です。

AWS CloudFormationInfrastructure As Code の実践を助けてくれるAWSサービスで、幅広いAWSリソースを、宣言的に設定ファイルに記述し、その設定ファイルから、AWS上のインフラストラクチャを自動的に生成したり、再生成できます。それによってAWS上のインフラストラクチャを手作業を自動化できます。

分散深層学習向けのインフラストラクチャの構築の作業負荷も大幅に軽減できます。EC2インスタンスを起動したり、必要なライブラリをインストール・設定したり、計算/通信性能の最適化設定を行ったりする作業を軽減できます。特に、ChainerMNにおいては、MPIクラスタを構築することが必要です。AWS CloudFormationはこの構築作業を自動化することができます。

本日、Chainer/ChainermNがプリインストールされたAMIChainerMN向けのクラスタを自動的に構築するためのCloudFormationテンプレートを公開しました。

この記事では、これらの利用方法とともに、自動構築されたクラスタ上でのChainerMNの実行方法について説明します。

 

Chainer AMI

Chainer AMI には Chainer/CuPy/ChainerMN, ChianerCV, ChainerRLといったChainerライブラリ群と CUDA-aware OpenMPI ライブラリがプリインストールされていいます。そのため、このイメージを利用すればGPUを搭載したAWS EC2 インスタンス上で簡単に高速に深層学習が実行できます。このイメージはAWS Deep Learning Base AMIを基にビルドされています。

Chainer AMIの最新バージョンは0.1.0で、同梱されているライブラリ群のバージョンは次のとおりです:

  • OpenMPI 2.1.3
    • CUDA 9向けにのみビルドされています
  • Chainerライブラリ群 (python, python3 両方の環境にインストールされています)
    • CuPy 4.1.0
    • Chainer 4.1.0
    • ChainerMN 1.3.0
    • ChainerCV 0.9.0
    • ChainerRL 0.3.0

 

CloudFormation Template For ChainerMN

このテンプレートは Chainer AMI を使って ChainerMN クラスタを自動的にAWS上に構築します。構築されるインフラストラクチャの概要は下記のとおりです。

  • クラスタが配置される VPC と Subnet (既存のVPC/Subnetを設定可能)
  • MPIプロセス起動時に利用するephemeralなssh鍵をクラスタ内で共有するための S3 バケット
  • クラスタが配置されるプレイスメントグループ(ネットワークスループット/レイテンシを最適化するため)
  • ChainerMNクラスタ
    • 1 台の マスター EC2 インスタンス
    • N (>=0) 台のワーカーインスタンス(AutoScalingGroup経由で起動されます)
    • MPIジョブ実行用の chainer ユーザ
    • MPIジョブ実行用の hostfile
  • (オプション) Amazon Elastic Filesystem (既存のFilesystemを設定可能)
    • このファイルシステムは各インスタンスに自動的にマウントされれます
  • 各種Security Group および IAM Role

Chaainer CFNの最新バージョンは0.1.0です。詳細なリソース定義についてはリリースされているテンプレートを参照してください。

先日公開した ChainerMN 1.3.0のブログで述べられている通り(英語)ChainerMN 1.3.0 の新機能である、ダブルバッファリング、 半精度浮動小数点数による All-Reduce を使えば、Infinibandが利用できないAWSであっても、ほぼ線形のスケーラビリティを期待できます。

 

CloudFromationテンプレート を使った ChainerMNクラスタ構築

ここでは、CloudFromationテンプレートを使ってChainerMNクラスタを構築する方法をstep-by-stepで説明します。

まず、下記のリンクから CloudFormationのページを開いて「次へ」をクリックしてください。

launch stack

「詳細の指定」画面では、スタック名、VPC/Subnet、クラスタ、EFSといった各種設定を入力できます。下記は 4 台の p3.16xlargeインスタンス(8 NVIDIA Tesla V100 GPUs/インスタンス) によって構成される ChainerMNクラスタを構築する設定例です(VPC, Subnet, EFS等はすべて新規作成)。

最後の確認画面では、Capabilities セクションにある、IAM Roleに関する同意をチェックする必要があります。この CloudFormation テンプレートではクラスタ内インスタンスに割り当てるためのIAM Roleを作成するためです。

しばらして、CloudFormationスタックの状態が CREATE_COMPLETE に遷移したら、クラスタは構築完了です。 スタックの出力セクションの ClusterMasterPublicDNS にマスターインスタンスの Public DNS が表示されます。

 

構築済みクラスタでのChainerMN ジョブ実行

クラスタ内インスタンスには、CloudFormationテンプレートのパラメータに設定したキーペアでログインが可能です。

ssh -i keypair.pem ubuntu@ec2-ww-xxx-yy-zzz.compute-1.amazonaws.com

クラスタ内のインスタンスは前述の [Chainer AMI][ChainerAMI] をつかって起動しているので、必要なライブラリ群はすべてインストール済みです。あとは、自身の学習用のコードとデータをダウンロードするだけです。

# switch user to chainer
ubuntu@ip-ww-xxx-yy-zzz$ sudo su chainer

# download ChainerMN's train_mnist.py into EFS
chainer@ip-ww-xxx-yy-zzz$ wget \
  https://raw.githubusercontent.com/chainer/chainermn/v1.3.0/examples/mnist/train_mnist.py \
  -O /efs/train_mnist.py

これで実行準備完了です。mpiexecコマンドを使ってChainerMNをつかったMNISTの例を実行できます。

# 4インスタンス上で合計32プロセス(-nオプション)を起動(8 プロセス/インスタンス(-N オプション))
chainer@ip-ww-xxx-yy-zzz$ mpiexec -n 32 -N 8 python /efs/train_mnist.py -g
...(you will see ssh warning here)
==========================================
Num process (COMM_WORLD): 32
Using GPUs
Using hierarchical communicator
Num unit: 1000
Num Minibatch-size: 100
Num epoch: 20
==========================================
epoch main/loss validation/main/loss main/accuracy validation/main/accuracy elapsed_time
1 0.795527 0.316611 0.765263 0.907536 4.47915
...
19 0.00540187 0.0658256 0.999474 0.979351 14.7716
20 0.00463723 0.0668939 0.998889 0.978882 15.2248

# 注意: 上記実行例は2回めの実行例です。(初回実行時はサンプルデータのダウンロードが行われます)

 

 

ChainerMNのクラウド環境向け新機能とAWSにおける性能評価

Shuji Suzuki

2018-05-25 17:00:23

※この記事はChainer Blogの抄訳です

Chainer にマルチノードでの分散学習機能を追加するパッケージであるChainerMN に、ネットワークスループットが低いシステム向けの以下の2つの機能をv1.2.0とv1.3.0で追加しました。

  • Double bufferingによる通信時間の隠ぺい機能
  • 半精度浮動小数点数(FP16)によるAll-Reduce機能

ChainerMNは高速なネットワークを持つスーパーコンピュータやMicrosoft Azureのようなシステムを想定して開発してきたため、高速なネットワークのない環境では高い並列性能を達成するのが難しいという問題がありました。しかし、これらの機能を使うことで、GTC2018で発表したようにAmazon Web Services (AWS)のような一般的なシステムでもChainerMNによって高い並列性能を達成することができるようになりました。

 

背景

データ並列による分散深層学習においては、学習時間のうちノード毎に計算したgradientの和を計算するAll-Reduceにかかる時間が支配的になります。以前、我々が実施した1024 GPUを利用した大規模な学習では、スーパーコンピュータでも利用される高速なインターコネクトであるInfiniBandと高速なAll-Reduceを実現可能なNVIDIA Collective Communications Library (NCCL)を利用することで解決しました [1]。一方、AWSのような一般的なシステムはInfiniBandのような高速なインターコネクトがないため、通信に時間がかかってしまいます。この結果、ノード数を増やしても学習が速くならない場合がありました。これらを解決するためにChainerMN v1.2.0, v1.3.0でdouble bufferingによる通信時間の隠ぺい機能とFP16によるAll-Reduce機能の2つを追加しました。

 

Double bufferingによる通信時間の隠ぺい機能

この機能は、計算(foward, backward, optimize)と通信(All-Reduce)をオーバーラップすることで通信にかかる時間を隠ぺいし、全体の計算時間を短縮する機能です。通常のChainerMNの場合、1イテレーションは下図のように forward, backward, All-Reduce, optimize の 4 つのステップからなります。

一方、double bufferingによる通信時間の隠ぺい機能を使うと以下のように計算の部分と 通信の部分をオーバーラップすることができます。

この際、optimizeには一つ前のイテレーションのgradientを利用して行います。これにより、精度に影響がでる可能性が考えられます。しかし、後ほど示す実験の通り、ImageNetの学習の場合、実際はほとんど精度を低下させずに学習を行うことができます。

この機能は以下のようにマルチノード用のoptimizerを作成していた部分で、double_buffering=Trueとするだけで使用できます。

optimizer = chainermn.create_multi_node_optimizer(optimizer, comm, double_buffering=True)

現在、この機能はpure_ncclのcommunicatorにのみ対応しています。

FP16によるAll-Reduce機能

v1.2.0のChainerMNはFP32のAll-Reduceにのみ対応していましたが、v1.3.0ではFP16にも対応しました。これにより、FP16のモデルでもChainerMNを利用して分散学習を実行することができるようになりました。All-ReduceにFP16を用いた場合、FP32のときと比較して、通信量が半分になるため、All-Reduceの大幅な時間短縮を期待できます。

また、計算においてFP32を使っていても、All-ReduceだけはFP16を利用し、All-Reduceにかかる時間を短縮するということも同時にできるようになりました。これは我々が1024 GPUを利用したImageNetの学習で利用したテクニックです[1]。

FP16のモデルの場合は特に変更を加えなくても、FP16のAll-Reduceが利用されます。また、計算とAll-Reduceで違うデータタイプを使用したい場合は、以下のようにcommunicatorを作成する際に、allreduce_grad_dtype='float16'とすることで利用することができます。

comm = chainermn.create_communicator('pure_nccl', allreduce_grad_dtype='float16')

この機能も現在はpure_ncclのcommunicatorにのみ対応しています。

実験結果

2つの新機能により、高い並列性能を得られることを示すために、ImageNet の画像分類データセットを使って性能を測定しました。CNN のモデルとしては ResNet-50 を使いました。実験には、低速なネットワークとしてPFNのスーパーコンピュータであるMN-1の10 Gb Ethernetと、AWSを利用しています。詳しい実験の設定については記事末尾の付録をご覧ください。

10Gb Ethernetによる評価

下記の図では、MN-1を利用し、InfiniBand FDRと10 Gb Ethernetを使った場合、さらに10 Gb Ethernet上で2つの新機能を使った場合の3通りで、GPU 数を増やしたときのスループットを示しています。

この図に示す通り、10 Gb Ethernetを使った場合、GPU数が増えても性能が上がっていないことがわかります。一方、新機能を使った場合は、線形に性能向上が得られており、理想的な高速化が達成できています。また、下記の表に32GPUを使って90 epochまでの学習を5回実行した際の平均validation accuracyと平均学習時間を示します。

Validation Accuracy (%) 学習時間 (hour)
InfiniBand FDR 76.4 6.96
10 Gb Ethernet 76.4 21.3
10 Gb Ethernet + Double Buffering
+ FP16 Allreduce
75.8 7.71

精度に関しては、2つの新機能を使ってもほとんど影響が出ていないことがわかります。また、学習時間については10 Gb Ethernetと2つの新機能を使った場合には、InfiniBand FDRを使った場合に比べて11%しか計算時間が増加しませんでした。このことから、2つの新機能を使うことで、InfiniBand のような高速なネットワークを利用しなくても、精度を維持したまま高い並列性能を得られることがわかりました。

AWSによる評価

AWSの検証ではp3.16xlargeを利用しました。このインスタンスは最新のGPUであるV100を8個搭載しています。このインスタンスを利用してGPU 数を増やしたときのスループットを以下の図に示します。

どれだけ並列性能がでているかの指標として並列化効率が良く用いられます。今回の実験の場合、基準となるスループットを\(t_0\)、基準から\(n\)倍のGPUを使用したときのスループットを\(t\)とすると、並列化効率\(e\)は以下のように計算できます。
$$e = t/(t_0*n)$$
この並列化効率が1(100%)に近いほど高い並列性能を達成していることを示しています。

この実験においては、8GPUを基準とした32GPUを利用した場合の並列化効率は96%となり、新機能を使うことにより高い並列化性能を達成できることがわかります。

今後の展望

今後、ChainerMNは多くの学習モデルにおいてデータ並列では実現できない多様なモデルの並列化に対応するために、モデル並列をはじめとした機能や、耐障害性を向上するための機能を追加していく予定です。また、我々のチームではChainerMNの開発だけでなく, ChainerとCuPyを含めた高速化、P100を1024機搭載したMN-1やV100を512機搭載した次のクラスタを全台使うような大規模実験に関する研究開発を行っています。このような分野に興味のある方のご応募お待ちしております。

付録

性能測定の詳細について

実験設定

データセット:ImageNet-1k
モデル:ResNet-50 (入力画像サイズ 224×224)

スループット測定時の設定

バッチサイズ:64
学習率:固定
Data augmentation:Goyal et al. [2]と同じ手法を利用
最適化:Momentum SGD (momentum=0.9)
Weight decay: 0.0001
測定回数:400イテレーション

90エポックまで学習させたときの設定

バッチサイズ:30エポックまで各 GPU が 64、その後、128
学習率:5エポックまでGradual warmup、30 エポックのとき0.2 倍、60エポック、80エポックで0.1倍
Data augmentation:Goyal et al. [2]と同じ手法を利用
最適化:Momentum SGD (momentum=0.9)
Weight decay: 0.0001
エポック数:90 エポック
この設定は基本的にGoyal et al. [2]をベースに、Smith et al. [3]のテクニックを利用した設定になっています。

10Gb Ethernetによる検証に使用した実験環境

実験環境
最大4ノード、計 32 GPUs
ノード
GPU: 8 * NVIDIA Tesla P100 GPUs
CPU: 2 * Intel Xeon E5-2667 processors (3.20 GHz, 8 cores)
ネットワーク: InfiniBand FDR
学習データの保存先:ローカルディスク

AWSによる検証に使用した実験環境

実験環境
最大4ノード、計 32 GPUs
ノード(p3.16xlarge)
GPU: 8 * NVIDIA Tesla V100 GPUs
CPU: 64 vCPUs
ネットワーク: 25 Gbps のネットワーク
学習データの保存先:RAM disk

References

[1] Akiba, T., et al. Extremely Large Minibatch SGD: Training ResNet-50 on ImageNet in 15 Minutes. CoRR, abs/1711.04325, 2017.
[2] Goyal, P., et al. Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour. CoRR, abs/1706.02677, 2017.
[3] Smith, S. L., et al. Don’t Decay the Learning Rate, Increase the Batch Size. CoRR, abs/1711.00489, 2017.

Chainerの可視化・実験管理を支援するChainerUIを公開

ofk
エンジニア

2017-12-20 10:58:59

Chainer上の実験中の学習ログの可視化や実験管理機能を追加するパッケージ、ChainerUIを公開しました。

ChainerUIは、多くのChainerユーザが持つ「学習中の実験ジョブの進捗を手軽に知りたい」、「複数の実験ジョブの手軽に管理したい」ニーズに応えるために開発しました。
具体的には、下記の機能を備えています。

  • 学習ログの可視化
  • 実験履歴閲覧
  • 実行中の実験に対する操作 (スナップショット・学習ハイパーパラメーター修正)

本パッケージは、Chainerの学習用Trainerを監視するChainer extensionとして機能するものです。このChainer extensionを有効化した実験を、Webブラウザからリアルタイムで監視、制御することができます。複雑な依存関係がないため、Trainerを用いる既存の実験スクリプトに簡単に導入できます。

学習ログの可視化


Chainerで実験中のLossやAccuracy等の学習ログを、Webブラウザで可視化することができます。表示する項目は、ユーザが任意に指定できます。

実験管理機能


Chainerを使った複数の実験を1つの画面に一覧表示することができます。各実験には、実験条件を表示することができます。また、ブラウザ上から実行中の実験に対して、スナップショット保存の実行や、ハイパーパラメータの修正が可能です。

セットアップおよび実行

ChainerUIのインストール後、セットアップを行います。

pip install chainerui
chainerui db create
chainerui db upgrade

プロジェクトを登録しサーバーを実行後、Webブラウザでhttp://localhost:5000/にアクセスします。プロジェクトの登録はサーバー起動後にも行うことができます。

chainerui project create -d PROJECT_DIR [-n PROJECT_NAME]
chainerui server

学習ログの可視化

Chainer標準のLogReportが出力するlogファイルを監視し、実験中の学習ログを表示します。下記はtrain_mnist.pyを使用した場合の実行例です。

chainerui project create -d path/to/result -n mnist
python train_mnist.py -o path/to/result/1

“mnist” プロジェクトに “…/result/1” という名前の実験が加えられ、”path/to/result/1”に出力されるlogファイルのデータをグラフに表示します。

実験管理機能

上記logファイルと同じディレクトリにあるargsファイルを一覧に表示します。このargsファイルはkey-value形式のJSONファイルです。下記はtrain_mnist.pyに対して、起動引数をargsファイルに保存するサンプルコード(抜粋)です。

# [ChainerUI] import chainerui util function
from chainerui.utils import save_args

def main():
    parser.add_argument('--out', '-o', default='result',
                        help='Directory to output the result')
    args = parser.parse_args()

    # [ChainerUI] save 'args' to show experimental conditions
    save_args(args, args.out)

実験中のジョブを操作するには、ChainerUIのCommandsExtensionを使用します。同じくtrain_mnist.pyに対するサンプルコード(抜粋)です。任意のタイミングでスナップショットを取ったり、学習率などのハイパーパラメータを修正することができます。

# [ChainerUI] import CommandsExtension
from chainerui.extensions import CommandsExtension

def main():
    trainer = training.Trainer(updater, (args.epoch, 'epoch'), out=args.out)

    # [ChainerUI] enable to send commands from ChainerUI
    trainer.extend(CommandsExtension())

コード全体は、examples/train_mnist.pyを参照してください。

公開の背景

ディープラーニングの応用によって、様々な課題に対するState-of-the-artが日夜目まぐるしく塗り替えられる現在、実験の可視化や管理の効率化は大きな課題となっています。そのため、効率化支援のアプリケーションが乱立する状況も生んでいます。

PFNは、Chainerユーザが上記の課題に悩まされることなく、心地よく実験をこなせることを望んでいます。このような背景から、本パッケージをChainerユーザの効率をよりいっそう高めるための公式ツールとして位置づけて公開します。

PFN2017夏インターンシップの成果

本パッケージは、PFN2017年夏インターンシップに参加した稲垣さんと小林さんの開発成果です。

多くのリサーチャーやエンジニアを抱えるPFN社内では、以前から効率的な機械学習の実験の実施が課題となっていました。しかしながら、各々個人の工夫に頼っていたのが実情でした。そこで、「実験の効率化を支援するためのフロントエンド・アプリケーション」をインターンシップの課題として位置づけて開発を開始しました。

フロントエンド・エンジニアとしてタッグを組んだおふたりは、2か月という短い期間ながらも社内に溶け込み、要件調整から設計・実装まで自発的にプロジェクトを進めました。そしてインターンシップ終了後もPEとして継続的にコミットを続けた上、社内での4ヶ月間のドッグフーディングを経ることで、本日の公開を迎えています。

今後の展望

PFNはChainerUIをChainer製品群の1つとして位置づけ、今後も積極的に開発を進めていく予定です。以下の機能の実装が予定されています。

  • グラフの出力機能
  • 操作コマンドExtensionの拡充 etc

また、PFNでは最先端の研究開発成果物を、エンドユーザに届けるスキルを持ったフロントエンド・エンジニアを募集しています。

化学、生物学分野のための深層学習ライブラリChainer Chemistry公開

Kosuke Nakago

2017-12-18 11:41:05

* English blog is also written here.

Chainer [1]を使った、化学、生物学分野のための深層学習ライブラリ Chainer Chemistry を公開しました。

 

本ライブラリにより、分子構造に対して簡単に深層学習(Deep learning)を適用することができるようになります。

例えば、化合物の分子構造を入力とした毒性の予測や、HOMO(最高被占軌道)レベルの回帰予測など、様々な化学的性質の予測に深層学習を適用することができます。

なお本ライブラリの開発にあたっては、PFN2017夏インターンシップに参加した京都大学の秋田大空さんにも実装に携わっていただきました。

 

特長

様々なGraph Convolutional Neural Network のサポート

Graph Convolutional Network (詳しくは下記参照)の登場により、”グラフ構造”を入力として深層学習が適用できるようになりました。Graph Convolutional Networkは現在盛んに研究がおこなわれていますが、本ライブラリでは今年発表されたばかりの論文も含めいくつかのネットワークを追実装しています。

現時点では以下のモデルが実装されています。

  • NFP: Neural Fingerprint [2, 3]
  • GGNN: Gated-Graph Neural Network [4, 3]
  • WeaveNet: Molecular Graph Convolutions [5, 3]
  • SchNet: A continuous-filter convolutional Neural Network [6]

 

データの前処理部分をライブラリ化・研究用データセットのサポート

様々なデータセットを共通のインターフェースで使えるように、ソフトウェアを設計しています。また、研究用によく使用されるデータセットに関してはライブラリ内でダウンロード・前処理を行うことができます。

現時点では以下のデータセットをサポートしています。

  • QM9 [7, 8]: 9個までのC、O、N、F原子とH原子から構成された有機分子に対して、B3LYP/6-31GレベルのDFT(密度汎関数法)で算出されたHOMO/LUMOレベル、内部エネルギーなどの物性値をまとめたデータセット
  • Tox21 [9]: 12種類のアッセイに対する毒性をまとめたデータセット

 

学習・推論コードのExample code を提供

ライブラリの使い方がわかるよう、モデルの学習コード・推論コードのExampleも公開しています。すでに実装済みのモデル・データセットに対して手軽に訓練・推論を試してみることができます。

 

背景

材料探索・創薬などの応用分野では、分子構造を入力とするシミュレーションが重要な位置を占めます。中でも量子力学的効果を高い精度で取り込みたい場合に用いられるDFT(密度汎関数法)のようなシミュレーション手法は、特に大きな分子に対して、膨大な計算量を要求することが知られています。このため、有用な新物質の候補となる多数の分子構造に対してシミュレーションを行うのが困難です。

そこで機械学習分野では、これまでに実測・計算されたデータを学習することにより、未知の分子の物性値を予測するというアプローチでの研究がおこなわれています。ニューラルネットワークを用いることにより、量子シミュレーションよりも高速に物性値の予測ができることが期待されています。

 

 

Cite from “Neural Message Passing for Quantum Chemistry”, Justin et al. https://arxiv.org/pdf/1704.01212.pdf

 

化合物に対して深層学習を適用することを考えた場合、その入出力をどのように扱うかということが問題となります。これは、通常の深層学習手法が固定長のベクトル値データを入力とするのに対し、分子構造は可変長で分岐やループを持ちうるデータ形式、つまりグラフであるためです。しかし、近年グラフ構造を扱うことのできるGraph Convolutional Neural Network が提案され、注目を集めています。

 

Graph Convolutional Neural Network とは

Convolutional Neural Network (畳み込みニューラルネットワーク)は、局所的な情報のみで計算を進める畳み込み層の導入によって、画像分類、セグメンテーションや画像生成などの分野で成功をおさめました。

Graph Convolutional Neural Network では、同様にグラフ上で近いノードに対する畳み込み演算を導入することにより、グラフ構造の取り扱いを可能にしています。

How graph convolutions work

CNNが画像を入力とするのに対し、Graph CNNではグラフ構造(分子構造など)を入力として深層学習を行います。

 

グラフ構造を入力とするGraph Convolutional Neural Network は、分子構造にかぎらず、ソーシャルネットワークや交通網などに広く適用でき、ここ最近研究が進んできています。例えば、文献[10] では画像、[11]ではナレッジベース、[12]では交通量予測にGraph Convolutionを適用しています。

Graph Convolutional Networkに関しては、以下のブログでもわかりやすく説明されています。

 

対象ユーザー

  1. Deep learningの研究者
    本ライブラリでは、最新のGraph Convolutional Neural Network の追実装を行っています。
    今後、Graph Convolutionは計算科学に限らず、様々な分野への適用が考えられる技術なので、ぜひ様々な方に使っていただきたいです。
  2. 物質探索・創薬などの研究者
    本ライブラリを用いることにより、様々な化合物に対する物性値予測のモデルを構築することができます。

 

今後の予定

本ライブラリはまだベータ版で、開発を行っているところです。今後は以下のような機能をサポートしていきたいと検討しています。

  • Pre-trained modelを提供し、推論だけでの使用をサポート。
  • データセットの拡充
  • モデルの追加

Tutorial も用意しているので、ぜひ試してみてフィードバックをいただけるとありがたいです。

 

参考文献

[1] Tokui, S., Oono, K., Hido, S., & Clayton, J. (2015). Chainer: a next-generation open source framework for deep learning. In Proceedings of workshop on machine learning systems (LearningSys) in the twenty-ninth annual conference on neural information processing systems (NIPS) (Vol. 5).

[2] Duvenaud, D. K., Maclaurin, D., Iparraguirre, J., Bombarell, R., Hirzel, T., Aspuru-Guzik, A., & Adams, R. P. (2015). Convolutional networks on graphs for learning molecular fingerprints. In Advances in neural information processing systems (pp. 2224-2232).

[3] Gilmer, J., Schoenholz, S. S., Riley, P. F., Vinyals, O., & Dahl, G. E. (2017). Neural message passing for quantum chemistry. arXiv preprint arXiv:1704.01212.

[4] Li, Y., Tarlow, D., Brockschmidt, M., & Zemel, R. (2015). Gated graph sequence neural networks. arXiv preprint arXiv:1511.05493.

[5] Kearnes, S., McCloskey, K., Berndl, M., Pande, V., & Riley, P. (2016). Molecular graph convolutions: moving beyond fingerprints. Journal of computer-aided molecular design, 30(8), 595-608.

[6] Kristof T. Schütt, Pieter-Jan Kindermans, Huziel E. Sauceda, Stefan Chmiela, Alexandre Tkatchenko, Klaus-Robert Müller (2017). SchNet: A continuous-filter convolutional neural network for modeling quantum interactions. arXiv preprint arXiv:1706.08566

[7] L. Ruddigkeit, R. van Deursen, L. C. Blum, J.-L. Reymond, Enumeration of 166 billion organic small molecules in the chemical universe database GDB-17, J. Chem. Inf. Model. 52, 2864–2875, 2012.

[8] R. Ramakrishnan, P. O. Dral, M. Rupp, O. A. von Lilienfeld, Quantum chemistry structures and properties of 134 kilo molecules, Scientific Data 1, 140022, 2014.

[9] Huang R, Xia M, Nguyen D-T, Zhao T, Sakamuru S, Zhao J, Shahane SA, Rossoshek A and Simeonov A (2016) Tox21 Challenge to Build Predictive Models of Nuclear Receptor and Stress Response Pathways as Mediated by Exposure to Environmental Chemicals and Drugs. Front. Environ. Sci. 3:85. doi: 10.3389/fenvs.2015.00085

[10] Michaël Defferrard, Xavier Bresson, Pierre Vandergheynst (2016), Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering, NIPS 2016.

[11] Michael Schlichtkrull, Thomas N. Kipf, Peter Bloem, Rianne van den Berg, Ivan Titov, Max Welling (2017) Modeling Relational Data with Graph Convolutional Networks. arXiv preprint arXiv: 1703.06103

[12] Yaguang Li, Rose Yu, Cyrus Shahabi, Yan Liu (2017) Diffusion Convolutional Recurrent Neural Network: Data-Driven Traffic Forecasting. arXiv preprint arXiv: 1707.01926

 

分散深層学習パッケージ ChainerMN 公開

秋葉 拓哉
リサーチャー

2017-05-09 06:28:29

Chainer にマルチノードでの分散学習機能を追加するパッケージ ChainerMN のベータ版を公開しました。

ChainerMN とは

ChainerMN は Chainer の追加パッケージで、Chainer を用いた学習を分散処理により高速化できます。柔軟で直感的に利用できる Chainer の利便性をそのままに、学習時間を大幅に短縮できます。1 ノード内の複数の GPU を活用することも、複数のノードを活用することもできます。既存の学習コードから数行の変更で ChainerMN を利用可能です。ChainerMN は既に社内の複数のプロジェクトで実証が行われています。

Chainer を用いた通常の学習における 1 イテレーションは下図のように Forward, Backward, Optimize の 3 つのステップからなります。

ChainerMN はこれに、下図のように、通信を行う All-Reduce のステップを挿入します。All-Reduce のステップでは通信を行い、全ワーカーが Backward で求めた勾配の平均を計算し全ワーカーに配ります。Optimize のステップでは、この平均の勾配が利用されます。全ワーカーは学習開始後は常に同じパラメータを持ちます。

下図は以前に行った大規模ベンチマークの結果です。ChainerMN で 128 GPU を利用し画像分類の学習を約 100 倍高速化することができました。詳しくはこちらの記事をご覧ください。

利用方法の概要

以下、ChainerMN の利用方法の概要を紹介します。詳しくはドキュメントをご覧ください。

セットアップ

ChainerMN をインストールする前に、CUDA-Aware MPI, NVIDIA NCCL のセットアップが必要です。

CUDA-Aware MPI

ChainerMN は MPI を利用しており、MPI は CUDA-Aware 機能が利用できる必要があります。CUDA-Aware 機能をサポートするオープンソースの MPI には Open MPI, MVAPICH などがあります。以下は Open MPI を CUDA-Aware でインストールする例です。

./configure --with-cuda
make -j4
sudo make install

複数ノードで利用する場合、InfiniBand 等の高速なインターコネクトの利用を推奨します。

NVIDIA NCCL

NCCL はノード内の GPU 間の集団通信を高速に行うためのライブラリです。こちらを参考にビルド・インストールし、環境変数を適切に設定して下さい。

ChainerMN

ChainerMN は pip よりインストールできます。

pip install chainermn

 

学習コードの変更

ChainerMN を利用した分散学習を行うためには、既存の Chainer による学習コードに変更を加える必要があります。ドキュメント内のチュートリアルでは順を追ってこの手順を説明しています。

以下では、そのうちの最も重要なステップである、コミュニケータの作成と、オプティマイザの置き換えについて説明します。

コミュニケータ

コミュニケータは以下のように作成します。

comm = chainermn.create_communicator()

通信はこのコミュニケータを通じて行います。コミュニケータからは、参加しているワーカー数や自分がその何台目か(rank と呼ばれます)などの情報を得ることができます。

オプティマイザ

ChainerMN は Chainer のオプティマイザを置き換えることによりワーカー間の通信処理を挿入します。以下は通常の Chainer のコードで Adam のオプティマイザを作成している部分です。

optimizer = chainer.optimizers.Adam()

ChainerMN では、以下のように create_multi_node_optimizer 関数を呼び出して、通信処理が追加されたオプティマイザを作成します。

optimizer = chainer.optimizers.Adam()
optimizer = chainermn.create_multi_node_optimizer(optimizer, comm)

create_multi_node_optimizer によって作成されたオプティマイザは、通信処理が追加されている以外は通常のオプティマイザと同様に扱うことができます。

実行

mpiexec または mpirun コマンドを用いて学習スクリプトを起動します。以下は localhost 内で MNIST example を 4 プロセスで起動する例です。

mpiexec -n 4 python train_mnist.py

終わりに

以上、ChainerMN の利用法を駆け足で紹介しました。かなりの部分を省略しているので、実際に利用される際にはドキュメントを見て頂ければと思います。

ChainerMN は今後、通信と計算のオーバーラップ、ワーカー間の非同期な計算、勾配の圧縮による通信効率化、耐障害性などの課題に取り組み、改善を続けていく予定です。

深層強化学習による自動駐車の実装

Shiba Shintaro

2017-03-22 19:15:13

初めまして! PFN でアルバイトをさせてもらっている芝慎太朗です。普段は東京大学大学院で行動神経科学の研究をしています。僕が去年取り組んでいた、「車が自ら駐車場に向かい停止する」自動駐車プロジェクトについて報告します。まずはこちらのアニメーションをご覧ください。(アニメーションがうまく再生されない場合は画像をクリックしてください)

We implemented self-driving car that parks itself using deep reinforcement learning. The English slide is available at SlideShare!

背景

深層強化学習は、2015年から非常に注目され始めた人工知能技術であり、深層学習と強化学習を組み合わせたものです。深層強化学習によって、それまでできなかったような複雑なタスクにおいてもコンピューターが人を上回り始めました。プロ棋士を破ったことで一躍話題になった Google DeepMind による囲碁の人工知能 AlphaGo もこの技術を使っています。最近では スマッシュブラザーズにおいても威力を発揮し 話題になりました。

深層強化学習は制御タスクとの相性がよく、実際に PFN でもぶつからない車の自動運転ドローンの制御などに成功してきました。

PFN が CES 2016 で展示した自動運転(参照)では、アルゴリズムとして深層強化学習ブームの火付け役となった Deep Q Network(以下DQN)を用いています [Mnih et al., 2015]。ニューラルネットワークへの入力は、LIDAR(wikipediaによる解説)を模した近接物への距離と角度センサー、直前の行動、現在の車のスピードとステアリング(ハンドルの曲がり具合)でした。

しかし自動運転技術を現実に応用することを考えると、一般に距離センサーよりもカメラの方が安価という特徴があります。一方で、距離の計算が必要になるためカメラ画像の方が制御は難しくなると考えられます。実際、つい最近も ブラウザ上で動作するような簡単な自動運転デモ が公開されたばかりですが、これも距離センサーを使用しており、使用しているニューラルネットは3層程度の簡易なものです。
距離センサー・カメラそれぞれに得意・不得意な状況や利点・欠点があるので一概にどちらを用いるべきとは言えませんが、いずれにせよ、距離センサーに頼らずカメラ画像のみを用いて車を制御するようなアルゴリズムの研究開発は非常に重要です。

本プロジェクト

このプロジェクトでは、距離センサーではなく、車に取り付けられたカメラによる主観的な画像の入力によってend-to-endのアルゴリズムで車を制御できないか、ということに挑戦しました。具体的なタスクとして選んだのは駐車です。すなわち、車を駐車スペースに移動して停止させます。

アルゴリズムとしては DQN の改善版である Double DQN を使用しました。Double DQN は行動価値の見積もり値である Q 値の過大評価を防ぎ、ニューラルネットの発散を防ぐことで学習を安定させるという特徴があります [Hasselt et al., 2015]。詳しくは解説スライド(この投稿の最後にリンクが貼ってあります)や元論文をご覧ください。

まずは環境の定義です。今回は実機や既存のシミュレータを使用せず、簡単な車の物理シミュレータを自分で実装しました。このシミュレータはアクセル、ブレーキ、ハンドルの曲がり具合を受け取り、牽引力、空気抵抗、転がり抵抗、遠心力、制動力、コーナリング力を計算し、車の位置、速度、加速度を更新します。車や駐車スペースの大きさと、車が探索できる地面の範囲なども定義しました。次の図は、シミュレーションされた環境を上から見た俯瞰画像です。黒い長方形が駐車スペース、赤と黄色の長方形が車(黄色が前)になります。


次にエージェントへの入出力を定義します。エージェントは環境の状態を入力として受け取り、アルゴリズムにしたがって適切な行動を選択します。現実世界に例えるなら車に乗っている人に相当するでしょう。行動はアクセル、ブレーキ、ハンドルを左右に曲げることの組み合わせで全部で9種類用意しました。状態としては、環境を車から見た主観画像と、現在の車のスピードとステアリング(ハンドルの曲がり具合)を使用しました。つまり、車の現在位置や駐車スペースまでの距離を直接知ることはできません。

主観画像は、車を中心に3方向または4方向に設置されたカメラ画像を用意し、車の周りをぐるりと見渡せるようにします。次の画像はカメラが4台の場合の主観画像です。画像の大きさはニューラルネットに入力する直前で 80 x 80 に縮小します。わかりやすいように中心に先ほどと同様の俯瞰画像を載せました。


エージェントは、画像の入力に合わせて適切な行動を選択し、車を駐車スペースに導いてそこで停車することが求められます。状態がカメラ台数分の画像と、画像でないパラメータ(現在の車のスピードとステアリング)からなるため、ニューラルネットの構造を工夫して以下のようにしました。この図はカメラが3台の場合に使用されたニューラルネットワークです。図中の Convolution とは、画像を処理するための畳み込みニューラルネットを示します。


最後に報酬を定義しておきます。「車が駐車スペースに向かい、その中で停止する」、すなわち「車ができるだけ長く駐車スペースの内側にいる」ことを学習するような報酬の与え方を考えます。いろいろな設定を試しましたが、最終的に

  • 車が駐車スペースの内側にいる場合、+1
  • 車が地面の外にいる場合、-1
  • その他の場合、0.01 – 0.01 * ゴールまでの距離

というふうに設定してみました。
その他の細かい設定や、他に試した報酬の設計などは末尾のスライドをご覧ください。

結果

GeForce GTX TITAN X 上で約一週間ほど学習を回し続けた結果、冒頭で示したように、車が自動で駐車スペースに向かい停止するように学習できました。次のアニメーションは冒頭と同じもので、左が車の軌跡、右が実際にニューラルネットワークに入力された画像です。

しかしながらやはりタスクの難しさもあって、このまま学習を続けていくと車が地面をぐるぐる回り続けたり、パラメタによっては学習途中でニューラルネットの出力が発散してしまったりという場合もありました。こちらも詳細はスライドを見ていただければと思います。


考察

深層強化学習を用いて、主観画像の入力から自動駐車を学習できました。画像を入力して車を制御するのは、距離や角度のセンサーよりも一段階難しいタスクです。実は、このプロジェクトも距離などを入力にして学習させるところから始めました。距離を直接入力した場合には安定してすぐに学習できたものの、主観画像では Q 値の発散や、うねうねと動き続ける車が誕生したりとなかなか安定しませんでした。

原因として考えられることの1つに、畳み込み層で車や駐車スペースの場所がうまく検出しきれていない可能性があります。先にCNNから位置を回帰するような事前学習をおこなってその重みを初期値として使うことや、一度 CNN 部分の出力を可視化してみることも有用でしょう。

また学習を安定させるために、アルゴリズムの変更も効果的かもしれません。例えば A3C [Mnih et al., 2016] や TRPO [Schulman et al., 2016] を使ってみたり、モンテカルロ法と組み合わせた学習などは試す価値があると考えられます。

実際にはいきなり始めから主観画像を入力したわけではなく、上で少し述べたように、簡単なタスクから徐々に難しくしていました。また、報酬の設計を変更しつつ、駐車スペースの位置や車の初期設定を変えながらカリキュラム学習をしたりと細かい実験を試しています。これらの詳細が知りたい方は上記のスライドを見ていただければと思います。

まとめ

本プロジェクトの結果はまだ様々な状況で完全に対応できるものではありませんが、深層強化学習によってカメラ画像のみで自動駐車が実装できる可能性を示したものだと言えます。今後の方向性としては、学習アルゴリズムを変更して学習を安定させたいです。シミュレーションだけではなく、実機でも実現できれば非常に面白いと思います。

僕は現在も他のプロジェクトに取り組みながらアルバイトを続けています。初めからプログラミングや強化学習ができたわけではなく、自分で勉強しつつ、わからないところをメンターに教えていただきながら、大変恵まれた環境で進めることができたプロジェクトでした。学生の皆さんも興味があればアルバイトやインターンに積極的に飛び込んでいってみてはいかがでしょうか。

深層強化学習ライブラリChainerRL

Yasuhiro Fujita

2017-02-16 19:10:47

Chainerを使った深層強化学習ライブラリChainerRLを公開しました. https://github.com/pfnet/chainerrl

PFNエンジニアの藤田です.社内でChainerを使って実装していた深層強化学習アルゴリズムを”ChainerRL”というライブラリとしてまとめて公開しました.RLはReinforcement Learning(強化学習)の略です.以下のような最近の深層強化学習アルゴリズムを共通のインタフェースで使えるよう実装してまとめています.

A3CでAtari 2600のゲームをプレイするexampleや,

DDPGでヒューマノイドロボットの制御を学習するexampleなどがあります.

以下では簡単にChainerRLの使い方を説明します.

まず,強化学習を使って問題を解くには,解きたい問題(”環境”と呼びます)をしっかり定義する必要があります.環境の定義の仕方は,OpenAIが公開している強化学習ベンチマーク環境のGym(https://github.com/openai/gym)のインタフェースに従っています.Gymの環境で動かすこともできますし,インタフェースを揃えればオリジナルな環境で動かすこともできます.基本的にはresetとstepという2つのメソッドが実装されていれば十分です.

env = YourEnv()
# reset は環境をリセットして現在の観測を返す
obs = env.reset()
action = 0
# step は環境にアクションを送り,4つの値(次の観測,報酬,エピソード終端かどうか,追加情報)を返す
obs, r, done, info = env.step(action)

深層強化学習では,状態から行動を決める方策(Policy)や,状態や行動の価値を予測する価値関数(V-function,Q-function)をニューラルネットで表現し,そのパラメータを学習します.ChainerRLでは,これらは単に__call__を実装したChainerのLinkとして表現されます.

class CustomDiscreteQFunction(chainer.Chain):
    def __init__(self):
        super().__init__(l1=L.Linear(100, 50)
                         l2=L.Linear(50, 4))
    def __call__(self, x, test=False):
        h = F.relu(self.l1(x))
        h = self.l2(h)
        return chainerrl.action_value.DiscreteActionValue(h)

class CustomGaussianPolicy(chainer.Chain):
    def __init__(self):
        super().__init__(l1=L.Linear(100, 50)
                         mean=L.Linear(50, 4),
                         var=L.Linear(50, 4))
    def __call__(self, x, test=False):
        h = F.relu(self.l1(x))
        mean = self.mean(h)
        var = self.var(h)
        return chainerrl.distribution.GaussianDistribution(mean, var)

このように作ったモデルやChainerのOptimizer,アルゴリズムごとに必要な引数を渡して”エージェント”を作ります.エージェントは環境とのインタラクションを通じてデータを集めながらモデルの学習を行います.

q_func = CustomDiscreteQFunction()
optimizer = chainer.Adam()
optimizer.setup(q_func)
agent = chainerrl.agents.DQN(q_func, optimizer, ...)  # 残りの引数は省略

エージェントを作ったら,自分で学習ループを書いて動かすか,

# Training
obs = env.reset()
r = 0
done = False
for _ in range(10000):
    while not done:
        action = agent.act_and_train(obs, r)
        obs, r, done, info = env.step(action)
    agent.stop_episode_and_train(obs, r, done)
    obs = env.reset()
    r = 0
    done = False
agent.save('final_agent')

あるいはあらかじめ用意されている学習用関数に渡せば学習が行なえます.

chainerrl.experiments.train_agent_with_evaluation(
    agent, env, steps=100000, eval_frequency=10000, eval_n_runs=10,
    outdir='results')

とりあえず動かしてみるためのクイックスタートガイドを用意しました. https://github.com/pfnet/chainerrl/blob/master/examples/quickstart/quickstart.ipynb

ChainerRLはまだベータ版ですが,強化学習に興味がある方はぜひ試してもらってフィードバックをいただけるとありがたいです.ライブラリとしての使いやすさや,新しいアルゴリズムの追加など,今後も改善を続けていこうと思います.

ChainerMN による分散深層学習の性能について

秋葉 拓哉
リサーチャー

2017-02-08 11:49:16

米サンフランシスコで開催された「Deep Learning Summit 2017」にて、PFN は Chainer のマルチノードでの分散学習対応への取り組みについて発表しました。本記事では、その発表について詳しく説明していきます。

分散深層学習の重要性と現状

GPU の性能は継続的に向上していますが、より大きなデータを活用してより精度の高いモデルを実現するために、深層学習で使われるモデルのパラメータ数や計算量も増大しています。そのため、現在でも、Chainer を含む一般的なフレームワークを用いた標準的な学習では 1 週間以上かかってしまうようなユースケースが少なくありません。より大規模なデータを扱ったり、試行錯誤のイテレーションを効率化するために、複数の GPU を連携させ学習を高速化させることは重要な課題です。そこで、我々は Chainer にマルチノードでの分散学習の機能を追加するパッケージ ChainerMN を開発しています。

ChainerMN の実装方針

今回の実装はデータ並列と呼ばれるアプローチを採用しており、その中でも同期型の実装を採用しています。これは、各ワーカーがモデルのコピーを持ち、1 イテレーションのミニバッチを分割し全ワーカーで協力して勾配を計算する、というアプローチです。

実装には MPI を利用しており、ノード外の通信は MPI を通じて行うことにより、InfiniBand のような高性能なネットワークの性能を活用できます。ノード内の GPU 間の通信には NVIDIA 公式の NCCL というライブラリを利用しています。

性能測定の結果

ImageNet の画像分類データセットを使って性能を測定しました。CNN のモデルとしては ResNet-50 を使いました。実験にはさくらインターネットの高火力コンピューティングを利用しています。詳しい実験の設定については記事末尾の付録をご覧ください。

以下の性能測定の結果は、完全に公平とは言えない可能性がある事をご留意下さい。まず、性能測定を行った環境は我々が開発を行った環境でもあるため、測定環境に特に適した実装になっている可能性があります。また、他のフレームワークに関しても、性能を出すためにある程度の試行錯誤をしたものの、我々は十分な経験を持ち合わせていないため、完全に性能を出し切れているとは限りません。第三者による検証を推奨するため、比較に利用したプログラムは他フレームワークのものも含めて公開予定です。

ChainerMN の性能

下図は、GPU 数を増やしたときに学習完了にかかる時間がどのように高速化されるかを表した図です。学習完了とは同じエポック数の学習を行うこととしています。4 GPU までが同じノード内で、8 GPU 以上ではノードを跨いでいます。比較的理想的な高速化を達成しており、今回の設定では 128 GPU で 100 倍程度の高速化となりました。

下図は、横軸に実時間、縦軸に validation accuracy を描いた学習曲線です。2 度精度がジャンプするところは、学習率を 0.1 倍しているタイミングであり、ImageNet 系の学習曲線で見られる一般的な現象です。この図から、今回の設定では 128 GPU を使った場合でもちゃんと精度が上がってきていることが確認できます。

他フレームワークとの比較

下図は、128 GPU を用いる同じ設定下で各フレームワークが学習完了に要する時間です。開発チームとしても実は意外な結果だったのですが、ChainerMN が最も高速という結果になりました。この理由については次の実験と併せて考察していきます。

下図は、GPU 数を変えた時の各フレームワークのスループットを描いています。計測のイテレーション数を少なめにしてしまったのでやや不安定ですが、傾向が見て取れます。まず、1GPU の時には ChainerMN よりも MXNet, CNTK のほうが高速です。これは、MXNet, CNTK が C++ で記述されているのに対し、Chainer が Python で記述されているからだと考えられます。次に、4GPU の時を見ると、MXNet が少し出遅れます。この理由の1つとしては、CNTK と ChainerMN が NVIDIA NCCL の提供する高速な GPU 間集団通信を活用しているのに対し、MXNet は自前でノード内の通信を行っている、ということが言えると思います。一方で、ノード間通信では、CNTK よりも MXNet, ChainerMN のほうが良いスケーラビリティを示しています。結果、128 GPU では、ノード内・ノード間の両方で高速な通信を実現した ChainerMN が最も高速です。

TensorFlow の結果の解釈には注意が必要です。TensorFlow は通常の利用では十分高速なフレームワークです。上図の実験で 1 GPU の時ですら低いパフォーマンスとなってしまっているのは、1 GPU でも分散実行時と同じ設定で実行しているためです。別プロセスとして起動しているパラメータサーバとの gRPC を用いた通信に大きなオーバーヘッドが存在し、1 GPU の時ですらこのような速度になってしまっています。TensorFlow の速度については、他所でのベンチマークでも同様の結果が報告されています [1, 2]。

分散深層学習の難しさと課題について

分散深層学習の難しさの 1 つとして、スループットの向上が常にそのまま学習効率の向上になるわけではない、という点が挙げられます。例えば、データ並列のアプローチでは、GPU 数を増やすほどバッチサイズが大きくなります。しかし、ある程度以上のバッチサイズでは、バッチサイズを大きくするとモデルの学習に悪い影響があり、得られるモデルの精度が段々下がっていきます。まず、同じエポック数の学習を行う場合、イテレーション数が減ってしまうため、モデルが成熟しないことがあります。加えて、勾配の分散が小さくなることにより、性質の悪い局所解(sharp minima と呼ばれます)に進みやすくなってしまい、結果として得られるモデルの汎化性能が悪くなってしまう、という現象も知られています。

こういったことを加味せずスループットのみを報告するベンチマーク結果には意味が有りません。バッチサイズを上げたり同期頻度を下げたりすることにより、いくらでもスループットのスケーラビリティは上げることができますが、そういった設定では有用なモデルを学習させることはできません。今回も、GPU のメモリにはかなり余裕がある状況ながら、各 GPU の担当バッチサイズを小さめに抑えることで、それなりの精度のモデルを得る事ができる設定にしています。

今後について

ChainerMN は、今月中にも社内での試用を開始し、そこでのフィードバックを反映した上で、数ヶ月以内に OSS で公開予定です。

続きを読む »

12