目录

  1. 概述
  2. MindSpore Lite Kit介绍
  3. 模型转换指南
  4. 模型推理指南
  5. 模型训练指南
  6. 基于ArkTS的图像分类实现
  7. 基于Native的图像分类实现
  8. 基于Native的语音识别实现
  9. 应用场景与价值
  10. 总结

概述

MindSpore Lite是华为推出的一款轻量级深度学习推理框架,专为端侧设备设计,支持在资源受限的设备上高效运行深度学习模型。本文档全面介绍了MindSpore Lite的核心功能、使用方法和应用场景,包括模型转换、推理、训练以及基于ArkTS和Native接口的应用开发。

MindSpore Lite Kit介绍

使用场景

MindSpore Lite广泛应用于多种AI场景,包括但不限于:

  • 图像分类
  • 目标检测
  • 语音识别
  • 自然语言处理

约束与限制

  • MindSpore Lite目前仅适用于手机和平板设备
  • 需要鸿蒙系统支持
  • 对设备硬件有一定要求

亮点与优势

  1. 性能优异:针对端侧设备优化,提供高效的推理能力
  2. 轻量化设计:占用资源少,适合资源受限的设备
  3. 全场景支持:支持多种AI应用场景
  4. 高效部署:提供简洁的部署流程和工具

开发流程

MindSpore Lite的开发流程主要分为两个阶段:

  1. 模型转换阶段:将原始模型转换为MindSpore Lite支持的.ms格式
  2. 模型部署阶段:将转换后的模型部署到目标设备上进行推理或训练

开发方式

MindSpore Lite支持两种开发方式:

  1. ArkTS API:适用于鸿蒙应用开发,提供简洁的TypeScript接口
  2. Native API:提供C/C++接口,适合需要更高性能控制的场景

与NNRt的关系

MindSpore Lite支持配置NNRt(Neural Network Runtime)以使能AI专用芯片加速推理,进一步提升推理性能。

模型转换指南

基本概念

  • MindSpore Lite:轻量级深度学习推理框架
  • NNRt:神经网络运行时,支持AI专用芯片加速

模型部署流程

原始模型 → .ms模型 → 推理

环境准备

  1. 工具下载/编译

    • 从官方渠道下载MindSpore Lite转换工具
    • 或根据源码编译转换工具
  2. 环境变量配置

    export MSLITE_HOME=/path/to/mindspore-lite
    export PATH=$MSLITE_HOME/tools/converter:$PATH
    

转换参数说明

必选参数
  • --fmk:原始模型格式,支持TF、CAFFE、ONNX、TFLITE、MINDIR等
  • --modelFile:原始模型文件路径
  • --outputFile:输出.ms模型文件路径
可选参数
  • --configFile:配置文件路径,用于扩展转换功能
  • --weightFile:权重文件路径(CAFFE格式需要)
  • --inputDataType:输入数据类型,支持FLOAT32、INT8等
  • --outputDataType:输出数据类型,支持FLOAT32、INT8等

使用示例

CAFFE模型转换示例
./converter_lite --fmk=CAFFE --modelFile=Lenet.prototxt --weightFile=Lenet.caffemodel --outputFile=lenet.ms

转换成功后,会生成lenet.ms文件,可用于MindSpore Lite推理。

离线模型转换

约束限制
  • 输入模型必须与目标设备兼容
  • 某些复杂算子可能不支持转换
扩展配置文件格式
{
  "version": "1.0",
  "converter": {
    "plugins": [
      {
        "name": "custom_plugin",
        "path": "/path/to/plugin.so"
      }
    ]
  }
}

模型推理指南

场景介绍

MindSpore Lite支持多种推理场景,包括:

  • 图像分类
  • 目标检测
  • 语义分割
  • 语音识别

基本概念

  • 张量:多维数组,是模型输入输出的基本数据结构
  • Float16推理模式:使用半精度浮点数进行推理,可减少内存占用

核心接口说明

Context接口

Context是模型运行的环境配置,包含设备类型、线程数等配置。

