3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NVIDIA CV-CUDAを動かしてみた - 情報まとめ -

Last updated at Posted at 2023-06-07

情報(と頭の)整理を兼ねて、先日GTC Spring 2023のkeynoteで触れられたCV-CUDAについて興味があったので周辺情報も含めて個人の備忘録として簡易的に纏めてみたいと思います。このライブラリ、同じくkeynoteで触れられたVPFとの相性も良さそうなので、余力があればそちらも後日まとめられたらなと思います。(願望)

はじめに

本ブログの元情報は主に以下の4つになります。もし本まとめ記事で気になった部分があればぜひ以下のリンクから詳細をご確認下さい。

  1. https://github.com/CVCUDA/CV-CUDA
  2. https://cvcuda.github.io/
  3. https://blogs.nvidia.com/blog/2022/09/20/computer-vision-cloud/
  4. https://developer.nvidia.com/zh-cn/blog/cv-cuda-high-performance-image-processing/

CV-CUDAとは ?

"CV"と名前についている通り、オープンソースのCV(Computer Vision)処理GPUプリミティブです。2023年3月に公開され、2023年5月現在、v0.3.0-betaとして公開されています。(ライセンスはApache2.0です)
インターネットのトラフィックの大半は動画像であり、それらに対してAIベースの画像処理パイプラインを構築するケースが増えています。CVベースの前処理や後処理が必要であるケースも多く、CV-CUDAはそれらのパイプラインをGPUで高速化する事を目的としています。

CVCUDAはC/C++/Pythonの3つの言語から呼び出す事が可能であり、画像処理結果、オペレータなどOpenCVとできるだけ揃えるようにデザインし、OpenCVからCVCUDAへの移行がしやすいように設計されているとの事です。

以下がCVCUDAの全体アーキテクチャ図になります。
image.png
図1: CVCUDA Architecture Overview
Tech Blog:CV-CUDA high-performance image processing acceleration libraryより引用

CV-CUDAにはメインのモジュールとして以下の3つが存在します。

  • NVCV
    • 画像抽象化クラス、バッチクラス、メモリマネージメントクラスなどCVCUDAのコア機能が実装されている
  • Operators
    • リサイズ、各種フィルタ処理などCV演算が実装されている
  • CV-CUDA Tools
    • オペレータ開発時に必要な様々な機能が実装されている

CVCUDAはnumpyやpytorchなどAIワークロード開発に使われるライブラリとも簡単に連携可能です。またスループットが出るようにバッチ処理にも対応しています。以下はCVCUDA各種オペレータの性能ベンチマークになります。
image.png
図2: CV-CUDA performance comparison ( CPU: Intel(R) Core(TM) i9-7900X CPU @ 3.30GHz )
Tech Blog:CV-CUDA high-performance image processing acceleration libraryより引用

CV-CUDA オペレータ

"CV"とつくとてOpenCVのAPIカバレッジが気になる所。v0.3.0-beta時点でのCV-CUDAオペレータ一覧はDeveloper Guideによると以下の通りです。

オペレータ名 概要
Adaptive Thresholding 適応2値化
AverageBlur 平均ぼかし
BilateralFilter バイラテラルフィルタ
Bounding Box バウンディングボックスの描画
Bounding Box Blur 矩形選択部分へのぼかし
CenterCrop クリッピング(トリミング)
ChannelReorder 画像チャンネルの順番をシャッフル
Composite マスクに従って2枚の画像を合成
Conv2D 二次元畳み込み
CopyMakeBorder 画像のパディング
CvtColor 色空間変換
DataTypeConvert 画像データの型変換
Erase 指定した領域を削除
Flip 反転
GammaContrast ガンマ補正
Gaussian ガウスぼかし
JointBilateralFilter ジョイントバイラテラルフィルタ
Laplacian ラプラシアンフィルタ
MedianBlur メディアンフィルタ
Morphology モルフォロジー変換
Non-Max Suppression IOUと信頼度の閾値に基づき、重なり合う箱の集合から最適なバウンディングボックスを選択
Normalize 正規化
PadStack 複数画像をパディングしてスタックする
PillowResize python-pillow のアルゴリズムを使用したリサイズ
Reformat 平面画像←→非平面画像
Remap 幾何学変換
Resize リサイズ
Rotate 回転
Thresholding 2値化
WarpAffine アフィン変換
WarpPerspective 射影変換

サポートしているオペレータ数はOpenCVに比べるとまだ少ないですが、ある程度CV界隈の人には直感的どのような処理が分かる命名になっていそうです。ブログによるとサポートするオペレータは今後も増える予定のようです。
(注: OpenCVライクな引数になっていますが引数など完全互換な訳ではなく癖はありそうです)

