论 做 AI 芯片的正确姿势

https://xie.infoq.cn/article/d5ab8bea53fa8a08406fabf9d

论做 AI 芯片的正确姿势

作者: flow
  • 2020-08-10
  • 本文字数:14908 字

    阅读完需:约 49 分钟

1 前言


  因为种种原因中断了自己的几个 AI 项目后,我去做了 AI 芯片以求一个 huge bless。也尝试了很多(ppt、code、optimize、AI 算法、IDE、软件、IP、架构),但终觉姿势不对而修不得。或许做 AI 芯片应该践行阳明心学知行合一:知之真切笃实处即是行,行之明觉精察处即是知

  目前市面上号称 AI 芯片的公司百家不止,流片成功的也有不少,关于 AI 芯片的文章亦是全网乱飞,但大多对藏在细节里的魔鬼不惊不扰。同时看到不少关于 AI 芯片开源工程介绍,感觉更到位。

1.《我这个人不懂什么 cpu,于是用代码模拟了一个》 2.《开源 AI 硬件的曙光:RISC-V+NVDLA 合二为一》 3.《3 天上手,30 天精通!—— 深度学习 FPGA 加速器设计》


   所以想象自己如果能不矫情不浮夸地写点东西也许有点意义,更能印证“知不易行不难,知行不分先后”之道理。

  正如马云曾经说过:人生是一场各自的修行,修行路上遇见自己方得福报。


2 背景


  直接举一个 AI 应用场景为例:MaskRCNN 部署到 IPhone 做 Inference。

2.1 MaskRCNN


  MaskRCNN 是一个非常典型且效果 SOTA 的深度学习网络,由 FasterRCNN + FCN 实例分割网络组成,一个网络涉及检测、分割、识别等三大视觉 AI 领域,有代表性。找了张图描述很到位,本想参考 PlotNeuralNet 编代码画得细节一些,到一半发现支持全部细节耗时耗力,纯属浪费作罢。


图.MaskRCNN 结构

  这里 MaskRCNN 我直接 pytorch 实现的 Facebook 官方范例,有几个特点:

  1. Backbone 用了 Resnet50 配置,用残差连接跨块传递梯度,加速训练谈笑风生, 比一根筋的 alexnent 高不知道哪里去了。卷积基本都是 3x3 和 1x1 卷积,未用 depth conv,也没有 dialated conv,也没有 deform conv 等骚操作。

  2. 用了 FPN 多尺度提取,大小目标一一照顾。

  3. 直接借鉴 faster rcnn 的 two stages 操作,先粗检测再分割识别边框回归。也算是一种注意力机制,比 one stage 的 ssd、yolo 之类效果好。

  4. 计算量巨大,我大概算了下(考虑到卷积计算量占了绝大部分用 MACs 计)。以单张分辨率 320x320 的 RGB 图像输入算,Resnet50 有 28GMACs 左右,FPN 有 11G MACs 左右,复杂图像经过第一阶段 RPN 后,假设嫌疑目标数有 100 个是比较合理(一般上限也是 100)。这样第二阶段对 100 个目标做 FCN 分割、边框回归和分类识别的计算量是 43GMACs 左右。

  5. 计算量之外也有一些逻辑操作,如 NMS、排序、ROI 操作等。

  网络运算效果如下:



图.MaskRCNN 效果

2.2 CPU(DSP)面对 AI 算法的囧境


  IPhone 是一个常见的部署平台,拥有优秀的操作系统和 CPU。这里只讨论纯 CPU 运行,会涉及 ARM 的 SIMD 加速指令,不涉及到 OpenGLES 和 coreml 做 GPU 和 NPU 的加速。

  算法移植到其他平台运行,需要从神经网络的解析、部署、优化一套流程,如果加上 Backward 求导功能,就是一个完整的神经网络框架了。因为当年我自己把 AI 算法往 IPHONE 上怼过撸过一遍,后面软件章会简单说说。

  取 Backbone 的 Resnet50 第一个 block 中最耗时的卷积层为例,图像输入输出都是 64x160x160,stride=1,卷积核尺寸 3x3,数据格式 Float。取开源 NCNN 的 neon 卷积加速代码为例,一窥现代先进 CPU 工作方式。NCNN 是一个 Inference 框架,优化性能在嵌入式 AI 业内也是有口碑的,SIMD 指令调用、寄存器复用率、排流水并行、cache 命中率都做得不错。


图.ARM NEON 汇编优化片段

  这段代码采用 Sliding Windows 直接卷积方法,未用 im2col、fft、winograd 等卷积加速法。采用 64 位 neon 指令加速计算,采用固定权重(Weight Stationary) 方式,预先读取 2 组卷积核的部分到 neon 寄存器,这样输入图读一次可以做两次计算,复用一点是一点。单张输入图像一次读取 4 行 8 列,可以做 2 行 4 列 8 个输出点的 3x3 的卷积。一次循环最后可以获得 2(输出图)x2(行)x4(列) =16 个点结果。

附送几个 IOS 汇编优化的小技巧:

  1. IOS 做多核 ARM 的并行调用,没有现成的 openmp。可以自己多开几个 pthread 划分数据简单并行,靠谱而且效率很高,也不用去管大核小核算力不同的同步问题。

  2. 现在的 LLVM 似乎也支持内联汇编配合 C 的用法了,如果感觉不适,可以用 vfmaqlaneqf32 之类的 intrinsic 汇编语法方便理解。如果还想要扣点性能出来,可以直接在.S 文件汇编指令实现整个函数。


  函数完成上述卷积层计算,要读数据 1200M Bytes,写 400M Bytes,核心循环有 70 条指令,所以总共要执行 440M 条指令,就算指令 cache、数据 cache 全部命中,每条指令都是单周期完成,这个卷积层也要花上 440M 个时钟周期。整个 MASKRCNN 最后跑下来几十秒一帧,这个效率基本上是废了。

  可以发现指令驱动的机制限制了 CPU 算力发挥,SIMD 执行单元很多时间都在空转。而更严重是指令单元占用 CPU 大量面积和功耗。如图所示,可以看出取指、译码、发射、执行等完整流程,执行只占用不到一成。就算 CPU 软硬件一起吃力地提高一点代码密度,少取几条指令,于事无补。也可以理解纯数据流 0 指令的 ASIC 为何如此省电。



