犀牛鸟 2026 研究笔记 estelledc.github.io

ONNX Runtime 深度解读

“标准集装箱港口——以 ONNX 标准为轴心的全平台推理枢纽”


一句话定位

ONNX Runtime 是微软主导的跨平台推理引擎,以 ONNX 标准格式为核心,通过 Execution Provider 插件机制对接 TensorRT/OpenVINO/CoreML/CUDA/QNN 等所有主流硬件后端。21K star,是工业界部署覆盖最广的推理引擎。

设计哲学上最精彩的地方

ONNX Runtime 最精彩的设计是 Execution Provider(EP)插件架构。这个设计的本质是把”谁来执行哪些算子”这个问题变成了一个竞价机制:多个 EP 按优先级排队,每个 EP 通过 GetCapability() 声明自己能处理哪些节点,优先级高的先认领,剩余的交给下一级,CPU EP 永远兜底。

类比:你有一个搬家任务(模型推理),同时请了专业搬家公司(TensorRT EP)、朋友帮忙(CUDA EP)和自己搬(CPU EP)。专业公司先挑走大件家具(计算密集子图),朋友搬中等物品,你自己搬剩下的小件。谁来搬什么不是预先固定的,而是根据每家的能力动态分配。当相邻节点落在不同 EP 上时,ORT 自动插入 MemcpyToHost/MemcpyFromHost 节点处理数据传输——搬家公司之间的交接也自动安排好了。

从 ORT 1.23 起,新 EP 推荐作为动态库插件.so/.dll)实现,无需修改 ORT 核心代码即可扩展。这意味着硬件厂商可以独立开发、独立发布自己的 EP,不用等 ORT 主仓合并。这种解耦程度在六个框架中是最高的。

第二个精彩设计是 ONNX opset 版本化。同一个 Add 算子在 opset 7-12 和 opset 14+ 可能有不同的语义,ORT 通过版本化注册机制精确匹配——REG_ELEMENTWISE_VERSIONED_TYPED_KERNEL(Add, 7, 12, float, Add)。这保证了 ORT 能正确运行跨越多年、多个训练框架导出的 ONNX 模型,向后兼容性是工业部署的生命线

标准化生态——ONNX 的枢纽价值

ORT 直接使用 ONNX 标准格式,不需要模型转换步骤。PyTorch/TensorFlow/PaddlePaddle/Keras 都能原生导出 ONNX。这意味着用户不需要学一个新的转换工具链——模型从训练到部署的路径最短

ONNX 标准还定义了完整的算子规范(约 200+ 个算子),每个算子有精确的数学语义定义。ORT 的 CPU EP 实现了全部标准算子,是事实上的”参考实现”。其他框架(ncnn/MNN/TNN 等)在支持 ONNX 模型时,也需要参考这些语义定义。

“最薄”的数据容器

ORT 的 Tensor 是六个框架中最”薄”的——不拥有内存,只持有裸数据指针 + 形状 + 设备位置信息。内存生命周期完全由 Executor/Workspace 管理。OrtMemoryInfo 精确描述数据位置:OrtDevice{DeviceType, MemoryType, DeviceId} 三元组可以表达”CUDA 设备 0 的 pinned memory”这样的细粒度位置。

ORT 不做内置的 SIMD 友好布局优化(没有 elempack 或 NC4HW4),把所有布局优化的责任推给了 EP 层。这是标准化路线的必然选择——标准层越薄,EP 的自由度越大,但也意味着 CPU 纯推理性能不如手写 NEON 优化的 ncnn。

局限性与场景边界

ORT 代码量最庞大(~8000 文件),覆盖云/边/端全平台,通读成本极高。抽象层最厚,单步调试时 call stack 较深。没有端侧训练能力,LLM 推理通过独立的 ONNX Runtime GenAI 模块支持。在纯移动端场景下,二进制体积和启动速度不如 ncnn/MNN 等轻量框架。ORT 的优势场景是”一个模型跑遍所有平台”,而非”在某一个平台上跑到极致”

本地代码结构

onnxruntime/
  onnxruntime/
    core/
      framework/
        tensor.h              # Tensor 数据容器(浅层指针)
        op_kernel.h           # OpKernel 基类
        execution_provider.h  # EP 接口定义
        session/
          inference_session.h # 推理会话
      graph/
        graph.h               # ONNX 图表示
        graph_transformer.h   # 图优化变换
      optimizer/              # 图优化 pass 集合
      providers/
        cpu/                  # CPU EP(参考实现)
        cuda/                 # CUDA EP
        tensorrt/             # TensorRT EP
        coreml/               # CoreML EP
        openvino/             # OpenVINO EP
        qnn/                  # Qualcomm QNN EP
    contrib_ops/              # 社区贡献算子
  include/
    onnxruntime/
      core/session/           # 公共 API 头文件

本地关键文件

文件 用途
core/framework/tensor.h Tensor 定义,裸指针 + 形状 + OrtMemoryInfo
core/framework/op_kernel.h OpKernel 基类,Compute() + PrePack() 接口
core/framework/execution_provider.h EP 插件接口,GetCapability/Compile/GetKernelRegistry
core/session/inference_session.h InferenceSession,图分区 + 执行计划
core/graph/graph_transformer.h 图优化变换管线
core/providers/cpu/ CPU EP 全量算子实现(ONNX 标准参考实现)
core/providers/cuda/ CUDA EP 实现