目录

使用 ExecuTorch SDK 对模型进行性能分析

作者: Jack Khuu

ExecuTorch SDK 是一组工具,旨在 为用户提供了对 ExecuTorch 进行性能分析、调试和可视化的能力 模型。

本教程将展示如何使用 SDK 的完整端到端流程。 具体来说,它将:

  1. 生成 SDK 使用的构件(ETRecordETDump)。

  2. 创建一个使用这些工件的 Inspector 类。

  3. 利用 Inspector 类来分析模型。

先决条件

要运行本教程,您需要安装 ExecuTorch。

设置 conda 环境。要在 Google Colab 中设置 conda 环境,请执行以下操作:

!pip install -q condacolab
import condacolab
condacolab.install()

!conda create --name executorch python=3.10
!conda install -c conda-forge flatbuffers

从源安装 ExecuTorch。如果 Google Colab 上的克隆失败,请将 确保 Colab -> 设置 -> Github -> Access Private Repo 已勾选:

!git clone --branch v0.1.0 https://{github_username}:{token}@github.com/pytorch/executorch.git
!cd executorch && bash ./install_requirements.sh

生成 ETRecord(可选)

第一步是生成一个 . 包含模型 用于将运行时结果(例如性能分析)链接到 热切的模型。这是通过 生成的。ETRecordETRecordexecutorch.sdk.generate_etrecord

executorch.sdk.generate_etrecord接收输出文件路径 (STR),则 edge dialect 模型 (),ExecuTorch dialect 模型 () 和其他模型的可选字典EdgeProgramManagerExecutorchProgramManager

在本教程中,使用 mobilenet v2 示例模型进行演示。

import copy

import torch

from executorch.examples.models.mobilenet_v2 import MV2Model
from executorch.exir import (
    EdgeCompileConfig,
    EdgeProgramManager,
    ExecutorchProgramManager,
    to_edge,
)
from executorch.sdk import generate_etrecord
from torch.export import export, ExportedProgram


# Generate MV2 Model
model: torch.nn.Module = MV2Model()

aten_model: ExportedProgram = export(
    model.get_eager_model().eval(),
    model.get_example_inputs(),
)

edge_program_manager: EdgeProgramManager = to_edge(
    aten_model, compile_config=EdgeCompileConfig(_check_ir_validity=True)
)
edge_program_manager_copy = copy.deepcopy(edge_program_manager)
et_program_manager: ExecutorchProgramManager = edge_program_manager.to_executorch()


# Generate ETRecord
etrecord_path = "etrecord.bin"
generate_etrecord(etrecord_path, edge_program_manager_copy, et_program_manager)
Downloading: "https://download.pytorch.org/models/mobilenet_v2-7ebf99e0.pth" to /var/lib/ci-user/.cache/torch/hub/checkpoints/mobilenet_v2-7ebf99e0.pth

  0%|          | 0.00/13.6M [00:00<?, ?B/s]
100%|██████████| 13.6M/13.6M [00:00<00:00, 198MB/s]
/opt/conda/envs/py_3.10/lib/python3.10/site-packages/torch/utils/_pytree.py:590: UserWarning: pytree_to_str is deprecated. Please use treespec_dumps
  warnings.warn("pytree_to_str is deprecated. Please use treespec_dumps")

警告

用户应该对 to_edge() 的输出进行深层复制,并传入 deepcopy 复制到 generate_etrecord API。这是必需的,因为 后续调用 to_executorch() 会执行就地更改,并将 在此过程中丢失调试数据。

生成 ETDump

下一步是生成一个 . 包含运行时结果 从执行模型。要生成,用户有两个选项:ETDumpETDump

选项 1:

使用 Buck:

python3 -m examples.sdk.scripts.export_bundled_program -m mv2
buck2 run -c executorch.event_tracer_enabled=true examples/sdk/sdk_example_runner:sdk_example_runner -- --bundled_program_path mv2_bundled.bp

选项 2:

使用 CMake:

cd executorch
python3 -m examples.sdk.scripts.export_bundled_program -m mv2
rm -rf cmake-out && mkdir cmake-out && cd cmake-out && cmake -DBUCK2=buck2 -DEXECUTORCH_BUILD_SDK=1 -DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=1 ..
cd ..
cmake --build cmake-out -j8 -t sdk_example_runner
./cmake-out/examples/sdk/sdk_example_runner --bundled_program_path mv2_bundled.bp

创建 Inspector

最后一步是通过传入工件路径来创建 。 Inspector 从中获取运行时结果并将其关联到 Edge Dialect Graph 的运算符。InspectorETDump

注意:An 不是必需的。如果未提供 an,则 Inspector 将显示运行时结果,而不显示运算符关联。ETRecordETRecord

要可视化所有运行时事件,请调用 Inspector 的 .print_data_tabular

from executorch.sdk import Inspector

etdump_path = "etdump.etdp"
inspector = Inspector(etdump_path=etdump_path, etrecord_path=etrecord_path)
inspector.print_data_tabular()
False

使用 Inspector 进行分析

Inspector提供 2 种访问摄取信息的方法:EventBlocks 和 .这些媒介使用户能够执行自定义 有关其模型性能的分析。DataFrames

以下是 和 方法的用法示例。EventBlockDataFrame

# Set Up
import pprint as pp

import pandas as pd

pd.set_option("display.max_colwidth", None)
pd.set_option("display.max_columns", None)

如果用户想要原始性能分析结果,他们将执行类似于 查找事件的原始运行时数据。addmm.out

for event_block in inspector.event_blocks:
    # Via EventBlocks
    for event in event_block.events:
        if event.name == "native_call_addmm.out":
            print(event.name, event.perf_data.raw)

    # Via Dataframe
    df = event_block.to_dataframe()
    df = df[df.event_name == "native_call_addmm.out"]
    print(df[["event_name", "raw"]])
    print()

如果用户想要将 Operator 追溯到他们的模型代码,他们会这样做 类似于查找 最慢的呼叫。convolution.out

for event_block in inspector.event_blocks:
    # Via EventBlocks
    slowest = None
    for event in event_block.events:
        if event.name == "native_call_convolution.out":
            if slowest is None or event.perf_data.p50 > slowest.perf_data.p50:
                slowest = event
    if slowest is not None:
        print(slowest.name)
        print()
        pp.pprint(slowest.stack_traces)
        print()
        pp.pprint(slowest.module_hierarchy)

    # Via Dataframe
    df = event_block.to_dataframe()
    df = df[df.event_name == "native_call_convolution.out"]
    if len(df) > 0:
        slowest = df.loc[df["p50"].idxmax()]
        print(slowest.event_name)
        print()
        pp.pprint(slowest.stack_traces)
        print()
        pp.pprint(slowest.module_hierarchy)

如果用户想要模块的总运行时间,他们可以使用 .find_total_for_module

print(inspector.find_total_for_module("L__self___features"))
print(inspector.find_total_for_module("L__self___features_14"))
0.0
0.0

注意:是 Inspector 的特殊一等方法find_total_for_module

结论

在本教程中,我们了解了使用 ExecuTorch 所需的步骤 模型。它还演示了如何使用 Inspector API 以分析模型运行结果。

文档

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

查看文档

教程

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

查看教程

资源

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

查看资源