Download as pdf or txt
Download as pdf or txt
You are on page 1of 92

|  硕士 学位论文


圓 





基 于 C N N 加 速器 的 深 度 学 习 编 译 器


设 计与 实 现

作 者 姓名 
张芳芳 

指 导 教师 姓 名 、 职 称 蔡 觉 平 教授

申 请 学 位 类 别 工学 硕 士


学校代码 10701 学 号 17111212547
分 类 号 TN4 密 级 公开

西安电子科技大学

硕士学位论文

基于 CNN 加速器的深度学习编译器
设计与实现

作者姓名:张芳芳

一级学科:电子科学与技术

二级学科(研究方向)
:微电子学与固体电子学

学位类别:工学硕士

指导教师姓名、职称:蔡觉平 教授

学 院:微电子学院

提交日期:2020 年 6 月
Design and Implementation of Deep Learning
Compiler Based on CNN Accelerator

A thesis submitted to
XIDIAN UNIVERSITY
in partial fulfillment of the requirements
for the degree of Master
in Electronics Science and Technology

By
Zhang FangFang
Supervisor: Cai Jueping Title: Professor
April 2020
摘要

摘要

近十年来,基于神经网络的深度学习技术将图像分类、语音识别和目标检测等技

术的准确率提高到了实用的水平。众多的科技巨头和初创公司都卷入其中,努力挖掘

各种可能的应用落地场景。深度学习技术已经走进并开始影响人们的生活。移动终端、
嵌入式系统、单片机以及各种 AI 加速器都是深度学习应用落地的重要硬件平台,不

同平台通常有不同的功能和特性,要在不同类型的设备上都获得最佳性能非常困难,

因为需要基于硬件对模型与运算核心同时进行优化才能充分发挥硬件的性能。所以在

现阶段为各种计算平台和加速器研发配套的软件工具来实现模型的高性能部署是深

度学习领域的一个工作重点,缺乏软件工具硬件就无法发挥其最大能效,也难以得到

推广。

本文以神经网络模型在低端嵌入式平台部署的挑战以及针对深度学习算法的定

制硬件对软件工具的需求为研究出发点,对深度学习模型的优化部署进行了研究,并

以本课题组的 CNN 加速器为目标设备设计并实现了一个深度学习编译器。实现了将

需要较复杂解析过程的深度学习模型计算映射到底层硬件的功能。本文的主要研究工

作包括以下几点:

(1)研究卷积神经网络从顶层模型到硬件体系结构的端到端优化部署,和深度
学习模型在低端微控制器部署的困难与挑战,提出适用于本课题组的集成了 CNN 加

速器的片上系统的深度学习编译器结构。编译器选择开放神经网络交换格式 ONNX

作为输入格式,并基于 ONNX IR 设计适合于编译器实现的具有足够表示能力同时又

相对简单的中间表示,编译器以该中间表示为载体进行模型优化和变换,并最终将模

型所描述的前向推理计算输出为等价的 C 函数。通过利用 C 语言良好的移植性与工

具链的成熟性,可以简化深度学习模型在低端设备的部署。
(2)研究神经网络模型的量化方法,量化是目前最广泛使用的模型压缩手段,

同时也是重要的模型加速手段,本文根据目标硬件资源的特点提出对应的模型量化方

案,并将模型量化的全过程内置到编译流程中,进一步简化了模型部署操作。

I
西安电子科技大学硕士学位论文

(3)设计并实现了基于 CNN 加速器的编译器后端,提出与体系结构相关的计算

管理、内存管理以及代码生成方案,研究 CNN 加速器的卷积计算原理及其限制,提

出基于 CNN 加速器的卷积实现方法。

通过测试表明,本文实现的编译器能够对预训练神经网络模型进行优化、量化以

及基于目标体系结构的代码生成。深度学习与 AI 芯片都是目前的热门研究领域,作

为连接深度学习算法及其实现的深度学习编译器也得到了越来越多的关注。通过了解
深度学习编译器,不仅可以加深对深度学习知识的理解,还对进一步学习其他成熟的

编译器框架有一定作用。

关 键 词:卷积神经网络,加速器,模型部署,编译器

II
ABSTRACT

ABSTRACT

In the past decade, deep learning technology has improved the accuracy of image
classification, speech recognition and object detection technologies to a practical level.
Many technology giants and startups are involved in it, and striving to tap various possible
application landing scenarios. Deep learning technology has begun to affect people's lives.
Many hardware devices, including mobile terminals, embedded systems, microcontrollers
and various AI accelerators, are important application landing platforms for deep learning.
Different hardware platforms often have different characteristics, so it is difficult to get the
best performance on all types of devices. Because in order to take full advantage of the
capabilities of the hardware, it is necessary to optimize both the model and the computing
core based on hardware. Therefore, at the current stage, developing software tools for
various computing platforms and accelerators is one of the priorities in the field of deep
learning applications. Without software tools, hardware cannot achieve its maximum energy
efficiency and gain popularity.

This article takes the challenges of deploying deep learning models on low-level embedded
platforms and the need for software tools for AI chips as the starting point for research,
conducts automatic deployment research of deep learning models. And implemented a
compiler that can map deep learning models to hardware. The main research work of this
article includes the following aspects:

1.Research the end-to-end optimized deployment of convolutional neural networks from


top-level models to hardware architecture. Investigate the challenges of deploying deep
learning models on low-end microprocessors. And proposed a deep learning compiler
structure suitable for the SOC system with CNN accelerator. Compiler take ONNX as the
input format, and based on ONNX design a relatively simple intermediate representation
that is suitable for compiler to implementation and has sufficient representation ability .
Compiler take intermediate representation as the object of model optimization and
transformation, and finally converts the model into C functions. By taking advantage of the
good portability of C language and the maturity of its tool chain, the transplantation of deep
learning models to low-end devices can be simplified.

III
西安电子科技大学硕士学位论文

2.Research the quantification method of neural network model. Quantization is currently the
most widely used model compression method, and it is also an important model acceleration
method. This article proposes a model quantization scheme according to the characteristics
of the target hardware , and the entire process of model quantization is built into the
compilation process, which further simplifies Model deployment.

3.Design and implement a CNN accelerator-based compiler backend, and propose


architecture-related calculation management, memory management, and code generation
schemes. Research the CNN accelerator's convolution calculation acceleration principle and
its limitations, and propose a Convolution implementation method.

Tests show that the compiler implemented in this article can optimize, quantify, and generate
code for the target architecture of pre-trained neural network model. Because deep learning
and AI chips are both currently hot research fields, deep learning compiler that connects
deep learning algorithms and their implementationhave also received more and more
attention. By understanding the deep learning compiler, can not only deepen your
understanding of deep learning, but also have a certain effect on further learning of other
mature compiler frameworks.

Keywords: Convolutional neural network, Accelerator, Model deployment, Compiler

IV
插图索引

插图索引

图 2.1 上下层神经元全部相连的多层感知机.............................................................. 7
图 2.2 典型的卷积神经网络结构示意图 ...................................................................... 8
图 2.3 卷积计算原理示意图 ........................................................................................... 8
图 2.4 多通道卷积计算示意图....................................................................................... 9
图 2.5 三种常见的非线性变换函数 ............................................................................ 10
图 2.6 CNN 加速器的整体结构 .................................................................................... 11
图 2.7 WRG 指令与 SRG 指令的编码格式................................................................. 12
图 2.8 可重构互联单元的逻辑示意图 ........................................................................ 13
图 2.9 能将模型导出或转换为 ONNX 格式的深度学习框架 ................................. 16
图 3.1 CNN 加速芯片模型部署软件栈示意图 ........................................................... 17
图 3.2 深度学习编译器架构 ......................................................................................... 18
图 3.3 解析器的工作流程图 ......................................................................................... 20
图 3.4 ONNX IR 布局..................................................................................................... 20
图 3.5 节点的结构化表示及其对应 OP 的拓扑 ........................................................ 21
图 3.6 编译器的 IR 布局 ............................................................................................... 22
图 3.7 计算图节点数据结构类图 ................................................................................ 23
图 3.8 通过运算融合来简化计算图和优化访存 ....................................................... 26
图 3.9 常量折叠优化示意图 ......................................................................................... 27
图 3.10 目标 SOC 在 FPGA 开发板上的资源占用情况 ........................................... 28
图 3.11 卷积层的量化计算过程 .................................................................................. 30
图 3.12 对称量化算法的示意图 .................................................................................. 31
图 3.13 编译器的量化处理流程图 .............................................................................. 32
图 4.1 神经网络的稀疏性示意图 ................................................................................ 35
图 4.2 加速器的卷积处理组件..................................................................................... 36
图 4.3 PE 单元的稀疏处理原理 .................................................................................... 37
图 4.4 加速器互联配置方案 1...................................................................................... 38
图 4.5 加速器互联配置方案 2...................................................................................... 38
图 4.6 加速器互联配置方案 3...................................................................................... 39
图 4.7 加速器执行一层卷积的流程 ............................................................................ 39
图 4.8 加速器卷积计算示意图..................................................................................... 40
图 4.9 按通道展开的卷积核示意图 ............................................................................ 41

V
西安电子科技大学硕士学位论文

图 4.10 计算单元分组示例 ........................................................................................... 41


图 4.11 计算分割算法示意图 ...................................................................................... 42
图 4.12 矩阵向量乘法示意图 ...................................................................................... 44
图 4.13 COO 格式的稀疏矩阵编码示意图 ................................................................. 45
图 4.14 权重的压缩格式及其数据存储结构 ............................................................. 45
图 4.15 编译器后端的工作流程 .................................................................................. 46
图 4.16 CNN 加速器类型的卷积节点属性 ................................................................. 47
图 4.17 编译器的激活值内存分配策略 ...................................................................... 49
图 4.18 记录节点生存期的类结构 .............................................................................. 50
图 4.19 编译器代码生成流程图 .................................................................................. 52
图 5.1 编译器的目录结构 ............................................................................................. 55
图 5.2 编译器 API 函数使用示例 ................................................................................ 55
图 5.3 计算图的 DAG 格式输出 .................................................................................. 57
图 5.4 特定环境下的编译器性能比较 ........................................................................ 60
图 5.5 编译器的整体验证流程图 ................................................................................ 61
图 5.6 测试模型的编译以及编译时间 ........................................................................ 62
图 5.7 编译测试模型生成的文件列表 ........................................................................ 63
图 5.8 编译生成的头文件代码 .................................................................................... 63
图 5.9 内存优化前后的内存占用比 ............................................................................ 64
图 5.10 编译生成源文件的核函数代码片段 ............................................................. 64
图 5.11 编译器输出的入口函数片段 .......................................................................... 65

VI
表格索引

表格索引

表 2.1 不同精度数据的动态范围 ................................................................................ 14


表 4.1 代码生成器的主要方法及其解释 .................................................................... 52
表 5.1 编译器源文件目录及其解释 ............................................................................ 56
表 5.2 与网络调试相关的编译选项及其解释............................................................ 57
表 5.3 测试用虚拟机的规格参数 ................................................................................ 58
表 5.4 模型量化前后的参数量、准确率与推理时间对比 ....................................... 58
表 5.5 Mnist 模型的权值和激活值浮点范围及对应量化缩放因子 ......................... 59
表 5.6 Cifar10 模型的权值和激活值浮点范围及对应量化缩放因子 ...................... 59
表 5.7 Lenet5 模型结构 ................................................................................................. 62
表 5.8 剪枝后的稀疏度与计算量 ................................................................................ 62
表 5.9 加速器片上缓存的地址映射 ............................................................................ 65
表 5.10 编译生成代码与手写代码性能比较.............................................................. 66

VII
符号对照表

符号对照表

符号 符号名称
𝑊𝑖𝑗 神经元之间的连接强度
𝑏𝑖 神经元的偏差
f 非线性变换函数
H 输入图像的高度
W 输入图像的宽度
𝐾ℎ 卷积核高度
𝐾𝑤 卷积核宽度
P 填充宽度
S 卷积步幅
𝑂ℎ 输出特征图的高度
𝑂𝑤 输出特征图的宽度
a lj 卷积层的输入输出通道
kijl 卷积核通道
C 输入通道数
r 浮点型数值
S 量化缩放因子
q 量化数值
Z 零点
x 张量元素
[] 向下取整
K 输出通道数

IX
缩略语对照表

缩略语对照表

缩略语 英文全称 中文对照


CNN Convolutional Neural Networks 卷积神经网络
ONNX Open Neural Network Exchange 开放神经网络交换格式
AI Artificial Intelligence 人工智能
PC Personal Computer 个人计算机
CPU Central Processing Unit 中央处理器
IR Intermediate Representation 中间表示
DSL Domain-specific Language 领域专用语言
GPU Graphics Processing Unit 图形处理单元
ASIC Application Specific Integrated Circuit 专用集成电路
NPU Neural-network Processing 神经网络处理器
TPU Tensor Processing Unit 张量处理单元
FPGA Field Programmable Gate Array 现场可编程门阵列
CGRA Coarse-grained Reconfigurable Architecture 粗粒度可重构计算
GEMM General Matrix Multiplication 通用矩阵乘法
FFT Fast Fourier Transform 快速傅里叶变换
GCC GNU Complier Collection GNU 编译器套件
SOC System-on-Chip 片上系统
RISC Reduced Instruction Set Computer 精简指令集计算机
DMA Direct Memory Access 直接存储器访问
JIT Just-in-time Compilation 即时编译
OP Operators 神经网络计算基本单元
API Application Programming Interface 应用程序接口
IDE Intergrated Development Environment 集成开发环境
NLP Natural Language Processing 自然语言处理
APB Advanced Peripheral Bus 高级外围总线
DAG Directed Acyclic Graph 有向无环图
AOT Ahead-of-time Compilation 提前编译
FLOPs Floating Point Operations 浮点运算次数

XI
目录

目录

摘要 .............................................................................................................................................. I
ABSTRACT ............................................................................................................................. III
插图索引 ................................................................................................................................... V
表格索引 .................................................................................................................................VII
符号对照表 .............................................................................................................................. IX
缩略语对照表 .......................................................................................................................... XI
第一章 绪论 .......................................................................................................................... 1
1.1 选题背景与研究意义 ............................................................................................. 1
1.2 国内外研究现状 ...................................................................................................... 3
1.2.1 深度学习编译器........................................................................................... 3
1.2.2 深度学习加速器........................................................................................... 4
1.2.3 卷积计算方法 ............................................................................................... 4
1.3 论文的主要研究工作 ............................................................................................. 5
1.4 论文章节安排 .......................................................................................................... 6
第二章 相关技术概述 .......................................................................................................... 7
2.1 卷积神经网络 .......................................................................................................... 7
2.1.1 卷积层 ........................................................................................................... 8
2.1.2 下采样层 ....................................................................................................... 9
2.1.3 全连接层 ..................................................................................................... 10
2.1.4 非线性层 ..................................................................................................... 10
2.2 CNN 加速器 .......................................................................................................... 10
2.2.1 CNN 加速器的整体结构 ........................................................................... 11
2.2.2 CNN 加速器的指令集架构....................................................................... 12
2.3 深度神经网络模型压缩 ....................................................................................... 14
2.3.1 模型量化 ..................................................................................................... 14
2.3.2 模型剪枝 ..................................................................................................... 15
2.4 ONNX ..................................................................................................................... 15
2.5 小结 ........................................................................................................................ 16
第三章 基于 CNN 加速器的深度学习编译器设计 ....................................................... 17
3.1 基于 CNN 加速器的深度学习编译器概述 ....................................................... 17
3.2 ONNX 模型的解析与重构 .................................................................................. 19

XIII
西安电子科技大学硕士学位论文

3.2.1 ONNX IR..................................................................................................... 20


3.2.2 编译器符号系统 ........................................................................................ 21
3.2.3 计算图重构 ................................................................................................. 24
3.3 计算图优化 ............................................................................................................ 25
3.4 编译器的模型量化 ............................................................................................... 27
3.4.1 神经网络模型量化方法 ............................................................................ 28
3.4.2 编译器的模型量化方案 ............................................................................ 28
3.5 小结 ........................................................................................................................ 33
第四章 基于 CNN 加速器的编译器后端设计 ................................................................ 35
4.1 基于 CNN 加速器的卷积神经网络计算 ........................................................... 35
4.1.1 CNN 加速器的卷积计算原理 .................................................................. 36
4.1.2 卷积计算分割方案 .................................................................................... 39
4.1.3 全连接计算 ................................................................................................. 44
4.1.4 权值压缩 ..................................................................................................... 44
4.1.5 偏置的处理 ................................................................................................. 46
4.2 体系结构相关的计算图变换 ............................................................................... 46
4.2.1 卷积节点变换............................................................................................. 47
4.2.2 体系结构相关的计算图优化.................................................................... 48
4.2.3 加速器卷积节点分解与优化 .................................................................... 48
4.3 后端的内存管理.................................................................................................... 49
4.3.1 激活值管理 ................................................................................................. 49
4.3.2 权值管理 ..................................................................................................... 50
4.4 后端的代码生成.................................................................................................... 51
4.5 小结 ........................................................................................................................ 53
第五章 编译器测试与分析 ............................................................................................... 55
5.1 编译器模块功能测试 ........................................................................................... 55
5.1.1 编译器目录结构 ........................................................................................ 55
5.1.2 编译器的网络调试功能测试.................................................................... 56
5.1.3 编译器量化功能测试 ................................................................................ 58
5.1.4 编译器代码生成功能测试与性能分析 ................................................... 59
5.2 编译器整体功能测试 ........................................................................................... 60
5.3 小结 ........................................................................................................................ 66
第六章 总结与展望 ............................................................................................................ 67
6.1 本文的工作总结.................................................................................................... 67

XIV
目录

6.2 未来的工作展望 .................................................................................................... 68


参考文献 .................................................................................................................................. 69
致谢 ........................................................................................................................................... 73
作者简介 .................................................................................................................................. 75

XV
第一章 绪论

第一章 绪论

1.1 选题背景与研究意义

深度学习是一种通过多层网络学习多个抽象级别数据表示的算法[1],属于机器学
习的一个分支,也是目前最热门的一个分支。在过去的 10 年中,人们见证了深度学
习在计算机视觉[2-4]、语音识别[5-6] 、自然语言处理[7]等领域取得的显著成果。深度学
习将许多 AI 技术推到了实用的地步,其中人脸识别和推荐系统业务在落地上做的较
好,医疗[8]、农业[9]、安防和金融也是深度学习的重要应用场景。虽然深度学习技术
在诸多领域表现出强大的优势和可拓展性,但近年来深度学习理论研究速度趋于减缓,
在如自动驾驶等一些应用领域上的可靠性问题也尚未解决[10-11]。未来深度学习能否维
持现有的热度和获得长足的发展与是否能有更多的深度学习应用落地息息相关。
与传统解决特定任务的软硬件算法不同,基于深度神经网络的深度学习算法依靠
从大量的训练数据中学习知识。这种从大量的数据中去匹配某种模式的学习方式,对
硬件的算力与存储有非常高的需求。且深度学习模型准确率的提升经常伴随着网络规
模的扩大,随着网络规模的扩大,相应对算力与存储的需求也会越大。相关研究显示,
自 2012 年以来最大规模的深度神经网络模型在训练时所需的计算呈指数增长,达到
每 3.4 个月翻一翻。
不过随着深度学习应用的普及,当下大多数的计算需求在于模型推理而不是模型
训练,模型推理的计算需求还将随着业务场景增加与用户数量增多快速膨胀。深度学
习的推理环境比训练更加复杂,目前深度学习应用被广泛的部署于包括移动设备、嵌
入式设备、机器人系统、无人机、自动驾驶车辆,甚至单片机在内的各种计算平台中。
与 PC 机还有服务器相比,多数嵌入式计算平台只具备有限的算力、存储以及功率,
所以许多模型难以直接部署在这些平台上。
为应对深度学习模型在嵌入式设备上的存储与低功耗计算问题,一种办法为通过
修改模型使其能够适应资源受限的计算平台,具体包括设计更适合移动端与嵌入式设
备的轻量级模型,例如视觉领域的 SqueezeNet[12]与 MobileNet[13],这两种模型具有相
对较小的模型尺寸与可接受的准确度,可以轻松的部署在现有的移动设备上;以及通
过模型压缩来达到削减网络尺寸的目的,常见的模型压缩方法包括量化[14]、剪枝[15-16]
和知识蒸馏[17]。另一种通用的解决方案为采用云端部署,即模型的推理在云端进行,
低端设备只需要向云端提供数据并接收返回结果,这种方法的缺点是易受网络波动的
影响,实时性、隐私性和数据安全性都比较差,而且云端部署的成本也比较高。在实
际的商业应用中,如果花费大量的成本带来的好处仅是使机器智能一点,那许多厂家

1
西安电子科技大学硕士学位论文

