首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

异构计算系列(三):Adlik在深度学习异构计算上的实践

“异构计算”(Heterogeneous computing),是指在系统中使用不同体系结构的处理器的联合计算方式。在 AI 领域,常见的处理器包括:CPU(X86,Arm,RISC-V 等),GPU,FPGA 和 ASIC。(按照通用性从高到低排序)本文是异构计算系列的第三篇文章,重点介绍Adlik在深度学习异构计算上的实践。

人工智能领域在近年发展迅速,不论是在图像识别,目标检测,机器翻译,还是语音识别等多个领域,人工智能的表现均已超过人类水平,尤其是在AlphaGo战胜了李世石之后,人们对人工智能可达到的成就有了新的认识。

机器学习(Machine Learning,ML)是人工智能的子领域,也是人工智能的核心,就是要设计让机器可以进行自动学习的算法。而深度学习(Deep Learning,DL)是机器学习的一个子类,是一种包含多个隐含层的神经网络结构,人们定义了神经网络中各种神经元的连接方法,以及神经元的激活函数,并利用反向传播技术完成神经网络的训练过程。深度学习技术在众多AI领域取得很多成果,解决了很多复杂的模式识别难题,所以也成为最近几年人工智能领域研究和应用上人气最火热的技术。

深度学习模型当前有多种训练框架,如常见的TensorFlow,PyTorch,MxNet,Caffe,PaddlePaddle等等,训练时大多是使用GPU,采用容器云方式,进行大规模并发计算,减少模型训练收敛时间。而在模型的应用上,则要使用深度神经网络的推理能力,完成网络前向计算,并将此计算部署为应用服务,产生商业价值。

Adlik做了什么?

各种算法在训练框架训练后得到各种模型,其服务应用可能要部署在不同的硬件平台,可能使用不同的推理框架,对应用场景有着不同的要求,如低时延。所以在训练中达到很好的收敛效果的深度学习模型,距离真正的投入应用,还有很多工作要做:

  • 针对不同设备的推理框架有很多,对用户难以选择,要付出较多的学习成本;
  • 不用应用场景的部署条件不同,有基于容器化部署场景,也有基于嵌入式硬件部署的场景,同样的模型服务,不同部署方案要掌握不同的技术;
  • 根据性能需求有很多的模型调优工作;
  • 推理服务应用于不同硬件,需要多类异构计算引擎的支持。

Adlik就是一种可以将深度学习模型从训练完成,到部署到特定硬件并提供应用服务的端到端工具链,其应用目的就是为了将模型从研发状态快速部署到生产应用环境。Adlik可以和多种推理引擎协作,支持多款硬件,提供统一对外推理接口,并提供多种灵活的部署方案,以及工程化的自适应参数优化方案,为用户提供快速,高性能的应用服务提供助力。Adlik的架构如下图:

Adlik在架构上,可以分为模型优化模块(Optimizer),模型编译模块(Compiler)和推理引擎模块(Inference Engine)。

训练好的模型,通过Adlik模型优化模块处理,生产优化后的模型,然后通过模型编译模块,完成模型格式转换,生成最终推理引擎支持的模型格式。

部署方案上,Adlik支持三种部署场景,并提供相应的特性支持:

1.云侧

Adlik支持原生容器化部署方案,优化和编译完成的模型,可以和Adlik Serving Engine镜像一起打包,发布为应用服务镜像,并在指定硬件的容器云上运行。

2.边缘侧

Adlik支持在启动的Adlik Serving Engine服务上,加载优化和编译完成的模型,并支持模型版本管理,自动升级,以及多模型实例调度功能,减少边缘侧计算资源的占用。

3.端侧

Adlik可以为用户提供C/C++的API接口,支持用户直接在计算引擎上调用完成了优化和编译的模型,并提供了模型编排能力,具备低延时和小体积的特性,可以在指定硬件运行模型应用。

Adlik目前的定位是深度学习模型工程化使用的工具链,是模型应用落地的加速器,包括端到端编译优化能力,主流深度学习推理引擎的集成,支持多种灵活部署方式,以SDK方式提供用户可扩展实现推理运行时的自定义开发能力,可以实现多模型协作推理,在工程化角度,Adlik还会引入工程参数自动优化的能力,提升易用性,给用户提供训练模型到推理应用上线的端到端优化能力。

Adlik在支持异构硬件计算的设计思路

