✅ 1. ONNX Runtime(官方推荐)——用于高性能推理
ONNX Runtime 是微软开发的跨平台高性能推理引擎,原生支持 C++ API,广泛用于生产环境(如 Windows、Linux、Android、iOS、嵌入式设备等),ONNX 本身是一个模型格式标准(即一个 protobuf 定义的文件),但围绕它有一整套 C++ 工具链。
🔧 C++ 使用示例(加载 ONNX 模型并推理)
#include <onnxruntime_cxx_api.h>
#include <vector>
#include <iostream>
int main() {
// 创建环境和会话选项
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test");
Ort::SessionOptions session_options;
session_options.SetIntraOpNumThreads(1);
// 加载 ONNX 模型
Ort::Session session(env, "model.onnx", session_options);
// 获取输入/输出信息
auto input_names = session.GetInputNames();
auto output_names = session.GetOutputNames();
// 准备输入数据 (假设输入 shape = [1, 784], float)
std::vector<float> input_tensor_values(784, 0.5f);
std::vector<int64_t> input_shape = {1, 784};
// 创建 Ort::Value 输入张量
Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(
OrtArenaAllocator, OrtMemTypeDefault);
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
memory_info, input_tensor_values.data(),
input_tensor_values.size(), input_shape.data(), input_shape.size());
// 执行推理
auto output_tensors = session.Run(
Ort::RunOptions{nullptr},
input_names.data(), &input_tensor, 1,
output_names.data(), 1);
// 获取输出结果
float* output_data = output_tensors[0].GetTensorMutableData<float>();
std::cout << "Output[0] = " << output_data[0] << std::endl;
return 0;
}
📦 编译依赖
你需要:
下载或编译 ONNX Runtime C++ 库(含头文件 onnxruntime_cxx_api.h 和 .lib/.so)
链接 onnxruntime.lib(Windows)或 libonnxruntime.so(Linux)
官方预编译包:https://github.com/microsoft/onnxruntime/releases
支持 CPU、CUDA、DirectML、TensorRT、OpenVINO 等后端。
✅ 2. 直接解析 ONNX 文件(底层方式)
ONNX 模型本质是 Protocol Buffers(protobuf) 序列化文件。你可以:
使用 ONNX 官方提供的 C++ protobuf 定义(onnx.proto)
用 protoc 生成 C++ 解析类
直接读取模型结构(节点、权重、输入输出等)
示例:读取输入维度(不进行推理)
#include "onnx/onnx.pb.h"
#include <fstream>
#include <iostream>
int main() {
onnx::ModelProto model;
std::ifstream input("model.onnx", std::ios::binary);
if (model.ParseFromIstream(&input)) {
const auto& graph = model.graph();
for (const auto& input_tensor : graph.input()) {
std::cout << "Input: " << input_tensor.name() << std::endl;
for (const auto& dim : input_tensor.type().tensor_type().shape().dim()) {
if (dim.has_dim_value()) {
std::cout << " Dim: " << dim.dim_value() << std::endl;
} else if (dim.has_dim_param()) {
std::cout << " Dim: " << dim.dim_param() << " (dynamic)" << std::endl;
}
}
}
}
return 0;
}
⚠️ 注意:这种方式只能解析模型结构,不能执行推理。要推理仍需 ONNX Runtime 或自研执行引擎。
🆚 对比:ONNX Runtime vs 原生 protobuf 解析

