ExecuTorch 概念¶
本页概述了 ExecuTorch 文档中使用的关键概念和术语。旨在帮助读者理解 PyTorch Edge 和 ExecuTorch 中使用的术语和概念。
AOT (Ahead of Time)¶
AOT 通常指执行前发生的程序准备。在高层面上,ExecuTorch 工作流程分为 AOT 编译和运行时。AOT 步骤涉及编译成中间表示 (IR),以及可选的转换和优化。
ATen 方言¶
ATen 方言是将 Eager 模式模块导出到图表示的直接结果。它是 ExecuTorch 编译管道的入口点;导出到 ATen 方言后,后续 Pass 可以降级到 核心 ATen 方言 和 Edge 方言。
ATen 方言是一个有效的 EXIR,具有额外的属性。它由功能性 ATen 运算符、高阶运算符(如控制流运算符)和注册的自定义运算符组成。
ATen 方言的目标是尽可能忠实地捕获用户的程序。
ATen 模式¶
ATen 模式使用来自 PyTorch 核心的 Tensor (at::Tensor
) 和相关类型(如 ScalarType
)的 ATen 实现。这与 ETensor 模式形成对比,后者使用 ExecuTorch 较小的张量实现 (executorch::runtime::etensor::Tensor
) 和相关类型(如 executorch::runtime::etensor::ScalarType
)。
依赖于完整
at::Tensor
API 的 ATen 内核可以在此配置中使用。ATen 内核倾向于进行动态内存分配,并且通常具有额外的灵活性(以及因此产生的开销)来处理移动/嵌入式客户端不需要的情况。例如,CUDA 支持、稀疏张量支持和 dtype 提升。
注意:ATen 模式目前正在开发中 (WIP)。
Autograd 安全 ATen 方言¶
Autograd 安全 ATen 方言仅包含可微分的 ATen 运算符,以及高阶运算符(控制流操作)和注册的自定义运算符。
后端¶
特定的硬件(如 GPU、NPU)或软件堆栈(如 XNNPACK),它使用图或图的一部分,具有性能和效率优势。
后端方言¶
后端方言是将 Edge 方言导出到特定后端的直接结果。它是目标感知的,可能包含仅对目标后端有意义的运算符或子模块。此方言允许引入不符合核心 ATen 运算符集中定义的模式且未在 ATen 或 Edge 方言中显示的目标特定运算符。
后端注册表¶
一个将后端名称映射到后端接口的表。这允许在运行时通过名称调用后端。
后端特定运算符¶
这些是不属于 ATen 方言或 Edge 方言的运算符。后端特定运算符仅由在 Edge 方言之后发生的 Pass 引入(请参阅后端方言)。这些运算符特定于目标后端,通常执行速度更快。
代码生成 (Codegen)¶
在高层面上,代码生成执行两项任务:生成 内核注册 库,以及可选地运行 选择性构建。
内核注册库将运算符名称(在模型中引用)与相应的内核实现(来自内核库)连接起来。
选择性构建 API 从模型和/或其他来源收集运算符信息,并且仅包含它们所需的运算符。这可以减小二进制文件大小。
代码生成的输出是一组 C++ 绑定(各种 .h
、.cpp
文件),它们将内核库和 ExecuTorch 运行时粘合在一起。
核心 ATen 方言¶
核心 ATen 方言包含核心 ATen 运算符以及高阶运算符(控制流)和注册的自定义运算符。
核心 ATen 运算符 / 规范 ATen 运算符集¶
PyTorch ATen 运算符库的一个精选子集。使用核心 ATen 分解表导出时,核心 ATen 运算符不会被分解。它们充当后端或编译器应从上游获得的基线 ATen 操作的参考。
核心 ATen 分解表¶
分解运算符意味着将其表示为其他运算符的组合。在 AOT 过程中,会采用默认的分解列表,将 ATen 运算符分解为核心 ATen 运算符。这称为核心 ATen 分解表。
自定义运算符¶
这些是不属于 ATen 库的运算符,但出现在 Eager 模式 中。注册的自定义运算符被注册到当前的 PyTorch Eager 模式运行时中,通常使用 TORCH_LIBRARY
调用。它们很可能与特定的目标模型或硬件平台相关联。例如,torchvision::roi_align 是 torchvision 广泛使用的自定义运算符(不针对特定硬件)。
DataLoader¶
一种接口,使 ExecuTorch 运行时能够从文件或其他数据源读取数据,而无需直接依赖于操作系统概念,如文件或内存分配。
维度顺序 (Dim Order)¶
ExecuTorch 引入 Dim Order
来通过返回维度排列(从最外层到最内层)来描述张量的内存格式。
例如,对于内存格式为 [N, C, H, W] 或 连续 内存格式的张量,[0, 1, 2, 3] 将是其维度顺序。
此外,对于内存格式为 [N, H, W, C] 或 channels_last 内存格式 的张量,我们返回 [0, 2, 3, 1] 作为其维度顺序。
目前,ExecuTorch 仅支持 连续 和 channels_last 内存格式的维度顺序表示。
DSP (数字信号处理器)¶
架构针对数字信号处理优化的专用微处理器芯片。
dtype¶
数据类型,张量中数据的类型(例如浮点型、整型等)。
动态形状¶
指模型在推理期间接受具有不同形状的输入的能力。例如,ATen 操作 unique_consecutive 和自定义操作 MaskRCNN 具有数据相关的输出形状。此类运算符难以进行内存规划,因为即使对于相同的输入形状,每次调用也可能产生不同的输出形状。为了在 ExecuTorch 中支持动态形状,内核可以使用客户端提供的 MemoryAllocator
分配张量数据。
Eager 模式¶
Python 执行环境,其中模型中的运算符在遇到时立即执行。例如,Jupyter / Colab 笔记本在 Eager 模式下运行。这与图模式形成对比,在图模式下,运算符首先被合成为图,然后编译和执行。
Edge 方言¶
EXIR 的一种方言,具有以下属性
所有运算符都来自预定义的运算符集,称为 “Edge 运算符” 或注册的自定义运算符。
图以及每个节点的输入和输出都必须是张量。所有标量类型都转换为张量。
Edge 方言引入了对 Edge 设备有用的特殊化,但不一定对通用(服务器)导出有用。但是,Edge 方言不包含除原始 Python 程序中已存在的特殊化之外的特定硬件的特殊化。
Edge 运算符¶
具有 dtype 特殊化的 ATen 运算符。
ExecuTorch¶
PyTorch Edge 平台内的一个统一的 ML 软件堆栈,专为高效的设备端推理而设计。ExecuTorch 定义了一个工作流程,用于准备(导出和转换)并在 Edge 设备(如手机、可穿戴设备和嵌入式设备)上执行 PyTorch 程序。
ExecuTorch 方法 (Method)¶
与 nn.Module
Python 方法等效的可执行文件。例如,forward()
Python 方法将编译为 ExecuTorch Method
。
ExecuTorch 程序 (Program)¶
ExecuTorch Program
将字符串名称(如 forward
)映射到特定的 ExecuTorch Method
条目。
executor_runner¶
ExecuTorch 运行时的示例包装器,包括所有运算符和后端。
EXIR¶
来自 torch.export
的 EXport Intermediate Representation (IR)(导出中间表示)。包含模型的计算图。所有 EXIR 图都是有效的 FX 图。
ExportedProgram
¶
torch.export
的输出,它将 PyTorch 模型(通常是 nn.Module
)的计算图与模型使用的参数或权重捆绑在一起。
flatbuffer¶
内存高效、跨平台的序列化库。在 ExecuTorch 的上下文中,Eager 模式 Pytorch 模型被导出到 flatbuffer,这是 ExecuTorch 运行时使用的格式。
框架开销 (Framework tax)¶
各种加载和初始化任务的成本(非推理)。例如;加载程序、初始化执行器、内核和后端委托调度以及运行时内存利用率。
功能性 ATen 运算符¶
没有任何副作用的 ATen 运算符。
图 (Graph)¶
EXIR 图是以 DAG(有向无环图)形式表示的 PyTorch 程序。图中的每个节点代表特定的计算或操作,图的边由节点之间的引用组成。注意:所有 EXIR 图都是有效的 FX 图。
图模式¶
在图模式下,运算符首先被合成为图,然后作为一个整体进行编译和执行。这与 Eager 模式形成对比,在 Eager 模式下,运算符在遇到时执行。图模式通常提供更高的性能,因为它允许运算符融合等优化。
高阶运算符 (Higher Order Operators)¶
高阶运算符 (HOP) 是指
接受 Python 函数作为输入、返回 Python 函数作为输出或两者兼有的运算符。
与所有 PyTorch 运算符一样,高阶运算符也具有针对后端和功能的可选实现。这使我们能够例如为高阶运算符注册 Autograd 公式,或定义高阶运算符在 ProxyTensor 跟踪下的行为。
混合量化 (Hybrid Quantization)¶
一种量化技术,其中模型的不同部分使用不同的技术进行量化,具体取决于计算复杂度和对精度损失的敏感度。模型的某些部分可能不会被量化以保持精度。
中间表示 (Intermediate Representation, IR)¶
程序在源语言和目标语言之间的表示。通常,它是编译器或虚拟机内部使用的数据结构,用于表示源代码。
内核 (Kernel)¶
运算符的实现。对于不同的后端/输入等,运算符可以有多个实现。
内核注册表 / 运算符注册表 (Kernel registry / Operator registry)¶
一个包含内核名称及其实现之间映射的表。这允许 ExecuTorch 运行时在执行期间解析对内核的引用。
低阶化 (Lowering)¶
将模型转换为在各种后端上运行的过程。之所以称为 “低阶化”,是因为它使代码更接近硬件。在 ExecuTorch 中,低阶化作为后端委托的一部分执行。
内存规划 (Memory planning)¶
为模型分配和管理内存的过程。在 ExecuTorch 中,内存规划 Pass 在图保存到 flatbuffer 之前运行。这为每个张量分配一个内存 ID 和缓冲区中的偏移量,标记张量的存储起始位置。
节点 (Node)¶
EXIR 图中的节点表示特定的计算或操作,并在 Python 中使用 torch.fx.Node 类表示。
运算符 (Operator)¶
张量上的函数。这是抽象概念;内核是实现。对于不同的后端/输入等,可以有不同的实现。
运算符融合 (Operator fusion)¶
运算符融合是将多个运算符组合成单个复合运算符的过程,由于内核启动次数减少且内存读/写次数减少,因此可以加快计算速度。这是图模式相对于 Eager 模式的性能优势。
Out 变体 (Out variant)¶
运算符的 out 变体不是在内核实现中分配返回的张量,而是接收预先分配的张量到其 out kwarg 中,并将结果存储在那里。
这使得内存规划器更容易执行张量生命周期分析。在 ExecuTorch 中,out 变体 Pass 在内存规划之前执行。
部分内核 (Partial kernels)¶
支持张量 dtype 和/或维度顺序子集的内核。
Partitioner (分区器)¶
模型的部分可能被委托在优化的后端上运行。分区器将图拆分为适当的子网络,并标记它们以进行委托。
ETensor 模式¶
ETensor 模式使用 ExecuTorch 较小的张量实现 (executorch::runtime::etensor::Tensor
) 以及相关类型(executorch::runtime::etensor::ScalarType
等)。这与 ATen 模式形成对比,后者使用 Tensor (at::Tensor
) 和相关类型(ScalarType
等)的 ATen 实现。
executorch::runtime::etensor::Tensor
,也称为 ETensor,是at::Tensor
的源代码兼容子集。针对 ETensor 编写的代码可以针对at::Tensor
构建。ETensor 本身不拥有或分配内存。为了支持动态形状,内核可以使用客户端提供的 MemoryAllocator 分配张量数据。
可移植内核 (Portable kernels)¶
可移植内核是编写为与 ETensor 兼容的运算符实现。由于 ETensor 与 at::Tensor
兼容,因此可移植内核可以针对 at::Tensor
构建,并与 ATen 内核在同一模型中使用。可移植内核是
与 ATen 运算符签名兼容
用可移植 C++ 编写,因此它们可以为任何目标构建
作为参考实现编写,优先考虑清晰性和简洁性而不是优化
通常比 ATen 内核尺寸更小
编写时避免使用 new/malloc 动态分配内存。
程序 (Program)¶
描述 ML 模型的代码和数据集。
程序源代码 (Program source code)¶
描述程序的 Python 源代码。它可以是 Python 函数,也可以是 PyTorch Eager 模式 nn.Module
中的方法。
PTQ (Post Training Quantization,训练后量化)¶
一种量化技术,其中模型在训练后进行量化(通常是为了提高性能)。PTQ 在训练后应用量化流程,而 QAT 在训练期间应用量化流程。
QAT (Quantization Aware Training,量化感知训练)¶
模型量化后可能会损失精度。与例如 PTQ 相比,QAT 通过在训练时对量化效果进行建模,能够实现更高的精度。在训练期间,所有权重和激活都被“伪量化”;浮点值被舍入以模仿 int8 值,但所有计算仍然使用浮点数完成。因此,训练期间的所有权重调整都“意识到”模型最终将被量化。QAT 在训练期间应用量化流程,而 PTQ 则在训练后应用量化流程。
量化 (Quantization)¶
在具有较低精度数据(通常为 int8
)的张量上执行计算和内存访问的技术。量化通过降低内存使用量和(通常)减少计算延迟来提高模型性能;根据硬件的不同,以较低精度完成的计算通常会更快,例如 int8
矩阵乘法与 fp32
矩阵乘法相比。通常,量化会以模型精度为代价。
运行时 (Runtime)¶
ExecuTorch 运行时在边缘设备上执行模型。它负责程序初始化、程序执行以及可选的销毁(释放后端拥有的资源)。
开发者工具 (Developer Tools)¶
用户使用 ExecuTorch 运行时分析、调试和可视化程序所需的一系列工具。
选择性构建 (Selective build)¶
一个 API,用于通过仅链接到程序使用的内核来构建更精简的运行时。这可以显著节省二进制文件大小。
静态量化 (Static Quantization)¶
一种量化方法,其中张量被静态量化。也就是说,浮点数在推理之前被转换为降低精度的数据类型。