HarmonyOS鸿蒙Next中修改官方MindSporeLiteArkTS示例,从CPU运行改为NPU运行时model.getInputs()返回undefined

HarmonyOS鸿蒙Next中修改官方MindSporeLiteArkTS示例,从CPU运行改为NPU运行时model.getInputs()返回undefined

在将官方提供的 MindSpore Lite 示例代码修改为在 Mate70 NPU 设备上运行时,遇到问题。原始代码在 CPU 上运行没有问题,但当切换到 NPU 设备时,调用 msLiteModel.getInputs() 返回 undefined

官方例子: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/mindspore-guidelines-based-js

修改后的代码:

let msLiteModel: mindSporeLite.Model = await mindSporeLite.loadModelFromBuffer(modelBuffer, context);
let modelInputs: mindSporeLite.MSTensor[] = msLiteModel.getInputs();  // 在 NPU 上返回 undefined
for (let i = 0; i < inputsBuffer.length; i++) {
 let inputBuffer = inputsBuffer[i];
 if (inputBuffer != null) {
   modelInputs[i].setData(inputBuffer as ArrayBuffer);
 }
}

问题出现在调用 getInputs() 后,返回 undefined,这阻止了我们设置模型的输入数据。该问题仅在 NPU 上出现,且原始代码在 CPU 上运行时没有任何问题。

环境:

  • HarmonyOS SDK API 版本:15 (5.0.4.135)
  • 设备:Mate70(NPU)
  • 模型:MindSpore Lite 模型(从缓冲区加载)
  • 设置:目标为 NPU(context.target = ['nnrt']),设备 ID 通过 context.nnrt.deviceID 配置。

预期行为: 即使在 NPU 设备上运行,getInputs() 方法应该返回模型的输入张量,从而允许正确设置输入数据。

修改后的完整代码 (src/main/ets/pages/Index.ets):

import { mindSporeLite } from '@kit.MindSporeLiteKit'
import Logger from '../common/utils/Logger';

export default async function modelPredict(
 modelBuffer: ArrayBuffer, inputsBuffer: ArrayBuffer[]): Promise<mindSporeLite.MSTensor[]> {

 let context: mindSporeLite.Context = {};

 // 获取所有设备信息
 let allDevices = mindSporeLite.getAllNNRTDeviceDescriptions();
 for (let i: number = 0; i < allDevices.length; i++) {
   console.info("Predictor", `device id = ${allDevices[i].deviceID().toString()}`);
   console.info("Predictor", `device type = ${allDevices[i].deviceType().toString()}`);
 }

 // 设置目标为 NPU 设备
 context.target = ['nnrt'];
 context.nnrt = {};
 context.nnrt.deviceID = allDevices[0].deviceID(); // 选择第一个 NPU 设备

 // 加载模型
 let msLiteModel: mindSporeLite.Model = await mindSporeLite.loadModelFromBuffer(modelBuffer, context);

 // 获取模型输入
 let modelInputs: mindSporeLite.MSTensor[] = msLiteModel.getInputs(); // 在 NPU 上返回 undefined

 // 如果 modelInputs 为 undefined,说明获取输入失败
 if (!modelInputs) {
   Logger.error('无法获取模型输入张量。');
   return [];
 }

 // 设置输入数据
 for (let i = 0; i < inputsBuffer.length; i++) {
   let inputBuffer = inputsBuffer[i];
   if (inputBuffer != null) {
     modelInputs[i].setData(inputBuffer as ArrayBuffer);
   }
 }

 Logger.info('=========MS_LITE_LOG: MS_LITE predict start=====');

 // 执行推理
 let modelOutputs: mindSporeLite.MSTensor[] = await msLiteModel.predict(modelInputs);

 return modelOutputs;
}

更多关于HarmonyOS鸿蒙Next中修改官方MindSporeLiteArkTS示例,从CPU运行改为NPU运行时model.getInputs()返回undefined的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

使用的是例子里的mobilenetv2.ms模型

更多关于HarmonyOS鸿蒙Next中修改官方MindSporeLiteArkTS示例,从CPU运行改为NPU运行时model.getInputs()返回undefined的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用MindSporeLite的ArkTS示例时,若将运行设备从CPU改为NPU后,model.getInputs()返回undefined,可能是由于NPU设备不支持该模型的输入格式或模型未正确加载。需检查模型是否已针对NPU进行优化,并确保模型文件与NPU兼容。

这是一个典型的NPU设备兼容性问题。在HarmonyOS Next中,当使用NPU设备时,需要特别注意以下几点:

  1. 模型兼容性检查:NPU对模型格式有特定要求,建议先确认模型是否已正确转换为NPU支持的格式。可以通过MindSpore Lite工具检查模型是否包含NPU算子。

  2. 上下文初始化顺序:在设置NPU上下文时,建议先初始化nnrt配置再设置target:

context.nnrt = {
  deviceID: allDevices[0].deviceID(),
  // 其他NPU特定参数
};
context.target = ['nnrt'];
  1. 错误处理增强:在loadModelFromBuffer后立即检查模型状态:
if (!msLiteModel || msLiteModel.getModelStatus() !== mindSporeLite.ModelStatus.SUCCESS) {
  Logger.error('模型加载失败');
  return [];
}
  1. NPU设备特性:某些NPU设备可能要求显式调用prepare方法后才能获取输入输出:
await msLiteModel.prepare();
let modelInputs = msLiteModel.getInputs();

建议先在CPU环境下验证模型能正常获取输入输出,再切换到NPU环境。如果问题依旧,可能需要检查模型是否包含NPU不支持的算子。

回到顶部