• 文件 >
  • 使用 XNNPACK 後端建置並執行 ExecuTorch
快捷鍵

使用 XNNPACK 後端建置並執行 ExecuTorch

以下教學將讓您熟悉如何利用 ExecuTorch XNNPACK Delegate,透過 CPU 硬體加速您的 ML 模型。它將涵蓋匯出模型並將其序列化為二進制檔案、鎖定 XNNPACK Delegate Backend,以及在支援的目標平台上執行模型。為了快速上手,請使用 ExecuTorch 儲存庫中的腳本,該腳本包含匯出和生成二進制檔案的說明,適用於一些範例模型,以演示整個流程。

您將在本教學中學到什麼

在本教學中,您將學習如何匯出 XNNPACK 降階 (lowered) 的模型,並在目標平台上執行它。

在開始之前,建議您先了解以下內容

將模型降階到 XNNPACK

import torch
import torchvision.models as models

from torch.export import export, ExportedProgram
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
from executorch.exir import EdgeProgramManager, ExecutorchProgramManager, to_edge_transform_and_lower
from executorch.exir.backend.backend_api import to_backend


mobilenet_v2 = models.mobilenetv2.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).eval()
sample_inputs = (torch.randn(1, 3, 224, 224), )

exported_program: ExportedProgram = export(mobilenet_v2, sample_inputs)
edge: EdgeProgramManager = to_edge_transform_and_lower(
    exported_program,
    partitioner=[XnnpackPartitioner()],
)

我們將使用從 TorchVision 函式庫下載的 MobileNetV2 預訓練模型來完成此範例。模型降階的流程在匯出模型 to_edge 之後開始。我們使用 XnnpackPartitioner 呼叫 to_backend API。Partitioner 會識別適合 XNNPACK backend delegate 使用的子圖。之後,識別出的子圖將使用 XNNPACK Delegate flatbuffer 模式序列化,並且每個子圖將被替換為對 XNNPACK Delegate 的呼叫。

>>> print(edge.exported_program().graph_module)
GraphModule(
  (lowered_module_0): LoweredBackendModule()
  (lowered_module_1): LoweredBackendModule()
)



def forward(self, b_features_0_1_num_batches_tracked, ..., x):
    lowered_module_0 = self.lowered_module_0
    lowered_module_1 = self.lowered_module_1
    executorch_call_delegate_1 = torch.ops.higher_order.executorch_call_delegate(lowered_module_1, x);  lowered_module_1 = x = None
    getitem_53 = executorch_call_delegate_1[0];  executorch_call_delegate_1 = None
    aten_view_copy_default = executorch_exir_dialects_edge__ops_aten_view_copy_default(getitem_53, [1, 1280]);  getitem_53 = None
    aten_clone_default = executorch_exir_dialects_edge__ops_aten_clone_default(aten_view_copy_default);  aten_view_copy_default = None
    executorch_call_delegate = torch.ops.higher_order.executorch_call_delegate(lowered_module_0, aten_clone_default);  lowered_module_0 = aten_clone_default = None
    getitem_52 = executorch_call_delegate[0];  executorch_call_delegate = None
    return (getitem_52,)

我們列印以上降階後的圖,以顯示為呼叫 XNNPACK Delegate 而插入的新節點。委派給 XNNPACK 的子圖是每個呼叫點的第一個參數。可以看出,大多數的 convolution-relu-add 區塊和 linear 區塊都能夠委派給 XNNPACK。我們還可以看見無法降階到 XNNPACK delegate 的運算子,例如 cloneview_copy

exec_prog = edge.to_executorch()

with open("xnnpack_mobilenetv2.pte", "wb") as file:
    exec_prog.write_to_file(file)

降階到 XNNPACK Program 之後,我們可以為 executorch 準備它,並將模型儲存為 .pte 檔案。.pte 是一種二進制格式,用於儲存序列化的 ExecuTorch 圖。

將量化模型降階到 XNNPACK

XNNPACK delegate 也可以執行對稱量化的模型。要了解量化流程並學習如何量化模型,請參閱 自訂量化 筆記。為了本教學,我們將利用方便地添加到 executorch/executorch/examples 資料夾中的 quantize() Python 輔助函數。

from torch.export import export_for_training
from executorch.exir import EdgeCompileConfig, to_edge_transform_and_lower

mobilenet_v2 = models.mobilenetv2.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).eval()
sample_inputs = (torch.randn(1, 3, 224, 224), )

