ONNX Runtime 架構
本文件概述了 ONNX Runtime 的高階設計。
目錄
主要目標
- 最大限度地自動利用不同平臺上的自定義加速器和執行時。
- 為自定義加速器和執行時提供正確的抽象和執行時支援。我們將這種抽象稱為執行提供者。它定義並向 ONNX Runtime 公開其一系列功能:它可以執行的單個或融合節點集、其記憶體分配器等等。自定義加速器和執行時都是執行提供者的例項。
- 我們不期望執行提供者總能完全在其裝置上執行 ONNX 模型。這意味著 ONNX Runtime 必須能夠在涉及多個執行提供者的異構環境中執行單個模型。
- 透過圖轉換 API 提供對高階最佳化的支援,這些最佳化可以表示為模型到模型的轉換。此類轉換分為兩類:全域性轉換(需要對整個圖進行分析和轉換)和區域性轉換(可以捕獲為簡單的(代數)重寫規則)。
高層系統架構
流程相當簡單。
- 從 ONNX 模型開始,ONNX Runtime 首先將模型圖轉換為其記憶體中圖表示。
- 它執行一組與提供者無關的最佳化。
- 它根據可用的執行提供者將圖劃分為一組子圖。
- 每個子圖都分配給一個執行提供者。我們透過使用
GetCapability()API 查詢執行提供者的能力來確保子圖可以由執行提供者執行。

關於分割槽的更多資訊
ONNX Runtime 根據可用的執行提供者將模型圖劃分為子圖,每個不同的提供者對應一個。ONNX Runtime 提供了一個預設執行提供者,用作無法推送到更專業但更高效的執行提供者的運算子的備用執行。直觀地說,我們希望儘可能將計算推送到更專業的執行提供者。
我們使用簡單的圖分割槽技術。可用的執行提供者將以特定順序考慮,每個提供者將被分配其能夠處理的最大子圖(可能不止一個)。ONNX Runtime 提供的預設執行提供者將是最後一個考慮的,它確保了完整性。未來可以考慮更復雜的最佳化(或者甚至可以將其實現為複合執行提供者)。
從概念上講,每個分割槽都被簡化為一個單獨的融合運算子。它透過呼叫執行提供者的 Compile() 方法建立,並將其包裝為自定義運算子。目前我們僅支援同步執行模式。執行提供者公開其記憶體分配器,該分配器用於為執行提供者分配輸入張量。重寫和分割槽將初始模型圖轉換為由分配給預設執行提供者或其他已註冊執行提供者的運算子組成的新圖。ONNX Runtime 執行引擎負責執行此圖。
關鍵設計決策
- 多個執行緒可以在同一推理會話物件上呼叫
Run()方法。有關更多詳細資訊,請參閱API 文件。 - 為了便於此,所有核心的
Compute()函式都是 const,這意味著核心是無狀態的。 - 執行提供者對運算子的實現稱為核心。每個執行提供者支援一部分(ONNX)運算子/核心。
- ONNX Runtime 保證所有運算子都由預設執行提供者支援。
- 張量表示:ONNX Runtime 對張量執行時值使用標準表示。執行提供者如果選擇,可以在內部使用不同的表示,但它們有責任在其子圖邊界處將值從/轉換為標準表示。