目前Adlik支持的推理引擎,包括常见的用于深度学习推理的TensorFlow Serving,TensorRT,OpenVINO,以及CNNA(FPGA特定运行时),并计划支持Tf Lite。而支持的异构硬件包括了GPU,CPU(x86),以及FPGA,计划支持CPU(ARM)。Adlik在框架层上提供了多种形式,支持用户扩展异构硬件的运行和部署。

Adlik Serving提供了模型的推理服务。它以插件的方式部署和隔离各种运行时的环境。Adlik Serving内置常见的运行时组件,包括TensorFlow Serving,OpenVINO,TensorRT,CNNA(FPGA特定运行时),Tf Lite等,各类应用可按需加载,开箱即用。 部署推理引擎时,需要根据具体场景灵活选择推理运行时,及其相应的异构硬件。例如,在CPU嵌入式环境下部署,因为只存在CPU环境,此时用户可以选择TensorFlow Serving on CPU,或OpenVINO on CPU等两种部署方式,如果环境使用ARM的CPU架构,那么也可以选择Tf Lite on CPU(ARM)的部署方式。

更为高级地,用户也可以通过Adlik提供的Serving SDK,开发用户自定义推理运行时环境,并在Adlik Serving框架下执行推理服务,满足极高的时延性的部署环境。Adlik Serving SDK提供了模型上载,模型升级,模型调度,模型推理,模型监控,运行时隔离等基础模型管理的功能特性,及其用户定制与开发推理服务的C++ API。用户要根据自己的需求,定制开发自己的模型和运行时。Serving SDK提供了标准的扩展点,方便用户高效地定制新的模型和运行时环境。基于Serving SDK,用户也可以开发组合式的模型,在进程内控制多模型之间的交互,而模型之间的运行时可以相互独立。例如,模型1的输出可以作为模型2的输入,模型1和模型2分别TensorFlow Serving和TensorRT运行时的模型。

默认地,Adlik Serving/Serving SDK不包含任何运行时组件,实现最小的依赖管理,应用根据部署环境灵活选择组装。也就是说,Adlik Serving/Serving SDK可以提供不同运行时组合的镜像集合,应用根据具体的部署环境选择合适的基础镜像。

以新增一款运行时引擎为例,介绍一下Adlik的框架是如何支持创建新运行时的,这对很多有自定义运行时和指定硬件平台的场景有重要的意义。假设A是要支持的新运行时。

  1. 定义A_Model类。这个指定的A_Model就是要创建的新运行时
  2. 定义具体计算引擎的实现类,A_Processor类,A_Processor类可以直接调用A计算引擎的执行API
  3. 调用Adlik提供的API接口,将A_Processor类其注册到Adlik运行时调度器,作为可调度的一个推理引擎
  4. 调用Adlik提供的API接口,将A_Model类注册到Adlik系统,这样Adlik在启动后就能够使用基于A_Model的运行时来执行推理任务

在上面简单的流程示意图中,Server收到推理请求后,runtime可以识别到A_Model运行时的请求数据,就通过调度器和具体调度算法,找到注册在调度器的A_Processor实现类,最终调到A引擎提供的计算API,完成整个推理过程。框架提供了丰富的管理和运行时调度功能,用户只需要关注计算引擎实现即可。

实现上述代码后,用户可以根据指定硬件平台依赖的编译器对代码进行编译,即可生成指定硬件上可执行的推理应用程序,完成对异构硬件的支持。

Adlik在支持FPGA异构计算上的实践

在计算密集型任务中(在深度学习模型推理领域),相比起仅具有数据并行能力的GPU,FPGA基于特定的门阵列硬件结构,可以同时实现数据并行和流水线并行,使得计算的延迟更小;对于特定结构的硬件电路,FPGA的计算延迟也相对稳定。同时,与CPU和GPU相比,FPGA具有较低的功耗,这在大规模的计算中具有一定的优势。此外,FPGA还具有动态可重配置逻辑资源的功能,可以根据不同的配置文件,加载相应的编译文件,比ASIC更具灵活性。因此FPGA深度学习模型推理领域日益受到重视,并在CNN网络的实现领域中占据了很重要的位置。

FPGA的特点是善于进行并行乘加计算,所以在实施深度学习计算时,我们要考虑将深度学习算法进行适当优化,将卷积、池化、下采样等大运算量的算子在FPGA中实现,从而提升整体计算引擎的效率和算力。在实践种,我们在xilinx zcu102单板上实现了卷积神经网络中卷积算子、池化算子、下采样算子以及全连接算子。此外,如resnet网络中涉及的scale和batchnorm算子也在建模中进行了适当优化,得以在FPGA中实现。

