Ubuntu24.04 MNN-llm配合高通AI Engine SDK(QNN)的NPU(HTP模拟器)的环境搭建
本文记录了在Ubuntu24.04系统下使用MNN和QNN运行大模型的环境搭建过程。重点包括:1)编译MNN时添加-DMNN_QNN=ON选项;2)获取QNN SDK依赖并配置路径;3)针对模拟器环境调整HTP核心库的配置方法;4)解决libc++.so.1缺失问题;5)处理模拟器运行时的平台信息查询警告。作者使用Modelscope提供的Qwen2.5-Omni-3B-MNN模型,详细说明了在没
前言
项目需要使用MNN的QNN的NPU跑大模型,同时由于暂时没有安卓机可以使用,需要用到QNN的HTP,搜了下全网关于MNN的环境搭建没涉及QNN,QNN的环境搭建又没涉及MNN,所以记录一下自己的搭建过程。
我的个人环境是Ubuntu24.04,可能22.04更好但我因为已经用了一段时间了懒得换系统了,目前没看到有什么系统版本的问题。
MNN环境搭建
如果不想再了解如何将.onnx转换为.mnn,可以学我直接使用Modelscope的Qwen2.5-Omni-3B-MNN,下下来就是.mnn模型,而且Modelscope的MNN使用教程非常干净有效(MNN-llm的搭建我已经吃过一次鳖了= =),但是如果要用QNN的话cmake的时候还要加一个宏-DMNN_QNN=ON:
# 下载MNN源码
git clone https://github.com/alibaba/MNN.git
# 编译
cd MNN
mkdir build && cd build
cmake .. -DMNN_QNN=ON -DMNN_LOW_MEMORY=true -DMNN_CPU_WEIGHT_DEQUANT_GEMM=true -DMNN_BUILD_LLM=true -DMNN_SUPPORT_TRANSFORMER_FUSE=true
make -j
# 测试运行,如果需要是对话模式的画不用输入prompt.txt。这里的运行使用的还是默认的CPU,还没改计算资源。
./llm_demo /path/to/Qwen2.5-Omni-3B-MNN/config.json prompt.txt
具体的MNN的QNN配置方法其实在MNN目录的docs-inference-npu.md里面,但是该配置方法是有实体安卓机条件下的,如果使用HTA模拟器略有不同,我将把带使用HTA模拟器的配置方法写下面:
获得QNN依赖
QNN后端依赖QNN SDK中的/include/QNN
与lib
,首先,我们需要获得相关依赖。
-
访问Qualcomm AI Engine Direct SDK(即QNN SDK)官网,下载SDK。
我下载的是个zip压缩包,所以要先解压unzip v2.38.0.250901.zip -d ~/qnn_sdk # 版本和路径可以跟我不一样
-
参考以下指令,将下载的sdk中的
/include/QNN
与lib
拷贝到MNN源码中的对应位置。
QNN_SDK_ROOT="/YOUR/QNN/SDK/PATH" # modify this variable according to your environment,需要到有bin、lib的路径
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后端运行
-
Backend Type设置为
MNN_FORWARD_NN
,即 5 。(意思是mnn模型里的config.json设为"npu") -
除MNN相关的库之外,QNN后端在运行时还依赖几个QNN库:
# 如果是使用模拟器,好像没影响
HEXAGON_ARCH="75" # modify this variable according to your environment
# 我们用的是模拟器,并没有实际的安卓地址,所以在Ubuntu上新建一个文件夹假装是安卓地址就行,不影响,这里我直接用./qnn_libs作为地址。
ANDROID_PATH="./qnn_libs"
mkdir -p ${ANDROID_PATH}
# 拷贝HTP核心库(模拟器)
cp ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so ${ANDROID_PATH}/
# 拷贝系统库(离线生成必用,在线生成不需要)
cp ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnSystem.so ${ANDROID_PATH}/
# 然后重新设置环境变量
export LD_LIBRARY_PATH=${HOST_LIB_PATH}:$LD_LIBRARY_PATH
# 如果需要加到bash/设置全局环境变量就不用上面这个代码,用下面这个
nano ~/.bashrc
export HOST_LIB_PATH="/home/junwei/桌面/try/qnn_libs"
export LD_LIBRARY_PATH=${HOST_LIB_PATH}:$LD_LIBRARY_PATH
source ~/.bashrc
然后就可以执行MNN了
./llm_demo /path/to/Qwen2.5-Omni-3B-MNN/config.json prompt.txt
然后我还遇到以下错误:
MNN_QNN: Failed to open QNN libs. Ensure that the libs related to the QNN HTP backend is available in your environment. dlerror() returns libc++.so.1: cannot open shared object file: No such file or directory.
是因为 QNN 库依赖 LLVM 的 C++ 标准库libc++.so.1,但你的系统中没有安装该库(QNN 通常基于 LLVM 工具链编译,依赖libc++而非系统默认的glibc++),安装一下即可:
sudo apt update
sudo apt install libc++1 libc++abi1
运行时会弹出警告:
<E> QnnDevice_getPlatformInfo API not supported
[Warning]: deviceGetPlatformInfo Failed to query platform infoconfig path is xxxxxx
这是因为 MNN 库在调用 QnnDevice_getPlatformInfo 接口时失败,该接口用于查询硬件平台信息,但在模拟器环境中通常不被支持(模拟器主要模拟计算逻辑,不提供完整的硬件平台信息查询能力)。其实不影响
更多推荐
所有评论(0)