1. 项目背景与动机
去年在部署一个图像分类模型时,我第一次真正接触到ONNX Runtime。当时为了把PyTorch训练好的模型部署到移动端,经历了onnx导出->图优化->量化->目标平台转换这一整套流程。最让我困惑的就是图优化环节——那些看似简单的算子融合、常量折叠等操作,到底是如何在不改变模型功能的前提下提升推理性能的?
市面上的深度学习框架文档往往只告诉你"这样做能优化",却很少解释"为什么能优化"。于是我决定自己动手实现一个迷你版的ONNX Runtime(我称之为miniONNXRuntime),专门研究图优化这个黑盒子。经过两个月的周末开发,终于弄明白了其中的门道。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ONNX Runtime核心架构解析
2.1 ONNX模型表示基础
ONNX模型本质上是计算图的序列化表示。一个典型的计算图包含:
python复制# 简化后的ONNX计算图结构示例
graph {
node { # 算子节点
input: ["input1", "input2"],
output: ["output1"],
op_type: "Conv"
}
initializer { # 权重常量
name: "conv1.weight",
data_type: FLOAT,
dims: [32, 3, 3, 3],
raw_data: [...]
}
}
这种基于Protocol Buffers的表示方式,使得模型可以跨框架移植。但原始的计算图往往存在以下优化空间:
- 冗余的转置操作(如连续Transpose-Op-Transpose结构)
- 可预先计算的常量表达式
- 相邻的同类型算子可合并(如多个Conv层融合)
2.2 图优化关键技术实现
2.2.1 常量折叠(Constant Folding)
这是最简单的优化手段。当发现图中某些节点的输入全部来自initializer(常量)时,可以预先计算这些节点的输出值。例如:
python复制# 优化前
Add(
input: ["const1", "const2"],
output:
