ONNX 在部署链路中的位置
跳转到“ONNX 在部署链路中的位置”ONNX 用计算图描述模型的运算、参数和输入输出约定。onnx Python 包负责读取、构造和检查这个模型;真正执行推理的是 ONNX Runtime 等运行时。一个文件能通过结构检查,不等于目标设备支持其中的全部算子,也不等于转换前后数值相同。
| 对象 | 表达什么 | 不能据此推断什么 |
|---|---|---|
| 图的输入、输出 | 张量名称、类型、形状等接口 | 图像一定是 RGB、一定按 0~1 归一化 |
| 节点 node | 如 Add、Mul、Conv 等运算 | 每个节点恰好对应一次 GPU kernel |
| initializer | 图中保存的常量或权重 | 它一定是待训练参数 |
| opset_import | 各算子域采用的算子规范版本 | Python 包版本与 opset 编号相同 |
| ir_version | 模型容器与图表示的版本 | 把数字改小就能自动兼容旧运行时 |
算子版本按域解释:例如默认域模型采用 opset 18,并不意味着每个算子都有一个叫“版本 18”的实现;它采用该算子在不超过 18 的规范中适用的最新定义。自定义算子还需要匹配的域和运行时实现。ONNX 概念说明
用一个小模型理解计算图
跳转到“用一个小模型理解计算图”令输入 ,每个元素都计算:
这里的 2 和 1 是标量,通过广播作用到所有元素。N 是批量维,第二维固定为 3。符号维 N 表示尺寸可变;这个名称本身不声明“只能在 1 到 8 之间”。
flowchart LR X["输入 X:N × 3,float32"] --> Mul["逐元素乘 2"] Mul --> Add["逐元素加 1"] Add --> Y["输出 Y:N × 3,float32"]下面的独立脚本生成 affine.onnx。显式选择 opset 18、IR 9 是这个基础示例的兼容约定;真实模型应按所用功能和目标运行时确定版本。
import numpy as npimport onnxfrom onnx import TensorProto, helper, numpy_helper
x_info = helper.make_tensor_value_info("x", TensorProto.FLOAT, ["N", 3])y_info = helper.make_tensor_value_info("y", TensorProto.FLOAT, ["N", 3])constants = [ numpy_helper.from_array(np.array(2.0, dtype=np.float32), name="scale"), numpy_helper.from_array(np.array(1.0, dtype=np.float32), name="bias"),]graph = helper.make_graph( [helper.make_node("Mul", ["x", "scale"], ["scaled"]), helper.make_node("Add", ["scaled", "bias"], ["y"])], "affine_demo", [x_info], [y_info], initializer=constants,)model = helper.make_model( graph, producer_name="vitalogos-example", ir_version=9, opset_imports=[helper.make_opsetid("", 18)],)onnx.checker.check_model(model, full_check=True)onnx.save(model, "affine.onnx")print("saved affine.onnx")check_model 会检查模型结构与类型/形状一致性等约束;它没有用你的真实业务数据验证精度。
读取与检查模型
跳转到“读取与检查模型”对刚生成的文件运行:
import onnx
model = onnx.load("affine.onnx")onnx.checker.check_model(model, full_check=True)print("IR:", model.ir_version)print("opsets:", [(item.domain or "ai.onnx", item.version) for item in model.opset_import])
for label, values in [("input", model.graph.input), ("output", model.graph.output)]: for value in values: tensor = value.type.tensor_type shape = [dimension.dim_value if dimension.HasField("dim_value") else dimension.dim_param or "?" for dimension in tensor.shape.dim] print(label, value.name, onnx.TensorProto.DataType.Name(tensor.elem_type), shape)该例应显示输入 x、输出 y,类型 FLOAT,形状 ['N', 3]。ONNX 的 FLOAT 对应此例使用的 32 位浮点数,不能仅因 Python 默认整数或浮点数“也能表示这些值”就换成其他 dtype。
大模型可能把权重保存为外部数据文件。复制或发布时,必须连同模型所引用的外部权重一起保留目录关系,不能只搬走 .onnx 文件。ONNX 外部数据说明
转换完成后的验证顺序
跳转到“转换完成后的验证顺序”- 固定输入约定:名称、dtype、布局、尺寸范围、单位、归一化及输出语义。
- 检查模型结构、IR/opset 和目标运行时支持范围。
- 用同一输入分别执行原模型和 ONNX,比较对应输出。
- 覆盖正常输入、边界尺寸以及有业务意义的困难样本。
- 最后测量目标硬件上的性能;不要把首次加载、预热或输入拷贝漏出所声明的指标。
对于浮点输出,常用的逐元素判据为:
容差由模型和业务确定。张量误差小仍可能改变分类边界、检测阈值或排序结果,因此还应比较最终任务指标。
接着阅读
跳转到“接着阅读”- ONNX Runtime:输入检查、执行后端与推理验证:执行本页的
affine.onnx。 - ONNX Simplifier:简化图并验证数值:保持原模型,比较简化前后结果。
- 模型导出与部署流程:把 PyTorch、ONNX 和 TensorRT 接成有验证步骤的流程。
本页模型构造、读取和结构检查已在 Python 3.11、ONNX 1.23.1 环境执行。版本记录描述本次验证环境,不代表所有项目都应升级到该版本。