diff --git a/zh-cn/application-dev/ai/Readme-CN.md b/zh-cn/application-dev/ai/Readme-CN.md index 0ff55cec35e1532fb791f531e02f0717d8f3e7f0..98c8e17ee6722a4d60a8595e11ecf70c31fd6f26 100644 --- a/zh-cn/application-dev/ai/Readme-CN.md +++ b/zh-cn/application-dev/ai/Readme-CN.md @@ -1,3 +1,5 @@ # AI -- [使用MindSpore Lite引擎进行模型推理](mindspore-lite-js-guidelines.md) +- [AI开发概述](./ai-overview.md) +- [使用MindSpore Lite JS API开发AI应用](./mindspore-guidelines-based-js.md) +- [使用MindSpore Lite Native API开发AI应用](./mindspore-guidelines-based-native.md) diff --git a/zh-cn/application-dev/ai/ai-overview.md b/zh-cn/application-dev/ai/ai-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..f39db02ae06e0324e0dad4e88cd71e232621a788 --- /dev/null +++ b/zh-cn/application-dev/ai/ai-overview.md @@ -0,0 +1,41 @@ +# AI开发概述 + +## 简介 + +OpenHarmony提供原生的分布式AI能力,AI子系统部件包括: +- MindSpore Lite:AI推理框架,为开发者提供统一的AI推理接口; +- Neural Network Runtime:神经网络运行时,作为中间桥梁连接推理框架和AI硬件。 + +## MindSpore Lite + +MindSpore Lite是OpenHarnomy内置的AI推理框架,提供面向不同硬件设备的AI模型推理能力,使能全场景智能应用,为开发者提供端到端的解决方案,目前已经在图像分类、目标识别、人脸识别、文字识别等应用中广泛使用。 + +**图 1** 使用MindSpore Lite进行模型推理的开发流程 +![mindspore workflow](figures/mindspore_workflow.png) + +MindSpore Lite开发流程分为两个阶段: + +- 模型转换 + + MindSpore Lite使用`.ms`格式模型进行推理。对于第三方框架模型,比如 TensorFlow、TensorFlow Lite、Caffe、ONNX等,可以使用MindSpore Lite提供的模型转换工具转换为`.ms`模型,使用方法可参考[推理模型转换](https://www.mindspore.cn/lite/docs/zh-CN/r1.8/use/converter_tool.html)。 + +- 模型推理 + + 调用MindSpore Lite运行时接口,实现模型推理,大致步骤如下: + + 1. 创建推理上下文,包括指定推理硬件、设置线程数等。 + 2. 加载`.ms`模型文件。 + 3. 设置模型输入数据。 + 4. 执行推理,读取输出。 + +MindSpore Lite已作为系统部件在OpenHarmony标准系统内置,基于MindSpore Lite开发AI应用的开发方式有: + +- 方式一:[使用MindSpore Lite JS API开发AI应用](./mindspore-guidelines-based-js.md)。开发者直接在UI代码中调用 MindSpore Lite JS API 加载模型并进行AI模型推理,此方式可快速验证效果。 +- 方式二:[使用MindSpore Lite Native API开发AI应用](./mindspore-guidelines-based-native.md)。开发者将算法模型和调用 MindSpore Lite Native API 的代码封装成动态库,并通过N-API封装成JS接口,供UI调用。 + +## Neural Network Runtime + +Neural Network Runtime(NNRt, 神经网络运行时)是面向AI领域的跨芯片推理计算运行时,作为中间桥梁连通上层AI推理框架和底层加速芯片,实现AI模型的跨芯片推理计算。 + +MindSpore Lite已支持配置Neural Network Runtime后端,开发者可直接配置MindSpore Lite来使用NNRt硬件。因此,这里不再对NNRt具体展开说明,主要针对MindSpore开发AI应用提供指导。关于更多NNRt的Native使用,请参见[NNRt Native模块](../napi/neural-network-runtime-guidelines.md)。 + diff --git a/zh-cn/application-dev/ai/figures/mindspore_workflow.png b/zh-cn/application-dev/ai/figures/mindspore_workflow.png new file mode 100644 index 0000000000000000000000000000000000000000..ae809ca4785835c7204acd13d8e5a948b3542850 Binary files /dev/null and b/zh-cn/application-dev/ai/figures/mindspore_workflow.png differ diff --git a/zh-cn/application-dev/ai/mindspore-lite-js-guidelines.md b/zh-cn/application-dev/ai/mindspore-guidelines-based-js.md similarity index 68% rename from zh-cn/application-dev/ai/mindspore-lite-js-guidelines.md rename to zh-cn/application-dev/ai/mindspore-guidelines-based-js.md index 092689bbac5109a3794c4fb7316d91e0be18b918..f69b448cde9d9aee637712a64dfb085d2238c828 100644 --- a/zh-cn/application-dev/ai/mindspore-lite-js-guidelines.md +++ b/zh-cn/application-dev/ai/mindspore-guidelines-based-js.md @@ -1,10 +1,8 @@ -# 使用MindSpore Lite引擎进行模型推理 +# 使用MindSpore Lite JS API开发AI应用 -## 场景介绍 +## 使用场景 -MindSpore Lite是一款AI引擎,它提供了面向不同硬件设备AI模型推理的功能,目前已经在图像分类、目标识别、人脸识别、文字识别等应用中广泛使用。 - -本文介绍使用MindSpore Lite推理引擎实现模型推理的通用开发流程。对于使用Native接口实现模型推理,具体指导请见:[使用MindSpore Lite引擎进行模型推理 ](../napi/mindspore-lite-guidelines.md)。 +开发者可以使用MindSpore Lite提供的JS API,在UI代码中直接集成MindSpore Lite能力,快速部署AI算法,进行AI模型推理。 ## 基本概念 @@ -25,18 +23,16 @@ MindSpore Lite是一款AI引擎,它提供了面向不同硬件设备AI模型 | getData(): ArrayBuffer | 获取张量的数据。 | | setData(inputArray: ArrayBuffer): void | 设置张量的数据。 | -## 开发步骤 +## 推理代码开发 + +假设开发者已准备好`.ms`格式模型。模型推理流程包括读取、编译、推理和释放,具体开发过程及细节如下: -主要流程包括模型的准备、读取、编译、推理和释放,具体开发过程及细节请见下文的开发步骤及示例。 +1. 创建上下文,设置线程数、设备类型等参数。 +2. 加载模型。本文从路径读入模型。 +3. 加载数据。模型执行之前需要先获取输入,再向输入的张量中填充数据。 +4. 执行推理并读取输出。使用predict接口进行模型推理。 -1. 模型准备。需要的模型可以直接下载,也可以通过模型转换工具获得。需要的数据从bin文件读取。 - - 下载模型的格式若为`.ms`,则可以直接使用。本文以mnet.caffemodel.ms为例。 - - 如果是第三方框架的模型,比如 TensorFlow、TensorFlow Lite、Caffe、ONNX等,可以使用[模型转换工具](https://www.mindspore.cn/lite/docs/zh-CN/r2.0/use/downloads.html#1-8-1)转换为`.ms`格式的模型文件。 -2. 创建上下文,设置线程数、设备类型等参数。 -3. 加载模型。本文从路径读入模型。 -4. 加载数据。模型执行之前需要先获取输入,再向输入的张量中填充数据。 -5. 执行推理并打印输出。使用predict接口进行模型推理。 ```js @State inputName: string = 'mnet_caffemodel_nhwc.bin'; @State T_model_predict: string = 'Test_MSLiteModel_predict' @@ -49,7 +45,6 @@ build() { .fontSize(30) .fontWeight(FontWeight.Bold) .onClick(async () => { - //1.模型准备 let syscontext = globalThis.context; syscontext.resourceManager.getRawFileContent(this.inputName).then((buffer) => { this.inputBuffer = buffer; @@ -57,20 +52,24 @@ build() { }).catch(error => { console.error('Failed to get buffer, error code: ${error.code},message:${error.message}.'); }) - //2.创建上下文 + + // 1.创建上下文 let context: mindSporeLite.Context = {}; context.target = ['cpu']; context.cpu = {} context.cpu.threadNum = 1; context.cpu.threadAffinityMode = 0; context.cpu.precisionMode = 'enforce_fp32'; - //3.加载模型 + + // 2.加载模型 let modelFile = '/data/storage/el2/base/haps/entry/files/mnet.caffemodel.ms'; let msLiteModel = await mindSporeLite.loadModelFromFile(modelFile, context); - //4.加载数据 + + // 3.设置输入数据 const modelInputs = msLiteModel.getInputs(); modelInputs[0].setData(this.inputBuffer.buffer); - //5.执行推理并打印输出 + + // 4.执行推理并打印输出 console.log('=========MSLITE predict start=====') msLiteModel.predict(modelInputs).then((modelOutputs) => { let output0 = new Float32Array(modelOutputs[0].getData()); @@ -89,7 +88,7 @@ build() { ## 调测验证 -1. 在DevEco Studio 中连接rk3568开发板,点击Run entry,编译自己的hap,有如下显示: +1. 在DevEco Studio 中连接设备,点击Run entry,编译自己的hap,有如下显示: ```shell Launching com.example.myapptfjs @@ -98,12 +97,12 @@ build() { $ hdc shell aa start -a EntryAbility -b com.example.myapptfjs ``` -2. 使用hdc连接rk3568开发板,并将mnet.caffemodel.ms推送到设备中的沙盒目录。mnet_caffemodel_nhwc.bin在本地项目中的rawfile目录下。 +2. 使用hdc连接设备,并将mnet.caffemodel.ms推送到设备中的沙盒目录。mnet_caffemodel_nhwc.bin在本地项目中的rawfile目录下。 ```shell hdc -t 7001005458323933328a00bcdf423800 file send .\mnet.caffemodel.ms /data/app/el2/100/base/com.example.myapptfjs/haps/entry/files/ ``` -3. 在rk3568屏幕中点击Test_MSLiteModel_predict触发用例,在HiLog打印结果中得到如下结果: +3. 在设备屏幕点击Test_MSLiteModel_predict触发用例,在HiLog打印结果中得到如下结果: ```shell 08-27 23:25:50.278 31782-31782/? I C03d00/JSAPP: =========MSLITE predict start===== diff --git a/zh-cn/application-dev/ai/mindspore-guidelines-based-native.md b/zh-cn/application-dev/ai/mindspore-guidelines-based-native.md new file mode 100644 index 0000000000000000000000000000000000000000..ed288808fc95a7b34d5f468cfb51f767709adc5c --- /dev/null +++ b/zh-cn/application-dev/ai/mindspore-guidelines-based-native.md @@ -0,0 +1,245 @@ +# 使用MindSpore Lite Native API开发AI应用 + +## 使用场景 + +开发者可使用MindSpore Lite提供的Native API来部署AI算法,并提供高层接口供UI层调用,进行AI模型推理。典型场景如:AI套件SDK开发。 + +## 基本概念 + +- [N-API](../reference/native-lib/third_party_napi/napi.md):用于构建JS本地化组件的一套接口。可利用N-API,将C/C++开发的库封装成JS模块。 + +## 环境准备 + +- 安装DevEco Studio,要求版本 >= 3.1.0.500,并更新SDK到API 10或以上。 + +## 开发步骤 + +### 1. 新建Native工程 + +打开DevEco Studio,新建工程,依次点击 **File -> New -> Create Project** 创建 **Native C++** 模板工程。在创建出的工程 **entry/src/main/** 目录下会默认包含 **cpp/** 目录,可以在此目录放置C/C++代码,并提供JS API供UI调用。 + +### 2. 编写C++推理代码 + +假设开发者已准备好.ms格式模型。 + +在使用MindSpore Lite Native API进行开发前,需要先引用对应的头文件。 + +```c +#include +#include +#include +#include +``` + +(1). 读取模型文件。 + +```C++ +void *ReadModelFile(NativeResourceManager *nativeResourceManager, const std::string &modelName, size_t *modelSize) { + auto rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, modelName.c_str()); + if (rawFile == nullptr) { + LOGE("Open model file failed"); + return nullptr; + } + long fileSize = OH_ResourceManager_GetRawFileSize(rawFile); + void *modelBuffer = malloc(fileSize); + if (modelBuffer == nullptr) { + LOGE("Get model file size failed"); + } + int ret = OH_ResourceManager_ReadRawFile(rawFile, modelBuffer, fileSize); + if (ret == 0) { + LOGI("Read model file failed"); + OH_ResourceManager_CloseRawFile(rawFile); + return nullptr; + } + OH_ResourceManager_CloseRawFile(rawFile); + *modelSize = fileSize; + return modelBuffer; +} +``` + +(2). 创建上下文,设置线程数、设备类型等参数,并加载模型。 + +```c++ +OH_AI_ModelHandle CreateMSLiteModel(void *modelBuffer, size_t modelSize) { + // 创建上下文 + auto context = OH_AI_ContextCreate(); + if (context == nullptr) { + DestroyModelBuffer(&modelBuffer); + LOGE("Create MSLite context failed.\n"); + return nullptr; + } + auto cpu_device_info = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_CPU); + OH_AI_ContextAddDeviceInfo(context, cpu_device_info); + + // 加载.ms模型文件 + auto model = OH_AI_ModelCreate(); + if (model == nullptr) { + DestroyModelBuffer(&modelBuffer); + LOGE("Allocate MSLite Model failed.\n"); + return nullptr; + } + + auto build_ret = OH_AI_ModelBuild(model, modelBuffer, modelSize, OH_AI_MODELTYPE_MINDIR, context); + DestroyModelBuffer(&modelBuffer); + if (build_ret != OH_AI_STATUS_SUCCESS) { + OH_AI_ModelDestroy(&model); + LOGE("Build MSLite model failed.\n"); + return nullptr; + } + LOGI("Build MSLite model success.\n"); + return model; +} +``` + +(3). 设置模型输入数据,执行模型推理并获取输出数据。 + +```js +void RunMSLiteModel(OH_AI_ModelHandle model) { + // 设置模型输入数据 + auto inputs = OH_AI_ModelGetInputs(model); + FillInputTensors(inputs); + + auto outputs = OH_AI_ModelGetOutputs(model); + + // 执行推理并打印输出 + auto predict_ret = OH_AI_ModelPredict(model, inputs, &outputs, nullptr, nullptr); + if (predict_ret != OH_AI_STATUS_SUCCESS) { + OH_AI_ModelDestroy(&model); + LOGE("Predict MSLite model error.\n"); + return; + } + LOGI("Run MSLite model success.\n"); + + LOGI("Get model outputs:\n"); + for (size_t i = 0; i < outputs.handle_num; i++) { + auto tensor = outputs.handle_list[i]; + LOGI("- Tensor %{public}d name is: %{public}s.\n", static_cast(i), OH_AI_TensorGetName(tensor)); + LOGI("- Tensor %{public}d size is: %{public}d.\n", static_cast(i), (int)OH_AI_TensorGetDataSize(tensor)); + auto out_data = reinterpret_cast(OH_AI_TensorGetData(tensor)); + std::cout << "Output data is:"; + for (int i = 0; (i < OH_AI_TensorGetElementNum(tensor)) && (i <= kNumPrintOfOutData); i++) { + std::cout << out_data[i] << " "; + } + std::cout << std::endl; + } + OH_AI_ModelDestroy(&model); +} +``` + + +(4). 调用以上3个方法,实现完整的模型推理流程。 + +```C++ +static napi_value RunDemo(napi_env env, napi_callback_info info) +{ + LOGI("Enter runDemo()"); + GET_PARAMS(env, info, 2); + napi_value error_ret; + napi_create_int32(env, -1, &error_ret); + + const std::string modelName = "ml_headpose.ms"; + size_t modelSize; + auto resourcesManager = OH_ResourceManager_InitNativeResourceManager(env, argv[1]); + auto modelBuffer = ReadModelFile(resourcesManager, modelName, &modelSize); + if (modelBuffer == nullptr) { + LOGE("Read model failed"); + return error_ret; + } + LOGI("Read model file success"); + + auto model = CreateMSLiteModel(modelBuffer, modelSize); + if (model == nullptr) { + OH_AI_ModelDestroy(&model); + LOGE("MSLiteFwk Build model failed.\n"); + return error_ret; + } + + RunMSLiteModel(model); + + napi_value success_ret; + napi_create_int32(env, 0, &success_ret); + + LOGI("Exit runDemo()"); + return success_ret; +} +``` + +(5). 编写CMake脚本,链接MindSpore Lite动态库`libmindspore_lite_ndk.so`。 + +```cmake +cmake_minimum_required(VERSION 3.4.1) +project(OHOSMSLiteNapi) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/include) + +add_library(mslite_napi SHARED mslite_napi.cpp) +target_link_libraries(mslite_napi PUBLIC mindspore_lite_ndk) # 链接MindSpore Lite动态库。 +target_link_libraries(mslite_napi PUBLIC hilog_ndk.z) +target_link_libraries(mslite_napi PUBLIC rawfile.z) +target_link_libraries(mslite_napi PUBLIC ace_napi.z) +``` + + +### 3. 使用N-API将C++动态库封装成JS模块 + + +在 **entry/src/main/cpp/types/** 新建 **libmslite_api/** 子目录,并在子目录中创建 **index.d.ts**,内容如下: + +```js +export const runDemo: (a:String, b:Object) => number; +``` + +以上代码用于定义JS接口`runDemo()` 。 + +另外,新增 **oh-package.json5** 文件,将API与so相关联,成为一个完整的JS模块: + +```json +{ + "name": "libmslite_napi.so", + "types": "./index.d.ts" +} +``` + +### 4. 在UI代码中调用封装的MindSpore模块 + +在 **entry/src/ets/MainAbility/pages/index.ets** 中,定义`onClick()`事件,并在事件回调中调用封装的`runDemo()`接口。 + +```js +import msliteNapi from 'libmslite_napi.so' // 导入msliteNapi模块。 + +...省略... + +// 点击UI中的文本,触发此事件。 +.onClick(() => { + resManager.getResourceManager().then(mgr => { + hilog.info(0x0000, TAG, '*** Start MSLite Demo ***'); + let ret = 0; + ret = msliteNapi.runDemo("", mgr); // 调用runDemo(),执行AI模型推理。 + if (ret == -1) { + hilog.info(0x0000, TAG, 'Error when running MSLite Demo!'); + } + hilog.info(0x0000, TAG, '*** Finished MSLite Demo ***'); + }) +}) +``` + +## 调测验证 + +在DevEco Studio 中连接设备,点击Run entry运行,应用进程有如下日志: + +```text +08-08 16:55:33.766 1513-1529/com.mslite.native_demo I A00000/MSLiteNativeDemo: *** Start MSLite Demo *** +08-08 16:55:33.766 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: Enter runDemo() +08-08 16:55:33.772 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: Read model file success +08-08 16:55:33.799 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: Build MSLite model success. +08-08 16:55:33.818 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: Run MSLite model success. +08-08 16:55:33.818 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: Get model outputs: +08-08 16:55:33.818 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: - Tensor 0 name is: output_node_0. +08-08 16:55:33.818 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: - Tensor 0 size is: 12. +08-08 16:55:33.826 1513-1529/com.mslite.native_demo I A00000/[MSLiteNapi]: Exit runDemo() +08-08 16:55:33.827 1513-1529/com.mslite.native_demo I A00000/MSLiteNativeDemo: *** Finished MSLite Demo *** +``` + diff --git a/zh-cn/application-dev/website.md b/zh-cn/application-dev/website.md index f574d848ff454c1238a689e5dc88add9cb4e538e..e5a9b7010701d87365e533cdc9272e3ff79ecbe6 100644 --- a/zh-cn/application-dev/website.md +++ b/zh-cn/application-dev/website.md @@ -540,7 +540,9 @@ - [Hap包签名工具指导](security/hapsigntool-guidelines.md) - [HarmonyAppProvision配置文件](security/app-provision-structure.md) - AI - - [使用MindSpore Lite引擎进行模型推理](ai/mindspore-lite-js-guidelines.md) + - [AI开发概述](./ai/ai-overview.md) + - [使用MindSpore Lite JS API开发AI应用](./ai/mindspore-guidelines-based-js.md) + - [使用MindSpore Lite Native API开发AI应用](./ai/mindspore-guidelines-based-native.md) - 网络与连接 - 网络管理 - [网络管理开发概述](connectivity/net-mgmt-overview.md)