前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >深度学习算法优化系列三 | Google CVPR2018 int8量化算法

深度学习算法优化系列三 | Google CVPR2018 int8量化算法

作者头像
BBuf
发布于 2019-12-27 05:32:20
发布于 2019-12-27 05:32:20
2.7K0
举报
文章被收录于专栏:GiantPandaCVGiantPandaCV

在这里插入图片描述

1. 前言

这是Google在CVPR 2018上发表的一篇int8量化的论文,题目为《Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference》。也是入门量化最经典的论文之一。论文介绍了一种只使用整数运算的量化方式,相比于浮点数运算效率更高。一起先来看看这篇论文吧。论文的axriv地址可以在附录中找到。

2. 背景

模型量化仍然属于模型压缩的范畴,而模型压缩的目的是降低模型的内存大小,加快模型推理速度。在这之前,主要有两方面的研究用于减少模型的大小和前向推理的时间。一是在网络结构上的改进,诸如MobileNet,SqueezeNet,ShuffleNet和DenseNet等等。二是量化权重和激活函数,将32位的浮点数用更低位的数来表示,如half-float,int,bit等等。然而这些方法并没有在一个合理的BaseLine基础上进行评估。这些网络的BaseLine几乎都是选在AlexNet,VGG16,GoogleNet这种大型网络,而这些大型网络在设计时为了达到高准确率存在很多容易,所以在压缩这些网络时都有不小的效果提现。其二在于很量化方法没有在真正的硬件上进行有效性证明。有的方法只在权重上进行量化,仅仅关心设备的存储,而不关心计算效率。有的方法如2-bit/3-bit权重网络和bit-shifit网络,它们把权重限制为0或者,即把乘法操作用二进制移位来实现。但在某些硬件上,二进制移位实现并不比乘法,加法好。并且,只有当Bit大的时候,乘法操作才显得比较"昂贵"。从上面的介绍引出这篇论文的目的,即是要将乘法的输入:权重和激活值都量化成比较小的位宽,即int8量化。

同时,量化一般可以分为两种模式,即训练后量化(post-training-quantizated)以及训练时量化(quantization-aware-training)。训练后量化比较容易理解,即将训练后的模型中的权重从float32量化到int8,并以int8的形式保存,但在实际推理时,还需要反量化为浮点数类型进行计算。这种量化方式在大模型上的效果很好,因为大模型的抗噪能力很强,但在小模型上表现就比较差了。而训练中量化意思是在训练的过程中引入伪量化操作,即在前向传播的时候,采用量化后的权重和激活值,但在反向传播的时候仍然对float类型的权重进行梯度下降,前向推理时全部使用int8的方式进行计算。

3. 方法

这篇论文提出了一种将float32量化为int8的方法,并给出了一个训练和推理框架,推理框架使得模型可以在能执行整型运算的计算设备上高效运行,训练框架和推理框架相辅相成,可以显著降低量化过程中的精度损失。

3.1 量化推理

3.1.1 量化方案

首先,定义代表量化后的值,代表原始的float32值,这篇论文抛弃了之前使用查表的方式将浮点数映射为整数的方法,而是直接引入了一个映射关系来表示,如公式(1)所示:

其中代表缩放系数,代表,即真实浮点数映射到整数时所对应的值,和的数据类型一致。对于int8量化,就是8-bit整数,对于B-bit量化,q就是B-bit的实数,对于有bias的情况,就固定量化为·32-bit的实数。其中的计算方式为:

然后可以表示为:

其中算子表示:

再从公式(1)推导得到反量化公式,这是训练的时候反向传播要用到的:

如果我们用C++里面的结构体来表示这个数据结构,那么就可以写成下面的形式:

可以将卷积层的量化过程总结如下,这部分借鉴了一篇CSDN博主的流程,链接放在附录的参考博客1了。卷积层的量化过程表示为:

  • 1、输入 量化的特征图lhs_quantized_val, uint8类型, 偏移量 lhs_zero_point, int32类型。
  • 2、输入 量化的卷积核rhs_quantized_val, uint8类型, 偏移量 rhs_zero_point, int32类型。
  • 3、转换uint8int32类型。
  • 4、每一块卷积求和,注意int32_accumulator求和有溢出的风险,可以换成固定点小数乘法。这部分公式表示为:int32_accumulator += (lhs_quantized_val(i, j) - lhs_zero_point) * (rhs_quantized_val(j, k) - rhs_zero_point)
  • 5、输入量化的乘子quantized_multiplier, int32类型和右移次数记录right_shift, int类型。将int32_accumulator右移right_shift位。
  • 6、计算乘法,得到int32结果,仍有溢出风险,可以换为固定点小数乘法。这部分公式表示为:quantized_multiplier * int32_accumulator
  • 7、加上结果的偏移量 result_zero_point
  • 8、左移right_shift位还原,得到int32的结果。
  • 9、将int32类型结果 限幅到[0, 255], 再强制转换到 uint8类型。
  • 10、之后再反量化到浮点数,更新统计输出值分布信息maxmin
  • 11、再量化回uint8。
  • 12、之后量化激活层。
  • 13、最后反量化到浮点数,即卷积层的输出。
  • 14、进入下一层,循环执行1-13步骤。

值得注意的一点事,如果有连续的层需要进行量化操作时,就没有必要反量化了,如上面的10->11步骤,但这很有可能带来乘加累积导致的溢出,所以每层量化似乎似乎是比较稳妥的做法。

3.1.2 纯整数算术矩阵乘法

从公式(1)可以看到,每个中的实数都表示带有一对参数和的实数。则对实数矩阵,做乘法,其结果矩阵的每个实数可以用下面的公式表示:

这个公式可以重写为:

其中:

可以看到是式子(3)中唯一不是整数的值,并且经验发现的值总是在中,所以可以将表示为下面的式子:

其中是非负整数,是一个整数。这样实数运算就变成了整数运算,同时可以用移位运算。这个就是上面介绍的卷积层量化过程中的右移参数。

注意,这里还有一个关键点就是在预测阶段,权重矩阵的量化系数可以通过已有的参数统计出来。而激活层的量化参数是大量训练数据指数移动均值计算出来的,所以这里才会有没出来,但先使用了。

3.1.3 零点的有效处理

在上面的公式(4)中因为两个矩阵都需要减去各自的零点Z值,减法运算后得到的值可能会突破int8范围,到时候就需要int16来存储,但整个运算为了控制在int8的类型下计算,论文做了下面的变换。

这样可以有效的避免计算过程中的值溢出int8范围。但可以发现,这个等效变换仍然没有改变整个计算的复杂度,都为。

3.1.4 融合一个层

前面描述了权重的矩阵计算,但在神经网络中还有偏置bias和激活函数的映射,因为int8类型的运算完之后的值应该是在int32之内的,所以bias选择int32的类型,这样的选择一是因为bias在整个神经网络中只占据极少的一部分,此外bias的作用其实非常重要,高精度的bias可以降低模型的偏差。因此加上bias之后就变成了int32,我们需要再次转换成int8类型(反量化),之后再进入到激活中。具体如下图所示:

再用公式详细表达一下,定义bias的量化:

其中,用int32表示。将weightsinput执行矩阵乘法后加上bias,公式表达为:

得到了int32之后的结果后需要再次转换成int8类型(反量化),之后再执行激活函数的操作。

4. 模拟量化训练

在介绍中提到,后处理量化过程适合大模型,而小模型会导致精度损失比较大。论文认为后处理量化主要存在两点问题:

  • 同一层不同通道的权重分布尺度差很多(超过100x)
  • 离散的权重会导致所有剩余权重的精度下降