便会放弃使用人工智能。所以如何提高深度学习模型在嵌入式等边缘设备的可部署性
和降低推理所需的能耗,是学术界和工业界的共同关注点。
在多种嵌入式处理器中,通用处理器 CPU 一直都是深度神经网络计算的主要处
理器类型。现代 CPU 具备的分支预测和多级缓存等机制可以高效执行多种通用程序,
但这些机制对于提高深度神经网络计算效率却没什么用,因为大多数深度神经网络的
计算只是由数量较少的几种运算组成[18],
如向量运算、矩阵运算和其他线性代数运算,
这些计算通常涉及大量的参数且具有一定的规则性,而不涉及复杂的分支预测与控制
指令。面对图像识别与语音处理等深度学习应用的大量推理计算需求,构建能进行密
集低精度线性计算的 AI 芯片来加速模型推理是学术界与工业界的一个研究热点。近
年来,与深度学习相关的 AI 芯片产品层出不穷,从谷歌、因特尔和英伟达这样的科
技巨头,到寒武纪、地平线这样的这样的初创公司都推出了自己解决方案。
相比于通用处理器架构,AI 芯片这样的特定领域架构由于专用性强其设计逻辑
通常反而更加简单。随着芯片设计技术的成熟,这种相对简单的架构也能更容易跟随
AI 技术的发展实现快速迭代。但 AI 芯片的自定义架构和指令集一般无法与现有的编
译器以及库兼容,所以软件工具的开发对芯片的使用和推广至关重要,缺乏完善的软
件工具,硬件就无法发挥其设计优势与达到最大效能。

早期的深度学习模型部署工具主要通过调用第三方库或者手写汇编代码来加速
推理,这种方式在某些架构上可以达到最佳性能,但通常只针对较窄范围的 GPU 和
CPU 平台进行了优化。近年来,将传统编译器的编译优化和代码生成技术引入到深
度学习模型的推理框架中成为了一种趋势。目前已经有不少公司开源了针对自身框架
生态或芯片产品的深度学习编译器,并得到了数量众多的 AI 算法与芯片公司的关注
与参与。开源的深度学习编译框架在一定程度上降低了 AI 芯片公司自研编译器的门
槛,但 AI 芯片及其硬件系统的复杂性与多样性决定了相对通用的编译框架难以为所
有的硬件平台提供一个最优的解决方案。

综上所述,随着深度学习应用向低端设备的蔓延,以及针对深度学习算法的专用
架构的爆发,为专用硬件架构开发深度学习编译器也成为了一个研究热点。本文以深
度学习模型在资源受限的定制硬件上的优化部署问题为切入点,设计并实现了一个基
于本课题组 CNN 加速器的深度学习编译器,实现了将神经网络模型中的各个计算任
务高效的映射到硬件的各个执行单元的功能。由于目前国内在深度学习编译器这块的
研究还不多,所以本文的研究具有一定的意义。

2
第一章 绪论

1.2 国内外研究现状

1.2.1 深度学习编译器
针对深度学习算法的定制硬件的出现提高了模型部署到更多硬件上的可能性,但
也相应提高了软件设计的复杂度。过去深度学习模型只能部署在有限的几种设备上,
借助第三方库(如线性代数库 BLAS[19]和计算库 Intel MLK)或通过手工优化核心代
码经常可以达到最优的效果。随着硬件平台种类的激增,传统的手工优化和单一的解
释运行方式经常难以应对所有的应用场合。因此近年来将传统的编译优化思想以及代
码生成技术引入深度学习部署工具中,来简化以及优化深度学习模型到硬件平台的移
植得到了越来越多的关注。
深度学习编译器属于特定领域编译器的范畴,是一种为现代深度学习系统设计的
编译组件。深度学习编译器的发展还处于早期阶段,目前较知名的开源深度学习编译
框 架 包 括 有 谷 歌 的 XLA , TVM[20] , 英 特 尔 的 nGraph[21] , 还 有 FaceBook 的
TensorComprehension[22]、Glow[23],以及 ONNC[24]等。相较于同质量化严重的深度学
习框架,深度学习编译器大都还处于积极开发的阶段,各自的技术路线与侧重点都有
所不同。
XLA 是谷歌为 TensorFlow 开发的线性代数编译器,
虽然目前还处于实验性阶段,
但已经被用于实际的生产活动中。XLA 将接收到的 TensorFlow 计算图节点映射为被
称为 HLO IR 的内部表示并进行目标无关的优化,编译器后端则对 HLO IR 进行目标
相关的优化与代码生成。XLA 的优化对象主要为非密集算子,密集算子则直接匹配
内置的 C++优化库转为相应的函数调用。除了 XLA,谷歌还推出了针对深度神经网
络的统一中间表示 MLIR,用于连接不同抽象级别的模型表示。FaceBook 的 Glow 采
用了和 XLA 类似的策略进行计算图优化与代码生成,不过其面向的框架为 Pytorch
和其他能转为 ONNX 的框架,且更侧重于对多后端与新型硬件的支持。nGarph 可以
将特定框架的算子转为与框架无关的 nGraph IR,再通过转换器将 IR 转为特定后端的
优化代码,nGarph 还可以作为其他框架的插件,将其他编译器的中间表示转为 nGraph
IR 进行部署。ONNC 是针对开放神经网络交换格式 ONNX 实现的编译工具,该编译
器对 ONNX 的算子集有较全面的支持。
TVM 是一个端到端的深度学习编译与优化软件栈,目前由活跃的社区进行开发
与维护。TVM 可以从现有的深度学习框架模型中获取模型信息,进行联合图级和运
算符级的优化,生成特定硬件的优化代码。TVM 通过将图节点转为基于 Halide[25]的
中间表示进行嵌套循环的优化,可以对严重依赖于手工优化的密集计算算子进行打击。

3
西安电子科技大学硕士学位论文

TensorComprehension 与 TVM 有许多类似的地方,比如两者都借用了 Halide 的


计算描述与调度分离的思想、都提供了 DSL 来对算子的计算进行描述、都提供了手
工和自动的调度方法。两者间最大的不同在于调度部分。TensorComprehension 的 DSL
只用于描述计算,其调度可以自动完成。TVM 的 DLS 还提供了调度原语,其调度由
用户的调度指令完成。
此外 TVM、XLA 和 Glow 等编译器都实现了生成 LLVM IR 的后端。借助 LLVM[26]
成熟的优化器和代码生成器,可以进一步简化机器码生成的工作量与难度。

1.2.2 深度学习加速器
随着随着深度学习技术的广泛应用,为深度学习算法定制硬件加速器也成了学术
与工业界的研究热点,一时间涌出大量的相关论文与产品。
按技术架构进行分类可将深度学习加速器分为:相对通用的处理单元,如 GPU;
专为特定 AI 产品或服务设计的 ASIC 芯片,例如寒武纪的 NPU 和谷歌的 TPU 以及
因特尔的 Nervana;基于神经形态设计的神经拟态芯片,例如 IBM 的 TrueNorth[27];
以及基于 FPGA 的半定制设计,例如 Xilinx 的 Everest。ASIC 的全定制设计通常可以
达到最先进的能效、面积和吞吐量,是 AI 加速器设计中最常见的一种形式。
下面列举一些比较有代表性的 AI 加速器相关论文。寒武纪在 2014 到 2016 年间
陆续发表了 DIANNAO 系列论文[28],在论文中提出了一系列全定制 AI 加速器的设计
方案,涉及多种常见的深度学习加速算法和系统优化方案。谷歌在其发表的论文 [29]
中提出了一种以脉动阵列为计算核心加速矩阵运算的 AI 加速器 TPU,该加速器在谷
歌测试平台上的能效上大幅度优于当时的 CPU 与 GPU。MIT 在论文[30-31]中提出了一
种可重配置的深度学习加速器 Eyeriss,该加速器还针对卷积运算的数据复用进行了
优化,而后在 2018 年又提出了一种用于紧凑神经网络模型的加速器 Eyeriss v2[32]。清
华的 thinker 团队则提出了一种基于 CGRA 的可重构加速器[33],该加速器可以通过对
计算引擎单元阵列进行动态配置,实现以相同的硬件支持包括卷积在内大多数神经网
络运算。

1.2.3 卷积计算方法
深度神经网络中的卷积网络在图像识别与音视频处理领域有着广泛的应用。其中
卷积是卷积神经网络中最重要一类计算,典型情况下,卷积及卷积相关的转置运算能
占据 50%-90%的模型推理时间[34]。相比其他计算类型,卷积计算由大量的规则性计
算组成,同时存在大量的数据复用,因此具有很大的优化空间,是各种编译器和硬件
加速器重点打击的对象。

4
第一章 绪论

直接卷积计算是根据深度学习的卷积计算原理使用一个卷积核在输入图像上滑
动窗口,窗口内的卷积核参数与输入图像进行乘加运算得到输出特征图的一个像素值。
由于在卷积过程中要不断的滑动窗口,直接根据卷积定义进行编程时具有较高的时间
复杂度。
一种常见的卷积计算优化方法是先将卷积计算重塑为通用矩阵乘法 GEMM[35],
然后通过调用线性代数库或手写汇编代码来优化矩阵乘运算。这种方法的优势是比较
简单且相比直接卷积具有更高的通用性,但输入图像与卷积核的变形增大了卷积所需
的内存,所以一般不适合资源受限的嵌入式平台。
基于 GEMM 的优化方法忽略了卷积计算本身的特性,另一种被称为快速卷积算
法的优化方法则利用了卷积运算对图像起到的滤波作用原理,通过对特征图与滤波器
进行 FFT[36]或 Winograd[37]变换减少了卷积所需的乘法运算次数。其中 FFT 算法通过
将空域的卷积滤波转为频域的点积来来加速运算,这种方法具有很大的局限性,比如
不适用于小型的卷积核(目前的 CNN 模型多使用 1x1 或 3x3 的小卷积核),以及频
域复数计算的复杂度问题,所以这种方法在提出以后并没有得到广泛的使用。
Winograd 算法主要针对 3x3 尺寸的卷积核进行了优化,所以对小型卷积核的加速效
果明显,得到了较广泛的使用。

1.3 论文的主要研究工作

本文以深度学习模型在资源受限设备上部署的挑战,以及领域专用硬件对软件工
具的需求为出发点,对深度学习模型的自动化部署进行了研究,并以本课题组的 CNN
加速芯片为目标体系结构设计并实现了一个深度学习编译器。编译器实现了将需要较
复杂解析过程的预训练模型结构扁平化为可以被应用程序直接调用的等价 C 函数的
功能,通过复用设备原有的 GCC 交叉编译工具可以得到能被设备直接载入内存运行
的可执行机器码,达到了可以使开发者在不了解硬件细节和模型优化知识的情况下实
现模型优化部署的目标。本文的主要研究工作包括以下几个方面:
1.研究卷积神经网络的前向推理过程以及从顶层模型到硬件体系结构的端到端优
化部署,
提出适用于本课题组集成了 CNN 加速器的片上系统的深度学习编译器结构,
主要包括解析器、优化器和 C 代码生成器。
2.研究深度学习模型的描述方法,选择开放神经网络交换格式 ONNX 为编译器输
入格式,基于 ONNX IR 设计适合于编译器实现的具有足够表示能力又相对简单的中
间表示,并基于该中间表示对 ONNX 格式计算图进行重构。
3.研究神经网络模型量化的方法,根据目标硬件设备的特点提出对应的模型量化
方案,并将模型量化功能内置到编译器中,进一步简化模型部署操作。

5
西安电子科技大学硕士学位论文

4.设计并实现基于 CNN 加速芯片的编译器后端,提出对应的计算管理、内存管理


以及代码生成方案,研究 CNN 加速器的卷积计算加速原理及其限制,提出基于 CNN
加速器的卷积实现方法。
5.实现所设计的编译器,对编译器的各个模块功能进行验证,并通过一个实例对
编译器的整体功能进行验证和分析。

1.4 论文章节安排

本文的全部章节的内容安排如下:
第一章主要阐述了神经网络模型在资源受限的嵌入设备上部署面临的挑战,和针
对深度学习算法的领域专用架构对软件工具的需求;接着介绍了深度学习编译器、深
度学习加速器以及深度神经网络的卷积计算方法的研究现状;之后介绍了本文的主要
研究工作。最后介绍了本文的章节安排
第二章首先介绍深度卷积神经网络的结构特点以及各个层的概念和功能;然后对
本课题组研发的 CNN 加速器的总体结构以及自定义指令集架构进行了介绍;接着描
述了深度学习模型压缩方法,包括模型量化和剪枝技术;最后对开放神经网络交换格
式 ONNX 进行了介绍。
第三章首先介绍了基于 CNN 加速器的深度学习编译器设计,给出了编译器的总
体结构;然后阐述了编译器的内部符号系统设计,和基于该内部符号系统的计算图重
构细节以及体系结构无关的计算图优化;最后对编译器采用的量化方案以及量化计算
图生成流程进行了介绍。
第四章主要实现了一个基于 CNN 加速芯片的编译器后端,详细介绍了 CNN 加
速器的卷积计算原理和局限,以及基于 CNN 加速器的卷积计算分割算法,然后介绍
了编译器后端的工作流程,包括体系结构相关的计算图变换,内存管理方案,以及半
自动的 C 代码生成方案。
第五章在 Linux 平台上对所实现编译器的各个模块基础功能进行了验证,并通过
一个例子对编译器的总体功能以及编译器生成代码的正确性进行验证。
第六章对本文所设计的系统进行了总结,提出了设计的不足之处,并对还可以改
进的地方进行了展望。

6
第二章 相关技术概述

第二章 相关技术概述

2.1 卷积神经网络

图 2.1 所示为一个典型的深度神经网络结构示意图,由输入层、输出层和多个隐
藏层堆叠构成,其中每层都由多个神经元组成。这种上下层神经元全部相连的网络结
构又称为全连接神经网络或多层感知机,相比只具有单个隐藏层的感知机,全连接神
经网络通过增加隐藏层数提高了对复杂函数的拟合能力。全连接神经网络对应的计算
公式如式(2-1)所示,其中𝑊𝑖𝑗 表征输入神经元与隐藏单元之间的连接强度,𝑏𝑖 为隐
藏单元的偏差,f 表示非线性变换。

n
Yi  f (Wij  X i  bi ) (2-1)
i 0

Y0

X0 Y1

X1 Y2

X2 Y3

Y4
Input Layer Hidden Layer Output Layer

图2.1 上下层神经元全部相连的多层感知机

全连接神经网络中相邻层的所有神经元都相互连接,每个连接都对应一个权重。
权重的数量随着网络深度的加深和神经元数量的增长快速膨胀。大量的参数不仅意味
着需要大量的训练数据和计算资源来支撑参数的学习,还容易引起过拟合问题以及陷
入局部最优。
卷积神经网络(Convolution Neutral Network)是一种重要的深度神经网络。相比
全连接神经网络结构,卷积神经网络通过引入局部连接和权值共享机制有效的减少了
模型参数的个数,并挖掘了数据的局部结构特点,所以非常适合图像数据的处理,被
广泛应用于计算机视觉领域。卷积神经网络中的卷积操作主要受生物学中视觉皮层对
视觉信号处理机制的启发,一般认为最早的卷积神经网络雏形是福岛的
Neocognitron[38],Neocognitron 采用局部连接,且每个特征图只对特定的特征做出最
大的响应。不过目前得到广泛使用的卷积神经网络结构主要源于 LeCun 在上个世纪
7
西安电子科技大学硕士学位论文

90 年代提出的结构(现在被称为 LeNet)[39],该网络采用反向传播(Backpropagation)[40]
进行训练,可以用于识别手写数字。图 2.2 所示即为一个典型的卷积神经网络结构示
意图,主要由几个基本处理层组成,包括:卷积层,下采样层,非线性层和全连接层,
其中非线性层未在图中显示。

Convolution Sub-sampling Convolution Sub-sampling Full-conneced

图2.2 典型的卷积神经网络结构示意图

2.1.1 卷积层

图2.3 卷积计算原理示意图

卷积层是卷积神经网络最核心的处理层之一,卷积层利用卷积核(也称为滤波器
或特征探测器)从输入中提取特征,这种特征提取方式可以保留输入数据的空间关系,
所以非常适合在空间上高度相关的图像数据的特征提取。在卷积计算时,卷积核在输
入图像上以特定的步长滑动窗口,窗口内的卷积核权重与输入图像进行点积得到输出
特征图的一个像素值。图 2.3 为卷积计算原理示意图。输出特征图的尺寸由输入图像
形状、卷积核形状、填充以及卷积步长等多种因素决定,例如,高宽为 H 与 W 的输
入图像与高宽为𝐾ℎ 与𝐾𝑤 的卷积核进行填充宽度为 P,步长为 S 的卷积,输出特征图
的高𝑂ℎ 与宽𝑂𝑤 的计算公式如式(2-2)所示。

8
第二章 相关技术概述

Oh  ( H  K h  2 P) / S  1 (2-2)

Ow  (W  K w  2 P) / S  1

由于单个卷积核只能提取一种图像特征,若需要提取多种特征则需要多个卷积核。
多个卷积核对应生成多个输出特征图,每个特征图都为一个通道。对于常规的卷积,
卷积核的通道数与输入特征图一致,卷积核的每个通道与特征图对应通道进行卷积计
算,多通道卷积计算示意图如图 2.4 所示,对应的计算公式为(2-3),其中 a lj 为第 l
层的第 j 个输出通道, ail 1 为第 l  1 层的第 i 个输出通道, kijl 为第 l 层第 j 个卷积核的
第 i 个通道,𝐾ℎ 和𝐾𝑤 为卷积核的高宽,C 为输入通道数。

alj ( x, y)    a l 1
i ( x  h, y  w)kijl (h, w) (2-3)
iC j hKh wK w

1 output channel per filter

4 output
channels
3 input channels

图2.4 多通道卷积计算示意图

2.1.2 下采样层
下采样层又称为池化层,在卷积神经网络中,池化层主要用于提取高维特征,以
及在保留大部分重要信息的情况下减小特征图的尺寸,进一步防止参数过多引起的过
拟合现象。最常见的池化方式包括最大池化和平均池化,这两种池化方式都属于局部
池化,主要用于特征图的尺度变换。局部池化将每个通道的输入数据分割为小块(一
般不重叠),再取每个小块的最大值或均值作为输出像素点的值。若将一个通道内的
数据缩为一个点,则为全局池化,全局池化主要用于连接卷积神经网络中的卷积与全
连接部分。

9
西安电子科技大学硕士学位论文

2.1.3 全连接层
卷积神经网络中的全连接层通常位于卷积层之后。全连接层与多层感知机的结构
相同,即每一层的神经元都与下层的每个神经元相连,全连接的输出层通常连接分类
器函数(一般为 Softmax 及其变种)。卷积神经网络中的全连接层的主要作用为对卷
积层学习到的输入图像的高级特性进行组合并通过这些特征对输入图像进行分类。

2.1.4 非线性层
非线性层也是卷积神经网络中非常重要的层。卷积神经网络中的卷积和全连接操
作都属于线性变换,为了将神经网络应用于众多非线性模型,神经网络应当具备高度
的非线性特征。非线性层的作用即对卷积层和全连接层的输出施加激活函数来为多层
网络引入非线性特征,使得卷积神经网络能拟合任何非线性函数。常见的激活函数包
括 Sigmoid,Tanh 和 Relu[41],对应的公式与函数曲线如图 2.5 所示。在深度神经网络
发展的早期阶段主要使用 Sigmoid 和 Tanh 函数,在 AlexNetwork[42]出现之后,更不
容易出现梯度消失问题且更易计算的 Relu 函数逐渐取代了 Sigmoid 和 tanh 函数得到
了广泛的使用。此外 Softmax 也为激活函数中的一种,它只被用在网络输出层,用来
进行最后的分类与归一化。

y=1/(1+e^-x) y=2σ(2x)-1 y=max(0,1)


1 1 1

-1 -1 -1
1 1 1
A. Sigmoid B. Tanh C. Relu

图2.5 三种常见的非线性变换函数

2.2 CNN 加速器

本文编译器的一个目标设备为本课题组的集成了 CNN 加速器的片上系统,该系


统可以运行低算力的深度学习应用,下面对该片上系统的体系结构进行简单的阐述。
目标设备的微控制体系结构为开源的单核系统 PULPissimo[43]。PULPissimo 是苏
黎世联邦理工学院的集成电路实验室与 UNIBO 节能嵌入式系统小组的联合项目
"PULP platform"中的一部分。该系统结构包括一个处理器核心、自动输入/输出子系
统、存储子系统以及中断控制器等。Pulpissimo 的可选处理器核心包括 RISCY 与

10
第二章 相关技术概述

Zero-riscy,根据不同的应用场景可配置不同的处理器核心。其中 RISCY 是一个基于


RISC-V[44]指令集架构的具有 4 级流水线的有序单核处理器核心,也是目标设备采用
的核心类型。RISC-V 为加州大学伯克利分校研发的第五代 RISC 指令集架构,具有
开放与模块化的特点。RISCY 核心为 RISC-V 的基础整数指令集(RV32I),以及包
括乘法指令集(RV32M)、单精度浮点指令集(RV32F)、压缩指令集(RV32C)
在内的扩展指令集提供了完全的支持。
由于 RISC-V 的标准指令集仅使用了部分的指令编码空间,剩余的编码空间被预
留给用户用于自定义扩展指令,所以相比其他主流的商业架构,RISC-V 架构具有更
高的开放性与可扩展性,能更容易的在通用架构基础上扩展协处理器。基于 RISC-V
指令架构的 PULPissimo 系统也提供了相应的接口用于扩展协处理器。本课题组的
CNN 加速器即通过 PULPissimo 协处理器扩展接口被集成到该微控制体系结构中,加
速器能在主处理器的控制下处理一些特定任务,在处理完毕后再用中断的方式通知主
处理器。由于加速器的自定义指令集需要与 RISC-V 标准指令集进行联合编译,所以
需要对编译工具进行定制。下面从微架构和指令集两个角度对 CNN 加速器进行介绍。

