Qualcomm® AI Engine Direct 使用手册(26)

这篇具有很好参考价值的文章主要介绍了Qualcomm® AI Engine Direct 使用手册(26)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


8.2 高级的

8.2.1 QNN HTP 共享缓冲区教程

介绍
本教程介绍如何使用数据缓冲区在 QNN HTP 后端的处理域之间进行共享访问。使用共享缓冲区可以消除主机 CPU 上的客户端代码和 HTP 加速器之间的数据复制。

HTP 后端支持两种类型的共享内存。

Qnn_MemDescriptor_t 类型 QnnMemHtp_Descriptor_t 类型 描述符
QNN_MEM_TYPE_ION 1、不适用 每个张量将被映射到它自己的共享缓冲区; 2、文件描述符和内存句柄之间的一对一关系
QNN_MEM_TYPE_CUSTOM QNN_HTP_MEM_SHARED_BUFFER 1、多个张量将被映射到一个共享缓冲区;2、文件描述符和内存句柄之间的一对多关系

》笔记
本教程仅关注共享缓冲区的使用。SDK 示例代码中有一些先决条件,此处未详细讨论。用户可以参考QNN文档中的相应部分,或者参考SampleApp。

SampleApp 文档:示例应用程序教程

示例应用代码:${QNN_SDK_ROOT}/examples/QNN/SampleApp

加载必备共享库
配备高通芯片组的硬件设备包含一个共享库,该库提供共享缓冲区操作的功能。

加载共享库
该libcdsprpc.so共享库可在大多数配备高通芯片组的主流设备(SD888 及更高版本)上使用。

我们可以动态加载它,如下所示:

1 void* libCdspHandle = dlopen("libcdsprpc.so", RTLD_NOW | RTLD_LOCAL);
2
3 if (nullptr == libCdspHandle) {
4   // handle errors
5 }

解析符号
共享库成功加载后,我们可以继续解析所有必需的符号。

下面的代码片段显示了解析共享库中符号的模板:

 1/**
 2* Defination: void* rpcmem_alloc(int heapid, uint32 flags, int size);
 3* Allocate a buffer via ION and register it with the FastRPC framework.
 4* @param[in] heapid  Heap ID to use for memory allocation.
 5* @param[in] flags   ION flags to use for memory allocation.
 6* @param[in] size    Buffer size to allocate.
 7* @return            Pointer to the buffer on success; NULL on failure.
 8*/
 9typedef void *(*RpcMemAllocFn_t)(int, uint32_t, int);
10
11/**
12* Defination: void rpcmem_free(void* po);
13* Free a buffer and ignore invalid buffers.
14*/
15typedef void (*RpcMemFreeFn_t)(void *);
16
17/**
18* Defination: int rpcmem_to_fd(void* po);
19* Return an associated file descriptor.
20* @param[in] po  Data pointer for an RPCMEM-allocated buffer.
21* @return        Buffer file descriptor.
22*/
23typedef int (*RpcMemToFdFn_t)(void *);
24
25RpcMemFreeFn_t rpcmem_alloc = (RpcMemAllocFn_t)dlsym(libCdspHandle, "rpcmem_alloc");
26RpcMemFreeFn_t rpcmem_free = (RpcMemFreeFn_t)dlsym(libCdspHandle, "rpcmem_free");
27RpcMemToFdFn_t rpcmem_to_fd = (RpcMemToFdFn_t)dlsym(libCdspHandle, "rpcmem_to_fd");
28if (nullptr == rpcmem_alloc || nullptr == rpcmem_free || nullptr == rpcmem_to_fd) {
29    dlclose(libCdspHandle);
30    // handle errors
31}

将 QNN_MEM_TYPE_ION 与 QNN API 结合使用
以下是 ION 共享缓冲区的表示,其中每个张量都有自己的共享缓冲区,具有自己唯一的内存指针、文件描述符和内存句柄。
qnninterface.h,AI,Qualcomm,笔记,人工智能,算法,Qualcomm,ai
一个例子如下所示:

