MNN/docs/inference/npu.md

5.4 KiB
Raw Permalink Blame History

NPU 及相应后端使用说明

目前 MNN 支持通过如下后端调用部分手机上的NPU能力

  • QNN
  • CoreML
  • NNAPI
  • HIAI

目前NPU相关后端均不支持可变形状、控制流等动态模型算子数相比CPU/GPU支持要少建议根据NPU是否能跑通反复调整模型结构。

同时由于QNN、CoreML与NNAPI在MNN中共用同一个Backend Type这三个后端对应的编译宏MNN_QNN、MNN_COREML、MNN_NNAPI在编译时至多只能打开一个。

QNN

适用于使用高通芯片且配备高通Hexagon张量处理器Hexagon Tensor ProcessorHTP的机型可参考高通官网的设备支持列表

获得QNN依赖

QNN后端依赖QNN SDK中的/include/QNNlib,首先,我们需要获得相关依赖。

  • 注册高通账号
  • 访问Qualcomm AI Engine Direct SDK即QNN SDK官网下载SDK。
  • 参考以下指令将下载的sdk中的/include/QNNlib拷贝到MNN源码中的对应位置。
QNN_SDK_ROOT="/YOUR/QNN/SDK/PATH" # modify this variable according to your environment
MNN_ROOT="/YOUR/MNN/PATH" # modify this variable according to your environment
INCLUDE_SRC="${QNN_SDK_ROOT}/include/QNN"
LIB_SRC="${QNN_SDK_ROOT}/lib"
INCLUDE_DEST="${MNN_ROOT}/source/backend/qnn/3rdParty/include"
LIB_DEST="${MNN_ROOT}/source/backend/qnn/3rdParty/lib"
mkdir "${MNN_ROOT}/source/backend/qnn/3rdParty"
cp -r ${INCLUDE_SRC} ${INCLUDE_DEST}
cp -r ${LIB_SRC} ${LIB_DEST}

QNN后端编译

  • 编译 MNN 时打开编译宏MNN_QNN,即-DMNN_QNN=ON
  • 如果运行离线编译QNN模型(离线编译方法使用MNN2QNNModel工具),需要开启MNN_WITH_PLUGIN宏。若需要减小库体积,可以选择关闭MNN_QNN_ONLINE_FINALIZE

QNN后端运行

  • Backend Type设置为MNN_FORWARD_NN,即 5 。
  • 除MNN相关的库之外QNN后端在运行时还依赖四个QNN库可参考以下指令将QNN中的库拷贝到设备中。其中变量HEXAGON_ARCH需要与你的目标机型匹配,可参考高通官网的设备支持列表如8gen3的设备需要设定HEXAGON_ARCH="75"
HEXAGON_ARCH="75" # modify this variable according to your environment
MNN_ROOT="/YOUR/MNN/PATH" # modify this variable according to your environment
ANDROID_PATH="/data/local/tmp"
adb push ${MNN_ROOT}/source/backend/qnn/3rdParty/lib/aarch64-android/libQnnHtp.so ${ANDROID_PATH}/libQnnHtp.so

/*
如下libQnnHtpPrepare.so和libQnnSystem.so两个库根据情况二选一
- 如果在线生成qnn图模型运行时需要libQnnHtpPrepare.so
- 如果离线生成qnn图模型运行时需要libQnnSystem.so
*/
adb push ${MNN_ROOT}/source/backend/qnn/3rdParty/lib/aarch64-android/libQnnHtpPrepare.so ${ANDROID_PATH}/libQnnHtpPrepare.so
adb push ${MNN_ROOT}/source/backend/qnn/3rdParty/lib/aarch64-android/libQnnSystem.so ${ANDROID_PATH}/libQnnSystem.so

adb push ${MNN_ROOT}/source/backend/qnn/3rdParty/lib/aarch64-android/libQnnHtpV${HEXAGON_ARCH}Stub.so ${ANDROID_PATH}/libQnnHtpV${HEXAGON_ARCH}Stub.so
adb push ${MNN_ROOT}/source/backend/qnn/3rdParty/lib/hexagon-v${HEXAGON_ARCH}/unsigned/libQnnHtpV${HEXAGON_ARCH}Skel.so ${ANDROID_PATH}/libQnnHtpV${HEXAGON_ARCH}Skel.so
  • 为了动态链接到QNN HTP相关的库需要在环境变量ADSP_LIBRARY_PATH中添加QNN HTP库所在的目录部分机型上有效。如果这样也没法成功链接可将可执行文件push到QNN HTP库所在目录/data/local/tmpcd到对应目录后再运行可执行文件参考如下指令。
adb shell "cd /data/local/tmp && LD_LIBRARY_PATH=/data/local/tmp ADSP_LIBRARY_PATH=/data/local/tmp ./MyExe.out"

QNN量化功能说明

  • 仅权重量化激活是浮点只支持Linear权重int8、channel-wise的对称量化。
  • 激活&权重都量化支持激活per-tensor对称量化权重是int8/int4、channel-wise的对称量化。

CoreML

适用于 Mac / iOS / iPad

CoreML 后端编译

  1. 编译 MNN 时打开编译宏 MNN_COREML -DMNN_COREML=ON
  2. 编译App / 可执行程序时,增加链接 CoreML.framework

CoreML 后端使用

backend type设置成MNN_FORWARD_NN

NNAPI

适用于 Android 系统,高通/联发科芯片

NNAPI 后端编译

打开编译宏 MNN_NNAPI 即可

cd ${MNN}
cd project/android
mkdir build && cd build
../build_64.sh -DMNN_USE_LOGCAT=ON -DMNN_NNAPI=ON

NNAPI 后端使用

backend type设置成MNN_FORWARD_NN

华为 HIAI

适用于 Android 系统, Kirlin芯片

HIAI 环境准备

  1. 从如下链接下载 DDK https://developer.huawei.com/consumer/cn/doc/hiai-Library/ddk-download-0000001053590180

  2. 拷贝相对应的so和include文件到 hiai/3rdParty 目录下如果没有3rdParty目录新建一个

mkdir ${MNN}/source/backend/hiai/3rdParty
cp -r ${DDK}/lib ${MNN}/source/backend/hiai/3rdParty/armeabi-v7a
cp -r ${DDK}/lib64 ${MNN}/source/backend/hiai/3rdParty/arm64-v8a
cp -r ${DDK}/include ${MNN}/source/backend/hiai/3rdParty/include

HIAI 编译执行

  1. cmake 参数打开npu开关 -DMNN_NPU=true
  2. backend type设置成MNN_FORWARD_USER_0
  3. 执行可执行程序需动态加载libMNN_NPU.so, libhiai_ir_build.so, libhiai_ir.so, libhiai.so