特色项目
要点速览
- ExecuTorch 扩展了 PyTorch 生态系统,旨在受限边缘设备上实现本地 AI 推理。为了提供切入点,Arm 创建了一套 Jupyter 实验课程,这些课程既是对官方 ExecuTorch 文档的补充,又详细解释了每一步操作的方法(how)和原理(why)。
- 本博客及其实验课程介绍了涵盖 Cortex-A 和 Cortex-M + Ethos-U 平台的 CPU 与 NPU 推理,并展示了如何使用 Arm 开发的 Model Explorer 适配器,从而深入了解模型在 ExecuTorch 中的部署情况。
AI 正在迅速且毋庸置疑地融入我们的工作和生活。然而,目前大部分智能处理仍依赖云端,通过 API 和 Web 接口进行访问。
这种模式并不总是适用。企业越来越希望将 AI 推向实际应用端——例如可穿戴设备、智能摄像头和其他低功耗边缘系统。在本地运行 AI 可以降低延迟、增强隐私并开启新的实时功能,但也带来了新的挑战:如何在内存、计算和功耗受限的硬件上高效运行复杂模型?
PyTorch 已成为云端 AI 模型训练和推理的首选框架。ExecuTorch 扩展了该生态系统,将本地 AI 推理引入边缘侧。它获取 PyTorch 模型,将其导出为轻量级格式,并通过专门为边缘推理构建的运行时环境运行。如果你已经熟悉 PyTorch,其优势显而易见:你可以在保持相同生态系统的同时,获得更适合实际设备的部署路径。
为了实现这一点,Arm 创建了一系列实践性 Jupyter 实验课程,引导开发者完成部署过程——从树莓派(Raspberry Pi)上的 CPU 推理到 Ethos-U NPU 上的硬件加速。无论你是已经熟悉 PyTorch 的机器学习开发人员,还是正在构建机器学习基础的嵌入式工程师,该系列实验都提供了一个实用的切入点,通过可执行示例对官方 ExecuTorch 文档进行补充,同时解释了每一步的方法和原理。
边缘 CPU 上的 ExecuTorch
你可能已经熟悉在树莓派 5 等边缘设备上运行 PyTorch。我们在课程 Optimizing Generative AI on Arm(在 Arm 上优化生成式 AI)中对此进行了探讨。虽然这行之有效,但树莓派属于单板计算机(SBC),其资源远多于许多生产级嵌入式或物联网系统。对于资源更受限的目标设备(如 Cortex-M 微控制器),由于 PyTorch 的体积和依赖项,无法在其上运行。
ExecuTorch 解决了这一问题,能够将 PyTorch 模型高效部署到边缘设备。这通过将模型导出为一个包含模型权重和静态计算图的最小化 .pte 文件来实现。这消除了运行时对 Python 的需求,并避免了推理过程中不必要的动态执行开销。
导出步骤之后是降低(lowering),即模型图被转换为后端兼容的形式。这也是硬件感知优化的开始。
最终生成的产物具有以下特点:
- 轻量且可移植
- 执行过程可预测
- 适合在受限系统上部署
除了 .pte 文件的可移植性外,还有其他优势。即使是在像树莓派这样无需 ExecuTorch 也能运行 PyTorch 模型的设备上,通过使用 ExecuTorch 也能获得性能提升。然而,性能在很大程度上取决于模型的执行方式。ExecuTorch 通过将模型的部分计算委托(delegating)给经过优化的后端来实现高性能。
在 Arm CPU 上,这通常通过 XNNPACK 后端完成。启用后,支持的算子(如卷积和矩阵乘法)将被委托给高度优化的实现。在 Arm 平台上,这些实现利用了 KleidiAI 微内核,从而有效利用了 Neon 等架构特性。在我们的实验室中,我们对比了 OPT-125M 转换模型在树莓派 5 上的推理表现。下图显示了使用带 XNNPACK 的 ExecuTorch 时,延迟有了显著降低。


