Slide 1

Slide 1 text

Deep Learning推論を高速化する ソフトウェア技術 Idein 中村晃一

Slide 2

Slide 2 text

自己紹介 ● 中村晃一 ● Idein代表取締役 ● https://nineties.github.io/ ● 創業前は大学で最適化コンパイラの研究などをしていました

Slide 3

Slide 3 text

宣伝 ● 第25回画像センシングシンポジウム(SSII2019)で 深層学習の高速化~高速チップ、分散学習、軽量モデル~​​ というセッションをやります。 ● 講演者の皆様 ○ 須藤さん(さくらインターネット) ○ 田中さん(Sony) ○ 内田さん(DeNA) ○ 私 ● 2019/6/12-14 @ みなとみらい ● 是非お越しください

Slide 4

Slide 4 text

研究分野 ここはbonotakeさんが話してくれたので割愛

Slide 5

Slide 5 text

弊社のコンパイラスタック

Slide 6

Slide 6 text

ソフトウェアベースの高速化は重要 ● 高性能なハードウェアが使えない場合がある ○ 金額が高い、消費電力が高い、発熱量が大きい、サイズが大きい、必要な機能が無い、供給保証 がない、ハードが枯れてない、ソフトが枯れてない、 etc ● 汎用ハードを使いたい場合がある ○ DLだけじゃなく、普通の処理もする ● ハードウェアが勝手に限界まで速くしてくれる訳ではない ○ 同じハードウェアでも、ソフトウェアによって大分速度が異なる ○ DNNは変換の自由度が高く、まだ全てハードウェア任せにできる感じではない ● 速ければ速いほど精度が上がり得る ○ 精度がクリティカルな用途では、少しでも速度を上げて計算量を稼ぎたい場面がある ● 特定のハードウェアに依存したくない場合がある ○ スマホアプリなど、様々なハードウェアで速くできる汎用的な方法が欲しい場面がある

Slide 7

Slide 7 text

ソフトウェアによる高速化 ● 大きく分けると2つの切り口がある ○ モデルのアーキテクチャ ○ 実装の技術

Slide 8

Slide 8 text

モデルアーキテクチャ ● DNNモデルの設計、探索、学習など の技術の進歩により 計算量・パラメータ数あたりの 精度が向上していっている https://github.com/tensorflow/models/tree/master/research/slim/nets/mobilenet

Slide 9

Slide 9 text

良いモデルを使いましょう ● 速いハードで遅いモデルを動かすという、もったいない例をたまに見る ○ Jetsonのデモより、ラズパイの同様のデモの方が速いという事があったり ● 遅いモデルをベースにそれを速くしたという研究をたまに見る ○ いろいろな研究の文脈があるのでそれが無意味という訳ではないが、 評価が不適切だと思う事はたびたび ● 細かい最適化よりも、まずは良いモデルを使うという事の方が重要 ● ハードウェアの特性によって、モデルの実行速度は変わる ○ 様々なモデルのベンチマークを取り、ハードとモデルの相性を理解しましょう

Slide 10

Slide 10 text

“ResNet-50から1%の精度低下でX倍速くなり、Y倍軽量になりました” ● 単純にMobileNet v2 1.4 224を使っただけでも、同じ精度で 6.7倍計算量が減り、4.2倍軽量になる top-1 top-5 MAC (M) Parameters (M) ResNet-50 75.8% 92.9% 3900 25.6 MobileNet V2 1.4 224 75.0% 92.5% 582 6.06 ● 知りたい情報は ○ 同精度の最も高速なモデルと比べてどれくらい速くなったのか? ○ 最も高速なモデルをベースにして、どれくらい速くできるのか? 例

Slide 11

Slide 11 text

1%精度を上げるのは大変 ● 高精度モデルであるほど 精度1%で稼げる計算量が 大きい。 ● ある高速化手法で1%の精度低下が 許容できる場合、特に工夫しない 場合にもそこそこ速くなる ● 高速化手法のメリットを評価する 場合に注意が必要なポイント