2.2.1 CNN 加速器的整体结构

TaskBuffer Output
FFU Router PE
InputBuffer Buffer
x16 x16

Decode
r Control Logic

DataMusk PU
Compreed &
Encoder
Data SCU

图2.6 CNN 加速器的整体结构

本文基于的 CNN 加速器是深度学习领域专用架构,该加速器的一个特点为针对


稀疏神经网络进行了计算化简,其整体结构如图 2.6 所示。从逻辑架构上看,加速器
主要由计算单元、存储单元、稀疏处理单元、可重构互联单元以及控制逻辑单元组成。
其中稀疏处理单元由特征图获取模块(Feature Fetcher Unit,FFU),输入特征图还原模
块(Decoder),输出特征图压缩模块(Encoder)以及处理单元(Processing Elements,PE)
组成。特征图获取模块可以对输入特征图进行稀疏访存选取,即只将有效特征图数据
传输到计算模块。加速器的 Encoder 模块可以将计算得到输出特征图动态压缩为仅含

11
西安电子科技大学硕士学位论文

特征图中非零元素及其掩码的数据结构,来减少片上传输带宽需求。压缩数据的还原
则由 Decoder 模块负责。
加速器的处理单元为加速器的核心计算模块,由 16 个 PE 计算单元组成,主要
用于执行卷积层的乘累加运算,同时负责加速器的权值稀疏处理。PE 模块从 FFU 模
块获取所需的数据,PE 与 FFU 模块间的 Router 模块为由一系列译码器组成的可重构
互联单元,其作用为改变 FFU 与 PE 的连接关系以使 PE 阵列能够适应不同卷积层的
结构。除了 PE 模块,加速器计算模块还包括了一个标量计算模块(Scalar Computeing
Unit,SCU)和一个池化模块(Pooling Unit,PU)。其中 SCU 的主要功能包括对 PE
模块输出的多组特征图的中间产物进行累加。PU 模块则为 PE 阵列不能处理的池化
功能提供了支持。
在存储设计上,加速器根据卷积计算的特点采用了分块的存储器设计,加速器内
的独立存储块包括输入特征图缓存(Input Buffer)、输出特征图缓存(Output Buffer)、
权重缓存(Weight Buffer)以及偏置缓存(Bias Buffer)等。
加速器内各种功能单元的配置和触发由控制逻辑单元(Control Logic)进行控制,
控制逻辑由一系列的寄存器组成。用户可以通过加速器的自定义指令对这些寄存器进
行配置与触发。

2.2.2 CNN 加速器的指令集架构


上一小节提到,加速器的控制逻辑由一系列的寄存器组成,用户可以通过配置寄
存器来设置模块参数和触发加速器的功能单元。控制逻辑内的寄存器通过一条 WRG
指令进行写入,而加速器执行过程中产生的寄存器数据则通过另一条 SRG 指令进行
读出,加速器与片外存储的批量数据交换则由系统的 uDMA 模块完成。

31 12 11 76 0
WRG imm[31:12] rd 0001011

31 25 24 20 19 15 14 12 11 76 0
SRG imm[11:5] rs1 rs2 001 imm[4:0] 0100011

图2.7 WRG 指令与 SRG 指令的编码格式

加速器的 WRG 指令扩展自 RISC-V 六种基本指令格式中用于立即数赋值的 U 型


指令,其指令格式如图 2.7 所示。指令格式中低 7 位为指令的操作码,rd 表示要写入
的控制寄存器,剩余的位数则表示要写入 rd 寄存器的立即数。
加速器的 SRG(Store Register)指令扩展自 RISC-V 指令集中的 S-type 指令,其指
令格式如下图所示。SRG 指令的操作码 0100011 与 RISC-V 指令集中的 Store 指令相

12
第二章 相关技术概述

同,即表示该指令挂靠在 RISC-V 的 Store 指令下。同一操作码的不同指令通过[14:12]


位的功能码来区别。此外编码格式中的 rs2 表示源寄存器,rs1 与偏移量则组成 Store
的目的地址。
加速器的控制寄存器组包括 8 个 16 位宽的寄存器,下文分别使用 Reg0~Reg7 进
行编号,并对每个寄存器的功能进行介绍。
0 号寄存器 Reg0 用于配置输入图像的尺寸,其中低 8 位表示输入图像的宽,高 8
位表示输入图像的高。
Reg1 为特征图获取模块的使能控制寄存器,加速器的特征图获取模块由 16 个
FFU 单元组成,Reg1 寄存器的每一位分别对应一个 FFU,置 1 时表示激活该 FFU 用
于数据获取。
加速器的可重构互联单元由两组互联模块构成,分别由 Reg2 与 Reg3 进行配置。
图 2.8 所示为可重构互联单元逻辑示意图,从图中可以看出,互联模块内有 6 个数据
选择节点用于控制 FFU 单元和 PE 单元间的数据通路。Reg2 和 Reg3 寄存器的最低位
为外部输入使能位,置 1 时表示模块可以接收最左边箭头表示的模块外部输入;寄存
器的[6:1]位为分别对应每个数据选择节点的输入数据通路,置 1 时节点接收上方 FFU
传入的数据,置 0 时则接收侧面数据选择节点传入的数据;寄存器的[14:7]位则用于
指示每个 PE 计算单元所连接的数据选择单元,置 1 时接收上方箭头表示的输入,置
0 时则接收斜侧边箭头表示的输入;其余位的用途暂时保留。

数据获取单元 数据选择节点 计算单元

图2.8 可重构互联单元的逻辑示意图

Reg4 用于配置池化单元的池化核尺寸参数,其中低 8 位表示池化核的宽,高 8


位表示池化核的高,目前加速器仅支持尺寸为 2x2、步长为 2 的最大池化。

13
西安电子科技大学硕士学位论文

Reg5 用于配置加速器的标量计算模块 SCU,Reg5 的最低位起到池化使能的作用,


置 1 时表示在数据累加结果上紧接一个降采样操作,Reg5[6:1]用于指示标量计算模块
得到一个完整的输出特征图通道需要执行的累加次数,其余的寄存器位为无效位。
Reg6 寄存器用于配置 PE 模块,其中[3:0]位为卷积核的大小,由于目前 PE 模块
仅支持方形的卷积核形状,所以卷积核的高宽可用同一个数值表示;Reg6[4]为 Relu
使能位,置 1 时表示对卷积计算得到的特征图进行 Relu 激活。
Reg7 为全局使能控制寄存器,Reg7[0]用于使能 PE 模块,Reg7[1]使能池化模块,
Reg7[2]使能标量模块,Reg7[3]使能图像解压缩模块,其余位无效。

2.3 深度神经网络模型压缩

随着深度学习应用向资源受限的终端与嵌入式端转移,通过模型压缩来降低模型
的尺寸也成为了一个重要的优化部署手段。其中模型量化和剪枝是两个广泛使用模型
压缩方法。模型剪枝可以减少有效权重的数量,量化则减少了每个权重的比特数,这
两种方法也可以配合进行模型的深度压缩,即先进行剪枝,再对剪枝后的模型进行量
化与稀疏编码。

2.3.1 模型量化
量化是指将连续或较大的一组值映射到离散或较小组值的过程。深度神经网络模
型量化即用低精度(Low precision)数来表示模型的权重和(或)激活值。低精度是
与常规精度相对的一个概念,深度神经网络模型训练与推理的常规精度为单精度浮点
型(FP32),与之相对的低精度则可以是半精度浮点、16 位整型、8 位整型和 4 位定点
数据格式,还可以是二值(+1,-1)、三值(-1,0,+1)数据格式。低精度数值存储所需的比
特数比常规精度少,且定点数计算的复杂度也低于浮点计算(在浮点计算单元上执行
浮点点积需要的时钟周期通常比定点点积更多),所以通过网络量化既可以起到模型
规模压缩的作用,又可以降低深度神经网络的计算复杂性。

表2.1 不同精度数据的动态范围
数据类型 动态范围 能表示的最小正数

FP32 34 1038 ~  34 1038 1.4 1045


INT16 32768~  32767 1
INT8 128~  127 1

与 32 位浮点数相比,低位宽的数据类型在可表示的值的动态范围和粒度上有较
大的限制,表 2.1 为 32 位浮点型、16 位整型和 8 位整型数所能表示的数值动态范围
14
第二章 相关技术概述

和粒度。从连续且较大的数值组向离散且较小的数值组进行映射无可避免会丢失一些
信息,所以量化神经网络通常会带来一定的预测准确率损失。不过研究表明深度神经
网络对噪声的容忍度比较高[45],
采用恰当方式进行量化后经常也能满足预测的准确率
需求。

2.3.2 模型剪枝
神经网络模型剪枝是基于网络中存在许多冗余参数的假设通过去除无效或不重
要的连接或神经元来降低网络的计算量与存储需求的技术。根据剪枝的方式,模型剪
枝可以分为结构化剪枝和非结构化剪枝。
非结构化剪枝不对剪枝的形式进行限制,所以网络内任何位置的参数都可能被剪
掉,这种剪枝方式又称为权重稀疏剪枝。使用这种方法进行剪枝后得到的稀疏权值矩
阵是无规则的,所以这种剪枝方式通常需要配合提供了稀疏处理单元的特定硬件进行
模型的压缩存储与加速。
与非结构化剪枝相反,结构化剪枝对修剪的方式进行了一定的限制,根据剪枝粒
度的不同又可以分为向量级剪枝、卷积核级剪枝、通道级剪枝和组级剪枝。相比非结
构化剪枝,结构化剪枝得到的网络具备更高的规则性,在通用硬件上也可以得到较好
的模型压缩与加速效果。

2.4 ONNX

ONNX(Open Neural Network Exchange)是 Facebook 联合微软,亚马逊和 IBM


等公司推出的开源的神经网络交换格式。ONNX 提供了一种与框架无关的模型描述,
可以作为神经网络模型在不同框架间或框架与工具间转换的中间格式,从而实现多种
工具的协同工作。ONNX 的设计目标是帮助 AI 开发人员摆脱深度学习框架或生态系
统的约束,使得在开发或部署的任意阶段都可以选择最合适的工具,从而加速人工智
能研究的实现与应用落地。
ONNX 将神经网络表示为一种可扩展的计算图结构。ONNX 计算图为有向无环
图形式,其每一个节点都指代一种运算调用(OP),连接节点的边则定义了节点间的
数据依赖关系。计算图为神经网络模型的运算提供了一个全局视图,而不用指定每个
运算的实现细节。且 ONNX 只指定计算图的可移植序列化格式,不预设或暗示任何
特定的运行时实施方法,在运行时可以根据具体需求将模型以不同的形式在内存中进
行表示。
目前 ONNX 得到了众多框架、工具和硬件产商的支持。包括 PyTorch、MXNet、
TensorFlow、Keras 在内的多种主流深度学习框架中的模型都可以直接导出或转换为

15
西安电子科技大学硕士学位论文

ONNX 格式。模型在保存为 ONNX 格式后,既可以再转为其他格式的描述形式,也


可以通过 TensorRT 和 TVM 等推理引擎及编译器在各种硬件平台上运行。此外因特
尔、ARM、AMD 等硬件和芯片公司也都宣布支持 ONNX,微软还开源了针对 ONNX
的多个项目,如 ONNX Runtim——为 ONNX 格式模型设计的神经网络推理引擎,和
ONNX JS——在浏览器上运行 ONNX 格式模型的 JavaScript 库。

图2.9 能将模型导出或转换为 ONNX 格式的深度学习框架

2.5 小结

本章首先对卷积神经网络的结构以及几种主要的网络处理层功能进行了介绍;接
着对本文研究中所使用硬件架构——集成了 CNN 加速器的片上系统进行了介绍,并
对加速器的总体结构以及加速器的指令集与寄存器组进行了阐述;然后本章还简要的
介绍了两个广泛使用的神经网络模型压缩方法,即模型量化和剪枝;最后本章对开放
神经网络交换格式 ONNX 进行了介绍。

16
第三章 基于 CNN 加速器的深度学习编译器设计

第三章 基于 CNN 加速器的深度学习编译器设计

随着深度学习应用从云端向嵌入式设备过渡,在低算力嵌入式端集成深度学习加
速器也成为了一个研发热点。在资源受限的嵌入式设备上(尤其是集成了专用加速器
的嵌入式设备上)部署深度学习应用面临许多挑战,其一,如何高效的将神经网络模
型的计算任务映射到合适的硬件单元上;其二,如何降低神经网络模型推理的计算量
与内存需求。本文以神经网络模型在资源受限的专用硬件上部署面临的挑战为切入点,
设计了一个面向低端微控制设备的多层次可扩展深度学习编译器,并以本课题组的集
成了 CNN 协处理器的 SOC 系统为目标设备对编译器进行实现,并最终达到了可以使
开发者在不了解硬件细节和模型优化知识的情况下实现模型优化部署的目标。本章首
先介绍了本文编译器的总体结构,然后对各个模块的设计进行具体介绍,包括用于模
型解析与重构的解析器,与硬件架构无关的中间表示设计,以及与体系结构无关的计
算图优化和编译器量化策略。与体系结构密切相关的编译器后端设计将在下一章具体
讨论。

3.1 基于 CNN 加速器的深度学习编译器概述

Onnx Compiler program file


model option

GCC

Compiler
executable file

J-Tag
C code

HardWare

图3.1 CNN 加速芯片模型部署软件栈示意图

神经网络模型在特定目标设备上的部署问题通常可以通过定制编译器与提供运
行时(runtime)来解决。现有的深度学习编译框架主要针对通用处理器 GPU/CPU 进
行模型优化与代码生成,或是预设目标平台可以提供一个包括解释器和加速库的较复
杂运行时,对于第二种情况编译器所需的工作仅为将模型编译成可在目标设备上解释
执行的 API 调用或可加载的扁平模型,
这种方式适用于目标平台不对外开放机器细节

17
西安电子科技大学硕士学位论文

的情形,但对于集成了加速器的部分低端微控制设备却并不适用。例如本文的目标设
备为集成了 CNN 加速器的裸机 SOC,在其上部署深度学习模型时需要先将模型交叉
编译为可直接载入内存运行的机器码。面对上述需求,本文的编译器设计通过将预训
练神经网络模型的前向推理过程转为等效的 C 代码,并复用目标平台原有的编译器
工具链来实现深度学习模型在低端设备上的部署,专用硬件的自定义指令则以内联汇
编的形式进行支持。图 3.1 所示为本文与模型部署相关的软件栈示意图,可以看出模
型的编译只是整个应用部署流程的一个环节,作用为将需要较复杂解析过程的神经网
络模型扁平化为等效的 C 函数,而后的工作则仍交由目标平台原有的开发工具链来
完成。
本文的深度学习编译器结构如图 3.2 所示。从图 3.2 可以看出,深度学习模型的
编译是一个多层次的过程,模型在不同的层次有不同的表示形式,比如在前端为框架
模型形式,在优化器中则是与前端及硬件架构无关的计算图,计算图在后端被赋予与
体系结构相关的信息,最后被转为等价的 C 代码。这种包括前端、优化器和后端的
三段式编译器结构也是目前最常见的通用程序语言编译器与深度学习编译器设计方
法。

ONNX模型

前端
模型解析与计算图重构

优化器
体系结构无关的计算图
变换

后端 体系结构相关的计算图
变换

代码生成

C代码

图3.2 深度学习编译器架构

与通用编程语言编译器相比,深度学习编译器需要面向的“源”与“目标”的种
类更加多样化,所以在编译器设计时的一个重要考量是软件的可扩展性和可持续性,
以避免在扩张支持更多框架模型和目标设备或是原先支持的硬件架构发生变动时对
现有的软件架构造成较大的冲击。在可扩展性这一点上编译基础框架 LLVM[26]做的非

18
第三章 基于 CNN 加速器的深度学习编译器设计

常好,LLVM 优秀的模块化设计以及其易于前端生成且具有足够表现力的中间表示
LLVM IR,使其具备强大的灵活性、可复用性和可扩展性,所以 LLVM 的应用并不
局限于传统编译器的后端,而是几乎所有需要 JIT 和 CodeGen 功能的应用场合,包括
数据库、区块链、分布式交叉编译和深度学习编译器等。包括本文在内的许多编译器
在设计时都直接或间接的借鉴了 LLVM 的一些设计思想,一些较成熟的深度学习编
译器框架还将 LLVM 作为其一个后端来复用其强大的优化器与代码生成器。下面基
于图 3.2 对本文编译器的各个层次的主要功能与设计思想进行概述。
(1)前端。编译器前端的作用包括:接收模型,验证模型的有效性以及将模型
重构为编译器内部表示。目前编译器只提供了一种模型载入方式,即通过解析器载入
一个完整的模型文件,接收的模型文件格式为开放神经网络交换格式 ONNX。选择
ONNX 作为编译器输入格式的主要原因为,ONNX 的定位即作为模型在不同框架间
或框架与工具间转换的中间格式,目前包括 PyTroch 和 TensorFlow 在内的大多数主
流深度学习框架都支持将模型导出或转为 ONNX 格式,所以使用 ONNX 作为输入格
的优势为可以在未添加多个模型解析器的情况下直接或间接的支持多种框架模型。
(2)优化器。优化器的主要作用为接收编译器前端构建的计算图进行体系结构
无关的计算图变换与优化,编译器提供的计算图优化策略包括算子融合、死代码消除
以及模型量化等。通过对计算图进行等价变换,可以降低计算图的计算复杂度和空间
复杂度,减少模型推理的运算时间。模型的低比特量化则可以起到压缩模型尺寸与降
低网络计算复杂度的作用,同时还可以满足专用硬件对量化计算的需求。
(3)后端。后端是编译器中与目标体系结构密切相关的部分,主要功能为生成
针对特定目标体系结构的优化代码。本文以本课题组的集成了 CNN 加速器的 SOC 芯
片为目标体系结构,设计并实现了一个编译器后端。后端以优化计算图为输入,进行
体系结构相关的变换和优化,以及运行时数据的生成和压缩、计算管理、内存管理和
代码生成等。

3.2 ONNX 模型的解析与重构

本文所述编译器将前端实现为一个解析器。解析器即用于将某种格式的文本或字
符串转换成某种数据结构的功能模块,在传统编译器中解析器对应于编译器的语法分
析器,用于将程序文本转换成编译器内部被称为“抽象语法树”的数据结构,而本文
的深度学习编译器为领域专用编译器,解析器的解析对象则为特定格式的模型文件。
解析器的总体工作流程如图 3.3 所示。
解析器的主要工作包括 ONNX 模型文件的加载、解析以及计算图重构。ONNX
使用 Protocol Buffers(简称为 ProtoBuf)作为深度学习模型的序列化存储格式,所以

19
西安电子科技大学硕士学位论文

解析器需要先对读取的模型文件进行反序列化才可以得到对应模型在内存中的表示
形式。在得到 ONNX 格式的计算图后,解析器需要将计算图重构为编译器内部 IR。
虽然 ONNX 格式的计算图也可以为网络计算提供全局描述,但其符号系统较为复杂,
有些特定于后端的变换也无法直接在 ONNX 图上实现,所以不适合直接作为编译器
内部的中间表示。IR 设计是编译器设计的一个重要环节,IR 设计的好坏直接影响代
码的可读性、编译器的可扩展性以及是否易于实现各种优化与变换。解析器在得到
ONNX IR 后将根据编译器内部符号系统对计算图进行重构,下文将对 ONNX 的 IR
布局,编译器内部符号系统以及计算图的重构过程分别进行描述。

ONNX模型 反序列化 ONNX IR

解析 重构 计算图

图3.3 解析器的工作流程图

3.2.1 ONNX IR
ONNX IR 的整体布局如图 3.4 所示。ONNX 使用顶层数据结构 Model 表示整个
机器学习模型,其内部具有多个属性字段,其中 Graph 属性涵盖与模型结构以及参数
相关的所有信息。除了 Graph,Model 内部的其他字段还记录了与 ONNX IR 版本以
及模型的算子集相关的其他模型信息,
这些信息对于 IDE 和模型库等工具非常有用。

Model Graph Node

Graph Name Name


IR Vesion Node List Operation Type
Operator set ID Tensor List Input List
Doc Input List Output List
Metadata Output List Attribute List
Other stuff Other stuff Other stuff

图3.4 ONNX IR 布局

ONNX 使用计算图对网络模型的计算进行抽象,Model 内部的 Graph 数据结构则


是计算图的序列化实现,Graph 由节点列表(Node List)
、参数列表(Tensor List)和

20
第三章 基于 CNN 加速器的深度学习编译器设计