我们采用了深鉴科技的笛卡尔架构进行了研究和实践。笛卡尔架构,如下图,是典型的zynq工程架构。片上ARM与逻辑资源之间由AXI接口连接,网络配置信息由axi-lite接口传送,图像数据和权重则通过DMA由PS传送至PL外挂的DDR中,在卷积计算中由PL与DDR通过AXI4协议通信存取。

在整体设计上,我们考虑使用了int8量化和DSP复用技术,多点滑窗卷积计算以及多算子融合技术,结合FPGA传统设计中常用的流水线及乒乓存取技术,使加速器获得了更高的算力,以及更短的网络处理时间。

1.Int8量化和复用DSP技术

基于Xilinx xczu9eg系列芯片中的DSP资源的特点,可以实现DSP的乘加复用。该系列芯片的DSP资源可以实现27×18bit的乘法计算,且某一级DSP的乘法输出结果可以级联到下一级DSP的加法输入端,从而实现乘加级联功能,无需额外使用逻辑资源搭建加法器。 如果将输入的图像和权重信息量化为int8格式,则可以使用权重移位的方式将某一权重左移18位后与另一权重相加,作为乘法器27bit的输入数据,从而使用一个DSP实现两次乘加计算,可以做到算力加倍。

2.基于multi-sliding的卷积计算

传统的二维卷积计算中,每个时钟沿参与卷积的因子为M个输入通道图像中的某个单点与对应输出通道的卷积核的对应单点相乘加,得到对应N个输出通道中对应位置的单点部分和。如下图,完成一个卷积核为3×3的卷积计算,需要9个时钟沿。如果stride=1,则完成一行输出图像的计算需要9×6=54个时钟沿。

传统的卷积单点计算示意图

使用multi-sliding window的卷积方式,引入PIX变量,表示每个时钟沿里,每个输入通道的图像参与卷积的像素点数,传统卷积中的PIX通常为1,即每个输入通道只有一个像素点参与乘加计算,而现在PIX可以取大于1的其他值,这样就使每个时钟沿参与卷积的图像像素点得到了伸展。

如下图,当卷积计算的参数pad=1,kernel=7,stride=1,ciWidth=28,PIX=8时,每输入通道在每个时钟沿里参与卷积的像素点数扩展为8,与对应的卷积核相乘加,作为对应输出通道的部分和。

multi-sliding window卷积计算示意图

如图,对于ibuf中的某一个输入通道中的每一行输入图像,每个时钟沿都有PIX个像素点参与卷积计算。随着sbuf中的权重由行首滑窗至行尾,每一个滑窗经过的像素点会在一个时钟沿的时间里完成所有在这一里要参与的卷积计算,不会在之后的时钟沿里被重复使用,使得整行的计算时间是传统的卷积方式的1/PIX,大大缩短了计算时间。

3.多算子融合

推理时的BatchNorm算子运算非常耗时,但由于其是线性运算,可以在建模初期将BatchNorm+Scale的线性变换参数融合到卷积层,替换原来的weights和bias。与单独计算BatchNorm相比,这种算子融合大大减少了内存的读写操作,有效提高了处理帧率。

4.流水线计算和乒乓加载技术

流水线技术和乒乓加载技术是FPGA设计中常用的手段。使用流水线可以使串行计算并行化,大大减少运算时间,乒乓加载技术则利用片上存储器实现了输入图像和权重的预加载,使输入图像由FPGA片外DDR传至片上的时间被卷积计算时间覆盖,同样起到了减小图像处理时间的作用。

结语

在深度学习计算这类计算密集型的应用场景下,通用硬件设计中的某些特点,如复杂任务调度等,很可能会成为计算瓶颈,导致降低计算效率,所以针对应用部署硬件的特征完成异构硬件上的计算优化,在当前已经成为研究的热点。Adlik首先在架构上支持多类异构硬件和计算引擎,也在FPGA异构计算上完成了一些技术实践,后续将继续进行特定硬件上的计算优化技术的研究,来加速推动AI模型的工程应用。

参考文献:

[1] https://github.com/Adlik/Adlik [2] Xilinx-ug579-UltraScale Architecture DSP Slice User Guide [3] Xilinx-WP486-Deep Learning with INT8 Optimization on Xilinx Devices [4] Google Inc. Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Interface.

作者简介:

[1]刘涛,中兴通讯算法高级系统工程师,Adlik开源项目负责人。 [2]李莹,中兴通讯技术规划部FPGA工程师,负责对FPGA加速器时序优化。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/eg4KWZd1UoFwjSsUzfgt
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券