Preferred Networksの基礎研究開発と産業応用

秋葉拓哉氏(以下、秋葉):ご紹介ありがとうございます。Preferred Networksから参りました、秋葉です。今日は唯一社外(サイバーエージェント以外)から参りました。

Preferred Networksという会社は、分散深層学習みたいに深層学習をメインとしたスタートアップの会社で、私はそこで「ChainerMN」というソフトと大規模分散深層学習の研究開発をしております。今日はそのへんの話をさせていただければと思います。

今ちょっと先走って紹介しちゃったんですけど、まず「そもそもお前らの会社ってなんなの?」というのを解説したいと思います。我々Preferred Networksは、深層学習の基礎研究開発とその産業応用の両方をやっております。基礎研究開発における有名な事例としては、まず「Chainer」の開発ですね。「Chainer」という深層学習フレームワークを開発しておりまして、おかげさまでけっこう多くの方に使っていただいております。ほかにも論文を書いたり、そういった研究開発をしております。

それから産業応用ですね。産業応用に関しては、交通システム、製造業、バイオ・ヘルスケアですね。その3つの分野が柱となっておりまして、上の段のような、深層学習を組み合わせて賢いロボットを作るとか、あとは下の段のような自動運転に向けた画像認識や制御の研究開発をしております。ここまでが弊社Preferred Networks(PFN)の紹介でした。

簡単に、今日お話しする私の自己紹介をしたいと思います。学生の頃はいわゆる競技プログラミングに打ち込んでました。『プログラミングコンテストチャレンジブック』という本を書いたりしました。ちょっと知っていてくれる人がいたらうれしいなと思います。

プログラミングコンテストチャレンジブック 第2版 ~問題解決のアルゴリズム活用力とコーディングテクニックを鍛える~

今では打って変わって違うことをしておりまして、Preferred Networksで大規模分散深層学習の研究開発をしております。「大規模」はそのままですね。「分散」とはどういう意味かというと、簡単に言うとGPUをいっぱい使うという意味です。深層学習ってGPUを使うんですけど、特にそのGPUがいっぱいあって、そいつらで分散並列処理をして深層学習を高速化する、そういった部分の研究と開発をしております。

あと趣味でKaggleという機械学習のコンテストに出ていて。機械学習のモデルを作って、予測を立てて精度が高い人が偉いという世界なんですけど、趣味でこのKaggleをやっておりまして、一応「Kaggle Master」という称号を得ています。けっこういい順位をとりました。

深層学習における3つの重要なポイント

今日はこの大規模分散深層学習について話していきます。まず最初に深層学習はどのように成功したのか、成功するにあたってなにが重要だったのかという話をしたいと思います。

深層学習においては、アルゴリズム、データ、そして計算パワー、この3つすべてが重要であると多くの場所で言われています。

例えば2011年にAlexNetのチームが深層学習を初めて……まあ初めてではないんですが、ある意味初めて画像分類に適用して、ImageNetと呼ばれる世界で一番有名な画像分類コンテストにおいて、2位に大差をつけて優勝しました。彼らは、例えばReLUやDropoutといったような当時最先端のニューラルネットワークのアルゴリズムを使った。それから、ImageNetは今までの常識からするとかなり大規模な画像分類のデータセットだったのですが、その画像分類のデータセットを使った。

あとは計算力ですね。CPUよりも計算力の高いGPUをGPGPUというかたちでニューラルネットワークの処理に適用して、大規模なデータを大規模なニューラルネットワークに入れることを可能にした。この3つすべてが揃って、彼らはあのコンテストで勝つことができました。

2018年現在もこの3つの要素が重要であるという点は変わっておりません。アルゴリズムも進歩しています。データも大きくなっています。そして計算力も重要です。私の仕事は、このうちの3つ目の計算力の部分ですね。とくに社内の人たちが、社外に対して競争力のある計算力を簡単に使えるようにする。これが我々の仕事です。

1,024台のGPUを活用し、ResNet-50を15分で学習