其他属性字段组成,其中节点列表中的每个节点都指示一个算子(OP)调用,参数
列表则以张量的形式存储模型的权重参数。
ONNX 使用 Node 数据结构来表示计算图节点,每个节点都对应一个 OP 的调用。
节点的属性包括节点名称、OP 类型、输入列表、输出列表和属性列表。一个节点可
以拥有 0 或多个输入以及 1 或多个输出,节点输入列表中的每个输入都对应 OP 的一
个操作数,而输出列表则对应 OP 的各个计算结果。图 3.5 所示为 ONNX 卷积节点的
结构化文本表示以及该节点对应的 OP 拓扑结构,节点的输入和输出通过空间位置与
OP 的操作数和结果对应,而节点属性通过名称与 OP 的属性对应。

""{ data kernel_shape = [ 5, 5]


input: "0"
pads = [ 0, 0, 0, 0]
input: "1" weights strides = [ 1, 1] out
input: "2" dilations = [ 1, 1]
output: "9" group = 1
bias
op_type: "Conv"
Attribute: {
strides : [ 1, 1]
dilations : [ 1, 1]
group : 1
kernel_shape : [ 5, 5]
pads : [ 0, 0, 0, 0]
}
}

图3.5 节点的结构化表示及其对应 OP 的拓扑

ONNX 使用张量作为数据存储与传输的媒介,ONNX 张量属性包括张量元素类


型、静态形状和元素值等。目前 ONNX 支持的张量元素类型包括 16 位、32 位、64
位的浮点类型,8 位、16 位、32 位、64 位有符号和无符号整数类型,以及复数类型,
布尔型和字符串类型。由于并不是所有计算都涉及张量布局信息,所以 ONNX 将张
量布局设为节点属性而不是张量属性。

3.2.2 编译器符号系统
上一小节对 ONNX IR 布局进行了介绍,本节则对编译器内部 IR 的结构与设计
思想进行介绍。编译器 IR 总体布局如图 3.6 所示。可以看出编译器的内部 IR 基本沿
用了 ONNX IR 布局,即使用 Model 作为 IR 的顶层数据结构,使用 Graph 作为计算
图的序列化实现,使用 Node 表示图节点,并使用张量 Tensor 作为数据存储与传输的
媒介,但编译器对各个类型数据结构的接口与实现进行了重新定义。
(1)Model

21
西安电子科技大学硕士学位论文

相比作为模型存储格式的 ONNX Model,编译器 Model 省去了与前向推理无关的


模型信息项,并添加了一个名称列表用于记录 Model 名称空间内的节点名称,编译器
可以借助该名称列表为节点生成在 Model 名称空间内独一无二的名称。为节点生成名
称的主要作用为便于对网络进行调试打印。此外,Model 内部还定义了一系列接口用
于计算图构造,独一无二名称的获取和计算图的访问等。

Graph
Node
Name
Node List Name
Model Node Kind
Weight List

Graph Input Node Output List

Name Set Output Node Use List

Other stuff Other stuff Other stuff

图3.6 编译器的 IR 布局

(2)Graph
编译器 Graph 的主要属性包括计算图名称,存放计算节点的 计算节点列表
NodeList,存储模型权重参数的数据节点列表 WeightList,表示计算图起始节点和终
止节点的 InputNode 和 OutputNode,以及指示该计算图所属模型的 Model 指针。编译
器的计算图设计采用了计算节点与数据节点分离的策略,以便后续对计算图进行各种
变换。Graph 提供的接口包括一系列节点构建函数,节点添加与删除函数,节点访问
函数,以及与调试相关的计算图打印函数。
(3)Node
在上一节提到过,ONNX IR 使用 Node 数据结构来统一表示所有的计算节点,并
通过输入列表、输出列表以及属性列表来隐藏不同类型节点在输入输出个数以及 OP
属性上的区别,因此不同类型的节点能存放于同质容器中。ONNX 计算图节点的数
依赖关系(在一个节点中使用的在其他节点中定义的值)通过引用其他节点或参数的
名称建立,而控制依赖关系(在一个节点被执行之前需要执行的其他节点)则通过节
点在顺序列表中的存储顺序表示。ONNX 的节点组织方式对于建立网络计算的全局
描述已经足够,但难以应付复杂的计算图变换操作。
本文的编译器在进行 IR 设计时,则借助了 C++语言的面向对象特点,将所有类
型节点的共同属性与通用接口抽象为一个 Node 基类,而不同类型节点的独特属性与
接口则在派生类中进行定义,通过利用继承自同一基类的派生类指针可以被赋给基类

22
第三章 基于 CNN 加速器的深度学习编译器设计

指针的特性,可以使用一个存储基类指针的同质容器进行计算节点的存储。这种设计
的优点在于可以将节点的输入输出以及其他属性以独立的数据成员的形式在派生类
中进行定义,并将节点的输入与对应 OP 的操作数通过名称进行关联,而不是通过位
置,可以使得代码更加清晰。节点间的控制依赖关系则通过两个分别指其前驱与后继
节点的指针进行维护,这样在对计算图进行一些会打乱其在顺序容器中存放次序的操
作后可以方便的对节点的顺序进行调整。编译器与 Node 相关的类图如图 3.7 所示。

NodeBase<T>
- m_pre: T*
- m_kind:T*

Node Use Value


- m_name: string - m_parend: Node* - m_node: Node*
- m_kind:NodeKind - m_value:Node* - m_No: int
- m_users: list<Use>
- m_results: vector<Result>

ConstNode Tensor
Conv2DNode - m_payload: Tensor* - m_data:uint8_t*
- m_input: Value - m_kind: ElemKind
- m_weight: Value - m_shape:vector<int>
- m_bias:Value - m_stride:vector<int>
Placeholder - m_scale:float
- m_kShape: Vector<int>
- m_strides: Vector<int> - m_offset:int32_t
- m_pads: Vector<int> - m_layout:string
- m_dilations: Vector<int> - m_device:Device
- m_group:int - m_isNull:bool

图3.7 计算图节点数据结构类图

编译器在所有节点的共同基类 Node 类中定义所有节点的共同属性与通用接口,


包括节点名称、节点类型、节点的输出列表以及节点的使用者列表。由于节点的输出
值为编译期未知的量,所以 Node 的输出列表仅用于记录节点输出值的类型和形状等
信息。节点的使用者列表 m_user 则记录了节点输出值的使用者,该属性的作用包括:
首先,在对计算图进行变换操作时可以根据该列表快速的更新节点的数据依赖;其次,
记录该节点是否被使用,未被使用的节点可以通过死代码消除优化进行剔除。
从图 3.7 中还可以看出,从 Node 派生的子类主要可以分为以下三种:Constant、
Placehoder 以及其他计算节点类。计算节点类对应计算图中的计算节点,每种计算类

23
西安电子科技大学硕士学位论文

型都对应一个独立的派生类,如卷积节点对应的派生类为 Conv2DNode,对应的节点
类型为 Conv2DnodeKind,计算节点类主要负责算法逻辑的表达。Constant 对应计算
图的存储节点,用来存储在编译期已知的模型参数。Placeholder 对应模型的输入和输
出节点,由于模型的输入输出值在运行时才可知,所以该节点主要用于占位以及指示
模型的输入输出形状,模型的输入输出类型以及形状属于编译期已知量。
(4)Tensor
与 ONNX 类似,本文所述编译器使用张量作为数据存储与传输的媒介。张量是
包含某种标量类型数据的 n 维数据结构。
在编译器中张量被抽象为 Tensor 数据结构。
张量的直观属性包括张量元素,以及用于描述张量形状及其所含元素类型的元数据。
Tensor 内部使用一个 uint8_t*类型的指针成员指向一个连续的动态分配内存,多维张
量元素被线性展开到内存中,每个元素相邻放置。张量的形状通过一个维度列表来进
行记录,张量元素的实际类型则通过一个枚举类型的属性来进行记录,在对数据进行
读写时可以通过强制类型转换来获得实际类型的张量数据。除了这三个直观的属性外,
Tensor 内部还增加了多个扩展属性,包括:
1.m_stride。辅助进行快速索引的步幅属性,例如一个被线性展开的三维张量
[x,y,z],对其进行访问时各维度对应的步幅为[y*z,z,1]。
2.m_scale 和 m_offset。与张量数据量化相关的属性,分别用于记录该张量的量
化缩放因子以及零点偏移;
3.m_layout。与卷积计算相关的张量布局信息属性,编译器内使用通道主序的张
量布局([批,通道,高,宽],又称为 NCHW)
,与 ONNX 一致。
4.m_device。该属性用于表示张量数据在实际运行时所存储的设备类型。
5.m_isNull。该属性用于表示该张量的数据指针是否指向动态分配的内存,数据
指针为空的情况发生在张量对象刚构建时。
除此之外 Tensor 类还定义了许多方法用于快速的操作与访问张量内部元素。

3.2.3 计算图重构
由于编译器 IR 采用了与 ONNX IR 类似的布局,所以计算图的重构过程比较简
单,总体的步骤如下。
(1)遍历 ONNX 计算图的参数列表,根据列表中的 ONNX 格式张量信息构建
编译器内部格式张量,并储存于解析器中以参数名为索引的映射表中,该表用于后续
构建计算图数据节点。
(2)遍历 ONNX 计算图的输入列表和输出列表,该列表中存储了计算图的所
有外部输入输出信息,根据节点列表信息构造编译器内部计算图的输入和输出节点。
(3)遍历 ONNX 计算图的计算节点列表,每个 ONNX 计算节点可以直接转为

24
第三章 基于 CNN 加速器的深度学习编译器设计

一个编译器内部格式的计算节点,然后添加到计算图的节点列表中;作为节点输入的
权重参数则被封装为 Constant 并添加到计算图的权重列表中;构建节点的同时需要建
立节点间的数据依赖关系,并将节点地址存储于以计算节点名称为索引的映射表中,
供后继节点构建时进行引用。
解析器在计算图重构的同时会验证 ONNX 模型的合法性,与传统编译器不同的
是,本文的编译器在遇到一个错误时就立刻退出编译,而不会尝试恢复到一个正确的
状态继续解析来尽可能多收集错误信息。因为神经网络模型由少数几种操作的大量重
复构成,采用传统编译器的错误处理策略很容易打印出大量重复的错误信息影响阅读。
解析器需要检验的模型信息包括:
(1)权重张量元素类型。ONNX 张量支持包括 16 位、32 位和 64 位的浮点类型,
8 位、16 位、32 位、64 位的有符号和无符号整数类型在内的多种元素类型。目前编
译器支持的张量类型仅为 32 位的单精度浮点型,所以编译器将拒绝接收其他数据格
式的模型文件。
(2)
计算节点的类型。
目前 ONNX 的默认算子集具有一百多个算子,涵盖 CNN,
NLP 等多种神经网络结构,且仍处于扩张阶段未形成稳定的算子集。要支持所有的
算子工作量太大并不现实,所以本文的编译器目前只支持一个 ONNX 算子集的子集,
其中多数算子与卷积神经网络相关。解析器在遍历 ONNX 的节点列表时若遇到编译
器未提供支持的算子,则报告给应用程序并退出。
(3)计算图的拓扑结构。表示深度神经网络的计算图为有向无环图形式,解析
器在解析计算图时会检测其拓扑结构内有无出现循环或中断错误,以及检测计算节点
的输入数据的格式错误。
解析器若成功解析 ONNX 计算图,则可以得到一个完整的内部格式计算图用于
后续的优化转换和代码生成,否则退出编译并打印错误信息。

3.3 计算图优化

上一节介绍了编译器前端的工作流程,前端的主要功能涵盖输入合法性检查以及
编译器内部格式计算图的构建。在得到作为中间表示的计算图以后,编译器的后续模
块将对计算图进行体系结构无关的优化以及量化。
计算图优化是通过对计算图进行等价变换来降低计算图的计算复杂度和空间复
杂度的模型优化策略。通过计算图优化可以减少计算图的推理时间。目前编译器提供
的计算图优化策略包括算子融合、运算顺序的调整、死代码消除以及常量折叠。
(1)算子融合
算子融合是将多个运算组合为一个运算核心的优化操作,主要作用为减少计算图

25
西安电子科技大学硕士学位论文

中非核心算子的访存开销,以及减少计算图运行时生成的中间值的内存开销,提高模
型的执行效率。图 3.8 所示为对卷积算子与逐元素加算子进行融合的示意图,通过将
原本属于卷积层运算操作之一的加偏置与卷积进行融合,可以将逐元素加操作提到卷
积输出被写回到内存之前进行,从而减少额外的内存访问开销。卷积与激活算子的融
合、以及卷积与 Batch Normalize 算子融合与其类似,但需要有具体运算实现的支持,
不同后端对计算的实现方式不同,例如对于在卷积模块后面连接了池化和激活模块的
硬件加速器,则可以将卷积、激活以及池化算子融合为 Conv+Pool+Relu 算子。

bias
bias
data
Conv Add data Conv
weights
weights

A. 算子融合优化前后的计算图

Memory

Conv Add Conv+Add

B. 算子融合优化前后的运算访存

图3.8 通过运算融合来简化计算图和优化访存

(2)节点运算顺序调整
卷积神经网络的卷积层后经常连接着激活层以及池化层,激活层需要对特征图的
每个神经元进行激活操作,池化层则对特征图进行降采样以缩小特征图的规模,由于
最大池化与激活的执行顺序对最终的输出并不产生影响,所以可以通过调整激活与最
大池化的在计算图中的位置,使池化位于激活之前来减少激活所需的计算量。这种优
化方式对计算图的执行效率影响不大,但可以减少运行时激活值的内存使用。
(3)死代码消除
死代码消除指的是将计算图中对运算结果没有影响的节点从计算图中删除的图
优化操作。计算图中的无效节点指的是输出值没有使用者的节点,以及不改变输入的
形状和值的节点,例如计算图中的只与训练相关的节点(如 Dropout)
、不改变输入形
状的 reshape 节点、池化核尺寸为 1 且无填充的池化节点,以及在对计算图进行节点
融合优化后还存在于节点列表内的旧节点都属于无效节点,这些节点可以通过一个死

26
第三章 基于 CNN 加速器的深度学习编译器设计

代码消除优化从计算图中删去,从而起到简化计算图和减少计算图运行时间的作用。
(4)常量折叠
常量折叠是指将计算图中在编译期就可以得到结果的计算节点替换为对应常量
值的图优化操作,该操作可以起到化简计算图复杂度和减少非核心算子运算时间的作
用。图 3.9 所示为将编译期可知其值的 shape 节点替换为对应常量节点的图优化操作
示意图,将 shape 替换为 constant 常量节点后,会引起该常量值在计算图中传播使计
算图得到进一步的化简。

constant constant unsqueeze

shape gather unsqueeze concat

maxpool reshape

constant

maxpool reshape

图3.9 常量折叠优化示意图

3.4 编译器的模型量化

模型量化是目前最广泛使用的模型压缩手段,将 32 位浮点型权重参数量化为 16
位整型参数可以将模型规模减小 50%,而 8bit 量化可以将模型规模减小 75%。另一
方面,使用定点点积来代替浮点点积还可以降低神经网络在无浮点运算单元设备上的
运算开销,以及提高神经网络在单指令多数据硬件设备上的运算效率,所以量化也是
一种重要推理加速手段。许多深度学习加速器直接被设计为定点计算形式来减小芯片
面积,节省带宽以及降低功耗。在资源受限的终端和嵌入式设备上进行低精度模型推
理来降低模型对硬件带宽和内存的需求已经是目前普遍采用的优化部署手段。
本文在第 2.2 节对作为编译器目标设备的 SOC 进行了介绍,该片上系统由一个
RISC-V 处理器和一个 CNN 加速协处理器组成,其中 CNN 协处理器仅支持 INT16 格
式的数据计算与缓存。整个片上系统通过 Verilog 硬件描述语言进行建模描述,使用
Vivado 工具进行综合与实现,然后烧写到 Xilinx UltraScale+架构的 FPGA 芯片上。协
处理器与其他电路在总逻辑资源中的占比如图 3.10 所示。为满足目标设备的 CNN 加
速器对量化的需求,并减轻资源受限目标设备的存储与带宽压力,有必要在编译器中
提供相应的量化功能。

27
西安电子科技大学硕士学位论文

图3.10 目标 SOC 在 FPGA 开发板上的资源占用情况

3.4.1 神经网络模型量化方法
神经网络模型量化根据量化时机可以分为训练感知量化( quantization aware
training)和训练后量化(post training quantizated)。训练感知量化是指在训练的过程
中引入伪量化操作,来对网络前向计算进行低比特模拟,而反向仍采用浮点类型进行
梯度更新,最终在对模型进行预测时则采用量化类型,这种量化方式所需的操作相对
复杂,但具有量化损失精度小的优点,目前 TensorFlow 以及 Pytorch 都提供了训练感
知量化的接口。
训练后量化是一种对预训练模型进行直接量化的方法,该方法不需要对量化模型
进行重训练,但通常会带来一定的模型准确率损失。训练后量化又可以分为单一权重
量化(weight only quantization)和全整型量化(Quantizing weights and activations)

单一权重量化只对权重进行量化和存储,在推理时再将权重反量化为浮点型进行计算,
这种量化方式无需校准数据集就能实现,但只能起到模型压缩的作用。全整型量化则
将模型的权重、激活值都进行量化,并将计算节点的运算实现转为量化版本,这种量
化方式需要一个校准集来统计输入与激活值的动态范围,以便进行精准量化。

3.4.2 编译器的模型量化方案
上一节对实际应用时常见的模型量化方法进行了介绍。与以提高量化模型准确率
或压缩率为主要目标的学术论文不同,实际应用中采用何种方式进行量化需要根据硬
件资源和应用场景等多种因素进行考虑。由于本文的编译器主要针对低端的嵌入式设
备,带宽和存储资源有限,且作为目标设备的加速器仅支持 16 位有符号整型计算,
所以本文编译器采用的量化方案为权重和激活皆量化的训练后量化。本文通过借鉴论
文[46]的思路设计并实现了适用于 CNN 加速芯片的 INT16 量化方法,并将该量化方法

28
第三章 基于 CNN 加速器的深度学习编译器设计

以功能模块的形式集成编译器设计中。
对模型进行 INT16 量化所需的操作包括将浮点型网络参数和激活值量化为
INT16 类型,以及将量化节点计算核心转为对应的量化版本。由于 32 位浮点数与 16
位整型数所能表示的数值范围与粒度都不同,所以将浮点数转为 16 位整数进行存储
时需要在两种数据类型之间建立一个一对一的映射。本文采用的映射方法为线性映射,
即原始数据与量化后的数据间仅存在一个简单的线性变换关系。线性变换的数学表达
式如式(3-1)所示,其中 q 表示量化后的整型数值, Z 为"Zero-Point"表示浮点 0 映
射值与整数 0 的偏移, S 为浮点型的量化缩放因子, r 为原始的浮点数。

r  S (q  Z ) (3-1)
式(3-1)所示的线性变换即神经网络权值和激活值量化与反量化公式。在进行
量化网络计算时,需要先对量化值进行反量化操作,得到原始浮点值的近似值,然后
对近似值进行运算操作,再将计算的结果量化为定点型进行存储与传输。式(3-2)
与(3-3)所示为量化网络的乘运算与加运算公式。可以看到相比于常规精度网络计
算,量化网络增加了整型的零偏移计算以及浮点型的反量化和量化操作。对于大范围
分布于卷积以及全连接层的乘加运算,可以通过提取公共的浮点乘因子来减少所需的
浮点计算,对应的公式如式(3-4)所示。

S1  S2
q3   (q1  Z1 )(q2  Z 2 )  Z3 (3-2)
S3
S S
q3 = 1 (q1  Z1 )  2 (q2  Z 2 )  Z3 (3-3)
S3 S3
Sw  S x n
y
Sy
 (w  Z
i 0
i w )( xi  Z x )  Z y (3-4)

式(3-4)将浮点乘加运算转为一个浮点数乘运算以及多个整型数乘加运算,运
算的结果仍旧被存储为定点格式。编译器在进行量化网络计算时,为了避免由于乘累
加溢出所引入的误差,需要对整型计算的结果进行处理。对于 INT16 量化,使用 INT64
的数据类型存放计算结果可以满足绝大多数的量化计算需求,在将计算结果写回到输
出缓存中时再截断为 INT16 格式。通过将网络层的输出值保存为量化格式可以在将
两个相邻的反量化与量化操作进行抵消,以在多个相邻的量化层间形成 INT16 类型
的数据流,而对于不支持量化操作的节点则需要先将输入反量化为浮点型。为了避免
在网络计算中引入额外的反量化操作,编译器为卷积、全连接和激活等运算都提供了
相应的量化版本,这样就在保留输入输出为浮点类型的情况下尽可能的保持网络内部
的流动数据类型为 INT16。

29
西安电子科技大学硕士学位论文

卷积神经网络中的卷积层和全连接层计算经常伴随加偏置操作,逐元素加操作通
常可以和卷积运算进行融合,例如一个输出神经元的计算可以表示为式(3-5)
,其中
x 为卷积输入,w 为权重,bias 为偏置。量化网络的卷积计算示意图如图 3.11 所示,
编译器将卷积偏置量化为 INT16,而不是更高精度的 INT32 或 INT64 整型格式,主
要原因为加速器仅支持 INT16 格式运算。

bias

data
Conv int64 Add int16
weights

图3.11 卷积层的量化计算过程

Sw  S x n Sy S
y ( ( wi  Z w )( xi  Z x )  Z y  bias (biasi  Zb )) (3-5)
Sy i 0 Sw  S x Sw  S x

