Architecture
このドキュメントでは、ONNX Runtimeの高レベル設計について概説します。
- 異なるプラットフォームで利用可能なカスタムアクセラレーターとランタイムを最大限かつ自動的に活用する。
- カスタムアクセラレーターとランタイムに適切な抽象化とランタイムサポートを提供する。この抽象化を実行プロバイダーと呼びます。これは、ONNX Runtimeに対してその機能のセットを定義し、公開します:実行可能な単一または融合ノードのセット、メモリアロケーター、その他。カスタムアクセラレーターとランタイムは実行プロバイダーのインスタンスです。
- 実行プロバイダーが常にONNXモデルを完全にそのデバイス上で実行できるとは期待していません。これは、ONNX Runtimeが複数の実行プロバイダーを含む異種環境で単一のモデルを実行できる必要があることを意味します。
- グラフ変換APIを介してモデル間変換として表現できる高レベル最適化のサポートを提供する。このような変換は2つのカテゴリーに分類されます:グラフ全体の分析と変換を必要とするグローバル変換と、単純な(代数的)書き換えルールとして捉えることができるローカル変換。
高レベルシステムアーキテクチャ
Section titled “高レベルシステムアーキテクチャ”フローは非常にシンプルです。
- ONNXモデルから開始して、ONNX Runtimeはまずモデルグラフをメモリ内グラフ表現に変換します。
- プロバイダー非依存の最適化のセットを実行します。
- 利用可能な実行プロバイダーに基づいてグラフをサブグラフのセットに分割します。
- 各サブグラフは実行プロバイダーに割り当てられます。
GetCapability()APIを使用して実行プロバイダーの機能を照会することで、サブグラフが実行プロバイダーによって実行できることを保証します。
分割についての詳細
Section titled “分割についての詳細”ONNX Runtimeは、利用可能な実行プロバイダーに基づいてモデルグラフをサブグラフに分割し、各異なるプロバイダーに対して1つずつ割り当てます。ONNX Runtimeは、より特殊化されているがより効率的な実行プロバイダーにプッシュできない演算子のフォールバック実行として使用されるデフォルト実行プロバイダーを提供します。直感的に、可能な限り計算をより特殊化された実行プロバイダーにプッシュしたいと考えています。
シンプルなグラフ分割技術を使用します。利用可能な実行プロバイダーは特定の順序で考慮され、それぞれが処理できる最大のサブグラフ(複数の場合もある)が割り当てられます。ONNX Runtimeが提供するデフォルト実行プロバイダーは最後に考慮され、完全性を保証します。より洗練された最適化は将来考慮される可能性があります(または複合実行プロバイダーとして実装することも可能です)。
概念的に、各パーティションは単一の融合演算子に縮約されます。これは実行プロバイダーのCompile()メソッドを呼び出すことによって作成され、カスタム演算子としてラップされます。現在、同期実行モードのみをサポートしています。実行プロバイダーはそのメモリアロケーターを公開し、これは実行プロバイダーの入力テンソルを割り当てるために使用されます。書き換えと分割により、初期モデルグラフは、デフォルト実行プロバイダーまたは他の登録された実行プロバイダーのいずれかに割り当てられた演算子で構成される新しいグラフに変換されます。ONNX Runtime実行エンジンは、このグラフの実行を担当します。
主要な設計決定
Section titled “主要な設計決定”- 複数のスレッドが同じ推論セッションオブジェクトで
Run()メソッドを呼び出すことができます。詳細についてはAPI docを参照してください。 - これを促進するために、すべてのカーネルの
Compute()関数はconstであり、カーネルがステートレスであることを意味します。 - 実行プロバイダーによる演算子の実装はカーネルと呼ばれます。各実行プロバイダーは(ONNX)演算子/カーネルのサブセットをサポートします。
- ONNX Runtimeは、すべての演算子がデフォルト実行プロバイダーによってサポートされることを保証します。
- テンソル表現:ONNX Runtimeは、テンソルランタイム値に標準表現を使用します。実行プロバイダーは、選択すれば内部的に異なる表現を使用できますが、サブグラフの境界で標準表現との間で値を変換する責任があります。