Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
ディープラーニングフレームワーク
とChainerの実装
2016/03/07 PPL2016@岡山 招待講演
(株)Preferred Networks
奥田 遼介
自己紹介
奥田 遼介
 -2014東北大学 修士
 文字列処理など
 2014 (株)プリファードインフラストラクチャー
 2014- (株)プリファードネットワークス
 映像解析系、製造業系にかかわる研究開発
 ChainerやC...
何を話すか?
 ディープラーニングの基礎
 ディープラーニングフレームワークの実装
 プログラミングモデル
 記号型と命令型
 Define and RunとDefine by Run
 CuPy:Chainerの裏側を支える技術
...
ディープラーニングの基礎
ニューラルネットワーク(多層パーセプトロン)
x
1
x
N
・・ h
1
h
H
・・・・ k
M
k
1
y
M
y
1
Forward
Backward
・・
・・
入力層 隠れ層 出力層
文書
画像
センサー
チューリップ
異常確率50...
ディープラーニング(DL:DeepLearning)とは
 層が深く、幅も広いニューラルネットワークを利用した
機械学習手法
 2012年の大ブレーク以来、研究コミュニティのみならず
産業界に多く使われてきた
 2014〜2015年中に出...
画像認識タスクでの性能向上(ILSVRC)
28.2
25.8
16.4
11.7
6.7 5.98
5.1 4.94 4.82
3.56
0
5
10
15
20
25
30
エラー率
Deep Learning
の衝撃
これが人
7/50
chainer-DCGAN 学習30分後
画像を0から生成するNN
https://github.com/mattya/chainer-DCGAN
8/50
学習2時間後
9/50
学習1日後
10/50
ニューラルネット
 値が伝播していく有向グラフ
 エッジで重みをかけて、ノードに入るところで足し
込み、ノードの中で非線形変換する
 全体としては巨大で複雑な関数を表す
11/50
ニューラルネット=合成関数
 ベクトルに対して線形・非線形な関数をたくさん適
用する合成関数と捉えるとよい
 各ノードはベクトルを保持する変数(テンソル)
12/50
一般のニューラルネットは DAG = 計算グラフ
一般にはグラフが分岐したり合流したりする
 分岐:同じ変数を複数の場所でつかう
 合流:二つ以上の変数を受け取る関数を適用する
13/50
計算グラフの例
z = x ** 2 + 2 * x * y + y
x
y
_ ** 2
2 * _ _ * _ _ + _ z
_ + _
14/50
誤差逆伝播は、計算グラフを逆向きにたどる
計算グラフと順伝播時の各変数の値があれば計算可能
15/50
ニューラルネットの学習方法
1. 目的関数の設計
 計算グラフを自分で設計する
2. 勾配の計算
 誤差逆伝播で機械的に計算できる
3. 最小化のための反復計算
 勾配を使って反復更新する
1さえ設計すれば残りは
ほぼ自動化されている
1...
Linear
L2
Linear
L1
MNIST & Chainer
 3層パーセプトロン L1 = L.Linear(784, n_units)