图 1. 树莓派 5 CPU 上 PyTorch 与 ExecuTorch 推理时间的对比
注意:PyTorch Eager 模式和 ExecuTorch + XNNPACK 运行测试时都舍弃了前几次预热迭代,以避免出现初期运行缓慢、随后趋于稳定这一典型模式。
在使用 ExecuTorch 的情况下,观察到的趋势恰好相反:最初测量的几次运行速度较快,随后的运行延迟逐渐增加。这种行为归因于树莓派的热效应。使用 ExecuTorch + XNNPACK 进行持续、高度优化的推理会给 CPU 带来更大负载,导致温度升高,从而随时间推移导致时钟频率下降。在这些实验中没有使用主动散热。
需要注意的是,后端委托并不是自动发生的。在不使用 XNNPACK 的情况下运行 ExecuTorch,延迟往往比 PyTorch(其自身拥有 KleidiAI 优化)更高,尽管你仍然受益于更小的运行时占用空间和更好的可移植性。
关键结论是:ExecuTorch 提供了部署框架,但后端选择决定了硬件的使用效率。
从 CPU 到 NPU:Ethos-U 与 TOSA
要进一步提升性能,我们可以针对 Arm Ethos-U NPU 进行硬件加速,它们通常与 Cortex-A 或 Cortex-M CPU 配对使用。
此时,执行过程变得异构。ExecuTorch 不再在单个处理器上运行整个模型,而是对图进行分区:
- 受支持的子图被委托给 NPU
- 不支持的算子回退到 CPU 执行
Ethos-U 在量化整数模型(通常为 INT8)上运行,因此模型在委托前必须进行量化。第一步是使用 EthosUQuantizer 和与你特定目标 Ethos-U 相匹配的 compile_spec 创建专用于该后端的量化器。
例如,此处目标设备是具有 256 个乘加(MAC)单元的 Ethos-U85:
compile_spec = EthosUCompileSpec(
target="ethos-u85-256",
system_config="Ethos_U85_SYS_DRAM_Mid",
memory_mode="Shared_Sram",
extra_flags=["--output-format=raw"],
)
quantizer = EthosUQuantizer(compile_spec)
创建量化器后,即可按照常规流程执行 PyTorch 2 Export (PT2E) 量化流程。
下一步涉及将模型降低为 TOSA(张量算子集架构),这是一种旨在架起高级框架与硬件后端之间桥梁的中间表示(IR)。TOSA 提供了一套稳定的、与硬件无关的算子集。模型被降低为 TOSA,硬件后端实现这套规模较小且标准化的算子集,而无需每个硬件供应商都支持每个框架特有的算子。
此步骤使用 to_edge_transform_and_lower API,并指定使用 EthosUPartitioner。对于 Ethos-U,这将触发序列化为 TOSA 的后端路径,并运行 Vela 生成优化的指令流以在 NPU 上执行。最后,.to_executorch(...) 将结果封装进一个 .pte 文件。
理解此流程对于分析性能很有帮助。高效的委托通常会生成在 NPU 上运行的大型连续子图。如果存在不支持的算子,图可能会碎片化,导致产生多个较小的子图,并因 CPU 和 NPU 之间的频繁切换而增加开销。
为了让这一过程可视化,实验课程使用了 Google 的 Model Explorer 以及 Arm 开发的适配器。这些工具使你能够:
- 检查 ExecuTorch 图 (.pte) 并可视化其在不同后端间的分区情况
- 检查 TOSA 表示 (.tosa)
- 你还可以可视化用于 Arm Vulkan® ML SDK 的 VGF (.vgf) 文件(本实验课程未涵盖)
例如,下方是针对相同 Ethos-U 配置的两个 .pte 文件,但它们由略有不同的模型生成。
右图显示了一个额外插入了 LRN 层的 MobileNetV2 模型。由于 LRN 不被原生支持,它在降低过程中被分解为低级操作。并非所有这些操作都能被委托,因此图被分区为多个段。受支持的区域被委托给 NPU,而不支持的部分则在 CPU 上运行。相比之下,左侧的模型是标准的 MobileNetV2,仅包含受支持的算子,从而允许整个计算区域作为一个单一、连续的 Ethos-U 子图进行委托。


图 2. 使用 PTE 适配器的 Model Explorer,用于检查针对 Ethos-U 的两个不同模型的 .pte 文件(MobileNetV2,以及带有 LRN 层的 MobileNetV2)
这种可视化的深度有助于解释性能表现,并可指导优化决策。
后续实践步骤
为了熟悉这些主题,我们发布了一系列 Jupyter 实验课程,旨在让你能在自己的硬件上运行和修改代码,从而将理论直接转化为实践。 点击此处查看。
该系列课程包含来自 Marcelo Rovai 教授(UNIFEI 大学,边缘 AI 基金会学术-产业合作伙伴成员)的贡献。
特别感谢 IIIT Bangalore 的学术评审人员,他们确保了材料经过严格验证,对开发者和学习者具有宝贵的参考价值。
如需更全面地了解 Arm 提供的边缘 AI 开发资源,请查看 此处。
构建模型只是成功的一半——让模型在边缘侧高效运行才是关键。ExecuTorch 使这成为可能,而这些实验课程将向你展示如何快速上手并理解底层概念。