// 创建Context
OH_AI_ContextHandle context = OH_AI_ContextCreate();
// 设置设备类型
OH_AI_ContextSetDeviceType(context, OH_AI_kDT_CPU);
// 设置线程数
OH_AI_ContextSetThreadNum(context, 2);
// 设置线程亲和性
OH_AI_ContextSetThreadAffinityMode(context, 1);
Model接口

Model是模型加载和执行的核心接口。

// 创建模型
OH_AI_ModelHandle model = OH_AI_ModelCreate();
// 编译模型
OH_AI_ModelBuildFromFile(model, model_path, model_type, context);
// 执行推理
OH_AI_ModelPredict(model, inputs, outputs, nullptr);
Tensor接口

Tensor用于管理模型的输入输出数据。

// 获取输入张量
OH_AI_TensorHandle input_tensor = OH_AI_ModelGetInput(model, 0);
// 获取张量数据
void *data = OH_AI_TensorGetMutableData(input_tensor);
// 设置张量数据
memcpy(data, input_data, data_size);

开发步骤

  1. 模型准备

    • 获取.ms模型文件
    • 确保模型与目标设备兼容
  2. 创建上下文

    OH_AI_ContextHandle context = OH_AI_ContextCreate();
    OH_AI_ContextSetDeviceType(context, OH_AI_kDT_CPU);
    OH_AI_ContextSetThreadNum(context, 2);
    
  3. 加载编译模型

    OH_AI_ModelHandle model = OH_AI_ModelCreate();
    OH_AI_ModelBuildFromFile(model, model_path, OH_AI_kMS, context);
    
  4. 准备输入数据

    OH_AI_TensorHandle input_tensor = OH_AI_ModelGetInput(model, 0);
    void *input_data = OH_AI_TensorGetMutableData(input_tensor);
    // 填充输入数据
    memcpy(input_data, image_data, image_size);
    
  5. 执行推理

    OH_AI_ModelPredict(model, inputs, outputs, nullptr);
    
  6. 获取输出结果

    OH_AI_TensorHandle output_tensor = OH_AI_ModelGetOutput(model, 0);
    float *output_data = reinterpret_cast<float*>(OH_AI_TensorGetMutableData(output_tensor));
    // 处理输出结果
    
  7. 释放资源

    OH_AI_ModelDestroy(&model);
    OH_AI_ContextDestroy(&context);
    

模型训练指南

端侧训练场景介绍

MindSpore Lite不仅支持模型推理,还支持在端侧设备上进行模型训练,适用于:

  • 联邦学习
  • 个性化模型微调
  • 增量学习

核心接口说明

训练上下文接口
// 创建训练上下文
OH_AI_ContextHandle context = OH_AI_ContextCreate();
OH_AI_ContextSetDeviceType(context, OH_AI_kDT_CPU);
OH_AI_ContextSetThreadNum(context, 2);
// 设置训练模式
OH_AI_ContextSetTrainMode(context, true);
设备信息接口
// 获取设备信息
OH_AI_DeviceInfoHandle device_info = OH_AI_DeviceInfoCreate();
OH_AI_DeviceInfoSetProvider(device_info, "CPU");
OH_AI_ContextSetDeviceInfo(context, device_info);
训练配置接口
// 创建训练配置
OH_AI_TrainCfgHandle train_cfg = OH_AI_TrainCfgCreate();
// 设置学习率
OH_AI_TrainCfgSetLearningRate(train_cfg, 0.01f);
// 设置优化器类型
OH_AI_TrainCfgSetOptimizerType(train_cfg, OH_AI_kSGD);
模型操作接口
// 设置训练模式
OH_AI_ModelSetTrainMode(model, true);
// 执行前向传播
OH_AI_ModelForward(model, inputs, outputs);
// 执行反向传播
OH_AI_ModelBackward(model, outputs);
// 更新权重
OH_AI_ModelUpdateWeights(model);