HTP 共享缓冲区示例

 1// QnnInterface_t is defined in ${QNN_SDK_ROOT}/include/QNN/QnnInterface.h
 2QnnInterface_t qnnInterface;
 3// Init qnn interface ......
 4// See ${QNN_SDK_ROOT}/examples/QNN/SampleApp code
 5
 6// Qnn_Tensor_t is defined in ${QNN_SDK_ROOT}/include/QNN/QnnTypes.h
 7Qnn_Tensor_t inputTensor;
 8// Set up common setting for inputTensor ......
 9/* There are 2 specific settings for shared buffer:
10*  1. memType should be QNN_TENSORMEMTYPE_MEMHANDLE; (line 40)
11*  2. union member memHandle should be used instead of clientBuf, and it
12*     should be set to nullptr. (line 41)
13*/
14
15
16size_t bufSize;
17// Calculate the bufSize base on tensor dimensions and data type ......
18
19#define RPCMEM_HEAP_ID_SYSTEM 25
20#define RPCMEM_DEFAULT_FLAGS 1
21
22// Allocate the shared buffer
23uint8_t* memPointer = (uint8_t*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, bufSize);
24if (nullptr == memPointer) {
25    // handle errors
26}
27
28int memFd = rpcmem_to_fd(memPointer);
29if (-1 == memfd) {
30    // handle errors
31}
32
33// Fill the info of Qnn_MemDescriptor_t and regist the buffer to QNN
34// Qnn_MemDescriptor_t is defined in ${QNN_SDK_ROOT}/include/QNN/QnnMem.h
35Qnn_MemDescriptor_t memDescriptor = QNN_MEM_DESCRIPTOR_INIT;
36memDescriptor.memShape = {inputTensor.rank, inputTensor.dimensions, nullptr};
37memDescriptor.dataType = inputTensor.dataType;
38memDescriptor.memType = QNN_MEM_TYPE_ION;
39memDescriptor.ionInfo.fd = memfd;
40inputTensor.memType = QNN_TENSORMEMTYPE_MEMHANDLE;
41inputTensor.memHandle = nullptr;
42Qnn_ContextHandle_t context; // Must obtain a QNN context handle before memRegister()
43// To obtain QNN context handle:
44// For online prepare, refer to ${QNN_SDK_ROOT}/docs/general/sample_app.html#create-context
45// For offline prepare, refer to ${QNN_SDK_ROOT}/docs/general/sample_app.html#load-context-from-a-cached-binary
46Qnn_ErrorHandle_t registRet = qnnInterface->memRegister(context, &memDescriptor, 1u, &(inputTensor.memHandle));
47if (QNN_SUCCESS != registRet) {
48    rpcmem_free(memPointer);
49    // handle errors
50}
51
52/**
53* At this place, the allocation and registration of the shared buffer has been complete.
54* On QNN side, the buffer has been bound by memfd
55* On user side, this buffer can be manipulated through memPointer.
56*/
57
58/**
59* Optionally, user can also allocate and register shared buffer for output as adove codes (lines 7-46).
60* And if so the output buffer also should be deregistered and freed as below codes (lines 66-70).
61*/
62
63// Load the input data to memPointer ......
64
65// Execute QNN graph with input tensor and output tensor ......
66
67// Get output data ......
68
69// Deregister and free all buffers if it's not being used
70Qnn_ErrorHandle_t deregisterRet = qnnInterface->memDeRegister(&tensors.memHandle, 1);
71if (QNN_SUCCESS != registRet) {
72    // handle errors
73}
74rpcmem_free(memPointer);

将 QNN_HTP_MEM_SHARED_BUFFER 与 QNN API 结合使用

以下是多张量共享缓冲区的表示,其中一组张量映射到单个共享缓冲区。这个单个共享缓冲区有一个内存指针和一个文件描述符,但是每个张量都有自己的内存指针偏移量和内存句柄。

qnninterface.h,AI,Qualcomm,笔记,人工智能,算法,Qualcomm,ai
一个例子如下所示:

HTP 多张量共享缓冲区示例

  1// QnnInterface_t is defined in ${QNN_SDK_ROOT}/include/QNN/QnnInterface.h
  2QnnInterface_t qnnInterface;
  3// Init qnn interface ......
  4// See ${QNN_SDK_ROOT}/examples/QNN/SampleApp code
  5
  6// Total number of input tensors
  7size_t numTensors;
  8
  9// Qnn_Tensor_t is defined in ${QNN_SDK_ROOT}/include/QNN/QnnTypes.h
 10Qnn_Tensor_t inputTensors[numTensors];
 11// Set up common setting for inputTensor ......
 12/* There are 2 specific settings for shared buffer:
 13*  1. memType should be QNN_TENSORMEMTYPE_MEMHANDLE; (line 40)
 14*  2. union member memHandle should be used instead of clientBuf, and it
 15*     should be set to nullptr. (line 41)
 16*/
 17
 18// Calculate the shared buffer size
 19uint64_t totalBufferSize;
 20for (size_t tensorIdx = 0; tensorIdx < numTensors; tensorIdx++) {
 21   // Calculate the tensorSize based on tensor dimensions and data type
 22   totalBufferSize += tensorSize;
 23}
 24
 25#define RPCMEM_HEAP_ID_SYSTEM 25
 26#define RPCMEM_DEFAULT_FLAGS 1
 27
 28// Allocate the shard buffer
 29uint8_t* memPointer = (uint8_t*)rpcmem_alloc(RPCMEM_HEAP_ID_SYSTEM, RPCMEM_DEFAULT_FLAGS, totalBufferSize);
 30if (nullptr == memPointer) {
 31    // handle errors
 32}
 33
 34// Get a file descriptor for the buffer
 35int memFd = rpcmem_to_fd(memPointer);
 36if (-1 == memfd) {
 37    // handle errors
 38}
 39
 40// Regiter the memory handles using memory descriptors
 41// This is the offset of the tensor location in the shared buffer
 42uint64_t offset;
 43for (size_t tensorIdx = 0; tensorIdx < numTensors; tensorIdx++) {
 44   // Fill the info of Qnn_MemDescriptor_t and register the descriptor to QNN
 45   // Qnn_MemDescriptor_t is defined in ${QNN_SDK_ROOT}/include/QNN/QnnMem.h
 46   Qnn_MemDescriptor_t memDescriptor;
 47   memDescriptor.memShape = {inputTensors[tensorIdx].rank, inputTensors[tensorIdx].dimensions, nullptr};
 48   memDescriptor.dataType = inputTensors[tensorIdx].dataType;
 49   memDescriptor.memType = QNN_MEM_TYPE_CUSTOM;
 50   inputTensor[tensorIdx].memType = QNN_TENSORMEMTYPE_MEMHANDLE;
 51   inputTensor[tensorIdx].memHandle = nullptr;
 52
 53   // Fill the info of QnnMemHtp_Descriptor_t and set as custom info
 54   // QnnMemHtp_Descriptor_t is defined in ${QNN_SDK_ROOT}/include/QNN/HTP/QnnHtpMem.h
 55   QnnMemHtp_Descriptor_t htpMemDescriptor;
 56   htpMemDescriptor.type = QNN_HTP_MEM_SHARED_BUFFER;
 57   htpMemDescriptor.size = totalBufferSize; //Note: it's total buffer size
 58
 59   QnnHtpMem_SharedBufferConfig_t htpSharedBuffConfig = {memFd, offset};
 60   htpMemDescriptor.sharedBufferConfig = htpSharedBuffConfig;
 61
 62   memDescriptor.customInfo = &htpMemDescriptor;
 63
 64   Qnn_ContextHandle_t context; // Must obtain a QNN context handle before memRegister()
 65   // To obtain QNN context handle:
 66   // For online prepare, refer to ${QNN_SDK_ROOT}/docs/general/sample_app.html#create-context
 67   // For offline prepare, refer to ${QNN_SDK_ROOT}/docs/general/sample_app.html#load-context-from-a-cached-binary
 68
 69   Qnn_ErrorHandle_t registRet = qnnInterface->memRegister(context, &memDescriptor, 1u, &(inputTensor[tensorIdx].memHandle));
 70   if (QNN_SUCCESS != registRet) {
 71      // Deregister already created memory handles
 72      rpcmem_free(memPointer);
 73      // handle errors
 74   }
 75
 76   // move offset by the tensor size
 77   offset = offset + tensorSize;
 78}
 79
 80/**
 81* At this place, the allocation and registration of the shared buffer has been complete.
 82* On QNN side, the buffer has been bound by memfd
 83* On user side, this buffer can be manipulated through memPointer and offset.
 84*/
 85
 86/**
 87* Optionally, user can also allocate and register shared buffer for output as adove codes (lines 7-78).
 88* And if so the output buffer also should be deregistered and freed as below codes (lines 98-104).
 89*/
 90
 91// Load the input data to memPointer with respecitve offsets ......
 92
 93// Execute QNN graph with input tensors and output tensors ......
 94
 95// Get output data from the memPointer and offset combination ......
 96
 97// Deregister all mem handles the buffer if it's not being used
 98for (size_t tensorIdx = 0; tensorIdx < numTensors; tensorIdx++) {
 99   Qnn_ErrorHandle_t deregisterRet = qnnInterface->memDeRegister(&(inputTensors[tensorIdx].memHandle), 1);
100   if (QNN_SUCCESS != registRet) {
101    // handle errors
102   }
103}
104rpcmem_free(memPointer);

