DirectML 執行提供程式
DirectML 執行提供程式是 ONNX Runtime 的一個元件,它使用 DirectML 來加速 ONNX 模型的推理。DirectML 執行提供程式能夠極大地縮短使用商用 GPU 硬體進行模型評估的時間,同時不犧牲廣泛的硬體支援或要求安裝供應商特定的擴充套件。
DirectML 是一個高效能、硬體加速的 DirectX 12 庫,用於 Windows 上的機器學習。DirectML 為廣泛支援的硬體和驅動程式提供常見的機器學習任務的 GPU 加速。
當單獨使用時,DirectML API 是一個低階 DirectX 12 庫,適用於高效能、低延遲的應用程式,如框架、遊戲和其他即時應用程式。DirectML 與 Direct3D 12 的無縫互操作性及其低開銷和跨硬體的一致性,使得 DirectML 在追求高效能且結果在不同硬體上具有可靠性和可預測性至關重要時,成為加速機器學習的理想選擇。
DirectML 執行提供程式目前使用 DirectML 版本 1.15.2,並支援高達 ONNX opset 20(ONNX v1.15),但 Gridsample 20: 5d 和 DeformConv 尚未支援。評估需要更高 opset 版本的模型將不受支援並導致效能不佳。注意:DirectML ONNX opset 支援可能與 ONNX Runtime 的支援不同,後者可以在此處找到。
目錄
安裝
包含 DirectML EP 的 ORT 預構建包釋出在 Nuget.org 上。請參閱:安裝 ONNX Runtime。
要求
DirectML 執行提供程式需要相容 DirectX 12 的裝置。近幾年釋出的大多數商用顯示卡都支援 DirectX 12。以下是一些相容硬體的示例:
- NVIDIA Kepler (GTX 600 系列) 及更高版本
- AMD GCN 第一代 (Radeon HD 7000 系列) 及更高版本
- Intel Haswell (第四代酷睿) 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_dml
DirectML 執行提供程式支援為 x64(預設)和 x86 架構構建。
請注意,您可以使用 DirectML 構建 ONNX Runtime。這使得 DirectML 可再發行包作為構建的一部分自動下載。請在 NuGet 文件中查詢額外的許可資訊。
用法
在使用啟用 DML 的 onnxruntime 構建時,可以透過 include/onnxruntime/core/providers/dml/dml_provider_factory.h 中包含的兩個工廠函式之一來啟用 DirectML 執行提供程式。
OrtSessionOptionsAppendExecutionProvider_DML 函式
建立一個 DirectML 執行提供程式,該提供程式在具有給定 device_id(也稱為介面卡索引)的硬體介面卡上執行。裝置 ID 對應於 IDXGIFactory::EnumAdapters 給出的硬體介面卡的列舉順序。device_id 為 0 總是對應於預設介面卡,通常是系統上安裝的主顯示 GPU。請注意,在具有多個 GPU 的系統中,主顯示器(GPU 0)通常不是效能最佳的,尤其是在具有雙介面卡的筆記型電腦上,其中電池壽命優先於效能。因此,您可以在任務管理器的效能選項卡中再次檢查哪個是哪個 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 函式
使用給定的 DirectML 裝置建立一個 DirectML 執行提供程式,並在提供的 D3D12 命令佇列上執行工作。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
);
配置選項
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。如果多個執行緒操作不同的推理會話物件,則允許同時呼叫 Run。
效能調優
DirectML 執行提供程式在會話建立時已知張量形狀時效率最高。以下是一些效能優勢:
- 常數摺疊更頻繁地發生,減少了評估期間的 CPU/GPU 複製和停頓。
- 更多的初始化工作發生在會話建立時,而不是在第一次評估時。
- 權重可以在 DirectML 內部進行預處理,從而實現更高效的演算法。
- 圖最佳化在 DirectML 內部進行。例如,Concat 運算子可能會被移除,並且可能會為運算子的輸入和輸出使用更最佳化的張量佈局。
通常,當模型輸入的形狀在會話建立期間已知時,ONNX Runtime 在建立該會話時會推斷模型其餘部分的形狀。
然而,如果模型輸入包含自由維度(例如批處理大小),則必須採取額外步驟以保留上述效能優勢。這包括:
- 編輯模型,用固定大小(透過 ONNX 使用“dim_value”指定)替換輸入的自由維度(透過 ONNX 使用“dim_param”指定)。
- 在建立會話時,使用 OnnxRuntime 的 AddFreeDimensionOverrideByName ABI 指定模型輸入中命名維度的大小。
- 編輯模型以確保輸入的自由維度具有標記(例如“DATA_BATCH”或自定義標記)。然後,在建立會話時,為每個標記指定維度大小。這可以使用 OnnxRuntime 的 AddFreeDimensionOverride ABI 完成。
示例
使用 DirectML 執行提供程式的 onnxruntime 完整示例可以在 samples/c_cxx/fns_candy_style_transfer 下找到