Deep Learningというのは非常に学習に時間がかかる。基本的にはこれが常識でした。例えば、先ほども紹介したAlexNetのチームは、そのAlexNetという彼らのニューラルネットワークが学習するのにだいたい1週間かかったと。けっこう待ちますね。そのあとに出てきたVGGという、これまた有名なニューラルネットワークアーキテクチャなんですけど、こちらではなんとトータルで2〜3週間も学習したということで、かなり時間がかかっています。

とくにImageNetというこのデータセットは大規模画像データセットで、それゆえにその上でConvolutional Neural Networkを学習させるのは非常に時間がかかるものだというのが2016年ぐらいまでの常識でした。

しかし主に去年、大きな進展があって、データ並列と呼ばれるテクニックがかなり進歩しました。それによって、去年の6月ぐらいの記録なのですが、FacebookのチームがなんとGPU256台をフル活用してResNet-50というモデルでImageNetを1時間で学習できたぞという論文を出してきました。1時間を256GPUで達成できると。これはかなり速いですね。これまで1週間という単位だったのが一気に1時間になりました。

ここからは我々(の成果)なんですけど。去年弊社は「MN-1」と呼ばれるスーパーコンピューターを作りまして、その中には1,024台のGPUがあります。ちょうど4倍の台数のGPUがある。さて、「じゃあ何分で学習が完了するか?」というのが、我々の最新の結果です。1,024台のGPUを活用してResNet-50を学習したところ、15分で終えるという記録を達成しました。こちらはNIPSという機械学習の学会のワークショップでも発表して、論文はarXivのほうにもあがっております。

2倍のGPUを用意しても2倍速くなるとは限らない

ここでちょっと明確にしておきたいことがあります。「そうはいっても、そもそも大規模分散深層学習ってなにが難しいのか?」という疑問を持つ人も多い気がします。具体的には、「GPUをいっぱい買ったら速くなるんでしょ? なんやん、カネの勝負やん?」って思われてるかもしれない。「4倍お金使ったから4倍速かったんでしょ」と。そうではないよ、というのが、僕が今日一番言いたいことですね。

分散深層学習は非常にテクニカルに難しいです。(スライドを指して)難しさは非常にいっぱいあって、そのうち思いつくものをここに書いてみたんですけれども、まあこんなもんじゃないですね。主に難しいのは2つの方向性です。1つがシステムプログラミングです。ちゃんと高速に、ちゃんとスケールする学習システムを作る必要があります。なので、高速なインターコネクト帯域を使うとか、ちゃんとレイテンシを隠蔽するような実装をするとか、そういったものを組み合わせて、実装の面でがんばっていくと。

ただ一方で、実装をがんばれば速くなるかというと実はそうではなくて、アルゴリズムの面もかなり難しいです。機械学習のレシピのような部分ですね。説明がやや難しいんですけれども、分散深層学習をやっていくと、GPUを2倍用意すれば必ずしも2倍速くなるとはかぎらないんですね。半分の時間で同じ精度を達成するためにいろんな工夫が必要になってきます。そういった部分も同時に進化させたり、そういった部分を意識してシステムを作っていく必要がある。それらが組み合わさった難しさがあります。

ただ、やっぱりそれでもいろんな会社がしのぎを削ってここをがんばっている。それはやっぱりここが非常に重要だということですね。分散深層学習の技術を確立して深層学習が速くなれば、実際に多くの研究者がこの試行錯誤のイテレーションを高速化できます。より大規模なデータやより大規模なモデルを使うこともできます。したがって、研究開発を加速したり、他社に差をつけるようなモデルを作ったりすることが可能になってくる。それゆえに我々も分散深層学習をがんばっています。

深層学習のイテレーションと並列化

長くなりましたが、ここまでが前置きで、ちょっとテクニカルな話に入っていきたいなと思います。まず分散深層学習ってどんな仕組みなんだろうという話をしたいと思います。けっこう時間がシビアなのでだんだん駆け足になります。

