快捷方式

ExecuTorch 概念

本页面概述了整个 ExecuTorch 文档中使用的关键概念和术语。旨在帮助读者理解 PyTorch Edge 和 ExecuTorch 中使用的术语和概念。

AOT(提前)

AOT 通常指的是在执行之前发生的程序准备。从高层次上看,ExecuTorch 工作流程分为 AOT 编译和运行时。AOT 步骤包括编译成中间表示 (IR),以及可选的转换和优化。

ATen

从根本上说,它是一个张量库,几乎所有其他 PyTorch 的 Python 和 C++ 接口都是基于它构建的。它提供了核心 Tensor 类,在其上定义了数百种操作。

ATen 方言

ATen 方言是将渴望模块导出到图形表示后的直接结果。它是 ExecuTorch 编译管道的入口点;在导出到 ATen 方言之后,后续传递可以降低到 核心 ATen 方言边缘方言

ATen 方言是具有附加属性的有效 EXIR。它包含函数式 ATen 运算符、高阶运算符(如控制流运算符)和注册的自定义运算符。

ATen 方言的目标是尽可能忠实地捕获用户的程序。

ATen 模式

ATen 模式使用来自 PyTorch 核心的 ATen 的 Tensor (at::Tensor) 和相关类型(如 ScalarType)实现。这与 ETensor 模式形成对比,ETensor 模式使用 ExecuTorch 的更小张量实现 (executorch::runtime::etensor::Tensor) 和相关类型(如 executorch::runtime::etensor::ScalarType)。

  • 依赖于完整 at::Tensor API 的 ATen 内核可以在此配置中使用。

  • ATen 内核倾向于进行动态内存分配,并且通常具有额外的灵活性(因此存在开销)来处理移动/嵌入式客户端不需要的情况。例如,CUDA 支持、稀疏张量支持和数据类型提升。

  • 注意:ATen 模式目前正在开发中。

自动微分安全的 ATen 方言

自动微分安全的 ATen 方言仅包括可微分 ATen 运算符,以及高阶运算符(控制流运算符)和注册的自定义运算符。

后端

特定硬件(如 GPU、NPU)或软件堆栈(如 XNNPACK),它使用图形或图形的一部分,并具有性能和效率优势。

后端方言

后端方言是将边缘方言导出到特定后端的直接结果。它是目标感知的,可能包含仅对目标后端有意义的运算符或子模块。这种方言允许引入不符合核心 ATen 运算符集中定义的模式,并且未在 ATen 或边缘方言中显示的目标特定运算符。

后端注册表

将后端名称映射到后端接口的表格。这允许在运行时通过名称调用后端。

后端特定运算符

这些运算符不是 ATen 方言或边缘方言的一部分。后端特定运算符仅由在边缘方言之后发生的传递引入(参见后端方言)。这些运算符特定于目标后端,通常执行速度更快。

Buck2

一个开源的大规模构建系统。用于构建 ExecuTorch。

CMake

一个开源的跨平台工具系列,旨在构建、测试和打包软件。用于构建 ExecuTorch。

代码生成

从高层次上看,代码生成执行两个任务;生成 内核注册 库,以及可选地运行 选择性构建

内核注册库将运算符名称(模型中引用)与相应的内核实现(来自内核库)连接起来。

选择性构建 API 从模型或其他来源收集运算符信息,并且仅包含它们所需的运算符。这可以减小二进制文件大小。

代码生成的输出是一组 C++ 绑定(各种 .h.cpp 文件),它们将内核库和 ExecuTorch 运行时粘合在一起。

核心 ATen 方言

核心 ATen 方言包含核心 ATen 算子以及高阶算子(控制流)和注册的自定义算子。

核心 ATen 算子 / 规范 ATen 算子集

PyTorch ATen 算子库的一个精选子集。核心 ATen 算子在使用核心 ATen 分解表导出时不会被分解。它们作为后端或编译器应该从上游期望的基线 ATen 算子的参考。

核心 ATen 分解表

分解算子意味着将其表示为其他算子的组合。在 AOT 过程中,使用默认的分解列表,将 ATen 算子分解为核心 ATen 算子。这被称为核心 ATen 分解表。

自定义算子

这些算子不是 ATen 库的一部分,但出现在 急切模式 中。注册的自定义算子注册到当前的 PyTorch 急切模式运行时,通常使用 TORCH_LIBRARY 调用。它们最有可能与特定目标模型或硬件平台相关联。例如,torchvision::roi_align 是 torchvision 广泛使用的自定义算子(不针对特定硬件)。

数据加载器

一个接口,使 ExecuTorch 运行时能够从文件或其他数据源读取数据,而无需直接依赖于操作系统概念,如文件或内存分配。

委托

在特定后端(例如 XNNPACK)上运行程序的一部分(或全部),而程序的其余部分(如果有)在基本的 ExecuTorch 运行时上运行。委托使我们能够利用专门的后端和硬件的性能和效率优势。

维度顺序

