HarmonyOS:使用 MindSpore Lite 引擎進行模型推理

HarmonyOS開發者社群發表於2023-12-14

場景介紹

MindSpore Lite 是一款 AI 引擎,它提供了面向不同硬體裝置 AI 模型推理的功能,目前已經在影像分類、目標識別、人臉識別、文字識別等應用中廣泛使用。

本文介紹使用 MindSpore Lite 推理引擎進行模型推理的通用開發流程。

基本概念

在進行開發前,請先了解以下概念。

張量:它與陣列和矩陣非常相似,是 MindSpore Lite 網路運算中的基本資料結構。

Float16 推理模式: Float16 又稱半精度,它使用 16 位元表示一個數。Float16 推理模式表示推理的時候用半精度進行推理。

介面說明

這裡給出 MindSpore Lite 推理的通用開發流程中涉及的一些介面,具體請見下列表格。

Context 相關介面

HarmonyOS:使用 MindSpore Lite 引擎進行模型推理


HarmonyOS:使用 MindSpore Lite 引擎進行模型推理


Model 相關介面

HarmonyOS:使用 MindSpore Lite 引擎進行模型推理


Tensor 相關介面

HarmonyOS:使用 MindSpore Lite 引擎進行模型推理


HarmonyOS:使用 MindSpore Lite 引擎進行模型推理


開發步驟

使用 MindSpore Lite 進行模型推理的開發流程如下圖所示。 圖 1 使用 MindSpore Lite 進行模型推理的開發流程


HarmonyOS:使用 MindSpore Lite 引擎進行模型推理


進入主要流程之前需要先引用相關的標頭檔案,並編寫函式生成隨機的輸入,具體如下:



#
include 
<stdlib.h>

#
include 
<stdio.h>

#
include 
"mindspore/model.h"


//生成隨機的輸入 int GenerateInputDataWithRandom (OH_AI_TensorHandleArray inputs) {   for ( size_t i = 0; i < inputs.handle_num; ++i) {     float *input_data = ( float *) OH_AI_TensorGetMutableData(inputs.handle_list[i]);     if (input_data == NULL) {       printf( "MSTensorGetMutableData failed.\n");       return OH_AI_STATUS_LITE_ERROR;    }     int64_t num = OH_AI_TensorGetElementNum(inputs.handle_list[i]);     const int divisor = 10;     for ( size_t j = 0; j < num; j++) {       input_data[j] = ( float)( rand() % divisor) / divisor;   // 0--0.9f    }  }   return OH_AI_STATUS_SUCCESS; }



然後進入主要的開發步驟,具括包括模型的準備、讀取、編譯、推理和釋放,具體開發過程及細節請見下文的開發步驟及示例。

1.  模型準備。

需要的模型可以直接下載,也可以透過模型轉換工具獲得。

a.  下載模型的格式若為.ms,則可以直接使用。本文以 mobilenetv2.ms 為例。

b.  如果是第三方框架的模型,比如 TensorFlow、TensorFlow Lite、Caffe、ONNX 等,可以使用 轉換為.ms 格式的模型檔案。

2.  建立上下文,設定執行緒數、裝置型別等引數。



// 建立並配置上下文,設定執行時的執行緒數量為2,綁核策略為大核優先
OH_AI_ContextHandle context = 
OH_AI_ContextCreate();

if (context == 
NULL) {
  
printf(
"OH_AI_ContextCreate failed.\n");
  
return OH_AI_STATUS_LITE_ERROR;
}

const 
int thread_num = 
2;

OH_AI_ContextSetThreadNum(context, thread_num);

OH_AI_ContextSetThreadAffinityMode(context, 
1);

//設定執行裝置為CPU,不使用Float16推理
OH_AI_DeviceInfoHandle cpu_device_info = 
OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_CPU);

if (cpu_device_info == 
NULL) {
  
printf(
"OH_AI_DeviceInfoCreate failed.\n");
  
OH_AI_ContextDestroy(&context);
  
return OH_AI_STATUS_LITE_ERROR;
}

OH_AI_DeviceInfoSetEnableFP16(cpu_device_info, 
false);

OH_AI_ContextAddDeviceInfo(context, cpu_device_info);





3.  建立、載入與編譯模型。

呼叫 OH_AI_ModelBuildFromFile 載入並編譯模型。

本例中傳入 OH_AI_ModelBuildFromFile 的 argv[1]引數是從控制檯中輸入的模型檔案路徑。



// 建立模型
OH_AI_ModelHandle model = 
OH_AI_ModelCreate();

if (model == 
NULL) {
  
printf(
"OH_AI_ModelCreate failed.\n");
  
OH_AI_ContextDestroy(&context);
  
return OH_AI_STATUS_LITE_ERROR;
}