图.CPU 耗能分

  现存大量设备还是这些 CPU(DSP)居多,上面跑 AI 算法也是实实在在的市场需求。似乎也只能做算法精简和架构创新,如修改图像分辨率、用小卷积核、channels 变少等简化设计、用 depthconv+pointconv 等方式。

  CPU 无能为力,主做图形计算嵌入式 GPU?虽然号称算力 10 倍于 CPU,但调用调试麻烦,算力也难发挥,可能最后跑下来还不如 CPU。如果这么大计算量的网络要部署到端上芯片,怎么办?

  是时候请出超级飞侠了,是 AI 芯片

3 硬的


  先不急,说几个我归纳的深度学习计算的几个特点:

  1. 计算方式简单:

  2. 最主要的计算是乘累加 MAC,占据 95%以上计算量,出没于 FC、CONV、BN。

  3. 指数计算,广泛存在于激活函数 sigmoid、elu,selu,softrelu、tanh 等,还有 loss 函数 softmax、BCE 等,还有其他部分如 VAE(可变分自编码器)对隐层的 reparameterize。虽然指数可以通过泰勒级数展开乘累加实现。

  4. 数据流量巨大,但流向固定简单,少有 if else 等逻辑判断,意味着可以预先优化数据流。

  5. 研究者巨量,所以带来各种骚操作层出不穷。如多变的卷积核 1xN、Nx1、1x1、多变的卷积方式 depth conv、dialated conv、deform conv、shuffle、胶囊网络等。


图.Deform Conv 可适应目标形状和大小的卷积核

  万物皆 AI,能计算者皆可乘 AI,正如一位业内大佬之名言:哪怕一条内裤、一张卫生纸、一组光透镜都有它的用处。


图. Dr Golden Gun

3.1 算力提升之道


  撇开 DSA、算法软件定义硬件、聪明的软件愚蠢的硬件之类有的没的概念,AI 芯片目的很简单:提升算力,降低面积和功耗。提升算力就是放多些计算单元,降低面积和功耗从上面例子看出减少指令的占比是个办法。具体方式我总结了 3 种:SIMD、SIMT、ASIC。  SIMD 和 SIMT 属于指令复用,让同一个指令尽量驱动更多的数据计算,ASIC 是通过固化数据运算和逻辑,不同程度地干掉些指令。当然所有算力的提升都会装到内存墙,内存系统设计更紧要,如多级 cache、sram 塞进 pe、多路 dma 等。



图.SIMT SIMD


SIMD


  SIMD(single instruction multiple data)的特点是在核内做数据运算的并行,通过数据宽度增加提高算力。如 Intel 的 simd 指令集从 MMX(64bits)、SSE(128bits)、AVX(256bits),还更极端的如 ARM SVE 指令集有做到了 2048bits 宽,相当于 64 个核并行(float32)。这种模式有几个缺点:

  1. 主要缺点就是 SIMD 指令太过复杂,如此宽的数据操作编译器自动矢量化无能为力,为难开发者手动汇编也不好做。

  2. 因为复杂指令系统依旧存在,simd 指令设计又很复杂,额外增加了寄存器和 cache,每个核都是巨无霸,想通过多核扩展提升算力性价比很低,而且 SMP(Symmetric MultiProcessing)设计也并不容易。

  这种模式一般提供算力在 100Gops 以下,主要玩家 CPU/DSP。(如果 SIMD 只做 GEMM 或 CONV 计算,归类为 ASIC)。

SIMT


  SIMT(single instruction multiple threads)方法是把核做瘦后在核间做并行,32 个瘦核绑在一个 warp 内共用指令控制,硬件做上下文线程切换。有几个特点:

  1. 核虽然瘦但是脱了有肉,内部设计也并不简单,也保留有取指译码执行等,一般也都会带 128bits 宽的 SIMD(如 nvidia ptx)。所以 SIMT 也不是会很省面积和功耗。

  2. 算力高了,容易撞墙,所以内存架构设计复杂。

  3. SIMT 编程比 SIMD 简单,方便并行。

  4. 扩展方便,直接堆核算力可以到 10Tops 以上。

  主要玩家 GPU,从 MIMD 到 SIMT 的这条路 GPU 走了 10 多年,现在已经得道升天,称霸 GPGPU 市场。就像革命者最后都变成了当初自己反对的那一方,现在的 GPU 挑战者们也在这条路上。

ASIC


  ASIC(application specific integrated circuit)零指令纯数据流的 AI 芯片没有见过,我猜原因可能是极端功耗敏感的场景下,不深又不宽的深度学习网络效果还不如基于先验的传统 CV、DSP 算法。

  大部分 AI 芯片都可算半 ASIC 化,放弃部分灵活性专门加速 AI 计算。

3.2 AI 芯片的组成


做好深度学习网络的加速,一个科学合理的 AI 芯片架构,我总结了至少包含三部分:

  1. 矩阵乘加速,只做简单 MAC 操作,大算力专门加速 FC、CONV。

  2. GPU 单元,算力中等可编程,灵活支持不能 MAP 到 MM 单元计算。

  3. 调度中心,解决数据传输瓶颈,塞好塞满计算核。