因此,论文提出了一种在前向传播阶段模拟量化的方法,反向传播和平常一样,所有的权重和biases都用浮点数保存以微调小变化。具体的量化方法如下: 1、 weights再输入进行卷积之前就开始量化,如果有bn层,将bn层融入到weights中。 2、 激活在激活函数执行完之后再量化。

如下图所示:

量化的公式如下:

这和上面介绍的推理阶段的量化公式完全一致,我就不再赘述了。

4.1 学习量化范围

对于上面的量化范围(a, b)weightactivation是不一样的,对于weight来说很简单,就是该权重中最大最小值,但是对于activation是不太一样的, 对于activation采用了EMA(滑动平均)来对输入中的最大最小值计算得到的,但是在训练初期,因为输入的值变化较大,会影响到滑动平均的值,因此在初期不对activation做量化,而是在网络稳定之后再引入。

4.2 折叠BN

对于bn层,在训练时是一个单独的层存在,但是在前向推理时为了提升效率是融合到卷积或全连接层的权重和偏置中的,如下图:

所以,为了模拟推断过程,训练时需要把BN层考虑到权重中,公式如下:

考虑了fold bn之后,最终可以用下图来表示训练过程中的量化:

在这里插入图片描述

后记

今天解读了CVPR 2018 《Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference》,对int8量化了有了基本认识,这两天随缘更新一个实战篇吧。

附录

论文原文:https://arxiv.org/pdf/1712.05877.pdf

参考博客1:https://blog.csdn.net/qq_19784349/article/details/82883271

