Waterman · 10月19日 · 辽宁

【“星睿O6”AI PC开发套件评测】基于MNN的LLM与VLM部署

首先非常感谢极术社区和arm china提供的这次试用机会!目前,端侧 AI 部署已成为行业发展的重要趋势。随着大语言模型(LLM)和多模态模型(VLM)技术的成熟,将这些强大的 AI 能力部署到边缘设备上,不仅能够保护用户隐私,还能显著降低网络延迟,提升用户体验。本次我们就基于MNN框架,在Orion O6上部署语言大模型和多模态大模型,测试它们在板卡上的运行效果。

软硬件环境

MNN

MNN 是一个轻量级的深度学习推理引擎,专为多平台优化而设计,尤其适合在 ARM 设备上运行,比如手机和嵌入式设备。它具备强大的硬件兼容性,不仅支持 CPU 计算,还集成了 ARM 的 KleidiAI 加速库,同时通过 OpenCL 和 Vulkan 接口兼容主流的 ARM Mali 等 GPU。只要设备配备相应的驱动程序,MNN 就能高效地运行各种深度学习模型。
这个引擎的最大优势在于其灵活性和高效性,编译过程非常灵活,生成的库文件体积小巧,推理速度却很快,这些特点使它成为端侧部署的理想选择。在实际应用中,MNN 已经在多个商业场景中得到验证,展现出了优异的性能表现。

Orion O6开发板

瑞莎星睿 O6(Radxa Orion O6)是一款面向 AI 计算和多媒体应用的专业级 Mini-ITX 主板。它搭载了先进的 Cix P1 SoC,型号为 CD8180,最高支持 64GB LPDDR5 内存,在紧凑的尺寸下提供了接近服务器级别的性能。
这款处理器采用了三丛集架构设计,包含四核大核 Cortex®-A720、四核中核 Cortex®-A720 和四核小核 Cortex®-A520,总共 12 个核心,配合 12MB L3 共享缓存,能够提供强大的计算能力。图形处理方面,它配备了 Arm® Immortals™ G720 MC10 GPU,支持硬件光线追踪技术,同时兼容 OpenGL® ES3.2 和 Vulkan 1.3 等现代图形 API。此外还搭载有高性能NPU。非常适合部署人工智能项目。

构建项目

虽然在官方提供的镜像中,/usr/share/cix/bin目录下已经预编译好了 llm_demo 供测试使用,但在实际使用过程中我还是遇到了 segmentation fault 错误。为了解决这个问题,我决定重新构建 MNN 项目。

项目准备

首先是运行如下git命令拉取MNN项目

git clone https://gitee.com/alibaba/MNN.git
cd MNN

安装python虚拟环境

因为我们在之后进行模型转换的时候需要用到仓库中的python代码,接下来我们需要安装并配置python的虚拟环境

python3 -m venv --system-site-packages mnn_env
source mnn_env/bin/activate
pip install -r transformers/llm/export/requirements.txt
pip install onnxscript -i https://pypi.tuna.tsinghua.edu.cn/simple

由于上述命令,默认安装的torch为最新版本2.9.0,在模型转换时会报如下错误,我们可以通过重新安装2.3.1版本的pytorch来解决。
1.PNG

pip install torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 --index-url https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn

安装OpenCL支持

首先运行如下命令,安装通用 OpenCL 开发包

sudo apt update
sudo apt install -y ocl-icd-opencl-dev opencl-headers
sudo apt install mesa-opencl-icd -y
sudo apt install -y clinfo
clinfo

如果配置正确,clinfo 命令会显示详细的 OpenCL 平台和设备信息。
2.PNG

安装Vulkan支持

除了PenCL,MNN还支持Vulkan,我们这里也同时安装一下Vulkan开发包。

sudo apt update
# 安装 Vulkan 开发环境
sudo apt install libvulkan-dev vulkan-tools -y

3.png
之后运行如下命令,查看Vulkan配置是否正确,如果有正常输出则说明没有问题。

vulkaninfo | grep deviceName

安装KleidiAI支持

MNN编译时默认是集成ARM的klediAI加速库,但是从配置文件中可以看到,它的下载源是github,在国内网络环境下可能会遇到访问困难的问题,导致编译失败。
4.png
我们可以在Cmake时使用-DMNN_KLEIDIAI=OFF将其关闭。也可以参考上图配置中对kleidiai的依赖,将对应的kleidiai1.14.0下载解压至本地,并手动设置路径-DKLEIDIAI_SRC_DIR=/home/zxfeng/文档/llm/kleidiai-1.14.0
5.png
6.png

项目构建

在完成以上准备步骤后,我们开始进行 MNN 项目的构建。首先在 MNN 目录下创建了 build_opencl 目录作为编译目录,之后配置CMake并执行编译。

mkdir build_opencl
cd build_opencl

# 重新编译时需要清理旧缓存
# rm -rf *

# 配置Cmake
cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DMNN_SEP_BUILD=OFF\
  -DMNN_BUILD_DEMO=ON \
  -DMNN_BUILD_LLM=ON \
  -DMNN_BUILD_LLM_OMNI=ON \
  -DMNN_OPENCL=ON \
  -DMNN_USE_SYSTEM_LIB=ON \
  -DMNN_KLEIDIAI=ON \
  -DMNN_VULKAN=ON\
  -DMNN_KLEIDIAI=OFF\
  -DMNN_BUILD_OPENCV=ON \
  -DMNN_IMGCODECS=ON
  
