PyTorch Blog

Bringing ExecuTorch to Arm Cortex-M CPUs

6.9内容质量
Bringing ExecuTorch to Arm Cortex-M CPUs

TL;DR · AI 摘要

Bringing ExecuTorch to Arm Cortex-M CPUs - PyTorch Featured projects TL;DR - Deploying PyTorch models on microcontroller...

核心要点

  • 主题聚焦:Bringing ExecuTorch to Arm Cortex-M CPUs
  • 来源:PyTorch Blog,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#后端#云计算#开源
打开原文

将 ExecuTorch 带入 Arm Cortex-M CPU - PyTorch

特色项目

TL;DR

  • 历史上在微控制器上部署 PyTorch 模型需要转换为其他框架格式、维护独立工具链并调试跨框架数值不匹配问题。ExecuTorch 完全消除了这一步骤。
  • Cortex-M 后端使 PyTorch 模型能够直接在 Arm Cortex-M CPU 上运行,并通过 Arm CMSIS-NN 加速。它支持所有能力层级(标量、DSP 和 MVE/Helium),且通过单一工作流程即可实现。
  • 我们在 Alif Ensemble E8 上对 MLPerf Tiny 套件中的五个模型中的四个进行了基准测试。每个模型在单个 Cortex-M55 核心上运行时间不超过 21.5 毫秒,且使用的内存低于 90 KiB。
  • 对于异构 SoC,Cortex-M 后端还提供了与 Ethos-U NPU 委派并行的 CPU 执行路径。
  • 极小的二进制体积。ExecuTorch 核心运行时占用的闪存低于 20 KiB,操作符选择性构建仅链接模型所需的运算符,因此代码总大小随模型规模变化而非框架规模。

背景

微控制器为数十亿个始终在线的设备提供动力:可穿戴设备、工业传感器、语音接口和智能家居电器。这些设备在极端限制条件下运行:通常静态随机存取存储器(SRAM)容量小于 1 MB、闪存容量为单数字兆字节,功耗预算以毫瓦为单位。尽管存在这些限制,但对在这些平台上运行有意义的机器学习(ML)工作负载的需求正在增长,硬件也在不断发展以满足这一需求。现代基于 Cortex-M 的微控制器单元(MCU)现在包括 DSP 和向量指令集架构(ISA)、大容量紧密耦合存储器(TCMs)以及高效能神经网络处理器(NPU)如 Arm Ethos-U NPU,这些特性使资源受限设备中的机器学习推理更加实用。

在此之前,在 Cortex-M 上部署机器学习意味着必须离开 PyTorch 生态系统。开发人员需要将模型转换为其他格式,为训练和部署维护独立的工具链,并调试转换过程中引入的数值不匹配问题。对于使用 PyTorch 进行训练的团队(占顶级机器学习会议发表的研究代码的 90% 以上),这种转换步骤会为每个迭代周期增加摩擦。

ExecuTorch 的设计旨在消除这一差距。通过 Ethos-U NPU 已经可以支持 Arm MCU,而 Cortex-M 后端将其扩展到 Cortex-M CPU,因此模型可以在有或没有加速器的设备上运行。训练后的 PyTorch 模型在导出时会进行量化和优化,且整个过程在与服务移动端、桌面端和服务器端模型相同的堆栈中完成。

Cortex-M 后端

ExecuTorch Cortex-M 后端通过提前编译器传递,将标准 PyTorch 运算符替换为基于 CMSIS-NN 的自定义运算符。在推理时,这些运算符直接调用 Arm 的 CMSIS-NN 库,这是一个针对 Cortex-M 处理器优化的神经网络内核开源集合。

关键特性:

  • CMSIS-NN 加速。量化运算(线性、卷积、加法、乘法、softmax、激活函数等)被替换为优化实现,这些实现直接调用 CMSIS-NN 函数和额外的 Cortex-M 优化实现。
  • 目标感知编译。CPU 变体(M0 到 M85)和 ISA 层级在编译时指定,因此会选择正确的 CMSIS-NN 后端,消除运行时调度开销。
  • 专用量化器。使用 PyTorch 的 PT2E 量化框架生成符合 CMSIS-NN 内核数据布局要求的 INT8 量化图。
  • 单一编译器工具链。Cortex-M 降低路径直接作用于 ExecuTorch 边缘方言,使编译流程保持简洁且易于调试。

