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 执行提供程序的要求:

  1. Visual Studio 2017 工具链
  2. 适用于 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 命令队列类型必须为 DIRECTCOMPUTE(参阅 D3D12_COMMAND_LIST_TYPE)。如果此函数成功,创建的推理会话将对 dml_devicecommand_queue 对象保持强引用。

OrtStatus* SessionOptionsAppendExecutionProvider_DML1(
    _In_ OrtSessionOptions* options,
    _In_ IDMLDevice* dml_device,
    _In_ ID3D12CommandQueue* cmd_queue
    );

配置选项

DirectML 执行提供程序不支持在 onnxruntime 中使用内存模式优化或并行执行。在创建 InferenceSession 期间提供会话选项时,这些选项必须被禁用,否则将返回错误。

如果使用 onnxruntime C API,必须调用 DisableMemPatternSetSessionExecutionMode 函数来设置 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 执行提供程序在会话创建时已知张量形状时效率最高。以下是一些性能优势:

  1. 常数折叠更频繁地发生,减少了评估期间的 CPU/GPU 复制和停顿。
  2. 更多的初始化工作发生在会话创建时,而不是在第一次评估时。
  3. 权重可以在 DirectML 内部进行预处理,从而实现更高效的算法。
  4. 图优化在 DirectML 内部进行。例如,Concat 运算符可能会被移除,并且可能会为运算符的输入和输出使用更优化的张量布局。

通常,当模型输入的形状在会话创建期间已知时,ONNX Runtime 在创建该会话时会推断模型其余部分的形状。

然而,如果模型输入包含自由维度(例如批处理大小),则必须采取额外步骤以保留上述性能优势。这包括:

  1. 编辑模型,用固定大小(通过 ONNX 使用“dim_value”指定)替换输入的自由维度(通过 ONNX 使用“dim_param”指定)。
  2. 在创建会话时,使用 OnnxRuntime 的 AddFreeDimensionOverrideByName ABI 指定模型输入中命名维度的大小。
  3. 编辑模型以确保输入的自由维度具有标记(例如“DATA_BATCH”或自定义标记)。然后,在创建会话时,为每个标记指定维度大小。这可以使用 OnnxRuntime 的 AddFreeDimensionOverride ABI 完成。

示例

使用 DirectML 执行提供程序的 onnxruntime 完整示例可以在 samples/c_cxx/fns_candy_style_transfer 下找到

额外资源

返回顶部