开发步骤

  1. 模型准备

    • 获取支持训练的.ms模型文件
    • 准备训练数据和标签
  2. 创建训练上下文

    OH_AI_ContextHandle context = OH_AI_ContextCreate();
    OH_AI_ContextSetDeviceType(context, OH_AI_kDT_CPU);
    OH_AI_ContextSetThreadNum(context, 2);
    OH_AI_ContextSetTrainMode(context, true);
    
  3. 编译训练模型

    OH_AI_ModelHandle model = OH_AI_ModelCreate();
    OH_AI_ModelBuildFromFile(model, model_path, OH_AI_kMS, context);
    OH_AI_ModelSetTrainMode(model, true);
    
  4. 准备训练数据

    // 准备输入数据
    OH_AI_TensorHandle input_tensor = OH_AI_ModelGetInput(model, 0);
    void *input_data = OH_AI_TensorGetMutableData(input_tensor);
    memcpy(input_data, train_data, data_size);
    
    // 准备标签数据
    OH_AI_TensorHandle label_tensor = OH_AI_ModelGetInputByIndex(model, 1);
    void *label_data = OH_AI_TensorGetMutableData(label_tensor);
    memcpy(label_data, train_labels, label_size);
    
  5. 执行训练

    // 训练循环
    for (int epoch = 0; epoch < epochs; epoch++) {
        for (int batch = 0; batch < batches; batch++) {
            // 前向传播
            OH_AI_ModelForward(model, inputs, outputs);
            
            // 计算损失
            OH_AI_ModelCalculateLoss(model, outputs, labels);
            
            // 反向传播
            OH_AI_ModelBackward(model, outputs);
            
            // 更新权重
            OH_AI_ModelUpdateWeights(model);
        }
    }
    
  6. 模型导出

    // 导出训练后的模型
    OH_AI_ModelExport(model, "trained_model.ms", OH_AI_kMS);
    
  7. 释放资源

    OH_AI_ModelDestroy(&model);
    OH_AI_ContextDestroy(&context);
    

基于ArkTS的图像分类实现

场景说明

基于ArkTS的图像分类广泛应用于:

  • 医学影像分析
  • 自动驾驶
  • 智能安防
  • 工业质检

基本概念

  • 张量:多维数组,是模型输入输出的基本数据结构
  • Float16推理模式:使用半精度浮点数进行推理,可减少内存占用

接口说明

loadModelFromFile接口
import mindspore from '@ohos.mindspore';

// 从文件加载模型
async function loadModelFromFile(modelPath: string): Promise<mindspore.Model> {
  return await mindspore.load(modelPath);
}
predict接口
// 执行推理
async function predict(model: mindspore.Model, input: mindspore.Tensor): Promise<mindspore.Tensor[]> {
  return await model.predict(input);
}

开发流程

  1. 选择模型:根据应用场景选择合适的图像分类模型
  2. 端侧推理:使用MindSpore Lite在设备上执行推理

开发步骤

  1. 模型选择与转换

    • 选择适合的预训练模型(如MobileNet、ResNet等)
    • 使用MindSpore Lite转换工具将模型转换为.ms格式
  2. 图像输入预处理

    // 图像预处理函数
    function preprocessImage(imageData: ArrayBuffer): Float32Array {
      // 调整图像大小
      const resizedImage = resizeImage(imageData, 224, 224);
      // 归一化
      const normalizedImage = normalizeImage(resizedImage);
      // 转换为Float32Array
      return new Float32Array(normalizedImage);
    }
    
  3. 推理代码编写

    import mindspore from '@ohos.mindspore';
    
    // 图像分类函数
    async function classifyImage(imagePath: string): Promise<string> {
      // 加载模型
      const model = await mindspore.load('models/mobilenet.ms');
      
      // 预处理图像
      const imageData = await readImageFile(imagePath);
      const inputTensor = preprocessImage(imageData);
      
      // 执行推理
      const output = await model.predict(inputTensor);
      
      // 后处理输出
      const result = postprocessOutput(output);
      
      return result;
    }
    
  4. 结果输出

    // 后处理函数
    function postprocessOutput(output: mindspore.Tensor[]): string {
      const scores = output[0].getData() as Float32Array;
      const maxScore = Math.max(...scores);
      const maxIndex = scores.indexOf(maxScore);
      
      // 根据索引获取类别标签
      const label = classLabels[maxIndex];
      
      return `${label}: ${(maxScore * 100).toFixed(2)}%`;
    }
    

