下载
中文
注册

多Batch模型推理

多Batch推理的基本流程与单Batch类似,请参见模型推理

多Batch推理与单Batch推理的不同点在于:

  • 多Batch场景下,在构建模型时,使用ATC工具的input_shape参数需根据实际的Batch数设置batch size值,详细说明请参见ATC工具使用指南
  • 在推理前,需要编写一段代码,实现逻辑为:等输入数据满足多Batch(例如:8Batch)的要求,申请Device上的内存存放多Batch的数据,作为模型推理的输入。如果最后循环遍历所有的输入数据后,仍不满足多Batch的要求,则直接将剩余数据作为模型推理的输入。
调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考,此处以8Batch为例:
 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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
uint32_t batchSize = 8;
uint32_t deviceNum = 1;
uint32_t deviceId = 0;

// 获取模型第一个输入的大小
uint32_t modelInputSize = aclmdlGetInputSizeByIndex(modelDesc, 0);
// 获取每个Batch输入数据的大小
uint32_t singleBuffSize = modelInputSize / batchSize;

// 定义该变量,用于累加batch size是否达到8Batch
uint32_t cnt = 0;
// 定义该变量,用于描述每个文件读入内存时的位置偏移
uint32_t pos = 0;

void* p_batchDst = NULL;
std::vector<std::string>inferFile_vec;

for (int i = 0; i < files.size(); ++i) 
        {
            // 每8个文件,申请一次Device上的内存,存放8Batch的输入数据 
            if (cnt % batchSize == 0)
            {
                pos = 0;
                inferFile_vec.clear();
                // 申请Device上的内存
                aclrtMalloc(&p_batchDst, modelInputSize, ACL_MEM_MALLOC_HUGE_FIRST);
            }

            // TODO: 从某个目录下读入文件,计算文件大小fileSize
            
            // 根据文件大小,申请内存,存放文件数据
            aclrtMallocHost(&p_imgBuf, fileSize);

            // 将数据传输到Device的内存
            aclrtMemcpy((uint8_t *)p_batchDst + pos, fileSize, p_imgBuf, fileSize, ACL_MEMCPY_HOST_TO_DEVICE);
            pos += fileSize;
            // 及时释放不使用的内存
            aclrtFreeHost(p_imgBuf);

            // 将第i个文件存入vector中,同时cnt+1
            inferFile_vec.push_back(files[i]);
            cnt++;

            // 每8Batch的输入数据送给模型推理进行推理
            if (cnt % batchSize == 0)
            {
                // TODO: 创建aclmdlDataset、aclDataBuffer类型的数据,用于描述模型的输入、输出数据
                // TODO: 调用aclmdlExecute接口执行模型推理
                // TODO: 推理结束后,调用aclrtFree接口释放Device上的内存
            }
        }

// 如果最后循环遍历所有的输入数据后,仍不满足多Batch的要求,则直接将剩余数据作为模型推理的输入。
if (cnt % batchSize != 0)
    {
            // TODO: 创建aclmdlDataset、aclDataBuffer类型的数据,用于描述模型的输入、输出数据
            // TODO: 调用aclmdlExecute接口执行模型推理
            // TODO: 推理结束后,调用aclrtFree接口释放Device上的内存
    }