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 文件。