Core ML 後端¶
Core ML delegate 是 ExecuTorch 利用 Apple 的 CoreML 框架在裝置端進行機器學習的解決方案。藉助 CoreML,模型可以在 CPU、GPU 和 Apple 神經網路引擎 (ANE) 上執行。
功能¶
動態排程到 CPU、GPU 和 ANE。
支援 fp32 和 fp16 計算。
目標裝置要求¶
以下是在各種硬體上執行 CoreML 委託的 ExecuTorch 模型的最低作業系統要求
使用 CoreML 後端¶
要在匯出和降級過程中指定 CoreML 後端,請將 CoreMLPartitioner 的例項傳遞給 to_edge_transform_and_lower。下面的示例演示了使用 torchvision 中的 MobileNet V2 模型完成此過程。
import torch
import torchvision.models as models
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
from executorch.backends.apple.coreml.partition import CoreMLPartitioner
from executorch.exir import to_edge_transform_and_lower
mobilenet_v2 = models.mobilenetv2.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).eval()
sample_inputs = (torch.randn(1, 3, 224, 224), )
et_program = to_edge_transform_and_lower(
torch.export.export(mobilenet_v2, sample_inputs),
partitioner=[CoreMLPartitioner()],
).to_executorch()
with open("mv2_coreml.pte", "wb") as file:
et_program.write_to_file(file)
Partitioner API¶
CoreML partitioner API 允許配置模型委託給 CoreML。傳遞一個不帶額外引數的 CoreMLPartitioner 例項將以預設設定在 CoreML 後端上執行儘可能多的模型。這是最常見的用例。對於高階用例,partitioner 透過 建構函式公開以下選項
skip_ops_for_coreml_delegation: 允許您跳過由 CoreML 委託的 ops(運算元)。預設情況下,CoreML 支援的所有運算元都將被委託。請參閱此處獲取跳過運算元委託的示例。compile_specs: CoreML 後端的 CompileSpec 列表。這些控制 CoreML 委託的低階細節,例如計算單元(CPU、GPU、ANE)、iOS 部署目標以及計算精度(FP16、FP32)。這些將在下面進一步討論。take_over_mutable_buffer: 一個布林值,指示狀態模型中的 PyTorch 可變緩衝區是否應轉換為 CoreML MLState。如果設定為 false,PyTorch 圖中的可變緩衝區將在底層轉換為 CoreML 降級模組的圖輸入和輸出。通常將 take_over_mutable_buffer 設定為 true 會帶來更好的效能,但使用 MLState 需要 iOS >= 18.0、macOS >= 15.0 和 XCode >= 16.0。
CoreML CompileSpec¶
CompileSpec 列表透過 CoreMLBackend.generate_compile_specs 構建。以下是可用選項
compute_unit: 控制 CoreML 使用的計算單元(CPU、GPU、ANE)。預設值為 coremltools.ComputeUnit.ALL。coremltools 中可用的選項有coremltools.ComputeUnit.ALL(使用 CPU、GPU 和 ANE)
coremltools.ComputeUnit.CPU_ONLY(僅使用 CPU)
coremltools.ComputeUnit.CPU_AND_GPU(使用 CPU 和 GPU,但不使用 ANE)
coremltools.ComputeUnit.CPU_AND_NE(使用 CPU 和 ANE,但不使用 GPU)
minimum_deployment_target: 最低 iOS 部署目標(例如,coremltools.target.iOS18)。預設值為 coremltools.target.iOS15。compute_precision: CoreML 使用的計算精度(coremltools.precision.FLOAT16, coremltools.precision.FLOAT32)。預設值為 coremltools.precision.FLOAT16。請注意,無論匯出的 PyTorch 模型中指定了什麼 dtype,都會應用此計算精度。例如,預設情況下,一個 FP32 PyTorch 模型在委託給 CoreML 後端時將被轉換為 FP16。另請注意,ANE 僅支援 FP16 精度。model_type: 在建立 .pte 檔案期間,模型是應該編譯為 CoreML mlmodelc 格式(CoreMLBackend.MODEL_TYPE.COMPILED_MODEL),還是應該在裝置上編譯為 mlmodelc(CoreMLBackend.MODEL_TYPE.MODEL)。使用 CoreMLBackend.MODEL_TYPE.COMPILED_MODEL 並提前進行編譯應該可以改善首次裝置端模型載入時間。
測試模型¶
生成 CoreML 委託的 .pte 檔案後,可以使用 ExecuTorch 執行時 Python 繫結從 Python 測試模型。這可用於對模型進行健全性檢查並評估數值精度。有關更多資訊,請參閱測試模型。
量化¶
要為 CoreML 後端量化 PyTorch 模型,請使用 CoreMLQuantizer。Quantizers 是特定於後端的,CoreMLQuantizer 配置為量化模型以利用 CoreML 後端可用的量化。
使用 PT2E 流程進行 8 位量化¶
要使用 PT2E 流程執行 8 位量化,請執行以下步驟
定義 coremltools.optimize.torch.quantization.LinearQuantizerConfig 並用它建立一個
CoreMLQuantizer例項。使用
torch.export.export_for_training匯出將用於量化的圖模組。呼叫
prepare_pt2e以準備模型進行量化。對於靜態量化,使用代表性樣本執行準備好的模型,以校準量化張量啟用範圍。
呼叫
convert_pt2e對模型進行量化。使用標準流程匯出和降級模型。
的輸出是一個 PyTorch 模型,可以使用正常流程進行匯出和降級。由於它是一個常規的 PyTorch 模型,因此也可以使用標準 PyTorch 技術評估量化模型的精度。convert_pt2e
import torch
import coremltools as ct
import torchvision.models as models
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
from executorch.backends.apple.coreml.quantizer import CoreMLQuantizer
from executorch.backends.apple.coreml.partition import CoreMLPartitioner
from torch.ao.quantization.quantize_pt2e import convert_pt2e, prepare_pt2e
from executorch.exir import to_edge_transform_and_lower
from executorch.backends.apple.coreml.compiler import CoreMLBackend
mobilenet_v2 = models.mobilenetv2.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).eval()
sample_inputs = (torch.randn(1, 3, 224, 224), )
# Step 1: Define a LinearQuantizerConfig and create an instance of a CoreMLQuantizer
quantization_config = ct.optimize.torch.quantization.LinearQuantizerConfig.from_dict(
{
"global_config": {
"quantization_scheme": ct.optimize.torch.quantization.QuantizationScheme.symmetric,
"milestones": [0, 0, 10, 10],
"activation_dtype": torch.quint8,
"weight_dtype": torch.qint8,
"weight_per_channel": True,
}
}
)
quantizer = CoreMLQuantizer(quantization_config)
# Step 2: Export the model for training
training_gm = torch.export.export_for_training(mobilenet_v2, sample_inputs).module()
# Step 3: Prepare the model for quantization
prepared_model = prepare_pt2e(training_gm, quantizer)
# Step 4: Calibrate the model on representative data
# Replace with your own calibration data
for calibration_sample in [torch.randn(1, 3, 224, 224)]:
prepared_model(calibration_sample)
# Step 5: Convert the calibrated model to a quantized model
quantized_model = convert_pt2e(prepared_model)
# Step 6: Export the quantized model to CoreML
et_program = to_edge_transform_and_lower(
torch.export.export(quantized_model, sample_inputs),
partitioner=[
CoreMLPartitioner(
# iOS17 is required for the quantized ops in this example
compile_specs=CoreMLBackend.generate_compile_specs(
minimum_deployment_target=ct.target.iOS17
)
)
],
).to_executorch()
有關更多資訊,請參閱 PyTorch 2 Export 訓練後量化。
執行時整合¶
要在裝置上執行模型,請使用標準的 ExecuTorch 執行時 API。有關更多資訊,包括構建 iOS 框架,請參閱在裝置上執行。
從原始碼構建時,在配置 CMake 構建時傳遞 -DEXECUTORCH_BUILD_COREML=ON 以編譯 CoreML 後端。
連結到 coremldelegate 目標。由於使用了靜態註冊,可能需要使用 whole-archive 進行連結。通常可以透過將 "$<LINK_LIBRARY:WHOLE_ARCHIVE,coremldelegate>" 傳遞給 target_link_libraries 來實現。
# CMakeLists.txt
add_subdirectory("executorch")
...
target_link_libraries(
my_target
PRIVATE executorch
extension_module_static
extension_tensor
optimized_native_cpu_ops_lib
coremldelegate)
除了連結目標之外,使用後端無需額外步驟。CoreML 委託的 .pte 檔案將在註冊的後端上自動執行。
高階話題¶
提取 mlpackage¶
可以從 CoreML 委託的 *.pte 檔案中提取 CoreML *.mlpackage 檔案。這對於熟悉 *.mlpackage 檔案的使用者進行除錯和效能分析很有幫助
python examples/apple/coreml/scripts/extract_coreml_models.py -m /path/to/model.pte
請注意,如果 ExecuTorch 模型包含圖中斷 (graph breaks),可能會提取出多個 *.mlpackage 檔案。