💡 绝大多数场景应使用 ONNX Runtime C++ API,除非你是在开发自己的推理引擎或做模型分析工具。
ONNX 模型在 Python 中的解析主要依赖两个官方库:
onnx:用于加载、检查、修改和保存 ONNX 模型结构(即 protobuf 定义的计算图)。
onnxruntime(ORT):用于高效执行推理(inference),不直接解析模型结构,但可查询输入/输出信息。
下面分别介绍它们如何“解析”ONNX模型。
✅ 一、使用 onnx 库:解析模型结构(静态分析)
ONNX 模型本质是一个 Protocol Buffers(protobuf) 文件。onnx Python 包提供了对这个 protobuf 结构的封装,让你能以面向对象的方式访问模型的图、节点、张量等。
🔧 安装
pip install onnx
📌 基本用法
import onnx
1. 加载 ONNX 模型(解析为 ModelProto 对象)
model = onnx.load("model.onnx")
2. 验证模型是否合法
onnx.checker.check_model(model)
3. 访问模型元信息
print("IR Version:", model.ir_version)
print("Producer:", model.producer_name, model.producer_version)
4. 遍历输入张量
print("\n=== Inputs ===")
for inp in model.graph.input:
name = inp.name
shape = [d.dim_value if d.HasField('dim_value') else d.dim_param
for d in inp.type.tensor_type.shape.dim]
dtype = onnx.mapping.TENSOR_TYPE_TO_NP_TYPE[inp.type.tensor_type.elem_type]
print(f"Name: {name}, Shape: {shape}, Dtype: {dtype}")
5. 遍历输出张量
print("\n=== Outputs ===")
for out in model.graph.output:
name = out.name
shape = [d.dim_value if d.HasField('dim_value') else d.dim_param
for d in out.type.tensor_type.shape.dim]
dtype = onnx.mapping.TENSOR_TYPE_TO_NP_TYPE[out.type.tensor_type.elem_type]
print(f"Name: {name}, Shape: {shape}, Dtype: {dtype}")
6. 遍历计算图中的所有节点(算子)
print("\n=== Nodes (Operators) ===")
for node in model.graph.node:
print(f"OpType: {node.op_type}, Inputs: {node.input}, Outputs: {node.output}")
💡 关键对象结构(简化版)
ModelProto
└── GraphProto
├── input: List[ValueInfoProto] # 输入张量定义
├── output: List[ValueInfoProto] # 输出张量定义
├── initializer: List[TensorProto] # 常量权重(如卷积核、bias)
└── node: List[NodeProto] # 计算节点(算子)
├── op_type: str # 如 "Conv", "Relu", "MatMul"
├── input: List[str]
├── output: List[str]
└── attribute: List[AttributeProto] # 算子参数(如 kernel_size)
✅ 适用场景:模型可视化、结构修改、格式转换、调试、自定义优化 pass。
✅ 二、使用 onnxruntime:解析运行时接口(用于推理)
onnxruntime 不解析整个模型结构,而是加载模型后提供推理接口,并允许你查询输入/输出的名称和形状。
🔧 安装
pip install onnxruntime # CPU 版
或
pip install onnxruntime-gpu # GPU 版(需 CUDA)
📌 基本用法
import onnxruntime as ort
import numpy as np
1. 创建推理会话
sess = ort.InferenceSession("model.onnx")
2. 查询输入/输出信息
print("Inputs:")
for inp in sess.get_inputs():
print(f" Name: {inp.name}, Shape: {inp.shape}, Type: {inp.type}")
print("Outputs:")
for out in sess.get_outputs():
print(f" Name: {out.name}, Shape: {out.shape}, Type: {out.type}")
3. 准备输入数据(必须匹配 shape 和 dtype)
input_name = sess.get_inputs()[0].name
x = np.random.randn(1, 3, 224, 224).astype(np.float32)
4. 执行推理
outputs = sess.run(None, {input_name: x}) # None 表示返回所有输出
print("Inference result shape:", outputs[0].shape)
✅ 适用场景:部署、推理、性能测试。这是生产中最常用的用法。
🔍 两种“解析”的区别总结

🛠️ 实际应用场景举例
场景1:想把 batch 维度改为动态?
→ 用 onnx 修改 model.graph.input[0].type.tensor_type.shape.dim[0].dim_param = “batch”
场景2:想知道模型需要什么输入?
→ 用 onnxruntime 的 sess.get_inputs() 快速查看
场景3:想提取模型中的权重?
→ 用 onnx 遍历 model.graph.initializer,每个是 TensorProto,可用 numpy_helper.to_array() 转为 NumPy
from onnx import numpy_helper
for init in model.graph.initializer:
weight = numpy_helper.to_array(init)
print(init.name, weight.shape)
✅ 总结
onnx:解析 ONNX 模型的静态结构(protobuf 内容),适合分析和修改模型。
onnxruntime:加载 ONNX 模型进行运行时推理,适合部署和预测,也能快速获取 I/O 信息。
两者互补,常在项目中配合使用。例如:
用 onnx 修改模型;
用 onnxruntime 验证修改后能否正常推理。
✅ ONNX 支持 C++:通过 ONNX Runtime 提供完整的高性能推理能力。
✅ 可直接解析 ONNX 文件:通过 protobuf,适合模型检查、转换工具开发。
推荐做法:在 C++ 项目中部署 ONNX 模型 → 使用 ONNX Runtime C++ API。
🔗 官方资源
ONNX Runtime C++ API 文档:
https://onnxruntime.ai/docs/api/c/
GitHub 示例:
https://github.com/microsoft/onnxruntime/tree/main/samples/c_cxx
预编译库下载:
https://github.com/microsoft/onnxruntime/releases
如果你需要具体平台(如 Windows + Visual Studio 或 Linux + CMake)的集成教程,也可以告诉我!
ONNX模型解析与推理指南
515

被折叠的 条评论
为什么被折叠?