Slide 12

Slide 12 text

参考資料 ● DeNA内田さんによる モデルアーキテクチャの観点からのDeep Neural Network高速化 を読みましょう ● 前述のSSII2019でもご講演頂きます

Slide 13

Slide 13 text

実装の技術 ● 同じモデル、同じハードでも実装によって大分速度が変わる ○ 場合によっては数倍差が出る ● ハードウェアの特性によって最適な実装は変わる

Slide 14

Slide 14 text

DNN特有の話 ● 許容され得る変換の種類が広い ○ floating pointの足し算、掛け算の順番を変える ○ メモリ上のレイアウトを変える ○ 数値の表現を変える ■ float32 → float16, int16, int8 など ○ 数学的な式変形を行う ○ など ● 理由 ○ 認識精度が落ちなければ良い、というアプリケーションである場合が多い ○ 計算グラフで表現される為、上記の変換を正しく行う事がしやすい

Slide 15

Slide 15 text

実際どれくらい変わるのか?① ● モデル: あるsegmentationのモデル、fp32, 320x200 ● ハード: Pi 3のCPU(Cortex-A 53)の1コアを利用 ● 全てNEONによるSIMD化利用 レイヤー融合 アルゴリズム ループアンロール メモリレイアウト 実行時間(ms) × direct × NCHW 733 ○ direct × NCHW 495 ○ im2col × NCHW 286 ○ im2col ○ NCHW 175 ○ im2col ○ NHWC 166 比較的単純な最適化のみで 4倍強変わる

Slide 16

Slide 16 text

実際どれくらい変わるのか?② ● モデル: MobileNet V2 1.0 224x224, 1000クラス分類 ● ハード: STM32H7(Cortex-M7) ● float32のまま乗せたもの(レイヤー融合等はしている):9秒 ● float32のままで最適化し3.1秒 ○ Tightly Coupled Memory(TCM)を上手く使う ○ Cortex-M7のSIMD命令 ○ メモリ配置最適化(特にアラインメント) ○ など ● int16化して最適化し1.1秒 ○ Cortex-M7のSIMD命令 ○ など (講演時、間違えてここに入れてしまいましたので訂正します )

Slide 17

Slide 17 text

レイヤー融合 Convolution Batch Normalization Convolution Convolution ReLU Convolution+ReLU 事前にWeight同士の積、 和を計算しておいて 一つにまとめてしまう Convolutionの最内ループ にReLUをインライン化する など

Slide 18

Slide 18 text

アルゴリズム ● 2D Convolutionのアルゴリズム ○ 入力サイズ=HxW, フィルタサイズ=3x3の場合 手法 概要 演算回数 メモリ使用量 備考 Direct 定義通り - - メモリが弱いプロセッサだとこれが強い場合がある im2col 行列乗算 同じ 入力が9倍 非常によく使われる winograd 高速乗算 4/9程度に減少 Weightが16/9倍 よく使われる。Separable Convに弱い。 FFT 高速乗算 最大2/9程度に減少 WeightがHW/9倍 複素演算が必要。あまり使われない。 ● 詳しくはConvolutionの数理とアルゴリズム

Slide 19

Slide 19 text

ループ最適化 ● 古典的な最適化手法。良く効く。奥が深い。 ○ ループアンローリング ○ ループ交換 ○ ソフトウェアパイプライニング ○ など ● ハードウェア特性を意識する事が必要 ○ アクセス順序 ○ アラインメント ○ レジスタの数 ○ ハードウェアパイプラインの構造 ○ など

Slide 20

Slide 20 text

● テンソルをメモリ上にどう配置するか? ○ 以下は2Dイメージの場合の絵 ○ 実際はもう一次元(N,バッチ)ある メモリレイアウト 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 5 2 6 3 7 4 8 1 2 3 4 5 6 7 8 H W C アドレス CHW HWC HCW など (講演時、以下の図が誤っていましたので修正しました )

Slide 21