Cortex-M 能力层级

后端支持完整的 Cortex-M 芯片系列:

| 层级 | 核心型号 | 关键特性 | 应用场景 | |------------|------------------|------------------------------|----------------------------| | Scalar | M0, M0+, M3, M23 | 标准 ARM 指令集 | 超低成本、极简硅芯片方案 | | DSP | M4, M7, M33, M35P | SIMD 累加乘法指令 | 中端 MCU、信号处理场景 | | MVE (Helium) | M55, M85 | 128 位向量运算、基于节拍的执行 | 高性能 MCU 机器学习推理 |

Arm Helium 技术带来了最大的性能提升。CMSIS-NN 利用 Helium 的基于节拍执行模型,将数据移动和计算流水线化,显著提升边缘 ML 架构中常见深度卷积和逐点卷积的吞吐量。尽管如此,相同的工作流适用于所有变体。目标配置会自动选择合适的后端。

ExecuTorch 的嵌入式友好特性

与需要在运行时适配多种硬件的移动端或云端环境不同,微控制器部署针对固定的硬件配置。嵌入式开发者对其部署目标具有精确的了解,包括具体的 CPU 核心、可用的 ISA 扩展、SRAM 分配和闪存容量。

ExecuTorch 的编译时栈正是为此设计。ExecuTorch 在编译时做出针对目标的决策:图级优化、内存规划、权重打包和内核选择都在编译时具备目标感知能力。

具体到 Cortex-M,这意味着:

  • 图级计算消除。在降低过程中移除冗余的数据类型转换、量化/反量化对以及内存格式转置,确保仅必要计算到达设备。
  • 量化参数折叠。在导出时预先计算缩放系数和零点算术,转换为整数乘法/移位形式,使量化内核推理全程保持定点运算。
  • AOT 权重布局转置。在导出时将卷积权重从 PyTorch 原生布局(OIHW)转置为 CMSIS-NN 期望格式(OHWI)。转置成本仅在编译时一次性支付,推理时无需重复操作。
  • 异构内存间的静态内存规划。所有张量和临时缓冲区在编译时预先分配并布局,支持跨多个内存区域(如 TCM 和 SRAM)分配。开发者还可自定义放置策略,将关键缓冲区置于快速本地内存。无需堆分配器、无需碎片管理、无需运行时内存管理。
  • 目标特定算子替换。CortexMPassManager 在编译时根据目标核心的 ISA 等级(Scalar/DSP/MVE)选择匹配的 CMSIS-NN 内核变体,而非运行时动态选择。

开发者工作流

code
import torch
from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_pt2e

from executorch.backends.cortex_m.edge_compile_config import cortex_m_edge_compile_config
from executorch.backends.cortex_m.passes.cortex_m_pass_manager import CortexMPassManager
from executorch.backends.cortex_m.quantizer.quantizer import CortexMQuantizer
from executorch.backends.cortex_m.target_config import CortexM, CortexMTargetConfig
from executorch.exir import to_edge_transform_and_lower

# 1. 导出模型
model = MyModel().eval()
example_inputs = (torch.randn(1, 1, 49, 10),)
exported = torch.export.export(model, example_inputs)

# 2. 量化与校准
quantizer = CortexMQuantizer(use_explicit_layout=True)
prepared = prepare_pt2e(exported.module(), quantizer)
for sample in calibration_data:
    prepared(sample)
quantized = convert_pt2e(prepared)

# 3. 重新导出量化后的模型
quantized_exported = torch.export.export(quantized, example_inputs)

# 4. 转换为Edge格式并应用Cortex-M优化
pass_manager = CortexMPassManager(
    target_config=CortexMTargetConfig(cpu=CortexM.M55),
    use_explicit_layout=True,
)
edge = to_edge_transform_and_lower(
    quantized_exported,
    compile_config=cortex_m_edge_compile_config(),
    transform_passes=pass_manager,
)