使用上述的量化方法对模型进行量化需要求出各个节点输入值、输出值以及权重
值的量化缩放因子以及 Zero-Point。由于加速器的卷积计算是逐层进行的,计算时接
收 INT16 类型的权重和输入值,计算结果也保存为 INT16 格式。所以编译器在对浮
点数进行量化计算时采用的是逐张量的对称量化策略,逐张量指的是对每一个输入张
量以及每一个权重张量使用同一个缩放因子进行映射,而对称量化则是指将浮点型张
量的绝对值最大值的正值映射到 INT16 数据的最大值,绝对值最大值的负值则映射
到 INT16 的最小值加 1 的映射方法。采用对称量化时浮点数 0 在量化后会映射到整
数 0 上,即 Zero_Point 为 0,所以式(3-5)可以简化为式(3-6)
。根据式(3-6)
,在
将卷积计算映射到加速器前,需要先将偏置值乘以浮点因子 N,以及在将输出值搬移
到外部存储后,需要对输出值乘以浮点因子 M。根据工程经验,N 是个大于 0 的值,
将 N 乘以 INT16 类型的偏置值再存储为 INT16 格式,可能导致溢出,从而带来推理
精度的损失,所以对于 INT16 位的定点计算,加速器在设计时的偏置缓存单元应该
取 INT64 位的宽度而不是 INT16。

 n



y  M  ( 
i 0
wi  xi  N  biasi )
 (3.6)
 M  S w  S x , N  Sbias
 Sy Sw  S x

30
第三章 基于 CNN 加速器的深度学习编译器设计

根据上述 量化策 略, 完整 的浮点 数量化 计算公 式可以 写为式 (3-7 )。其中


max x f l o a t 表示张量的绝对值最大值, Round () 为取整操作,clamp() 作用为将取整后
的值限制在 INT16 数据格式所能表示的 [(215  1), 215  1] 范围内。


 xq  clamp ((215  1), 215  1, Round ( x))

 x float
x  (3-7)
 S
 max x float
S 
 215  1

-|Max| 0.0 +|Max|

-32767 0 32767
图3.12 对称量化算法的示意图

神经网络的权值属于编译期已知常量,所以权值的量化可以在编译器期进行,权
重的缩放因子可以通过统计权重张量的绝对值最大值得到。激活值属于运行期才能确
定的量,所以在计算激活值的缩放因子时需要先通过一个校准集来统计激活值的浮点
动态范围,然后再根据该动态范围计算量化缩放因子,这种激活值量化方式又称为静
态量化。编译器采用滑动平均最大最小值法(MovingAverageMinMax)来确定激活值
的动态范围,对应的求最大值公式如下所示:

max( X ) xmax  None


xmax  
(1  a) xmax  a max( X ) otherwise (3-8)

式(3-8)中 X 为每个校准集样本的张量绝对值最大值,编译器根据参数 a 对最
大值进行迭代,参数 a 的默认值为 0.01。由于编译器对激活值也采用对称量化,所以
只统计激活值的绝对值最大值。
上文对编译器采用的量化方案进行了描述,编译器在进行量化方案选择时主要考
虑的是量化操作在硬件上的可实施性,所以许多方案都不是准确率最优或压缩率最优
的。编译器量化模块根据上述方案对计算图的量化处理流程如流程图 3.13 所示,具
体步骤包括:

31
西安电子科技大学硕士学位论文

开始

是否进行量化?

是否提供校准集?


在计算图中插入用于统计激活值动态范围的伪
量化节点

运行校准集,获取激活值的动态范围

记录各节点输出值的浮点动态范围,去除计算
图的伪量化节点

在计算图中支持量化的节点前后插入量化与反
量化节点

对量化节点 的权重参数进行INT16量化与存储

对量化计算图进行量化相关的优化

结束

图3.13 编译器的量化处理流程图

(1)检查量化编译选项,若需要进行量化则继续判断是否提供了用于确定激活
值浮点范围的数据集,目前编译器只提供了上述一种需要校准集的量化方式,所以若
未提供则报错并退出编译。
(2)在支持量化操作的计算节点前后插入激活值动态范围收集节点,激活值动
态范围收集节点用于在运行校准集时统计计算图各个节点的输入和输出值浮点范围。
(3)在计算图上运行校准集,使用滑动平均最大最小值法来收集各个节点输入
输出值的浮点范围。
(4)将动态范围搜集节点从计算图中剔除,然后根据获取的浮点动态范围计算

32
第三章 基于 CNN 加速器的深度学习编译器设计

并记录各个节点输出值的缩放因子,接着对支持量化操作的节点输入进行量化,并在
节点后插入反量化节点,得到量化计算图,编译器在代码生成时可以根据节点的数据
类型调用对应的核函数模板。
(5)计算量化节点的权重参数量化缩放因子,并对权重参数进行量化。
(6)对量化计算图进行优化,将计算图中两个相邻的反量化与量化节点进行抵
消去除,得到最终的量化计算图。

3.5 小结

本章通过对深度学习模型在资源受限的定制硬件设备上部署的困难与挑战进行
研究,在 3.1 节提出了一个编译器结构,并对编译器的组成以及各个模块的功能进行
了介绍;3.2 节主要介绍了编译器采用的 IR 布局结构,并对编译器的计算图重构流程
进行了说明;4.3 节对编译器采用的体系结构无关的图优化进行了阐述;4.4 节根据目
标硬件特性提出一个模型量化方案,并对编译器的量化计算图生成流程进行了介绍。

33
西安电子科技大学硕士学位论文

34
第四章 基于 CNN 加速器的编译器后端设计

第四章 基于 CNN 加速器的编译器后端设计

上一章主要对本文编译器的整体架构以及编译器的 IR 设计、图优化和量化方案
进行了阐述,本章则介绍编译器的后端设计。后端是编译器中与体系结构密切相关的
部分,本章以本课题组集成了 CNN 加速器的 SOC 系统为目标设备实现了一个编译器
后端,提出了相应的计算管理方案、内存管理方案以及代码生成方案,后端设计的目
标为将计算图中的各个运算高效的映射到硬件的各个执行单元,在实现硬件资源的最
优配置的同时尽可能的减少数据的搬移。

4.1 基于 CNN 加速器的卷积神经网络计算

卷积神经网络的前向计算包括卷积层计算、全连接层计算、池化层计算和激活层
计算等。其中卷积层计算占据了大多数的网络计算时间,是 CNN 加速器的重点优化
对象。卷积神经网络的卷积计算原理已经在 2.1 节介绍过了,本文还在 1.2.3 节列出
了几种主要的卷积计算方法,包括直接卷积、GEMM 和快速卷积算法,这些算法同
样可以固化到硬件中来加速卷积计算。但无论采用何种卷积计算方式,加速器设计核
心都为:提高计算的并行度和数据的复用率,通过增加片上缓存来减少与片外存储器
的数据交换次数,以及配合模型量化和稀疏化等方式来简化计算。

A. 静态稀疏 B. 动态稀疏
图4.1 神经网络的稀疏性示意图

本文基于的 CNN 加速器主要特点为针对稀疏神经网络进行了计算优化。稀疏神


经网络指的是存在大量无效连接的网络。网络的稀疏性可以分为动态稀疏性和静态稀
疏性,对应的示意图如图 4.1 所示。其中静态稀疏性指的是网络参数的稀疏,即参数
为 0 的神经元对于任何输入都不产生响应也不会影响最终结果。动态稀疏性指的是神
经元对某个阈值之下的输入不产生响应,例如 Relu 激活会将所有小于等于 0 值的输
入值都输出为 0。本文基于的加速器则同时利用了神经网络的动态稀疏以及静态稀疏
来简化计算,加速器的静态稀疏优化通过跳过参数为 0 的计算来降低功耗;动态稀疏

35
西安电子科技大学硕士学位论文

优化通过只对有效特征图数据进行传输来避免无效的 0 元素对带宽的占用。
下面对 CNN 加速器的卷积加速原理,以及基于 CNN 加速器的卷积计算实现进
行具体介绍。

4.1.1 CNN 加速器的卷积计算原理


本文在 2.2 节对加速器的整体结构进行了介绍,其主要由计算单元、稀疏处理单
元、存储单元、控制逻辑以及一个可重构互联单元构成,一个卷积层的执行需要这些
模块共同作用。图 4.2 为加速器中与卷积计算直接相关的功能模块示意图,其余部分
多是围绕这些模块来运转的。加速器的处理单元 PE(Processing Elements)负责执行
卷积所需的乘加计算,以及权重的静态稀疏处理,即自动跳过权值为 0 的计算。特
征图数据获取模块 FFU(Feature Fetcher Unit)用于获取有效特征图数据,使得传输到处
理单元的数据总是有效的,也即起到了动态稀疏处理的作用。处理单元与 FFU 相互
配合可以对有效数据和无效数据交织在一起稀疏神经网络的卷积计算进行简化。可重
构互联模块则用于改变 PE 与 FFU 的连接关系,使加速器能够适应不同规格的卷积计
算。

Input Buffer

Output Buffer

数据获取单元 数据选择节点 计算单元

图4.2 加速器的卷积处理组件

加速器的处理单元是加速器的核心计算模块,由 16 个 PE 单元组成,每个 PE
单元包括两个共享输入的计算单元 PECU(Processing Elements Calculate unit)
、两个
权值缓存以及两个权值解码模块。加速器采用分时复用的方法将一个卷积窗口内的有
效特征值输入到 PE 中,然后由 PECU 对输入的特征值与权值缓存内的权值执行乘加
运算。对于单通道卷积,一个 PECU 每次可以计算一个输出神经元,对于多通道卷积
则只能得到一个输出神经元的中间值。由于数据获取单元只对有效特征图数据进行传

36
第四章 基于 CNN 加速器的编译器后端设计

输,所以在传输数据的同时还要将有效数据对应的权值索引也输入到 PE 单元。PE
单元的稀疏处理原理如图 4.3 所示,首先 PE 的权值解码模块将获取的特征图掩码
musk A 与权值矩阵掩码 musk B 进行“与”操作,其中权重掩码和特征图掩码分别用
于指示卷积窗口内的权重参数和特征图数据的有效性,得到结果掩码 musk C 中值为
1 的位对应为卷积窗口内权值和输入都有效的位置,即正真需要计算的位。musk C
与有效特征图数据对应的权值索引进行作用生成一个门控使能信号,来控制 PECU 内
部的乘加单元跳过无效计算。通过上诉机制,加速器的计算单元只需要对权值和输入
特征值都非 0 的有效数据进行计算,有效减少了卷积的乘加计算次数。加速器的稀疏
处理无需软件参与,但 PE 进行静态稀疏处理所需的卷积核参数掩码需要外部提供。

1 0 0 musk A
0 5 0 100 010 1000
8 0 0 musk C
AND 000 010 100
0 0 0
4 3 0 001 110 101
7 0 6 musk B

图4.3 PE 单元的稀疏处理原理

PE 单元所需的有效数据、有效数据对应的权值索引和特征图掩码都来自于上方
特征图获取模块 FFU。在介绍 FFU 的工作原理之前,先介绍加速器关于“任务”的
概念,加速器将卷积核通道在特征图上向左滑动一行的计算的称为一个任务,例如对
于输入图像高宽为 32,输入通道数为 1,卷积核高宽为 5,步长为 1,无填充的单个
输出通道的计算可以被分为 28 个任务,每个任务得到一行的输出像素值。加速器在
执行卷积计算时会生成任务掩码,然后将计算任务对应掩码地址分配给激活的 FFU,
FFU 得到地址后则对任务掩码进行解码,得到有效特征图数据及对应权值索引,再逐
个发给 PE 单元。加速器的任务分配、任务解码都无需软件的参与,但输入特征图的
掩码需要软件提供。
加速器的特征图获取模块同样由 16 个获取单元 FFU 组成,每个获取单元可以与
PE 进行一对一的数据分配,也可以连接多个 PE 单元实现特征图的数据复用。FFU
与 PE 的连接关系可以通过可重构互联模块进行调整。可重构互联模块内有两组由互
联单元,通过互联配置,单个的 FFU 可以连接 16 个 PECU,进行 16 个并行计算。
加速器的可重构互联由上层软件进行配置。
本文在 2.2 节对加速器的 8 个控制寄存器进行了介绍,其中与互联配置相关的寄
存器为 Reg1,Reg2 和 Reg3,每个寄存器位宽都为 16 比特。Reg1 中的 16 个比特位

37
西安电子科技大学硕士学位论文

分别对应 16 个 FFU,置 1 时表示激活对应的 FFU 用于接收任务。Reg2 和 Reg3 分别


对应一组互联模块,其中最低位为控制最左侧的数据选择节点是否要接收模块外部数
据的标志位;[6:1]分别对应 6 个数据选择节点,置 1 时表示连接上方的数据通路,置
0 时则连接侧面的数据通路;[14:7]对应 8 个 PE 单元,置 1 时表示连接直上方的数据
通路,置 0 时则连接斜上方的数据通路。可重构互联模块配置相对复杂,下面以一个
具体的例子对加速器的互联配置进行说明。
以输入通道为 1,卷积核个数为 6 的卷积层为例,可选的互联方式包括:
(1)激活 3 个 FFU,每个都与一个 PE 进行 1 对 1 的数据分配(每个 PE 有两
个权重缓存,可以存储两个卷积核通道),对应的互联逻辑示意图如图 4.4 所示。此
时 Reg1 值为 0x0007,Reg2[0]=0,Reg2[6:1]=6'b000111,Reg2[14:7]=8'b00000111。
根据卷积计算原理该层的 6 个卷积核可以共享输入数据,且加速器的一个 FFU 最多
可以传输数据给 16 个 PECU,所以这种方式没有很好的利用输入数据的可复用性,
同时也未充分利用 PE 单元的计算资源。

图4.4 加速器互联配置方案 1

(2)激活 1 个 FFU,该 FFU 提供数据给 6 个卷积核,对应的互联逻辑示意图如


图 4.5 所 示 。 此 时 Reg1 值 为 0x0004 , Reg2[0]=0x0 , Reg2[6:1]=6'b000100 ,
Reg2[14:7]=8'b0000101,这种连接方式单个 FFU 的数据复用提高了,但多数 PE 依旧
被闲置,计算资源的利用率依较低。

图4.5 加速器互联配置方案 2

(3)激活 5 个 FFU,每个 FFU 连接将数据提供给 6 个 PECU 进行计算,对应的


互联逻辑示意图如图 4.6 所示。
此时 Reg1 为 0x1864,
Reg2[0]=0,
Reg2[6:1]=6'b010100,
Reg2[14:7]=8'b01101101,Reg3[0]=1,Reg3[6:1]=6'b001000,Reg3[14:7]=8'b01011011。

38
第四章 基于 CNN 加速器的编译器后端设计

这种连接方式可以并行执行 30 个乘加运算,充分利用了输入特征图的数据复用性以
及计算资源。

图4.6 加速器互联配置方案 3

从以上的例子可以看出,互联模块的配置方案对加速器的卷积计算效率有较大影
响,在对可重构互联进行配置时应该尽可能的复用输入特征图的数据,以及尽可能的
利用计算资源。这种通过改变硬件单元连接关系来满足不同卷积层的不同计算需求的
方式在一定程度上提高了硬件的灵活性,但也提高了硬件使用的复杂性。能否提供有
效的软件算法来隐藏这些硬件细节是提高加速器易用性的关键。

4.1.2 卷积计算分割方案
上一节对加速器的卷积计算原理进行了分析,本节首先对加速器的卷积计算流程
流程进行介绍,然后分析加速器的几个重要的限制,并提出相应的解决或折衷方案。
本文所述的加速器对网络的计算是逐层进行的,加速器执行一层卷积的工作流程
如下图 4.7 所示。具体步骤包括:

数据准备 配置寄存器

使能计算 得到结果

图4.7 加速器执行一层卷积的流程

(1)数据准备。该步骤需要将单个卷积层的权重、偏置、特征图以及特征图掩
码和权重掩码分别载入加速器中对应的权值缓冲区、偏置缓冲区、输入缓冲区以及特
征图掩码缓冲区和权重掩码缓存区中。
(2)寄存器配置。该步骤需要通过加速器的寄存器配置指令对加速器的各个功
能模块参数进行配置,包括特征图尺寸、卷积核尺寸,以及可重构互联配置等。
(3)使能计算。该步骤通过加速器的全局使能寄存器进行卷积计算的使能。
(4)得到结果。

39
西安电子科技大学硕士学位论文

加速器在执行卷积计算时,FFU 从输入缓存中获取输入数据提供给 PE 单元,PE


单元将计算的结果存储到输出缓存中,由于 PE 单元只能存储卷积核的一个通道,对
于多通道卷积 PE 单元的输出仅为最终输出的中间值,所以输出缓存中的数据还需要
经过标量计算单元的处理才能得到最终的结果并将结果送回输入缓存,加速器多通道
卷积计算示意图如图 4.8 所示。

2 input channels 2 filter middle value 2 output channels

图4.8 加速器卷积计算示意图

CNN 加速器利用分块的片上缓存来存储卷积的输入、输出和权重等数据,以避
免频繁的片外存储访问和计算时的数据访问冲突,但缓存的大小通常也是加速器的一
个限制因素。本文基于的 CNN 加速器的输入缓存大小为 2KB,输出缓存仅为 16KB,
内部缓存大小极为有限,当加速器内部的存储单元无法容纳一个卷积层的所有特征图
或输出值时,则需要对数据进行切分和拼接。除了缓存限制外,加速器的另一个限制
是计算单元 PE 的数量。加速器内部仅有 16 个 PE 单元,每个 PE 单元只内只有两个
大小为 25x16bit 的权值 Buffer,每次可以加载两个尺寸不大于 5x5 的卷积核通道,极
其有限的计算单元的数量决定了对于卷积核数量较多或通道数较大的卷积层,需要进
行计算的分割。每个分割得到的子计算都需要经历数据准备以及寄存器配置等一系列
流程,复杂的准备工作会降低加速器对大型卷积计算的效率,而有限的输入输出缓存
区还会加剧这一问题。
为解决加速器计算单元数量限制和缓存大小限制的问题,有必要在需要时对卷积
进行分割。加速器的所需卷积分割包括基于缓存大小限制的数据分割(输入输出特征
图的切割),和基于 PE 数量限制的计算分割。目前编译器只实现了基于 PE 单元数量
限制的计算分割,当加速器无法容纳完整输入输出特征图,或卷积核尺寸大于 5x5
时则将卷积计算映射到通用处理器上执行。下面对编译器的卷积计算分割方案进行介
绍。

40
第四章 基于 CNN 加速器的编译器后端设计

F0,0 F0,1 F0,2 F0,c-1

F1,0 F1,1 F1,2 ... F1,c-1

K
F2,0 F2,1 F2,2 F2,c-1
..
. Fk-1,c-1
Fk-1,0 Fk-1,1 Fk-1,2

图4.9 按通道展开的卷积核示意图

图 4.9 所示为将一个卷积层的卷积核按通道展开所得的方阵示意图,其中每个方
块都表示一个卷积核通道,C 和 K 分别表示一个卷积层的输入输出通道数。由于每
个通道的计算都是相互独立的,当加速器的 PE 单元无法容纳所有的通道时,可以基
于通道进行分组卷积。根据卷积的计算原理,矩阵的每一列通道都与输入特征图的同
一序号的通道进行卷积,体现在加速器上即为可以连接一个 FFU 进行数据共享,而
每一行通道则对应与输入特征图的不同通道进行卷积。考虑到数据复用率和计算单元
利用率这两个指标,编译器在计算分割时优先按列进行划分。
在介绍加速器的计算分割方案之前,先介绍加速器的互联配置生成方案。为了适
应不同卷积层的计算需求,加速器引入了可重构互联来改变数据获取单元与计算单元
的连接,也就是说加速器将数据复用优化以及计算资源的分配工作交给了上层软件,
上层软件可以通过配置对应的控制寄存器来控制加速器的数据复用与计算资源的分
配。虽然加速器的可配置资源并不多,但要获取任意连接方案对应的寄存器配置值也
相当困难。为了降低互联配置生成的复杂度,编译器对能够生成的配置方案进行了限
制,将所有的可行配置转为可用两个参数——PE 的分组数以及每组的 PECU 数量进
行描述的问题,并提供了一个搜索空间来根据参数直接获得该参数下的最佳配置方案。

A. 将32个PECU(16个PE)分为1组,所
有PECU共享输入

B. 将32个PECU(16个PE)分为8组,每
组4个PECU共享输入

C. 将32个PECU(16个PE)分为5组,每
组6个PECU共享输入
图4.10 计算单元分组示例

41
西安电子科技大学硕士学位论文

互联配置方案的好坏可以通过该方案使用的 PECU 数量(计算单元利用率)和激