3.2.1 矩阵乘加速


  正如 GEMM 处在 AI 的核心,MM(矩阵乘,Matrix Multiplication)加速单元是 AI 芯片核心的核心,。我归纳了目前最主流的两种加速架构:“超宽 SIMD”、脉动阵列。都由 PE 组成,每个 PE 自带 register file 和简单的控制逻辑。

超宽 SIMD 加速 MM


  这是最自然并行思路:PEs 一字排开,从 3 块连续的内存挨个读写数据做 MAC 操作。至于 pe 间有没有交互传递一些数据看设计了。正如前面介绍的 arm sve,只要实现 2048bits FMLA simd 指令,设计一下内存,做 AI 加速也不错。

脉动阵列加速 MM


  脉动阵列(systolic array)可以看作是 2D 的 simd,是目前最密集的矩阵计算结构,广受好评,大批 AI 芯片公司采用这种架构,有 google 、arm、nv 等巨头。。下面两图描述比较清晰直接。



图.TPU 示意



图.TPU 脉动阵列 cell 示意

  脉动阵列的优点:

  1. 2 个维度最大化复用数据,从上传下 PE 间复用权重和 partial sum,从左到左传 PE 间复用输入特征图。从邻居家拿数据,前后门传一下就行,不需要去共享大型 sram 取数据,省掉一堆寻址逻辑,数据能耗更低。

  2. 控制简化,布线简单,省下的晶体管资源,频率也更容易做高。

  3. 高效支持 FC 层和 CONV 层,只要互换 WEIGHT 和 Input 的处理方式。

  4. 该架构易扩展,多片并联或者单片增减脉动阵列尺寸很方便。

  有一个问题,脉动阵列由于尺寸和形状固定,数据会不会喂不饱?如 TPU 的 256x256 脉动阵列,当遇到 FC 层输入输出节点少、1x1 的卷积核等情况,reformat 数据就能?是否可以将"权重"固定在 weight register 上传下只要传 partial sum?还有要延迟 256 周期才能有第一个计算结果,对于大计算量的网络层算不值一提。

  arm 做了一个名为 SCALE-Sim( Systolic CNN Accelerator Simulator)的工具,从 PE 阵列大小和形状、数据流不同映射方式、sram 大小和带宽等多尺度来模拟评估性能,以便找出最佳配方的脉动阵列。

  我一个猜测:未来有 3DSram 基础上 3D 脉动阵列

举俩例子


  硬件实现好了,至于怎么利用那又是另外一篇文章。比如卷积用滑窗(sliding window)、im2col、winograd、fft 都可以设计,图像是要切块、切片、切条?切多大多厚也要测试。。。。都不容易。举两个例子:


开源的 NVDLA,内部 MAC 以 1024bits 宽并行计算 MAC,硬件实现 CONV、FC、Pooling、激活等层。有个基于 AWS FireSim 的开源项目,就用 rocket + nvdla 做了一个 AI 芯片。


NVIDIA 的 tensor core,volta 架构每个 SM(stream multiprocess)多了 8 个这玩意,一个周期完成 4x4 矩阵的乘累加共 64 个 MACs,听说内部是个小型的脉动阵列,有 SIMT、SIMT、脉动阵列 三种设计。还开放接口(WMMA)供用户灵活调用,CUDNN、CUBLAS 也不在话下。



图.TPU TensorCore 的 Core

3.2.2 GPU


  这部分主要特点是可编程算力,灵活支持各种日常所需,还有一个目的买一送一打开市场,让客户感觉买了 AI 芯片还送一个 DSP(GPU),毕竟 NVIDIA 都在买一送二:买 NVDLA 送 CUDA 再送 TensorCore。  算力设计有几个点要考虑:

  1. 根据各自负责的算法算力比例,相应设计 GPU 和 MM 加速单元的算力比。

  2. 根据可能的应用场景算力需求,如传统 CV 算法、音频算法、传统机器学习算法等。

  举个例子,假设端侧 AI 芯片总共有 4Tops 算力,那这个 GPU 分个 400Gops 很 ok。其实每个场景都不一定,全凭经验和理解。

  计算格式最好能够支持 int8、int16、fp32 三种(fp16 不要的原因后续),提供几百 Gops 的算力,还要方便用户调用做并行计算,只能上 SIMT 架构了。通过支持 OPENCL 标准,对接大量成熟 opencl 开源工程。如果 SIMT 每个并行小核也设计了宽度不等的 simd,更考验编译器水平。

3.2.3 调度中心


  AI 计算特点之一就是巨量数据的存取,这部分占整体能耗很大比例,尤其是通过总线的 dram,高延迟严重拖累整体效率。解决办法就是设立一个调度中心,包含 DataProcessor、内存系统,是整个芯片设计最复杂最需要优化的。

  DataProcessor 主要做深度学习网络的 reshape、flatten、slice 等数据搬运操作。根据计算复杂度和 GPU 配合,做一些数据的 reformat,如 deform conv、winograd、脉动阵列、padding 这些操作之前的 transform。还有很多 AI 芯片放在 GEMM 单元后面的 BN、Pool、激活层硬件单元,是不是可以去掉在这里搬运时顺道做。

  内存系统包含:DRAM、SRAM、DMA 等。DRAM 在片外,容量大传输慢一般也就 100GB/S,Sram 在片上纯晶体管组成,容量小传输快以 10TB/S 起跳,DMA 绕过 CPU 直接从内存存取数据。在 AI 芯片上和传统 CPU 有几点不同:

  1. 因为 AI 计算数据流相对简单和固定,Sram 采用 ScratchPad Mem 组织,有自己独立的地址空间,计算单元直接操作。相比常见的 Cache 设计,可以省下 Tag、比较逻辑,也不需要组相关全相连之类的 map 预测逻辑,更不用 L1、L2、L3 这种多级设置。

  2. 同样是因为数据流简单固定,DMA 的主要工作可以是 DRAM 和 SRAM 之间的数据传输。

  3. samrt DMA、内存同步,双缓冲等等之类,我也不知道怎么做,“知”的功夫还没达到“行”的境界。

