重要提示:此信息仅适用于 ONNX Runtime 1.10 及更早版本。请使用更新的版本。
ONNX Runtime 移动性能调优
了解不同优化如何影响性能,并获取使用 ORT 格式模型进行性能测试的建议。
ONNX Runtime Mobile 可用于在 Android 平台上使用 NNAPI(通过 NNAPI 执行提供程序 (EP))执行 ORT 格式模型,以及在 iOS 平台上使用 CoreML(通过 CoreML EP)执行模型。
首先,请回顾 在 ONNX Runtime Mobile 中使用 NNAPI 和 在 ONNX Runtime 中使用 CoreML 中的介绍性详细信息。
重要提示: 为简洁起见,本页中的示例均指 NNAPI EP。此信息同样适用于 CoreML EP,因此下文中任何对“NNAPI”的引用都可以替换为“CoreML”。
在 ONNX Runtime 1.9 版本中添加了对创建 CoreML 感知型 ORT 格式模型的支持,类似于创建 NNAPI 感知型 ORT 格式模型。
目录
1. ONNX 模型优化示例
ONNX Runtime 会对 ONNX 模型应用优化以提高推理性能。这些优化在导出 ORT 格式模型之前发生。有关可用优化的更多详细信息,请参阅图优化文档。
了解不同优化级别如何影响模型中的节点非常重要,因为这将决定模型有多少部分可以使用 NNAPI 或 CoreML 执行。
基本
基本优化会删除冗余节点并执行常量折叠。在修改模型时,这些优化仅使用 ONNX 操作符。
扩展
扩展优化会用自定义的内部 ONNX Runtime 操作符替换一个或多个标准 ONNX 操作符,以提升性能。每个优化都有一个适用于它的 EP 列表。它将只替换分配给该 EP 的节点,并且替换的节点将使用相同的 EP 执行。
布局
布局优化可能是硬件特定的,涉及 ONNX 使用的 NCHW 图像布局与 NHWC 或 NCHWc 格式之间的内部转换。它们在优化级别设置为“all”时启用。
- 对于 ONNX Runtime 1.8 之前的版本,在创建 ORT 格式模型时,不应使用布局优化。
- 对于 ONNX Runtime 1.8 或更高版本,可以启用布局优化,因为硬件特定优化会自动禁用。
创建优化后的 ORT 格式模型时的优化结果
以下是当仅启用 CPU EP 并应用于 MNIST 模型时,基本和扩展优化中发生的变化示例。优化级别在创建 ORT 格式模型时指定。
- 在基本级别,我们组合了 Conv 和 Add 节点(加法通过 Conv 的“B”输入完成),我们将 MatMul 和 Add 组合成一个 Gemm 节点(加法通过 Gemm 的“C”输入完成),并执行常量折叠以移除一个 Reshape 节点。
python <ORT repository root>/tools/python/convert_onnx_models_to_ort.py --optimization_level basic /dir_with_mnist_onnx_model
- 在扩展级别,我们还使用内部 ONNX Runtime FusedConv 操作符融合了 Conv 和 Relu 节点。
python <ORT repository root>/tools/python/convert_onnx_models_to_ort.py --optimization_level extended /dir_with_mnist_onnx_model
使用 NNAPI EP 执行优化后的 ORT 格式模型的结果
如果在运行时注册了 NNAPI EP,它将有机会选择加载模型中它可以执行的节点。这样做时,它会尽可能多地将节点组合在一起,以最大程度地减少在 CPU 和 NNAPI 之间复制数据以执行节点的开销。每组节点都可以被视为一个子图。每个子图中的节点越多,子图越少,性能就会越好。
对于每个子图,NNAPI EP 将创建一个NNAPI 模型,该模型复制原始节点的处理过程。它将创建一个执行此 NNAPI 模型并执行 CPU 和 NNAPI 之间任何所需数据复制的函数。ONNX Runtime 将用一个调用此函数的单个节点替换加载模型中的原始节点。
如果 NNAPI EP 未注册或无法处理某个节点,则该节点将使用 CPU EP 执行。
下面是一个 MNIST 模型的示例,比较了如果在运行时注册 NNAPI EP,ORT 格式模型会发生什么。
由于基本级别优化会生成一个仅使用 ONNX 操作符的模型,因此 NNAPI EP 能够处理模型的大部分,因为 NNAPI 可以执行 Conv、Relu 和 MaxPool 节点。这是通过单个 NNAPI 模型完成的,因为所有 NNAPI 可以处理的节点都已连接。我们预计使用 NNAPI 会使此模型获得性能提升,因为单个 NNAPI 节点在 CPU 和 NNAPI 之间进行设备复制的开销很可能低于使用 NNAPI 一次性执行多个操作所节省的时间。
扩展级别优化引入了自定义的 FusedConv 节点,NNAPI EP 会忽略这些节点,因为它只会处理使用 NNAPI 可以处理的 ONNX 操作符的节点。这导致两个节点使用 NNAPI,每个节点处理一个 MaxPool 操作。此模型的性能可能会受到不利影响,因为 CPU 和 NNAPI 之间设备复制的开销(在两个 NNAPI 节点之前和之后都需要)不太可能超过每次使用 NNAPI 执行单个 MaxPool 操作所节省的时间。通过不注册 NNAPI EP,使模型中的所有节点都使用 CPU EP 执行,可能会获得更好的性能。
2. 初始性能测试
最佳优化设置因模型而异。有些模型可能在使用 NNAPI 时表现更好,有些则不然。由于性能是模型特有的,您必须运行性能测试以确定最适合您模型的组合。
建议运行性能测试
- 启用 NNAPI,并使用基本级别优化创建的 ORT 格式模型
- 禁用 NNAPI,并使用扩展或所有级别优化创建的 ORT 格式模型
- ONNX Runtime 1.8 或更高版本使用所有,早期版本使用扩展
对于大多数场景,预计这两种方法之一将产生最佳性能。
如果使用具有基本级别优化和 NNAPI 的 ORT 格式模型产生相同或更好的性能,则可能通过创建 NNAPI 感知型 ORT 格式模型来进一步提高性能。此模型的区别在于,更高级别的优化仅应用于无法使用 NNAPI 执行的节点。是否有任何节点属于此类别取决于模型。
3. 创建 NNAPI 感知型 ORT 格式模型
NNAPI 感知型 ORT 格式模型将保留 ONNX 模型中所有可以使用 NNAPI 执行的节点,并允许对任何剩余节点应用扩展优化。
对于我们的 MNIST 模型,这意味着在应用基本优化后,红色阴影中的节点保持不变,绿色阴影中的节点可以应用扩展优化。
要创建 NNAPI 感知型 ORT 格式模型,请按照以下步骤操作。
-
通过从源代码构建 ONNX Runtime,创建一个包含 NNAPI EP 的 ONNX Runtime“完整”构建。
此构建可在任何平台上进行,因为 NNAPI EP 可用于创建 ORT 格式模型,而无需 Android NNAPI 库,因为此过程中没有模型执行。构建时,如果缺少任何标志,请将
--use_nnapi --build_shared_lib --build_wheel
添加到构建标志中。请勿添加
--minimal_build
标志。- Windows
<ONNX Runtime repository root>\build.bat --config RelWithDebInfo --use_nnapi --build_shared_lib --build_wheel --parallel
- Linux
<ONNX Runtime repository root>/build.sh --config RelWithDebInfo --use_nnapi --build_shared_lib --build_wheel --parallel
注意:对于 ONNX Runtime 1.10 及更早版本,如果您之前使用简化操作符内核进行了最小构建,则需要运行
git reset --hard
以确保在执行“完整”构建之前撤销所有操作符内核排除。否则,您可能由于缺少内核而无法加载 ONNX 格式模型。 - Windows
- 从构建输出目录安装 python wheel。
- Windows:位于
build/Windows/<config>/<config>/dist/<package name>.whl
。 - Linux:位于
build/Linux/<config>/dist/<package name>.whl
。包名称将根据您的平台、Python 版本和构建参数而异。<config>
是构建命令中--config
参数的值。pip install -U build\Windows\RelWithDebIfo\RelWithDebIfo\dist\onnxruntime_noopenmp-1.7.0-cp37-cp37m-win_amd64.whl
- Windows:位于
- 按照标准说明运行
convert_onnx_models_to_ort.py
来创建 NNAPI 感知型 ORT 格式模型,并启用 NNAPI (--use_nnapi
),将优化级别设置为扩展或所有(例如--optimization_level extended
)。这将允许在 NNAPI 无法处理的任何节点上运行更高级别的优化。python <ORT repository root>/tools/python/convert_onnx_models_to_ort.py --use_nnapi --optimization_level extended /models
必须安装从启用了 NNAPI 的“完整”构建中获得的 python 包,
--use_nnapi
才能成为有效选项创建的这个 ORT 模型可以与包含 NNAPI EP 的最小构建一起使用。