CV-CUDAのインストール

インストールガイドに従ってここからdebianパッケージをダウンロードし、インストールします。
今回は、他のサーバでもCV-CUDAを試してみたかったので、実験環境を移動させやすいようにdocker container化する事にしましたが、勿論ホストに直接環境構築しても大丈夫です。CV-CUDAはC/C++から呼び出す事も可能ですが、今回はCV-CUDAのpython環境を構築する事にしました。

注:
github上のガイドにはPython wheelからのインストール方法の記載がありますが、v0.3.0-beta現在、wheelのインストールだけではエラーが出るような気がしますので(一部の必要モジュールが含まれない)、debianパッケージからのインストールがおススメです

まずはCV-CUDAの実験用Dockerコンテナを作成します。

CV-CUDA dockerコンテナの作成
$ wget https://gist.githubusercontent.com/acc-mu3n/afd50123316e43b6d49e8ecf8193908a/raw/ad5158680adab72c0d6afd9e39997cc666024c20/Dockerfile
$ mv Dockerfile ./Docker
$ docker build -t cvcuda-test:0.3.0-beta ./Docker 

今回はCuPyやPyTorch、OpenCVなど実験に使いそうなモジュールも一緒にインストールしていますが必須ではありません。
次に作成したコンテナを起動します。

CV-CUDA dockerコンテナの起動
$ docker run --rm -it --network=host --gpus all -e DISPLAY=$DISPLAY -v $HOME/.Xauthority:/root/.Xauthority cvcuda-test:0.3.0-beta bash

cvcudaモジュールがimport出来るかテストします。

cvcuda import テスト
$ python3 -c "import cvcuda"

これでCV-CUDAのインストールが完了しました。

CV-CUDAのpythonインターフェースを触ってみる

シンプルなコードでテスト

CV-CUDAの環境構築が出来たら、早速コードを実行してみようと思います。
以下は、画像を読み込み、いくつかのCVCUDAの関数を適用するというシンプルなコードのサンプルです。(フィルタは適当に選んだものです)

cvcuda-simpe-test.py
import cvcuda
import cv2
import numpy as np
import cupy as cp

# load image
img = cvcuda.as_image(cp.asarray(cv2.imread("./tabby_tiger_cat.png")))
img_tensor = cvcuda.as_tensor(img)

print("Src image shape:",img_tensor.shape)

# resize image
resized_img = cvcuda.resize(img_tensor,(1,244,244,3),cvcuda.Interp.CUBIC)
print("Resized image shape:",resized_img.shape)

# cropping
cropped_img = cvcuda.center_crop(resized_img,[200,200])
print("Cropped image shape:",cropped_img.shape,"\n")

# apply filter to image
gauss_img = cvcuda.gaussian(cropped_img,[9,9],[0.5,0.5],cvcuda.Border.REFLECT)
bilat_img = cvcuda.bilateral_filter(gauss_img,40,20,20,cvcuda.Border.REFLECT)

# export to image
result = cp.asarray(bilat_img.cuda())
cv2.imwrite("result.png",cp.asnumpy(result[0]))

OpenCVの関数で同等の処理を実行した場合との比較をしたかった為、最終的にはこのようなコードを作成し、実行しました。

opencv-cvcuda-test.pyの実行
$ python3 opencv-cvcuda-test.py
cvcuda exec...
Src image shape: (1, 720, 720, 3)
Resized image shape: (1, 244, 244, 3)
Cropped image shape: (1, 200, 200, 3)

opencv exec...
Src image shape: (720, 720, 3)
Resized image shape: (244, 244, 3)
Cropped image shape: (200, 200, 3)
$ ls |grep .png
result.png
result_opencv.png
tabby_tiger_cat.png

result.pngがCVCUDA、result_opencv.pngはOpenCVを用いた画像処理の結果です。

cvcuda(result.png) opencv(result_opencv.png)
result.png result_opencv.png

OpenCVと違って境界処理を明示的に指定する必要があったり違いは感じたので、慣れるのに少し時間が必要かもしれませんが、推論の前処理後処理に便利そうです。ベータ版なのでこれからの進化にも期待したい所です。

まとめ

今回は、AIベースの画像処理パイプラインの前処理、後処理に便利なCV-CUDAの概要、インストール方法、簡単な使い方を纏めました。
次回があれば、バッチ処理、動画の読み込みから推論までの一連のパイプラインの組み方、性能計測の為のプロファイリング等々してみようかなと思います。つづく(かも)

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?