ONNX Runtime 架构

本文档概述了 ONNX Runtime 的高级设计。

目录

主要目标

  • 最大限度地自动利用不同平台上的自定义加速器和运行时。
  • 为自定义加速器和运行时提供正确的抽象和运行时支持。我们将这种抽象称为执行提供者。它定义并向 ONNX Runtime 公开其一系列功能:它可以执行的单个或融合节点集、其内存分配器等等。自定义加速器和运行时都是执行提供者的实例。
  • 我们不期望执行提供者总能完全在其设备上运行 ONNX 模型。这意味着 ONNX Runtime 必须能够在涉及多个执行提供者的异构环境中执行单个模型。
  • 通过图转换 API 提供对高级优化的支持,这些优化可以表示为模型到模型的转换。此类转换分为两类:全局转换(需要对整个图进行分析和转换)和局部转换(可以捕获为简单的(代数)重写规则)。

高层系统架构

流程相当简单。

  1. 从 ONNX 模型开始,ONNX Runtime 首先将模型图转换为其内存中图表示。
  2. 它执行一组与提供者无关的优化
  3. 它根据可用的执行提供者将图划分为一组子图。
  4. 每个子图都分配给一个执行提供者。我们通过使用 GetCapability() API 查询执行提供者的能力来确保子图可以由执行提供者执行。

ONNX Runtime high level system architecture

关于分区的更多信息

ONNX Runtime 根据可用的执行提供者将模型图划分为子图,每个不同的提供者对应一个。ONNX Runtime 提供了一个默认执行提供者,用作无法推送到更专业但更高效的执行提供者的运算符的备用执行。直观地说,我们希望尽可能将计算推送到更专业的执行提供者。

我们使用简单的图分区技术。可用的执行提供者将以特定顺序考虑,每个提供者将被分配其能够处理的最大子图(可能不止一个)。ONNX Runtime 提供的默认执行提供者将是最后一个考虑的,它确保了完整性。未来可以考虑更复杂的优化(或者甚至可以将其实现为复合执行提供者)。

从概念上讲,每个分区都被简化为一个单独的融合运算符。它通过调用执行提供者的 Compile() 方法创建,并将其包装为自定义运算符。目前我们仅支持同步执行模式。执行提供者公开其内存分配器,该分配器用于为执行提供者分配输入张量。重写和分区将初始模型图转换为由分配给默认执行提供者或其他已注册执行提供者的运算符组成的新图。ONNX Runtime 执行引擎负责运行此图。

关键设计决策

  • 多个线程可以在同一推理会话对象上调用 Run() 方法。有关更多详细信息,请参阅API 文档
  • 为了便于此,所有内核的 Compute() 函数都是 const,这意味着内核是无状态的。
  • 执行提供者对运算符的实现称为内核。每个执行提供者支持一部分(ONNX)运算符/内核。
  • ONNX Runtime 保证所有运算符都由默认执行提供者支持。
  • 张量表示:ONNX Runtime 对张量运行时值使用标准表示。执行提供者如果选择,可以在内部使用不同的表示,但它们有责任在其子图边界处将值从/转换为标准表示。

可扩展性选项

返回顶部