# 5. 序列化以集成到固件中
et_program = edge.to_executorch()
with open("model.pte", "wb") as f:
    f.write(et_program.buffer)

生成的.pte二进制文件会与ExecuTorch运行时和CMSIS-NN库一起链接到固件中,然后烧录到设备。运行时,推理会执行预编译的计算图,几乎不产生运行时开销,且不需要为张量进行动态内存分配。

与Ethos-U协同使用Cortex-M后端

许多Cortex-M微控制器会将CPU与Arm Ethos-U NPU(如U55、U65或U85)搭配使用。ExecuTorch的EthosUPartitioner通过Vela编译器将支持的操作委托给NPU,而未被划分的操作则在Cortex-M CPU上以相同计算图运行。

Cortex-M优化在Ethos-U划分之后执行,并复用计算图中已有的量化参数。这使得使用EthosUQuantizer量化后的模型可以利用CMSIS-NN执行满足Cortex-M后端量化、布局和形状约束的CPU操作。否则会回退到ExecuTorch的可移植内核,这些内核功能正常但未加速。

实际优势在于NPU算子覆盖范围不是非此即彼的限制条件。即使模型中只有少量未委托的操作,也可以今天就部署在混合CPU/NPU执行环境中,并随着覆盖范围的扩大逐步将更多计算图迁移到NPU。

MLPerf Tiny基准测试套件

/think

我们在 Alif Ensemble E8 上对 MLPerf Tiny Inference 基准测试中五个模型中的四个进行了推理延迟和内存使用测量。这些基准模型代表了 TinyML 工作负载中常见的一组深度神经网络。Alif E8 集成了多个 Cortex-M55 核心以及 Ethos-U55 和 U85 NPUs;我们测量的是单个 M55 高性能核心在 400 MHz 频率下运行的情况,Ethos-U NPUs 未使用。ExecuTorch 的提前内存规划使 RAM 使用具有确定性和可预测性,在持续负载下不存在碎片化风险。通过 ExecuTorch 的算子选择性构建,仅包含推理所需的算子,从而实现最小的闪存占用。所有模型均使用 CortexMQuantizer 进行 INT8 量化,Alif ML Embedded Evaluation Kit 作为测试框架。这些是我们的测量结果而非官方 MLPerf Tiny 提交,因此不能直接与 MLCommons 领域排行榜上的已发布结果进行比较。

所有四个模型都在 90 KiB 的 RAM 内运行,其中三个模型在 60 KiB 以内,异常检测自编码器仅使用 5.2 KiB。由于每个模型仅链接其使用的算子,代码占用保持在 15 至 37 KiB 之间。

| 模型 | 任务 | 延迟 (ms) | 每秒推理次数 | 峰值 RAM (KiB) | 闪存 (KiB) | |--------------|------------------|-----------|--------------|----------------|------------| | DS-CNN | 关键词识别 | 5.825 | 172 | 26.00 | 37.67 | | MobileNet v1 0.25 | 视觉唤醒词 | 21.450 | 47 | 85.15 | 253.07 | | ResNet-8 | 图像分类 | 15.290 | 65 | 55.14 | 89.77 | | Autoencoder | 异常检测 | 1.208 | 828 | 5.20 | 272.03 |

*代码使用 GCC 15.2.1 编译,包含 ExecuTorch 核心运行时(-Oz)和内核(-O3),禁用日志记录。

示例:实时人物检测

为了展示 Cortex-M 后端的实际能力,我们在由 Arm Cortex-M85 驱动的 Renesas EK-RA8D1 板上部署了 µYOLO 人物检测模型。该部署在 MCU 级内存限制内运行良好:

  • 任务:实时人物检测
  • 模型:µYOLO,使用深度可分离 CNN 主干和线性预测头的修剪模型
  • 模型大小:452 KiB(INT8 .pte 文件)
  • 总闪存:640 KiB
  • 峰值 RAM:254 KiB
  • 推理延迟:480 MHz 下每帧推理 24 ms
  • 端到端吞吐量:12.7 FPS
  • 输入:128×128 RGB 相机帧

