こんにちは。2019年に新卒としてALBERTに入社した、データソリューション本部の水船です。入社してから、画像認識プロトタイピングのツールの開発や、画像認識の研究開発案件に取り組んでいます。また、弊社では先進技術部という部署が新設され、私自身は所属は違うものの、先進技術ワーキンググループの一員として業務の20%をリサーチ業務に充てています。今回は先進技術ワーキンググループの活動として取り組んできた、「TensorRTを用いたエッジデバイス上でのDNN (Deep Neural Network) 推論高速化」について話していきます。
なぜエッジデバイス上での高速化を行うのか?
DNNモデルをシステムに実装する時に、大きく分けて、Microsoft Azureなどの「クラウドサービス」かJetsonシリーズなどの「エッジデバイス」のどちらかにDNNモデルをデプロイすることになります。クラウドサービスには計算機の維持管理コストが低く、必要な時に必要なだけの計算リソースが確保出来るなどのメリットもありますが、ネットワークを経由することによる処理の遅延やセキュリティ面の観点からエッジデバイスを選択されるお客様が増えてきています。
さらに、システムによってはリアルタイムで推論をする必要があり、厳しい処理速度の要件を満たすためにエッジデバイスを用いる以上のさらなる高速化を求められることも多いです。しかしながら、自動運転のような技術はリアルタイム処理が求められますが、精度を犠牲にすると事故につながりますので、精度を下げるような高速化はできません。高速化のためには性能の良いデバイスを使えば良いのですが、電力消費量や費用面を考えると難しい場面が非常に多いです。
そこでこの記事では、なるべく経済的に精度を落とさずに高速化するために、Jetsonシリーズで現在一番省電力・低コストであるJetson Nanoを用いて、Chainerで推論したニューラルネットのモデルに対しTensorRTを使ったらどれくらい早くなるのかを説明します。また、どのようなニューラルネットのモデルを構築すればより速度を改善できるのかも検証していきます。
高速化するにはどうすれば良いのか?
TensorRTについて触れる前に、高速化手法にはどのようなものがあるかを概観します。結論から述べると、以下の方法が考えられます。
- ONNX Runtime, TVM, TensorRTなどのDNNコンパイラを使用する
- SqueezeNetやMobileNetなどの軽量なDNNモデルを用いる
- fp32からfp16に変更する
- Knowledge Distillation
- Pruning
- 量子化
まず、DNNコンパイラについて説明します。DNNコンパイラにはいろいろあり、有名なものだとnGraphやTVM、TensorRTがあります。これらのコンパイラが何を行なっているかを一部挙げると、
- NNのLayer Fusion: 複数のネットワークの処理を一つの処理として結合。ConvolutionとReLUの演算を融合させたりできる
- メモリやオペレータレベルでの最適化: 処理を行う時に無駄な空き時間ができるが、それらの空き時間をできるだけ消すことができる
といったことを行なっています。この資料が非常にまとまっているので、もう少し詳しく知りたい方はこちらが参考になります。後でプロファイラを用いて、コンパイラによってどのような最適化が行われるかを確認していきます。
SqueezeNetなどの軽量なモデルの利用は、モデル部分の実装を変えるだけでよく、非常に導入が容易です。案件でもとりあえず動かしたい、というときはSqueezeNetをベースにして実験したりすることが多いです。ただし、精度はある程度落ちてしまうので注意が必要です。
そのほかの手法に関しては様々な場所でよく紹介されているので説明を省きますが、これらも速度向上が見込める代わりに精度を犠牲にする可能性が高く、実装も一手間必要なのでこの記事では使用を見送ります。
本記事では高速化コンパイラとして、Jetson nanoと同じくNVIDIAに開発され、Jetson Nano Developer Kit SD Card Imageにもデフォルトで入っているTensorRTを使います。
実験
上記の環境構築の元、1枚の224×224のRGB画像に対して以下の実験を行いました。
- VGG16をChainerの推論とTensorRTの推論で速度比較
- ResNet101をChainerの推論とTensorRTの推論で速度比較
- SqueezeNet v1.1をChainerの推論とTensorRTの推論で速度比較
実行環境は以下の通りです。
- NVIDIA Jetson Nano
- Python3.6.8
- Jetpack 4.2.0
- TensorRT 5.1.6.1
- CUDA 10.0
- cuDNN 7.5.0
また実行前に以下のコマンドを実行してパフォーマンスを最大化しています。
$ sudo nvpmodel -m 0 $ sudo jetson_clocks
速度比較に関しては100回推論のモデルを計算させ、その平均時間を最終的な推論時間としています。ただし、100回推論させる前に1回推論を実行し、計測時間に含めないようにしています(最初の1回はカーネル起動や計算グラフ構築のために時間がかかるため)。実際のシステムでは継続的にDNNモデルが動くことが想定されるので、1回目の推論時間は捨てた方がより現実に沿った計測になります。
実験結果は以下の通りです。
モデル | Chainer | TensorRT | Speedup |
---|---|---|---|
VGG16 | 152ms | 140ms | 8% UP |
ResNet101 | 146ms | 89ms | 64% UP |
SqueezeNet v1.1 | 24ms | 8ms | 200% UP |
SqueezeNet、さすがの速さですね。TensorRTを使うと100FPSくらい出そうです。結果を見ると、ResNet101がVGG16と比べかなり高速化されていることがわかります。ResNet101はVGG16と比較すると良い精度を出せることが多いと感じているので、さらに高速化の余地も見込めるとなると非常に嬉しいですね。ちなみにこちらの結果では、ResNet101の方が精度が良いと出ています。またSqueezeNetに至っては3倍も速度が向上しています。
以上の結果から、TensorRTによってどのモデルも速度向上されることが分かりました。しかし、これらのネットワークアーキテクチャによる差は気になるので、その原因を調べていきます。
NVIDIA Visual Profilerで速度改善の要因を探る
NVIDIA Visual Profilerで、それぞれのモデルのどの部分で時間がかかっているかを計測しました。結論としては、以下の速度改善が確認されました。
- ConvolutionとReLU, BNのLayer Fusion
- 処理の空き時間の減少
- Residual ModuleのIdentity MappingのLayer Fusion
- SqueezeNetのconcat処理の削除
一方、FC層は速度改善が見られませんでした。
ResNetはVGGと比較するとFC層が少なく、ReLUだけでなくBN層やIdentity Mappingの処理が統一されることによって、VGGと比較すると速度向上が大きかったと考えられます。また、SqueezeNetは他の手法と比べるとかなり空き時間が発生しており、その解消が大幅な速度改善につながったと考えられます。
以下の節ではこのうち、ConvolutionとReLUのLayer Fusionと処理の空き時間の解消について、Visual Profilerで可視化していきます。
ConvolutionとReLUのLayer Fusion
まず、SqueezeNetのConv1層目の挙動を確認します。上の結果がTensorRT、下の結果がChainerの推論時間のプロファイルです。ただし見やすくするために時間幅が上下で異なることに注意してください。SqueezeNetではConv1層目の次の処理がPoolingなので、それまでの処理時間を比較すれば良いことになります。
TensorRTのConv1層の推論時間は0.5msであったのに対し、Chainerの推論では2ms強の推論時間となっているため、ここの処理が4倍になっています。また、Chainerでは3つのプロセスが動いているのに対し、TensorRTでは1つの処理となっていることが確認されました。これはLayer Fusionの最適化が働いていそうですね!
他のプロセスも確認してみましたが、Convolution+ReLUの処理は2~4倍くらい速くなっていました。
- TensorRTのプロファイラ結果