3.3 其他


  ZeroSkip:主要是利用数据的稀疏性加速运算。细一些就在 MAC 内部做非零判断,粗一点直接做稀疏表达矩阵乘,后面软件部分会再聊两句。

  关于 MAC 多精度设计:现在业内关于低精度深度学习网络的研究也是热门,MAC 支持低于 8 位的 int1、int2、int4 等格式,除了可以刷 TOPS/W 去吹牛 B,也是有点实用价值的。不管是加法树、查表法实现乘法器,多精度支持的关键在于复用,尽量减少额外的芯片资源和能耗。另外不同的精度也需要相应调整 PE 阵列、带宽、SRAM 等。如下图是今年一篇论文的 AI 芯片研究,通过配置带宽、脉动阵列、MAC 精度等参数来适应不同的深度学习网络。



图.可配置 AI 计算核心


  PileLine:实际应用场景包含各种算法、AI 网络层,都可能 map 到 CPU、MM 加速、GPU 等计算单元上,在处理视频的连续帧,就可以找机会做帧间 PipeLine,如前处理和后处理等流程。

  存内计算:因为内存上数据搬运和芯片上数据计算都是晶体管状态改变,直接把数据存取、计算合一起做了,比较高调的 mythic-ai.com 和 syntiant.com。其实在 FPGA 应用常见,把 Register File 放进 PE 内也算一种内存优化:“近内存的计算或近计算的内存”。

  类脑计算:忆阻器直接模拟大脑神经元,电阻作权重电流电压作输入输出。

  模拟计算:传感器直接模拟信号低精度运行,不知道要不用加 AD/DA。这几天新闻热点导电碳纳米管做的 RISC-V 芯片。

  更屌的光计算:《几乎零能耗零延迟:UCLA 发明光衍射神经网络》,《光速执行 AI 运算,港科大双层全光学神经网络不要计算机也能做分类》,虽然现在很原始,但这也许超越碳基、硅基的另一种文明思考方式。 



图.神说.要有光

  这些现在都是科研热门,在资本市场也很吃香,很可惜我不懂。

4 软的


  AI 芯片讲究软硬一体说学逗唱,无论是卖 IP 授权、卖芯片、卖开发板、卖解决方案,芯片参数之外,一个友善的开发环境是客户最有感的东西,包括操作系统、驱动、IDE(图形化界面、profiler、debugger 等)、python/c/c++多种接口、自定义网络层(python、c 接口,map 到最合适硬件)、提供的 demo 细粒度可从应用->网络->网络层等。开发环境可以分阶段,比如先 c/c++接口再提供 python,比如嵌入式场景 python 是否合适?图形化 IDE 要不要?图形化神经网络这个噱头怎么吹?联机调试、指令模拟、交叉编译能不能省?

  硬件是少林功夫傻大黑粗练就对了,软件是唱歌跳舞观众有感,更需要身段透软、形象嗓音面面俱到。就算都做好了也上了台,也可能会被啤酒瓶砸头,然后看有人在台上唱、跳、rap 和篮球,号称练习了两年。



图.还踢球?

4.1 自研 AI 框架是必需品


  AI 框架包含训练和推理,毕竟云端训练需求的都是土豪,我没体会过土豪们的快乐,所以大部分时间可能都说的是 Inference。

  自研 AI 框架是必需品几个理由:

  1. 简单。因为深度学习算法由简单而暴力的算法堆砌,动手撸一个自己的框架并不复杂。所以现在写的不错开源框架遍地开花,甚至很多只是程序员业余时间开发。以 Inference 为例,无非是 parse 其他框架的模型,然后 deploy 到自己的平台上。如果是别人的平台,以我之前在 IOS 的先撸为例,CPU(NEON)、GPU(OpenGLes、metal)、NPU(CoreML)各种计算资源用起来要费点心思。

  2. 安全。自研框架自定义格式方便客户加密深度学习网络。

  3. 方便。相比照搬开源 AI 框架实现,自研框架更方便集成到软件开发环境,如 Debgger、Profiler 等,也更方便在自己硬件上发挥。

4.2 AI 编译器 ?编译器 AI !


  有人喜欢形而上提概念:用“AI 编译器”编译 AI 网络。我看好像只是一个 Inference 框架而已,言必称编译器过度解读了。原因:

  1. 传统编译器支持 x86\arm 几个硬件即可,而 AI 加速硬件实现有几十上百,自己不可能去自适应,要 AI 芯片公司自己来配合你标准的动机不够。

  2. 如果自己再硬凹一个开源硬件加速器去搭配这个编译器,感觉本末倒置因果颠倒了。

  3. 再说想要一个一劳永逸的 AI 编译器,并不能预知未来的 AI 进化成什么样子。

  我觉得可以反过读编译器 AI 也许有价值。用 AI 改造训练传统编译器,智能排流水、智能利用寄存器、智能矢量化、智能预取提高 cache 成功率等提高优化 GCC、llvm 编译效率。汇编这个活请不到那么多三哥偷偷在后台做,不会有类似这样的造假《用印度码农冒充 AI,这家明星公司挣了 1 个亿》。

4.3 自研 AI 框架实现


  AI 框架包括 parser、内存管理、计算管理。可以集邮票这种一点点收集的形式来实现,开始多一些 if else 可以容忍, 毕竟 AI 网络都很简单,做得多了再去归纳总结标准化也不迟。

  Parser 模块功能是解析各大框架的网络,如果自己一个个去支持(mxnet、torch、darknet、chainer、paddle、tensorflow、keras、pytorch..),特别是不幸遇到 tensorflow,其上百种类型几千个节点组成的静态图网络,吐血。不如先通过支持一些大公司推的中间标准格式,如 onnx、onnx 等,来的省事,当然用户看不到 onnx 这层。

  内存管理有几个要点:

采用预分配技术,需要分析整个网络架构,理想情况是网络运行前 malloc,运行中填空,结束后 free,尽量减少无意义的 memcpy 操作,Inplace 到极致。如 resnet 的 block 的 ADD 操作,第一个 conv 的输入可以作为最后一个 conv 的输出。

只是设计一个内存池来管理?但耗时的不是 malloc free 操作而是读写操作。


  计算管理主要映射、融合和优化。优化部分放在后面一节单独聊几分钟。

  映射是根据各个网络层的特质映射到相应的计算单元(主控 CPU、data processor、gpu、mm)运行。如逐像素的计算图像均值方差、MM 之前的 transform 操作、众多的指数操作、NMS、RPN、视频处理时前后帧的 PipeLine。

  融合最常见的是 Activation 函数融合到 NORM、CONV、FC 之后,省下一次内存的读写,还有如 nearest 算法对图像做 2X 的 Upsamle 操作也可以融合到其他计算,可融合的其实也不少。但是如果不同层 map 在不同计算单元上,就不好协同融合,更多是以硬件形式融合了,如 TPU 在 Accumulator 之后接了硬件的 Activation 和 Pool。

  再随便说几个细节:

  1. 留好 backward 接口,考虑周全些也许哪天被土豪云看上了。

  2. Deconv 层,有 Transposed conv、分子卷积(stride<1)等多种叫法,常在 encoder-decoder 网络的 decode 时做 upsample 用。光从多个名字就能猜出不同框架实现不同,有的是先对输入图 upsampe 填充 0 再正常卷积,有的先正常卷积再对输出图 upsample 填充 0。做算法 Deploy 需要注意,如果是调包侠可以用 upsample(nearest)+ 正常卷积替换,效果更佳。

  3. Instance Norm 层,Inference 时用 Training 过程的 runningmean 和 runningvar 效果会很差,尤其是图像检测和分割。宁可一张张单独算 mean 和 var,虽然添加了计算和并行流水架构被打乱。Batch Norm 层可能是因为 channel 数多,直接用 running 倒没那么糟糕。

4.4 AI 计算的优化


  主要是讲 CONV 的优化,FC 计算实际 MACs 不多,优化更在于巨量的 weight 稀疏性的利用,FC 层的权重和输入互换成 1D-CONV,可以运行在 MM 加速单元。

  CONV 计算可以分两种:1. 输入图像和卷积核转换成矩阵进行相乘。2. 直接滑窗实现。

  转换成矩阵乘的好处之一就是方便支持各种奇奇怪怪的卷积,在 transform 就做了 dialation、stride、deform、pad、非对称卷积核等处理,但会多几个数据 Transform 和额外的内存读写。直接滑窗可能不需要 Transform 和额外内存读写,但优化起来卷积方式相对受限,如 stride、dialtion 等逻辑在卷积过程处理的话,可能影响效率。

  关于数据流格式和数据复用,脉动阵列、tensoecore 这类相对尺寸固定,权重和输入图像固定了流向,已经最方便的复用了权重和输入图。心思更多是怎样对数据切分和 Transform,使之与脉动阵列达成最和谐的姿势。

关于优化切分

  昂贵快速的 SRAM 不放不下所有 FeatureMap、output、FC 层的 weight,必须要做切分。至于切块、横切、竖切怎么选,要考虑输入图像分辨率,channels 、Transform 方式、CONV 计算方式、MM 加速器的尺寸、Sram 大小、带宽等综合考虑。有时候是多种切法的组合,有时候不是切而是拼接。要保证切分后的网络精度,需要对图像进行无痛切分:在开刀处把邻居像素作为 pad 存下来,这样才能即无痕又不影响工作。

Winograd:

  Winograd 是一种降精度的卷积加速法,加速如 3x3 的小卷积核卷积。需要对输入、权重、输出做 Transform 操作,Transform 可以由简单的移位和加减法组成。有一篇文章 Sparse winograd cnn on systolic array,研究在脉动阵列上做 winograd 卷积。

  Winograd 计算如图所示,图像中每个 2x2 的块扩到 4x4 再 Transform,3x3 的卷积核 Tranform 到 4x4,一阵倒腾后做矩阵乘,最后再对矩阵乘结果做 Transform,图中还考虑同时做了输入图像 Channel 间的复用,有的开源 winograd 实现并没有这么做。通过转换,只要 16 个乘法就能得到 4 个点输出,正常卷积要 36 个。但多出了 Transform 的开销,需要衡量该开销和 MACs 减少带来的收益。加上 Winograd 总归是一种降精度近似计算,在已有的 AI 芯片方案中实际应用的好像也不多。



图. Winograd m =2 F(2x2,3x3)


FFT 加速卷积:

  快速傅里叶变换对图像分块做 8x8 或 16x16 的 FFT 蝶形运算,卷积核也要略大一些好映射到相应尺寸。但现在大卷积核在深度学习中并不流行,FFT 加速卷积的应用不多。

4.5 其他