ExecuTorch 引入 Dim Order 来描述张量的内存格式,通过返回维度从最外层到最内层的排列来实现。

例如,对于内存格式为 [N, C, H, W] 的张量,或 连续 内存格式,[0, 1, 2, 3] 将是它的维度顺序。

此外,对于内存格式为 [N, H, W, C] 的张量,或 通道最后内存格式,我们返回 [0, 2, 3, 1] 作为它的维度顺序。

目前 ExecuTorch 仅支持 连续通道最后 内存格式的维度顺序表示。

DSP(数字信号处理器)

专用的微处理器芯片,其架构针对数字信号处理进行了优化。

数据类型

数据类型,张量中数据的类型(例如,浮点数、整数等)。

动态量化

一种量化方法,其中张量在推理期间动态量化。这与 静态量化 相反,在静态量化中,张量在推理之前被量化。

动态形状

指的是模型能够在推理期间接受不同形状的输入。例如,ATen 算子 unique_consecutive 和自定义算子 MaskRCNN 具有数据相关的输出形状。这类算子难以进行内存规划,因为即使对于相同的输入形状,每次调用也可能产生不同的输出形状。为了在 ExecuTorch 中支持动态形状,内核可以使用客户端提供的 MemoryAllocator 为张量数据分配内存。

急切模式

Python 执行环境,其中模型中的算子在遇到时立即执行。例如,Jupyter / Colab 笔记本在急切模式下运行。这与图模式相反,在图模式中,算子首先被合成到图中,然后编译和执行。

边缘方言

EXIR 的一种方言,具有以下属性

  • 所有算子都来自预定义的算子集,称为“边缘算子”,或者是由注册的自定义算子。

  • 图的输入和输出,以及每个节点的输入和输出,必须是张量。所有标量类型都转换为张量。

边缘方言引入了对边缘设备有用的专门化,但对一般的(服务器)导出并不一定有用。然而,边缘方言不包含特定硬件的专门化,除了原始 Python 程序中已经存在的那些。

边缘算子

一个具有数据类型专门化的 ATen 算子。

ExecuTorch

PyTorch Edge 平台中一个统一的 ML 软件栈,专为高效的设备上推理而设计。ExecuTorch 定义了一个工作流程,用于在边缘设备(如移动设备、可穿戴设备和嵌入式设备)上准备(导出和转换)和执行 PyTorch 程序。

ExecuTorch 方法

nn.Module Python 方法的可执行等价物。例如,forward() Python 方法将编译成 ExecuTorch Method

ExecuTorch 程序

一个 ExecuTorch Program 将字符串名称(如 forward)映射到特定的 ExecuTorch Method 条目。

executor_runner

一个围绕 ExecuTorch 运行时的示例包装器,其中包含所有算子和后端。

EXIR

来自 torch.export 的 **EX**port **I**ntermediate **R**epresentation(IR)。包含模型的计算图。所有 EXIR 图都是有效的 FX 图

ExportedProgram

torch.export 的输出,它将 PyTorch 模型(通常是 nn.Module)的计算图与模型使用的参数或权重捆绑在一起。

flatbuffer

内存高效、跨平台的序列化库。在 ExecuTorch 的背景下,急切模式 Pytorch 模型被导出到 flatbuffer,这是 ExecuTorch 运行时使用的格式。

框架税

各种加载和初始化任务(不是推理)的成本。例如:加载程序、初始化执行器、内核和后端委托调度,以及运行时内存利用率。

函数式 ATen 算子

没有副作用的 ATen 算子。

EXIR 图是一种以 DAG(有向无环图)形式表示的 PyTorch 程序。图中的每个节点代表一个特定的计算或操作,图的边由节点之间的引用组成。注意:所有 EXIR 图都是有效的 FX 图

图模式

在图模式中,算子首先被合成到图中,然后作为整体编译和执行。这与急切模式相反,在急切模式中,算子在遇到时执行。图模式通常提供更高的性能,因为它允许诸如算子融合之类的优化。

高阶算子

高阶算子(HOP)是一个算子,

  • 要么接受 Python 函数作为输入,要么返回 Python 函数作为输出,或者两者兼而有之。

  • 与所有 PyTorch 算子一样,高阶算子也具有可选的后端和功能实现。这使我们能够例如为高阶算子注册一个自动微分公式,或者定义高阶算子在 ProxyTensor 跟踪下的行为。

混合量化

一种量化技术,其中模型的不同部分根据计算复杂度和对精度损失的敏感性采用不同的技术进行量化。模型的某些部分可能不被量化,以保持精度。

中间表示(IR)

源语言和目标语言之间的程序表示。通常,它是由编译器或虚拟机内部使用的用于表示源代码的数据结构。

内核

算子的实现。一个算子可以针对不同的后端/输入/等有多种实现。

内核注册表 / 算子注册表

一个表格,其中包含内核名称及其实现之间的映射。这使 ExecuTorch 运行时能够在执行期间解析对内核的引用。

降低

