core sync是什么软件_NV DLA开源项目学习分享之-2深度学习软件栈/编译器(a)

接上篇TaT

https://zhuanlan.zhihu.com/p/338223669

本来打算这一篇写NV DLA软件栈的,结果一水就是这么长……临时决定分a,b篇了!

这篇通篇都在说背景扯有的没的TaT

还是借用一下清华尹首一教授的图吧,(#^.^#):

fe976992bedba2ac2865279db7df6d7d.png

从软件人员的角度,分类嘛肯定得按class来,不然就没有对象了,个么简单点我们可以把AI芯片分为几类:

1. 带指令集的芯片 – 编程开发方式类似 GPU、CPU

2. 不带指令集的芯片 – 编程开发方式类似DSP或者更low-level的ASIC

3. 可重构芯片 – 编程开发方式类似FPGA

4. 其他各种各样的形态 -据不完全统计存算一体、模拟计算、神经拟态、量子神经网络芯片、光学芯片、等等等等;根据老夫多年从(hun)业(quan)经验判断,离应用的距离还有点距离,主要还是集中在学术圈,跨足产业化

带指令集的AI芯片就是设计一套指令,来操作芯片做一些操作,大家应该都知道世界上比较著名的CPU芯片架构和指令集,什么x86(CISC)啊,arm(RISC)啊,MIPS啊,RISC-V啊等等,相信不少同学都学过计组啊微原啊什么的,x86的什么的汇编指令,数据MOV来MOV去,再ADD一下什么的。(最后考试还要写个游戏,痛苦的回忆起西北某高校的求学生涯(〃>皿<=))

有了指令集之后,就可以基于指令集做编译器了,gcc就是经典的c编译器了。

懒得打字,百度一下:

569fe1593d205041faa1525b18193dc2.png

不懂gcc啊编译器啊的同学们没关系(其实我也不懂编译器怎么实现的TaT,毕竟也没做过,这玩意挺考古的)看这里:“gcc后端经由一次读取步骤后,利用描述目标处理器的指令集时所取得的信息,将抽象暂存器替换成处理器的真实暂存器。此阶段非常复杂,因为它必须关注所有gcc可移植平台的处理器指令集的规格与技术细节。”

也就是说~有了指令集,做个编译器,就能用c代码编译生成目标平台的机器码了。

17778b18f5fd70bc15a3f5b013fb79bd.png

同学们会发现,这玩意都是垂直打通的,不具有兼容性。那么,中间件来一层。LLVM来咯。

a85b551c192f22bfa51b0d89cf25293f.png

LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。

LLVM 核心库提供了与编译器相关的支持,可以作为多种语言编译器的后台来使用。能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。LLVM的项目是一个模块化和可重复使用的编译器和工具技术的集合。

关键是这是个开源项目。也就是说,现在做芯片只要做了指令集,对接上LLVM,上面都有中间件现成的了~

说了这么一大堆,和带指令集AI芯片有什么关系呢?那当然是要做深度学习编译器啦!

先看传统编译器的输入输出

input: 沙茶酱真帅.cpp

output: marchine code

深度学习编译器(NN Compiler)

把深度学习模型当成一种数据流编程模式的话, 它本身也算是一种代码吧

input: NN models (for example:沙茶酱真帅.pb)

output: executable(marchine) codes on Hardware

emmm,具体NN complier怎么做容我卖个关子哈,下集再说下集再说(主要是画画天负图还没画好,上一期被师弟吐槽图画的太丑,这种师弟居然能毕业,哼)

94ae607a0e5bce54872b1e382825d5a2.png

简单点说呢就是,AI芯片实现个指令集,来操作芯片做一些操作,再把这个指令集对到LLVM,我们就能实现c语言到AI芯片咯。

再把深度学习的计算图变成c或者变成其他的中间件,再套上LLVM,大工告成~当然这里面还是挺复杂的,还要考虑很多控制流、计算的tuning啊schedule啊,怎么来做自动优化啊(别看gcc -o2-o3一键优化,其实贼贼贼贼贼麻烦!)

当然有梦想的话也可以不对接LLVM,自己垂直搞一套编译器。

NPU其实实现的功能相比CPU简单太多,因此指令集也不算复杂,有些厂家自研,有些厂家会套用VLIM(超长指令集),因为很多MAC都是1024bit什么的,很长很长,就……

细节后续有空再说,高阶玩家可以了解一下

1. MLIR

2. TVM

3. Tengine+Auto Kernel

吐槽一下就是谷歌搞的MLIR的新名词太多了,非常谷歌,很难受

TVM 代码比较难懂,做的还算挺完善的

Auto kernel是小姐姐做的,嗯,100%保真,repo看这里https://github.com/OAID

那么,说了这么多,我在做AI芯片的朋友们,有个特点就是-大厂才做指令集!(投入还是非常大的~)arm中国啊,寒武纪啊,verisilicon啊~

投入巨大的情况下,Start-up的朋友们要么按着一个市场个别模型卷,要么干脆跳过指令集了,反正做个ASIC,搞那么复杂干啥,做个没梦想的咸鱼有时候比画个大饼充饥多了。

那么怎么干呢,上NV DLA架构图;

d1c8318f22008ec44db474b988a05d9d.png

NVDLA对NN的所有op都通过硬化实现,包括:

  • 卷积运算core与buffer,(由于Conv layer权重信息过大且在部分模式如direct下会重复调用一块数据,为避免重复访问系统内存,因此设计了conv buffer,fc应该也是在这块硬件来处理。)
  • 单数据算子(Activation engine)
  • Planar Data Processor(Pooling engine)
  • Multi-Plane processor(Local resp.nom CDP)
  • 数据存储和 Reshape操作(DMA)

细节 看上一篇https://zhuanlan.zhihu.com/p/338223669

看到这些block,搞个最简单的方法,直写寄存器吧!深度学习不就那么些算子么,我们的硬件不也是照着那些个算子实现的ASIC么,直写寄存器好了呀!毕竟我们RTL都写了这点小事不是。

既然可以直写,或者直接操作硬件,那么搞点稍微高级点的,那做个c api直接调用,把control和运算封一起,底层全部封死算了。

当然说起来简单,实际上没这么简单,有些芯片可能直写寄存器,直接保存配置表,有些数据流的芯片可能封装简单一些,有些要考虑很多trick在封装里面解决,有些还有更奇怪的操作…可能封的不好性能也会有问题。

不过总的来说思路就是这样啦~比如卷卷卷:

https://github.com/nvdla/sw/blob/master/umd/core/src/compiler/engine-ast/ConvolutionOp.cpp

75928e47111447b92666f36a6c7d1e4f.png

把常用的算子都封成c api:

https://github.com/nvdla/sw/tree/master/umd/core/src/compiler/engine-ast

有同学会问一系列问题:

1. 封了这些算子上面深度学习模型咋调用呢?

最简单就手撸c代码来撸一个NN模型咯,或者拿一些现成的模型格式,比如NV DLA就有个caffe解析器来解析caffe的模型。https://github.com/nvdla/sw/blob/master/umd/core/src/compiler/caffe/CaffeParser.cpp

当然这样工作量还是会非常大,那拿一个已经对上兼容很多的模型格式来对接就可以了,比如

Tengine NNIR/ONNX/ncnn/TVM Relay IR都行~

2. 内存怎么弄呢,数据搬运那些呢?

最好运算的全封死……留下DMA接口。或者给个申请内存的接口,不然会发生什么,谁也不知道。

3. 调度什么的怎么办呢?

端侧NPU好多就一个大core,别调度了,直接啃吧。

4. 除了这些之外的可拓展性怎么办呢?

扩个毛啊,先把模型跑起来吧[○・`Д´・ ○]量化不挂用户用起来才是真的

5. 通用性?

莫斯科不相信眼泪,ASIC不相信通用性。

6. 这样是不是要runtime编译?

可以pre-build。也可以干脆生成c代码编译成.bin直接run。

这种方式听起来很简单粗暴,也不太美,毕竟美帝的科学和艺术还是挂钩的, Academy of Arts and Sciences。

实用主义一点的说,毕竟大部分同学也没和初恋在一起。

实际上这样可以在投入比较小的情况下,短平快的生效。对DNN处理器都好使,以后软硬件人员就在一个平台上交(si)流(bi),再也不会有芯片工程师吊软件说你不懂芯片了。所有的limited都在API层面可见。

完了找个完整的深度学习框架怼上去,最好是端侧框架,就能解决很多问题了。毕竟刚tape out一两版的芯片,招个几十人做深度学习指令集啊编译器啊软件啊算法啊把工具做的很通用很好,对绝大多数start up的AI芯片公司来说也不现实。具体怎么搞,第三篇再说。

当然,有这个梦想的很多,但是有时候也招不到这么多人,毕竟现在懂这个的同学们还是不太多。编译器、指令集都是几十年的冷板凳,在中国更没人搞了,毕竟上海深圳房价这么贵……

对FPGA-based那种可重构芯片,最初的想法是可以分块实现不同的功能块,还是硬件可配置的。想想非常的强大且美好,但仔细一想又有点不太对劲,毕竟FPGA开放出来用HDL对电路编程已经很烦了,再加上怎么实现NN,简直是万水千山总是情,柳暗花明又一坑。

怕不是要先把NN model翻译成c,再把c翻译成verilog(我这种骄傲的硅农,怎么也不会用高阶语言做FPGA实现的,哼),再vavido/ISE一整套,完了编译了一晚上,资源不够,碰,板子被砸掉了。

7b2fce20978803f039abf1b64f90b2e2.png

当然现在很多主流公司用这些做AI的话,也会做一些预编译的工作,IP core做做好,包括软件和硬件。电路网表也都事先准备好了,最后实现的就和NPU功能差不多的硬件了,频率低一些而已了,软件很多也是简单粗暴的封装接口去撸的。

对其他拟态芯片&……暂时没有研究,倒是有以前的博士同学留所没事问我什么硅光神经网络芯片……但也不请我吃饭,于是没有下文ing。


版权声明:本文为weixin_28698129原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。