模型量化

1 minute read

Published:

浅谈 Deep Learning 落地与工程部署问题

转载自(https://polariszhao.github.io/2020/12/14/%E6%B5%85%E8%B0%88DeepLearning%E8%90%BD%E5%9C%B0%E4%B8%8E%E5%B7%A5%E7%A8%8B%E9%83%A8%E7%BD%B2/)[https://polariszhao.github.io/2020/12/14/%E6%B5%85%E8%B0%88DeepLearning%E8%90%BD%E5%9C%B0%E4%B8%8E%E5%B7%A5%E7%A8%8B%E9%83%A8%E7%BD%B2/]

一. 概述

模型的的压缩加速:轻量级架构设计、剪枝、蒸馏、量化、低秩分解

框架层面 基础优化:算子优化(conv 实现)、 图优化(DAG、op 融合)、不同精度的训练/推理

代码层:循环展开、汇编、并行优化(SIMD)

系统调度:内存优化、Cache 优化、流水线重排

计算引擎: neon、cuda、vulkan、Metal、OpenVINO、HiAI、OpenCL

编译器:TVM 和 MLIR

硬件: arm、gpu、cpu、x86、npu

几个值得关注的点:

MLIR(MachineLearning Intermediate Represent) : 可以参照:MLIR(https://github.com/tensorflow/mlir)、TVM、XLA

软硬件协同设计

NLP 领域的模型压缩进展

二. 常用模型压缩与加速方法

轻量级网络设计与搜索:

设计轻量化的网络架构,如 mobilenet 、shufflenet、ghostnet 等

使用 NAS 搜索较为高效的网络结构

模型蒸馏:使用复杂模型( teacher model) 去训练另一个轻量化的网络(student model)

网络的压缩技术(剪枝、稀疏化、量化)

在训练时使用稀疏约束(加入权重的稀疏正则项,引导模型的大部分权重趋向于0,然后在完成训练后,剪去滤波器上的这些权重较低的节点

量化:模型量化是指权重或激活输出可以被聚类到一些离散、低精度(reduced precision) 的数值点上。常见的有二值网络、三值网络、int8 量化

低秩分解

上述的 1 会改变网络的计算图, 而 2 则不会改变网络的计算图,而是在原有计算图的基础上进行网络模型的压缩和加速

三. 常见的推理框架

​ 一般会提供模型优化和推断引擎两个模块。模型优化模块用于将给定的模型转化为标准的 Intermediate Representation (IR) ,并对模型优化。推断引擎 (Inference Engine) 则会根据特定的硬件进行算子的优化,以实现高效的前向推导。

国外:

google:tf-lite https://www.tensorflow.org/lite/performance/post_training_quantization

facebook:caffe2 + qnnpack: https://github.com/pytorch/QNNPACK

intel: open-vino(for intel CPU) https://software.intel.com/en-us/openvino-toolkit

apple: core ml

nvidia: TensorRT(for nvidia GPU)

国内:

腾讯:ncnn -> TNN(for arm chip) https://github.com/Tencent/ncnn

阿里: mnn https://github.com/alibaba/MNN

百度: paddlelite https://github.com/PaddlePaddle/Paddle-Lite

小米:mace https://github.com/XiaoMi/mace

其他

TVM: https://github.com/dmlc/tvm

TC: TensorComprehensions

onnx: https://github.com/onnx/onnx

四、硬件发展

各类硬件的发展都离不开芯片制程、核心数量、指令架构优化三个主要方向

服务器端硬件分类

x86_64 CPU、NVIDIA GPU、服务器 NPU

移动端硬件分类

​ ARM CPU、ARM GPU(Adreno、mali系列)、移动端NPU、NVIDIA Jeston系列、Apple 家的芯片(自家GPU、NPU)

其他

​ DSP、FPGA、外接式加速设备,各种云平台形式的部署

五. 一些基本的问题

  1. 工程上对卷积操作如何进行优化的? 目前,卷积的计算大多采用间接计算的方式,主要有以下几种实现方式, 其中前三种是主流方案

滑窗机制。这种方法是最直观最简单的方法。 但是,该方法不容易实现大规模加速,因此,通常情况下不采用这种方法(但是也不是绝对不会用,在一些特定的条件下该方法反而是最高效的)

im2col + GEMM。 caffe/MXNet等很多框架中都使用了这种计算方式,原因是将问题转化为矩阵乘法后可以方便的使用很多矩阵运算库(如MKL、openblas、Eigen等)

Winograd:快速卷积算法,针对不同大小的卷积核进行优化,减少计算中的乘法运算次数,提升运行速度。-> 大部分的前向推导框架都实现了 winograd算法

FFT变换。 时域卷积等于频域相乘,因此可将问题转化为简单的乘法问题。傅里叶变换和快速傅里叶变化是在经典图像处理里面经常使用的计算方法,但是,在 ConvNet 中通常不采用,主要是因为在 ConvNet 中的卷积模板通常都比较小,例如 3×3 等,这种情况下,FFT 的时间开销反而更大,所以很少在CNN中利用FFT实现卷积

  1. 为什么 mobilenet 理论上速度很快,工程上并没有特别大的提升?

(1) 硬件相关:GPU 偏重于并行、CPU 侧重于侧重于串行。很多细粒度的操作没法很好的并行。

(2) 和对应的 DL 框架实现细节有关:没有对 dw 和 pw 算子进行优化,比如访存次数、cache miss 较多等。

(3) 参数量和计算量:设计衡量的指标是 FLOPS、而不是时间。很多 element-wise 操作以及细粒度操作会增加推导时间

  1. 模型压缩方向 NAS 研究进展追踪(该方向自己暂时没有形成系统理论,不独立成文)

DARTS:Differentiable Architecture Search 可微分神经网络架构搜索

Designing Network Design Spaces

NAS-Bench-101: Towards Reproducible Neural Architecture Search

AMC:AMC: AutoML for Model Compression and Acceleration on Mobile Devices

AutoSlim: Towards One-shot Architecture Search for Channel Numbers

  1. 软硬件联合设计研究进展追踪(该方向自己暂时没有形成系统理论,不独立成文)

Algorithm-Hardware Co-Design of Adaptive Floating-Point

SmartExchange: Trading Higher-cost Memory Storage/Access for Lower-cost Computation

Drynamic region-based quantization for deep neural network acceleration

MCUNet: Tiny Deep Learning on IoT Devices

Once-for-all: train one network and specialize it for efficient deployment