更新时间:2021-03-18 GMT+08:00
分享

模型推理资源申请

基本原理

在模型推理前,需要从离线模型文件(适配昇腾AI处理器的离线模型)中加载模型数据到内存中。

  • 关于模型转换

    在模型加载前,需要将第三方网络(例如,Caffe ResNet-50网络)转换为适配昇腾AI处理器的离线模型,请参见ATC工具使用指导中的使用ATC工具转换模型

    若涉及色域转换(转换图像格式),在模型转换时,还需参见ATC工具使用指导中的AIPP配置进行配置。

  • 关于获取模型占用的内存大小

    当由用户管理内存时,为确保内存不浪费,在申请工作内存、权值内存前,需要调用aclmdlQuerySize接口查询模型运行时所需工作内存、权值内存的大小。

  • 关于模型加载
    加载模型数据分为以下4种方式:
    • aclmdlLoadFromFile:从文件加载离线模型数据,由系统内部管理内存。
    • aclmdlLoadFromMem:从内存加载离线模型数据,由系统内部管理内存。
    • aclmdlLoadFromFileWithMem:从文件加载离线模型数据,由用户自行管理模型运行的内存(包括工作内存和权值内存)。
    • aclmdlLoadFromMemWithMem:从内存加载离线模型数据,由用户自行管理模型运行的内存(包括工作内存和权值内存)。
  • 关于模型的输入、输出数据

    aclmdlDataset主要用于描述模型推理时的输入数据/输出数据,模型可能存在多个输入/多个输出,每个输入/输出的内存地址、内存大小用aclDataBuffer类型的数据来描述。

示例代码

示例代码如下,调用接口后,需增加异常处理的分支,同时通过ERROR_LOG记录报错日志、通过INFO_LOG记录各动作的提示日志,示例代码中不一一列举。

示例代码如下,您可以从acl_dvpp_resnet50样例的“src/sample_process.cpp”“src/model_process.cpp”文件中查看完整样例代码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "acl/acl.h"
//......
//1.初始化变量。
//此处的..表示相对路径,相对可执行文件所在的目录
//例如,编译出来的可执行文件存放在out目录下,此处的..就表示out目录的上一级目录
const char* omModelPath = "../model/resnet50_aipp.om";
//......

//2.根据模型文件获取模型执行时所需的权值内存大小、工作内存大小。
aclError ret = aclmdlQuerySize(omModelPath, &modelMemSize_, &modelWeightSize_);

//3.根据2中的工作内存大小,申请Device上模型执行的工作内存。
ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_NORMAL_ONLY);

//4.根据2中的权值内存的大小,申请Device上模型执行的权值内存。
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_NORMAL_ONLY);

//5.加载离线模型文件(适配昇腾AI处理器的离线模型),由用户自行管理模型运行的内存(包括权值内存、工作内存)。
//模型加载成功,返回标识模型的ID。
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_,
        modelMemSize_, modelWeightPtr_, modelWeightSize_);

//6.根据5中加载成功的模型的ID,获取该模型的描述信息。
//modelDesc_为aclmdlDesc类型。
modelDesc_ = aclmdlCreateDesc();
ret = aclmdlGetDesc(modelDesc_, modelId_);

//7.创建aclmdlDataset类型的数据,描述模型推理的输出。
//output_为aclmdlDataset类型
output_ = aclmdlCreateDataset();

//7.1 获取模型的输出个数.
size_t outputSize = aclmdlGetNumOutputs(modelDesc_);

//7.2 循环为每个输出申请内存,并将每个输出添加到aclmdlDataset类型的数据中.
for (size_t i = 0; i < outputSize; ++i) {
    size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i);
    void *outputBuffer = nullptr;
    aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);
    aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size);   
    ret = aclmdlAddDatasetBuffer(output_, outputData);
    }
//......
分享:

    相关文档

    相关产品

close