跳到主要内容

编译运行

模型推理

功能介绍

使用mxVision模型推理功能通过给定输入和指定模型,进行推理获得输出结果,支持om格式的模型推理,可使用ATC工具构建的动态Batch、动态分辨率和分档动态维度模型进行推理。

接口调用流程

使用模型推理前,用户需准备好输入数据以及需要加载的模型,根据模型路径或者内存方式初始化Model类,通过调用Model类的Infer接口获取模型推理结果。输入数据必须和模型输入数据类型以及格式一致,如果用户自行申请输出数据内存,则输出数据类型和格式需和模型输出保持一致,模型输入输出信息可以通过Model类的相关接口进行查询。

模型推理调用流程参考如下:

关键接口说明如下:

  1. 调用MxInit()接口进行全局初始化。

  2. 模型初始化。

    用户需根据实际业务情况确认模型加载方式,选择从文件加载模型从内存加载模型。如果从内存加载,需要先将模型文件读取到内存,可通过以下两种方式传入。

    • 从文件加载模型,可选择直接向Model接口传入模型路径,进行初始化。
    • 通过结构体ModelLoadOptV2中的“loadType”字段指定加载方式后,再传入Model接口,其中加载方式在模型方面区分从文件加载模型,还是从内存加载模型,在内存方面区分是由系统内部管理,还是由用户管理,具体可参见ModelLoadOptV2
  3. 调用MxDeInit()接口对初始化的全局资源进行去初始化。

示例代码

以下为功能特性关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。