- Chainerのプロファイラ結果
処理の空き時間の減少
次に処理の空き時間について確認します。上の図がTensorRTの処理で、下の図がChainerの処理です。プロファイラ結果を見ると、Chainerの推論では0.2~0.5msの空き時間が散見されるのに対し、TensorRTの推論ではほとんど空き時間がありません。このことから、TensorRTがオペレータやメモリの最適化を行なっていることを確認できました。
たかがコンマms、されどコンマmsです。それが積もり積もることで、SqueezeNetは3倍も速度向上したと考えられます。
- TensorRTのプロファイル結果

- Chainerのプロファイル結果

まとめ
この記事ではJetson Nano上でTensorRTを動かして、どれくらい速度改善されるか、またどのようなモデルがどれくらい速度改善されるかを実験し、モデルの構造によって大きく改善幅が異なることを紹介しました。近頃はプログラミングが不要の深層学習ツールなども登場し、深層学習を試す敷居は格段に下がりました。しかしながら、処理速度などの要件を満たすようにモデルを適切に改良したりすることは、まだまだツールだけでは不可能であり、今後はしっかりとモデルの中身を理解し、実社会に深層学習を実装できる技術者の需要が高まっていくと思われます。
今回は画像分類のモデルに対して高速化の実験を行いましたが、物体検知や深度推定などのより応用的なタスクに対しても高速化を試そうと考えています。タスク特有のネットワーク構造によって最適化しやすい/しにくいなどや、そもそもコンパイルできるかどうかもやってみないとわからないところがあります。次の機会にこれらの結果を紹介したいです。
今回実験をしてみて、実験条件、精度や推論速度などの実験管理の部分でもっと工夫の余地があったと感じています。ConvolutionとReLUがLayer Fusionされることを確認しましたが、今回使用した3つのモデルに入っていない、他のActivation LayerやNormalization Layerも同様にLayer Fusionされるかはやってみないとわからないので、それらを確かめるために、より多くのモデルに対して実験を行う必要があるためです。分析プロジェクトでも実験管理を工夫することによって、作業効率や再現性の向上が期待されるため、プロジェクト業務の方でも色々試していきたいです。
新技術は実験してみないとなかなか実務に活かせなかったりする一方で、機械学習分野は発展が著しいので、常日頃から新しい技術を積極的に学んでいくことが重要です。先進技術のワーキンググループでは、深層学習に関する知識・経験が弊社でもトップクラスの先輩方と、活発に議論をしながら非常に楽しくリサーチ業務をやっています。リサーチ業務はすぐプロジェクトに役立つというものではありませんが、会社の技術力向上に貢献し、お客様により大きな価値を提供するために、今後も積極的に取り組んでいきたいです。
ALBERTではこのような先進的な技術調査のマネジメントを行うメンバーやその他の様々な職種のメンバーを積極的に募集しています!ご興味のある方はこちらをご覧ください!