在前面的文章里,我们已经手动完成了环境准备和跑通了一个原生的ACLHelloWorld。你可能已经发现了,虽然跑通了很有成就感,但每次都要写一堆aclInitaclrtCreateContextaclrtCreateStream这样的“八股文”代码,还是挺繁琐的。

如果只是初始化还好,但凡涉及到模型推理、图片视频处理,那代码量和复杂度就直线上升了。官方显然也意识到了这个问题,所以提供了一个名叫AclLite的封装库,目的就是把这些重复、繁琐的操作打包好,让我们能更专注于业务逻辑本身。

这篇文章,我们就来好好聊聊AclLite到底是什么,它能干嘛,以及怎么用。

1. AclLite是什么?为什么需要它?

简单来说,AclLite是昇腾官方提供的一套C++和Python的二次封装库。它位于我们应用代码和原生AscendCL(ACL)接口之间,像一个得力的助手,帮我们打理好了很多杂活。

你可以把它想象成一个“装修施工队”。我们(开发者)是业主,只想实现“客厅要个大屏幕看电影”(模型推理)、“厨房要能快速洗菜切菜”(图像处理)这样的最终效果。我们不想去关心电线怎么走(资源初始化)、水管怎么接(Stream管理)、水泥怎么和(内存对齐)。AclLite就是这个施工队,它把这些底层的、标准化的脏活累活都包了,我们只需要给它下指令就行。

名词解释:

  • 二次封装:就是在已有的接口(这里指ACL接口)基础上,再包一层,提供更简单、更高级的接口。好比手机厂商基于安卓系统做了自己的UI,虽然内核还是安卓,但用起来更方便了。
  • AscendCL (ACL):昇腾计算架构下的应用层API,是我们在应用软件里调用昇腾硬件计算能力的“官方语言”。我们之前用的aclInitaclrtSetDevice都属于这个范畴。

没有AclLite的时候,我们的代码长这样(回顾一下ACLHelloWorld):

// 各种头文件
#include "acl/acl.h"

int main() {
    // 1. 初始化ACL
    aclInit(nullptr);
    // 2. 指定设备
    aclrtSetDevice(0);
    // 3. 创建上下文
    aclrtContext context;
    aclrtCreateContext(&context, 0);
    // 4. 创建Stream
    aclrtStream stream;
    aclrtCreateStream(&stream);

    // --- 这里才是你的业务逻辑 ---

    // 5. 销毁Stream
    aclrtDestroyStream(stream);
    // 6. 销毁上下文
    aclrtDestroyContext(context);
    // 7. 重置设备
    aclrtResetDevice(0);
    // 8. 去初始化ACL
    aclFinalize();
    return 0;
}

有了AclLite之后,上面这一大堆初始化和收尾工作,可能就变成下面这样(以C++为例):

#include "AclLiteResource.h"

int main() {
    // 一句话完成所有初始化
    AclLiteResource aclResource;
    aclResource.Init();

    // --- 这里写你的业务逻辑 ---

    // 对象析构时会自动完成所有资源的释放
    return 0;
}

是不是清爽多了?这还只是资源管理部分,AclLite在模型推理、图像视频处理上的简化效果更为明显。

2. AclLite的核心功能模块

通过翻阅samples/inference/acllite目录下的源码和文档,我们可以发现AclLite主要由以下几个核心模块组成:

2.1 资源管理模块

这是最基础也是最重要的模块。它负责管理ACL的初始化、Device/Context/Stream的生命周期。

  • C++实现:主要通过AclLiteResource这个类。利用了C++的RAII(Resource Acquisition Is Initialization,资源获取即初始化)特性,在构造函数里获取资源(比如Init()方法),在析构函数里释放资源。这样我们只需要创建一个AclLiteResource对象,它就能在作用域结束时自动帮我们擦屁股,避免了忘记aclFinalize之类的资源泄漏问题。
  • Python实现:对应acllite_resource.py,提供了AclLiteResource类,同样简化了初始化和资源释放的流程。

2.2 模型推理模块