基于Native的图像分类实现

场景说明

基于Native的图像分类实现适用于需要更高性能控制的场景,如:

  • 实时图像处理
  • 批量图像分类
  • 自定义图像预处理

基本概念

  • N-API:Node.js API,用于实现C/C++与JavaScript之间的互操作

开发流程

  1. 选择模型:根据应用场景选择合适的图像分类模型
  2. 端侧推理:使用MindSpore Lite Native API在设备上执行推理

开发步骤

  1. 模型选择

    • 选择适合的预训练模型(如MobileNet、ResNet等)
    • 使用MindSpore Lite转换工具将模型转换为.ms格式
  2. 图像输入预处理

    // 图像预处理函数
    std::vector<float> preprocessImage(const uint8_t* imageData, int width, int height) {
      // 调整图像大小
      auto resizedImage = resizeImage(imageData, width, height, 224, 224);
      
      // 归一化
      std::vector<float> normalizedImage;
      for (int i = 0; i < resizedImage.size(); i++) {
        normalizedImage.push_back(resizedImage[i] / 255.0f);
      }
      
      return normalizedImage;
    }
    
  3. 推理代码编写

    // 图像分类函数
    extern "C" napi_value ClassifyImage(napi_env env, napi_callback_info info) {
      // 获取参数
      size_t argc = 2;
      napi_value args[2];
      napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
      
      // 获取图像路径
      size_t str_size;
      napi_get_value_string_utf8(env, args[0], nullptr, 0, &str_size);
      char* modelPath = new char[str_size + 1];
      napi_get_value_string_utf8(env, args[0], modelPath, str_size + 1, &str_size);
      
      // 加载模型
      OH_AI_ModelHandle model = OH_AI_ModelCreate();
      OH_AI_ContextHandle context = OH_AI_ContextCreate();
      OH_AI_ContextSetDeviceType(context, OH_AI_kDT_CPU);
      OH_AI_ModelBuildFromFile(model, modelPath, OH_AI_kMS, context);
      
      // 预处理图像
      auto imageData = readImageFile(modelPath);
      auto inputTensor = preprocessImage(imageData.data(), imageData.width(), imageData.height());
      
      // 设置输入
      OH_AI_TensorHandle input = OH_AI_ModelGetInput(model, 0);
      void *inputData = OH_AI_TensorGetMutableData(input);
      memcpy(inputData, inputTensor.data(), inputTensor.size() * sizeof(float));
      
      // 执行推理
      OH_AI_ModelPredict(model, &input, &output, nullptr);
      
      // 获取输出
      OH_AI_TensorHandle outputTensor = OH_AI_ModelGetOutput(model, 0);
      float* outputData = reinterpret_cast<float*>(OH_AI_TensorGetMutableData(outputTensor));
      
      // 后处理输出
      auto result = postprocessOutput(outputData);
      
      // 创建返回值
      napi_value resultStr;
      napi_create_string_utf8(env, result.c_str(), result.length(), &resultStr);
      
      // 释放资源
      OH_AI_ModelDestroy(&model);
      OH_AI_ContextDestroy(&context);
      delete[] modelPath;
      
      return resultStr;
    }
    
  4. CMake脚本编写

    cmake_minimum_required(VERSION 3.5.0)
    project(ImageClassification)
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
    
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
    
    add_library(entry SHARED image_classification.cpp)
    target_link_libraries(entry PUBLIC mindspore_lite_ndk)
    target_link_libraries(entry PUBLIC hilog_ndk.z)
    target_link_libraries(entry PUBLIC rawfile.z)
    target_link_libraries(entry PUBLIC ace_napi.z)
    
  5. N-API封装ArkTS模块

    // 定义导出函数
    static napi_value Init(napi_env env, napi_value exports) {
      napi_property_descriptor desc[] = {
        {"classifyImage", nullptr, ClassifyImage, nullptr, nullptr, nullptr, napi_default, nullptr}
      };
      napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
      return exports;
    }
    
    // 注册模块
    NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
    
  6. 调用推理并输出结果

    // Index.ets
    import imageClassifier from 'libentry.so';
    
    @Entry
    @Component
    struct Index {
      @State result: string = '';
      
      build() {
        Row() {
          Column() {
            Button('选择图像')
              .onClick(() => {
                // 选择图像文件
                const imagePicker = new ImagePicker();
                imagePicker.select().then((uri) => {
                  // 调用C++函数进行分类
                  this.result = imageClassifier.classifyImage(uri);
                });
              })
            
            if (this.result) {
              Text(`分类结果: ${this.result}`)
                .fontSize(20)
                .margin({ top: 20 })
            }
          }
        }
      }
    }
    

