🚀

InsightFaceをGPUで動かしてみた

2021/08/08に公開

目次

初めに

ここ半月で3本に渡り、InsightFaceに関する記事を書きました。

これまではすべてCPU上で動作させていましたが、実際に顔検出に使用するには少々遅いので、NVIDIAのGPU上で動かしてみました。
結果から言えば、あっさりと動作しました。

InsightFaceをGPUで動かす

InsightFaceをGPUで動かすためには、以下の2箇所を修正する必要がありました。

  • onnxruntimeパッケージをonnxruntime-gpuパッケージに変更する。
  • ベースイメージを、NVIDIA Container Runtime用のDockerイメージに変更する。

具体的な修正箇所は、以下のPull Requestを参照してください。

https://github.com/nayutaya/202107-face-detector/pull/3

ONNX Runtimeパッケージの変更

InsightFaceでは、推論処理に「ONNX Runtime」が使用されています。
そのため、GPUで処理するためには、CPU版のパッケージ(onnxruntime)からGPU版のパッケージ(onnxruntime-gpu)に変更する必要がありました。

InsightFace自体は、既にGPU版のパッケージが考慮されているため、インストールするパッケージの変更だけで済みます。

ベースイメージの変更

Docker上でGPUを使用するため、NVIDIA Container Runtime(NVIDIA Docker)を使用しました。
それに伴い、CPU版ではDockerイメージのベースイメージとしてubuntu:20.04を使用していましたが、GPU版ではnvidia/cuda:11.0.3-cudnn8-devel-ubuntu20.04に変更しました。

汎用的(?)な「ベースイメージの探し方」は以下の通りです。

  1. ONNX Runtimeの「CUDA Execution Provider」ページを確認し、要件(CUDAバージョンなど)を調べる。
  2. DockerHubの「nvidia/cuda」からその要件を満たすDockerイメージを探す。

処理時間の測定

CPUからGPUに変更することで、処理時間がどう変化したのかを測定しました。
測定のため、顔検出サーバに処理時間の測定処理を追加しました。詳しくは以下のPull Requestを参照してください。

https://github.com/nayutaya/202107-face-detector/pull/4

測定条件

処理時間の測定は、以下の条件で実施しました。

環境

以下の環境で顔検出サーバ(detector-insightface)を動作させ、処理時間を測定しました。

  • 環境1(CPU):
    • MacBook Pro
    • CPU: Intel Core i7 1068NG7 2.3GHz 4コア/8スレッド
  • 環境2(CPU):
    • 自作PC
    • CPU: AMD Ryzen 7 3700X 3.6GHz 8コア/16スレッド
  • 環境3(GPU):
    • 自作PC
    • CPU: AMD Ryzen 7 3700X 3.6GHz 8コア/16スレッド
    • GPU: GeForce GTX 1070 8GB
    • NVIDIAドライバ: 460.91.03
    • CUDA: 11.0.3

コード

測定対象のコードとして、20210808aタグのコードを使用しました。

https://github.com/nayutaya/202107-face-detector/tree/20210808a

画像ファイル

測定対象の画像ファイルとして、Gitリポジトリに同梱しているpakutaso_43730.jpg(1人)、pakutaso_5574.jpg(4人)を使用しました。

コマンド

測定には以下のコマンドを使用しました。

curl --silent \
  --request POST \
  --header "Content-Type: multipart/form-data" \
  --form "file=@pakutaso_43730.jpg;type=image/jpeg" \
  http://localhost:8000/detect \
  | jq .response.detectionTimeInNanoseconds

curl --silent \
  --request POST \
  --header "Content-Type: multipart/form-data" \
  --form "file=@pakutaso_5574.jpg;type=image/jpeg" \
  http://localhost:8000/detect \
  | jq .response.detectionTimeInNanoseconds

測定回数

測定は4回行い、1回目は破棄し、残り3回の平均値を結果としています。

測定結果

測定結果は以下の通りです。

環境 CPU/GPU pakutaso_43730.jpg pakutaso_5574.jpg
環境1 CPU 1,588 ミリ秒 5,177 ミリ秒
環境2 CPU 241 ミリ秒 687 ミリ秒
環境3 GPU 50 ミリ秒 152 ミリ秒

CPUが同じ「環境2」と「環境3」を比べてみると、4.5倍ほどの速度で動作している様です。劇的とまでは行かないにしろ、やはりGPUは早いですね。

また、検出される顔が増えると処理時間が増えることも確認できます。顔器官点検出、顔属性推定は顔毎に行われるので当然ですね。

CPUでも1秒あたり4フレーム、GPUだと20フレームを処理できるので、リアルタイムは難しいですが、多くのアプリケーションに適用できそうです。

最後に

今回はInsightFaceのGPUでの動作に挑戦してみました。結果として、拍子抜けするぐらいあっさり成功しました。

高速に顔検出できるようになったので、動画の処理にも挑戦したいと思っています。

InsightFaceを使って動画から顔検出してみた』に続く。

Discussion