原文链接:
Open Neural Network Exchange Intermediate Representation (ONNX IR) Specification
开放神经网络交换中间表示(ONNX IR)规范
目的
本文档包含ONNX语义的规范性规范。
在onnx文件夹下的.proto
和.proto3
文件构成了其语法的规范性规范,这些文件使用Protocol Buffers定义语言编写。.proto
和.proto3
文件中的注释旨在提高这些文件的可读性,但如果与本文档冲突,则不具有规范性。此类冲突应报告为文档错误。
关于模型验证的说明
提供了一个工具来根据此规范对模型进行一般验证。它使用C++实现,并带有Python命令行包装器。
关于本文档及所有相关文档中语言的说明:
-
本文档中使用的SHOULD、MUST、MAY等术语与RFC 2119一致。
-
使用“列表”表示项目的有序集合,“集合”表示唯一元素的无序集合,“包”表示可能包含非唯一元素的无序集合。
组件
ONNX是一个开放规范,由以下组件组成:
-
可扩展计算图模型的定义。
-
标准数据类型的定义。
-
内置运算符的定义。
#1和#2共同构成了ONNX中间表示(IR)规范,本文档涵盖了这些内容;内置运算符在文档末尾列出的文档中涵盖。具体来说,内置运算符分为一组原始运算符和函数。函数是一个运算符,其语义通过扩展为使用其他运算符(和函数)的子图(称为函数体)来正式表达。功能上,如果ONNX兼容框架或运行时没有相应的函数实现,则可以内联函数体来执行它。
有两个官方的ONNX变体;两者之间的主要区别在于默认的运算符集。__ONNX-ML__扩展了__ONNX__运算符集,包含了不基于神经网络的机器学习算法。
直到IR版本6,ONNX规范和模型格式仅支持推理(也称为评分)。从IR版本7开始,ONNX规范和模型格式还支持训练。ONNX训练模型是推理模型的扩展。仅支持推理的运行时可以忽略训练相关的扩展来使用训练模型。然而,仅支持推理的模型可能比训练模型更适合推理目的。
运行时无关性
ONNX不预设或暗示任何特定的运行时实现方法。
例如,实现可能包括一个丰富的运行时来解释模型;它可能是一个代码生成器,将模型整体翻译为某种目标编程语言的可执行代码;它可能是一个硬件实现;它可能是上述两种或三种的组合。
本规范中的任何内容都不应被解释为提倡一种实现方法优于其他方法;任何关于具体实现内部工作的评论都应被解释为示例。
ONNX版本控制
IR规范、各个模型和运算符集都有版本控制。此外,每个单独的运算符都指示了它在其包含的运算符集中引入或稳定的版本。
版本号可以作为一个简单的数字使用,也可以用于编码语义版本(也称为SemVer)。如果使用语义版本,约定是使用两个最高有效字节表示主版本号,接下来的两个字节表示次版本号,最低有效的四个字节表示补丁/构建/修复版本号。使用语义版本控制时,主版本号或次版本号中至少有一个必须为非零。
IR规范使用简单的单调递增数字作为其版本。有效的IR版本由onnx.proto中的onnx.Version
枚举定义。
运算符集使用简单的版本号。每个运算符集版本表示一组运算符及其在特定时间点的语义的快照。
本规范未提供模型生产者应使用何种版本控制方案的指导。
有关IR、运算符集和模型版本控制的约定和最佳实践的更多详细信息,请参阅版本控制。
可扩展的计算图模型
ONNX指定了计算图的可移植、序列化格式。它不必是框架内部使用的形式。例如,实现可以在内存中以不同的方式表示模型,如果在优化过程中更高效。
实现可以通过添加表达超出标准运算符集语义的运算符来扩展ONNX。其机制是在依赖扩展运算符的模型中向opset_import
属性添加运算符集。
模型 Models
ONNX的顶层结构是“模型”,在协议缓冲区中表示为onnx.ModelProto
类型。
模型结构的主要目的是将元数据与包含所有可执行元素的图关联起来。元数据在首次读取模型文件时使用,为实现提供确定是否能够执行模型、生成日志消息、错误报告等所需的信息。此外,元数据对工具(如IDE和模型库)非常有用,这些工具需要它来向人类传达给定模型的用途和特征。
每个模型具有以下组件:
名称 | 类型 | 描述 |
---|---|---|
ir_version | int64 | 模型假设的ONNX版本。 |
opset_import | OperatorSetId | 模型可用的运算符集标识符集合。实现必须支持集合中的所有运算符或拒绝模型。 |
producer_name | string | 用于生成模型的工具名称。 |
producer_version | string | 生成工具的版本。 |
domain | string | 表示模型命名空间或域的反向DNS名称,例如’org.onnx’ |
model_version | int64 | 模型本身的版本,编码为整数。 |
doc_string | string | 此模型的人类可读文档。允许使用Markdown。 |
graph | Graph | 评估以执行模型的参数化图。 |
metadata_props | map<string,string> | 命名的元数据值;键应唯一。 |
training_info | TrainingInfoProto[] | 包含训练信息的可选扩展。 |
functions | FunctionProto[] | 模型本地的可选函数列表。 |
模型必须指定一个域,并使用基于负责组织身份的反向域名,与命名Java包使用的约定相同。
注意:探索ONNX文件
您可以使用Protocol Buffers发行版中的protoc
工具来检查ONNX文件的内容,如下所示:
$ protoc --decode=onnx.ModelProto onnx.proto < yourfile.onnx
其中onnx.proto是此存储库中的文件。
或者,您可以使用Netron等工具来探索ONNX文件。
模型语义 Model Semantics
推理模型的语义是一个_无状态函数_(除了可能用于随机数生成的状态)。因此,每当使用推理模型(没有随机生成器操作)对相同输入执行推理时,预期会产生相同的输出。
训练模型的语义是一个_有状态对象_,状态由当前训练权重值(以及学习算法所需的任何其他辅助状态,例如动量)组成。具体来说,其语义通过三种方法捕获:初始化方法(用于初始化或重置状态变量的值)、训练步骤方法(用于使用一批输入-输出对进行训练)和推理方法(使用当前学习到的权重值执行推理)。前两种方法更新对象的状态,而第三种方法是无副作用的。