OpenCVのDNNモジュールがCUDAバックエンドに対応した
はじめに
1年ちょっとぶりにブログ更新しました、お久しぶりです
さて、去年12月にOpenCVの最新バージョンであるOpenCV 4.2.0がリリースされました
そのChange Logをみると嬉しい更新が
DNN module:
Integrated GSoC project with CUDA backend: #14827
DNNモジュールにCUDAバックエンドが追加され、ついにNVIDIA GPUでもDNNを動かせるようになったようです!
そこで今回は、手持ちのGPUで実際にDNNモジュールが速くなるのか検証してみました
結果だけ知りたい方は目次から計測結果に飛んでください
目次
環境構築
CUDAバックエンドに対応するために、OpenCV 4.2.0をソースからビルドします
私のビルド環境は以下の通りです
- Visual Studio 2019
- CUDA Toolkit 10.2
また、追加で以下が必要になります
cuDNNのインストール
手持ちのCUDA Toolkitのバージョンに対応したcuDNNをダウンロード・解凍し、
bin
,include
,lib
の中身をCUDA Toolkitの同名のフォルダ以下にコピーしておきます
CMakeの設定
CMake(cmake-gui)を立ち上げ、ソースとビルドのパスを指定したら一旦Configure
次に以下の項目を設定していきます
WITH_CUDA
にチェックOPENCV_DNN_CUDA
にチェックOPENCV_EXTRA_MODULES_PATH
にoepncv_contrib/modules
のパスを設定CUDA_ARCH_BIN
から古いバージョン番号を消す※
設定したら再度Configureし、問題なければGenerateでプロジェクトを作成
あとはビルドしてひたすら待ちましょう!
※CUDA_ARCH_BIN
はデフォルトで3.0 3.5 3.7 5.0 5.2 6.0 6.1 7.0 7.5
と設定されていると思いますが、そのままConfigureしたら以下のエラーが発生
CUDA backend for DNN module requires CC 5.3 or higher. Please remove unsupported architectures from CUDA_ARCH_BIN option.
DNNモジュールは古いバージョンのCUDAに対応してないようです
自分のGPUはGTX 1080(SM61)なので6.1以上のものだけ残しました
計測用コード作成
前回記事で紹介したSemantic Segmentationのサンプルopencv/samples/dnn/segmentation.cpp
を使用します(ネットワークも前回同様Enetです)
推論処理net.forward()
の前後にタイマーを挟んで、適当回数実行した際の中央値をとります
さて、CUDAバックエンドを有効化する方法は使い方はいたって簡単で、実行時の引数に以下を追加するだけ!
--backend=5 --target=6
これはそれぞれネットワークにDNN_BACKEND_CUDA(=5)
とDNN_TARGET_CUDA(=6)
を設定していることになります
比較用に、ターゲットをCPU(--target=0
)とOpenCL(--target=1
)に設定した際の処理時間も計測しました
計測結果
計算機は以下の通りです
- CPU : Core-i7 6700K(4.00 GHz/4Core/8T)
- GPU : GeForce GTX 1080
入力サイズ1024×512
に対するEnetの推論時間はおおよそ以下の通りになりました
CPU | OpenCL | CUDA |
---|---|---|
350[milli sec] | 100[milli sec] | 21[milli sec] |
さすがCUDAバックエンドは圧倒的に速いですね!このサイズで50FPS近く出るのは驚きです
次いでOpenCLですが、実のところOpenCLを指定した際にどのデバイスで実行されているのかよく知りません…(CPUよりは速くなってるので、内蔵GPUで動いてるのかな?)
おわりに
CUDAバックエンドに対応したDNNモジュールを動かし、高速に動作することを確認しました
DNNを利用したアルゴリズム開発において、OpenCVが一層便利になったのではないでしょうか!