快捷方式

本页介绍了可移植内核库和优化内核库,它们是 ExecuTorch 附带的默认内核库。建议那些有兴趣使用这些内核库执行 ExecuTorch 程序或想要实现自己的内核和内核库的人阅读。

ExecuTorch 内核库概述

ExecuTorch 程序编码了描述程序应执行的计算的指令。许多这些指令将对应于调用特定的 ATen 运算符,例如 aten.convolution。然而,ExecuTorch 的核心设计原则之一是运算符的签名应该与运算符的实现分离。这意味着 ExecuTorch 运行时不附带任何 ATen 运算符的标准实现;用户必须确保链接到包含其 ExecuTorch 程序所需的运算符实现的内核库,并配置 运算符注册 将运算符签名映射到所需的实现。这使得调整执行 ExecuTorch 程序时将调用的运算符(例如 aten.convolution)的实现变得容易;它允许用户选择完全满足其用例的独特性能、内存使用、电池使用等约束的运算符实现。

本质上,内核库只是一组遵循共同主题或设计原则的 ATen 运算符实现。请注意,由于 ExecuTorch 的选择性构建过程(在下一节中讨论),运算符实现是单独链接的。这意味着用户可以在构建中轻松混合不同的内核库,而不会牺牲构建大小。

ExecuTorch 默认附带两个内核库:可移植内核库优化内核库,两者都提供 CPU 运算符实现。

可移植内核库

可移植内核库在某种意义上是 ExecuTorch 使用的“参考”内核库。可移植内核库的开发考虑了以下目标

  • 正确性

    • 提供 ATen 运算符的直接实现,这些实现与 PyTorch 的 ATen 库中运算符的原始实现严格一致

  • 可读性/简单性

    • 提供清晰、可读的源代码,以便想要开发运算符自定义实现的人员可以轻松理解运算符的预期行为。

  • 可移植性

    • 可移植内核应该与 ExecuTorch 运行时一样可移植;运算符实现不应使用任何外部依赖项,也不应使用 C++ 的任何未经授权的功能。

  • 运算符覆盖率

    • 作为 ExecuTorch 的“参考”内核库,可移植内核库旨在提供高度的算子覆盖率。目标是为可移植内核库提供对所有列为 Core ATen 算子的算子的实现。但请注意,可移植内核库的算子覆盖率仍在开发中。

可移植内核库主要旨在提供易于访问的算子实现,这些实现将在大多数平台上“正常工作”,并保证提供正确的输出。性能不是可移植内核库的目标。事实上,许多瓶颈算子(如卷积和矩阵乘法)以最直接的方式实现,以优先考虑简单性和可读性。因此,如果只使用可移植内核库,不应该期望观察到快速的推理时间。但是,除了特定的瓶颈算子之外,大多数算子都足够简单,可移植内核库的直接实现仍然可以提供足够的性能。二进制大小也不是可移植内核库的目标。

优化内核库

优化内核库是与 ExecuTorch 一起提供的补充内核库,与可移植内核库相反,它旨在以牺牲可移植性和可读性为代价,提供面向性能的算子实现。优化内核库中的许多算子实现都受到 PyTorch 的 ATen 库中相应实现的启发或基于它,因此在许多情况下,可以预期相同的性能水平。

一般来说,优化内核库中的算子通过以下两种方式之一进行优化:

  1. 使用 CPU 向量内联指令

  2. 使用优化的数学库,例如 sleefOpenBLAS

虽然可移植性不是优化内核库的设计目标,但实现并不意味着要针对特定的 CPU 架构进行微调。相反,优化内核库旨在提供可以在各种平台上应用的高性能实现,而不是使用针对单个平台的优化。

另一个重要的注意事项是,算子覆盖率也不是优化内核库的目标。没有计划为每个 Core ATen 算子添加优化的内核;相反,优化的内核是根据需要添加的,以提高特定模型的性能。因此,优化内核库中的算子覆盖率将比可移植内核库有限得多。

文档

访问 PyTorch 的全面开发者文档

查看文档

教程

获取针对初学者和高级开发人员的深入教程

查看教程

资源

查找开发资源并获得问题的解答

查看资源