[经验分享] 拆·应用丨第5期:开源鸿蒙MNN AI应用开发与MNN移植经验

开源鸿蒙知行录 显示全部楼层 发表于 2026-1-22 17:15:18

【拆·应用】是为开源鸿蒙应用开发者打造的技术分享平台,是汇聚开发者的技术洞见与实践经验、提供开发心得与创新成果的展示窗口。诚邀您踊跃发声,期待您的真知灼见与技术火花! 引言 本期内容由AI Model SIG提供,介绍了在开源鸿蒙中,利用MNN开源框架开发AI应用以及基于MNN源码编译与Har包封装的方法。

技术背景

MNN是一个由阿里巴巴开发的轻量级的深度神经网络引擎,支持深度学习的推理和训练,适用于服务器、手机、嵌入式等各类设备。MNN提供了对大语言模型和多模态大模型的支持,可以将原本需要在云端运行的大模型,经过压缩、编译和系统级优化后,直接部署在手机、PC、车载、XR 头显、机器人等终端设备上,使其无需联网即可完成生成、理解、推理等任务。

MNN的主要特性

  1. 轻量性:MNN的主体功能无任何依赖,代码精简,可以方便地部署到移动设备和各种嵌入式设备中。
  2. 通用性:MNN提供了丰富的算子,支持多种文件格式,如:TensorflowONNXTorchscripts等,支持 CNNTransformer等网络结构;在大模型领域,MNN提供了对目前主流的开源 LMM模型的支持。
  3. 高性能:MNN对iOS / Android / PC / Server 的CPU架构进行了适配,充分发挥了 CPU的算力,单线程下运行常见CV模型接近设备算力峰值;支持基于 Metal / OpenCL / Vulkan 使用端侧设备上的GPU进行推理,支持部分设备的 NPU 计算。 目前已完成MNN在 OpenHarmony 5.1 Release上的适配,支持在CPU下进行LLM、MLLM推理。

环境准备

  1. 硬件准备
  • 开发板 DAYU200
  • 芯片型号 SOC 系统芯片: Rockchip RK3568。 CPU中央处理器: Cortex-A55。 GPU图形处理器: Mali-G52
  1. 软件准备
  • 开发环境:windows 10 + ubuntu 22.04windows下进行设备连接、程序烧录、文件传输;linux进行程序编译(官方推荐)。可参考文档
  • OpenHarmonySDK下载 ohos-sdk-windows_linux-public。解压到指定目录,里边包含window和linux的库文件,分别放到对应的设备上。
  • DevEco Studio: 版本5.1.0。下载地址

开源鸿蒙MNN AI 应用开发

  1. mnnllm har包介绍 mnnllm har包是由开源鸿蒙AI Model SIG发布的大模型本地推理库,基于 mnnllm推理框架通过native api进行封装,可供ArkTS语言快速开发应用程序,当前已支持大语言模型和多模态大模型本地推理。 mnnllm har包已提交到开源鸿蒙第三方中心仓库
  2. 基于 mnnllm har包的应用开发
  • 安装 mnnllm har包,通过 ohpm install命令,可快速安装,命令如下: 1.png
  • 准备大模型并转换成mnn支持的格式 在进行测试前,需要先下载并转换成mnn格式的模型, 通过 llmexport工具即可快速转换成mnn格式,如果不想转换,也可以直接从魔搭社区下载已经转换好的mnn模型。 将大模型转换成mnn格式,llmexport命令可参考mnn官方文档

从modelscope社区直接下载mnn模型

文件准备好了之后,需要将模型文件放在 entry/src/main/resource/rawfile目录下(仅模型文件,不需要包含模型名称的外层目录),对于多模态大模型,还需在 rawfile下准备一张测试图片 test.jpg

注意:DAYU200的开发板由于算力限制,可以选择参数较小的模型(如 SmolVLM-256M-Instruct-MNN)进行验证。

应用程序开发

mnnllm har包中通过import导入对应的函数,具体函数说明,见表1。

`import{nativeLoad,nativeChat,nativeChatVLM,nativeUnload}from '@ai_model_sig/mnnllm';

定义函数 onCopyRawFileToLocal,将模型文件拷贝到应用程序沙箱。 调用 nativeLoad函数,加载模型。 如果是大语言模型,调用 nativeChat函数,输入对话内容,返回模型回答结果;如果是多模态大模型,调用 nativeChatVLM函数,输入对话内容和图片,返回模型回答结果。 应用程序结束,调用 nativeUnload函数,释放模型资源。

<div align="center">表1 Har包函数说明</div>

2.png

  • 代码示例 以下是部分关键示例代码,供参考。 3.png

<div align="center"><img src="https://forums-obs.openharmony.cn/forum/202601/22/172543cjbgv3c0jznufj36.jpg" alt="4.jpg"></div> <div align="center">编译并执行示例代码后,屏幕打印出的信息</div>

基于mnn源码编译与native接口封装

以下内容介绍基于mnn源码编译与native接口封装,如果对系统移植感兴趣的可以继续往下阅读,如果只专注应用开发,可跳过此部分内容。 源代码地址和编译方法链接(可供参考)。

  1. 适配 OpenHarmonymnn静态库打包
  • 设置 HARMONY_HOME环境变量,指向SDK解压后的目录。

    export HARMONY_HOME=/home/xxx/ohos-sdk
  • 编译 mnn的静态库,cmake时指定

    -DCMAKE_TOOLCHAIN_FILE
    -DMNN_BUILD_SHARED_LIBS=OFF
    -DMNN_BUILD_LLM=ON
  • 获取编译后的 libMNN.a的静态库。

  1. 基于mnnc++推理代码开发
  • 准备头文件和mnn的静态库,从 /path/to/MNN拷贝到 src/main/cpp目录下,libMNN.a拷贝到 /path/to/cpp/libs/
  • 模型的准备。可参考模型的转换
  • mnnc++推理代码开发和验证。代码示例(非完整代码): 5.png
  1. 基于 NAPInative方法封装
  • 开发前的准备。 打开DevEco,在创建好的项目处,右键选择 new > Module > Static Library。 将2中准备好的头文件和静态库,复制到新创建的 Modulesrc/main/cpplibsinclude目录下。
  • 接口函数的制定 6.png
  • Native方法的封装,封装以上4个函数 7.png
  • har包的开发 在 src/main/cpp/types/libentry/Index.d.ts,定义ArkTS接口。 oh-package.json5文件,将API与so相关联,成为一个完整的ArkTS模块。 在src/main/ets/export.ets导出native方法。 通过 Index.ets对外暴露har包的接口函数。

常见问题和解决方法

Native方法封装过程中,libllm.solibMNN.solibMNN_Express.so等动态库之间的复杂相互依赖问题导致的失败。 解决方法:MNN的编译过程中,指定cmake的参数 DMNN_BUILD_SHARED_LIBS=OFF,编译静态库 libMNN.a,放置在 src/main/cpp/libs下面。 Native方法封装过程中,接口函数中 loadchat等方法难以通过 NAPI的数据类型来传递模型实例。 解决方法:在c++推理代码中定义静态全局的模型,然后在 load中通过 reset方法重置模型的配置文件。 应用开发调用时,接口函数 load调用过程中,传入的模型文件无法读取的问题。 解决方法:将转换好的MNN模型文件全部放在 rawfile目录下,然后将文件全部拷贝到应用沙箱中,最后通过沙箱路径读取模型的文件。

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2025  OpenHarmony开发者论坛  京ICP备2020036654号-3 | 京公网安备11030102011662号 |技术支持 Discuz!

返回顶部