まず、普通の深層学習の学習イテレーションを復習しましょう。深層学習、とくにSupervised Learning、教師あり学習の場合を仮定するんですけど、(スライドを指して)深層学習の1イテレーションっていうのはこんな感じですね。まずニューラルネットワークにデータを見せて、予想させるわけですね。これがForward Computation、前向き計算です。

次がBackward Computation、後ろ向き計算ですね。今度は出力の側に正しい答えを入れて逆向きに情報を伝搬していきます。これによって、「勾配」と言うんですが、このエラーを直す方向というものを手に入れるんですね。どのようにパラメータを直すと予測が正しくなっていきそうかというデータを手に入れます。

そしたら、この勾配を使ってニューラルネットワークをアップデートする。それによってニューラルネットワークはちょっとだけ賢くなります。

この3つのステップが1イテレーションですね。これを何万回、何十万回、何百万回と繰り返すことによって、ニューラルネットワークは少しずつ賢くなっていって、ゆくゆくは正しい予想ができるようになっていきます。これがニューラルネットワークの学習イテレーションです。

じゃあこれをどうやって並列化するか? 基本的には2つのアプローチがあるのですが、今日はData Parallelというアプローチについて解説します。

Data Parallelのアプローチは、各ワーカーがこのニューラルネットワークのレプリカを持つんです。みんながパラメータを持ってると。各ワーカーが違うデータを処理するんですね。あるニューラルネットワークは「2」っていう画像を見せられて、あるニューラルネットワークは「4」という画像を見せられてる。そんな感じですね。

それで前向き計算、後ろ向き計算をすると、違う勾配が手に入るんですね。「2」も「4」も見た勾配というのが非常に価値が高いので、その2つをアグリゲートしてやってより良い勾配を得る。具体的には平均するだけでいいんですけれども、そうやってやるとニューラルネットワークがより賢くなる勾配が手に入るんですね。そいつを使ってニューラルネットワークをアップデートしてやると。これがデータ並列のアプローチです。わりとシンプルですね。

データ並列の同期型と非同期型はどちらがいいのか

実はデータ並列のアプローチの中でも、いくつかアプローチの違いがあります。一番シンプルなのが同期型ですね。(スライドを指して)Synchronousと書いてあるほうです。

これはもう非常にシンプルで、各ワーカーが一緒に処理を進めていきます。いっせーのせでスタートして、例えば一部のニューラルネットワークが「2」の画像を見て、別のワーカーでは「4」の画像が入ってくる。これで計算をしたあと、みんなで勾配を手に入れたら、みんなで通信をして、そのアグリゲートした勾配でニューラルネットワークをアップデートする。みんなで手をつないで進んでいく。これが同期型です。

非同期型はもう少し複雑ですね。各ワーカーはいっせーのせでスタートせずに、ばらばらに進んでいきます。例えばあるワーカーはある瞬間に前向き計算してるかもしれないし、あるワーカーは後ろ向き計算してるかもしれない。じゃあどうやってうまく一緒に協調作業するのかっていったら、ワーカーに加えてパラメータサーバを用意します。

パラメータサーバというのがニューラルネットワークのパラメータを管理するんですね。各ワーカーはまずパラメータサーバから最新のパラメータをもらいます。もらったパラメータを使って前向き計算・後ろ向き計算をして勾配を手に入れます。勾配を手に入れたら、その勾配をパラメータサーバにプッシュします。パラメータサーバがパラメータをアップデートします。

その間にワーカー間の同期はありません。なので、パラメータサーバのモデルは逐次変わり続けて、それによってニューラルネットワークは少しずつ賢くなっていく。そういった仕組みが非同期型です。今回強調したいなと思うのは、「じゃあこの同期型と非同期型どっちがいいんかい?」という話をしたいと思います。

(スライドに)もう書いちゃってるんですけど、よく誤解されるのは「非同期型のほうがいいんじゃないのか」って思われることです。

