示例代码
您可以从样例介绍中获取完整样例代码。
调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝运行,仅供参考。
基本原理
模型加载成功、模型输入和输出数据结构准备好之后,还需将输入数据传输到模型输入数据结构的对应内存中,用于模型执行。
模型执行结束后,若无需使用输入数据、aclmdlDesc类型、aclmdlDataset类型、aclDataBuffer类型等相关资源,需及时释放内存、销毁对应的数据类型,防止内存异常。模型可能存在多个输入、多个输出,每个输入/输出的内存地址、内存大小用aclDataBuffer类型的数据来描述,针对每个输入/输出,需调用acl.destroy_data_buffer接口销毁相应的aclDataBuffer类型,并调用acl.rt.free接口释放内存中的数据。
示例代码(执行模型)
ACL_MEMCPY_HOST_TO_DEVICE = 1 ACL_MEMCPY_DEVICE_TO_HOST = 2 NPY_BYTE = 1 images_list = ["./data/dog1_1024_683.jpg", "./data/dog2_1024_683.jpg"] for image in images_list: # 1.自定义函数transfer_pic,使用Python库读取图片文件,并对图片进行缩放、剪裁等操作。 # transfer_pic函数的实现请参考样例中源代码。 img = transfer_pic(image) # 2.准备模型推理的输入数据,运行模式默认为运行模式为ACL_HOST,当前实例代码中模型只有一个输入。 bytes_data = img.tobytes() np_ptr = acl.util.bytes_to_ptr(bytes_data) # 将图片数据从Host传输到Device。 ret = acl.rt.memcpy(self.input_data[0]["buffer"], self.input_data[0]["size"], np_ptr, self.input_data[0]["size"], ACL_MEMCPY_HOST_TO_DEVICE) # 3.执行模型推理。 # self.model_id表示模型ID,在模型加载成功后,会返回标识模型的ID。 ret = acl.mdl.execute(self.model_id, self.load_input_dataset, self.load_output_dataset) # ......
示例代码(准备模型的输入和输出数据结构)
# 初始化变量。 ACL_MEM_MALLOC_HUGE_FIRST = 0 # 1.根据模型的ID,获取该模型的描述信息。 # self.model_desc为aclmdlDesc类型。 self.model_desc = acl.mdl.create_desc() ret = acl.mdl.get_desc(self.model_desc, self.model_id) # 2.准备模型推理的输入数据集。 # 创建aclmdlDataset类型的数据,描述模型推理的输入。 self.load_input_dataset = acl.mdl.create_dataset() # 获取模型输入的数量。 input_size = acl.mdl.get_num_inputs(self.model_desc) self.input_data = [] # 循环为每个输入申请内存,并将每个输入添加到aclmdlDataset类型的数据中。 for i in range(input_size): buffer_size = acl.mdl.get_input_size_by_index(self.model_desc, i) # 申请输入内存。 buffer, ret = acl.rt.malloc(buffer_size, ACL_MEM_MALLOC_HUGE_FIRST) data = acl.create_data_buffer(buffer, buffer_size) _, ret = acl.mdl.add_dataset_buffer(self.load_input_dataset, data) self.input_data.append({"buffer": buffer, "size": buffer_size}) # 3.准备模型推理的输出数据集。 # 创建aclmdlDataset类型的数据,描述模型推理的输出。 self.load_output_dataset = acl.mdl.create_dataset() # 获取模型输出的数量。 output_size = acl.mdl.get_num_outputs(self.model_desc) self.output_data = [] # 循环为每个输出申请内存,并将每个输出添加到aclmdlDataset类型的数据中。 for i in range(output_size): buffer_size = acl.mdl.get_output_size_by_index(self.model_desc, i) # 申请输出内存。 buffer, ret = acl.rt.malloc(buffer_size, ACL_MEM_MALLOC_HUGE_FIRST) data = acl.create_data_buffer(buffer, buffer_size) _, ret = acl.mdl.add_dataset_buffer(self.load_output_dataset, data) self.output_data.append({"buffer": buffer, "size": buffer_size}) # ......
示例代码(处理推理结果:直接处理内存中的数据)
以图片分类网络为例,模型执行结束后,需处理每一张图片的模型推理结果,直接输出top5置信度的类别编号。
# 处理模型推理的输出数据,输出top5置信度的类别编号。 inference_result = [] for i, item in enumerate(self.output_data): buffer_host, ret = acl.rt.malloc_host(self.output_data[i]["size"]) # 将推理输出数据从Device传输到Host。 ret = acl.rt.memcpy(buffer_host, self.output_data[i]["size"], self.output_data[i]["buffer"], self.output_data[i]["size"], ACL_MEMCPY_DEVICE_TO_HOST) bytes_out = acl.util.ptr_to_bytes(buffer_host, self.output_data[i]["size"]) data = np.frombuffer(bytes_out, dtype=np.byte) inference_result.append(data) tuple_st = struct.unpack("1000f", bytearray(inference_result[0])) vals = np.array(tuple_st).flatten() top_k = vals.argsort()[-1:-6:-1] print("======== top5 inference results: =============") for j in top_k: print("[%d]: %f" % (j, vals[j])) # ......
示例代码(释放模型的输入、输出资源)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 释放模型推理的输入、输出资源。 # 释放输入资源,包括数据结构和内存。 while self.input_data: item = self.input_data.pop() ret = acl.rt.free(item["buffer"]) input_number = acl.mdl.get_dataset_num_buffers(self.load_input_dataset) for i in range(input_number): data_buf = acl.mdl.get_dataset_buffer(self.load_input_dataset, i) if data_buf: ret = acl.destroy_data_buffer(data_buf) ret = acl.mdl.destroy_dataset(self.load_input_dataset) # 释放输出资源,包括数据结构和内存。 while self.output_data: item = self.output_data.pop() ret = acl.rt.free(item["buffer"]) output_number = acl.mdl.get_dataset_num_buffers(self.load_output_dataset) for i in range(output_number): data_buf = acl.mdl.get_dataset_buffer(self.load_output_dataset, i) if data_buf: ret = acl.destroy_data_buffer(data_buf) ret = acl.mdl.destroy_dataset(self.load_output_dataset) |
父主题: 模型执行