// 初始化
MxBase::MxInit();
{
// 输入二进制数据, 需用户自行准备
std::string filePath = "./test.bin";
// 读取输入数据到内存
void* dataPtr = ReadTensor(filePath);
// 输入数据类型,和模型输入数据类型一致
auto dataType = MxBase::TensorDType::INT32;
// 构造输入shape,和模型输入shape一致
std::vector<uint32_t> shape = &#123;1, 128&#125;;
// 构造tensor
MxBase::Tensor tensor(dataPtr, shape, dataType, 0);
// 构造模型输入
std::vector<MxBase::Tensor> inputs&#123;tensor&#125;;
// 模型路径,需用户自行指定
std::string modelPath = "./test.om";
// 根据模型路径加载模型
MxBase::Model model(modelPath);
// 执行模型推理, outputs即为推理结果
std::vector<MxBase::Tensor> outputs = model.Infer(inputs);
&#125;
//去初始化
MxBase::MxDeInit();

根据结构体ModelLoadOptV2方式初始化示例参考如下:

MxBase::ModelLoadOptV2 mdlLoadOpt;
mdlLoadOpt.loadType = ModelLoadOptV2::LOAD_MODEL_FROM_FILE; // 指定模型加载方式
mdlLoadOpt.modelPath = modelPath;
MxBase::Model model(mdlLoadOpt);

父主题: 使用API接口方式开发(C++)

异步调用

功能介绍

mxVision默认采用同步执行模式,部分接口已支持用户通过申请AscendStream异步执行,具体接口异步支持情况请参见API参考(C++)

接口调用流程

  • 用户通过自定义AscendStream类构造需要的Stream实例传入异步接口,通过接口传入并在指定Stream上执行,同一Stream串行指定接口任务后可通过调用Synchronize()接口阻塞应用程序或线程运行,直到该Stream中的所有任务全部完成。
  • 支持多Stream异步执行,每个Stream内接口顺序执行,如果用户使用多Stream异步执行或异步执行结果需传入不支持异步接口情况,需要用户可选择执行Synchronize()接口,在适当位置执行同步Stream操作,保证结果已正确返回供后续使用。
  • 对于异步调用进行媒体数据处理时,需要调用Synchronize()接口使异步任务完成才能及时归还使用的通道,避免资源池被耗尽。

图1 Stream异步模式接口调用流程(以Resize操作为例)

mxVision提供AscendStream类进行Stream管理,关键步骤说明如下:

  1. 调用MxInit()接口进行全局初始化。

  2. 初始化Stream。

    用户通过向构造函数传入“deviceId”指定要创建Stream的设备,支持的“deviceId”根据用户环境存在差异。

  3. 创建Stream。

  4. 调用异步接口。

    • 支持异步的接口传入指定Stream,同一Stream中接口按顺序串行执行。
    • 指定不同Stream的接口之间并行执行。
  5. 同步Stream。

    如需保证异步执行结果在作为下一个接口入参时已执行完成,可调用Synchronize()成员函数显式同步Stream。

  6. 销毁Stream。

    用户在业务流程完成或Stream结束时,需调用DestroyAscendStream()成员函数销毁Stream,否则可能会造成Stream耗尽情况。

  7. 调用MxDeInit()接口对初始化的全局资源进行去初始化。

示例代码

以图像异步缩放和yoloV3模型异步推理为例,提供关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。

// 初始化
MxBase::MxInit();
&#123;
// 用户创建目标deviceId的stream
AscendStream stream(deviceId)
stream.CreatAscendStream();
// 创建图像解码类实例
ImageProcessor imageProcessor(deviceId);
// 解码后的Image类实例
Image decodedImage;
// 根据图像路径进行解码
APP_ERROR ret = imageProcessor.Decode(imagePath, decodedImage);
// 缩放后的图像类实例
Image resizedImage;
// 异步调用缩放接口
ret = imageProcessor.Resize(decodedImage, Size(416, 416), resizedImage, Interpolation::HUAWEI_HIGH_ORDER_FILTER, stream);
// 调用同步接口,可以显式保证调用后续接口时缩放已完成
stream.Synchronize();
// 将 Image 类转换为 Tensor 类
Tensor tensorImg = resizedImage.ConvertToTensor();
// yoloV3模型推理
string yoloPath = "./model/yolov3_tf_bs1_fp16.om";
Model yoloV3(yoloPath, deviceId);
// 构造推理输入输出 (单batch)
vector<Tensor> yoloV3Inputs = &#123;tensorImg&#125;;
vector<Tensor> yoloV3Outputs = &#123;&#125;;
// 开始异步推理
ret = yoloV3.Infer(yoloV3Inputs, yoloV3Outputs,stream);
// 调用同步接口,可以显式保证调用后续接口时缩放已完成
// 用户也可选择同步前在该stream串行其他异步接口
stream.Synchronize();
// 调用DestroyAscendStream销毁stream
stream.DestroyAscendStream();
&#125;
//去初始化
MxBase::MxDeInit();

父主题: 使用API接口方式开发(C++)

编译运行

运行样例前,需设置mxVison环境变量。

source &#123;mxVison安装目录&#125;/mxVision/set_env.sh

编译

  1. 文件准备,用户准备好自己的源码文件“main.cpp”,以及“CMakeLists.txt”文件,“CMakeLists.txt”编写可参考如下内容:

    # CMake lowest version requirement
    cmake_minimum_required(VERSION 3.5.2)
    # project information
    project(MindX_SDK_Sample)
    set(MX_SDK_HOME $ENV&#123;MX_SDK_HOME&#125;)
    if (NOT DEFINED ENV&#123;MX_SDK_HOME&#125;)
    string(REGEX REPLACE "(.*)/(.*)/(.*)/(.*)" "\\1" MX_SDK_HOME $&#123;CMAKE_CURRENT_SOURCE_DIR&#125;)
    message(STATUS "set default MX_SDK_HOME: $&#123;MX_SDK_HOME&#125;")
    else ()
    message(STATUS "env MX_SDK_HOME: $&#123;MX_SDK_HOME&#125;")
    endif()
    # Compile options
    add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
    add_definitions(-Dgoogle=mindxsdk_private)
    add_compile_options(-std=c++11 -fPIC -fstack-protector-all -Wall)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $&#123;CMAKE_CURRENT_SOURCE_DIR&#125;)
    set(CMAKE_CXX_FLAGS_DEBUG "-g")
    set(CMAKE_EXE_LINKER_FLAGS "$&#123;CMAKE_EXE_LINKER_FLAGS&#125; -Wl,-z,relro,-z,now,-z,noexecstack -s -pie")
    set(CMAKE_SKIP_RPATH TRUE)

    # add mxbase header path
    include_directories(
    $&#123;MX_SDK_HOME&#125;/include/
    $&#123;MX_SDK_HOME&#125;/opensource/include/
    )

    # add mxbase lib path
    link_directories(
    $&#123;MX_SDK_HOME&#125;/lib/
    $&#123;MX_SDK_HOME&#125;/lib/modelpostprocessors/
    $&#123;MX_SDK_HOME&#125;/opensource/lib/
    $&#123;MX_SDK_HOME&#125;/opensource/lib64/
    )
    add_executable(main main.cpp)
    target_link_libraries(main glog mxbase opencv_world cpprest pthread mindxsdk_protobuf)
    install(TARGETS main DESTINATION $&#123;CMAKE_RUNTIME_OUTPUT_DIRECTORY&#125;)
  2. CMake编译。

    1. 在“CMakeLists.txt”文件所在目录新建“build”目录。

      mkdir build
    2. 进入“build”目录。

      cd build
    3. 执行cmake命令。

      cmake ..
    4. 执行make命令生成可执行文件“main”。

      make -j

运行

执行编译生成的可执行文件即可运行程序。

./main

:::note 说明

父主题: 使用API接口方式开发(C++)

开发流程

流程介绍

图1 API开发流程

关键步骤说明

  1. 使用mxVision接口进行应用开发,需首先进行初始化才能进行后续处理,具体请参见初始化
  2. 媒体数据处理/模型推理。
    1. 媒体数据处理功能,可实现图像编解码、抠图、缩放、补边等操作,具体请参见媒体数据处理
    2. 模型推理,可实现如目标识别,图像分类等应用,环节可参考以下几个步骤,具体请参见模型推理
      1. 模型推理前,需准备合适的om模型。
      2. 模型加载,将准备好的模型通过文件或内存方式加载到系统中,具体请参见模型推理
      3. (可选)媒体数据处理,模型推理前,可对输入的媒体数据进行处理,如图片解码、抠图、缩放、补边等操作。
      4. 模型执行,使用模型实现图片分类、目标识别等功能。
      5. (可选)模型后处理,对模型推理输出的数据进行后处理操作,此处根据用户的实际需求来处理推理结果,如整理为可理解阅读的具体结果。模型后处理支持通过两种方式进行:
        • (推荐)自行选择模型后处理方式。
        • 通过调用mxVision接口进行,具体操作请参见模型后处理

父主题: 使用API接口方式开发(Python)

初始化

功能介绍

mxVision应用开发初始化接口,在代码调用相关接口之前,需调用全局初始化函数mx_init()申请设备资源和日志资源。

示例代码

以下为初始化方法的代码示例,不可以直接拷贝运行,仅供参考。

全局初始化,加载设备资源和日志资源。

from mindx.sdk import base
base.mx_init()
## 执行全局初始化后即可正常调用mxVision接口

父主题: 使用API接口方式开发(Python)

图片解码

功能介绍

通过对输入图片数据进行解码处理,将本地图片转换为Image类,用于后续前处理和推理业务,类型目前支持JPEG和PNG格式。

接口调用流程

用户需准备好本地待解码的图片文件,初始化ImageProcessor类,通过调用ImageProcessor类的decode接口解码返回输出的Image对象。

图片解码调用流程参考如下:

图1 图片解码接口调用流程

关键步骤说明如下:

  1. 调用mx_init()接口进行全局初始化。

  2. ImageProcessor初始化。

    用户构造ImageProcessor对象,构造时需用户指定设备ID。

  3. 调用decode接口对图片进行解码。

    用户需根据解码的不同需要,传入对应格式参数到decode接口。

示例代码

以下为功能特性关键步骤的代码示例,不可以直接拷贝运行,仅供参考。

from mindx.sdk import base
from mindx.sdk.base import ImageProcessor, Image
## 图像解码
## 初始化ImageProcessor对象
imageProcessor = ImageProcessor(device_id)
image_path = "test_image.jpg"
## 读取图片路径进行解码,解码格式为nv12(YUV_SP_420)
decoded_image = imageProcessor.decode(image_path, base.nv12)

父主题: 媒体数据处理

在线提单