目录

ExecuTorch 概念

本页面提供了贯穿ExecuTorch文档的关键概念和术语的概览。其目的是帮助读者理解PyTorch Edge和ExecuTorch中所使用的术语和概念。

AOT(提前编译)

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

ATen

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

ATen 语言

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

ATen dialect 是一个有效的 EXIR,并具有额外的属性。它由功能性的 ATen 操作符、高阶操作符(如控制流操作符)和注册的自定义操作符组成。

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

ATen 模式

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

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

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

  • 注意:ATen 模式目前仍处于开发中。

Autograd 安全的 ATen 语法

Autograd 安全的 ATen 方言仅包含可微分的 ATen 操作符,以及高阶操作符(控制流操作符)和已注册的自定义操作符。

后端

一种特定的硬件(如 GPU、NPU)或软件栈(如 XNNPACK),它消耗图或其一部分,以获得性能和效率的优势。

后端方言

后端方言是将 Edge 方言导出到特定后端的直接结果。它是目标感知的,可能包含仅对目标后端有意义的操作符或子模块。此方言允许引入特定于目标的操作符,这些操作符不符合 Core ATen 操作符集定义的模式,并且不会在 ATen 或 Edge 方言中显示。

后端注册表

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

后端特定操作符

这些操作符不属于 ATen 方言或 Edge 方言。后端特定的操作符仅由发生在 Edge 方言之后的 passes 引入(参见 Backend 方言)。这些操作符特定于目标后端,通常执行速度更快。

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库,但出现在 eager mode 中。注册的自定义操作符会注册到当前PyTorch eager mode运行时,通常通过一个 TORCH_LIBRARY 调用。它们很可能与特定的目标模型或硬件平台相关联。例如,torchvision::roi_align 是一个被torchvision广泛使用的自定义操作符(不针对特定硬件)。

DataLoader

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

委托

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

Dim Order

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

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

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

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

数字信号处理器 (DSP)

专为数字信号处理优化的专用微处理器芯片。

dtype

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

动态量化

一种在推理过程中动态量化张量的量化方法。与静态量化不同,静态量化是在推理之前对张量进行量化。

动态形状

指模型在推理过程中接受不同形状输入的能力。例如,ATen 操作 unique_consecutive 和自定义操作 MaskRCNN 具有数据依赖的输出形状。此类操作在进行内存规划时较为困难,因为即使对于相同的输入形状,每次调用可能会产生不同的输出形状。为了在 ExecuTorch 中支持动态形状,内核可以使用客户端提供的 MemoryAllocator 来分配张量数据。

急切模式

Python 执行环境,其中模型中的运算符在遇到时立即执行。例如,Jupyter / Colab 笔记本是在急切模式下运行的。这与图模式形成对比,在图模式中,运算符首先被综合成一个图,然后再进行编译和执行。

边缘方言

一种具有以下特性的 EXIR 方言:

  • 所有操作符都来自一个预定义的操作符集合,称为“Edge 操作符”,或者注册的自定义操作符。

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

Edge dialect 引入了一些对 Edge 设备有用的特殊化功能,但不一定适用于通用(服务器)导出。然而,Edge dialect 并不包含除原始 Python 程序中已有的特殊化功能之外的特定硬件特殊化功能。

边缘操作符

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

ExecuTorch

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

执行Torch方法

一个 nn.Module Python 方法的可执行等效形式。例如,forward() Python 方法将编译为 ExecuTorch Method

执行Torch程序

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

executor_runner

一个围绕 ExecuTorch 运行时的示例包装器,包含所有操作符和后端。

EXIR

torch.export 导出的 EX 中间 I 表示 R(IR)。包含模型的计算图。所有 EXIR 图都是有效的 FX 图

ExportedProgram

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

flatbuffer

内存高效、跨平台的序列化库。在 ExecuTorch 的上下文中,eager 模式 Pytorch 模型被导出为 flatbuffer,这是 ExecuTorch 运行时所使用的格式。

框架税

