ExecuTorch Vulkan 委托¶
ExecuTorch Vulkan 委托是 ExecuTorch 的原生 GPU 委托,即 构建在跨平台 Vulkan GPU API 标准之上。它主要是 旨在利用 GPU 加速 Android 设备上的模型推理, 但可以在支持 Vulkan 实现的任何平台上使用: 笔记本电脑、服务器和边缘设备。
注意
Vulkan 委托及其组件目前正在积极开发中 可能会发生变化。
什么是 Vulkan?¶
Vulkan 是作为 OpenGL 的后继者开发的低级 GPU API 规范。 与 以前的规范,以减少开销并最大化 功能。
Vulkan 已被 GPU 供应商和大多数现代 GPU( desktop 和 mobile)在市场上支持 Vulkan。Vulkan 也包含在 Android 7.0 及更高版本。
请注意,Vulkan 是 GPU API,而不是 GPU 数学库。也就是说 提供了一种在 GPU 上执行计算和图形操作的方法,但不提供 附带一个内置的高性能计算内核库。
Vulkan 计算库¶
ExecuTorch Vulkan Delegate 是独立运行时的包装器,称为 Vulkan 计算库。Vulkan 计算库的目标是 通过 GLSL 计算着色器为 PyTorch 运算符提供 GPU 实现。
Vulkan 计算库是 PyTorch Vulkan 后端的分叉/迭代。 PyTorch Vulkan 后端的核心组件被分叉到 ExecuTorch 中 并适用于模型推理的 AOT 图形模式风格(而不是 PyTorch 采用模型推理的急切执行风格)。
Vulkan Compute Library 的组件包含在目录中。列出了核心组件
并描述如下:executorch/backends/vulkan/runtime/
runtime/
├── api/ .................... Wrapper API around Vulkan to manage Vulkan objects
└── graph/ .................. ComputeGraph class which implements graph mode inference
└── ops/ ................ Base directory for operator implementations
├── glsl/ ........... GLSL compute shaders
│ ├── *.glsl
│ └── conv2d.glsl
└── impl/ ........... C++ code to dispatch GPU compute shaders
├── *.cpp
└── Conv2d.cpp
特征¶
Vulkan 委托目前支持以下功能:
内存规划
生命周期不重叠的中间张量将共享内存分配。这减少了模型推理的峰值内存使用量。
基于功能的分区:
可以通过分区器将图形部分降低到 Vulkan 委托,分区器将识别 Vulkan 委托支持的节点(即运算符),并仅降低支持的子图
支持上限动态形状:
只要张量的当前形状小于降低期间指定的边界,就可以在推理之间更改形状
除了增加操作员覆盖范围外,以下功能还包括 目前正在开发中:
量化支持
我们目前正在努力支持 8 位动态量化,并计划在未来扩展到其他量化方案。
内存布局管理
内存布局是优化性能的重要因素。我们计划引入图形传递,以在整个图形中引入内存布局转换,以优化对内存布局敏感的运算符,例如 Convolution 和 Matrix Multiplication。
选择性构建
我们计划通过选择要构建的运算符/着色器来控制构建大小
端到端示例¶
要进一步了解 Vulkan Delegate 的功能及其使用方法, 请考虑以下使用 MobileNet V2 的端到端示例。
编译模型并将其降低到 Vulkan Delegate¶
假设 ExecuTorch 已经设置和安装,以下脚本可以是
用于将 MobileNet V2 模型降低为 。vulkan_mobilenetv2.pte
import torch
import torchvision.models as models
from torch.export import export, ExportedProgram
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import EdgeProgramManager, ExecutorchProgramManager, to_edge
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(exported_program)
# Lower the model to Vulkan backend
edge = edge.to_backend(VulkanPartitioner())
exec_prog = edge.to_executorch()
with open("vulkan_mobilenetv2.pte", "wb") as file:
exec_prog.write_to_file(file)
与其他 ExecuTorch 委托一样,模型可以降低到 Vulkan 委托
使用 API。Vulkan Delegate 实现标识图中节点(即运算符)的类
,并分隔
要在 GPU 上执行的模型。to_backend()
VulkanPartitioner
这意味着 a 模型可以降低到 Vulkan 委托,即使它包含 一些不支持的运算符。这只是意味着只有图形的一部分 将在 GPU 上执行。
注意
可以检查 Vulkan 分区程序代码,以检查当前在 Vulkan 中实现了哪些运算 委托。
构建 Vulkan Delegate 库¶
构建和测试 Vulkan Delegate 的最简单方法是针对 Android 进行构建 并在本地 Android 设备上进行测试。Android 设备内置了对 Vulkan 和 Android NDK 附带一个 GLSL 编译器,需要该编译器才能 编译 Vulkan 计算库的 GLSL 计算着色器。
使用 CMake 进行构建时,可以通过设置来构建 Vulkan Delegate 库。-DEXECUTORCH_BUILD_VULKAN=ON
首先,确保您已安装 Android NDK - Android NDK r25c 是
推荐。还应安装 Android SDK,以便您具有访问权限
自。adb
# Recommended version is Android NDK r25c.
export ANDROID_NDK=<path_to_ndk>
# Select an appropriate Android ABI
export ANDROID_ABI=arm64-v8a
# All subsequent commands should be performed from ExecuTorch repo root
cd <path_to_executorch_root>
# Make sure adb works
adb --version
使用 Vulkan 构建和安装 ExecuTorch 库(适用于 Android) 委托:
# From executorch root directory
(rm -rf cmake-android-out && \
pp cmake . -DCMAKE_INSTALL_PREFIX=cmake-android-out \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$ANDROID_ABI \
-DEXECUTORCH_BUILD_VULKAN=ON \
-DPYTHON_EXECUTABLE=python \
-Bcmake-android-out && \
cmake --build cmake-android-out -j16 --target install)
在设备上运行 Vulkan 模型¶
注意
由于目前对运算符的支持有限,因此只有二进制算术运算符 将在 GPU 上运行。预计推理会很慢,因为大多数运算符 正在通过 Portable 运算符执行。
现在,部分委托模型可以在您设备的 GPU!
# Build a model runner binary linked with the Vulkan delegate libs
cmake --build cmake-android-out --target vulkan_executor_runner -j32
# Push model to device
adb push vulkan_mobilenetv2.pte /data/local/tmp/vulkan_mobilenetv2.pte
# Push binary to device
adb push cmake-android-out/backends/vulkan/vulkan_executor_runner /data/local/tmp/runner_bin
# Run the model
adb shell /data/local/tmp/runner_bin --model_path /data/local/tmp/vulkan_mobilenetv2.pte