将模型转换为在各种后端上运行的过程。它被称为“降低”,因为它正在将代码更接近硬件。在 ExecuTorch 中,降低是在后端委托的一部分中执行的。

内存规划

模型内存分配和管理的过程。在 ExecuTorch 中,内存规划步骤会在图保存到 flatbuffer 之前执行。此步骤会为每个张量分配一个内存 ID 和缓冲区中的偏移量,标记张量存储的开始位置。

节点

EXIR 图中的节点代表特定计算或操作,在 Python 中使用 torch.fx.Node 类表示。

运算符

张量上的函数。这是抽象概念;内核是实现。对于不同的后端/输入等,可以有不同的实现。

运算符融合

运算符融合是将多个运算符组合成单个复合运算符的过程,由于内核启动次数更少,内存读写次数更少,因此可以实现更快的计算。这是图模式相对于急切模式的性能优势。

输出变体

运算符的输出变体不会在内核实现中分配返回的张量,而是会接收一个预分配的张量到其 out 关键字参数,并将结果存储在那里。

这使得内存规划器更容易执行张量生命周期分析。在 ExecuTorch 中,输出变体步骤会在内存规划之前执行。

PAL(平台抽象层)

提供了一种方法,使执行环境能够覆盖以下操作;

  • 获取当前时间。

  • 打印日志语句。

  • 使进程/系统出现故障。如果默认 PAL 实现不适用于特定客户端系统,则可以将其覆盖。

部分内核

支持部分张量数据类型和/或维度顺序的内核。

分区器

模型的某些部分可能会被委托到优化的后端运行。分区器将图分割成适当的子网络,并为它们标记以进行委托。

ETensor 模式

ETensor 模式使用 ExecuTorch 的更小的张量实现 (executorch::runtime::etensor::Tensor) 以及相关类型 (executorch::runtime::etensor::ScalarType 等)。这与 ATen 模式形成对比,ATen 模式使用 ATen 的 Tensor 实现 (at::Tensor) 和相关类型 (ScalarType 等)。

  • executorch::runtime::etensor::Tensor,也称为 ETensor,是 at::Tensor 的源兼容子集。针对 ETensor 编写的代码可以针对 at::Tensor 构建。

  • ETensor 不会自行拥有或分配内存。为了支持动态形状,内核可以使用客户端提供的 MemoryAllocator 分配 Tensor 数据。

可移植内核

可移植内核是为与 ETensor 兼容而编写的运算符实现。由于 ETensor 与 at::Tensor 兼容,因此可移植内核可以针对 at::Tensor 构建,并与 ATen 内核在同一模型中使用。可移植内核是

  • 与 ATen 运算符签名兼容

  • 用可移植 C++ 编写,因此可以为任何目标构建

  • 作为参考实现编写,优先考虑清晰度和简单性,而不是优化

  • 通常比 ATen 内核尺寸更小

  • 编写为避免使用 new/malloc 动态分配内存。

程序

用于描述 ML 模型的一组代码和数据。

程序源代码

用于描述程序的 Python 源代码。它可以是 Python 函数,也可以是 PyTorch 急切模式下的方法 nn.Module

PTQ(训练后量化)

一种量化技术,在模型训练完成后对其进行量化(通常是为了提高性能)。PTQ 在训练后应用量化流程,与在训练期间应用量化的 QAT 形成对比。

QAT(量化感知训练)

模型在量化后可能会损失精度。与 PTQ 等方法相比,QAT 能够在训练期间模拟量化的影响,从而实现更高的精度。在训练期间,所有权重和激活都被“伪量化”;浮点值被舍入以模拟 int8 值,但所有计算仍然使用浮点数完成。因此,训练期间的所有权重调整都“意识到”模型最终将被量化。QAT 在训练期间应用量化流程,与在之后应用量化的 PTQ 形成对比。

量化

用于对精度较低的张量数据执行计算和内存访问的技术,通常为 int8。量化通过降低内存使用量(通常)并减少计算延迟来提高模型性能;根据硬件的不同,以较低精度执行的计算通常会更快,例如 int8 矩阵乘法与 fp32 矩阵乘法。通常,量化会以牺牲模型精度为代价。

运行时

ExecuTorch 运行时在边缘设备上执行模型。它负责程序初始化、程序执行以及可选的销毁(释放后端拥有的资源)。

开发工具

用户需要的一组工具,用于分析、调试和可视化使用 ExecuTorch 运行的程序。

选择性构建

用于通过仅链接程序使用的内核来构建更精简运行时的 API。这提供了显著的二进制大小节省。

静态量化

一种量化方法,其中张量被静态量化。也就是说,浮点数在推理之前被转换为精度较低的数据类型。

XNNPACK

针对 ARM、x86、WebAssembly 和 RISC-V 平台的优化神经网络接口运算符库。这是一个开源项目,被 PyTorch 和 ExecuTorch 使用。它是 QNNPack 库的继任者。运算符支持浮点值和量化值。

文档

访问 PyTorch 的综合开发人员文档

查看文档

教程

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

查看教程

资源

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

查看资源