4.5.1 量化(INT8)


  因为方便上手也为容易讲清楚,这里只讨论 int8 量化,其实嵌入式 AI 业内做低于 8 位的深度学习也是大热门,如 int1(二进制)、int2、int4 等,二进制网络见过几个团队做效果不错,int2、int4 精度现有 CPU、DSP、GPU 无力支持,只有 FPGA 上实现。

  关于浮点和定点:定点的表达逻辑比浮点简单很多,反映在芯片资源和功耗都是数量级的差距。测试过 INT16 模式运行完整网络,精度不差于 FP16。

  下面聊聊量化的几个知识点:

  1. 深度学习网络各种 norm 层(BN、IN),激活层(relu、selu、sigmoid、tanh)广泛分布,输入特征图、weight 常浮在是 0-1 附近。我简单统计了一些网络的权重值分布,一般单层 SUM 值差不多都在 10 左右,INT32 = INT8xINT8 + INT32 无溢出之忧。

  2. 网络训练一般 learnin grate 都从 0.001 甚至更小起步,一点点迭代抠精度。如果要以 INT8 训练,要修改训练框架的 GPU 加速部分,用浮点硬件模拟定点运算。

  3. IEEE 浮点数表达方式比定点复杂太多,int8 代替 fp32 省下的除了看得见的 24bit,在芯片资源占用和计算能耗都是数量级的提升。

  4. 秉持不麻烦客户的原则,所以现在 int8 量化都是 post training 阶段,只要网络和一些样本直接一键量化。



  受益于深度学习网络的鲁棒性和冗余性,量化得当一般精度降低范围可控。现在有不少开源的 int8 量化方案,很多应该源自 TensorRT,实现也大同小异。分为对称和非对称两种方法,以 CNN 卷积层为例。

  1. 对称算法应用于 weight 量化:

  2. 找出 group 内权重绝对值最大值 absmax.

  3. scale =127 / absmax .

  4. 对 weight 进项量化: weight=weight * scale.

  5. 非对称算法应用于 activation 量化:  处理激活值稍麻烦,我也试过对称算法,直接按照 absmax 量化效果非常糟糕。因为激活值分布范围广,也不如 weight 规整。

  6. 跑几张样本,保存所有的激活值,然后 flatten()操作拍平成一维数组 A,找到数组 A 最大绝对值 absmax.

  7. 计算直方图间隔单位值,histinter = absmax/bins,这里先设定 bins =2048

  8. 将数组 A 按照 histinter 间隔计算直方图。如果该 absmax 是一个很大的孤立点,那么会出现这张直方图都会落在左边一点点位置,明显很不均匀不 ok.

  9. 在 2048 里面找出一个值 T,将[0,T]区间的直方图分布作为一个分布 P,然后把 P 分成 128 份做一个 bin=128 的直方图 P1,然后把 P1 缩放成一个 bins 与 P 一样的分布 Q,用 P1 的均值作为 Q 的值。然后计算 P 和 Q 的相对熵。

  10. 通过循环找到一个点 T,让 P 和 Q 分布最相似。根据直方图 P 中 T 位置的边界中最大绝对值作为 absmax。

  11. scale =127 / absmax ,卷积计算时输出值量化 act = act * scale.

  不同的网络层类型和超参数,量化方式都要谨慎选择一一尝试找出最优解。如 CONV 层输入图像太大、channel 数多、FC 层输入节点太多等情况下,保证网络精度的考虑,是不是不量化了,或者量化到 INT16。不同芯片平台量化方式也有不同考量,比如是否 FP32、int8、int16 多种格式,而且不同格式间是否复用、算力有没打折,选取最具性价比的一种混合精度模式。不同应用场景,有不同的精度考量,比如图像按照量化敏感度排:识别分类<目标检测<图像分割,语音 NLP 领域,RNN、GRU、LSTM 等全部 FC 层更要用心对待好好相处。