// 載入與編譯模型,模型的型別為OH_AI_MODELTYPE_MINDIR int ret = OH_AI_ModelBuildFromFile(model, argv[ 1], OH_AI_MODELTYPE_MINDIR, context); if (ret != OH_AI_STATUS_SUCCESS) {   printf( "OH_AI_ModelBuildFromFile failed, ret: %d.\n", ret);   OH_AI_ModelDestroy(&model);   return ret; }



4.  輸入資料。

模型執行之前需要向輸入的張量中填充資料。本例使用隨機的資料對模型進行填充。



// 獲得輸入張量
OH_AI_TensorHandleArray inputs = 
OH_AI_ModelGetInputs(model);

if (inputs.handle_list == 
NULL) {
  
printf(
"OH_AI_ModelGetInputs failed, ret: %d.\n", ret);
  
OH_AI_ModelDestroy(&model);
  
return ret;
}

// 使用隨機資料填充張量
ret = 
GenerateInputDataWithRandom(inputs);

if (ret != OH_AI_STATUS_SUCCESS) {
  
printf(
"GenerateInputDataWithRandom failed, ret: %d.\n", ret);
  
OH_AI_ModelDestroy(&model);
  
return ret;
}





5.  執行推理。

使用 OH_AI_ModelPredict 介面進行模型推理。



// 執行模型推理
OH_AI_TensorHandleArray outputs;
ret = 
OH_AI_ModelPredict(model, inputs, &outputs, 
NULL, 
NULL);

if (ret != OH_AI_STATUS_SUCCESS) {
  
printf(
"OH_AI_ModelPredict failed, ret: %d.\n", ret);
  
OH_AI_ModelDestroy(&model);
  
return ret;
}




6.  獲取輸出。

模型推理結束之後,可以透過輸出張量得到推理結果。



// 獲取模型的輸出張量,並列印

for (
size_t i = 
0; i < outputs.handle_num; ++i) {
  OH_AI_TensorHandle tensor = outputs.handle_list[i];
  
int64_t element_num = 
OH_AI_TensorGetElementNum(tensor);
  
printf(
"Tensor name: %s, tensor size is %zu ,elements num: %lld.\n", 
OH_AI_TensorGetName(tensor),
        
OH_AI_TensorGetDataSize(tensor), element_num);
  
const 
float *data = (
const 
float *)
OH_AI_TensorGetData(tensor);
  
printf(
"output data is:\n");
  
const 
int max_print_num = 
50;
  
for (
int j = 
0; j < element_num && j <= max_print_num; ++j) {
    
printf(
"%f ", data[j]);
  }
  
printf(
"\n");
}





7.  釋放模型。

不再使用 MindSpore Lite 推理框架時,需要釋放已經建立的模型。



// 釋放模型

OH_AI_ModelDestroy(&model);



調測驗證

1.  編寫 CMakeLists.txt。


cmake_minimum_required(VERSION 3.14)
project(Demo)


add_executable(demo main.c)
target_link_libraries(         demo         mindspore-lite.huawei         pthread         dl )



●  使用 ohos-sdk 交叉編譯,需要對 CMake 設定 native 工具鏈路徑,即:-DCMAKE_TOOLCHAIN_FILE="/xxx/native/build/cmake/ohos.toolchain.camke"。

●  工具鏈預設編譯 64 位的程式,如果要編譯 32 位,需要新增:-DOHOS_ARCH="armeabi-v7a"。

2.  執行。

●  使用 hdc_std 連線裝置,並將 demo 和 mobilenetv2.ms 推送到裝置中的相同目錄。

●  使用 hdc_std shell 進入裝置,並進入 demo 所在的目錄執行如下命令,即可得到結果。


./demo mobilenetv2.ms




得到如下輸出:


# ./QuickStart ./mobilenetv2.ms                                            
Tensor name: Softmax-
65, tensor size 
is 
4004 ,elements num: 
1001.
output 
data 
is:

0.000018 
0.000012 
0.000026 
0.000194 
0.000156 
0.001501 
0.000240 
0.000825 
0.000016 
0.000006 
0.000007 
0.000004 
0.000004 
0.000004 
0.000015 
0.000099 
0.000011 
0.000013 
0.000005 
0.000023 
0.000004 
0.000008 
0.000003 
0.000003 
0.000008 
0.000014 
0.000012 
0.000006 
0.000019 
0.000006 
0.000018 
0.000024 
0.000010 
0.000002 
0.000028 
0.000372 
0.000010 
0.000017 
0.000008 
0.000004 
0.000007 
0.000010 
0.000007 
0.000012 
0.000005 
0.000015 
0.000007 
0.000040 
0.000004 
0.000085 
0.000023 






來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70009402/viewspace-3000184/,如需轉載,請註明出處,否則將追究法律責任。

相關文章