体验MindSpore Lite C++极简Demo
Linux
Windows
X86
C++
全流程
推理应用
数据准备
初级
概述
本教程提供了MindSpore Lite执行推理的示例程序,通过随机输入、执行推理、打印推理结果的方式,演示了C++进行端侧推理的基本流程,用户能够快速了解MindSpore Lite执行推理相关API的使用。本教程通过随机生成的数据作为输入数据,执行MobileNetV2模型的推理,打印获得输出数据。相关代码放置在mindspore/lite/examples/quick_start_cpp目录。
使用MindSpore Lite执行推理主要包括以下步骤:
模型加载:从文件系统中读取由模型转换工具转换得到的
.ms
模型,通过mindspore::lite::Model::Import导入模型,进行模型解析,创建得到Model *
。创建配置上下文:创建配置上下文Context,保存会话所需的一些基本配置参数,用于指导图编译和图执行。
创建会话:创建LiteSession会话,并将上一步得到的Context配置到会话中。
图编译:执行推理之前,需要调用LiteSession的
CompileGraph
接口进行图编译。图编译阶段主要进行子图切分、算子选型调度等过程,该阶段会耗费较多时间,所以建议LiteSession创建一次,编译一次,多次推理。输入数据:图执行之前需要向
输入Tensor
中填充数据。执行推理:使用LiteSession的
RunGraph
进行模型推理。获得输出:图执行结束之后,可以通过
输出Tensor
得到推理结果。释放内存:无需使用MindSpore Lite推理框架时,需要释放已创建的LiteSession和Model。
如需查看MindSpore Lite高级用法,请参考使用Runtime执行推理(C++)。
构建与运行
Linux X86
环境要求
编译构建
在
mindspore/lite/examples/quick_start_cpp
目录下执行build脚本,将自动下载MindSpore Lite推理框架库以及文模型文件并编译Demo。bash build.sh
若使用该build脚本下载MindSpore Lite推理框架失败,请手动下载硬件平台为CPU、操作系统为Ubuntu-x64的MindSpore Lite 模型推理框架mindspore-lite-{version}-linux-x64.tar.gz,将解压后
inference/lib
目录下的libmindspore-lite.a
文件拷贝到mindspore/lite/examples/quick_start_cpp/lib
目录、inference/include
目录里的文件拷贝到mindspore/lite/examples/quick_start_cpp/include
目录下。若MobileNetV2模型下载失败,请手动下载相关模型文件mobilenetv2.ms,并将其拷贝到
mindspore/lite/examples/quick_start_cpp/model
目录。通过手动下载并且将文件放到指定位置后,需要再次执行build.sh脚本才能完成编译构建。
执行推理
编译构建后,进入
mindspore/lite/examples/quick_start_cpp/build
目录,并执行以下命令,体验MindSpore Lite推理MobileNetV2模型。./mindspore_quick_start_cpp ../model/mobilenetv2.ms
执行完成后将能得到如下结果,打印输出Tensor的名称、输出Tensor的大小,输出Tensor的数量以及前50个数据:
tensor name is:Default/head-MobileNetV2Head/Softmax-op204 tensor size is:4000 tensor elements num is:1000 output data is:5.26823e-05 0.00049752 0.000296722 0.000377607 0.000177048 8.02107e-05 0.000212864 0.000422286 0.000273189 0.000234105 0.00099807 0.0042331 0.00204993 0.00124968 0.00294458 0.00139795 0.00111545 0.000656357 0.000809457 0.00153731 0.000621049 0.00224637 0.00127045 0.00187557 0.000420144 0.000150638 0.000266477 0.000438628 0.000187773 0.00054668 0.000212853 0.000921661 0.000127179 0.000565873 0.00100394 0.000300159 0.000282677 0.000358067 0.00215288 0.000477845 0.00107596 0.00065134 0.000722132 0.000807501 0.000631415 0.00043247 0.00125898 0.000255094 8.2606e-05 9.91917e-05 0.000794512
Windows
环境要求
编译构建
库下载:请手动下载硬件平台为CPU、操作系统为Windows-x64的MindSpore Lite模型推理框架mindspore-lite-{version}-win-x64.zip,将解压后
inference/lib
目录下的libmindspore-lite.a
拷贝到mindspore/lite/examples/quick_start_cpp/lib
工程目录、inference/include
目录里的文件拷贝到mindspore/lite/examples/quick_start_cpp/include
工程目录下。(注意:工程项目下的lib
、include
目录需手工创建)模型下载:请手动下载相关模型文件mobilenetv2.ms,并将其拷贝到
mindspore/lite/examples/quick_start_cpp/model
目录。编译:在
mindspore/lite/examples/quick_start_cpp
目录下执行build脚本,将能够自动下载相关文件并编译Demo。
call build.bat
执行推理
编译构建后,进入
mindspore/lite/examples/quick_start_cpp/build
目录,并执行以下命令,体验MindSpore Lite推理MobileNetV2模型。call mindspore_quick_start_cpp.exe ../model/mobilenetv2.ms
执行完成后将能得到如下结果,打印输出Tensor的名称、输出Tensor的大小,输出Tensor的数量以及前50个数据:
tensor name is:Default/head-MobileNetV2Head/Softmax-op204 tensor size is:4000 tensor elements num is:1000 output data is:5.26823e-05 0.00049752 0.000296722 0.000377607 0.000177048 8.02107e-05 0.000212864 0.000422286 0.000273189 0.000234105 0.00099807 0.0042331 0.00204993 0.00124968 0.00294458 0.00139795 0.00111545 0.000656357 0.000809457 0.00153731 0.000621049 0.00224637 0.00127045 0.00187557 0.000420144 0.000150638 0.000266477 0.000438628 0.000187773 0.00054668 0.000212853 0.000921661 0.000127179 0.000565873 0.00100394 0.000300159 0.000282677 0.000358067 0.00215288 0.000477845 0.00107596 0.00065134 0.000722132 0.000807501 0.000631415 0.00043247 0.00125898 0.000255094 8.2606e-05 9.91917e-05 0.000794512
配置CMake
以下是通过CMake集成libmindspore-lite.a
静态库时的示例代码。
集成
libmindspore-lite.a
静态库时需要将-Wl,--whole-archive
的选项传递给链接器。由于在编译MindSpore Lite的时候增加了
-fstack-protector-strong
栈保护的编译选项,所以在Windows平台上还需要链接MinGW中的ssp
库。
cmake_minimum_required(VERSION 3.14)
project(QuickStartCpp)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3.0)
message(FATAL_ERROR "GCC version ${CMAKE_CXX_COMPILER_VERSION} must not be less than 7.3.0")
endif()
# Add directory to include search path
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# Add directory to link search path
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
file(GLOB_RECURSE QUICK_START_CXX ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
add_executable(mindspore_quick_start_cpp ${QUICK_START_CXX})
target_link_libraries(
mindspore_quick_start_cpp
-Wl,--whole-archive mindspore-lite -Wl,--no-whole-archive
pthread
)
# Due to the increased compilation options for stack protection,
# it is necessary to target link ssp library when Use the static library in Windows.
if(WIN32)
target_link_libraries(
mindspore_quick_start_cpp
ssp
)
endif()
模型加载
模型加载需要从文件系统中读取MindSpore Lite模型,并通过mindspore::lite::Model::Import
函数导入模型进行解析。
// Read model file.
size_t size = 0;
char *model_buf = ReadFile(model_path, &size);
if (model_buf == nullptr) {
std::cerr << "Read model file failed." << std::endl;
return -1;
}
// Load the .ms model.
auto model = mindspore::lite::Model::Import(model_buf, size);
delete[](model_buf);
if (model == nullptr) {
std::cerr << "Import model file failed." << std::endl;
return -1;
}
模型编译
模型编译主要包括创建配置上下文、创建会话、图编译等步骤。
mindspore::session::LiteSession *Compile(mindspore::lite::Model *model) {
// Create and init context.
auto context = std::make_shared<mindspore::lite::Context>();
if (context == nullptr) {
std::cerr << "New context failed while." << std::endl;
return nullptr;
}
// Create the session.
mindspore::session::LiteSession *session = mindspore::session::LiteSession::CreateSession(context.get());
if (session == nullptr) {
std::cerr << "CreateSession failed while running." << std::endl;
return nullptr;
}
// Compile graph.
auto ret = session->CompileGraph(model);
if (ret != mindspore::lite::RET_OK) {
delete session;
std::cerr << "Compile failed while running." << std::endl;
return nullptr;
}
// Note: when use model->Free(), the model can not be compiled again.
if (model != nullptr) {
model->Free();
}
return session;
}
模型推理
模型推理主要包括输入数据、执行推理、获得输出等步骤,其中本示例中的输入数据是通过随机数据构造生成,最后将执行推理后的输出结果打印出来。
int Run(mindspore::session::LiteSession *session) {
auto inputs = session->GetInputs();
// Generate random data as input data.
auto ret = GenerateInputDataWithRandom(inputs);
if (ret != mindspore::lite::RET_OK) {
std::cerr << "Generate Random Input Data failed." << std::endl;
return ret;
}
// Run Inference.
ret = session->RunGraph();
if (ret != mindspore::lite::RET_OK) {
std::cerr << "Inference error " << ret << std::endl;
return ret;
}
// Get Output Tensor Data.
auto out_tensors = session->GetOutputs();
for (auto tensor : out_tensors) {
std::cout << "tensor name is:" << tensor.first << " tensor size is:" << tensor.second->Size()
<< " tensor elements num is:" << tensor.second->ElementsNum() << std::endl;
auto out_data = reinterpret_cast<float *>(tensor.second->MutableData());
std::cout << "output data is:";
for (int i = 0; i < tensor.second->ElementsNum() && i <= 50; i++) {
std::cout << out_data[i] << " ";
}
std::cout << std::endl;
}
return mindspore::lite::RET_OK;
}
内存释放
无需使用MindSpore Lite推理框架时,需要释放已经创建的LiteSession
和Model
。
// Delete model buffer.
delete model;
// Delete session buffer.
delete session;