Ascend310处理器上推理MindIR模型
本文介绍如何在Ascend310处理器中推理MindIR模型。Ascend环境配置可参考Ascend安装指南,完整推理代码可参考ascend310_resnet50_preprocess_sample。
推理代码介绍
推理部分使用了CPU算子来进行数据的预处理,然后完成推理。整体代码存放在main.cc
文件中,现在对其中的功能实现进行说明。
引用mindspore
和mindspore::dataset
的名字空间。
namespace ms = mindspore;
namespace ds = mindspore::dataset;
环境初始化,指定硬件为Ascend 310,DeviceID为0:
auto context = std::make_shared<ms::Context>();
auto ascend310_info = std::make_shared<ms::Ascend310DeviceInfo>();
ascend310_info->SetDeviceID(0);
context->MutableDeviceInfo().push_back(ascend310_info);
加载模型文件:
// 加载MindIR模型
ms::Graph graph;
ms::Status ret = ms::Serialization::Load(resnet_file, ms::ModelType::kMindIR, &graph);
// 图编译
ms::Model resnet50;
ret = resnet50.Build(ms::GraphCell(graph), context);
获取模型所需输入信息:
std::vector<ms::MSTensor> model_inputs = resnet50.GetInputs();
加载图片文件:
ms::MSTensor ReadFile(const std::string &file);
auto image = ReadFile(image_file);
图片预处理(使用CPU算子):
// 对图片进行解码,变为RGB格式,并重设尺寸
std::shared_ptr<ds::TensorTransform> decode(new ds::vision::Decode());
std::shared_ptr<ds::TensorTransform> resize(new ds::vision::Resize({256}));
// 输入归一化
std::shared_ptr<ds::TensorTransform> normalize(new ds::vision::Normalize(
{0.485 * 255, 0.456 * 255, 0.406 * 255}, {0.229 * 255, 0.224 * 255, 0.225 * 255}));
// 剪裁图片
std::shared_ptr<ds::TensorTransform> center_crop(new ds::vision::CenterCrop({224, 224}));
// shape (H, W, C) 变为 shape (C, H, W)
std::shared_ptr<ds::TensorTransform> hwc2chw(new ds::vision::HWC2CHW());
// 定义preprocessor
ds::Execute preprocessor({decode, resize, normalize, center_crop, hwc2chw});
// 调用函数,获取处理后的图像
ret = preprocessor(image, &image);
执行推理:
// 创建输入输出向量
std::vector<ms::MSTensor> outputs;
std::vector<ms::MSTensor> inputs;
inputs.emplace_back(model_inputs[0].Name(), model_inputs[0].DataType(), model_inputs[0].Shape(),
image.Data().get(), image.DataSize());
// 执行推理
ret = resnet50.Predict(inputs, &outputs);
获取推理结果:
// 获取推理结果的最大概率
std::cout << "Image: " << image_file << " infer result: " << GetMax(outputs[0]) << std::endl;
构建脚本介绍
构建脚本用于构建用户程序,完整代码位于CMakeLists.txt
,下面进行解释说明。
为编译器添加头文件搜索路径:
option(MINDSPORE_PATH "mindspore install path" "")
include_directories(${MINDSPORE_PATH})
include_directories(${MINDSPORE_PATH}/include)
在MindSpore中查找所需动态库:
find_library(MS_LIB libmindspore.so ${MINDSPORE_PATH}/lib)
file(GLOB_RECURSE MD_LIB ${MINDSPORE_PATH}/_c_dataengine*)
使用指定的源文件生成目标可执行文件,并为目标文件链接MindSpore库:
add_executable(resnet50_sample main.cc)
target_link_libraries(resnet50_sample ${MS_LIB} ${MD_LIB})
编译并执行推理代码
若运行完整推理代码ascend310_resnet50_preprocess_sample,可将实验的脚本下载至Ascend310环境中编译并执行。
创建并进入工程目录ascend310_resnet50_preprocess_sample
,执行cmake
命令,其中pip3
需要按照实际情况修改:
cmake . -DMINDSPORE_PATH=`pip3 show mindspore-ascend | grep Location | awk '{print $2"/mindspore"}' | xargs realpath`
再执行make
命令编译即可。
make
编译成功后,会获得resnet50_sample
可执行文件。在工程目录ascend310_resnet50_preprocess_sample
下创建model
目录放置MindIR文件resnet50_imagenet.mindir。此外,创建test_data
目录用于存放待分类的图片,图片可来自ImageNet等各类开源数据集,输入执行命令即可获取推理结果:
./resnet50_sample