活的 FFU 数量(数据复用率)来衡量,一个最优配置应该在利用尽可能多的 PE 的同
时激活尽可能少的 FFU,但这两者有时可能无法同时达到最优,编译器在两者相矛盾
时优先选择满足 PE 的最高利用率。编译器提供的搜索空间为一个由多个 if 和 else 语
句组成的函数,
该函数的两个参数分别表示 PECU 的分组数量,以及每组包含的 PECU
数量,理论上同一组的 PECU 可以共享输入,但由于一个 FFU 最多能提供数据给 16
个 PECU,所以同一组的 PECU 并不一定能连接到同一个 FFU 。函数根据该参数在
if 语句中进行匹配,输出该配置下对应控制寄存器的值,以及被激活的 FFU 索引,
以及每组 PECU 的索引。此外编译器还提供了一个辅助的函数用于获取当 N 个通道
为一组进行共享输入时,PE 单元最多可以容纳几组这样的通道。

32
...

6
...

C
图4.11 计算分割算法示意图

加速器的计算分割算法如算法 4.1 所示,对应的示意图如 4.11 所示。该算法以


32 行卷积通道为一组进行计算分割,当剩余要处理的行数大于等于 32 时,则直接将
该组通道分割为 C 个子计算,每个子计算对应为加载一列 32 个卷积核通道到 PECU
中,所有的 PECU 具有相同的输入,接着以 1 和 32 为参数(表示将所有的 16 个 PE
归位一组,该组的 PECU 数为 32)生成加速器互联配置信息,并根据该配置信息和
通道行号列号生成一个子计算数据结构实例,添加到子计算表中,然后接着处理下一
组通道。用于表示子计算的数据结构需要记录的信息包括:每个子计算对应的互联配
置,该子计算涉及的卷积核通道在权重张量中的偏移,每个通道对应的 PECU 索引,

42
第四章 基于 CNN 加速器的编译器后端设计

以及每个 PECU 输出值在输出缓存中的起始地址。当剩余的通道行数不足 32 时,则


剩余的通道方阵的一个列无法占满 32 个 PECU,此时需要判断通道行数是否大于等
于 16,若大于 16 则以行卷积通道为一组进行计算分割,每次加载两列通道到计算单
元中,否则计算当每个小组的 PECU 数为剩余行数时,PE 单元最多可以分为多少个
这样的小组,然后以组数与剩余行数为参数进行互联配置与子计算的生成。对于剩余
列数也不足以填满所有的计算单元时,则以剩余列数和行数为参数获得互联配置以及
生成子计算。

算法 4.1 基于加速器的卷积计算分割算法伪代码
INPUT 输出通道数 K
输入通道数 C
OUTPUT 子计算列表
1 for(int row=0; row<K ; row+=32){
2 if(row+32<K){
3 for(int col=0;col<C;++col){
4 //以(1,32)为参数生成连接配置信息
5 //生成一个子计算,并添加到子计算表中
6 }
7 }
8 else{
9 int r=row;
10 if(r+16<K){
11 for(int col=0;col<C;col+=2){
12 if(col+2<C){
13 //以(2,16)为参数生成连接配置信息
14 //生成一个子计算,并添加到子计算表中
15 }else{
16 //以(1,16)为参数生成连接配置信息
17 //生成一个子计算,并添加到子计算表中
18 }
19 }
20 r += 16;
21 }
22 int A=k-r; //剩余要处理的通道行数

43
西安电子科技大学硕士学位论文

23 //每个小组的 PECU 数为剩余行数时,PE 单元最多可以分为多少个这样的小组


24 int B=get_solution(A);
25 for(int col=0;col<C;col+=B){
26 if(col+B<C){
27 //以(B,A)为参数获取连接配置信息
28 //生成一个子计算,并添加到子计算表中
29 } else{
30 //以(C-col,A)为参数获取连接配置信息
31 //生成一个子计算,并添加到子计算表中
32 }
33 }
34 }
35 }

4.1.3 全连接计算

Input
Weights 2 Output
3 2 5 2 1 6 42
5 1 6 3 4 1 73
1 4 2 7 2 5 81
9

图4.12 矩阵向量乘法示意图

组成卷积神经网络的另一个重要的计算为全连接,全连接层计算的原理在 2.1 节
已经介绍过了,在计算时全连接通常被转为如图 4.12 所示的矩阵向量乘法。虽然理
论上全连接运算可以被转为卷积核为 1x1 的卷积运算映射到加速器进行加速,但加速
器在处理大量 1x1 卷积核通道时需要进行计算切分的次数过多,计算效率低下,所以
编译器在进行网络映射时并不将加速器作为全连接层的目标处理单元。

4.1.4 权值压缩
本文在 4.1.1 节提到过,本文基于的加速器能够利用网络的稀疏性进行计算化简。
稀疏网络的权值参数存在大量的 0 值,所以可以通过对权值进行压缩存储和传输来减
少权值的内存占用和传输带宽。加速器采用的权值压缩方法为数据索引压缩方法,该
方法与 COO 压缩格式类似。COO(Coordinate Format)压缩格式又称为三元组压缩格式,
是最常用的稀疏矩阵存储格式之一,被普遍应用于标准线性代数库或数值运算库中。

44
第四章 基于 CNN 加速器的编译器后端设计

COO 使用三种数据来对稀疏矩阵进行编码,包括有效数值以及该数值在稀疏矩阵中
的列下标和行下标。如图 4.13 所示,其中第一行存储的是矩阵的非 0 值个数、总行
数和总列数。这种存储方式非常简单,但较别的压缩方式需要记录的信息多,因此不
是空间最优的。

序号 值 行 列
0 7 6 6
1 1 0 3
0 0 0 1 0 0 2 2 1 4
0 0 0 0 2 0 3 3 2 2
0 0 3 0 0 0 4 1 3 0
M6x6 =
1 0 0 1 0 0 5 1 3 3
0 2 0 0 0 0 6 2 4 1
0 0 0 0 0 3 7 3 5 5

图4.13 COO 格式的稀疏矩阵编码示意图

本文基于的 CNN 加速芯片所需的权值位宽为 16,计算单元个数为 32,计算单元


内的权值缓存深度为 25。所以在采用数据索引压缩方式时,直接采用位宽为 32 的数
据格式对有效的权值进行编码,其中低 16 位用于存储有效权重数据,[23:16]位用于
存储有效数据在卷积核中的位置信息,也即在深度为 25 的权值缓存中的索引;[31:24]
位用于存储该卷积核通道对应的 PECU 索引。硬件设备的总线位宽为 32 位,所以每
次可以传输一个压缩数据。权值压缩格式及其在编译器中的存储格式如图 4.14 所示,
这种压缩存储方式将原本 16 位的参数扩展为 32 位,所以只有在权值的稀疏度高于
50%时,压缩数据的空间占用才会低于未压缩数据。

行 列 数据

8bit 8bit 16bit

A. 权重参数的压缩格式

struct DataIndex{
int32_t data:16;
int32_t col:8;
int32_t row:8;
};
B. 压缩参数的存储格式

图4.14 权重的压缩格式及其数据存储结构

45
西安电子科技大学硕士学位论文

4.1.5 偏置的处理
加速器使用三个相邻的缓冲区存储卷积层的偏置值、权重掩码以及 PECU 的输出
地址。偏置缓冲区的大小为 32x16bit,可以存储 32 个 16bit 的偏置值,每个都对应一
个 PECU 单元,在执行卷积计算时,加速器的每个计算单元都以偏置值或 0 值作为乘
累加的基数。加速器偏置缓冲区的映射地址为 0x30020000,在偏置缓存后紧接着的
是权重掩码缓存,共 32x32bit,每个也分别对应 PE 模块内的 32 个权重缓存。紧接在
权重掩码缓存后为 PECU 输出地址缓存,共 32x16bit,每个也分别对应 PE 模块内的
32 个 PECU,该地址的作用为指示 PECU 的输出起始地址。这三个缓冲区数据统称为
bwi_data,可以通过一条数据搬移指令完成三个缓冲区的数据填充。

4.2 体系结构相关的计算图变换

本文在 2.2 节对作为目标设备的 SOC 系统进行了介绍,该系统的处理单元包括


一个 RISC-V 处理器核心和一个 CNN 协处理器,其中通用处理器可以执行控制型的
事务和各种计算,而专用的 CNN 加速器则只能执行少数几种卷积神经网络计算,包
括卷积、最大池化和 Relu 层计算,而构成卷积神经网络的其他重要的层,如全连接
和 Sigmoid 网络分类层等仍需要由 CPU 完成。本节主要介绍与该体系结构相关的计
算图变换,在这之前先对编译器的后端的工作流程进行介绍。

计算图合法性 体系结构相关
计算图
验证 的计算图变换

内存管理和模
代码生成
型参数保存

图4.15 编译器后端的工作流程

图 4.15 所示为编译器后端的工作流程,具体步骤包括:
(1)计算图的合法性验证。该步骤主要用于验证各个计算图的节点类型是否能
被后端支持,即后端是否有对该节点对应的计算进行实现。
(2)体系结构相关的计算图变换。该步骤主要用于向计算图中引入与后端相关
的信息,这一部分的工作包括体系结构相关的节点替换、算子融合以及算子的分解。
(3)内存管理和权重参数保存。该步骤对网络的激活值的内存进行预分配,并
将网络权重参数以数组形式保存到独立的文本文件中。
(4)代码生成。该步骤包括模型所对应的 C 头文件以及源文件的生成。

46
第四章 基于 CNN 加速器的编译器后端设计

体系结构相关计算图变换的作用为对网络进行计算管理,即将计算图的节点映射
到合适的硬件单元——CPU 或加速器。计算图节点的默认执行设备为 CPU,所以该
阶段仅需要将能映射到加速器的节点替换为加速器限定的节点即可。加速器支持的计
算类型包括常规卷积计算,最大池化和 Relu 激活计算,其中池化和激活的计算量较
小,所以不对其进行单独的映射,而是通过将其和卷积节点进行融合,形式
Conv+Relu+Maxpool 的网络流水计算。编译器在进行卷积节点映射时需要根据节点的
属性判断其是否满足加速器的限制条件,只有满足限制条件的节点才能映射到加速器
上执行。从上一节的加速器卷积计算原理可以看出,本文的加速器基于直接卷积计算
的原理对卷积进行优化加速,所以除了缓存大小限制和计算资源限制的问题外,加速
器还面临了所能支持的卷积类型的限制,包括卷积核的尺寸限制——只支持高宽不大
于 5 的卷积核,卷积步长限制——固定为 1,卷积类型限制——只支持常规卷积。此
外由于加速器仅支持 INT16 类型的计算,所以在节点映射时还需要对节点各个输入
的数据类型进行检查。编译器需要对硬件的配置以及特性有充分的理解才能正确的将
节点映射到合适的硬件单元并生成正确的硬件指令。

4.2.1 卷积节点变换

DLAConvNode

-m_input: Value
-m_weight: Value
-m_bias: Value
-m_kernelShape: vector<int>
-m_pads: vector<int>
-m_strides: vector<int>
-m_dilation: int
-m_group: int
-m_doRelu: bool
-m_doMaxpool: bool

图4.16 CNN 加速器类型的卷积节点属性

卷积节点变换对应的操作为将符合加速器限制条件的卷积节点 Conv2DNode 替
换为加速器类型卷积节点 DLAConvNode,加速器卷积节点的属性如图 4.16 所示,相
比 Conv2Dnode 其内部增加两个个属性:表示是否进行 Conv+Relu 融合的 doRelu 标
志,表示是否进行 Conv+Maxpool 融合的 doMaxpool 标志。在将符合限制条件的卷积
节点替换为加速器限定卷积节点后,还需要根据加速器的工作原理对卷积节点进行计
算分割、bwi_data 数据的生成和权值的压缩。卷积节点的计算分割策略已经在上一节
介绍过,该阶段在分割得到子计算后,将依次对子计算进行 bwi_data 数据的生成和

47
西安电子科技大学硕士学位论文

权重压缩。每个子计算的 bwi_data 数据都由偏置值、权值掩码和 PECU 输出地址组


成,大小固定为 256byte,在得到所有子计算的 bwi_data 值后,编译器使用该值替换
偏置节点的张量负载,并将该张量的设备类型改为加速器,同时保存每个子计算的
bwi_data 在该张量中的偏移。对于权值的处理类似,在权值压缩完毕后,编译器将权
值节点的张量负载替换为对应的压缩值,并将其设备类型改为加速器,同时保存每个
子计算权值在该张量的偏移。

4.2.2 体系结构相关的计算图优化
后端执行的体系结构相关图优化主要包括体系结构相关的节点融合以及死代码
消除,具体的操作为:
(1)将 DLAConvNode 节点与 Relu 节点进行融合,得到一个 doRelu 属性被置为
true 的 DLAConvNode 节点。加速器在卷积计算单元的输出缓存后连接了可以进行
Relu 激活的标量计算单元,将卷积与 Relu 进行硬件融合可以形成卷积与激活的流水
计算,加速模型的推理。
(2)将 DLAConvNode 节点与最大池化节点 MaxPoolNode 节点进行融合,得到一
个 doMaxpool 属性被置为 true 的 DLAConvNode 节点。加速器在卷积计算单元的输出
缓存后连接了可以进行最大池化计算的池化单元,将卷积与 MaxPool 进行融合可以
形成卷积与池化的流水计算,加速模型的推理。需要注意的是加速器的池化单元仅支
持尺寸为 2x2、步长为 2 的最大池化,对于其他尺寸的最大池化则不能进行融合。
(3)若在体系结构相关的计算图变换过程确定发生了节点变换,则通过调用死代
码消除优化对计算图中的旧节点进行删除。

4.2.3 加速器卷积节点分解与优化
从上文的加速器卷积计算原理可知,加速器卷积节点由包括输入图像压缩、数据
搬移、寄存器配置、输出图像解压缩在内的多个动作构成。由于相邻的两个加速器卷
积节点可以在加速器内形成流水操作,从而减少复杂费时的数据搬移与压缩与解压操
作,所以编译器在体系结构相关的计算图变换阶段,还对加速器卷积节点进行分解与
优化。卷积节点的分解指的是将加速器卷积节点的数据压缩与解压操作、以及输入输
出特征图数据的搬移操作从卷积操作中分离出来,形成额外的节点。然后编译器可以
通过图优化将两个相邻的压缩与解压缩操作进行抵消,以及将两个相邻但方向相反的
数据搬移操作进行抵消。此外分解得到的压缩与解压节点还可以参与后续的内存预分
配优化。

48
第四章 基于 CNN 加速器的编译器后端设计

4.3 后端的内存管理

编译器的内存管理即对参与网络计算的数据的传输和存储进行管理,涉及的数据
类型包括模型权重和激活值。由于深度神经网络是大数据量的计算,因此存储管理方
案对模型推理的速度与功耗都有重要的影响。
本文基于的 CNN 加速器芯片的存储系统相对简单,由加速器的片上缓存和片外
存储构成,处理器可以通过 APB 总线配置 uDMA 与加速器进行批量的数据交换,处
理器只需要配置传输参数,传输过程由 uDMA 模块完成。

4.3.1 激活值管理
神经网络的激活值属于模型运行期才能确定的值,但其所需的存储空间在编译期
就能确定,所以编译器可以通过存储分析来对运行时激活值所需空间进行预分配,避
免运行期间的内存请求和释放操作,并最小化运行时所需的内存。
编译器的激活值内存分配策略如图 4.17 所示,
即预先申请一片较大的连续内存,
后续的内存分配工作则转为了在该内存空间中寻找一块符合需求的空闲内存段,然后
返回该空闲内存段地址与连续内存起始地址的偏移。编译器使用一个从节点输出值到
偏移地址的映射表来存储每个节点输出值在该内存段中的偏移。通过预先内存分配,
免去了模型在运行时所需的激活值内存申请与释放工作。另一方面,由于模型节点的
输出值并不是在整个模型推理期间都有效,所以可以通过对节点进行生存期分析来释
放无效的节点输出值的内存占用,被释放的内存可以被后续的节点使用,从而减小运
行时所需的内存。

节点 预分配连续内存

图4.17 编译器的激活值内存分配策略

在对节点的输出进行内存分配前,编译器需要对节点输出值的生命期进行分析。
加速器使用如图 4.18 所示的数据结构来记录节点的生命期,其中 m_start 与 m_end 分
别对应节点输出值 m_value 的定义与最后一次被使用时分别所在的节点序号。由于在
该阶段计算节点在节点列表中的顺序即为计算节点的执行顺序,所以编译器将节点在
顺序列表中的索引作为节点的序号,并使用一个映射表存储节点到其序号的映射,然

49
西安电子科技大学硕士学位论文

后通过遍历节点的使用者列表,该列表记录了节点输出值的使用者,其中序号最大的
使用者即为该节点输出值最后一次被使用的位置。由于逐元素操作如激活不改变输入
形状,所以当节点输出值的最后一次使用落在激活节点上时,可以将该值的生存范围
延长到对应激活节点最后一次被使用的位置,减少不必要的内存分配。
在获得节点的生命期后,要根据该列表在计算图中插入用于辅助进行内存分配与
释放的内存分配节点和内存释放节点。内存分配节点对应的操作为通过内存分配器申
请一段指定大小的内存,分配器将返回所分配内存段的偏移地址,内存释放节点对应
的操作为通过内存分配器释放指定偏移地址处的指定大小的内存。与内存分配相关的
节点对应的操作在内存管理阶段完成,在内存分配完毕后可以通过一个死代码消除优
化将与内存分配相关的节点从计算图中去除。
内存分配器使用一个列表来记录所有非空闲的内存段,对于内存分配请求,分配
器将从 0 偏移地址开始寻找满足分配请求内存段,并从中截取一段作为申请得到的内
存,将其起始地址返回给申请者,然后分配器将该被占用的内存段加入非空闲内存表
中。若非空闲内存列表中没有符合要求的内存段,则需要对总内存进行扩充。而内存
释放操作则为将对应内存段从非空闲列表中剔除。在激活值内存管理完成后,编译器
将统计与记录需要预分配的激活值总内存大小。

图4.18 记录节点生存期的类结构

4.3.2 权值管理
神经网络模型的权重参数属于模型训练完成后就能确定的系数,在编译期为已知
常量,本文在第三章关于模型解析器的介绍中提到过,编译器将 ONNX 模型文件中
的权重参数读取到内部张量数据结构中,并在计算图中以 Constant 节点的形式存在,
编译器可以通过遍历计算图的权重节点列表来访问所有的权重参数。编译器后端在权
值管理阶段将权重参数保存到文本文件中。编译器可选的权重保存格式包括文本文件

50
第四章 基于 CNN 加速器的编译器后端设计

格式和二进制文本格式。将权重参数保存为文本格式的优点为可以通过 include 命令
将文本中的内容直接展开到数组中,所以更适合低端的无文件系统的微控制设备,但
对于大型的深度神经网络,文本格式的参数保存方式会加大网络参数的大小,且难以
直接展开到数组中。将权值参数输入到文件的同时,编译器需要记录各个参数在权重
数组中的偏移,后续对模型权值的访问则转为对权重数组起始地址加偏移地址的访问。
权重数组地址在应用程序调用模型对应的函数时,以参数的形式传递给函数。

4.4 后端的代码生成

前文对编译器后端的计算管理和内存管理进行了介绍,本节将阐述编译器的代码
生成方法。本章所述编译器后端的代码生成由一个 C 代码生成器完成,代码生成器
的主要工作为将计算图转为一个外部可调用的 C 函数,计算图中的每个节点都被转
为一条或多条的 C 语句。编译器将这个外部可调用的 C 函数称为入口函数,并生成
一个独立的头文件对该函数进行声明,其他应用程序可以通过 inlude 该头文件对模型
进行调用。编译生成的头文件主要包括一个入口函数声明,入口函数签名如下所示:
void entry(uint8_t* input, uint8_t* output, uint8_t* active, uint8_t* weight);
函数签名中的第一个参数 input 表示模型的输入,即待识别的图像数据;第二参数
output 表示模型的输出,即图像的分类结果;active 为预分配的激活值内存起始地址,
weight 则为存储模型权重的数组起始地址。入口函数的函数体定义在对应的源文件中,
源文件内除了入口函数还有一系列与图节点计算相关的函数定义,这些函数被定义为
静态函数,表示函数仅在源文件内部使用。模型的权重参数则保存在另一个文本文件
中。
将神经网络模型转为转为 C 代码的优点包括:
(1)C 函数可以直接被其他应用程序调用进行联合编译,无需提供复杂运行时
支持,且提供了仅次于汇编语言的高效性。
(2)可以复用硬件系统原有的 C 编译工具链,且可以通过内联汇编为编译器不
支持的特殊指令提供支持。
(3)相比其他格式的输出(如二进制代码、汇编和序列化可加载模型)
,C 语言
的可读性更强,更易于开发人员进行阅读、调试与修改。
表 4.1 为代码生成器的主要方法及其解释。编译器的代码生成过程主要包括头文
件和源文件的生成。由于头文件的内容相对固定,可以直接使用一个 C 风格字符串
进行表示,在生成时只需要对其中的可变参数进行格式化即可。对于 C 源文件的生
成,编译器使用半自动的代码生成方式,即预先将图节点的计算实现为模板函数,发
射到源文件中,然后通过遍历计算图的节点,将节点对应的计算直接转为特定参数下

51
西安电子科技大学硕士学位论文

的函数调用语句,简化代码的生成过程。源文件代码的生成流程如图 4.20 所示。

