Summary of Deep Learning Acceleration Methods

Abstract: In order to improve the performance of deep learning inference, the deep learning inference acceleration technology has made remarkable progress in recent years. It effectively accelerates the speed of deep learning inference by optimizing the network structure, data, algorithm and hardware. This article will introduce several common deep learning acceleration techniques.

优化方向 优化方法 适用场景
计算优化 模型结构优化 在CNN模型上应用较多,但需要根据模型和业务特点优化计算组件
模型剪枝 受底层计算平台限制较多,精度损失较明显,适用于精度不敏感的模型推理应用场景
模型量化 量化技术适用场景较广,加速效果明显
知识蒸馏 适用于大模型的推理应用,不同模型蒸馏的效果差异明显
系统优化 通信机制优化 PS框架适用于推荐类模型DNN浅层模型, RingAllReduce适用于DNN深度模型
通信数据量优化 适用于通信占比高的应用场景
硬件优化 GPU/TPU/TensorRT TensorRT目前仅支持推理

一、计算优化

1.模型结构优化

模型结构优化的方法大部分还是基于人工经验去设计一些具有相似功效的“轻型”计算组件来替换原模型中“重型”计算组件。

这一点在CNN神经网络的进化历史上显得尤为突出。比如CNN神经网络基于图像的局部感知原理设计滤波器计算组件来替代全连接神经网络,以局部计算和权值共享的方式实现了模型瘦身。而随后的NIN、VGG、GoogleNet、SqueezeNet、MobileNets、ShuffleNets等则是在滤波器上动刀,用小组件替换大组件做进一步优化,具体优化方法如下:

模型 优化结构 优化方式
NIN MLP-conv模块 通过1x1卷积核及Avg-pooling代替fully connected layers减小参数
VGG 3x3卷积核 采用连续的3x3的小卷积核代替AlexNet中的大卷积核
GoogleNet Inception模块 使用多个不同尺寸的卷积层,以一种结构化的方式来捕捉不同尺寸的信息
SqueezeNet Fire模块 Squeeze层用1x1的卷积核实现数据压缩, Expand层用1x1和3x3卷积核进行特征抽取
MobileNets Depth-wise conv模块 用深度可分离的卷积方式代替传统卷积方式
ShuffleNets Group-conv模块
Channel-shuffle模块
用Channel-shuffle模块优化组间信息交换

上述这些优化操作都依赖于人工经验,费时费力,组合优化这种事情更适合让机器来做,于是神经网络结构搜索(NAS)技术就应运而生。

2. 模型剪枝

模型剪枝的初衷就是深度学习模型的过度参数化,说白了就是你的模型太胖了,跑不动,需要减肥。根据模型剪枝的方法可以分为两大类:一类是结构化剪枝,另一类是非结构化剪枝。

所谓结构化剪枝是对参数矩阵做有规律的裁剪,比如按行或列裁剪,使得裁剪后的参数矩阵仍然是一个规则的的矩阵。结构化裁剪主流的方法有Channel-level、Vector-level、Group-level、Filter-level级别的裁剪。

非结构化剪枝是将原本稠密的参数矩阵裁剪为稀疏的参数矩阵,一般矩阵大小不变,其效果类似于参数正则化。因为目前大部分计算平台不支持稀疏矩阵的计算,只有结构化剪枝才能真正减少计算量。

根据业界的实践经验,非结构化模型剪枝的模型精度损失较小,但受限于底层计算框架,计算加速效果有限。而结构化模型剪枝可以较大幅度地减少模型参数,实现可观的计算加速,但容易造成明显的性能损失。

3.模型量化

模型量化是通过减少表示每个权重参数所需的比特数来压缩原始网络,从而实现计算加速。

半浮点精度(FP16)和混合精度是一种常见的做法,不过需要底层计算框架支持,否则无法实现计算加速。另一种是INT8量化,即将模型的权重参数从FP32转换为INT8,以及使用INT8 进行推理。量化的加速主要得益于定点运算比浮点运算快,但从FP32量化为INT8会损失模型精度。量化不会改变权重参数的分布,只是将权重参数从一个值域映射到另一个值域,过程类似于数值的归一化。

采用普通量化方法时,靠近零的浮点值在量化时没有精确地用定点值表示。因此,量化后的模型预测准确度会显著下降,如均一量化,会将具有动态值密度的浮点映射成具有恒定值密度的定点。其中一种的做法是在量化过程中做值域调整。

值域调整的目标是学习能在量化后更准确地运行网络的超参数min/max,即归一化参数。根据调整的时机,可以进一步划分为训练后量化和训练时量化,代表分别为 Nvidia Calibration 和 TensorFlow Quantization-aware Training。

