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 对张量运行时值使用标准表示形式。执行提供程序可以在内部使用不同的表示形式(如果他们选择这样做),但是他们有责任在其子图的边界处将值从/转换为标准表示形式。

可扩展性选项

返回顶部