Slide 21 text

並列化 ● SIMD ● マルチコア ● … N C H W ● どこでどう並列化するのか?

Slide 22

Slide 22 text

テンソルのshapeによって最適実装は変わる ● 長さ16のSIMD演算器があったとして、どう使う? 224 あるレイヤ: 224x224の3チャンネル 例えばこの辺の16pixelを計算 あるレイヤ: 7x7の1280チャンネル 7 同じコードだと ここの計算が無駄 16

Slide 23

Slide 23 text

フィルタサイズでも最適実装は変わる 3 3 1 1

Slide 24

Slide 24 text

と言った事をいろいろ追求していった結果 ● こんな感じに(一番多いところを取ってますが ) ※python利用はカーネルのコード生成の為。 コンパイラ自体はHaskell実装。

Slide 25

Slide 25 text

VideoCore IVでの高速化 ● Raspberry PiシリーズにはVideoCore IVというGPUが搭載されている BCM2835 BCM2837 CPU 1GHz single-core ARM1176JZF-S 1.2GHz 64-bit quad-core ARM Cortex-A53 GPU VideoCore IV CPU peak performance 2Gflops 38.4Gflops GPU peak performance 28.8Gflops 28.8Gflops

Slide 26

Slide 26 text

VideoCore IVのアーキテクチャ ● 16wayのSIMDコアが4x3個 ○ fp32の乗算,加算 ○ Special function unit ● HostからGPUへは L2 Cache経由とDMA ● GPUからHostへはDMAのみ ● Register AllocationやScheduling等 のハードウェア機能はない ● よくある感じの(ちょっと昔の) アーキテクチャ Using Raspberry Pi GPU for Deep Neural Networkより

Slide 27

Slide 27 text

VideoCoreを使う為のソフトウェア ● py-videocoreを使うと、VideoCoreのアセンブリプログラミングができます ● github.com/Idein/qmkl が単精度行列乗算の実装例 最近使ってくれた方が

Slide 28

Slide 28 text

行列乗算のみGPU化 pure GPU化 もろもろのGPU化や 特定計算用の特化コー ド用意など レイヤー融合や メモリ転送最適化など golf, メモリ最適化 タイリング最適化など いろいろ googlenet top1:68.7%, top5:88.9% mobilenet v1 top1:70.9%, top5:88.9% mobilenet v2 top1:71.8%, top5:91.0% depthwise, pointwise改善 メモリ管理改善などいろいろ ※ラズパイの GPU周波数に対する誤解があり、 ここ以前はオーバークロック状態 (400MHz)で測っているケースがありました。 ここ以後はデフォルト周波数 (300MHz)での値です。

Slide 29

Slide 29 text

https://www.youtube.com/watch?v=DyR183n0ZXA

Slide 30

Slide 30 text

https://www.youtube.com/watch?v=L_kAUnAgkfg

Slide 31

Slide 31 text

https://www.youtube.com/watch?v=hHUSSP2SLLo

Slide 32

Slide 32 text

最近取り組んでいる事 ● ラズパイでの高速化はほぼサチった気がする ○ (何回か過去にそう思ったけど、気のせいだったことも ) ● 大分知見が溜まったので、他のハードウェアに広げていく事を進めている ○ ARM Cortex-A ○ ARM Cortex-M ○ ESP32 ○ FPGA などを調査研究している

Slide 33

Slide 33 text

宣伝 ● Actcastというサービスを開発しています。α版公開中で無料です。 ● さっきのデモが、皆さんの手元で動きます。是非お試しを。 ● actcast.io

Slide 34

Slide 34 text

まとめ ● 良いモデルを使いましょう ○ ハード毎に特性が違うのでベンチマークを取りましょう ● 良い実装を研究しましょう ○ 同じモデル、ハードでも実装によって大分差があります ○ “まだ”、自動で最適実装が得られる感じにはなっていないと思う。いずれそうなるかも。 ● 既にあるプロセッサでも、結構計算できるのでtryしましょう