L2 = L.Linear(n_units, 10))
def forward(self, ...
Recurrent Net
 ループがあるニューラルネット
 時刻の概念があり、t=T の状態は t=T-1 の状態と t=T の
入力を使って求める
T
T-1
T
18/50
Recurrent Net は時間展開して考える
 時間展開すれば、DAG の計算グラフになる
 DAG の計算グラフは誤差逆伝播できる(Backprop
Through Time)
t=1
t=2
t=3
t=4
19/50
ディープラーニングフレームワークの
実装
フレームワークの構成要素
 いずれも似たような構成要素からなる
 テンソルデータ構造
 変数
 レイヤー(ビルディングブロックとして)
 関数
 ネット
 上の二つをつないだり、たどったり
 最適化ルーチン
 最適化関数(SG...
無数にあるディープラーニングフレームワーク
 2015年時点で数十〜数百くらいあるらしい(派生含む)
 注:数え方による
 いろんな会社や団体が作っていてまさに戦国時代
 比較ポイント
 使っている言語 :C/C++, Python,...
有名なDLフレームワーク比較
主要実装言語 Python C++ Lua Python C++/Python
主要開発者 Preferred
Networks/
Infrastructure
BVLC Idiap Research
Instit...
記号型(Symbolic)と命令型(Imperative)
 記号型
 記号に対して計算指示を行うこ
とで計算グラフを構築
 Theano, TensorFlow
 設定ファイル型:Caffe, cxxnet
 命令型
 データに対...
記号型が有利:最適化しやすい
 学習ではコンパイル1回に対して実行は複数回
 依存関係解析に長い時間を書けることが可能
 メモリ使用量やマルチGPU、マルチノード最適がしやすい
 不要な値、一時的な値を探しやすい
 例えばTensor...
命令型が有利:記述の自由度
 プログラミング言語の制御構文を利用して書ける
 複雑な分岐構造や、再帰構造の場合は命令型が有利
a = numpy.ones(10)
b = numpy.ones(10) * 2
c = b * a
d = 0...
Q. 再帰使うような例があるのか?
A. Recursive Neural Network
 事前に与えられた構造(普通は構文木)に沿って、再帰的
にベクトルを結合する
 Recurrent Netは直鎖に対するRecursive Netと...
それぞれの欠点はなくせるのか
 命令型:最適化が難しい
 遅延評価する
 過去の実行の演算手順をキャッシュする
 記号型:柔軟性がとぼしい
 がんばってDSLを導入する
 命令型の方針を取り入れる
 向かう先:混ざる
 遅延評価...
現在のChainerの仕組み
 Define by Run
 基本的には命令型
 変数に対してbackwardが呼べるように拡張
 つまり、順方向の計算と同時に計算グラフを作る
 Define and Run(対立概念)
 基本的に...
なぜDefine by Runを考えたのか?
 より自由にNNを書けるようにするため
 NNの研究を制約しないフレームワークを作る
 可変長、再帰、動的なアテンション
 グラフの途中で値を見て分岐する事もOK
 アイデア
 NNの逆...
NNフレームワークの現在・今後の課題
 メモリ使用量の削減
 GPUのメモリは小さい(Tesla K80@24GB とても高い)
 150層を超えるような巨大なネットワーク
 長いリカレントネットワーク
 マルチGPU・マルチノード
...
ミニバッチをなぜやめたいか?
 NNの学習では複数のデータを一つにまとめて計算する
 例:100枚を1個のデータにして流す
 なぜミニバッチにするかはNvidiaの講演資料を参照ください
 可変長データを扱うとき辛い
 現在はパディン...
まとめ
 計算グラフを作るアプローチを説明
 記号型と命令型
 Define and RunとDefine by Run
 最適化と利便性のトレードオフ
 課題
 メモリ使用量の削減
 マルチGPU・マルチノード
 ミニバッチを...
CuPy:Chainerの裏側を支える技術
CuPyとは何か?
 CUDA上で計算を行うNumPyサブセットのライブラリ
 関数・メソッドのサブセットを実装
 Chainer v1.5.0では 約174個の関数が実装済み
 行列積などはcuBLASを利用(高速)
 配列のスライ...
どこで使われているのか?
• モデル管理
• 学習ループ抽象化
学習・認識処理
• 自動微分(変数と関数)
• 重みの最適化
計算グラフ処理
• CuPy ← ここ
• Torch(本体), Eigen::Tensor
テンソル計算
• BLA...
CuPy の使い方は?
 numpy の代わりに cupy を使う(だいたい動く)
 CPU/GPU の両方で動く関数の書き方
 例えば下は NumPy と CuPy の両方で動く logsumexp の実装例
 より省メモリな実装を考...
CuPyはどのくらい早いの?
 状況しだいですが、最大数十倍程度速くなります
def test(xp):
a = xp.arange(1000000).reshape(1000, -1)
return a.T * 2
test(numpy)
...
CuPyの特徴(1/2)
 Cythonによる高速動作
 PythonはCの200倍遅い
 NumPy準拠のためにいろんな判定が入っている
 NumPy準拠の挙動
 複雑なキャスティングルールも再現(「NumPy闇入門」参照)
 整...
CuPyの特徴(2/2)
 CUDAコードの動的生成
 対象のテンソルの次元数、データ型に応じてコードを生成
 その場でnvccによるコンパイル(←ここが遅い)
 生成したバイナリはキャッシュされる
 なぜ動的生成するか?
 性能の...
CuPyの全体構造は?
 大まかに3層構造
 cupy.core cupy.cuda はCythonで書かれている
CUDA(cuBLAS, cuRNAD, cuDNN)
ndarray
ufunc, elementwise, reduct...
テンソルの実体
 Python側はndarray 、 C++側はCArray
template <typename T, //データ型
int ndim> //次元数
class CArray {
private:
T* data_; //G...
GPU上で計算したい場合
 カーネルをPython中にC++コードで書く
 よく使うものはラップしてある
 ElementwiseKernel
 全要素に同じ計算を行う
 ReductionKernel
 複数要素の集約を計算を行う...
ElementwiseKernelの作り方
 要素ごとの2乗誤差をとる関数を定義
 使い方
 ブロードキャストや型チェックは全自動
squared_diff = cupy.ElementwiseKernel(
‘float32 x, fl...
型をジェネリックに扱うことも可能
 1文字の型名はプレースホルダーになる
squared_diff = cupy.ElementwiseKernel(
‘T x, T y’, //入力
‘T z’, //出力
‘z = (x - y) * (...
Elementwiseカーネルの実体
 Pythonの文字列テンプレートを使って生成
${preamble}
extern "C" __global__ void ${name}(${params})
{
${loop_prep};
CUPY...
cupy.add(x, y)はどのように実行されるか?
 NumPyのための部分
 引数のオプションを解決(args, kwdargs)
 引数の個数チェック
 引数のdeviceチェック
 引数の型を正規化
 ブロードキャストを実...
CuPyの問題点
 細かい単位の関数呼び出しが多くなる
 GPUの帯域律速
 関数合成の仕組みが必要
 非同期呼び出しとメモリプールの相性が悪い
 Malloc, Freeがボトルネックとなるめメモリプールを利用
 現在は一つのスト...
まとめ
 ディープラーニングの基礎
 順伝播のみを書く
 逆伝播、最適化は自動化できる
 フレームワークの実装
 数十を超える実装があり、競い合っている
 記号型、命令型に着目した分類とそのトレードオフ
 CuPy
 Chain...
参考資料
 MXNet 設計ドキュメント
 Programming Models for Deep Learning
 http://mxnet.readthedocs.org/en/latest/program_model.html
...
Nächste SlideShare
Wird geladen in …5
×

ディープラーニングフレームワーク とChainerの実装

9.264 Aufrufe

Veröffentlicht am

PPL2016@岡山
ディープラーニングの研究開発時には、計算を支援するためのフレームワークが用いられる。ChainerはPython上で動くディープラーニングフレームワークの一つである。他の多くのフレームワークと異なり、順伝播処理を行った時の実行履歴情報をもとに逆伝播のグラフを動的に構築するdefine-by-runという方式を採用している。この方式により、分岐や再帰を含むような複雑な構造のネットワークも直感的に構築でき、加えてデバッグが容易である。また、CuPyと呼ばれるNumPyサブセットのCUDAによる行列演算ライブラリを作成し、バックエンドとして利用している。本講演では、ディープラーニングフレームワークの基礎と実装、そして課題についてChainerを通して説明する。

Veröffentlicht in: Ingenieurwesen
  • Als Erste(r) kommentieren

ディープラーニングフレームワーク とChainerの実装

  1. 1. ディープラーニングフレームワーク とChainerの実装 2016/03/07 PPL2016@岡山 招待講演 (株)Preferred Networks 奥田 遼介
  2. 2. 自己紹介 奥田 遼介  -2014東北大学 修士  文字列処理など  2014 (株)プリファードインフラストラクチャー  2014- (株)プリファードネットワークス  映像解析系、製造業系にかかわる研究開発  ChainerやCuPyの開発 最新v1.7 (2016/3/1) 2/50
  3. 3. 何を話すか?  ディープラーニングの基礎  ディープラーニングフレームワークの実装  プログラミングモデル  記号型と命令型  Define and RunとDefine by Run  CuPy:Chainerの裏側を支える技術  話さない事  Chainerの使い方、インストール方法 3/50
  4. 4. ディープラーニングの基礎
  5. 5. ニューラルネットワーク(多層パーセプトロン) x 1 x N ・・ h 1 h H ・・・・ k M k 1 y M y 1 Forward Backward ・・ ・・ 入力層 隠れ層 出力層 文書 画像 センサー チューリップ 異常確率50% カテゴリ:政治 ・・ ・・・・ 5/50
  6. 6. ディープラーニング(DL:DeepLearning)とは  層が深く、幅も広いニューラルネットワークを利用した 機械学習手法  2012年の大ブレーク以来、研究コミュニティのみならず 産業界に多く使われてきた  2014〜2015年中に出された関連論文数は1500を超える*  画像認識、音声認識などで劇的な精度向上を果たし、その 多くが既に実用化されている  囲碁でもDeepMindの AlphaGoが大きな成果  あと40時間でLee Sedol (魔王)と戦う 2014年の一般画像認識コンテストで優勝した 22層からなるNNの例 [Google] *http://memkite.com/deep-learning-bibliography/ 2015年の一般画像認識コンテストで優勝した 152層からなるNNの例 [MSRA] 6/50
  7. 7. 画像認識タスクでの性能向上(ILSVRC) 28.2 25.8 16.4 11.7 6.7 5.98 5.1 4.94 4.82 3.56 0 5 10 15 20 25 30 エラー率 Deep Learning の衝撃 これが人 7/50
  8. 8. chainer-DCGAN 学習30分後 画像を0から生成するNN https://github.com/mattya/chainer-DCGAN 8/50
  9. 9. 学習2時間後 9/50
  10. 10. 学習1日後 10/50
  11. 11. ニューラルネット  値が伝播していく有向グラフ  エッジで重みをかけて、ノードに入るところで足し 込み、ノードの中で非線形変換する  全体としては巨大で複雑な関数を表す 11/50
  12. 12. ニューラルネット=合成関数  ベクトルに対して線形・非線形な関数をたくさん適 用する合成関数と捉えるとよい  各ノードはベクトルを保持する変数(テンソル) 12/50
  13. 13. 一般のニューラルネットは DAG = 計算グラフ 一般にはグラフが分岐したり合流したりする  分岐:同じ変数を複数の場所でつかう  合流:二つ以上の変数を受け取る関数を適用する 13/50
  14. 14. 計算グラフの例 z = x ** 2 + 2 * x * y + y x y _ ** 2 2 * _ _ * _ _ + _ z _ + _ 14/50
  15. 15. 誤差逆伝播は、計算グラフを逆向きにたどる 計算グラフと順伝播時の各変数の値があれば計算可能 15/50
  16. 16. ニューラルネットの学習方法 1. 目的関数の設計  計算グラフを自分で設計する 2. 勾配の計算  誤差逆伝播で機械的に計算できる 3. 最小化のための反復計算  勾配を使って反復更新する 1さえ設計すれば残りは ほぼ自動化されている 16/50
  17. 17. Linear L2 Linear L1 MNIST & Chainer  3層パーセプトロン L1 = L.Linear(784, n_units) L2 = L.Linear(n_units, 10)) def forward(self, x): h1 = F.relu(L1(x)) return L2(h1) x h1 W bias 0 5 9 W bias ReLU 17/50
  18. 18. Recurrent Net  ループがあるニューラルネット  時刻の概念があり、t=T の状態は t=T-1 の状態と t=T の 入力を使って求める T T-1 T 18/50
  19. 19. Recurrent Net は時間展開して考える  時間展開すれば、DAG の計算グラフになる  DAG の計算グラフは誤差逆伝播できる(Backprop Through Time) t=1 t=2 t=3 t=4 19/50
  20. 20. ディープラーニングフレームワークの 実装
  21. 21. フレームワークの構成要素  いずれも似たような構成要素からなる  テンソルデータ構造  変数  レイヤー(ビルディングブロックとして)  関数  ネット  上の二つをつないだり、たどったり  最適化ルーチン  最適化関数(SGDとかAdamとか)  フレームワークによってこれらの設計指針や抽象化の粒 粒度度、インターフェイスが異なる 21/50
  22. 22. 無数にあるディープラーニングフレームワーク  2015年時点で数十〜数百くらいあるらしい(派生含む)  注:数え方による  いろんな会社や団体が作っていてまさに戦国時代  比較ポイント  使っている言語 :C/C++, Python, R, Matlab, Julia  機能の充実度 :よりけり  ネットワークの定義の方式 :命令型、記号型  GPUサポート :無し、CUDA、OpenCL  マルチGPU/ノードサポート :無し、有り  開発体制 :企業、大学、研究機関 22/50
  23. 23. 有名なDLフレームワーク比較 主要実装言語 Python C++ Lua Python C++/Python 主要開発者 Preferred Networks/ Infrastructure BVLC Idiap Research Institute, DeepMind Univ. of Montreal Google コミュニティ △(日本○) ◎ ○ ○ ○ RNN/LSTM対応 ◎ × ○ ○ ○ 動的ネットワー ク構築 ○ × × × × 拡張性 ○ △ ○ ○ ○ ネットワーク 設計 言語内DSL 設定ファ イル (prototxt) 言語内DSL 設定ファイ ル(YAML) 言語内DSL (Python) 特徴 ネットワーク動 的構築による省 リソース 画像認識 が得意 LuaJITによる 高速化 自動微分機 構 マルチGPU、マル チノード(gRPC )をサポート 23/50
  24. 24. 記号型(Symbolic)と命令型(Imperative)  記号型  記号に対して計算指示を行うこ とで計算グラフを構築  Theano, TensorFlow  設定ファイル型:Caffe, cxxnet  命令型  データに対して直接計算を指示  Chainer  Torch(本体), Minerva #記号型 A = Variable('A') B = Variable('B') C = B * A D = C + Constant(1) # compiles the function f = compile(D) d = f(A=numpy.ones(10), B=numpy.ones(10) * 2) #命令型 a = numpy.ones(10) b = numpy.ones(10) * 2 c = b * a d = c + 1 24/50
  25. 25. 記号型が有利:最適化しやすい  学習ではコンパイル1回に対して実行は複数回  依存関係解析に長い時間を書けることが可能  メモリ使用量やマルチGPU、マルチノード最適がしやすい  不要な値、一時的な値を探しやすい  例えばTensorFlow では各シンボルは型とサイズを持つ #記号型 A = Variable('A') B = Variable('B') C = B * A D = C + Constant(1) A D B B * A + 1 A B DC B * A C + 1 最適化 25/50
  26. 26. 命令型が有利:記述の自由度  プログラミング言語の制御構文を利用して書ける  複雑な分岐構造や、再帰構造の場合は命令型が有利 a = numpy.ones(10) b = numpy.ones(10) * 2 c = b * a d = 0 for i in range(c): d += c[i] + i 26/50
  27. 27. Q. 再帰使うような例があるのか? A. Recursive Neural Network  事前に与えられた構造(普通は構文木)に沿って、再帰的 にベクトルを結合する  Recurrent Netは直鎖に対するRecursive Netともとれる  ChainerのExampleに入っている x1 x2 p1 x3 p2 p1 = f(x1, x2) p2 = f(p1, x3) 27/50
  28. 28. それぞれの欠点はなくせるのか  命令型:最適化が難しい  遅延評価する  過去の実行の演算手順をキャッシュする  記号型:柔軟性がとぼしい  がんばってDSLを導入する  命令型の方針を取り入れる  向かう先:混ざる  遅延評価の命令型 or 命令型は記号型に自動変換  例:MXNet  デザインノートが充実している 28/50
  29. 29. 現在のChainerの仕組み  Define by Run  基本的には命令型  変数に対してbackwardが呼べるように拡張  つまり、順方向の計算と同時に計算グラフを作る  Define and Run(対立概念)  基本的には記号型  TensorFlow, Theano, Torch nn a = numpy.ones(10) b = numpy.ones(10) * 2 c = b * a d = c + 1 a b dc b * a c + 1 Define by Runで作られる計算グラフ 29/50
  30. 30. なぜDefine by Runを考えたのか?  より自由にNNを書けるようにするため  NNの研究を制約しないフレームワークを作る  可変長、再帰、動的なアテンション  グラフの途中で値を見て分岐する事もOK  アイデア  NNの逆伝播は、順伝播で通った計算の逆で良い  順伝播を命令型で書けば言語側の制御構文が使える  命令型で計算グラフを覚える方式  問題点  最適化が難しい 30/50
  31. 31. NNフレームワークの現在・今後の課題  メモリ使用量の削減  GPUのメモリは小さい(Tesla K80@24GB とても高い)  150層を超えるような巨大なネットワーク  長いリカレントネットワーク  マルチGPU・マルチノード  どこにどのようなデータを置くか  どのようなタイミングで転送するか  自動で最適化しないと使ってもらえない  ミニバッチをやめたい  各データ単位で別々のネットワーク構造を使えない  例:可変長データ、再帰構造データ31/50
  32. 32. ミニバッチをなぜやめたいか?  NNの学習では複数のデータを一つにまとめて計算する  例:100枚を1個のデータにして流す  なぜミニバッチにするかはNvidiaの講演資料を参照ください  可変長データを扱うとき辛い  現在はパディングで対応しているが、かなりつらい状況 t=1 t=2 t=3 t=4 t=1 t=2 データA 長さ4 データB 長さ2 32/50
  33. 33. まとめ  計算グラフを作るアプローチを説明  記号型と命令型  Define and RunとDefine by Run  最適化と利便性のトレードオフ  課題  メモリ使用量の削減  マルチGPU・マルチノード  ミニバッチをやめたい 33/50
  34. 34. CuPy:Chainerの裏側を支える技術
  35. 35. CuPyとは何か?  CUDA上で計算を行うNumPyサブセットのライブラリ  関数・メソッドのサブセットを実装  Chainer v1.5.0では 約174個の関数が実装済み  行列積などはcuBLASを利用(高速)  配列のスライス、転置、reshape 等が自由にできる  カスタムカーネルの記述も可能  elementwise, reduction  Python上で簡単にGPUが使える事を追求  Python上で簡単に多次元配列といえばNumPy  PC上で簡単にGPUといえばCUDA  CUDA+NumPy =CuPy 35/50
  36. 36. どこで使われているのか? • モデル管理 • 学習ループ抽象化 学習・認識処理 • 自動微分(変数と関数) • 重みの最適化 計算グラフ処理 • CuPy ← ここ • Torch(本体), Eigen::Tensor テンソル計算 • BLAS(OpenBLAS, MKL) • CUDA(cuBLAS, cuDNN) 行列・畳み込み計算  DLフレームワークは次のような機能単位で構成される  かなり雑です。複数の領域にまたがる機能もあります 低 高 36/50
  37. 37. CuPy の使い方は?  numpy の代わりに cupy を使う(だいたい動く)  CPU/GPU の両方で動く関数の書き方  例えば下は NumPy と CuPy の両方で動く logsumexp の実装例  より省メモリな実装を考えてみてください def logsumexp(x, axis=None): xp = cuda.get_array_module(x) #おまじない x_max = x.max(axis) exp_sum = xp.exp(x - x_max).sum(axis) return x_max + xp.log(exp_sum) 37/50
  38. 38. CuPyはどのくらい早いの?  状況しだいですが、最大数十倍程度速くなります def test(xp): a = xp.arange(1000000).reshape(1000, -1) return a.T * 2 test(numpy) t1 = datetime.datetime.now() for i in range(1000): test(numpy) t2 = datetime.datetime.now() print(t2 -t1) test(cupy) t1 = datetime.datetime.now() for i in range(1000): test(cupy) t2 = datetime.datetime.now() print(t2 -t1) 時間 [ms] 倍率 NumPy 2929 1.0 CuPy 585 5.0 CuPy + Memory Pool 123 23.8 Intel Core i7-4790 @3.60GHz, 32GB, GeForce GTX 970 38/50
  39. 39. CuPyの特徴(1/2)  Cythonによる高速動作  PythonはCの200倍遅い  NumPy準拠のためにいろんな判定が入っている  NumPy準拠の挙動  複雑なキャスティングルールも再現(「NumPy闇入門」参照)  整数8タイプ、浮動小数点数3タイプの計算をサポート  NumPyお約束のバグも再現 39/50
  40. 40. CuPyの特徴(2/2)  CUDAコードの動的生成  対象のテンソルの次元数、データ型に応じてコードを生成  その場でnvccによるコンパイル(←ここが遅い)  生成したバイナリはキャッシュされる  なぜ動的生成するか?  性能の確保とインストール時間短縮のため  例えば、加算 A+B=C でもパターン数は3万以上  次元数0~25:即値を含め 27  型:整数8、浮動小数3:11^3=1331  Chainerのテストを全部回すと11595個のカーネルができる  初回呼び出しは遅い 40/50
  41. 41. CuPyの全体構造は?  大まかに3層構造  cupy.core cupy.cuda はCythonで書かれている CUDA(cuBLAS, cuRNAD, cuDNN) ndarray ufunc, elementwise, reduction CUDA Python wrapper cupy.cuda cupy.core 関数群(演算、テンソル操作) cupy 41/50
  42. 42. テンソルの実体  Python側はndarray 、 C++側はCArray template <typename T, //データ型 int ndim> //次元数 class CArray { private: T* data_; //GPUメモリへのポインタ int size_; //CArray全体の要素数 int shape_[ndim]; //各次元の要素数 int strides_[ndim]; //各次元のストライド } //不連続な領域を扱うため 42/50
  43. 43. GPU上で計算したい場合  カーネルをPython中にC++コードで書く  よく使うものはラップしてある  ElementwiseKernel  全要素に同じ計算を行う  ReductionKernel  複数要素の集約を計算を行う  テンソルに対して任意軸(複数)でのReduceが可能  テンソルのサイズによって2種類の方式を使い分ける  ufunc  NumPy互換のElementwise 43/50
  44. 44. ElementwiseKernelの作り方  要素ごとの2乗誤差をとる関数を定義  使い方  ブロードキャストや型チェックは全自動 squared_diff = cupy.ElementwiseKernel( ‘float32 x, float32 y’, #入力 ‘float32 z’, #出力 ‘z = (x - y) * (x - y)’, #計算 ‘squared_diff’) #名前 squared_diff(cupy.arange(10), 10) 44/50
  45. 45. 型をジェネリックに扱うことも可能  1文字の型名はプレースホルダーになる squared_diff = cupy.ElementwiseKernel( ‘T x, T y’, //入力 ‘T z’, //出力 ‘z = (x - y) * (x - y)’, //計算 ‘squared_diff’) //名前 45/50
  46. 46. Elementwiseカーネルの実体  Pythonの文字列テンプレートを使って生成 ${preamble} extern "C" __global__ void ${name}(${params}) { ${loop_prep}; CUPY_FOR(i, _ind.size()){ //全要素のループ _ind.set(i); //インデックスを計算 ${operation}; //計算部分 } ${after_loop}; } 46/50
  47. 47. cupy.add(x, y)はどのように実行されるか?  NumPyのための部分  引数のオプションを解決(args, kwdargs)  引数の個数チェック  引数のdeviceチェック  引数の型を正規化  ブロードキャストを実行  add をどの型の組み合わせで実行するかを解決  CUDA実行のための部分  戻り値の割り当て実行  計算が高速に実行できるように引数を最適化  CUDAのカーネルコードを生成(キャッシュ付)  CUDAのカーネル呼び出しのための引数を構築  カーネル呼び出しを実行 47/50
  48. 48. CuPyの問題点  細かい単位の関数呼び出しが多くなる  GPUの帯域律速  関数合成の仕組みが必要  非同期呼び出しとメモリプールの相性が悪い  Malloc, Freeがボトルネックとなるめメモリプールを利用  現在は一つのストリームのみ使っている  時々同期する複数ストリームへメモリをどのように割り当てるか?  その他  NumPyの関数のカバー率が低い  Chainerに必要なものから実装中 48/50
  49. 49. まとめ  ディープラーニングの基礎  順伝播のみを書く  逆伝播、最適化は自動化できる  フレームワークの実装  数十を超える実装があり、競い合っている  記号型、命令型に着目した分類とそのトレードオフ  CuPy  Chainerをどのように支えているのか  NumPy準拠はつらい 49/50
  50. 50. 参考資料  MXNet 設計ドキュメント  Programming Models for Deep Learning  http://mxnet.readthedocs.org/en/latest/program_model.html  なぜGPUはディープラーニングに向いているか  http://www.slideshare.net/NVIDIAJapan/gpu-51812528  CuPy解説  http://www.slideshare.net/ryokuta/cupy  NumPy闇入門  http://www.slideshare.net/ryokuta/numpy-57587130 We are Hiring! https://www.preferred-networks.jp/job_ja 50/50

×