表4.1 代码生成器的主要方法及其解释
方法 解释
+save 驱动头文件与源文件代码的生成
-saveWeightFile 生成模型参数文件
-saveHeadFile 生成 C 头文件
-saveSourceFile 生成 C 源文件
-emitMacroDefinition 发射源文件的 include 头文件包含和宏定义
-emitTemplateFunction 发射模板函数定义,包括辅助函数与计算节点对应的核函数
-emitEntryFunction 发射模型入口函数
-emitDlaCfigure 发射加速器卷积操作相关的指令,以内联汇编的形式输出
-emitFunctionCall 用于发射模板函数的函数调用代码

输出启动解码单元指令

初始化
输出重置解码单元指令
输出模板函数定义 Y
是否处理完所有的子计算
输出入口函数定义 N
uDma传输权值和bwi数据
Y
是否处理完所有计算节点
输出寄存器配置指令
N

是否为加速器卷积节点 Y 输出卷积计算使能指令

N
输出标量计算使能指令
输出计算节点对应的模板
函数调用语句

图4.19 编译器代码生成流程图

C 源代码文件生成的主要步骤包括:
52
第四章 基于 CNN 加速器的编译器后端设计

(1)代码生成前的准备工作,包括指定名称的 C 源文件新建和打开。
(2)将计算图中的各类计算节点对应的模板函数定义,辅助函数定义,以及宏
定义输出到源文件中。
(3)输出入口函数的签名,和函数体起始部分。
(4)遍历计算图的节点,对于非加速器卷积类型的节点,直接输出节点对应的
核函数调用语句。
(5)对于加速器卷积节点,则需要根据卷积节点的属性生成一组加速器相关的
指令,具体步骤包括:
(5a)输出启动解码单元指令,将压缩特征图解压到输入缓冲区中,并生成任务
掩码,然后输出重置解码单元指令。
(5b)根据卷积节点信息输出加速器参数配置指令,对输入特征图大小和卷积核
尺寸等参数进行配置。
(5c)遍历卷积节点的子计算列表,针对每个子计算输出权值传输指令、偏置传
输支持、互联寄存器配置指令以及卷积计算使能指令。
(5d)如需要则输出加速器的标量计算使能指令,得到该层卷积的最终输出。
(6)输出入口函数体终止部分。
(7)关闭打开的 C 文件。

4.5 小结

本章主要实现了以集成了 CNN 加速器的 SOC 为目标设备的编译器后端。本章首


先对 CNN 加速器的卷积加速原理以及工作流程进行了介绍,并提出了加速器互联配
置生成方案与卷积计算的分割方案;接着介绍了与体系结构相关的计算图变换,包括
计算映射以及节点融合;然后对编译器的激活值与权值的内存管理方案进行了阐述;
最后描述了编译器采用的代码生成方法。

53
西安电子科技大学硕士学位论文

54
第五章 编译器测试与分析

第五章 编译器测试与分析

本文在第三介绍了编译器的总体结构以及编译器前端和优化器的实现,在第四章
则介绍了基于 CNN 加速器的编译器后端实现,本章将基于 Linux 环境对本文实现的
深度学习编译器进行测试与分析。本章在 5.1 节首先通过介绍编译器源代码的目录结
构对构成编译器的各个模块的功能进行了总结,然后对编译器网络调试功能、量化功
能以及代码生成功能进行了测试和分析,接着在 5.2 节以一个 Lenet5 网络为例通过搭
建软硬件测试平台对基于 CNN 加速器的后端代码生成功能进行测试。

5.1 编译器模块功能测试

5.1.1 编译器目录结构
图 5.1 所示为编译器源代码的源文件目录结构,其中每个子目录都表示编译器的
一个功能模块,各子目录对应的解释如表 5.1 所示。各个功能模块的功能已经通过对
应的测试文件进行了正确性测试。编译器使用者可以通过调用编译器驱动器并提供对
应的命令行参数来调用各个编译模块进行 ONNX 模型解析、量化和代码生成等功能;
也可以通过调用编译器的 API 函数进行计算图的构建、量化和代码生成。图 5.2 所示
的代码段即为编译器通过 API 函数进行计算图构建与图节点构建的示例。

图5.1 编译器的目录结构

图5.2 编译器 API 函数使用示例

55
西安电子科技大学硕士学位论文

表5.1编译器源文件目录及其解释
目录 解释
backends 编译器后端,包括一个解释器(Interpreter)
、一个生
成标准 C 代码的后端,以及一个基于 CNN 加速器进
行代码生成的后端
base 编译器基础数据结构和函数定义,包括向量、数据集、
计时器等数据结构定义,以及错误处理、文本格式化
等函数定义
codegen 节点生存期分析以及内存分配器相关模块
graph 编译器的 IR 定义,涵盖 Model、Graph 和计算节点
等与体系结构无关的数据类型定义
optimiser 计算图优化器,支持的优化方法包括各种节点融合优
化、死代码消除优化、常量折叠优化等
parser 解析器,目前仅支持载入 ONNX 格式的模型文件
quantization 编译 器量 化模 块, 目前 支持 的量 化类 型包 括对称
INT16 量化、对称 INT8 量化和 weight only 量化

5.1.2 编译器的网络调试功能测试
编译器的网络调试功能指的是编译器提供的对编译中间产物进行打印输出的功
能,该功能可以用于对输入模型的结构以及编译工作的正确性进行把握。编译器以计
算图为模型转换的中间表示,目前可以进行计算图打印的编译阶段包括计算图优化前、
图优化后,以及量化后。编译器驱动器提供的与网络调试相关的编译选项如表 5.2 所
示,从表中可以看出,编译器提供两种格式的计算图打印方式,第一种为以结构化文
本的形式对计算图结构进行打印,第二种则为以图形描述语言的格式将计算图输出到
dot 文件中。结构化文本的打印方式以屏幕作为输出目标,对计算图的计算节点属性
进行打印。DAG 格式的打印方式则以.dot 文件作为输出目标,所以还需要指定输出
文件名,这种打印方式可以将计算图绘制为可视化的有向无环图形式,提供了更加直
观的网络描述。
图 5.3 所示为编译器以 dot 文件格式输出的量化计算图片段,图中的每一个矩形
框节点都表示一个计算节点,每一个圆边矩形框表示一个数据节点,节点间的有向边
则表示了节点间的数据依赖关系。在节点内部为该节点的名称、节点类型、属性值以
及输出形状等信息描述,对于量化节点,其内部还存储了由该节点输出值的动态范围
计算得到的量化缩放因子以及零偏置,节点的输入形状以及元素类型可以通过其前驱
节点的输出进行推断。通过计算图的打印也可以对编译器的解析模块、优化模块和量

56
第五章 编译器测试与分析

化模块的正确性进行验证。

表5.2与网络调试相关的编译选项及其解释
编译选项 解释
dumpGraph 将重构计算图以结构化文本的形式输出到屏幕
dumpGraphAfterOptimise 将优化计算图以结构化文本的形式输出到屏幕
dumpGraphAfterQuantize 将量化计算图以结构化文本的形式输出到屏幕
dumpDAG 将重构计算图以图形描述语言的形式输出到 dot 文件
dumpDAGAfterOptimise 将优化计算图以图形描述语言的形式输出到 dot 文件
dumpDAGAfterQuantize 将量化计算图以图形描述语言的形式输出到 dot 文件

图5.3 计算图的 DAG 格式输出

57
西安电子科技大学硕士学位论文

5.1.3 编译器量化功能测试
基于嵌入式设备在内存和带宽资源上受限的问题,以及硬件加速设备对定点计算
的需求,本文的编译器内置了量化模块用于对模型进行量化。本节针对编译器的
INT16 量化模块设置 了两组 量化实验 ,量化 对象分 别为基于 Mnist[47] 数据集和
Cifar10[48]数据集训练的小型图像识别网络。实验在 PC 机的虚拟机上执行,对应的规
格参数如表 5.3 所示。表 5.4 展示了模型量化前后的参数大小以及其在测试集上的预
测精度和运行速度对比。从表中可以看出编译器的 INT16 量化可将模型的可学习参
数大小减少 50%,达到 2 倍的压缩比。虽然量化并未减少模型的参数数量,但其降低
了计算的复杂度并降低了带宽需求、提高缓存命中率以及可以更好的利用处理器的单
指令多数据功能,所以也能起到加速的作用。另一方面,由于从浮点型到低位宽的量
化会丢失部分信息,所以压缩后的模型在预测精度上略有损失。

表5.3测试用虚拟机的规格参数
操作系统 Ubuntu 16.04 LTS
CPU 型号 Intel ® Core™ i5- 4200
CPU 主频 2.8GHZ
核心数量 单核心
二级缓存 3M

表5.4 模型量化前后的参数量、准确率与推理时间对比
网络类型 数据类型 参数(K) 准确率(%) 推理时间(s)
Mnist FP32 88.6 98.9 6.552
Mnist INT16 44.3 98.3 4.235
Cifar10 FP32 249.4 66.2 21.931
Cifar10 INT16 124.7 65.7 15.778

Mnist 是一个手写数字数据集,包含 6 万个训练样本和 1 万个测试样本,每个样


本都为分辨率为 28x28 的单通道图片,所有图片被分为 10 个类别。该数据集使用包
括两个卷积层和两个全连接层的 Lenet5 网络也可以达到较高的准确率。实验选取
1000 张 Mnist 测试集图片作为校准集对模型其进行量化,然后在量化后的计算图上运
行整个测试集得到推理的准确率和总推理时间。对照组则在未量化的计算图上运行测
试集得到推理的准确度和总推理时间。采用 3.4 节的量化策略统计得到模型每一层的
权重和激活值的绝对值最大值和对应的量化缩放因子如表 5.5 所示。对于该组对照实
验,模型在量化前后的加速比为 1.547。

58
第五章 编译器测试与分析

表5.5 Mnist 模型的权值和激活值浮点范围及对应量化缩放因子


Layer Max(|weight|) Scale Max(|bias|) Scale Max(|activation|) Scale
conv1 0.5776 1.762×10-5 0.3329 1.015×10-5 5.5225 1.685×10-4
conv2 0.7021 2.142×10-5 0.1588 4.846×10-6 9.9252 3.029×10-4
fc1 0.4800 1.464×10-5 0.1237 3.775×10-6 15.6516 4.776×10-4
fc2 0.3636 1.109×10-5 0.1584 4.834×10-6 13.1837 4.023×10-4

Cifar10 是一个包含 6 万张图片的数据集,每个样本都是分辨率为 32x32 的彩色


图片,所有的图片被分为 10 个类别,其中 5 万张图片做为训练样本,剩下的 1 万则
为测试样本。相比于 Mnist 数据集,简单卷积网络对 Cifar10 分类的准确率并不高,
但由于本实验的目的并不在于追求高准确率,所以也只使用了一个包括两个卷积层和
三个全连接层的简单模型进行测试。实验选取 1000 张 Cifar10 测试集图片作为校准集
对模型其进行量化,然后在量化后的计算图上运行整个测试集得到推理的准确率和总
推理时间。对照组则在未量化的计算图上运行测试集得到推理的准确度和总推理时间。
采用 3.4 节的量化策略统计得到模型每一层的权重和激活值的绝对值最大值和对应的
量化激活因子如表 5.6 所示。对于该组对照实验,模型在量化前后的加速比为 1.389。

表5.6Cifar10 模型的权值和激活值浮点范围及对应量化缩放因子
Layer Max(|weight|) Scale Max(|bias|) Scale Max(|Activation|) Scale
conv1 0.2932 8.948×10-6 0.2855 8.713×10-6 2.7310 8.334×10-5
conv2 0.3472 1.059×10-5 0.2717 8.291×10-8 3.3575 1.024×10-4
fc1 0.2886 8.807×10-6 0.2844 8.679×10-6 5.7710 1.761×10-4
fc2 0.3605 1.100×10-5 0.2919 8.908×10-6 5.3330 1.627×10-4
fc3 0.3653 1.114×10-5 0.1539 4.696×10-6 4.9894 1.522×10-4

5.1.4 编译器代码生成功能测试与性能分析
通用编程语言编译器的性能指标主要包括代码的编译时间以及编译生成可执行
文件的运行速度。深度学习编译器作为领域专用编译器,其后端涵盖解释器、JIT 和
AOT 等多种形式,不同编译器生成的代码类型也不同,例如 XLA 的 AOT 模式可以
,NCNN[24]可以针对特定的芯片生成目标系统可加
编译模型生成目标文件(.o 文件)
载的模型文件,TVM[20]则可以生成其提供的运行时可加载的文件。由于不同编译器
的生成代码类型不尽相同,所以模型编译时间通常不作为深度学习编译器的一个性能
指标。此外,由于深度学习编译器生成的文件通常不能直接运行,所以一个常用于评
价深度学习编译器性能的指标为编译器每秒可以处理的图像数量(frame per second),
即对一个图像进行分类所需的时间。

59
西安电子科技大学硕士学位论文

虽然前文主要基于本课题组的 CNN 加速器进行后端的设计的与代码生成,但由


于目前并无其他编译器对该硬件系统进行支持,所以本节以编译器实现的通用 CPU
后端为例对编译器生成代码的性能进行测试,并与其他成熟的编译器进行比较。编译
器的通用 CPU 后端与 CNN 加速器后端主要区别为通用 CPU 后端只生成标准 C 代码。
实验以基础深度神经网络 lenet5 与 Alexnet[42]为目标模型进行编译与代码生成,
对照编译器为 Tensorflow XLA 1.12 和 Glow[23]编译器,实验环境为如表 5.3 所示 PC
机虚拟机,
网络模型均使用 Pytorch 进行预训练并导出为 ONNX 格式,由于 Tensorflow
不支持直接加载 ONNX 模型文件,所以需要使用模型转换器转为其支持的模型文件
格式。在使用 Tensorflow 对模型进行编译时启用了 XLA 的 JIT 模式进行加速,Glow
则采用 AOT 模式进行网络模型对应的目标文件生成。所有实验均在单线程环境下完
成,实验结果如图 5.4 所示。

图5.4 特定环境下的编译器性能比较

图 5.4 给出了在 Intel ® Core™ i5- 4200CPU 下,本文的 DLC 编译器和 Glow 以及
XLA 的性能对比。可以看出在本节的实验环境下,对于 Lenet5 和 Alexnet 网络,Glow
的性能要优于本文的编译器以及 XLA,主要的原因为 Glow 采用了更适合 CPU 进行
卷积加速的 NHWC 数据布局并基于直接卷积计算原理对卷积计算进行循环优化,而
XLA 与本文的编译器均采用了 caffe 的 im2col+gemm 进行卷积计算优化,在矩阵计
算前引入了额外的图像重排操作。而本节实验中本文编译器的性能要优于 XLA,主
要原因为实验涉及的模型较为简单,没有太多优化的余地,在同样使用 im2col 进行
卷积加速的情况下,本文的编译器通过将模型输出为 C 文件,并通过 gcc 编译器进行
-O3 优化级别的编译,可以得到比 XLA 的 JIT 模式更高的速度。

5.2 编译器整体功能测试

上一节介绍了编译器源代码的目录结构,并对编译器的量化功能和代码生成功能
进行了测试与性能分析,本小节将通过一个实例对包括 CNN 加速器后端的编译器整

60
第五章 编译器测试与分析

体功能进行测试。整体验证流程如图 5.5 所示。


测试实验在 Linux 环境下进行,涉及的软件工具包括本文实现的编译器、目标硬
件平台的 gnu 交叉编译工具链和开发套件,以及 J-Tag 下载工具。本文编译器的主要
工作为接收 ONNX 格式的模型为输入进行计算图的重构与优化、利用校准集进行计
算图的量化,以及通过编译器后端生成与模型前向推理计算等价的 C 代码。然后通
过编写测试程序对编译器生成的 C 函数进行调用。riscv-gun-tools 用于对编译生成的
模型代码和测试代码进行联合交叉编译,得到可执行的机器码。可执行文件由 J-Tag
工具下载到目标设备的内存中执行以验证代码的正确性。

Onnx Data Compiler


model set option program file

riscv-gnu-toolchain

Compiler
executable file

J-Tag
C file
FPGA

图5.5 编译器的整体验证流程图

编译器的目标体系结构为集成了 CNN 加速器的单核 SOC 平台 PULPissimo[43],


整个系统通过 Vivado 工具进行综合与实现,然后烧写到 FPGA 中进行验证。使用的
硬 件 平 台 为 Xilinx FPGA 开 发 板 ZCU102 , 架 构 为 Xilinx UltraScale , 型 号 为
XCZU9EG-2FFVB1156。
在进行交叉编译前需要先将加速器的自定义指令添加到 RISC-V 工具链中。在
gnu 工具链的的汇编级别添加一条指令只需要修改 binutils 代码而不需要修改编译器
本身,通过将加速器的 WRG 指令添加到 opcodes/riscv-opc.c 中,将指令的格式添加
到 inlude/opcodes/riscv-opc.h 中,
汇编器就能够识别出现在内联汇编中的加速器指令,
并转为对应的机器码。
本实验使用的网络模型为 Lenet5,该模型使用 Mnist 数据集进行训练。实验使用
的 Lenet5 模型结构如表 5.7 所示,该模型由 2 两个卷积层和 3 个全连接层构成,除最
后一个全连接层外每个层的输出都使用 Relu 函数进行激活。由于目标设备的加速器
针对稀疏网络进行了优化,为了能充分体现加速器的性能,该模型还进行了权值剪枝
以提高模型的权值稀疏性。

61
西安电子科技大学硕士学位论文

表5.7 Lenet5 模型结构


层类型 核尺寸/步长 输入 输出
conv 5x5/1 1x32x32 6x28x28
maxpool 2x2/2 6x28x28 6x14x14
conv 5x5/1 6x14x14 16x10x10
maxpool 2x2/2 16x10x10 16x5x5
fc - 400 120
fc - 120 84
fc - 84 10
对 Lenet5 模型进行权值剪枝后得到每个卷积层的稀疏度和对应的计算量如表 5.8
所示。表中的稀疏度指的是 0 值权重在所有权重中所占的比例,FLOPs 为每秒浮点数
的计算次数,可以用于衡量算法或模型的复杂度。通过权重剪枝提高权重稀疏度,可
以减少卷积层的有效计算量 ,经过权重剪枝的模型准确率由原来的 99.02%降为
98.79%,只是略有损失。这种非结构化剪枝通常需要配合专用的硬件才可以起到较好
的模型压缩与加速效果。虽然在参数剪枝时也对全连接层的权重参数进行了剪枝,但
由于编译器并不将全连接计算映射到支持稀疏处理的加速器上执行,所以编译器不对
全连接层参数进行压缩,避免引入额外的解压缩操作。

表5.8 剪枝后的稀疏度与计算量
层名称 权重稀疏度(%) 原始 FLOPs(K) 有效 FLOPs(K)
conv1 32.67% 235.2 158.38
conv2 74.54% 480 122.2

图5.6 测试模型的编译以及编译时间

Lenet5 模型的编译指令以及参数如图 5.6 所示,其中 dlc 为编译器驱动器可执行


文件名称;--model 参数指示待编译 ONNX 模型文件路径与名称;--outDir 指示编译
输出文件夹的路径;--modelName 指示编译输出文件以及与模型等价的 C 函数名称;
--backend 指示目标设备类型(可选的设备类型包括 interpreter、cpu、dla)
;--quantize
指示了编译采用的量化类型;--dataSet 指示量化校准集文件路径,该校准集包含了
1000 个已经经过预处理的 Mnist 测试集图片,每个图片都为尺寸为 32x32 的灰度图;
--time 指示驱动器打印模型总编译时间,对于图 5.5 所示的编译参数,总的编译时间
62
第五章 编译器测试与分析

为 119.559s,其中约 99.6%的时间用于激活值动态范围的收集和计算图的量化;编译
环境为 PC 机上的虚拟机,规格参数如表 5.3 所示。
由上述编译命令生成的文件列表如图 5.7 所示,包括一个头文件、一个源文件以
及一个 txt 格式的文本文件。其中 lenet5.txt 以数组的形式保存了模型的所有参数,这
些参数可以以下述代码的形式直接展开到数组中。
uint8_t weight[]={
#include "lenet5.h"
};

图5.7 编译测试模型生成的文件列表

lenet5.h 头文件内主要包括编译生成的模型入口函数声明,具体如图 5.8 所示。

图5.8 编译生成的头文件代码

除了入口函数声明,生成的头文件还在注释中指示了模型的输入输出形状和数据
类型。文件中的宏 ACTIVATION_SIZE_IN_BYTE 为模型运行时所需的激活值存储空
间大小,单位为 byte,该存储空间由调用模型的应用程序负责进行分配与释放。宏
WEIGHT_SIZE_IN_BYTE 则为存储所有权重参数所需的内存空间,单位为 byte。图
5.9 显示了编译器对激活值进行内存优化前后以及对权值进行压缩前后的内存占用比,

63
西安电子科技大学硕士学位论文

从图中可以看出,经过内存优化可以将运行时激活值内存需求降低 26.8%,权值的内
存需求可以降低 50.04%。

权值内存

优化前
激活值内存 优化后

0 0.2 0.4 0.6 0.8 1 1.2

图5.9 内存优化前后的内存占用比