4.模型蒸馏

模型蒸馏本质上和迁移学习类似,只是它还多了一个模型压缩的目的,即通过模型蒸馏,将大模型压缩为小模型,使小模型可以跑得又快又好。所以,最基本的想法就是将大模型学习得到的知识作为先验,将先验知识传递到小规模的神经网络中,并在实际应用中部署小规模的神经网络。在实际研究中,我们将大模型称为Teacher,小模型称为Student,模型蒸馏的过程就是让Student去学习Teacher的知识。目前大部分模型蒸馏框架都是基于Teacher-Student的模式,只是有些方法会请多几个Teacher或者配个Assistant。

二、系统优化

加速深度学习模型训练速度最有效的方法便是增加计算资源,将单机训练的模型扩展为多机训练。目前各大主流框架的多GPU分布式训练一般存在两种模式:模型并行和数据并行

模型并行是将模型切分为多个子模块,每个计算设备负责其中一个子模块的计算。数据并行则是对训练数据进行切分,将数据分片分配到不同设备上进行并行计算。随着内存和显存容量的扩大,大部分深度学习模型可以直接存放在单个节点上,以数据并行的方式运行。

分布式机器学习系统的核心是参数的同步和更新,而Parameter Server(PS)是目前主流的深度学习系统默认参数同步方案。该方案中包含两类节点,一类是Server,负责存储模型参数;一类是Worker,负责模型计算。Worker在每次训练迭代开始前,从Server拉取最新的模型参数,并在本地完成模型的计算;Worker在每次训练迭代结束后,发送梯度给Server,由Server来更新参数。

整个模型训练过程涉及了大量的数据交换,由于深度学习模型具有大量的参数,即便使用10GbE网络,参数的传输也会成为瓶颈。实验证明,在8个节点进行Tensorflow分布式训练,对于VGG19网络,90%的时间花在等待网络传输上面。因此,大量的研究工作集中在消除网络通信瓶颈。

目前主要有两大类方向,一类是研发新的通信机制,实现最优的参数交换,如RingAllReduce。RingAllReduce将计算节点组织成环状结构,每个节点只和邻居节点进行通信,每次交换一部分数据,通过2*(N-1) 次通信就可以完成数据的同步。

另一类是试图减少节点之间的数据交换量,从而消除网络通信瓶颈,如梯度压缩,其核心思想是每次只选择“重要”的梯度进行更新,从而减少通信开销。

梯度累计和补偿是目前最常见的一种做法,目前大部分研究都是围绕这一点在展开。从单机单卡扩展为多机多卡是实现模型加速最有效的途径,消除网络通信瓶颈的研究只是为了追求更高的计算性价比。

三、硬件优化

  • 深度学习应用开发的两个阶段
    • 训练:利用训练数据生成和优化网络模型
    • 推理:把网络模型集成到应用程序,输入现实数据,得到推理结果
  • TensorRT深度优化了推理的运行效率
    • 自动选取最优 kernel
      • 矩阵乘法、卷积有多种UDA实现方式,根据数据大小和形状自动选取最优实现
    • 计算图优化
      • 通过 kerne融合、减少数据拷贝等手段,生成网络的优化计算图
    • 支持fp16/int8
      • 对数值进行精度转换与缩放,充分利用硬件的低精度高通量计算能力

TensorRT能够优化重构由不同深度学习框架训练的深度学习模型:

  • 对于Caffe与TensorFlow训练的模型,若包含的操作都是TensorRT支持的,则可以直接由TensorRT优化重构;
  • 对于MXnet, PyTorch或其他框架训练的模型,若包含的操作都是TensorRT支持的,可以采用TensorRT API重建网络结构,并间接优化重构;
  • 其他框架训练的模型,转换为ONNX中间格式后,若包含的操作是TensorRT支持的,可采用TensorRT-ONNX接口予以优化;
  • 若训练的网络模型包含TensorRT不支持的操作:
    • TensorFlow模型可通过tf.contrib.tensorrt转换,其中不支持的操作会保留为TensorFlow计算节点;MXNet也支持类似的计算图转换方式。
    • 不支持的操作可通过Plugin API实现自定义并添加进TensorRT计算图,例如Faster Transformer的自定义扩展;
    • 将深度网络划分为两个部分,一部分包含的操作都是TensorRT支持的,可以转换为TensorRT计算图。另一部则采用其他框架实现,如MXnet或PyTorch,并建议使用C++ API实现,以确保更高效的runtime。
  • TensorRT的INT8量化需要校准(calibration)数据集,一般至少包含1000个样本(反映真实应用场景),且要求GPU的计算功能集sm >= 6.1;