快捷方式

运行时集成

本节介绍配置和自定义 ExecuTorch 运行时的选项。虽然预构建的包旨在提供“开箱即用”的体验,但在生产环境中进行发货时,通常需要额外的配置。ExecuTorch 提供了编译时门控功能(例如日志记录)、自定义系统集成以及仅包含运行特定模型所需的算子(选择性构建)的能力。

日志记录

ExecuTorch 运行时代码包含各种级别的日志记录语句,以帮助集成和调试。日志记录的包含由构建时的 EXECUTORCH_ENABLE_LOGGINGEXECUTORCH_LOG_LEVEL CMake 选项控制。将这些作为编译时配置公开,允许在不使用时排除所有与日志相关的代码,这对于资源受限的系统至关重要。

在主机平台上,日志默认发送到 STDOUT 和 STDERR,在 Android 和 iOS 上会重定向到特定于操作系统的日志。有关日志路由的更多信息,请参阅下面的 平台抽象层

要配置从源文件构建时的日志级别,请将 EXECUTORCH_ENABLE_LOGGING 指定为开启或关闭,并将 EXECUTORCH_LOG_LEVEL 指定为 debug、info、error 或 fatal 之一。日志在调试构建中默认启用,在发布构建中默认禁用。日志级别默认为 info。

有关更多信息,请参阅 从源文件构建

cmake -b cmake-out -DEXECUTORCH_ENABLE_LOGGING=ON -DEXECUTORCH_LOG_LEVEL=DEBUG ...

平台抽象层 (PAL)

ExecuTorch 平台抽象层(简称 PAL)是一个粘合层,负责提供与特定宿主系统的集成。这包括日志路由、时间戳和中止处理。ExecuTorch 为符合 POSIX 标准的目标以及 Android 和 iOS 提供了默认实现,并包含在适当的扩展中。

对于不符合 POSIX 标准的系统,提供了一个最小的无操作 PAL 实现。用户需要覆盖相关的 PAL 方法才能启用日志记录、时间戳和中止。可以通过使用 -DEXECUTORCH_PAL_DEFAULT=minimal 进行构建来选择最小 PAL。

覆盖 PAL

通常会覆盖默认的 PAL 实现,以将日志路由到用户指定的目的地,或在嵌入式系统上提供 PAL 功能。PAL 可以使用运行时 API 或在链接时覆盖。除非您特别需要链接时覆盖,否则首选运行时 API。

运行时 PAL 注册

要注册自定义 PAL 实现,请执行以下步骤:

  • 在您的应用程序的某个 .c.cpp 文件中包含 executorch/runtime/platform/platform.h

  • 创建 PalImpl 结构体的一个实例。

    • 将一个或多个字段设置为自定义 PAL 函数实现。将字段留空以使用默认平台实现。

    • PalImpl 结构体为此目的提供了一个 create 方法。

  • 调用 executorch::platform::register_pal(pal_impl) 来注册实现。

    • 这可以从全局构造函数完成,如下面的示例所示。

以下是来自 pybindings.cpp 的一个完整示例,其中日志被重定向到 Python notebook 环境中正确显示。

namespace {
  void emit_log_message(
      et_timestamp_t timestamp,
      et_pal_log_level_t level,
      const char* filename,
      ET_UNUSED const char* function,
      size_t line,
      const char* message,
      ET_UNUSED size_t length) {
    std::cerr << "[" << filename << ":" << line << "] " << message << std::endl;
  }

  runtime::PalImpl build_pal() {
    return runtime::PalImpl::create(emit_log_message, __FILE__);
  }

  // Update PAL to redirect logs.
  ET_UNUSED bool registration_result = runtime::register_pal(build_pal());
}

弱符号覆盖

ExecuTorch 还提供了一种通过弱符号在链接时覆盖 PAL 的方法。此方法主要用于向后兼容。

要覆盖一个或多个 PAL 方法,请执行以下步骤:

默认的 PAL 函数是弱符号,因此提供自己的强符号定义可以在链接时覆盖它们。为确保您的定义优先,您可能需要确保强定义在链接顺序中先于弱定义。

有关 PAL 函数签名,请参阅 runtime/platform/platform.h,有关参考 POSIX 实现,请参阅 runtime/platform/default/posix.cpp

内核库

在导出过程中,模型被分解为一系列算子,每个算子提供一些基本计算。两个张量相加是一个算子,卷积也是。每个算子都需要一个相应的算子内核来在目标硬件上执行计算。ExecuTorch 后端是实现此目的的首选方式,但并非所有后端都支持所有算子。

为了处理这种情况,ExecuTorch 提供了两个实现——*可移植*和*优化*的内核库。可移植内核库以平台无关的方式提供对所有算子的完全支持。优化库带有额外的系统要求,但能够利用多线程和向量化代码来获得更高的性能。可以在单个构建中同时使用这两种内核库,从而在可用时使用优化库,并以可移植库作为回退。

使用移动设备预构建包时,内核库的选择对用户来说是透明的。但是,在从源文件构建时,尤其是在嵌入式系统上,这一点很重要。在移动设备上,优先使用可用的优化算子。有关更多信息,请参阅 ExecuTorch 内核库概述

选择性构建

默认情况下,ExecuTorch 附带所有支持的算子内核,使其能够以任何精度运行任何支持的模型。这会产生几兆字节的二进制文件大小,这对于生产用例或资源受限的系统可能不理想。为了最小化二进制文件大小,ExecuTorch 提供了选择性构建功能,以便仅包含运行特定模型所需的算子。

请注意,选择性构建仅适用于可移植和优化内核库。委托不参与选择性构建,可以通过单独链接来包含或排除它们。有关更多信息,请参阅 内核库选择性构建

文档

访问全面的 PyTorch 开发者文档

查看文档

教程

为初学者和高级开发者提供深入的教程

查看教程

资源

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

查看资源