基于Native的语音识别实现

场景说明

基于Native的语音识别实现广泛应用于:

  • 智能语音助手
  • 语音转文字
  • 语音命令控制
  • 实时翻译

开发流程

  1. 选择模型:根据应用场景选择合适的语音识别模型
  2. 端侧推理:使用MindSpore Lite Native API在设备上执行推理

开发步骤

  1. 模型选择

    • 选择适合的语音识别模型(如Whisper、DeepSpeech等)
    • 使用MindSpore Lite转换工具将模型转换为.ms格式
    • 常用模型包括:
      • tiny-encoder.ms:音频编码模型
      • tiny-decoder-main.ms:主解码模型
      • tiny-decoder-loop.ms:循环解码模型
  2. 音频播放ArkTS代码

    // 播放音频文件
    import { media } from '@kit.MediaKitKit';
    import { fileIo } from '@kit.CoreFileKit';
    
    export class AVPlayerDemo {
      private avPlayer: media.AVPlayer | undefined = undefined;
      
      async avPlayerFdSrcDemo() {
        // 创建AVPlayer实例
        this.avPlayer = await media.createAVPlayer();
        
        // 设置状态监听
        this.setAVPlayerCallback();
        
        // 初始化播放
        this.avPlayer.state = 'initialized';
        
        // 准备播放
        this.avPlayer.prepare();
      }
      
      setAVPlayerCallback() {
        this.avPlayer?.on('stateChange', (state) => {
          console.info(`MS_LITE_LOG: AVPlayer state ${state} called.`);
        });
        
        this.avPlayer?.on('error', (err) => {
          console.error(`MS_LITE_LOG: AVPlayer error: ${err.message}`);
        });
      }
    }
    
  3. 音频识别C++代码

    // 音频识别函数
    extern "C" napi_value RecognizeAudio(napi_env env, napi_callback_info info) {
      // 获取资源管理器
      napi_value args[1];
      size_t argc = 1;
      napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
      
      // 读取音频文件
      auto resourcesManager = GetResourceManager(env, args[0]);
      auto audioFile = ReadAudioFile(resourcesManager, "zh.wav");
      
      // 音频预处理
      std::vector<uint8_t> data = audioFile.getData();
      ResampleAudio(data, audioFile.getSampleRate(), WHISPER_SAMPLE_RATE, 1, SRC_SINC_BEST_QUALITY);
      std::vector<float> audio(data.begin(), data.end());
      
      // 添加填充
      int padding = 480000;
      audio.insert(audio.end(), padding, 0.0f);
      
      // 提取梅尔频谱特征
      int sr = 16000;
      int n_fft = 480;
      int n_hop = 160;
      int n_mel = 80;
      int fmin = 0;
      int fmax = sr / 2.0;
      
      std::vector<std::vector<float>> mels_T = librosa::Feature::melspectrogram(
        audio, sr, n_fft, n_hop, "hann", true, "reflect", 2.f, n_mel, fmin, fmax);
      
      std::vector<std::vector<float>> mels = TransposeMel(mels_T);
      ProcessMelSpectrogram(mels);
      
      // 转换为一维数组
      std::vector<float> inputMels(mels.size() * mels[0].size(), 0);
      for (int i = 0; i < mels.size(); i++) {
        std::copy(mels[i].begin(), mels[i].end(), inputMels.begin() + i * mels[0].size());
      }
      
      BinBuffer inputMelsBin(inputMels.data(), inputMels.size() * sizeof(float));
      
      // tiny-encoder.ms模型推理
      auto encoderBin = ReadBinFile(resourcesManager, "tiny-encoder.ms");
      auto encoder = CreateMSLiteModel(encoderBin);
      
      int ret = RunMSLiteModel(encoder, {inputMelsBin});
      if (ret != OH_AI_STATUS_SUCCESS) {
        OH_AI_ModelDestroy(&encoder);
        return error_ret;
      }
      
      auto outputs = OH_AI_ModelGetOutputs(encoder);
      auto n_layer_cross_k = GetMSOutput(outputs.handle_list[0]);
      auto n_layer_cross_v = GetMSOutput(outputs.handle_list[1]);
      
      // tiny-decoder-main.ms模型推理
      std::vector<int> SOT_SEQUENCE = {WHISPER_SOT, WHISPER_SOT + 1 + 1, 
                                       WHISPER_TRANSCRIBE, WHISPER_NO_TIMESTAMPS};
      BinBuffer sotSequence(SOT_SEQUENCE.data(), SOT_SEQUENCE.size() * sizeof(int));
      
      auto decoderMainBin = ReadBinFile(resourcesManager, "tiny-decoder-main.ms");
      auto decoder_main = CreateMSLiteModel(decoderMainBin);
      int ret2 = RunMSLiteModel(decoder_main, {sotSequence, n_layer_cross_k, n_layer_cross_v});
      
      if (ret2 != OH_AI_STATUS_SUCCESS) {
        OH_AI_ModelDestroy(&decoder_main);
        OH_AI_ModelDestroy(&encoder);
        return error_ret;
      }
      
      auto decoderMainOut = OH_AI_ModelGetOutputs(decoder_main);
      auto logitsBin = GetMSOutput(decoderMainOut.handle_list[0]);
      auto out_n_layer_self_k_cache_Bin = GetMSOutput(decoderMainOut.handle_list[1]);
      auto out_n_layer_self_v_cache_Bin = GetMSOutput(decoderMainOut.handle_list[2]);
      
      // tiny-decoder-loop.ms模型推理
      auto modelBuffer3 = ReadBinFile(resourcesManager, "tiny-decoder-loop.ms");
      auto decoder_loop = CreateMSLiteModel(modelBuffer3);
      
      auto data_embedding = ReadBinFile(resourcesManager, "tiny-positional_embedding.bin");
      
      int loop_times = WHISPER_N_TEXT_CTX - SOT_SEQUENCE.size();
      int offset_init = SOT_SEQUENCE.size();
      auto output_tokens = LoopPredict(decoder_loop, n_layer_cross_k, n_layer_cross_v, 
                                      logitsBin, out_n_layer_self_k_cache_Bin,
                                      out_n_layer_self_v_cache_Bin, data_embedding, 
                                      loop_times, offset_init);
      
      // 解码输出
      std::vector<std::string> token_tables = ProcessDataLines(ReadTokens(resourcesManager, "tiny-tokens.txt"));
      std::string result;
      for (const auto i : output_tokens) {
        char str[1024];
        base64_decode((const uint8 *)token_tables[i].c_str(), (uint32)token_tables[i].size(), str);
        result += str;
      }
      
      // 释放资源
      OH_AI_ModelDestroy(&encoder);
      OH_AI_ModelDestroy(&decoder_main);
      OH_AI_ModelDestroy(&decoder_loop);
      
      // 创建返回值
      napi_value out_data;
      napi_create_string_utf8(env, result.c_str(), result.length(), &out_data);
      return out_data;
    }
    
  4. CMake脚本编写

    cmake_minimum_required(VERSION 3.5.0)
    project(ASR)
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
    
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
    
    # libsamplerate
    set(LIBSAMPLERATE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libsamplerate)
    include_directories(${LIBSAMPLERATE_DIR}/include)
    add_subdirectory(${LIBSAMPLERATE_DIR})
    
    file(GLOB SRC src/*.cc)
    
    add_library(entry SHARED mslite_napi.cpp ${SRC})
    target_link_libraries(entry PUBLIC samplerate)
    target_link_libraries(entry PUBLIC mindspore_lite_ndk)
    target_link_libraries(entry PUBLIC hilog_ndk.z)
    target_link_libraries(entry PUBLIC rawfile.z)
    target_link_libraries(entry PUBLIC ace_napi.z)
    
  5. N-API封装ArkTS模块

    // 定义导出函数
    static napi_value Init(napi_env env, napi_value exports) {
      napi_property_descriptor desc[] = {
        {"recognizeAudio", nullptr, RecognizeAudio, nullptr, nullptr, nullptr, napi_default, nullptr}
      };
      napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
      return exports;
    }
    
    // 注册模块
    NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
    
  6. 调用封装的ArkTS模块进行推理并输出结果

    // Index.ets
    import msliteNapi from 'libentry.so';
    import AVPlayerDemo from './player';
    
    @Entry
    @Component
    struct Index {
      @State message: string = 'MSLite Whisper Demo';
      @State wavName: string = 'zh.wav';
      @State content: string = '';
      
      build() {
        Row() {
          Column() {
            Text(this.message)
              .fontSize(30)
              .fontWeight(FontWeight.Bold);
              
            Button() {
              Text('播放示例音频')
                .fontSize(20)
                .fontWeight(FontWeight.Medium)
            }
            .type(ButtonType.Capsule)
            .margin({ top: 20 })
            .backgroundColor('#0D9FFB')
            .width('40%')
            .height('5%')
            .onClick(async () =>{
              // 播放音频
              let myClass = new AVPlayerDemo();
              myClass.avPlayerFdSrcDemo();
            })
              
            Button() {
              Text('识别示例音频')
                .fontSize(20)
                .fontWeight(FontWeight.Medium)
            }
            .type(ButtonType.Capsule)
            .margin({ top: 20 })
            .backgroundColor('#0D9FFB')
            .width('40%')
            .height('5%')
            .onClick(() => {
              let resMgr = this.getUIContext()?.getHostContext()?.getApplicationContext().resourceManager;
              
              // 调用封装的recognizeAudio函数
              console.info('MS_LITE_LOG: *** Start MSLite Demo ***');
              let output = msliteNapi.recognizeAudio(resMgr);
              console.info('MS_LITE_LOG: output length = ', output.length, ';value = ', output.slice(0, 20));
              this.content = output;
              console.info('MS_LITE_LOG: *** Finished MSLite Demo ***');
            })
            
            // 显示识别内容
            if (this.content) {
              Text('识别内容: \n' + this.content + '\n')
                .focusable(true)
                .fontSize(20)
                .height('20%')
            }
          }.width('100%')
        }
        .height('100%')
      }
    }
    

应用场景与价值

典型应用场景

  1. 智能移动设备

    • 智能手机和平板上的AI应用
    • 实时图像处理和识别
    • 语音助手和语音转文字
  2. 物联网设备

    • 智能家居控制
    • 工业物联网监测
    • 智能穿戴设备
  3. 汽车电子

    • 驾驶辅助系统
    • 车内语音控制
    • 驾驶行为分析
  4. 医疗健康

    • 医学影像分析
    • 健康监测设备
    • 便携式诊断工具

总结

MindSpore Lite作为一款轻量级深度学习推理框架,为端侧AI应用开发提供了强大的支持。通过本文档的介绍,我们了解了MindSpore Lite的核心功能、使用方法和应用场景,包括模型转换、推理、训练以及基于ArkTS和Native接口的应用开发。

MindSpore Lite的主要优势在于其轻量化设计、高性能推理和丰富的API接口,使得开发者能够轻松地在端侧设备上部署和运行深度学习模型。随着端侧AI应用的不断发展,MindSpore Lite将在更多领域发挥重要作用,推动人工智能技术的普及和应用。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