先日、ONNX Runtimeを使って、MNISTの推論を試した。
今回は、dlshogiのResnet 10ブロック、192フィルタのモデルを使って、GPUで実行した場合の速度と、CPUで実行した場合の速度を比較した。
測定条件
GPUでのONNXの推論にはTensorRT(FP16)を使用する。
CPUの測定にはONNX Runtimeを使用し、デフォルトのCPUプロバイダと、MKL-MLを有効にしたCPUプロバイダ、DNNLプロバイダのそれぞれで測定した。
OSはWindows 10 64bit、GPUはGeForce 2080Ti、CPUはCore i7-6700K(4コア、8スレッド、4GHz)を使用した。
推論の対象は、floodgateの棋譜からサンプリングした1万局面、バッチサイズは128とした。
それぞれの条件で、3回測定し、その平均時間を求める。
デフォルトCPUプロバイダ
NuGetでビルド済みバイナリが提供されているので、Microsoft.ML.OnnxRuntimeをインストールして使用した。
条件 | 平均処理時間 |
---|---|
CPU(デフォルト) | 32.6秒 |
GPUよりも、106.7倍遅い。
CPU使用率は、ほぼ100%で張り付いている。
なお、NuGetで取得できるCPUプロバイダはOpenMPが有効になっているので、スレッド数は自動で調整されている。
グラフ最適化のオプションを設定してみたが、変わらなかった。
session_options.SetGraphOptimizationLevel(ORT_ENABLE_ALL);
ORT_DISABLE_ALLにすると2倍くらい遅くなったため、デフォルトでグラフの最適化は有効になっているようだ。
MKL-MLを有効にしたCPUプロバイダ
NuGetから取得できるので、Microsoft.ML.OnnxRuntime.MKLMLをインストールして使用した。
条件 | 平均処理時間 |
---|---|
CPU(MKL-ML) | 37.5秒 |
デフォルトのCPUプロバイダより遅くなっている。
CPU使用率は、余裕が残っている。
CPUを使い切っていないので、スレッド数を明示的に設定してみた。
session_options.SetIntraOpNumThreads(8);
すると、CPU使用率は100%近くになった。
処理時間は、
条件 | 平均処理時間 |
---|---|
CPU(MKL-ML、スレッド8) | 31.3秒 |
となり、デフォルトCPUプロバイダより速くなった。
MKL-MLの場合は、スレッド数を調整した方が速くなる場合があるようだ。
なお、ONNX Runtimeのスレッド数の設定には、SetInterOpNumThreadsとSetIntraOpNumThreadsがあるが、前者はグラフ全体のスレッド数、後者はノード内の実行を並列化する際のスレッド数を設定する。
参考:https://github.com/microsoft/onnxruntime/issues/2177
SetInterOpNumThreadsの方も8に変えてみたが、処理時間に変化はなかった。
DNNLプロバイダ
ビルド済みバイナリが提供されていないため、ソースからビルドした。
スタートメニューから「x64 Native Tools Command Prompt for VS 2019」を起動して、GitHubのレポジトリをcloneして以下のようにビルドする。
git clone --recursive https://github.com/Microsoft/onnxruntime cd onnxruntime .\build.bat --config RelWithDebInfo --build_shared_lib --parallel --use_dnnl --cmake_generator "Visual Studio 16 2019"
「build\Windows\RelWithDebInfo\RelWithDebInfo」にビルド済みライブラリができる。
DNNLプロバイダを有効にするには、
#include <dnnl_provider_factory.h> OrtSessionOptionsAppendExecutionProvider_Dnnl(session_options, 1);
のように、ソースコードでプロバイダを追加する処理が必要になる。
処理時間は、
条件 | 平均処理時間 |
---|---|
CPU(DNNL) | 35.0秒 |
となり、スレッド数を調整したMKL-MLよりも遅い。
CPU使用率は、ほぼ100%になっている。
まとめ
ONNX Runtimeを使用して、CPUでdlshogiのモデルの推論を行った。
GPUと比較した場合、100倍以上遅くdlshogiをCPUで実行しても、とりあえず動かせる程度で強さは期待できなそうだ。
CPUのプロバイダの比較では、MKL-MLを有効にしたプロバイダが一番速かった。
ただし、デフォルトの設定ではCPUを使い切らないため、スレッド数を調整する必要がある。
測定に使用したソースは以下の場所にある。
DeepLearningShogi/onnx_benchmark.cpp at feature/onnx_runtime · TadaoYamaoka/DeepLearningShogi · GitHub