体验Java极简并发推理Demo
概述
本教程提供了MindSpore Lite执行并发推理的示例程序,通过随机输入、执行推理、打印推理结果的方式,演示了利用MindSpore Lite Java API进行端侧并发推理的基本流程,用户能够快速了解MindSpore Lite执行并发推理相关Java API的使用。本教程通过随机生成的数据作为输入数据,执行MobileNetV2模型的推理,打印获得输出数据。相关代码放置在mindspore/lite/examples/quick_start_server_inference_java目录。
使用MindSpore Lite 推理主要包括以下步骤:
模型加载:从文件系统中读取由模型转换工具转换得到的
.ms
模型。创建配置选项:创建配置选项RunnerConfig,保存并发推理所需的一些基本配置参数,用于指导并发量以及图编译和图执行。主要包括MSContext:配置上下文、
WorkersNum
:并发模型数量。初始化:在执行并发推理前,需要调用ModelParallelRunner的init接口进行并发推理的初始化,主要进行模型读取,创建并发,以及子图切分、算子选型调度。这部分会耗费较多时间,所以建议init初始化一次,多次执行并发推理。
输入数据:图执行之前需要向输入Tensor中填充数据。
执行推理:使用ModelParallelRunner的predict进行并发推理。
获得输出:图执行结束之后,可以通过输出Tensor得到推理结果。
释放内存:无需使用MindSpore Lite推理框架的时候,需要释放已创建的ModelParallelRunner。
构建与运行
环境要求
编译构建
在
mindspore/lite/examples/quick_start_server_inference_java
目录下执行build脚本,将自动下载MindSpore Lite推理框架库以及文模型文件并编译Demo。bash build.sh
若MindSpore Lite推理框架下载失败,请手动下载硬件平台为CPU、操作系统为Ubuntu-x64的MindSpore Lite 框架mindspore-lite-{version}-linux-x64.tar.gz,解压后将
runtime/lib
以及runtime/third_party
目录下的所有so和jar拷贝到mindspore/lite/examples/quick_start_server_inference_java/lib
目录。若MobileNetV2模型下载失败,请手动下载相关模型文件mobilenetv2.ms,并将其拷贝到
mindspore/lite/examples/quick_start_server_inference_java/model/
目录。通过手动下载并且将文件放到指定位置后,需要再次执行build.sh脚本才能完成编译构建。
执行推理
编译构建后,进入
mindspore/lite/examples/quick_start_server_inference_java/target
目录,并执行以下命令,体验MindSpore Lite推理MobileNetV2模型。export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:../lib/ java -Djava.library.path=../lib/ -classpath .:./quick_start_server_inference_java.jar:../lib/mindspore-lite-java.jar com.mindspore.lite.demo.Main ../model/mobilenetv2.ms
执行完成后将能得到如下结果:
========== model parallel runner predict success ==========
初始化
模型编译主要包括创建配置上下文、编译等步骤。
private static ModelParallelRunner runner;
private static List<MSTensor> inputs;
private static List<MSTensor> outputs;
// use default param init context
MSContext context = new MSContext();
context.init(1,0);
boolean ret = context.addDeviceInfo(DeviceType.DT_CPU, false, 0);
if (!ret) {
System.err.println("init context failed");
context.free();
return ;
}
// init runner config
RunnerConfig config = new RunnerConfig();
config.init(context);
config.setWorkersNum(2);
// init ModelParallelRunner
ModelParallelRunner runner = new ModelParallelRunner();
ret = runner.init(modelPath, config);
if (!ret) {
System.err.println("ModelParallelRunner init failed.");
runner.free();
return;
}
模型推理
模型推理主要包括输入数据、执行推理、获得输出等步骤,其中本示例中的输入数据是通过随机数据构造生成,最后将执行推理后的输出结果打印出来。
// init input tensor
inputs = new ArrayList<>();
MSTensor input = runner.getInputs().get(0);
if (input.getDataType() != DataType.kNumberTypeFloat32) {
System.err.println("Input tensor data type is not float, the data type is " + input.getDataType());
return;
}
// Generator Random Data.
int elementNums = input.elementsNum();
float[] randomData = generateArray(elementNums);
ByteBuffer inputData = floatArrayToByteBuffer(randomData);
// create input MSTensor
MSTensor inputTensor = MSTensor.createTensor(input.tensorName(), DataType.kNumberTypeFloat32,input.getShape(), inputData);
inputs.add(inputTensor);
// init output
outputs = new ArrayList<>();
// runner do predict
ret = runner.predict(inputs,outputs);
if (!ret) {
System.err.println("MindSpore Lite predict failed.");
freeTensor();
runner.free();
return;
}
System.out.println("========== model parallel runner predict success ==========");
内存释放
无需使用MindSpore Lite推理框架时,需要释放已经创建的model
。
private static void freeTensor(){
for (int i = 0; i < inputs.size(); i++) {
inputs.get(i).free();
}
for (int i = 0; i < outputs.size(); i++) {
outputs.get(i).free();
}
}
freeTensor();
runner.free();