make -j$(nproc)

在配置 CMake 时,我们指定了多个重要的编译选项。其中DMNN_BUILD_LLM为选择编译llm库和demo,DMNN_BUILD_LLM_OMNI为提供多模态支持,DMNN_OPENCL为支持OpenCL。另外,如下两个编译宏是是与多模态的图片输入相关的,LLM可以不设置,但VLM如果不设置无则法识别输入的图片。

  -DMNN_BUILD_OPENCV=ON \
  -DMNN_IMGCODECS=ON
 # -DMNN_BUILD_AUDIO=ON

编译宏的详细介绍可以参考MNN官方文档:编译宏介绍 — MNN-Doc 2.1.1 documentation
编译完成图如下:
7.png
可以看到目录中已经生成了.so库文件以及我们需要用到的llm_demollm_bench程序。
8.png

LLM部署

模型导出

首先在MNN目录下,使用transformers/llm/export/llmexport.py脚本将我们下载的模型转换为mnn支持的格式。

source mnn_env/bin/activate
python3 transformers/llm/export/llmexport.py --path ../models/Qwen2.5-3B-Instruct --export mnn --quant_bit 4 --quant_block 128 --dst_path ../models/Qwen2.5-3B-Instruct-mnn

9.png

模型基准测试

完成模型转换后,我们使用llm_bentch进行模型的基准测试。
由于在使用OpenCL时,会在当前目录的tmp目录下创建cache文件,因此我们需要首先新建一个tmp目录,否则会报cache相关的错误提示。
10.png
官方文档中建议OpenCL推理时使用线程数为68,这里不是传统意义的线程数,代表的是opencl buffer存储和tuning wide模式。相关命令如下:

mkdir tmp
#CPU
./llm_bench -m ../../models/Qwen2.5-3B-Instruct-mnn/config.json -a cpu -t 4,8 -p 32,64 -n 32 -rep 3
#OpenCL
./llm_bench -m ../../models/Qwen2.5-3B-Instruct-mnn/config.json -a opencl -t 68 -p 32,64 -n 32 -rep 3

运行结果如下:
11.png

12.png
测试结果显示,CPU 在短prompt处理上更快,而OpenCL在长prompt时性能反而略微更有优势,但在生成阶段两者性能接近。这是可能因为CPU擅长低延迟、小批量的串行计算,适合短prompt;而GPU擅长大规模并行计算,只有在输入足够长时才能有效摊薄调度开销并发挥算力优势。

交互测试

之后我们使用llm_demo命令来进行大模型的交互测试。
在模型目录下的config.json中,我们也可以通过直接修改backend_type参数,来设置模型是在cpu上还是OpenCL上运行。
13.png
执行命令如下:

#export LD_LIBRARY_PATH=$(pwd):$(pwd)/express:$LD_LIBRARY_PATH
./llm_demo ../../models/Qwen2.5-3B-Instruct-mnn/config.json

14.png
在测试中,可以发现大模型的输出速度还是很快的。此外我们还可以创建prompt文件并传入给大模型进行推理。首先新建一个prompt.txt文件并输入如下内容。

请用中文写一段关于“秋天”的描述,不少于50字。

执行推理

./llm_demo ../../models/Qwen2.5-3B-Instruct-mnn/config.json prompt.txt

VLM部署

模型转换

与LLM部署类似,首先也是需要将下载下来的模型文件转换为mnn支持的格式。

cd MNN
source mnn_env/bin/activate
python3 transformers/llm/export/llmexport.py --path ../models/Qwen3-VL-4B-Instruct --export mnn --quant_bit 4 --quant_block 128 --dst_path ../models/Qwen3-VL-4B-Instruct-mnn

15.png
开发板的RAM大小为16G,在转换时可能会遇到Killed,这是因为内存不够了,可以关闭无用的程序窗口为模型转换腾出内存空间。

运行测试

运行如下命令进行交互,也可以直接将prompt存入文件输入给模型。

./llm_demo ../../models/Qwen3-VL-4B-Instruct-mnn/config.json

在prompt中,输入的图像需要以<img>*.jpeg</img>的形式给出,具体参考如下:

<img>https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg</img>介绍一下图片里的内容
# 指定图片大小
<img><hw>280, 420</hw>https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg</img>介绍一下图片里的内容

<img>./demo.jpeg</img>介绍一下图片里的内容

运行效果

16.png
17.png
可以看到模型能够准确识别到图片内容并针对指令给出清晰的回答。

小结

通过本次实验,我们成功在瑞莎星睿 O6 开发板上基于 MNN 框架部署了LLM和VLM,并实现了稳定高效的运行效果。测试结果表明,尽管目前官方尚未提供 NPU 对大模型的明确支持文档,但 Orion 6 的 CPU 与 GPU 已展现出出色的端侧推理能力,完全能够支撑复杂 AI 算法的部署需求。后续,我将持续探索大模型在端侧的实际应用,并进一步研究NPU在传统模型加速方面的测试与分享。

推荐阅读
关注数
0
文章数
2
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息