这个在边缘设备上实现的资源受限且持续运行的视觉示例,支持机器人感知、占用监控、安全系统、智能摄像头和触发式设备等应用。

同样重要的是,该示例展示了 ExecuTorch 启用的开发工作流程。模型定义、训练代码、导出流程和嵌入式部署都位于同一个基于 PyTorch 的生态系统中。中间表示形式保持可执行性,使得可以在导出和优化过程中比较模型输出,而非将部署视为黑盒。生成的图也可以使用 Model Explorer 等工具进行检查,而 ETDump 则可以暴露每个算子的执行成本,用于目标设备上的性能分析。这些工具共同使开发者能够在持续验证模型行为不变的前提下,迭代优化模型架构、精度、内存使用和延迟。与传统导出模型后才发现数值或性能退化不同,开发者可以检查并执行转换流水线的中间阶段。

模型定义、训练和导出流程可在 ExecuTorch 仓库中找到。为便于在无需物理目标设备的情况下快速启动演示,内置应用针对 Corstone FVP 进行了优化。设备端演示的板级适配基于 ra-fsp-examples 仓库的代码,通过 RA Smart Configurator 进行配置,使用 Arm GNU Toolchain 编译,并通过 J-Link Flash 烧录。在上述性能测试中,最昂贵操作符的权重被放置在 DTCM 中,并启用了指令缓存。这使得推理延迟从 191 毫秒降低至 24 毫秒,性能提升了近 8 倍。

入门指南

Cortex-M 后端目前可在 ExecuTorch 仓库中使用:

| 资源 | 描述 | |------|------| | Cortex-M 后端文档 | 支持的操作符、目标配置和构建设置 | | Arm 后端示例 | 包含完整示例目录和设置脚本 | | CMSIS-ExecuTorch 项目模板 | Docker 构建 + Keil Studio + AVH 模拟 | | Zephyr RTOS 集成 | 在 Zephyr 上使用 CMSIS Toolbox 的 ExecuTorch | | Raspberry Pi Pico 2 示例 | Cortex-M33,MNIST 数字分类 |

平台支持

| 平台 | CPU | 可通过以下方式获取 | |------|-----|------------------| | Arm Corstone-300 FVP | Cortex-M55 + Ethos-U55 | 内置示例,已在 CI 中验证 | | Arm Corstone-320 FVP | Cortex-M85 + Ethos-U85 | Alif Ensemble E8 | | Alif ML 嵌入式评估套件 | Cortex-M55 (MVE) | Alif ML 嵌入式评估套件 | | Raspberry Pi Pico 2 | Cortex-M33 (DSP) | 内置示例 | | Renesas EK-RA8D1 | Cortex-M85 | 树外板级端口;内置演示在 Corstone FVP 上运行 |

后续计划

  • 扩展混合精度支持:将 A8W4 和 A16W8 混合精度支持扩展到完整操作符集。
  • 浮点内核:CMSIS-NN 8.0.0 引入了 fp32 和 fp16 MVE 内核。通过 Cortex-M 后端暴露这些内核,使非全量化模型可以使用相同的降级路径,无需单独的部署流程。
  • 更广泛的操作符覆盖:支持注意力操作符、层归一化和其他传统 CNN 以外的流行架构模式,以及 CMSIS-DSP 操作符(如 FFT),使特征提取可以作为图的一部分运行。
  • 更多端到端示例:语音活动检测、手势识别、预测性维护、流式唤醒词,以及需要多帧推理测试基础设施的第五个 MLPerf Tiny 基准测试。
  • 更多硬件验证:扩展已验证平台和开发套件的范围。

我们对这一进展为嵌入式机器学习社区带来的可能性感到兴奋。如果您正在边缘部署机器学习,无论是部署在 1 美元的传感器节点上,还是在运行语音命令的 Cortex-M55 上,ExecuTorch 现在提供了从 PyTorch 训练到设备端推理的直接路径。

了解更多:ExecuTorch 文档 | ExecuTorch 仓库 | Cortex-M 后端 | ExecuTorch Discord