编译生成的源文件内为后端代码生成器输出的 C 函数定义,包括与模型前向推
理计算等价的 lenet5 函数定义、各个节点计算对应的核函数定义,以及辅助函数定义
和宏定义。节点的核函数和辅助函数都为编译器内置的手写函数,在代码生成时可以
直接以字符串的形式直接输出到源文件中,图 5.10 所示为从源文件中截取的代码片
段,可以看出以 C 代码为编译输出形式具有非常高的可读性与可编辑性。

图5.10 编译生成源文件的核函数代码片段

图 5.11 所示为编译输出的入口函数片段,该代码段包括了多个节点映射,其中
量化操作、输入特征图压缩和数据搬移操作被输出为编译器的内置模板函数调用,而
加速器卷积节点对应的操作则被输出为由多条语句组成的语句块。从图中可以看出,
加速器卷积节点对应的动作包括权重数据搬移和控制寄存器配置。输入图像的压缩采

64
第五章 编译器测试与分析

用的是直接索引压缩方法,即仅保存图像中的非 0 数据,并提供图形掩码用于数据的
解压缩。通过调用编译器内置压缩函数,可以得到压缩数据、压缩数据对应的掩码以
及压缩数据的大小信息,紧接着压缩数据及其掩码被搬移到加速器的缓存中。外部存
储与加速器缓存间的批量数据传输由硬件平台的 uDMA 模块完成,加速器缓存与片
外存储进行统一编址,片上缓冲区在地址空间的映射如表 5.9 所示。加速器的参数配
置与功能模块的激活都通过 WRG 扩展指令完成,这条指令需要与其他标准 C 代码进
行联合编译,被以内联汇编的形式输出到源文件中。WRG 指令扩展自 RISC-V 指令
集中用于立即数赋值的 U 型指令,其伪指令的第一个参数为待赋值的控制寄存器,
第二个参数为所赋的立即数值。

图5.11 编译器输出的入口函数片段

表5.9 加速器片上缓存的地址映射
缓存类型 地址范围 大小 起始地址宏
输入缓存 0x30000000~0x30000800 2KB FEATURE_DATA_ADDR
特征图掩码缓存 0x30010000~0x30010400 1KB FEATURE_MUSK_ADDR
权重缓存 0x30020000~0x30020800 2KB WEIGHT_ADDR
偏置缓存 0x30030000~0x30030100 0.25KB BWI_ADDR

在得到 Lenet5 模型前向计算的等价函数后,还需要编写测试代码来调用该函数


以验证代码的正确性。由于程序运行的目标平台为 PULPissimo SOC,所以需要在主
机上对程序进行交叉编译得到可执行文件,然后下载到 FPGA 平台运行。

65
西安电子科技大学硕士学位论文

常用用于评价深度学习编译器性能的一个指标为编译器生成代码的运行时间,由
于目前并无其他编译器针对本实验所基于的硬件设备进行支持,故测试仅针对编译器
生成代码与手写代码的性能进行比较。
实验编写测试程序对手写模型推理代码和编译器生成的模型代码进行调用,实现
模型的推理。实验表明本文编译器自动生成的代码在目标设备上每秒可以处理的图形
数量为 1080.7 帧,而手写 Verilog 模型推理代码在 FPGA 上每秒可以处理的图像数量
为 1316.9 帧。手写代码的执行速度优于编译器自动生成代码,主要原可能是编译器自
动生成的加速器配置方案并非最优的,且也未对全连接层稀疏进行优化。

表5.10 编译生成代码与手写代码性能比较
手写代码 编译器生成代码
语言 Verilog C
FPS 1316.9 1080.7

5.3 小结

本章对编译器的网络调试功能、量化功能以及编译器的整体功能进行了测试和分
析,验证了其基本功能的完整性。实验表明本文的编译器可以成功的将深度学习模型
编译为等价的 C 代码与加速器指令,并在与测试程序一同编译后可以生成可执行文
件,虽然编译生成的代码在运行速度上略低于手写代码,但生成代码所需工作量与时
间都大大减少了。

66
第六章 总结与展望

第六章 总结与展望

6.1 本文的工作总结

基于神经网络的深度学习技术将图像识别和语音识别等领域的准确率提高到了
实用的地步。虽然深度神经网络的功能非常强大,但其运行成本也非常昂贵。大多深
度学习应用都是存储密集和计算密集型计算,对于资源受限的硬件设备来说模型推理
所需的计算可能会占据其大部分的计算资源、带宽以及功耗,这种高昂开销是许多设
备难以负担的。为了将深度学习模型移植到资源受限的终端与嵌入式平台,许多相关
的方法被提出,包括模型的压缩以及构建能够进行密集低精度计算的 AI 加速器。本
文主要以资源受限的深度学习专用硬件对软件工具的需求为出发点,以本课题组的集
成了 CNN 加速器的 SOC 芯片为例,设计并实现了一个深度学习编译器,本文完成的
工作如下:
(1)研究卷积神经网络的前向推理过程以及从顶层模型到硬件体系结构的端到端
优化部署,提出适用于本课题组的集成了 CNN 加速器的片上系统的深度学习编译器
结构,编译器通过将计算图所描述的计算转为等价的 C 代码,来复用原有的编译工
具链,并通过生成内联汇编提供对加速器自定义指令的支持。
(2)研究神经网络模型的描述方法,选择开放神经网络交换格式 ONNX 为编译
器的输入格式,基于 ONNX IR 设计适合于编译器实现的中间表示,并通过模型解析
器实现从 ONNX 计算图到编译器内部计算图的重构。
(3)研究工业上可行的神经网络模型量化方法,根据目标设备的硬件资源特点提
出相应的模型量化方案,并将模型量化功能内置到编译器中,使编译生成的 C 代码
能够在资源受限的设备上高效的执行,实验表明本文实现的量化方法可以在损失部分
推理精度的情况下将模型的规模减小 50%,并将模型推理所需的时间降低 21%~34%。
(4)设计并实现基于 CNN 加速器的编译器后端,提出对应的计算管理、内存管
理以及代码生成方案,
研究 CNN 加速器的卷积计算加速原理及其限制,提出基于 CNN
加速器的卷积计算分割方法,实验表明,本文的编译器后端可以实现将计算图转为等
价的 C 代码的功能,且可以通过激活值内存优化减少运行时激活值内存的使用。

深度学习编译器既需要面向复杂的硬件编程模型,又需要联系顶层的模型算法,
是 AI 芯片软件生态的重要组成部件。目前国内的学术领域对于深度学习编译的研究
不多,本文以本课题组研发的 CNN 加速芯片为目标设备,设计并实现了一个深度学
习编译器,并展示一个可行的深度学习模型解析、优化和编译流程。通过了解深度学
习编译器,不仅可以加深对深度学习知识的理解,也可以对如何在软硬件设计时进行

67
西安电子科技大学硕士学位论文

合理的软硬件任务划分起到一定的启示作用。本文实现的深度学习编译器与其他较成
熟的开源编译器类似,都采用经典的分层设计结构,且都以计算图作为图优化和变换
的中间表示;本文的编译器与其他编译器不同的地方在于直接以 C 代码作为编译器
的输出语言,且实现了基于 CNN 加速器的计算调度和加速指令的自动生成。编译器
还通过将模型量化全过程直接内置到编译流程中,进一步简化了编译器的使用。此外,
通过了解本文的编译器对进一步学习其他成熟编译器框架也有帮助。

6.2 未来的工作展望

深度学习与 AI 芯片都是目前的热门研究领域,作为连接深度学习算法及其实现
的深度学习编译器也得到了越来越多的关注。本文基于 CNN 加速器设计的深度学习
编译器实现了将深度学习模型扁平化为可以直接被其他程序调用 C 代码的功能,成
功隐藏了模型优化细节和硬件细节,达到了本文的设计目的。但本文的编译器仍旧是
个在功能和性能上都较弱的编译器,存在许多改进的空间。
(1)本文编译器目前仅支持一个 ONNX 算子的子集,主要与卷积神经网络相关,
后续可以添加更多算子来支持更多深度学习模型的编译,同时还可以添加多个模型解
析器来支持更多框架模型。
(2)本文的优化器只实现了少数几种计算图级别的模型优化算法,后续还需要
继续研究神经网络模型的优化策略,对优化器的功能进行扩充。
(3)本文的编译器后端只针对加速器计算资源限制进行卷积计算分割,未进行
基于缓存大小限制的特征图分割,后续还需对特征图分割方法进行探索。
(4)本文采用的模型量化方法较为单一,在设计上也未以量化模型的准确率为
主要考虑因素,后续还需继续研究各种高效的量化方法,扩充编译器的量化功能。
(5)目前本文的编译器需要通过命令行来进行调用,后续可以考虑为编译器添
加图形化界面,进一步提高编译器的易操作性。

68
参考文献

参考文献

[1] Sze Vivienne, Chen Yu-Hsin, Yang Tien-Ju, et al. Efficient Processing of Deep Neural Networks: A
Tutorial and Survey[J]. Proceedings of the IEEE, 2017, 105(12):2295-2329.
[2] Szegedy C, Ioffe S, Vanhoucke V, et al. Inception-v4, Inception-ResNet and the Impact of Residual
Connections on Learning[J]. arXiv preprint arXiv: 1602.07261, 2016.
[3] Real E, Moore S, Selle A, et al. Large-Scale Evolution of Image Classifiers[J]. Proceedings of the
34th International Conference on Machine Learning-Volume 70. JMLR. org, 2017. p. 2902-2911.
[4] Tan M, Le Q V . EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks[J].
arXiv preprint arXiv:1905.11946, 2019.
[5] Geoffrey Hinton, Li Deng, Dong Yu, et al. Deep Neural Networks for Acoustic Modeling in
Speech Recognition: The Shared Views of Four Research Groups[J]. IEEE Signal Processing
Magazine, 2012, 29(6):82-97.
[6] Chan W, Jaitly N , Le Q, et al. Listen, attend and spell: A neural network for large vocabulary
conversational speech recognition[C]// 2016 IEEE International Conference on Acoustics, Speech
and Signal Processing (ICASSP). IEEE, 2016.
[7] Devlin J, Chang M W, Lee K, et al. BERT: Pre-training of Deep Bidirectional Transformers for
Language Understanding[J]. arXiv preprint arXiv:1810.04805, 2018.
[8] Rajkomar A, Jeffrey D, Kohane I, et al. Machine Learning in Medicine.[J]. New England Journal
of Medicine, New England Journal of Medicine, 2019, 380(14): 1347-1358.
[9] Amanda R ,Kelsee B, Peter M C, et al. Deep Learning for Image-Based Cassava Disease
Detection[J]. Frontiers in Plant Science, 2017, 8:1852-.
[10] Amodei D, Olah C, Steinhardt J, et al. Concrete Problems in AI Safety[J]. arXiv preprint
arXiv:1606.06565, 2016.
[11] Grigorescu S, Trasnea B, Cocias T, et al. A Survey of Deep Learning Techniques for Autonomous
Driving[J]. Journal of Field Robotics, 2019.
[12] Iandola F N, Han S, Moskewicz M W, et al. SqueezeNet: AlexNet-level accuracy with 50x fewer
parameters and <0.5MB model size[J].arXiv preprint arXiv:1602.07360, 2016.
[13] Howard A G, Zhu M, Chen B, et al. MobileNets: Efficient Convolutional Neural Networks for
Mobile Vision Applications[J]. arXiv preprint arXiv:1704.04861, 2017.
[14] Gupta S, Agrawal A, Gopalakrishnan K, et al. Deep Learning with Limited Numerical
Precision[J].International Conference on Machine Learning. 2015. p. 1737-1746.
[15] Liu Z, Li J, Shen Z, et al. Learning Efficient Convolutional Networks through Network

69
西安电子科技大学硕士学位论文

Slimming[J]. Proceedings of the IEEE International Conference on Computer Vision. 2017. p.


2736-2744.
[16] Li H, Kadav A, Durdanovic I, et al. Pruning Filters for Efficient ConvNets[J]. arXiv preprint
arXiv:1608.08710, 2016.
[17] Hinton G, Vinyals O, Dean J. Distilling the Knowledge in a Neural Network[J]. Computer ence,
2015, 14(7):38-39.
[18] Vanhoucke V, Senior A, Mao M Z. Improving the speed of neural networks on CPUs[C]. In the
Deep Learning and Unsupervised Feature Learning Workshop, NIPS, 2011.
[19] Kazushige Goto, Robert Geijn van de. High-Performance Implementation of the Level-3 BLAS[J].
Acm Trans.math.softw, 2006, 35(1):2573-2580.
[20] Chen T, Moreau T, Jiang Z, et al. TVM: An Automated End-to-End Optimizing Compiler for Deep
Learning[C]. 13th {USENIX} Symposium on Operating Systems Design and Implementation
({OSDI} 18). 2018. 578-594.
[21] Cyphers S, Bansal A K, Bhiwandiwalla A, et al. Intel nGraph: An Intermediate Representation,
Compiler, and Executor for Deep Learning[J]. arXiv preprint arXiv:1801.08058, 2018.
[22] N. Vasilache, O. Zinenko, T. Theodoridis, et al. Tensor Comprehensions: Framework-Agnostic
HighPerformance Machine Learning Abstractions[J]. arXiv preprint arXiv:1802.04730, 2018.
[23] Nadav Rotem, Jordan Fix, Saleem Abdulrasool, Garret Catron, et al, Glow: Graph Lowering
Compiler Techniques for Neural Networks[J], arXiv preprint arXiv:1805.00907, 2018.
[24] W. F. Lin, D. Y. Tsai, L. Tang, et al. ONNC: A compilation framework connecting ONNX to
proprietary deep learning accelerators[J], in IEEE International Conference on Artificial
Intelligence Circuits and Systems (AICAS 2019). IEEE, 2019.
[25] Jonathan Millar Ragan-Kelley, Connelly Barnes, Andrew Adams,et al. Halide: A Language and
Compiler for Optimizing Parallelism, Locality, and Recomputation in Image Processing
Pipelines[C]// Proceedings of the 34th ACM SIGPLAN conference on Programming language
design and implementation. ACM, 2013.
[26] C. Lattner, V. Adve. LLVM: a compilation framework for lifelong program analysis &
transformation[C]// International Symposium on Code Generation & Optimization. IEEE, 2004.
[27] AKOPYAN, Filipp, et al. TrueNorth: Design and Tool Flow of a 65mW 1 Million Neuron
Programmable Neurosynaptic Chip[J]. IEEE Transactions on Computer Aided Design of Integrated
Circuits & Systems, 2015, 34(10):1537-1557.
[28] Chen Y, Chen T, Xu Z, et al. DianNao family: energy-efficient hardware accelerators for machine
learning[J]. Communications of the ACM, 2016, 59(11):105-112.
[29] Jouppi N P, Borchers A, Boyle R, et al. In-Datacenter Performance Analysis of a Tensor Processing

70
参考文献

Unit[C]// the 44th Annual International Symposium. IEEE Computer Society, 2017.
[30] Chen Y H, Krishna T, Emer J S, et al. Eyeriss: An Energy-Efficient Reconfigurable Accelerator for
Deep Convolutional Neural Networks[C]// IEEE International Solid State Circuits Conference.
IEEE, 2016.
[31] Chen Y H, Emer J, Sze V. Eyeriss: A Spatial Architecture for Energy-Efficient Dataflow for
Convolutional Neural Networks[J].ACM SIGARCH Computer Architecture News, 2016, 44(3):
367-379.
[32] Chen Y H, Yang T J, Emer J, et al. Eyeriss v2: A Flexible Accelerator for Emerging Deep Neural
Networks on Mobile Devices[J]. IEEE Journal on Emerging and Selected Topics in Circuits and
Systems, 2019, 9(2): 292-308.
[33] Yin S., Ouyang P., Tang S, et al. A High Energy Efficient Reconfigurable Hybrid Neural Network
Processor for Deep Learning Applications[J]. IEEE Journal of Solid State Circuits, 2018, 53(4):
968-982.
[34] Ma N, Zhang X, Zheng H T, et al. ShuffleNet V2: Practical Guidelines for Efficient CNN
Architecture Design[C]. In Proceedings of the European Conference on Computer Vision (ECCV).
2018.116-131.
[35] Sharan Chetlur, Cliff Woolley, Philippe Vandermersch, et al. cuDNN: Efficient Primitives for Deep
Learning[J]. arXiv preprint arXiv: 1410.0759, 2014.
[36] Michael Mathieu, Mikael Henaff, Yann LeCun. Fast Training of Convolutional Networks through
FFTs[J], arXiv preprint arXiv:1312.5851, 2013
[37] Lavin A, Gray S. Fast Algorithms for Convolutional Neural Networks[C]. Proceedings of the IEEE
Conference on Computer Vision and Pattern Recognition. 2016. 4013-4021
[38] Fukushima K. Neocognitron: A self-organizing neural network model for a mechanism of pattern
recognition unaffected by shift in position[J]. Biological Cybernetics, 1980, 36(4):193-202.
[39] Lecun Y, ottou L, Bengio Y, et al. Gradient-based learning applied to document recognition[J].
Proceedings of the IEEE, 1998, 86(11):2278-2324.
[40] Cun Y L, Boser B, Denker J S, et al. Handwritten Digit Recognition with a Back-Propagation
Network[J]. Advances in neural information processing systems, 1997, 2(2):396--404.
[41] 田娟, 李英祥, 李彤岩. 激活函数在卷积神经网络中的对比研究[J]. 计算机系统应用, 2018,
v.27(07):45-51.
[42] Krizhevsky A, Sutskever I, Hinton G. ImageNet Classification with Deep Convolutional Neural
Networks[J]. Advances in neural information processing systems, 2012, 25(2).
[43] Schiavone P D, Rossi D, Pullini A, Di Mauro A, Conti F, and Benini L. Quentin: An
ultra-low-power pulpissimo soc in 22 nm FDX[C], in Proc. IEEE SOI-3D-Subthreshold

71
西安电子科技大学硕士学位论文

Microelectron. Technol. Unified Conf. (S3S), 2018,1–6.


[44] I.S.A. VIBU, Waterman A, Lee Y, et al. The RISC-V instruction set manual[M]. University of
California, Berkeley, 2016.
[45] Hubara I, Courbariaux M, Soudry D, et al. Quantized neural networks: Training neural networks
with low precision weights and activations[J]. The Journal of Machine Learning Research, 2017,
18(1): 6869-6898.
[46] Jacob B, Kligys S, Chen B, et al. Quantization and Training of Neural Networks for Efficient
Integer-Arithmetic-Only Inference[C]. Proceedings of the IEEE Conference on Computer Vision
and Pattern Recognition. 2018. 2704-2713.
[47] Deng L. The MNIST Database of Handwritten Digit Images for Machine Learning Research [Best
of the Web][J]. Signal Processing Magazine, IEEE, 2012, 29(6): 141-142.
[48] Krizhevsky A, Hinton G. Learning multiple layers of features from tiny images[M] . [S.l.]:Citeseer,
2009.

72
致谢

致谢

时光飞逝,转眼已经在西电度过了七年光阴。在西电的这四年本科和三年研究生
学习和生活中经历了许多的有意思的人和事,有收获也有遗憾,但无论如何这段求学
经历都会是我人生旅途中非常重要的一个节点。在此特要感谢这三年研究生生涯中帮
助、关心过我的人。
首先我要感谢我的导师蔡觉平老师,他在我这几年的学习和生活中起到了十分重
要且积极的作用。每次在我学习工作遇到困难时,老师都及时给予我新的思路和角度
来看待问题,使我在科研工作中收益匪浅。生活中遇到的问题和矛盾时也能给予及时
的开导与鼓励。当然蔡老师做的远不止这些,他严谨认真的工作态度,严于律己、宽
厚待人的为人处世方式都给我们立下了十分好的榜样。在此要衷心感谢蔡老师三年来
的培养。
其次我要感谢的实验室的伙伴们,感谢他们一路走来对我的对我的帮助和关怀。
感谢同届的王松、郭捷、张灿和陈腾腾,以及温凯林、褚洁、阮文长等师兄在科研上
对我的细心帮助和指导。他们积极求学、刻苦专研的态度深深的影响了我,他们出色
的能力也鞭策我要不断努力学习,提高自己的专业水平,成为更有用的人。
最后还要感谢我的父母,感谢你们一直以来对我的理解和支持,感谢你们从不给
我压力,让我可以自由选择自己的方向,可以专注于学习与科研。
在此再次衷心感谢本硕七年在西电遇到的所有老师和同学!

73
西安电子科技大学硕士学位论文

74
作者简介

作者简介

1. 基本情况

张芳芳,女,福建宁德人,1995 年 3 月出生,西安电子科技大学微电子学院微电
子学与固体电子学专业 2017 级硕士研究生。

2. 教育背景

2013.08~2017.07 西安电子科技大学,本科,专业:集成电路设计与集成系统
2017.08~ 西安电子科技大学,硕士研究生,专业:微电子学与固体电子学

3. 攻读硕士学位期间的研究成果

3.1 申请(授权)专利

[1] 蔡觉平, 张芳芳, 专利名称:一种用于可扩展指令集的编译器及编译方法, 中


国专利申请号: 201911298413.1

75
X I D IA N UN I V E R S I T Y

地址 :
西 安 市 太 白 南 路2号


邮编 : 7 1 0 07 

You might also like