重要提示:此資訊僅適用於 ONNX Runtime 1.10 及更早版本。請使用更新的版本。
ONNX Runtime 移動效能調優
瞭解不同最佳化如何影響效能,並獲取使用 ORT 格式模型進行效能測試的建議。
ONNX Runtime Mobile 可用於在 Android 平臺上使用 NNAPI(透過 NNAPI 執行提供程式 (EP))執行 ORT 格式模型,以及在 iOS 平臺上使用 CoreML(透過 CoreML EP)執行模型。
首先,請回顧 在 ONNX Runtime Mobile 中使用 NNAPI 和 在 ONNX Runtime 中使用 CoreML 中的介紹性詳細資訊。
重要提示: 為簡潔起見,本頁中的示例均指 NNAPI EP。此資訊同樣適用於 CoreML EP,因此下文中任何對“NNAPI”的引用都可以替換為“CoreML”。
在 ONNX Runtime 1.9 版本中添加了對建立 CoreML 感知型 ORT 格式模型的支援,類似於建立 NNAPI 感知型 ORT 格式模型。
目錄
1. ONNX 模型最佳化示例
ONNX Runtime 會對 ONNX 模型應用最佳化以提高推理效能。這些最佳化在匯出 ORT 格式模型之前發生。有關可用最佳化的更多詳細資訊,請參閱圖最佳化文件。
瞭解不同最佳化級別如何影響模型中的節點非常重要,因為這將決定模型有多少部分可以使用 NNAPI 或 CoreML 執行。
基本
基本最佳化會刪除冗餘節點並執行常量摺疊。在修改模型時,這些最佳化僅使用 ONNX 運算子。
擴充套件
擴充套件最佳化會用自定義的內部 ONNX Runtime 運算子替換一個或多個標準 ONNX 運算子,以提升效能。每個最佳化都有一個適用於它的 EP 列表。它將只替換分配給該 EP 的節點,並且替換的節點將使用相同的 EP 執行。
佈局
佈局最佳化可能是硬體特定的,涉及 ONNX 使用的 NCHW 影像佈局與 NHWC 或 NCHWc 格式之間的內部轉換。它們在最佳化級別設定為“all”時啟用。
- 對於 ONNX Runtime 1.8 之前的版本,在建立 ORT 格式模型時,不應使用佈局最佳化。
- 對於 ONNX Runtime 1.8 或更高版本,可以啟用佈局最佳化,因為硬體特定最佳化會自動停用。
建立最佳化後的 ORT 格式模型時的最佳化結果
以下是當僅啟用 CPU EP 並應用於 MNIST 模型時,基本和擴充套件最佳化中發生的變化示例。最佳化級別在建立 ORT 格式模型時指定。
- 在基本級別,我們組合了 Conv 和 Add 節點(加法透過 Conv 的“B”輸入完成),我們將 MatMul 和 Add 組合成一個 Gemm 節點(加法透過 Gemm 的“C”輸入完成),並執行常量摺疊以移除一個 Reshape 節點。
python <ORT repository root>/tools/python/convert_onnx_models_to_ort.py --optimization_level basic /dir_with_mnist_onnx_model
- 在擴充套件級別,我們還使用內部 ONNX Runtime FusedConv 運算子融合了 Conv 和 Relu 節點。
python <ORT repository root>/tools/python/convert_onnx_models_to_ort.py --optimization_level extended /dir_with_mnist_onnx_model

使用 NNAPI EP 執行最佳化後的 ORT 格式模型的結果
如果在執行時註冊了 NNAPI EP,它將有機會選擇載入模型中它可以執行的節點。這樣做時,它會盡可能多地將節點組合在一起,以最大程度地減少在 CPU 和 NNAPI 之間複製資料以執行節點的開銷。每組節點都可以被視為一個子圖。每個子圖中的節點越多,子圖越少,效能就會越好。
對於每個子圖,NNAPI EP 將建立一個NNAPI 模型,該模型複製原始節點的處理過程。它將建立一個執行此 NNAPI 模型並執行 CPU 和 NNAPI 之間任何所需資料複製的函式。ONNX Runtime 將用一個呼叫此函式的單個節點替換載入模型中的原始節點。
如果 NNAPI EP 未註冊或無法處理某個節點,則該節點將使用 CPU EP 執行。
下面是一個 MNIST 模型的示例,比較瞭如果在執行時註冊 NNAPI EP,ORT 格式模型會發生什麼。
由於基本級別最佳化會生成一個僅使用 ONNX 運算子的模型,因此 NNAPI EP 能夠處理模型的大部分,因為 NNAPI 可以執行 Conv、Relu 和 MaxPool 節點。這是透過單個 NNAPI 模型完成的,因為所有 NNAPI 可以處理的節點都已連線。我們預計使用 NNAPI 會使此模型獲得性能提升,因為單個 NNAPI 節點在 CPU 和 NNAPI 之間進行裝置複製的開銷很可能低於使用 NNAPI 一次性執行多個操作所節省的時間。
擴充套件級別最佳化引入了自定義的 FusedConv 節點,NNAPI EP 會忽略這些節點,因為它只會處理使用 NNAPI 可以處理的 ONNX 運算子的節點。這導致兩個節點使用 NNAPI,每個節點處理一個 MaxPool 操作。此模型的效能可能會受到不利影響,因為 CPU 和 NNAPI 之間裝置複製的開銷(在兩個 NNAPI 節點之前和之後都需要)不太可能超過每次使用 NNAPI 執行單個 MaxPool 操作所節省的時間。透過不註冊 NNAPI EP,使模型中的所有節點都使用 CPU EP 執行,可能會獲得更好的效能。

