摘要:昇腾 AI 计算解决方案以极致算力,端边云融合、全栈创新,开放生态的硬核实力。用户可以使用标准的 Matrix 接口实现业务引擎,对外释放昇腾 AI 加速能力。
从卷积神经网络中的矩阵乘法(GEMM)说起
说起 AI 业务,就不得不提最经典的 AlexNet,AlexNet 模型于 2012 年提出,其被认为是计算机视觉领域最有影响力的模型之一。AlexNet 网络主要包含八层,前五层是卷积层,最后三层是全连接层。 配合 pooling 及 norm 运算,以下列出所有卷积层和全连接层的参数规模以及每层的浮点计算量,从图中可以看出 AlexNet 网络的参数规模达到了 6 千万量级,计算量达到 720MFlops。通过在横向比较几个经典的分类网络,参数规模以及计算量都是巨大的。那么从计算量的角度来看计算中 99%以上都是卷积运算,本质都是矩阵运算。
在如此级别的规模参数及计算量下,矩阵运算如何加速,成为了视觉计算领域亟需解决的问题。举例:一个典型的 16*16 的两个矩阵乘运算,在不同硬件上是如何进行计算的?
在 CPU 中矩阵乘需要做 3 个 for 循环,每一位依次进行乘加运算,理论上需要 16*16*16*2 的时钟周期。
GPU 中矩阵乘做了相关的优化,GPU 是可以直接进行向量的乘加运算,那么上述运算可以拆解为 16*16 个乘加运算,即需要 256 个时钟周期。
昇腾处理器提供专门的矩阵乘运算单元,一个时钟周期就可以完成一次矩阵乘运算。其凭借着在 AI 推理上的优异性能以及超低功耗,被应用于昇腾 AI 计算解决方案。
昇腾 AI 计算解决方案,力算云上新视界
昇腾 AI 计算解决方案以极致算力,端边云融合、全栈创新,开放生态的硬核实力,助力行业客户在图片分类、目标检测、人体检测、人脸识别、车辆检测等 AI 视觉类计算领域取得亮眼的成绩。
在 IAAS 层,昇腾 AI 计算解决方案可提供昇腾 Ai 推理实例——包括 Ai1,KAi1,及可用于 Ai 训练的裸机实例 KAt1。
在算子层,昇腾 AI 计算解决方案可支持主流框架 TensorFlow 与 Caffe 的算子,以及自定义算子的能力。基于算子层还提供 Matrix 标准化接口,用户可以通过基于 Matrix 标准化接口构建昇腾业务引擎。
同时,用户还可以使用华为昇腾 Serving,对外提供 RestFull API 或 gRPC 请求,轻松解耦业务。上层再配合 AI 容器服务,轻松实现弹性伸缩,大大缩短业务部署周期。
如何用 Matrix 接口实现业务引擎
用户可以使用标准的 Matrix 接口实现业务引擎,通过 SDK 方式对外释放昇腾 AI 加速能力。
Matrix 为通用业务流程执行引擎,运行于操作系统之上,业务应用之下。可以屏蔽操作系统差异,为应用提供统一的标准化接口,包括流程编排接口(支持 C/C++语言、Python 语言)和模型管家接口(支持 C++语言)。
对于一个典型的业务流,通常包含数据读取,数据的预处理(图片的解码,前处理),模型推理,数据后处理等过程。
那么在 Matrix 框架中,可以把上述每个过程抽象为一个 engine,engine 就是特定功能的计算引擎。若干 engine 构成 Graph,Graph 负责对 engine 进行管理。Matrix 是一个通用的业务流程执行引擎,能够管理 Graph 的生成,执行以及销毁。
Matrix 计算流程
关于 Matrix 的计算流程,我们从创建流程、执行流程、销毁流程展开来看。
创建流程,如红色箭头所示:
根据 Graph 配置创建 Graph 对象。
上传离线模型文件和配置文件到 Device 侧。
初始化 engine,推理 Engine 通过离线模型管家(AIModelManager)的 Init 接口加载模型。
执行流程,如灰色箭头所示:
输入数据
预处理 Engine 调用 dvpp 的 api 接口,进行数据预处理,例如对视频/图像进行编解码、抠图、缩放。
推理 Engine 调用离线模型管家(AIModelManager)的 Process 接口进行推理计算。
推理 Engine 调用 Matrix 提供的 SendData 接口将推理结果返回给 DestEngine。DestEngine 通过回调函数将推理结果返回给 APP。
销毁流程,如蓝色箭头所示:
结束程序,销毁 Graph 对象。
Matrix 数据流向和调用流程的双 BUFF 加成
数据流“0”拷贝
我们可以看到,在 Matrix 框架中数据流的传输性能是至关重要的。
在框架中单独提供了一套内存分配和释放接口,包括 HIAI_DMalloc/HIAI_DFree、 HIAI_DVPP_DMalloc/HIAI_DVPP_DFree,支持 C/C++语言。
其中,
HIAI_DMalloc/HIAI_DFree 接口主要用于申请内存,再配合 SendData 接口从 Host 侧搬运数据到 Device 侧;
HIAI_DVPP_DMalloc/HIAI_DVPP_DFree 接口主要用于申请 Device 侧 DVPP 使用的内存。
通过调用 HIAI_DMalloc/HIAI_DFree、 HIAI_DVPP_DMalloc/HIAI_DVPP_DFree 接口申请内存,能够尽量少拷贝,减少流程处理时间。
HIAI_Dmalloc 在跨侧传输以及模型推理阶段,性能最优,主要优势体现在:
申请的内存是可以用于数据搬运对的,这样可以避免 Matrix 与数据传输模块间的数据拷贝。
申请的内存可以直接使能模型推理零拷贝机制,减少数据拷贝时间。
HIAI_DVPP_Dmalloc 接口体现在:
申请的内存可以给 DVPP 使用,同时可以在 DVPP 使用完后透传给模型推理时使用。
如果不需要做模型推理,申请的内存中的数据可以直接回传给 Host 侧。
对用户友好的 Host-Device 的数据传输
在 Host-Device 间数据传输情况下,用 HIAI_REGISTER_SERIALIZE_FUNC 对自定义数据类型进行序列化/反序列化,可以实现高性能数据传输,节省传输时间。
Matrix 通过“控制信息+数据信息”的形式描述要传输的数据,控制信息指用户自定义的数据类型,数据信息指需要传输的数据内容。为保证 Host 和 Device 之间的数据传输,Matrix 提供如下机制:
在传输数据前,用户可调用 HIAI_REGISTER_SERIALIZE_FUNC 宏注册用户自定义数据类型、用户自定义序列化函数、用户自定义反序列化函数。
用户在本端调用 SendData 接口发送数据后,Matrix 会做如下处理,处理流程如下:
调用用户自定义的序列化函数对控制信息序列化,将序列化后的控制信息放入内存(ctrlBuf)。
通过 DMA(Direct Memory Access)映射将控制信息拷贝一份存放到对端的内存中,并保持本端与对端之间控制信息的映射关系。 指向数据信息的内存(dataBuf)指针已通过 SendData 接口的入参传入,dataBuf 是由用户调用 HIAI_DMalloc/HIAI_DVPP_DMalloc 接口申请的,申请该内存后系统将本端的数据信息通过 DMA 映射拷贝一份存放到对端的内存中,并保持本端与对端之间数据信息的映射关系。
拼装消息发送给对端,主要将 ctrlBuf 的地址及大小、dataBuf 的地址及大小发送到对端。
对端收到消息后,Matrix 会调用用户自定义的反序列化函数解析对端已获取到的控制信息和数据信息,并将解析后的数据发送给对应的接收 Engine 进行处理。
对端解析数据后,控制信息已使用完成,因此可以释放掉存放控制信息的内存(ctrlBuf),但由于存放控制消息的内存是在本端申请的,因此对端需要给本端发送释放 ctrlBuf 的消息。
本端收到消息后,释放 ctrlBuf。
Engine 在收到数据并完成所有处理后,便可以释放 dataBuf 了,但由于 Matrix 并不知道用户何时会使用完 dataBuf,因此需要用户在实现反序列化函数时,dataBuf 以智能指针返回并绑定析构器 hiai::Graph::ReleaseDataBuffer。当智能指针结束生命周期析构时,便会自动调用析构器给本端发送释放 dataBuf 内存消息。
本端收到消息后,释放 dataBuf。
以上,我们详细介绍了如何使用 Matrix 接口构建业务引擎,同时用户还可以集成昇腾 Serving 对外提供标准 RestFull API 或者 gRPC 请求,提供解耦的标准推理接口能力。或者配合 AI 容器服务,提供弹性伸缩,易于部署的能力,模型热替换的能力。
评论