Windows - DirectML
DirectML 実行プロバイダー
Section titled “DirectML 実行プロバイダー”注意:DirectMLは持続的エンジニアリング段階にあります。 DirectMLは引き続きサポートされますが、新機能の開発はWindowsベースのONNX Runtime展開のためにWinMLに移行しました。WinMLは同じONNX Runtime APIを提供しつつ、ハードウェアに基づいて最適な実行プロバイダーを動的に選択します。インストール手順については、WinMLインストールセクションを参照してください。
DirectML実行プロバイダーは、DirectMLを使用してONNXモデルの推論を高速化するONNX Runtimeのコンポーネントです。DirectML実行プロバイダーは、幅広いハードウェアサポートを犠牲にしたり、ベンダー固有の拡張機能をインストールする必要なく、一般的なGPUハードウェアを使用してモデルの評価時間を大幅に改善することができます。
DirectMLは、Windows上での機械学習のための高性能でハードウェアアクセラレーションされたDirectX 12ライブラリです。DirectMLは、幅広いサポートされているハードウェアとドライバーで、一般的な機械学習タスクにGPUアクセラレーションを提供します。
スタンドアロンで使用する場合、DirectML APIは低レベルのDirectX 12ライブラリであり、フレームワーク、ゲーム、その他のリアルタイムアプリケーションなどの高性能、低レイテンシのアプリケーションに適しています。DirectMLのDirect3D 12とのシームレスな相互運用性、低オーバーヘッド、ハードウェア間での適合性により、DirectMLは、高性能が望まれ、ハードウェア間での結果の信頼性と予測可能性が重要である場合に、機械学習を加速するのに理想的です。
DirectML実行プロバイダーは現在、DirectMLバージョン1.15.2を使用しており、 Gridsample 20: 5dとDeformConv(まだサポートされていません)を除き、最大でONNX opset 20(ONNX v1.15)までサポートしています。より高いopsetバージョンを必要とするモデルの評価はサポートされておらず、パフォーマンスが低下します。注意:DirectML ONNX opsetのサポートは、ONNX Runtimeのサポートとは異なる場合があります。ONNX Runtimeのサポートについては、こちらを参照してください。
インストール
Section titled “インストール”DirectML EPを搭載したORTのビルド済みパッケージはNuget.orgで公開されています。参照:ONNX Runtimeのインストール。
DirectML実行プロバイダーには、DirectX 12対応デバイスが必要です。過去数年間にリリースされたほとんどすべての市販のグラフィックカードはDirectX 12をサポートしています。互換性のあるハードウェアの例をいくつか示します。
- NVIDIA Kepler (GTX 600シリーズ)以上
- AMD GCN 第1世代 (Radeon HD 7000シリーズ)以上
- Intel Haswell (第4世代コア) HD統合グラフィックス以上
- Qualcomm Adreno 600以上
DirectMLは、Windows 10、バージョン1903、および対応するバージョンのWindows SDKで導入されました。
DirectML実行プロバイダーをビルドするための要件:
- Visual Studio 2017ツールチェーン
- Windows 10、バージョン1803用のWindows 10 SDK (10.0.17134.0) (またはそれ以降)
DML EPを含むonnxruntimeをビルドするには、build.batに--use_dmlフラグを指定します。
例:
build.bat --config RelWithDebInfo --build_shared_lib --parallel --use_dmlDirectML実行プロバイダーは、x64 (デフォルト)とx86の両方のアーキテクチャのビルドをサポートしています。
注意:ONNX Runtime with DirectMLをビルドできます。これにより、ビルドの一部としてDirectML再頒布可能パッケージが自動的にダウンロードされます。追加のライセンス情報については、NuGetのドキュメントを参照してください。
DML対応ビルドのonnxruntimeでC APIを使用する場合、DirectML実行プロバイダーはinclude/onnxruntime/core/providers/dml/dml_provider_factory.hに含まれる2つのファクトリ関数のいずれかを使用して有効にできます。
OrtSessionOptionsAppendExecutionProvider_DML 関数
Section titled “OrtSessionOptionsAppendExecutionProvider_DML 関数”与えられたdevice_id(アダプターインデックスとも呼ばれる)を持つハードウェアアダプターで実行するDirectML実行プロバイダーを作成します。デバイスIDは、IDXGIFactory::EnumAdaptersによって与えられるハードウェアアダプターの列挙順に対応します。device_idが0の場合は常にデフォルトのアダプターに対応し、これは通常、システムにインストールされているプライマリディスプレイGPUです。複数のGPUを搭載したシステムでは、プライマリディスプレイ(GPU 0)は、特にバッテリー寿命がパフォーマンスよりも優先されるデュアルアダプター搭載のラップトップでは、最もパフォーマンスの高いGPUではないことが多いことに注意してください。そのため、タスクマネージャーのパフォーマンスタブでどのGPUがどれであるかを確認できます。負のdevice_idは無効です。
C APIの例:
OrtStatus* OrtSessionOptionsAppendExecutionProvider_DML( _In_ OrtSessionOptions* options, int device_id );C# APIの例:
NugetパッケージMicrosoft.ML.OnnxRuntime.DirectMLをインストールし、次のコードを使用してDirectML EPを有効にします。
SessionOptions sessionOptions = newSessionOptions();sessionOptions.GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL;sessionOptions.AppendExecutionProvider_DML(0);SessionOptionsAppendExecutionProvider_DML1 関数
Section titled “SessionOptionsAppendExecutionProvider_DML1 関数”与えられたDirectMLデバイスを使用し、提供されたD3D12コマンドキューで作業を実行するDirectML実行プロバイダーを作成します。DirectMLデバイスとD3D12コマンドキューは、同じ親ID3D12Deviceを持つ必要があります。そうでない場合はエラーが返されます。D3D12コマンドキューは、DIRECTまたはCOMPUTEタイプである必要があります(D3D12_COMMAND_LIST_TYPEを参照)。この関数が成功した場合、作成された推論セッションはdml_deviceとcommand_queueオブジェクトの両方への強い参照を維持します。
OrtStatus* SessionOptionsAppendExecutionProvider_DML1( _In_ OrtSessionOptions* options, _In_ IDMLDevice* dml_device, _In_ ID3D12CommandQueue* cmd_queue );設定オプション
Section titled “設定オプション”DirectML実行プロバイダーは、onnxruntimeでのメモリパターン最適化または並列実行の使用をサポートしていません。InferenceSessionの作成時にセッションオプションを指定する場合、これらのオプションは無効にする必要があります。そうしないとエラーが返されます。
onnxruntime C APIを使用している場合は、DisableMemPatternおよびSetSessionExecutionMode関数を呼び出して、DirectML実行プロバイダーに必要なオプションを設定する必要があります。
onnxruntime\include\onnxruntime\core\session\onnxruntime_c_api.hを参照してください。
OrtStatus*(ORT_API_CALL* DisableMemPattern)(_Inout_ OrtSessionOptions* options)NO_EXCEPTION;
OrtStatus*(ORT_API_CALL* SetSessionExecutionMode)(_Inout_ OrtSessionOptions* options, ExecutionMode execution_mode)NO_EXCEPTION;onnxruntime InferenceSessionオブジェクトを直接作成する場合は、onnxruntime::SessionOptions構造体の適切なフィールドを設定する必要があります。具体的には、execution_modeをExecutionMode::ORT_SEQUENTIALに設定し、enable_mem_patternをfalseにする必要があります。
さらに、DirectML実行プロバイダーは並列実行をサポートしていないため、同じ推論セッションでのRunへのマルチスレッド呼び出しをサポートしていません。つまり、DirectML実行プロバイダーを使用する推論セッションの場合、一度にRunを呼び出すことができるスレッドは1つだけです。複数のスレッドが、異なる推論セッションオブジェクトで操作する場合に限り、Runを同時に呼び出すことが許可されます。
パフォーマンスチューニング
Section titled “パフォーマンスチューニング”DirectML実行プロバイダーは、セッション作成時にテンソル形状がわかっている場合に最も効率的に機能します。いくつかのパフォーマンス上の利点があります。
- 定数畳み込みがより頻繁に発生し、評価中のCPU/GPUコピーとストールが減少します。
- セッション作成時に、最初の評価中ではなく、より多くの初期化作業が行われます。
- 重みはDirectML内で前処理される可能性があり、より効率的なアルゴリズムが可能になります。
- グラフの最適化はDirectML内で行われます。たとえば、Concat演算子が削除され、演算子の入力と出力に最適なテンソルレイアウトが使用される場合があります。
通常、セッション作成時にモデル入力の形状がわかっている場合、モデルの残りの部分の形状は、そのセッションが作成されるときにOnnxRuntimeによって推測されます。
ただし、モデル入力に自由な次元(バッチサイズなど)が含まれている場合は、上記のパフォーマンス上の利点を維持するために追加の手順を実行する必要があります。これらには以下が含まれます。
- モデルを編集して、入力の自由な次元(ONNXでは「dim_param」を使用して指定)を固定サイズ(ONNXでは「dim_value」を使用して指定)に置き換えます。
- OnnxRuntime AddFreeDimensionOverrideByName ABIを使用してセッションを作成する際に、モデル入力内の名前付き次元の値を指定します。
- モデルを編集して、入力の自由な次元にデノテーション(「DATA_BATCH」やカスタムデノテーションなど)があることを確認します。次に、セッションを作成する際に、各デノテーションの次元サイズを指定します。これは、OnnxRuntime AddFreeDimensionOverride ABIを使用して行うことができます。
DirectML実行プロバイダーを使用するonnxruntimeの完全なサンプルは、samples/c_cxx/fns_candy_style_transferにあります。