ORT 模型格式
目录
什么是 ORT 模型格式?
ORT 格式是精简版 ONNX Runtime 构建所支持的格式。精简版构建可能更适合在尺寸受限的环境中使用,例如移动和 Web 应用程序。
完整版 ONNX Runtime 构建同时支持 ORT 格式模型和 ONNX 模型。
向后兼容性
一般来说,目标是特定版本的 ONNX Runtime 可以运行当前版本(在 ONNX Runtime 发布时)或更旧版本的 ORT 格式的模型。
尽管我们尽力保持向后兼容性,但仍然存在一些重大更改。
ONNX Runtime 版本 | ORT 格式版本支持 | 注释 |
---|---|---|
1.14+ | v5、v4(有限支持) | 有关有限的 v4 支持的详细信息,请参阅此处。 |
1.13 | v5 | v5 重大更改:删除了内核定义哈希。 |
1.12-1.8 | v4 | v4 重大更改:更新了内核定义哈希计算。 |
1.7 | v3、v2、v1 | |
1.6 | v2、v1 | |
1.5 | v1 | 引入 ORT 格式 |
将 ONNX 模型转换为 ORT 格式
ONNX 模型使用 convert_onnx_models_to_ort
脚本转换为 ORT 格式。
转换脚本执行两个功能
- 加载和优化 ONNX 格式模型,并将其保存为 ORT 格式
- 确定优化模型所需的运算符,以及可选的数据类型,并将这些保存在配置文件中,以便在需要时用于精简运算符构建
转换脚本可以对单个 ONNX 模型或目录运行。如果针对目录运行,则将递归搜索该目录以查找要转换的“.onnx”文件。
每个“.onnx”文件都会被加载、优化,并以 ORT 格式保存为“.ort”扩展名的文件,与原始“.onnx”文件位于同一位置。
脚本输出
- 每个 ONNX 模型对应一个 ORT 格式模型
-
包含优化 ONNX 模型所需运算符的构建配置文件(“required_operators.config”)。
如果启用类型精简(ONNX Runtime 1.7 或更高版本),则配置文件还将包含每个运算符所需的类型,并命名为“required_operators_and_types.config”。
如果您使用的是预构建的 ONNX Runtime iOS、Android 或 Web 包,则构建配置文件不会使用,可以忽略。
脚本位置
ORT 模型格式受 ONNX Runtime 1.5.2 或更高版本支持。
将 ONNX 格式模型转换为 ORT 格式利用了 ONNX Runtime Python 包,因为模型会被加载到 ONNX Runtime 中并在转换过程中进行优化。
对于 ONNX Runtime 1.8 及更高版本,转换脚本直接从 ONNX Runtime Python 包运行。
对于早期版本,转换脚本从本地 ONNX Runtime 存储库运行。
安装 ONNX Runtime
从 https://pypi.ac.cn/project/onnxruntime/ 安装 onnxruntime Python 包,以便将模型从 ONNX 格式转换为内部 ORT 格式。需要 1.5.3 或更高版本。
安装最新版本
pip install onnxruntime
安装以前的版本
如果您从源代码(自定义、精简或最小构建)构建 ONNX Runtime,则必须使 Python 包版本与您检出的 ONNX Runtime 存储库的分支相匹配。
例如,要使用 1.7 版本
git checkout rel-1.7.2
pip install onnxruntime==1.7.2
如果您使用的是 git 存储库中的 main
分支,则应使用 nightly ONNX Runtime Python 包
pip install -U -i https://test.pypi.org/simple/ ort-nightly
将 ONNX 模型转换为 ORT 格式脚本用法
ONNX Runtime 1.8 或更高版本
python -m onnxruntime.tools.convert_onnx_models_to_ort <onnx model file or dir>
其中
- onnx 模型文件或目录是 .onnx 文件或包含一个或多个 .onnx 模型的目录的路径
当前可选参数可通过使用 --help
参数运行脚本获得。不同 ONNX Runtime 版本支持的参数和默认值略有不同。
来自 ONNX Runtime 1.11 的帮助文本
python -m onnxruntime.tools.convert_onnx_models_to_ort --help
usage: convert_onnx_models_to_ort.py [-h] [--optimization_style {Fixed,Runtime} [{Fixed,Runtime} ...]] [--enable_type_reduction] [--custom_op_library CUSTOM_OP_LIBRARY] [--save_optimized_onnx_model] [--allow_conversion_failures] [--nnapi_partitioning_stop_ops NNAPI_PARTITIONING_STOP_OPS]
[--target_platform {arm,amd64}]
model_path_or_dir
Convert the ONNX format model/s in the provided directory to ORT format models. All files with a `.onnx` extension will be processed. For each one, an ORT format model will be created in the same directory. A configuration file will also be created containing the list of required
operators for all converted models. This configuration file should be used as input to the minimal build via the `--include_ops_by_config` parameter.
positional arguments:
model_path_or_dir Provide path to ONNX model or directory containing ONNX model/s to convert. All files with a .onnx extension, including those in subdirectories, will be processed.
optional arguments:
-h, --help show this help message and exit
--optimization_style {Fixed,Runtime} [{Fixed,Runtime} ...]
Style of optimization to perform on the ORT format model. Multiple values may be provided. The conversion will run once for each value. The general guidance is to use models optimized with 'Runtime' style when using NNAPI or CoreML and 'Fixed' style otherwise.
'Fixed': Run optimizations directly before saving the ORT format model. This bakes in any platform-specific optimizations. 'Runtime': Run basic optimizations directly and save certain other optimizations to be applied at runtime if possible. This is useful when
using a compiling EP like NNAPI or CoreML that may run an unknown (at model conversion time) number of nodes. The saved optimizations can further optimize nodes not assigned to the compiling EP at runtime.
--enable_type_reduction
Add operator specific type information to the configuration file to potentially reduce the types supported by individual operator implementations.
--custom_op_library CUSTOM_OP_LIBRARY
Provide path to shared library containing custom operator kernels to register.
--save_optimized_onnx_model
Save the optimized version of each ONNX model. This will have the same level of optimizations applied as the ORT format model.
--allow_conversion_failures
Whether to proceed after encountering model conversion failures.
--nnapi_partitioning_stop_ops NNAPI_PARTITIONING_STOP_OPS
Specify the list of NNAPI EP partitioning stop ops. In particular, specify the value of the "ep.nnapi.partitioning_stop_ops" session options config entry.
--target_platform {arm,amd64}
Specify the target platform where the exported model will be used. This parameter can be used to choose between platform-specific options, such as QDQIsInt8Allowed(arm), NCHWc (amd64) and NHWC (arm/amd64) format, different optimizer level options, etc.
可选脚本参数
优化风格
自 ONNX Runtime 1.11 起
指定转换后的模型将完全优化(“Fixed”)还是具有保存的运行时优化(“Runtime”)。默认情况下会生成两种类型的模型。有关更多信息,请参阅此处。
这取代了早期 ONNX Runtime 版本的优化级别选项。
优化级别
ONNX Runtime 1.10 及更早版本
设置 ONNX Runtime 将用于优化模型,然后再以 ORT 格式保存的优化级别。
对于 ONNX Runtime 1.8 及更高版本,如果模型将在 CPU EP 上运行,建议使用all。
对于早期版本,建议使用extended,因为all级别以前包含设备特定的优化,这会限制模型的可移植性。
如果模型将与 NNAPI EP 或 CoreML EP 一起运行,建议使用 basic 优化级别创建 ORT 格式模型。应进行性能测试,以比较在启用 NNAPI 或 CoreML EP 的情况下运行此模型与使用 CPU EP 运行优化到更高级别的模型,以确定最佳设置。
有关更多信息,请参阅关于移动场景性能调优的文档。
启用类型精简
在 ONNX Runtime 1.7 及更高版本中,可以限制所需运算符支持的数据类型,以进一步减小构建大小。此剪枝在本文档中称为“运算符类型精简”。在转换 ONNX 模型时,每个运算符所需的输入和输出数据类型会被累积并包含在配置文件中。
如果您希望启用运算符类型精简,则必须安装 Flatbuffers Python 包。
pip install flatbuffers
例如,Softmax 的 ONNX Runtime 内核同时支持 float 和 double。如果您的模型使用 Softmax,但仅使用 float 数据,我们可以排除支持 double 的实现,以减小内核的二进制大小。
自定义运算符支持
如果您的 ONNX 模型使用自定义运算符,则必须提供包含自定义运算符内核的库的路径,以便可以成功加载 ONNX 模型。自定义运算符将保留在 ORT 格式模型中。
保存优化的 ONNX 模型
添加此标志以保存优化的 ONNX 模型。优化的 ONNX 模型包含与 ORT 格式模型相同的节点和初始化器,并且可以在 Netron 中查看,以进行调试和性能调优。
以前版本的 ONNX Runtime
在 ONNX Runtime 1.7 之前的版本中,模型转换脚本必须从克隆的源代码存储库运行
python <ONNX Runtime repository root>/tools/python/convert_onnx_models_to_ort.py <onnx model file or dir>
加载并执行 ORT 格式的模型
执行 ORT 格式模型的 API 与 ONNX 模型相同。
有关各个 API 用法的详细信息,请参阅ONNX Runtime API 文档。
按平台划分的 API
平台 | 可用 API |
---|---|
Android | C、C++、Java、Kotlin |
iOS | C、C++、Objective-C (通过桥接的 Swift) |
Web | JavaScript |
ORT 格式模型加载
如果您为 ORT 格式模型提供文件名,则会推断文件扩展名“.ort”为 ORT 格式模型。
如果您为 ORT 格式模型提供内存中字节,则将检查这些字节中的标记以确定它是否为 ORT 格式模型。
如果您希望显式声明 InferenceSession 输入是 ORT 格式模型,您可以通过 SessionOptions 来实现,尽管这通常不是必需的。
从文件路径加载 ORT 格式模型
C++ API
Ort::SessionOptions session_options;
session_options.AddConfigEntry("session.load_model_format", "ORT");
Ort::Env env;
Ort::Session session(env, <path to model>, session_options);
Java API
SessionOptions session_options = new SessionOptions();
session_options.addConfigEntry("session.load_model_format", "ORT");
OrtEnvironment env = OrtEnvironment.getEnvironment();
OrtSession session = env.createSession(<path to model>, session_options);
JavaScript API
import * as ort from "onnxruntime-web";
const session = await ort.InferenceSession.create("<path to model>");
从内存中字节数组加载 ORT 格式模型
如果使用包含 ORT 格式模型数据的输入字节数组创建会话,默认情况下,我们将在会话创建时复制模型字节,以确保模型字节缓冲区有效。
您还可以通过将会话选项配置条目 session.use_ort_model_bytes_directly
设置为 1
来启用直接使用模型字节的选项。这可能会降低 ONNX Runtime Mobile 的峰值内存使用量,但您需要保证模型字节在 ORT 会话的整个生命周期内都有效。对于 ONNX Runtime Web,默认情况下会设置此选项。
如果启用了 session.use_ort_model_bytes_directly
,还可以选择直接使用模型字节作为初始化程序,以进一步降低峰值内存使用量。将会话选项配置条目 session.use_ort_model_bytes_for_initializers
设置为 1
以启用此功能。请注意,如果初始化程序被预先打包,它将撤消直接使用模型字节作为该初始化程序带来的峰值内存使用量节省,因为需要为预先打包的数据分配新的缓冲区。预先打包是一种可选的性能优化,它涉及在初始化程序布局与当前平台的最佳排序不同时,将其更改为最佳排序。如果降低峰值内存使用量比潜在的性能优化更重要,则可以通过将 session.disable_prepacking
设置为 1
来禁用预先打包。
C++ API
Ort::SessionOptions session_options;
session_options.AddConfigEntry("session.load_model_format", "ORT");
session_options.AddConfigEntry("session.use_ort_model_bytes_directly", "1");
std::ifstream stream(<path to model>, std::ios::in | std::ios::binary);
std::vector<uint8_t> model_bytes((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
Ort::Env env;
Ort::Session session(env, model_bytes.data(), model_bytes.size(), session_options);
Java API
SessionOptions session_options = new SessionOptions();
session_options.addConfigEntry("session.load_model_format", "ORT");
session_options.addConfigEntry("session.use_ort_model_bytes_directly", "1");
byte[] model_bytes = Files.readAllBytes(Paths.get(<path to model>));
OrtEnvironment env = OrtEnvironment.getEnvironment();
OrtSession session = env.createSession(model_bytes, session_options);
JavaScript API
import * as ort from "onnxruntime-web";
const response = await fetch(modelUrl);
const arrayBuffer = await response.arrayBuffer();
model_bytes = new Uint8Array(arrayBuffer);
const session = await ort.InferenceSession.create(model_bytes);