CoreML 執行提供程式
Core ML 是 Apple 推出的一種機器學習框架。它旨在無縫高效地利用強大的硬體技術,包括 CPU、GPU 和神經網路引擎,以最大限度地提高效能,同時最大限度地減少記憶體和功耗。
目錄
要求
CoreML 執行提供程式 (EP) 需要執行 iOS 13 或更高版本的 iOS 裝置,或執行 macOS 10.15 或更高版本的 Mac 電腦。
建議使用配備 Apple 神經網路引擎的 Apple 裝置以獲得最佳效能。
安裝
ONNX Runtime 針對 iOS 的 CoreML EP 預構建二進位制檔案已釋出到 CocoaPods。
請參閱此處獲取安裝說明。
構建
有關 iOS 裝置的構建說明,請參閱構建 iOS 版。
用法
ONNX Runtime API 詳情請見此處。
CoreML EP 可透過 C、C++、Objective-C、C# 和 Java API 使用。
建立推理會話時必須顯式註冊 CoreML EP。例如
Ort::Env env = Ort::Env{ORT_LOGGING_LEVEL_ERROR, "Default"};
Ort::SessionOptions so;
std::unordered_map<std::string, std::string> provider_options;
provider_options["ModelFormat"] = std::to_string("MLProgram");
so.AppendExecutionProvider("CoreML", provider_options);
Ort::Session session(env, model_path, so);
在 ONNX Runtime 1.20.0 中,API OrtSessionOptionsAppendExecutionProvider_CoreML 已棄用。請改用 OrtSessionOptionsAppendExecutionProvider。
Ort::Env env = Ort::Env{ORT_LOGGING_LEVEL_ERROR, "Default"};
Ort::SessionOptions so;
uint32_t coreml_flags = 0;
Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CoreML(so, coreml_flags));
Ort::Session session(env, model_path, so);
配置選項(新 API)
CoreML EP 有幾個執行時選項可用。
要使用 CoreML EP 執行時選項,請建立一個表示這些選項的無符號整數,並透過使用按位或運算子來設定每個單獨的選項。
可透過將字串傳遞給 AppendExecutionProvider 方法來設定 ProviderOptions。
Ort::Env env = Ort::Env{ORT_LOGGING_LEVEL_ERROR, "Default"};
Ort::SessionOptions so;
std::string model_path = "/a/b/c/model.onnx";
std::unordered_map<std::string, std::string> provider_options;
provider_options["ModelFormat"] = "MLProgram";
provider_options["MLComputeUnits"] = "ALL";
provider_options["RequireStaticInputShapes"] = "0";
provider_options["EnableOnSubgraphs"] = "0";
so.AppendExecutionProvider("CoreML", provider_options);
Ort::Session session(env, model_path, so);
使用 CoreML EP 執行時選項的 Python 推理示例程式碼
import onnxruntime as ort
model_path = "model.onnx"
providers = [
('CoreMLExecutionProvider', {
"ModelFormat": "MLProgram", "MLComputeUnits": "ALL",
"RequireStaticInputShapes": "0", "EnableOnSubgraphs": "0"
}),
]
session = ort.InferenceSession(model_path, providers=providers)
outputs = ort_sess.run(None, input_feed)
可用選項(新 API)
ModelFormat 可以是以下值之一:(預設為 NeuralNetwork)
MLProgram:建立 MLProgram 格式模型。需要 Core ML 5 或更高版本 (iOS 15+ 或 macOS 12+)。NeuralNetwork:建立 NeuralNetwork 格式模型。需要 Core ML 3 或更高版本 (iOS 13+ 或 macOS 10.15+)。
MLComputeUnits 可以是以下值之一:(預設為 ALL)
CPUOnly:限制 CoreML 僅在 CPU 上執行。CPUAndNeuralEngine:為配備相容 Apple 神經網路引擎 (ANE) 的 Apple 裝置啟用 CoreML EP。CPUAndGPU:為配備相容 GPU 的 Apple 裝置啟用 CoreML EP。ALL:為所有相容的 Apple 裝置啟用 CoreML EP。
RequireStaticInputShapes 可以是以下值之一:(預設為 0)
僅允許 CoreML EP 接受輸入具有靜態形狀的節點。預設情況下,CoreML EP 也將允許輸入具有動態形狀,但動態形狀的輸入可能會對效能產生負面影響。
0:允許 CoreML EP 接受輸入具有動態形狀的節點。1:僅允許 CoreML EP 接受輸入具有靜態形狀的節點。
EnableOnSubgraphs 可以是以下值之一:(預設為 0)
啟用 CoreML EP 在控制流運算子(即 Loop、Scan 或 If 運算子)主體中的子圖上執行。
0:停用 CoreML EP 在控制流運算子主體中的子圖上執行。1:啟用 CoreML EP 在控制流運算子主體中的子圖上執行。
SpecializationStrategy:此功能自 macOS>=10.15 或 iOS>=18.0 開始可用。此過程可能會影響模型載入時間和預測延遲。使用此選項可為您的模型定製專門化策略。導航至 Apple 文件瞭解更多資訊。可以是以下值之一:(預設為 Default)
預設:快速預測:
ProfileComputePlan:分析 Core ML MLComputePlan。這將記錄每個運算子被分派到哪個硬體以及估計的執行時間。旨在供開發人員使用,但如果效能不符合預期,則提供有用的診斷資訊。可以是以下值之一:(預設為 0)
0:停用配置檔案。1:啟用配置檔案。
AllowLowPrecisionAccumulationOnGPU:請參閱 Apple 文件。可以是以下值之一:(預設為 0)
0:使用 float32 資料型別累積資料。1:使用低精度資料 (float16) 累積資料。
ModelCacheDirectory:儲存 Core ML 模型快取的目錄路徑。CoreML EP 會將捕獲的子圖編譯成 CoreML 格式圖並儲存到磁碟。對於給定模型,如果未啟用快取,CoreML EP 每次都會編譯並儲存到磁碟,這對於複雜模型可能會花費大量時間(甚至幾分鐘)。透過提供快取路徑,可以重用 CoreML 格式的模型。(預設停用快取)。
"":停用快取。(預設為空字串)"/path/to/cache":啟用快取。(快取目錄路徑,如果不存在將建立)
模型的快取資訊儲存在快取目錄中模型雜湊下。計算雜湊的方式有三種,按優先順序排序。
- 從模型 metadata_props 讀取。這為使用者提供了直接控制雜湊的方式,也是推薦的用法。快取鍵應滿足以下條件:(1)值必須只包含字母數字字元。(2)len(value) < 64。EP 將重新雜湊快取鍵以滿足這些條件。
- 建立推理會話時使用的模型 URL 的雜湊值。
- 如果推理會話是使用記憶體中的位元組建立的(即沒有模型路徑),則為圖輸入和節點輸出的雜湊值。
至關重要的是,如果模型發生更改,則雜湊值必須更改,或者您必須清除之前的快取資訊。例如,如果模型 URL 用於雜湊(上述選項 2),則必須從不同的路徑載入更新的模型以更改雜湊值。
ONNX Runtime 沒有跟蹤模型更改並刪除快取條目的機制。
以下是如何在模型元資料中填充模型雜湊的示例
import onnx
import hashlib
# You can use any other hash algorithms to ensure the model and its hash-value is a one-one mapping.
def hash_file(file_path, algorithm='sha256', chunk_size=8192):
hash_func = hashlib.new(algorithm)
with open(file_path, 'rb') as file:
while chunk := file.read(chunk_size):
hash_func.update(chunk)
return hash_func.hexdigest()
CACHE_KEY_NAME = "CACHE_KEY"
model_path = "/a/b/c/model.onnx"
m = onnx.load(model_path)
cache_key = m.metadata_props.add()
cache_key.key = CACHE_KEY_NAME
cache_key.value = str(hash_file(model_path))
onnx.save_model(m, model_path)
配置選項(舊 API)
uint32_t coreml_flags = 0;
coreml_flags |= COREML_FLAG_ONLY_ENABLE_DEVICE_WITH_ANE;
可用選項(已棄用 API)
COREML_FLAG_USE_CPU_ONLY
限制 CoreML 僅在 CPU 上執行。
這會降低效能,但提供沒有精度損失的參考輸出值,這對於驗證很有用。
僅供開發人員使用。
COREML_FLAG_ENABLE_ON_SUBGRAPH
啟用 CoreML EP 在控制流運算子(即 Loop、Scan 或 If 運算子)主體中的子圖上執行。
COREML_FLAG_ONLY_ENABLE_DEVICE_WITH_ANE
預設情況下,CoreML EP 將對所有相容的 Apple 裝置啟用。
設定此選項將僅對配備相容 Apple 神經網路引擎 (ANE) 的 Apple 裝置啟用 CoreML EP。請注意,啟用此選項並不能保證整個模型僅使用 ANE 執行。
有關更多資訊,請參閱哪些裝置有 ANE?
COREML_FLAG_ONLY_ALLOW_STATIC_INPUT_SHAPES
僅允許 CoreML EP 接受輸入具有靜態形狀的節點。預設情況下,CoreML EP 也將允許輸入具有動態形狀,但動態形狀的輸入可能會對效能產生負面影響。
COREML_FLAG_CREATE_MLPROGRAM
建立 MLProgram 格式模型。需要 Core ML 5 或更高版本 (iOS 15+ 或 macOS 12+)。預設情況下會建立 NeuralNetwork 模型,因為該模型需要 Core ML 3 或更高版本 (iOS 13+ 或 macOS 10.15+)。
支援的運算子
NeuralNetwork
建立 NeuralNetwork 模型(預設)時 CoreML 執行提供程式支援的運算子
| 運算子 | 注意 |
|---|---|
| ai.onnx:Add | |
| ai.onnx:ArgMax | |
| ai.onnx:AveragePool | 僅支援 2D 池化。 |
| ai.onnx:BatchNormalization | |
| ai.onnx:Cast | |
| ai.onnx:Clip | |
| ai.onnx:Concat | |
| ai.onnx:Conv | 僅支援 1D/2D 卷積。 權重和偏差應為常數。 |
| ai.onnx:DepthToSpace | 僅支援 DCR 模式的 DepthToSpace。 |
| ai.onnx:Div | |
| ai.onnx:Flatten | |
| ai.onnx:Gather | 不支援標量值的輸入 indices。 |
| ai.onnx:Gemm | 輸入 B 應為常數。 |
| ai.onnx:GlobalAveragePool | 僅支援 2D 池化。 |
| ai.onnx:GlobalMaxPool | 僅支援 2D 池化。 |
| ai.onnx:LeakyRelu | |
| ai.onnx:LRN | |
| ai.onnx:MatMul | 輸入 B 應為常數。 |
| ai.onnx:MaxPool | 僅支援 2D 池化。 |
| ai.onnx:Mul | |
| ai.onnx:Pad | 僅支援常量模式和最後兩個維度的填充。 輸入 pads 和 constant_value 應為常數。 如果提供,axes 應為常數。 |
| ai.onnx:Pow | 僅支援兩個輸入均為 fp32 的情況。 |
| ai.onnx:PRelu | 輸入斜率應為常數。 輸入斜率的形狀應為 [C, 1, 1] 或只有一個元素。 |
| ai.onnx:Reciprocal | |
| ai.onnx.ReduceSum | |
| ai.onnx:Relu | |
| ai.onnx:Reshape | |
| ai.onnx:Resize | 4D 輸入。coordinate_transformation_mode == asymmetric。mode == linear 或 nearest。nearest_mode == floor。exclude_outside == falsescales 或 sizes 必須是常數。 |
| ai.onnx:Shape | 不支援帶有非預設值的屬性 start。不支援屬性 end。 |
| ai.onnx:Sigmoid | |
| ai.onnx:Slice | 輸入 starts、ends、axes 和 steps 應為常數。不支援空切片。 |
| ai.onnx:Softmax | |
| ai.onnx:Split | 如果提供,splits 必須是常數。 |
| ai.onnx:Squeeze | |
| ai.onnx:Sqrt | |
| ai.onnx:Sub | |
| ai.onnx:Tanh | |
| ai.onnx:Transpose |
MLProgram
當建立 MLProgram 模型(設定 COREML_FLAG_CREATE_MLPROGRAM 標誌時)CoreML 執行提供程式支援的運算子
| 運算子 | 注意 |
|---|---|
| ai.onnx:Add | |
| ai.onnx:Argmax | |
| ai.onnx:AveragePool | 目前僅支援 2D 池化。如果需要,可以新增 3D 和 5D 支援。 |
| ai.onnx:Cast | |
| ai.onnx:Clip | |
| ai.onnx:Concat | |
| ai.onnx:Conv | 僅支援 1D/2D 卷積。 如果提供,偏差必須是常數。 |
| ai.onnx:ConvTranspose | 權重和偏差必須是常數。 不支援 SAME_UPPER/SAME_LOWER 的 padding_type。 kernel_shape 必須有預設值。 不支援 output_shape。 output_padding 必須有預設值。 |
| ai.onnx:DepthToSpace | 如果“mode”為“CRD”,則輸入必須具有固定形狀。 |
| ai.onnx:Div | |
| ai.onnx:Erf | |
| ai.onnx:Gemm | 輸入 B 必須是常數。 |
| ai.onnx:Gelu | |
| ai.onnx:GlobalAveragePool | 目前僅支援 2D 池化。如果需要,可以新增 3D 和 5D 支援。 |
| ai.onnx:GlobalMaxPool | 目前僅支援 2D 池化。如果需要,可以新增 3D 和 5D 支援。 |
| ai.onnx:GridSample | 4D 輸入。 “mode”為“linear”或“zeros”。 不支援 (mode==linear && padding_mode==reflection && align_corners==0)。 |
| ai.onnx:GroupNormalization | |
| ai.onnx:InstanceNormalization | |
| ai.onnx:LayerNormalization | |
| ai.onnx:LeakyRelu | |
| ai.onnx:MatMul | 目前僅支援 transA == 0、alpha == 1.0 和 beta == 1.0 的情況。 |
| ai.onnx:MaxPool | 目前僅支援 2D 池化。如果需要,可以新增 3D 和 5D 支援。 |
| ai.onnx:Max | |
| ai.onnx:Mul | |
| ai.onnx:Pow | 僅支援兩個輸入均為 fp32 的情況。 |
| ai.onnx:PRelu | |
| ai.onnx:Reciprocal | 這需要一個 epislon (預設 1e-4),而 onnx 沒有提供 |
| ai.onnx:ReduceSum | |
| ai.onnx:ReduceMean | |
| ai.onnx:ReduceMax | |
| ai.onnx:Relu | |
| ai.onnx:Reshape | |
| ai.onnx:Resize | 請參閱 resize_op_builder.cc 實現。組合情況太多,無法一一描述所有有效組合。 |
| ai.onnx:Round | |
| ai.onnx:Shape | |
| ai.onnx:Slice | starts/ends/axes/steps 必須是常量初始化器。 |
| ai.onnx:Split | 如果提供,splits 必須是常數。 |
| ai.onnx:Sub | |
| ai.onnx:Sigmoid | |
| ai.onnx:Softmax | |
| ai.onnx:Sqrt | |
| ai.onnx:Squeeze | |
| ai.onnx:Tanh | |
| ai.onnx:Transpose | |
| ai.onnx:Unsqueeze |