QAI AppBuilder快速上手(4):用户指南
摘要:Qualcomm® AI Runtime SDK为AI开发提供统一的API支持,支持在Snapdragon X Elite设备上运行模型。开发人员可通过高通软件中心或QPM下载SDK,并根据不同平台架构(x64/ARM64)选择对应的运行时库。Python项目可使用QNNContext等API进行模型初始化和推理,C++项目则通过libappbuilder.dll提供的接口实现。文档详细说明
环境设置
Qualcomm® AI Runtime SDK 旨在为 AI 开发提供统一的低级 API。可以从高通软件中心下载:
https://softwarecenter.qualcomm.com/#/catalog/item/Qualcomm_AI_Runtime_SDK
或者从 QPM [此选项预计很快就会被弃用]
https://qpm.qualcomm.com/#/main/tools/details/Qualcomm_AI_Runtime_SDK
来自 Qualcomm® AI Runtime SDK 的库:
我们需要以下来自 Qualcomm® AI Runtime SDK 的库,以便在 Snapdragon X Elite(Snapdragon 设备上的 Windows)上使用 AppBuilder。
注意:对于 X64 和 ARM64EC 程序,请使用文件夹“arm64x-windows-msvc”下的库;对于 ARM64 程序,请使用文件夹“aarch64-windows-msvc”下的库。
我们有 2 个选项来获取这些运行时库:
-
下载 QAIRT Runtime 并将依赖库解压到应用程序文件夹。
-
安装 Qualcomm® AI Runtime SDK 并将依赖库复制到应用程序文件夹。
如果使用 x64 Python,请使用 Qualcomm® AI Runtime SDK 中的以下库:
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\arm64x-windows-msvc\QnnHtp.dll (backend for running model on HTP)
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\arm64x-windows-msvc\QnnCpu.dll (backend for running model on CPU)
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\arm64x-windows-msvc\QnnHtpPrepare.dll
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\arm64x-windows-msvc\QnnSystem.dll
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\arm64x-windows-msvc\QnnHtpV73Stub.dll
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\hexagon-v73\unsigned\libQnnHtpV73Skel.so
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\hexagon-v73\unsigned\libqnnhtpv73.cat
如果使用 ARM64 Python,请使用 Qualcomm® AI Runtime SDK 中的以下库(ARM64 Python 在 Snapdragon X Elite 平台中性能更好):
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\aarch64-windows-msvc\QnnHtp.dll (backend for running model on HTP)
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\aarch64-windows-msvc\QnnCpu.dll (backend for running model on CPU)
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\aarch64-windows-msvc\QnnHtpPrepare.dll
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\aarch64-windows-msvc\QnnSystem.dll
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\aarch64-windows-msvc\QnnHtpV73Stub.dll
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\hexagon-v73\unsigned\libQnnHtpV73Skel.so
C:\Qualcomm\AIStack\QAIRT\{SDK Version}\lib\hexagon-v73\unsigned\libqnnhtpv73.cat
我们可以将这些库复制到一个文件夹中。例如:C:\<Project Name>\qnn\
QAI AppBuilder快速上手(2):环境设置(Python x64)可以帮助自动设置 x64 Python 环境。
在 WoS 平台中,ARM64 Python 具有更好的性能,但一些 Python 扩展不适用于当今的 ARM64 Python。有关如何设置使用 ARM64 Python 的环境的详细帮助信息,您可以参考
QAI AppBuilder快速上手(3):环境设置(Python arm64)
来自 AppBuilder Python 绑定扩展的 API 用于 Python 项目
此扩展中有几个 Python 类:
- QNNContext - QNN 模型的上下文,用于初始化 QNN 模型、运行推理和销毁模型资源
- QNNContextProc - 它与 QNNContext 类似,但支持将模型加载到单独的进程中
- QNNShareMemory - 它用于在使用 QNNContextProc 时创建进程共享内存
- QNNConfig - 用于配置 Qualcomm® AI Runtime SDK 库路径、运行时(CPU/HTP)、日志杠杆、分析级别
- PerfProfile - 设置 HTP 性能配置文件
笔记:
a. 请在调用任何其他 API 之前,使用 API LogLevel.SetLogLevel() for Python 项目初始化日志函数。
Sample Code(Python) 示例代码(Python)
from qai_appbuilder import (QNNContext, Runtime, LogLevel, ProfilingLevel, PerfProfile, QNNConfig)
import os
execution_ws = os.getcwd()
des_dir = execution_ws + "\\qnn"
def SetQNNConfig():
QNNConfig.Config(des_dir, Runtime.HTP, LogLevel.DEBUG, ProfilingLevel.BASIC)
class TextEncoder(QNNContext):
#@timer
def Inference(self, input_data):
input_datas=[input_data]
output_data = super().Inference(input_datas)[0]
# Output of Text encoder should be of shape (1, 77, 768)
output_data = output_data.reshape((1, 77, 768))
return output_data
SetQNNConfig() # We need to call this function to configure the basic environment before using any other AppBuilder functions.
model_text_encoder = "text_encoder"
text_encoder_model = "models\\text_encoder_quantized.serialized.v73.bin"
# Instance for TextEncoder
text_encoder = TextEncoder(model_text_encoder, text_encoder_model)
# Burst the HTP before inference.
PerfProfile.SetPerfProfileGlobal(PerfProfile.BURST)
# Run the inference of text encoder on tokens.
user_text_embedding = text_encoder.Inference(tokens)
# Release the HTP.
PerfProfile.RelPerfProfileGlobal()
# Destroy the model and free the memory resource.
del(text_encoder)
来自“libappbuilder.dll”的 API 用于 C++项目
- bool LibAppBuilder::ModelInitialize(…)
- std::string model_name:模型名称,例如“unet”、“text_encoder”、“controlnet_canny”。对于不同的模型文件,模型名称必须是唯一的。
- std::string proc_name:这是一个可选参数,仅当您希望在单独的进程中执行模型时才需要。如果使用进程名称,则该模型将加载到“QAIAppSvc”服务进程中。一个服务进程可以加载多个模型。可以有许多服务流程
- std::string model_path:模型的路径
- std::string backend_lib_path: ‘QnnHtp.dll’ 的路径
- std::string system_lib_path: ‘QnnSystem.dll’ 的路径
- bool LibAppBuilder::ModelInference(…)
- std::string model_name:'ModelInference’中使用的模型名称
- std::string proc_name:‘ModelInference’ 中使用的进程名称。这是一个可选参数,仅当您希望在单独的进程中执行模型时才需要
- std::string share_memory_name:‘CreateShareMemory’ 中使用的共享内存名称。这是一个可选参数,与“proc_name”一起使用
- std::vector<uint8_t>&; inputBuffers*:模型所需的所有输入数据
- std::vector<size_t>& inputSize: ‘inputBuffers’ 中输入数据的大小。这是一个可选参数,与“proc_name”一起使用
- std::vector<uint8_t>& outputBuffers*:用于保存模型的所有输出数据
- std::vector<size_t>& outputSize: ‘outputBuffers’ 中输出数据的大小
- bool LibAppBuilder::ModelDestroy(…)
- std::string model_name:'ModelInference’中使用的模型名称
- std::string proc_name:‘ModelInference’ 中使用的进程名称。这是一个可选参数,仅当您希望在单独的进程中执行模型时才需要
- bool LibAppBuilder::CreateShareMemory(…)
- std::string share_memory_name:共享内存名称。此共享内存将用于存储模型输入和输出数据
- size_t share_memory_size:模型输入和输出数据内存大小较大的那个。例如:模型输入数据大小的总大小为 10M,输出数据大小为 16M,我们可以将 ‘share_memory_size’ 设置为 16M
- bool LibAppBuilder:😄 eleteShareMemory(…)
- std::string share_memory_name:共享内存名称。
- 打印日志的辅助功能:
bool SetLogLevel(int32_t log_level)
void QNN_ERR(const char* fmt, …)
void QNN_WAR(const char* fmt, …)
void QNN_INF(const char* fmt, …)
void QNN_VEB(const char* fmt, …)
void QNN_DBG(const char* fmt, …)
- log_level:
QNN_LOG_LEVEL_ERROR = 1
QNN_LOG_LEVEL_WARN = 2
QNN_LOG_LEVEL_INFO = 3
QNN_LOG_LEVEL_VERBOSE = 4
QNN_LOG_LEVEL_DEBUG = 5
笔记:
a. 对于 C++(Visual Studio) 项目,您需要将“运行时库”设置为“多线程 DLL (/MD)”。详情请参阅以下连结:https://learn.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=msvc-170
b. 请在调用任何其他 API 之前,使用 API SetLogLevel() for C++ 项目初始化日志函数。
示例代码(C++:将模型加载到本地进程。
#include "LibAppBuilder.hpp"
LibAppBuilder libAppBuilder;
SetLogLevel(2);
std::vector<uint8_t*> inputBuffers;
std::vector<uint8_t*> outputBuffers;
std::vector<size_t> outputSize;
libAppBuilder.ModelInitialize(model_name, model_path, backend_lib_path, system_lib_path);
// Fill the inputBuffers before inference.
...
libAppBuilder.ModelInference(model_name, inputBuffers, outputBuffers, outputSize);
// Use the data in outputBuffers.
...
// Free the memory in outputBuffers.
for (int j = 0; j < outputBuffers.size(); j++) {
free(outputBuffers[j]);
}
outputBuffers.clear();
outputSize.clear();
libAppBuilder.ModelDestroy(model_name);
更多推荐
所有评论(0)