こんにちは、AnyTechの赤川です。
この記事では、PyTorchとPyTorchのC/C++版であるLibTorchとの間で比較検証を行い、LibTorchの採用がもたらすモデルの推論速度の改善度合いについて、考察しました。
背景
PyTorchはPythonicな記述でモデル開発ができ、エコシステムもとても充実しているディープラーニングフレームワークです。
PyTorchを利用している人の多くはプログラミングにPythonを普段から利用している人が多いのではないかと思います。Pythonを利用していると、よく「Pythonは動作速度が遅い」ということを耳にする方も多いと思います。確かに、非効率な記述をすれば動作がとても遅くなることが多々あり、スピードを求められるシステムにPythonを利用するときは十分に注意する必要があります(もちろん、適切にコーディングしてあげれば速度面でもいいパフォーマンスを出せる場合があるので一概にはいえませんが!)。
Pythonで動作速度を改善したいとなった場合、多くの人はPythonの既存のライブラリやデフォルトで用意されている仕組みをうまく使うことで高速化させようと思う方が大多数だと思います。一方、Python以外を利用して高速化することも可能です。その例がC/C++言語(以下、Cと記載)を用いたPythonモジュールの開発です。一般的に利用されているPythonはCで書かれているCPythonというものを利用しており、Cとの互換性がとてもいいです。なので、例えばPythonでは苦手なfor文のネストも、Cで実装してあげれば高速化が見込まれる場合も多々あります。
話を戻すと、PyTorchではCで利用するためにLibTorchというものが提供されています。LibTorchはCで実装できるので、AIを開発するためのPython高速化という意味では、LibTorchを活用できるとメリットがあるかなと考えています。そこで、今回はPyTorchとLibTorchのパフォーマンスの比較をしてみました。
検証条件
検証を行うにあたり、今回は学習時間ではなく単純な推論時間(モデルにテンソルを入力して出力されるまでの時間)を指標としてパフォーマンスを比較しようと思います。主な実験条件は以下になります。
- 実験環境
- iMac (Retina 5K, 27-inch, 2017)
- プロセッサ:3.4 GHz クアッドコアIntel Core i5
- メモリ:40 GB 2400 MHz DDR4
- 検証モデル
- PyTorchとLibTorchともに一からモデルを構築(可能な限り両者同じ実装にしていますが、一部異なる場所があります)
- MLP
- 入力:(バッチサイズ、100)
- レイヤー:100 →256→512→1024→2048→4096
- ResNet50
- 入力:(バッチサイズ、3、224、224)
- パフォーマンス測定方法
- バッチサイズを複数用意(1、2、4、8、16、32、64、128)
- 同じ条件で50回実行し、その平均時間とする
検証結果
MLP
MLPの実験では次のような結果となりました。大きな差はないものの、バッチサイズに関係なく数msほどLibTorchを利用した方が早いという結果になりました。
ResNet50
ResNet50の実験では次のような結果となりました。バッチサイズが小さいときは両者ほとんど変わらないですが、20を超えたあたり(今回の検証では32以上)になると徐々に差が大きくなります。本結果から、LibTorchを利用した方が高速に処理できると言えます。なお、こちらの結果はMLPの時と違い縦軸のスケールが大きいので、大きなバッチサイズで推論する場合は、かなり実行時間に差が出ることが推測されます。
まとめ
今回の検証では対象モデルはMLPとResNet50だけであり、かつ学習ではなく推論を行いました。なので今回の実験環境以外のシチュエーションではPyTorchの方が有利な場面もあると想定されます。また、PythonでプログラミングをするのはCを用いるのに比べてとても短時間で(慣れている人はCの方が早いかもですが)実装できるため、例えば「最初のモデル構築とテスト」はPythonで、「システムとして導入するため」にはCで書くという分け方をしてもいいかなと思います!
今回はPython高速化シリーズの一つ目としてPyTorchとLibTorchの比較を行いました。まだまだ少ない条件での検証なので、今後シリーズ化して色々と検証していこうと考えています。