2. 初始效能測試
最佳最佳化設定因模型而異。有些模型可能在使用 NNAPI 時表現更好,有些則不然。由於效能是模型特有的,您必須執行效能測試以確定最適合您模型的組合。
建議執行效能測試
- 啟用 NNAPI,並使用基本級別最佳化建立的 ORT 格式模型
- 停用 NNAPI,並使用擴充套件或所有級別最佳化建立的 ORT 格式模型
- ONNX Runtime 1.8 或更高版本使用所有,早期版本使用擴充套件
對於大多數場景,預計這兩種方法之一將產生最佳效能。
如果使用具有基本級別最佳化和 NNAPI 的 ORT 格式模型產生相同或更好的效能,則可能透過建立 NNAPI 感知型 ORT 格式模型來進一步提高效能。此模型的區別在於,更高級別的最佳化僅應用於無法使用 NNAPI 執行的節點。是否有任何節點屬於此類別取決於模型。
3. 建立 NNAPI 感知型 ORT 格式模型
NNAPI 感知型 ORT 格式模型將保留 ONNX 模型中所有可以使用 NNAPI 執行的節點,並允許對任何剩餘節點應用擴充套件最佳化。
對於我們的 MNIST 模型,這意味著在應用基本最佳化後,紅色陰影中的節點保持不變,綠色陰影中的節點可以應用擴充套件最佳化。

要建立 NNAPI 感知型 ORT 格式模型,請按照以下步驟操作。
-
透過從原始碼構建 ONNX Runtime,建立一個包含 NNAPI EP 的 ONNX Runtime“完整”構建。
此構建可在任何平臺上進行,因為 NNAPI EP 可用於建立 ORT 格式模型,而無需 Android NNAPI 庫,因為此過程中沒有模型執行。構建時,如果缺少任何標誌,請將
--use_nnapi --build_shared_lib --build_wheel新增到構建標誌中。請勿新增
--minimal_build標誌。- Windows
<ONNX Runtime repository root>\build.bat --config RelWithDebInfo --use_nnapi --build_shared_lib --build_wheel --parallel - Linux
<ONNX Runtime repository root>/build.sh --config RelWithDebInfo --use_nnapi --build_shared_lib --build_wheel --parallel
注意:對於 ONNX Runtime 1.10 及更早版本,如果您之前使用簡化運算子核心進行了最小構建,則需要執行
git reset --hard以確保在執行“完整”構建之前撤銷所有運算子核心排除。否則,您可能由於缺少核心而無法載入 ONNX 格式模型。 - Windows
- 從構建輸出目錄安裝 python wheel。
- Windows:位於
build/Windows/<config>/<config>/dist/<package name>.whl。 - Linux:位於
build/Linux/<config>/dist/<package name>.whl。包名稱將根據您的平臺、Python 版本和構建引數而異。<config>是構建命令中--config引數的值。pip install -U build\Windows\RelWithDebIfo\RelWithDebIfo\dist\onnxruntime_noopenmp-1.7.0-cp37-cp37m-win_amd64.whl
- Windows:位於
- 按照標準說明執行
convert_onnx_models_to_ort.py來建立 NNAPI 感知型 ORT 格式模型,並啟用 NNAPI (--use_nnapi),將最佳化級別設定為擴充套件或所有(例如--optimization_level extended)。這將允許在 NNAPI 無法處理的任何節點上執行更高級別的最佳化。python <ORT repository root>/tools/python/convert_onnx_models_to_ort.py --use_nnapi --optimization_level extended /models必須安裝從啟用了 NNAPI 的“完整”構建中獲得的 python 包,
--use_nnapi才能成為有效選項建立的這個 ORT 模型可以與包含 NNAPI EP 的最小構建一起使用。