文档
注册

快速入门

在本章节中,您可以通过各功能点介绍以及关键接口代码示例了解使用pyACL接口(Python语言接口)开发应用的基本过程以及开发过程中涉及的关键概念。

开发场景

开发图片分类应用,对2张分辨率为1024*683的*.jpg图片分类。若想直接运行该样例,请参见基于Caffe ResNet-50网络实现图片分类(同步推理)

该场景涉及以下功能点,关键代码请参见关键代码开发

功能点

功能简介

接口调用流程

pyACL初始化与去初始化

使用pyACL接口开发应用时,必须先初始化,否则可能会导致后续系统内部资源初始化出错,进而导致其它业务异常。

有初始化就有去初始化,在确定完成了pyACL的所有调用之后,或者进程退出之前,需调用接口实现pyACL去初始化。

功能接口调用流程及示例请参见pyACL初始化与去初始化

运行管理资源申请与释放

您需要按顺序依次申请如下资源:Device、Context、Stream,确保可以使用这些资源执行运算、管理任务。

所有数据处理都结束后,需要释放运行管理资源,包括Stream、Context、Device。释放资源时,需要对应顺序释放:Stream,Context,Device。

Stream、Context、Device资源的介绍请参见表1

功能接口调用流程及示例请参见运行管理资源申请与释放

  • 调用acl.rt.set_device接口指定用于运算的Device。
  • 调用acl.rt.get_run_mode接口获取昇腾AI软件栈的运行模式,根据运行模式的不同,内部处理流程不同。
  • 调用acl.rt.reset_device接口复位当前运算的Device,回收Device上的资源。

内存申请与释放

调用pyACL提供的接口申请或释放内存。

数据传输

通过内存复制的方式实现数据传输。

功能接口调用流程及示例请参见数据传输

如果在Host上运行应用,则需调用acl.rt.memcpy接口:

  • 将数据从Host传输到Device上,作为解码的输入数据。
  • 模型推理结束后,将推理结果从Device传输到Host。

如果在板端环境上运行应用,则无需进行数据传输。

模型推理

本文介绍的场景是图片分类,因此需要选取开源的分类网络,此处选择的是Caffe ResNet-50网络,将开源的ResNet-50网络转换为适配昇腾AI处理器的离线模型(*.om文件),使用该离线模型推理图片所属的类别。

ResNet-50网络对输入图片宽高的要求为224*224,且要求输入图片格式为RGB。但当前输入图片是*.jpg格式,因此下文的样例中使用Python库对图片进行预处理。

接口调用流程及示例请参见模型推理基本场景

数据后处理

提供样例代码,处理模型推理的结果,直接在终端上显示top5置信度的类别编号。

关键代码开发

即使您不理解所有细节也没关系,此处仅仅是关键步骤的代码示例,不可以直接拷贝运行,仅供参考,旨在帮助您快速了解整体的代码逻辑。若想获取该样例的完整代码,请参见应用样例参考

  1. 导入acl模块。
    1
    import acl
    
  2. pyACL初始化。
    1
    ret = acl.init()
    
  3. 运行管理资源申请。
    1
    2
    3
    4
    5
    6
    7
    self.device_id = 0
    
    # 指定运算的Device。
    ret = acl.rt.set_device(self.device_id)
    
    # 显式创建一个Context,用于管理Stream对象。
    self.context, ret = acl.rt.create_context(self.device_id)
    
  4. 加载模型,并获取模型描述信息。
    在模型加载前,需要将第三方网络(例如,Caffe ResNet-50网络)转换为适配昇腾AI处理器的离线模型(*.om文件),请参见ATC工具使用指南
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 初始化变量。
    self.model_path = './model/resnet50.om'
    
    # 加载离线模型文件,返回标识模型的ID。
    self.model_id, ret = acl.mdl.load_from_file(self.model_path)
    
    # 根据加载成功的模型的ID,获取该模型的描述信息。
    self.model_desc = acl.mdl.create_desc()
    ret = acl.mdl.get_desc(self.model_desc, self.model_id)
    
  5. 准备模型推理的输入、输出数据结构。
     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
    # 初始化变量。
    ACL_MEM_MALLOC_HUGE_FIRST = 0
    
    # 1.准备模型推理的输入数据集。
    # 创建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})
    
    # 2.准备模型推理的输出数据集。
    # 创建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})
    
  6. 准备模型推理的输入数据,并进行推理。
     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
    60
    61
    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)
            
        # 4.处理模型推理的输出数据,输出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]))
        
    # 5.释放模型推理的输入、输出资源。
    # 释放输入资源,包括数据结构和内存。
    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)
    
  7. 卸载模型,并释放模型描述信息。
    1
    2
    3
    4
    5
    6
    7
    # 卸载模型。
    ret = acl.mdl.unload(self.model_id)
    
    # 释放模型描述信息。
    if self.model_desc:
        ret = acl.mdl.destroy_desc(self.model_desc)
        self.model_desc = None
    
  8. 运行管理资源释放。
    1
    2
    3
    4
    5
    6
    7
    # 释放Context。
    if self.context:
        ret = acl.rt.destroy_context(self.context)
        self.context = None
    
    # 释放Device。
    ret = acl.rt.reset_device(self.device_id)
    
  9. pyACL去初始化。
    1
    ret = acl.finalize()
    
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词