CANN Samples(四):AclLite封装总览
在前面的文章里,我们已经手动完成了环境准备和跑通了一个原生的ACLHelloWorld。你可能已经发现了,虽然跑通了很有成就感,但每次都要写一堆aclInit、aclrtCreateContext、aclrtCreateStream这样的“八股文”代码,还是挺繁琐的。
如果只是初始化还好,但凡涉及到模型推理、图片视频处理,那代码量和复杂度就直线上升了。官方显然也意识到了这个问题,所以提供了一个名叫AclLite的封装库,目的就是把这些重复、繁琐的操作打包好,让我们能更专注于业务逻辑本身。
这篇文章,我们就来好好聊聊AclLite到底是什么,它能干嘛,以及怎么用。
1. AclLite是什么?为什么需要它?
简单来说,AclLite是昇腾官方提供的一套C++和Python的二次封装库。它位于我们应用代码和原生AscendCL(ACL)接口之间,像一个得力的助手,帮我们打理好了很多杂活。
你可以把它想象成一个“装修施工队”。我们(开发者)是业主,只想实现“客厅要个大屏幕看电影”(模型推理)、“厨房要能快速洗菜切菜”(图像处理)这样的最终效果。我们不想去关心电线怎么走(资源初始化)、水管怎么接(Stream管理)、水泥怎么和(内存对齐)。AclLite就是这个施工队,它把这些底层的、标准化的脏活累活都包了,我们只需要给它下指令就行。
名词解释:
- 二次封装:就是在已有的接口(这里指ACL接口)基础上,再包一层,提供更简单、更高级的接口。好比手机厂商基于安卓系统做了自己的UI,虽然内核还是安卓,但用起来更方便了。
- AscendCL (ACL):昇腾计算架构下的应用层API,是我们在应用软件里调用昇腾硬件计算能力的“官方语言”。我们之前用的
aclInit、aclrtSetDevice都属于这个范畴。
没有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++实现:
AclLiteImageProc和AclLiteVideoProc类。提供了Resize、Crop、JpegD(JPEG解码)、Vdec(视频解码)等简单明了的接口。 - Python实现:
acllite_imageproc.py和dvpp_vdec.py。同样提供了jpegd、resize等方法,输入输出都用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++项目:
- 你需要先根据
inference/acllite/cplusplus/README.md的指引,编译生成libacllite.so这个动态库。这步可能需要先安装ffmpeg等依赖。 - 在你的项目里,包含
AclLite的头文件,并链接libacllite.so库。
- 你需要先根据
-
对于Python项目:
- 这个更简单,你只需要把
inference/acllite/python这个完整的目录,复制到你的项目里,或者一个Python可以搜索到的路径下。 - 根据
inference/acllite/python/README.md安装av,numpy,Pillow等几个pip依赖。 - 然后就可以在你的代码里
from acllite_model import AclLiteModel这样直接使用了。
- 这个更简单,你只需要把
总的来说,AclLite是一个非常实用的官方“甜点”。它虽然不是非用不可,但善用AclLite,绝对能让你在开发昇腾应用时,少写很多样板代码,把精力更多地放在业务创新上,强烈推荐大家在自己的项目中尝试使用。
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐

所有评论(0)