mobilenet_v2 = export_for_training(mobilenet_v2, sample_inputs).module() # 2-stage export for quantization path

from torch.ao.quantization.quantize_pt2e import convert_pt2e, prepare_pt2e
from torch.ao.quantization.quantizer.xnnpack_quantizer import (
    get_symmetric_quantization_config,
    XNNPACKQuantizer,
)


def quantize(model, example_inputs):
    """This is the official recommended flow for quantization in pytorch 2.0 export"""
    print(f"Original model: {model}")
    quantizer = XNNPACKQuantizer()
    # if we set is_per_channel to True, we also need to add out_variant of quantize_per_channel/dequantize_per_channel
    operator_config = get_symmetric_quantization_config(is_per_channel=False)
    quantizer.set_global(operator_config)
    m = prepare_pt2e(model, quantizer)
    # calibration
    m(*example_inputs)
    m = convert_pt2e(m)
    print(f"Quantized model: {m}")
    # make sure we can export to flat buffer
    return m

quantized_mobilenetv2 = quantize(mobilenet_v2, sample_inputs)

量化需要兩個階段的匯出。首先,我們使用 export_for_training API 來擷取模型,然後將其提供給 quantize 實用程式函數。在執行量化步驟之後,我們現在可以利用 XNNPACK delegate 來降階量化的匯出模型圖。從這裡開始,該程序與將非量化模型降階到 XNNPACK 的程序相同。

# Continued from earlier...
edge = to_edge_transform_and_lower(
    export(quantized_mobilenetv2, sample_inputs),
    compile_config=EdgeCompileConfig(_check_ir_validity=False),
    partitioner=[XnnpackPartitioner()]
)

exec_prog = edge.to_executorch()

with open("qs8_xnnpack_mobilenetv2.pte", "wb") as file:
    exec_prog.write_to_file(file)

使用 aot_compiler.py 腳本降階

我們還提供了一個腳本,可以快速降階和匯出一些範例模型。您可以執行該腳本來生成降階的 fp32 和量化模型。此腳本僅用於方便,並執行與前兩節中列出的步驟相同的所有步驟。

python -m examples.xnnpack.aot_compiler --model_name="mv2" --quantize --delegate

請注意上面的範例中,

  • -—model_name 指定要使用的模型

  • -—quantize 標誌控制是否應該量化模型

  • -—delegate 標誌控制我們是否嘗試將圖的部分內容降階到 XNNPACK delegate。

生成的模型檔案將根據提供的參數命名為 [model_name]_xnnpack_[qs8/fp32].pte

使用 CMake 執行 XNNPACK 模型

匯出 XNNPACK Delegated 模型之後,我們現在可以使用 CMake 嘗試使用範例輸入執行它。我們可以構建並使用 xnn_executor_runner,它是 ExecuTorch Runtime 和 XNNPACK Backend 的範例包裝器。我們首先配置 CMake 建置,如下所示

# cd to the root of executorch repo
cd executorch

# Get a clean cmake-out directory
./install_requirements.sh --clean
mkdir cmake-out

# Configure cmake
cmake \
    -DCMAKE_INSTALL_PREFIX=cmake-out \
    -DCMAKE_BUILD_TYPE=Release \
    -DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
    -DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
    -DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
    -DEXECUTORCH_BUILD_XNNPACK=ON \
    -DEXECUTORCH_ENABLE_LOGGING=ON \
    -DPYTHON_EXECUTABLE=python \
    -Bcmake-out .

然後,您可以使用以下命令建置 runtime 組件

cmake --build cmake-out -j9 --target install --config Release

現在您應該能夠在 ./cmake-out/backends/xnnpack/xnn_executor_runner 找到建置的可執行檔,您可以使用您生成的模型執行該可執行檔,如下所示

./cmake-out/backends/xnnpack/xnn_executor_runner --model_path=./mv2_xnnpack_fp32.pte
# or to run the quantized variant
./cmake-out/backends/xnnpack/xnn_executor_runner --model_path=./mv2_xnnpack_q8.pte

使用 XNNPACK Backend 建置和連結

您可以建置 XNNPACK backend CMake 目標,並將其與您的應用程式二進制檔案連結,例如 Android 或 iOS 應用程式。有關此的更多資訊,您可以查看此 資源

文件

存取 PyTorch 的完整開發者文件

檢視文件

教學

取得初學者和高級開發人員的深入教學課程

檢視教學課程

資源

尋找開發資源並獲得問題解答

檢視資源