这是我们最关心的模块之一。它把加载OM模型、创建输入输出、执行推理、获取结果这一套复杂的流程大大简化了。

  • C++实现AclLiteModel类。你只需要用模型路径构造一个对象,然后调用CreateInput准备输入数据,再调用Execute执行推理,最后从返回的InferenceOutput结构体里拿到结果。
  • Python实现acllite_model.py里的AclLiteModel类。这个用起来更爽,execute方法可以直接接收一个numpy array列表作为输入,返回值也是一个numpy array列表,完美融入Python的数据科学生态。

一个Python的例子感受一下:

from acllite_model import AclLiteModel

# 1. 初始化模型,传入om模型路径
model = AclLiteModel("../model/resnet50.om")

# 2. 准备输入数据 (假设是个numpy数组)
import numpy as np
input_data = np.random.rand(1, 3, 224, 224).astype(np.float32)

# 3. 执行推理
result_list = model.execute([input_data,])

# 4. 处理结果 (result_list里就是推理输出的numpy数组)
print("Inference success, output shape:", result_list[0].shape)

对比一下用原生ACL接口写推理,是不是感觉幸福感爆棚?

2.3 媒体处理模块(DVPP/VPC)

这部分是AclLite的另一个精华。昇腾芯片里有专门的硬件单元负责图像和视频处理,比如DVPP(Digital Vision Pre-Processing)和VPC(Vision Pre-processing Core)。它们能高效地完成JPEG/PNG/H.265/H.264的编解码、图像缩放、裁剪、色域转换等操作。

自己调用这些硬件单元的原生ACL接口是相当复杂的,因为要手动处理各种内存对齐、格式转换的细节。AclLite把这些都封装好了。

  • C++实现AclLiteImageProcAclLiteVideoProc类。提供了ResizeCropJpegD(JPEG解码)、Vdec(视频解码)等简单明了的接口。
  • Python实现acllite_imageproc.pydvpp_vdec.py。同样提供了jpegdresize等方法,输入输出都用AclLiteImage这个统一的类来表示,非常方便。

比如,要把一张JPEG图片解码并缩放到224x224,用AclLite可能就是这样:

from acllite_imageproc import AclLiteImageProc
from acllite_image import AclLiteImage

# 假设我们已经有了一个AclLite的资源实例 acl_resource
# 并初始化了图像处理模块
image_proc = AclLiteImageProc(acl_resource)

# 1. 读取图片
image = AclLiteImage("../data/cat.jpg")

# 2. 解码 (jpeg -> yuv)
yuv_image = image_proc.jpegd(image)

# 3. 缩放
resized_image = image_proc.resize(yuv_image, 224, 224)

# resized_image.data 就是缩放后的图像数据,可以直接送去模型推理了

2.4 应用与多线程模块

这部分主要在C++版本里体现,通过AclLiteApp, AclLiteThreadMgr, AclLiteThread这几个类,提供了一个简单的单例模式应用框架。你可以定义不同的线程,每个线程干不同的事(比如一个线程从摄像头读数据,一个线程做推理,一个线程显示结果),然后用AclLiteThreadMgr把它们管理起来。这对于构建一个完整的、高性能的推理应用非常有帮助。

3. 如何在项目中使用AclLite

AclLite并不是随CANN工具包默认安装的,它是samples仓库的一部分。所以使用它有点像个“绿色软件”。

  • 对于C++项目

    1. 你需要先根据inference/acllite/cplusplus/README.md的指引,编译生成libacllite.so这个动态库。这步可能需要先安装ffmpeg等依赖。
    2. 在你的项目里,包含AclLite的头文件,并链接libacllite.so库。
  • 对于Python项目

    1. 这个更简单,你只需要把inference/acllite/python这个完整的目录,复制到你的项目里,或者一个Python可以搜索到的路径下。
    2. 根据inference/acllite/python/README.md安装av, numpy, Pillow等几个pip依赖。
    3. 然后就可以在你的代码里from acllite_model import AclLiteModel这样直接使用了。

总的来说,AclLite是一个非常实用的官方“甜点”。它虽然不是非用不可,但善用AclLite,绝对能让你在开发昇腾应用时,少写很多样板代码,把精力更多地放在业务创新上,强烈推荐大家在自己的项目中尝试使用。

Logo

昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链

更多推荐