8.2.2 使用 DLC 执行

教程设置
本教程假设已遵循QNN和SNPE的一般设置说明。特别是,使用工具转换为 DLC需要适当设置 PYTHONPATH 和 SNPE_ROOT。

此外,本教程需要获取 Inception V3 Tensorflow 模型文件和示例图像。这是由提供的安装脚本处理的setup_inceptionv3.py。该脚本位于:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py

用法如下:

usage: setup_inceptionv3.py [-h] -a ASSETS_DIR [-d] [-c] [-q]

Prepares the inception_v3 assets for tutorial examples.

required arguments:
  -a ASSETS_DIR, --assets_dir ASSETS_DIR
                        directory containing the inception_v3 assets

optional arguments:
  -d, --download        Download inception_v3 assets to inception_v3 example
                        directory
  -c, --convert_model   Convert and compile model once acquired.
  -q, --quantize_model  Quantize the model during conversion. Only available
                        if --c or --convert_model option is chosen

在使用脚本之前,请将环境变量设置TENSORFLOW_HOME为指向TensorFlow包的安装位置。该脚本使用 TensorFlow 实用程序,例如 optimize_for_inference.py,它们位于 TensorFlow 安装目录中。

  1. 找到TensorFlow包的位置:
$ python3 -m pip show tensorflow
  1. TENSORFLOW_HOME使用 TensorFlow 包的安装位置(步骤 #1 中输出的位置字段)设置环境变量:
$ export TENSORFLOW_HOME=<tensorflow-location>/tensorflow_core
  1. 使用以下脚本安装 Inception V3 TensorFlow 模型和示例图像setup_inceptionv3.py:
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py -a ~/tmpdir -d

该模型文件现在应填充在以下位置:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/tensorflow/inception_v3_2016_08_28_frozen.pb

此原始图像现在应填充在以下位置:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped

型号转换

获取模型资产后,可以使用 Qualcomm® 神经处理 SDK 中的转换工具将模型转换为 DLC。

笔记
HTP 和 DSP 后端需要使用量化模型。请参阅模型量化以生成量化的 DLC。

使用snpe-tensorflow-to-dlc工具转换 Inception V3 模型 。

$ ${SNPE_ROOT}/bin/x86_64-linux-clang/snpe-tensorflow-to-dlc \
  --input_network ${QNN_SDK_ROOT}/examples/Models/InceptionV3/tensorflow/inception_v3_2016_08_28_frozen.pb \
  --input_dim input 1,299,299,3 \
  --out_node InceptionV3/Predictions/Reshape_1 \
  --output_path ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.dlc \

这会生成${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.dlcDLC 文件。

DLC 包含序列化模型、网络拓扑和关联的模型数据。

模型量化
DLC 可以使用snpe-dlc-quantize 工具进行量化。用法示例如下:

$ ${SNPE_ROOT}/bin/x86_64-linux-clang/snpe-dlc-quantize \
  --input_dlc ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.dlc \
  --input_list ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped/raw_list.txt \
  --output_dlc ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.dlc \

这将产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.dlc

笔记
量化模型时,输入列表必须包含输入数据的绝对路径。

执行需要生成的 DLC 和提供的实用程序库libQnnModelDlc.so。该库扩展了QNN 模型 API 以组成 QNN 图并从提供的 DLC 路径返回其句柄。

ModelError_t QnnModel_composeGraphsFromDlc(Qnn_BackendHandle_t backendHandle,
                                        QNN_INTERFACE_VER_TYPE interface,
                                        Qnn_ContextHandle_t contextHandle,
                                        const GraphConfigInfo_t **graphsConfigInfo,
                                        const char *dlcPath,
                                        const uint32_t numGraphsConfigInfo,
                                        GraphInfoPtr_t **graphsInfo,
                                        uint32_t *numGraphsInfo,
                                        bool debug,
                                        QnnLog_Callback_t logCallback,
                                        QnnLog_Level_t maxLogLevel)

QnnGraph_ComposeGraphs这与添加了输入参数的 API相同dlcPath 。然后可以最终确定并执行返回的 QNN 图句柄。

以下部分演示了 DLC 的执行。

CPU后端执行
在Linux主机上执行

  1. qnn-net-run使用libQnnModelDlc.so实用程序库作为–model参数和 Inception_v3.dlc 作为参数来执行模型–dlc_path。
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnCpu.so \
              --model ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnModelDlc.so \
              --dlc_path ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.dlc \
              --input_list data/cropped/raw_list.txt

结果将位于${QNN_SDK_ROOT}/examples/Models/InceptionV3/output。

查看结果。

$ python ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output/ \
                                                                               -l data/imagenet_slim_labels.txt

在安卓上执行
在 Android 目标上运行 CPU 后端与在 Linux x86 目标上运行类似。

在 Android 设备上为示例创建一个目录。

$ adb shell "mkdir /data/local/tmp/inception_v3"

将必要的库和 DLC 推送到设备。

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnCpu.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.dlc /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnModelDlc.so /data/local/tmp/inception_v3

将输入数据和列表推送到设备。

$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt /data/local/tmp/inception_v3

将qnn-net-run工具推至设备。

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/inception_v3

设置设备环境。

$ adb shell
$ cd /data/local/tmp/inception_v3
$ export LD_LIBRARY_PATH=/data/local/tmp/inception_v3

qnn-net-run使用以下参数运行。

$ ./qnn-net-run --backend libQnnCpu.so --model libQnnModelDlc.so --dlc_path Inception_v3.dlc --input_list target_raw_list.txt

运行的输出将位于默认的 ./output 目录中。

退出设备并查看结果。文章来源地址https://www.toymoban.com/news/detail-831346.html

$ exit
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ adb pull /data/local/tmp/inception_v3/output output_android
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output_android/ \
                                                                               -l data/imagenet_slim_labels.txt

GPU后端执行

笔记
不支持在 Windows 设备上运行 GPU 后端。

在安卓上执行
在 Android 目标上运行 GPU 后端与在 Android 目标上运行 CPU 后端类似。

在 Android 设备上为示例创建一个目录。

$ adb shell "mkdir /data/local/tmp/inception_v3"

将必要的库和 DLC 推送到设备。

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnGpu.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.dlc /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnModelDlc.so /data/local/tmp/inception_v3

将输入数据和列表推送到设备。

$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt /data/local/tmp/inception_v3

将qnn-net-run工具推至设备。

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/inception_v3

设置设备环境。

$ adb shell
$ cd /data/local/tmp/inception_v3
$ export LD_LIBRARY_PATH=/data/local/tmp/inception_v3

qnn-net-run使用以下参数运行。

$ ./qnn-net-run --backend libQnnGpu.so --model libQnnModelDlc.so --dlc_path Inception_v3.dlc --input_list target_raw_list.txt

运行的输出将位于默认的 ./output 目录中。

退出设备并查看结果。

$ exit
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ adb pull /data/local/tmp/inception_v3/output output_android
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                              -o output_android/ \
                                                                              -l data/imagenet_slim_labels.txt

HTP 后端执行
在Linux主机上执行

笔记
可以使用 HTP 模拟后端在 Linux 主机上运行 HTP 后端。

qnn-net-run使用libQnnModelDlc.so实用程序库作为–model参数和 Inception_v3_quantized.dlc 作为参数来执行模型–dlc_path。

$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
              --model ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnModelDlc.so \
              --dlc_path ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.dlc \
              --input_list data/cropped/raw_list.txt

笔记
HTP 仿真后端需要量化模型。有关量化的更多信息,请参阅模型量化。

结果将位于${QNN_SDK_ROOT}/examples/Models/InceptionV3/output。

查看结果。

$ python ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output/ \
                                                                               -l data/imagenet_slim_labels.txt

在安卓上执行
在 Android 目标上运行 HTP 后端与在 Android 目标上运行 CPU 和 GPU 后端类似,不同之处在于 HTP 后端需要量化模型和用户生成的序列化上下文。有关量化的更多信息,请参阅模型量化。

  1. qnn-context-binary-generator通过使用 libQnnModelDlc.so 作为–model参数和量化 DLC 作为参数运行,从 DLC 生成序列化上下文–dlc_path。
$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-context-binary-generator \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
              --model ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnModelDlc.so \
              --dlc_path ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.dlc \
              --binary_file Inception_v3_quantized.serialized

上下文将在 处创建./output/Inception_v3_quantized.serialized.bin。

  1. 在 Android 设备上为示例创建一个目录。
$ adb shell "mkdir /data/local/tmp/inception_v3"
  1. 将必要的库和 DLC 推送到设备。
$ adb push ${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/output/Inception_v3_quantized.serialized.bin /data/local/tmp/inception_v3

笔记
本节演示了 Android 上的 HTP 执行以及离线准备的图形步骤。要执行设备上(在线)准备好的图表,请推送设备上准备库和量化 DLC。

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.dlc /data/local/tmp/inception_v3

将输入数据和列表推送到设备。

$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt /data/local/tmp/inception_v3

将qnn-net-run工具推至设备。

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/inception_v3

设置设备环境。

$ adb shell
$ cd /data/local/tmp/inception_v3
$ export LD_LIBRARY_PATH=/data/local/tmp/inception_v3
$ export ADSP_LIBRARY_PATH="/data/local/tmp/inception_v3"

qnn-net-run使用以下参数运行。

$ ./qnn-net-run --backend libQnnHtp.so --input_list target_raw_list.txt --retrieve_context Inception_v3_quantized.serialized.bin

运行的输出将位于默认的 ./output 目录中。

退出设备并查看结果。

$ exit
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ adb pull /data/local/tmp/inception_v3/output output_android
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                              -o output_android/ \
                                                                              -l data/imagenet_slim_labels.txt

到了这里,关于Qualcomm® AI Engine Direct 使用手册(26)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity 开发人员转CGE(castle Game engine)城堡游戏引擎指导手册

    一、简介 2. Unity相当于什么GameObject? 3. 如何设计一个由多种资产、生物等组成的关卡? 4. 在哪里放置特定角色的代码(例如生物、物品)?Unity 中“向 GameObject 添加 MonoBehaviour”相当于什么? 5.Unity子目录相当于什么Assets? 6. 支持哪些模型格式? 7. 支持FBX模型格式吗? 8.

    2024年02月07日
    浏览(76)
  • 《使用Unreal Engine Python插件进行UE4中的Python开发》学习笔记1

    ·本文为B站系列教学视频 《使用 UnrealEnginPython 插件进行UE4中的Python开发》 ——《 Day 01 初识 UnrealEnginePython 》的学习笔记,UP主为腾讯游戏策划、虚幻社区贡献者 世欺子。 本节课对基于虚幻引擎( Unreal Engine )的 Python 集成开发插件 UnrealEnginePython 进行简要介绍,接着在虚幻

    2024年04月11日
    浏览(62)
  • Gurobi笔记(使用手册)

    连续问题、整数问题、线性和二次凸问题、二次非凸问题、广义非线性问题等 广义非线性问题——广义函数约束 函数形式可以是 高阶多项式、对数、指数、三角函数 等非线性函数,那么Gurobi 会对这些函数 自动分段线性化 进行近似,用户可以通过参数来平衡近似的精度和速

    2024年02月02日
    浏览(28)
  • 开源:小狐狸GPT付费AI-v2.0.0 H5和小程序端增加使用手册

    小狐狸GPT付费AI体验系统、系统版本更新至1.2.0, 源码为小程序、H5、WEB版本 ,购买含更新, 独立版; 开源、开源、开源、可二开!!200包含H5、web的vue全开源, 最新版更新了:H5和小程序端增加使用手册 测试环境:系统环境:CentOS Linux 7.6.1810 (Core)、运行环境:宝塔 Linux

    2024年02月12日
    浏览(51)
  • Character Animation With Direct3D 读书笔记

    2D动画:循环播放多张图片 3D动画: 骨骼动画、变形动画 Win32 应用程序 Application类:处理主程序循环,图形设备的初始化 Init:加载资源并创建图形设备 Update:更新游戏世界,移动对象,更新物理引擎 Render:渲染所有对象,并将结果呈现给屏幕 Quit Cleanup DirectX 渲染循环:

    2024年02月12日
    浏览(39)
  • AI绘图提示词/咒语/词缀/关键词使用指南(Stable Diffusion Prompt 设计师操作手册)

    基本知识 : 安装及其问题解决参考:《Windows安装Stable Diffusion WebUI及问题解决记录》; 运行使用时问题《Windows使用Stable Diffusion时遇到的各种问题整理》; 模型运用及参数《Stable Diffusion 个人推荐的各种模型及设置参数、扩展应用等合集》; 提示词生图咒语《AI绘图提示词

    2024年02月01日
    浏览(71)
  • Ai工具推荐 - Claude(一款没有任何限制,可以直接使用的媲美ChatGPT产品,手机端也可使用) 保姆级操作手册

    ChatGPT现在非常的火爆,很多小伙伴都想体验一下,但体验它是需要一些限制的,比如美国手机号。这无形中给很多人增加了使用的门槛。今天给大家介绍一个没有任何限制,就可以使用的一款与它效果基本一致的AI产品,Claude。它不仅可以在PC端使用,同时还可以在手机端使

    2024年02月05日
    浏览(95)
  • Unreal Engine 5.1 AI行为树基础入门

    ai行为树理解起来其实是npc根据自身一些情况进行一些逻辑执行,而这些逻辑是我们使用ai行为树去实现的。 ai行为树需要一个寻路网格体边界体积,在ue引擎中,体积Actor分为多种,寻路网格体边界体积只是其中的一种。 关于其它的体积,可以在官网网站查看 通过上面的介绍

    2024年02月11日
    浏览(36)
  • 一、D3D12学习笔记——初始化Direct3D

    工厂类IDXGIFactory4,这个类有两个作用: 1.枚举适配器(显卡); 2.创建交换链 这个类对象的创建如下: 用这个对象mdxgiFactory枚举我们可以使用的显卡等适配器: 对于一个选定的适配器pIAdapter,拿着它去创建设备 IID_PPV_ARGS这个宏实际包含了两个东西,uuid的COM ID和对象的指针

    2024年02月10日
    浏览(47)
  • WPS AI最全申请与使用手册;AIGC制作游戏音乐;便宜快捷使用完整版SD;人人都能看懂的ChatGPT原理课 | ShowMeAI日报

    👀 日报周刊合集 | 🎡 生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 作者在这篇文章中探讨了生成式AI在虚拟世界的应用,并绘制了 Market Map V3.0 (市场全景图),来展示 Experiences 、 Discovery、Creator Economy、Spatial Computing、Decentralization、Human Interface、Infrastructure 各部分

    2024年02月09日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包