onnx之模型文件语法介绍

onnx之模型文件语法介绍 ONNX最核心的语法结构介绍 ONNX核心语法全景图ONNX模型本质上是一个由Protocol Buffers定义的嵌套数据结构。我们可以把它想象成一个俄罗斯套娃最外层是模型打开后是计算图再打开是节点和张量。 语法详解逐层拆解1. 模型层ModelProto—— 身份证每个ONNX文件最外层都是一个ModelProto它定义了模型的身份证信息。文本语法示例 ir_version: 8, // ONNX中间表示版本 opset_import: [ : 18 ], // 导入的算子集默认域为空字符串 producer_name: PyTorch, producer_version: 2.1.0, model_version: 1, doc_string: 这是一个简单的线性模型 agraph ... // 后面是计算图内容关键字段详解字段类型含义实践意义ir_versionint64ONNX IR规范版本决定了模型结构的解析方式opset_importrepeated导入的算子集列表每个算子集由(domain, version)唯一标识producer_namestring生成工具名称调试时追溯来源graphGraphProto核心计算图模型的主体内容算子集opset_import的深层理解默认算子集domain是所有模型必须导入的可以导入多个自定义算子集如com.microsoft、com.nvidia每个算子集版本号单调递增新版本可能新增、修改或弃用算子运行时必须支持所有导入算子集否则拒绝执行2. 计算图层GraphProto—— 施工图GraphProto是整个模型的核心它描述了计算的具体流程。文本语法示例agraph (float[N, 128] X, float[128, 10] W, float[10] B) (float[N, 10] C) { T MatMul(X, W) S Add(T, B) C Softmax(S) }等价Python API构造from onnx import helper, TensorProto # 定义输入输出张量 X helper.make_tensor_value_info(X, TensorProto.FLOAT, [N, 128]) W helper.make_tensor_value_info(W, TensorProto.FLOAT, [128, 10]) B helper.make_tensor_value_info(B, TensorProto.FLOAT, [10]) C helper.make_tensor_value_info(C, TensorProto.FLOAT, [N, 10]) # 定义节点 node1 helper.make_node(MatMul, [X, W], [T]) node2 helper.make_node(Add, [T, B], [S]) node3 helper.make_node(Softmax, [S], [C]) # 构建图 graph helper.make_graph( [node1, node2, node3], # 节点列表**必须按拓扑序**[citation:2] linear_graph, [X, W, B], # 输入 [C] # 输出 )3. 节点层NodeProto—— 施工工序每个NodeProto代表计算图中的一个算子是实际执行计算的基本单元。文本语法中的节点T MatMul(X, W) // 输出 算子名(输入1, 输入2, ...)节点构成要素要素含义示例算子类型执行的操作MatMul、Add、Conv输入输入张量名列表[X, W]输出输出张量名列表[T]属性算子参数常量kernel_shape,pads,strides重要概念输入vs属性输入表示动态计算得到的值属性是图中固定的常量。这种区分对硬件实现很重要因为属性可能在编译期就确定。4. 张量层ValueInfoProto/TensorProto—— 材料清单ONNX中有两种材料一种是流动的中间结果ValueInfoProto一种是固定的权重TensorProto。ValueInfoProto中间结果声明# 定义形状为[10,10]的浮点张量 tensor_info helper.make_tensor_value_info( a, TensorProto.FLOAT, # 数据类型 [10, 10] # 形状可用维度符号如N、batch )TensorProto常量数据import numpy as np from onnx import numpy_helper # 将numpy数组转为ONNX常量 weights np.random.randn(128, 10).astype(np.float32) weights_tensor numpy_helper.from_array(weights, nameW) # 将常量添加到图的initializer列表中 graph.initializer.append(weights_tensor) 实战用语法眼看一个真实模型让我们用刚才学的语法知识解读一个真实ONNX模型的文本输出。下面这个例子来自MMDeploy教程textir_version: 8 graph { node { input: a input: x output: c op_type: Mul } node { input: c input: b output: output op_type: Add } name: linear_func input { # 输入a的声明 name: a type { tensor_type { elem_type: 1 # FLOAT类型 shape { dim {dim_value: 10} dim {dim_value: 10} } } } } input { name: x ... } # 输入x input { name: b ... } # 输入b output { name: output ... } # 输出 } opset_import {version: 15}语法分析模型层ir_version: 8表示遵循ONNX IR v8规范opset_import {version: 15}表示使用默认算子集v15图层graph包含2个节点、3个输入、1个输出节点层先Mul后Add符合拓扑序因为Add依赖Mul的输出c张量层所有输入输出都是形状[10,10]的float32