参考博客2:https://blog.csdn.net/holmosaint/article/details/82423610

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GiantPandaCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深度学习算法优化系列九 | NIPS 2015 BinaryConnect
当前CNN网络主要的运算集中在实数权值乘以实数激活值或者实数权值乘以实数梯度。论文提出BinaryConnect将用于前向传播和后向传播计算的实数权值二值化为, 从而将这些乘法运算变为加减运算。这样即压缩了网络模型大小,又加快了速度。论文提到,SGD通过平均权重带来的梯度来得到一些小的带噪声的步长,尝试更新权重去搜索参数空间,因此这些梯度非常重要,要有足够的分辨率,sgd至少需要6—8bits的精度。如果对权重进行量化,就会导致无法对权重直接求导,所以我们可以把二值化权重看成是带噪声的权重。论文认为,带噪声的权重往往能够带来正则化,使得泛化能力更好,类似Dropout,DropCconnect这种就是对激活值或者权重加入了噪声,它们表明只要权重的期望值是高精度的,添加噪声往往是有益处的,所以对权重进行量化理论角度是可行的。
BBuf
2020/02/21
8810
深度学习算法优化系列九 | NIPS 2015 BinaryConnect
LLM 大模型学习必知必会系列(六):量化技术解析、QLoRA技术、量化库介绍使用(AutoGPTQ、AutoAWQ)
模型的推理过程是一个复杂函数的计算过程,这个计算一般以矩阵乘法为主,也就是涉及到了并行计算。一般来说,单核CPU可以进行的计算种类更多,速度更快,但一般都是单条计算;而显卡能进行的都是基础的并行计算,做矩阵乘法再好不过。如果把所有的矩阵都加载到显卡上,就会导致显卡显存的占用大量增加,尤其是LLM模型大小从7b、14b、34b到几百b不等,占用显存的大小就是惊人的数字,如何在减少运算量和显存占用的条件下,做到推理效果不下降太多呢?在这里需要引入浮点数和定点数的概念。
汀丶人工智能
2024/05/26
2.3K0
LLM 大模型学习必知必会系列(六):量化技术解析、QLoRA技术、量化库介绍使用(AutoGPTQ、AutoAWQ)
【AI系统】TVM 实践案例
在本文我们探讨一下,如何利用 AI 编译器在新的硬件上部署一个神经网络,从算法设计到实际运行,有哪些需要考虑的地方?本文将以 TVM 为例,首先介绍一下 TVM 的工作流:
用户11307734
2024/12/02
3510
深度学习Int8的部署推理原理和经验验证
论文出处:《Integer Quantization for Deep Learning Inference Principles and Empirical Evaluation》 时间:2020.April 单位:NVIDIA
BBuf
2022/05/27
2.1K0
深度学习Int8的部署推理原理和经验验证
深度学习算法优化系列十二 | 旷视科技 DoReFa-Net
我们知道,XORNet以及BNN都没有在反向传播阶段做梯度的量化,之前也没有任何工作可以在反向传播阶段将梯度量化到8位一下并且保持相当的预测精度。在BNN和XORNet中,虽然权重是二值化的,但是梯度仍然是全精度浮点数,因此在反向传播时反卷积依然是1bit和32bit数之间的运算,这导致BNN和XORNet的训练时间主要花在反向传播阶段。
BBuf
2020/02/25
2.7K4
F8Net:只有8比特乘法的神经网络量化
【GaintPandaCV导语】F8Net用定点化量化方法对DNN进行量化,在模型推理只有8-bit的乘法,没有16-bit/32-bit的乘法,采用非学习的方法即标准差来定小数位宽。目前是我看到的第一篇硬件层面全8-bit乘法的模型推理的方法。
BBuf
2022/04/06
1.6K0
F8Net:只有8比特乘法的神经网络量化
深度学习算法优化系列十 | 二值神经网络(Binary Neural Network,BNN)
昨天介绍的BinaryConnect提出将浮点权重量化到1bit,提出了完整的量化权重训练/测试流程,并且从带噪声权重的角度来解释了量化权重。但这种方法还有一个缺点,即并没有对激活函数进行量化,所以Bengio大神在2016年发表了这篇Binary Neural Network,论文原文和代码链接见附录。
BBuf
2020/02/21
2.8K0
深度学习算法优化系列十 | 二值神经网络(Binary Neural Network,BNN)
一起实践神经网络量化系列教程(一)!
老潘刚开始接触神经网络量化是2年前那会,用NCNN和TVM在树莓派上部署一个简单的SSD网络。那个时候使用的量化脚本是参考于TensorRT和NCNN的PTQ量化(训练后量化)模式,使用交叉熵的方式对模型进行量化,最终在树莓派3B+上部署一个简单的分类模型(识别剪刀石头布静态手势)。
老潘
2023/10/19
1.4K0
一起实践神经网络量化系列教程(一)!
解决LLaMA、BERT等部署难题:首个4-bit浮点量化LLM来了
大语言模型 (LLM) 压缩一直备受关注,后训练量化(Post-training Quantization) 是其中一种常用算法,但是现有 PTQ 方法大多数都是 integer 量化,且当比特数低于 8 时,量化后模型的准确率会下降非常多。想较于 Integer (INT) 量化,Floating Point (FP) 量化能更好的表示长尾分布,因而越来越多的硬件平台开始支持 FP 量化。而这篇文章给出了大模型 FP 量化的解决方案。文章发表在 EMNLP 2023 上。
机器之心
2023/11/18
3650
解决LLaMA、BERT等部署难题:首个4-bit浮点量化LLM来了
在消费级GPU调试LLM的三种方法:梯度检查点,LoRA和量化
LLM的问题就是权重参数太大,无法在我们本地消费级GPU上进行调试,所以我们将介绍3种在训练过程中减少内存消耗,节省大量时间的方法:梯度检查点,LoRA和量化。
deephub
2023/08/30
1.3K0
在消费级GPU调试LLM的三种方法:梯度检查点,LoRA和量化
INT8量化训练
【GiantPandaCV导读】本文聊了两篇做INT8量化训练的文章,量化训练说的与quantization-aware Training有区别,量化训练指的是在模型训练的前向传播和后向传播都有INT8量化。两篇文章都是基于对梯度构建分析方程求解得到解决量化训练会引起的训练崩溃和精度损失严重的情况。
BBuf
2021/04/30
1.2K0
轻松学Pytorch之量化支持
模型的边缘端部署需要深度学习模型更加的小型化与轻量化、同时要求速度要足够快!一个量化之后的模型可以使用整数运算执行从而很大程度上降低浮点数计算开销。Pytorch框架支持8位量化,相比32位的浮点数模型,模型大小对内存需要可以降低四倍左右,硬件支持8位量化之后的模型推理可以加速2到4倍左右。模型量化是模型部署与加速推理预测首选技术方案。
OpenCV学堂
2021/12/17
1.8K0
轻松学Pytorch之量化支持
模型量化-学习笔记
随着深度学习的不断发展,神经网络广泛应用于不同的领域,取得远超以往的效果的同时深度网络模型的复杂度也越来越高, 这严重制约了它在工业界发展.
Johns
2022/06/22
4.3K0
INT4量化用于目标检测
【GiantPandaCV】文章2019 CVPR,讲的是Int 4量化用于目标检测,主要是工程化的一些trick。
BBuf
2021/03/24
1.1K0
INT4量化用于目标检测
8比特数值也能训练模型?商汤提训练加速新算法丨CVPR 2020
在CVPR 2020上,商汤研究院链接与编译团队、高性能计算团队和北航刘祥龙老师团队合作提出了用于加速卷积神经网络训练过程的INT8训练技术。该工作通过将网络的输入、权重和梯度量化到8比特来加速网络的前向传播和反向传播过程,缩短卷积神经网络训练时间。
AI科技大本营
2020/04/14
1.5K0
【AI系统】低比特量化原理
计算机里面数值有很多种表示方式,如浮点表示的 FP32、FP16,整数表示的 INT32、INT16、INT8,量化一般是将 FP32、FP16 降低为 INT8 甚至 INT4 等低比特表示。
用户11307734
2024/12/05
2480
TensorFlow下构建高性能神经网络模型的最佳实践
作者 | 李嘉璇 责编 | 何永灿 随着神经网络算法在图像、语音等领域都大幅度超越传统算法,但在应用到实际项目中却面临两个问题:计算量巨大及模型体积过大,不利于移动端和嵌入式的场景;模型内存占用过大,导致功耗和电量消耗过高。因此,如何对神经网络模型进行优化,在尽可能不损失精度的情况下,减小模型的体积,并且计算量也降低,就是我们将深度学习在更广泛的场景下应用时要解决的问题。 加速神经网络模型计算的方向 在移动端或者嵌入式设备上应用深度学习,有两种方式:一是将模型运行在云端服务器上,向服务器发送请求,接收服务器
用户1737318
2018/07/20
1.2K0
低比特量化之DoreFa-Net理论与实践
这篇文章首先详细介绍了DoreFaNet任意比特量化网络的原理,然后提供了DoreFaNet的Pytorch代码实现解析,并给出将DoreFa-Net应用到YOLOV3模型上之后的精度测试结果。论文原文:https://arxiv.org/pdf/1606.06160.pdf 。
BBuf
2020/07/28
1.4K0
低比特量化之DoreFa-Net理论与实践
如何使用PyTorch的量化功能?
在深度学习中,量化指的是使用更少的 bit 来存储原本以浮点数存储的 tensor,以及使用更少的 bit 来完成原本以浮点数完成的计算。这么做的好处主要有如下几点:
AI算法与图像处理
2021/02/05
6.3K0
如何使用PyTorch的量化功能?
【白话模型量化系列一】矩阵乘法量化
模型量化是模型加速方向一个很重要的方法,主要思想就是用int8数据格式来存储和进行计算。这样做有两点好处:
godweiyang
2021/12/02
1.1K0
推荐阅读
相关推荐
深度学习算法优化系列九 | NIPS 2015 BinaryConnect
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档