これはなぜかというと、確かに非同期型のほうが効率は良さそうなんですよ。というのも、同期型って各ワーカーが手を繋いで待たないといけないんですね。全ワーカーが終わるまで待つ。例えば遅いワーカーがいたらそいつのことを待っている間はムダです。一方、非同期型はそういったことはなく、計算が終わったらまたすぐにおかわりができるので、速いんじゃないのかと。スループットが高い。

ここでスループットと言っているのは、ニューラルネットワークにどんだけデータを食わせられるかということですね。イテレーションの回数のことです。これが多いんじゃないのかというふうに考えられます。まあ一理あります。

重要なのはスループットではなく精度

また、実際に僕も「なんで非同期型を使わないのか?」ってよく言われるんですけれども、(スライドを指して)そう言われる1つの理由はこれかなと思います。

Google Scholarって論文検索サイトで「Distributed Deep Learning(分散深層学習)」って検索すると、この論文が出てくるんですね。この論文はなにかというと、Google BrainチームがNIPS 2012年で発表したDistBeliefというGoogle社内で使われている分散深層学習フレームワークについて書いた論文です。

この論文は非常に非同期型推しで、基本的には非同期型のことしか考えていないぐらい。「同期型なんてありえないでしょ?」みたいな勢いで書かれているんですね。しかもGoogle Brainチームが書いているし、検索したら一番上に出てくる。みんなこれが常識なんじゃないのかと思って、「この論文で非同期型使ってるけど、なんで君らは同期型使ってるの? もしかして実装する力がないの? しょぼいね」みたいに言ってくる。まあ、さすがにそこまで言う人はいないですけど、そういうニュアンスを感じるようなことを言われたりするんですね。

ここで僕が強調したいのは、この論文は2012年に発表されていて、書かれたのが2011年。古すぎるんですね。今はもう2018年ですか。7年前ですね。ご存じのとおり、ニューラルネットワークって非常に進展の速い世界で、常識がどんどん変わっています。その1つがこれですね。残念ながらこの論文は古すぎてoutdatedです。ニューラルネットワークの世界でいえば、7年前は本当に原始時代に近いものです。なので、こういうものを鵜呑みにしないでほしいなと思います。

はい。というわけで、もうみなさんおわかりだとは思うんですけど、ここでの主張はスループットがたとえ高くても意味がない、本当に重要なのは精度だよねって話です。

現在の主流は同期型

(スライドを指して)これが実際に最近出た論文で、横軸が時間、縦軸が精度、上に行くほどいいですね。

同期型と非同期型を比較していて、非同期型が青です。実際、同期型のほうが上にきているのが確認できます。しかもおもしろいのが、実はこの論文を書いてるのはGoogle Brainチームなんですね。なので、Google Brainチームの人たちも同期型のほうが精度は高くなるというのを認識しています。

最近のTPUポッドとかも実はSync型の分散深層学習しかサポートしていないという話もあったりして、実際に彼らの中でも認識はちゃんと変わっています。そういったところで、実際に今はみんな同期型を使っています。

例えばこのFacebookの論文でも、「同期型を使ってるよ」とひと言書いて、もう比較もしないぐらい。

これもGoogle Brainチームのとある論文ですが、やっぱり「同期型の分散深層学習をしたよ」とサラッと書いてあると。

それからImageNetという最初に言及したコンテストも「優勝チームは同期型を使っているよ」という感じですね。なので、同期型のほうがいいよね、というのはpractitionerの間ではかなりのコンセンサスになりつつあります。

というわけでChainerMNも同期型を実装しているんですけど、実は同期型を使うと分散深層学習って非常にシンプルです。普通の学習ってForward・Backward・Optimizeをするという話をさっきしたと思うんですけれども、分散学習では、まずForwardをすると。次にBackwardをしてみんなが勾配を手に入れてるんですけど、そのあとでOptimizeの前にAll-Reduceという通信をします。

ここでみんなの勾配をアグリゲートして1つのより洗練された勾配を手に入れます。具体的には平均をとってるだけです。その平均をとった勾配を使ってみんなでモデルをアップデートするということによって分散深層学習ができます。あとはこれをいっぱい繰り返すだけですね。これが分散深層学習です。