4.5.2 稀疏、剪枝和蒸馏


  AI 网络的稀疏性产生,就像人类大脑年岁渐长大脑神经元连接变得固定,去掉很多神经元连接,所以异想天开的能力只存在那天赋异禀的少数。


  FC 层关注权重的稀疏性,CONV 层关注激活输出的稀疏。但是现在 VGG 里 4096x4096 类似规模的 FC 层不太在新网络架构出现,用 conv 层来代替 fc 层的也不奇怪。尤其是嵌入式 AI 领域,消除 FC 层稀疏权重是目标,认识一个做 KWS(keyword spotting)算法加芯片的团队,一直揉网络挤压尺寸从几 M 到几百 K。

  而 CONV 层卷积核参数本来就很少,之前由于因为 relu 引入造成输出的大量稀疏,但是现在 prelu、selu 之类加入抢救了一下负激活值,整个网络效果还提升不少,所以我倾向当 CNN 网络 run 起来是不稀疏的,再说稀疏性和 winograd、im2col、fft 之类 transform 再 gemm 的加速方法八字并不合。

  如果 retrain 做剪枝(删除小权重再找跑几个 epocs 微调剩下的权重,属于算法训练领域,调参师调包侠们的多调一个包,但是让算法变得硬件友好他们并不在意。基于不麻烦客户的前提,如果不 retrain 剪枝完后精度怎么保证?对着客户动辄几百 M 上 G 的网络,FC 层稀疏的权重真的置之不理吗?有几个办法:

  1. 在 inference 之前对权重进行处理,做行标、列标的 Index 数组,进行稀疏表达下的矩阵乘法。常用的如 CSR/CSC(Compressed Sparse Columns/Row),用前面非零数值的个数代替行(列)下标压缩。

  2. 在 MAC 内部做 zero skipping。

  3. 权重做 Huffman 压缩,计算换时间,这些逻辑多少会占用芯片资源。

  4. FC 层输入输出节点不能删减情况下,只是去掉小参数的连接,计算不均匀的情形怎么办?如用深鉴的论文介绍,如何对非零权重重新分组排列适配并行 PE 处理?

  秉持 Risc 不过度设计的宗旨,我觉得 AI 芯片要不要做剪枝可议,理由如下:芯片做深度学习推理时,FC 层大概率也是 CONV 层顺序执行的,FC 层完全可以复用 conv 层的硬件计算资源,脉动阵列对于 GEMM 的效率早已经过严峻考验,带宽、sram、PE 已经准备好迎接 FC 层。只要简单改下逻辑:把 FC 层的权重当作 CONV 层的输入图,FC 层的输入节点当作 CONV 层的卷积核。

  知识蒸馏,压缩大网络变小网络。怎样减少卷积层 channel 数、卷积核尺寸、fc 层节点数?本就不稀疏含水量不多的网络怎么蒸馏映射?需要 Retrain 的话训练策略方法改不改?大堆细节。最后还不如重新训练一个小的?!各大会议和媒体上吹水常见,但实际应用没见过。

5. 生态


5.1 拥挤的赛道


  《一文看全:全球 99 家 AI 芯片公司全景图,中国正在崛起》这篇文章列了 99 家 AI 芯片公司,赛道拥挤。我也随意聊几个曾经评估试玩的芯片:有 CPU、GPU 出身的,算力从 10G、100G、4000G 都有。也包括插电、电池供电、PCI-E 板卡等环境,都有个普遍特点:软件都不是很好用。。

  某 A 团队,专做语音识别方案,算力要求不高(RNN、DNN、LSTM),采用 CPU 加 HW GEMM,也跑得挺溜。  某绿浪公司 GAP8,1 个 risc-v 主控大核加 7 个 risc-v 从动大核,都含 32bits 宽的 SIMD 做 4 个 int8 并行加速,共享指令 cache,硬件同步,再加一个 HW CONV 单元。倒是挺省电的,算力 10Gops(int8)。感觉像 mimd 到 simt 的第一步。



图 绿浪 GAP8


  某 Esperanto 公司,走的更极端目标更远大:直接要用 risc-v 挑战 intel、arm、nvdia。16 个 64 位的高性能 rv 大核当 CPU,完整的 L1 L2cache 设计,4096 个 rv 小核并行做当 GPU。大小核都带 64 位 simd 指令处理。带 shader 编译器可吃鸡,带不知道加速什么的 ASIC,不知道 4096 个小核并行画面烫不烫?随意搜了下,只有一个 2017 年名为 simty 的项目,将已有二进制程序的 RV 指令 MAP 到 SIMD 和 SIMT 硬件,但 SIMT riscv 又在哪?基于 risc-v 的开源 GPU 个人有点期待。

  还有和某 GPU 公司玩的较多,篇幅有限就不介绍了。有一些在区块链割韭菜来做 AI 芯片,而且 cloud 端、edge 端都做。感觉怪怪的,不知真假动机。我的另一篇 韭菜 AI 大逃杀。

5.2 BenchMark 不服跑个分


  AI 芯片辣么多,挖掘技术哪家强?固定输入参数,跑钦定的网络层,刷 Tops/W 指标,除了去会议媒体吹,这种细粒度完全没有意义。不如选择一些典型识别、检测、分割网络,用 roofline 模型定义好神经网络的算力和数据带宽比例再跑或许科学一些。能整个网络 run 说明软件对于网络 deploy 初步过关。不细究硬件架构如何,按照 fps 数一排列立分高下,不服也不行。如果能再上一层跑实际深度学习应用场景,多个网络结合传统算法和一些逻辑处理,考验 cpu、dsp、音视频编解码、ISP 等综合 SOC 能力,这种 benchmark 客户会更有感。

  BenchMark 这种没啥技术含量但又有曝光度的好事情,小米、阿里、腾讯、fb 等公司都争着开源了不少工程,现在也没啥标准。

5.3 做芯片不赚钱就是交个朋友


  接触过的一些行业,随意聊聊。行业生态直接决定了芯片进展,如手机人脸快速识别这个高频需求,才算直接催生了 AI 芯片在手机领域的流行,因为 GPU/CPU 的性能和功耗都不达标,3D 结构光人脸快速识别的需求催生了苹果的 A11 NPU,安卓跟上了寒武纪、谷歌 visual core、高通等一众 AI 芯片,随之而来便是手机应用一波 AI 革新:人脸识别、场景识别、场景分割、相册图像理解、ocr 翻译、语音助手、离线翻译、AI 相机等。

  SOC 是 AI 芯片存在形态,根据应用选装集成如主控 CPU、音视频编解码及采集、蓝牙、wifi、usb、pci-e、axi、hdmi、mipi、stat、tf、arduino、ISP 单元、视频运动检测等。还有一种不多见是外挂 NPU 扩展已有 SOC 的 AI 能力,瑞芯微似乎就外挂了一颗芯原 NPU。SOC 形态中,如果能把 AI 计算那部分 DSP 能力开放出来加分不少,需要考虑怎样的接口方便用户调用做一些传统信号处理算法,如边缘检测、插值缩放、直方图统计、模板匹配、色彩转换、去噪等。

  云计算领域的 AI 芯片,谷歌、AWS、阿里云等土豪自研自用,传家宝不外泄。提高与 nvidia 议价能力,3 万单价的 NV 计算卡和 3 千的游戏卡怎么算成本?更重要是这一套完整的芯片研发流程,搭建起硬件设计、前软后端流片、编译器、AI 算法、AI 框架等整套闭环生态,一支高大上形象科学的研发团队呼之欲出,所以傻子才不做 AI 芯片。这里 AI 芯片算法训练是主流,需要 backward prop,内存需求高一个数量级,软件开发把芯片算力嵌入 tensforflow、pytorch、caffe 等开源框架最佳,不过大佬们都有自己深度学习框架,更方便集成和定制。

  云计算需要 AI 芯片灵活缩放能力、虚拟化、弹性化。灵活缩放的能力代表单芯片分割并行计算多网络分割,怎么切分 PE 阵列、分带宽、分 sram?放的能力代表多芯片相连分布式计算扩展(通过以太网口、NVLINK),硬件可以通过以太网口(nvlink)交互,软件上传统方法是采用一个参数服务器+多个计算终端模式中心化设计,逻辑简单效率低。比较创新去中心化设计如的 tensorflow 的 Ring All-reduce 算法(scatter-reduce + allgather),多个芯片组成一个一维或者 2 维环,每个芯片的分块计算结果在其中流动,都是从左(上)邻居拿数据,传数据给右(下)邻居,类似脉动阵列 partial sum 概念传递梯度,芯片内部和外部如此相似设计,说明重复和对称才是宇宙秩序和天理。



图.Ring all-reduce

  再聊一个 AI 视频云处理场景:用户上传原始视频、服务器解码视频、按帧识别检测 NSFW(鉴黄师)、人像分割(避免弹幕糊脸)、物体商品场景识别(视频标签、流量变现、多帧视频做时序分析(还不成熟)。此时芯片需要提供强大的 AI 计算能力之外,还要附带相应的多路音视频编解码 ASIC。竞品 NVIDIA 集成了 NVENC/NVDEC,FPGA 移植个 RTL 的事。



图.NVENC/NVDEC

  聊聊无人车、无人机、机器人,见最多还是成熟的 GPU 方案。不管规模大小的似乎每家公司都有自己的 AI 芯片计划,和互联网云巨头们类似:如果能够每年卖很多台,一台车俩 AI 芯片自研 AI 芯片这生意怎么看都不亏,如果卖不出量,AI 芯片概念在上市财报还是给投资人看,会有人买单,找别人现成的 AI 芯片方案冠个名也只是小钱。接触过几个无人机无人车团队,感觉技术方案里 AI 成分都不多。

  聊聊 Deep-Q-Learning(强化学习、CNN)的应用,这种输入图像输出操作的模式在游戏中也许可以,一天迭代几百万次,现实世界由没人会用这黑箱来做决策。常见还是深度学习提取特征然后再用逻辑判断(也没有 Q-table)。无人车为例:普遍多摄像头融合、多传感器融合后进行深度学习提取特征,如采用激光雷达点云卷积、双目融合、目标识别、目标检测、实例分割等技术,再判断车道、行人、标志、车辆等信息。无人车在现实环境中在线无监督训练学习,当前好像也没这需求,车载 AI 芯片暂时也不用考虑 backward propagation。

  还有其他功能如 NLP 智能对话、导航规划等对于算力的需求不大,端云配合双保险,断网也 OK 的。

  语音识别激活 kws(keyword spotting),速度要求实时同步采样帧率,算法复杂但计算量不多,交给 DSP 靠谱,如多阵列麦克风降噪合成。有的是电池供电场景功耗极端敏感,cpu+dsp/GEMM 技术方案灵活选择,DNN 小网络 int8 量化最好 retrain。

  关于 FPGA:1.作为 IC 开发的验证工具、开发平台,也是各大”AI 芯片“公司们的“产品实体”。2.在云计算和端侧,都是属于高端货。如云计算一块算力 4T 的 PCI-E 的 fpga 计算卡能卖 2 万多,蹭 NVIDIA 高价计算卡。edge 端也是无人机、高级摄像头的存在。

  嵌入式领域 AI 芯片,基于数据实时性、安全隐私和成本考虑,不方便上云运算。包括各种设备的智能升级,如音箱,冰箱、安防 IPCamera、DVR 等,检测识别人脸、人体、车辆、物体、灾情、动作等等。嵌入式 AI 这块我做过一些工作有点思考,不少考验:

  1. 考验 AI 芯片的裁剪能力,相比云计算高能版本,端侧精简版会不会费事费力二次开发?

  2. 考验 SOC 集成能力,需要:CPU 甚至 GPU(如带屏幕交互、人脸库快速存储检索)、音视频编解码 ASIC、运动物体检测 ASIC(光流角点计算)、DVAFS 动态电压调频、休眠技术(always on 省电场景)等。

  3. 考验算法优化能力,嵌入式可能会面对精简版 AI 和传统 CV 算法两种选择。支持传统 CV 算法,需要对如 haarlike 特征提取、积分图、人脸识别、卷积等计算热点加速,映射到 AI 芯片的 GEMM 单元,或是 DSP 单元来加速?

  4. 考验 IOT、AIOT、lora、nb、liteos...上来就能一顿胡扯的能力。

5.4 AI 芯片创业是机会?


  快速迭代的 AI 算法引领着行业的变革,老旧的芯片架构和工艺要跟上适应节奏。但 AI 芯片是基础设施,中小创业者的冒然闯入是机会?要活下去必须灵活应对市场和资本的瞬息万变,待客户和投资人如衣食父母,有理想要上进必须需要具备“全栈”能力:行业市场大局观、深度学习算法长久耕耘、芯片架构专家突破旧俗、前端后端尚可外包、软件开发环境、操作系统借助开源也要自己集成。一套昂贵的 veloch 仿真工具只是零头,人力开支,IP 开支,流片前后端研发、流片封装测试,够烧到哪一步?后面商业推广顺利否?好不容易做出来,发现比 NVIDIA、intel、海思等大佬的产品差一截,落个为国流片的结局,回想当初做矿机芯片割韭菜是什么结局?



图.我太难了

  传统芯片公司的慢节奏正被互联网公司带了节奏,玩敏捷开发(用户需求、快速迭代、模块化、标准化)。行业先知 DARPA 预见了变革,推的项目 CRAFT(Circuit Realization At Faster Timescales),目的集成电路快速定制、标准化做到加速开发。

  创业关于 3D 脉动阵、存内计算这些高端货创新,没资本驱动中小创业公司能不能活过一集?帮客户训练算法、编软件、嵌入式移植、端云结合的开发都是偶一为之的。卖 IP 授权的公司替客户做 IC design,蹭国产 AI 芯片的热点,也是种商业模式探索。有心做或许反而在其他领域栽柳柳成荫。


发布于: 2020-08-10 阅读数: 531
用户头像

flow

关注

还未添加个人签名 2020-02-26 加入

还未添加个人简介

评论

发布
暂无评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值