各种加载和初始化任务(不包括推理)的成本。例如:加载程序、初始化执行器、内核和后端代理调度,以及运行时内存使用情况。

功能ATen运算符

无副作用的 ATen 操作符。

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

图模式

在图模式下,操作符首先会被综合成一个图,然后作为整体进行编译和执行。这与立即执行模式形成对比,在立即执行模式中,操作符会在遇到时立即执行。图模式通常能提供更高的性能,因为它允许诸如操作符融合等优化。

高阶运算符

一个高阶操作符(HOP)是指:

  • 既可以接受一个 Python 函数作为输入,也可以返回一个 Python 函数作为输出,或者两者皆可。

  • 和所有 PyTorch 操作符一样,高阶操作符也有一个可选的后端和功能实现。这让我们例如可以为高阶操作符注册一个自动求导公式,或者定义高阶操作符在 ProxyTensor 跟踪下的行为。

混合量化

一种量化技术,根据计算复杂度和对精度损失的敏感程度,对模型的不同部分采用不同的量化方法。模型的一些部分可能不会被量化以保持精度。

中间表示(IR)

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

内核

一个操作符的实现。对于不同的后端/输入等,可以有多个操作符的实现。

内核注册表 / 操作符注册表

一个包含内核名称与其实现映射的表格。这允许 ExecuTorch 运行时在执行期间解析对内核的引用。

降低

将模型转换为在各种后端上运行的过程。由于它使代码更接近硬件,因此被称为“降低”(lowering)。在 ExecuTorch 中,降低是作为后端委托的一部分进行的。

内存规划

模型内存的分配和管理过程。在 ExecuTorch 中,在将图保存为 flatbuffer 之前会运行一个内存规划阶段。该阶段为每个张量分配一个内存 ID,并在缓冲区中指定一个偏移量,标记张量存储的起始位置。

节点

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

操作符

张量上的函数。这是抽象;内核是实现。不同的后端/输入等可能会有不同的实现方式。

算子融合

算子融合是将多个算子组合成一个复合算子的过程,从而减少内核启动次数和内存读写次数,实现更快的计算。这是图模式相比立即执行模式的性能优势。

我们的变体

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

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

PAL(平台抽象层)

提供一种执行环境覆盖操作的方法,例如;

  • 获取当前时间。

  • 打印一条日志语句。

  • 引发进程/系统恐慌。 如果默认的 PAL 实现对某个特定客户端系统不起作用,可以覆盖它。

部分核函数

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

分区器

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

ETensor 模式

ETensor模式使用ExecuTorch中张量(executorch::runtime::etensor::Tensor)的较小实现,以及相关类型(executorch::runtime::etensor::ScalarType等)。这与ATen模式形成对比,ATen模式使用ATen实现的张量(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 动态分配内存。

程序

描述一个机器学习模型的代码和数据集合。

程序源代码

描述程序的Python源代码。它可以是一个Python函数,或是在PyTorch的eager模式中的一个方法 nn.Module

PTQ (后训练量化)

一种量化技术,模型在训练完成后进行量化(通常是为了提升性能)。PTQ 在训练之后应用量化流程,与在训练过程中应用量化的 QAT 相对比。

QAT (量化感知训练)

量化后模型可能会损失精度。QAT(量化感知训练)相比例如PTQ(后训练量化),能够在训练过程中建模量化的影响,从而实现更高的精度。在训练期间,所有的权重和激活值都会被“假量化”;浮点数值会被四舍五入以模拟int8值,但所有的计算仍然使用浮点数进行。因此,在训练过程中所有的权重调整都会考虑到模型最终会被量化的事实。QAT在训练过程中应用量化流程,而PTQ则是在训练之后应用量化流程。

量化

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

运行时

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

开发人员工具

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

选择性构建

一种用于通过仅链接程序使用的内核来构建更轻量级运行时的API。这能带来显著的二进制文件大小节省。

静态量化

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

XNNPACK

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

文档

访问 PyTorch 的全面开发人员文档

查看文档

教程

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

查看教程

资源

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

查看资源