记录深度学习量化操作

news/2024/9/17 18:58:01/ 标签: 深度学习, 人工智能

0. 简介

深度学习中做量化提升运行速度是最常用的方法,尤其是大模型这类非常吃GPU显存的方法。一般是高精度浮点数表示的网络权值以及激活值用低精度(例如8比特定点)来近似表示达到模型轻量化,加速深度学习模型推理,目前8比特推理已经比较成熟。比如int8量化,就是让原来32bit存储的数字映射到8bit存储。int8范围是[-128,127], uint8范围是[0,255]。

使用低精度的模型推理的优点:1. 模型存储主要是每个层的权值,量化后模型占用空间小,32比特可以缩减至8比特,并且激活值用8比特后,减小了内存的访问带宽需求。2:单位时间内处理定点运算指令比浮点数运算指令多。


1. 量化分类

一般按照量化阶段不同分为后量化和训练时量化,用的比较多的是后量化,像tensorRT和RKNN按照量化映射方法又可以分为对称量化和非对称量化。

1.1 非对称量化(uint8 0-256)

非对称量化需要一个偏移量Z来完成零点的映射,即量化前的零点和量化后的零点不一致。非对称量化的一般公式为:

S = r m a x − r m i n q m a x − q m i n S = \frac{r_{max} - r_{min}}{q_{max} - q_{min}} S=qmaxqminrmaxrmin

Z = q m a x − R o u n d ( r m a x S ) Z = q_{max} - Round(\frac{r_{max}}{S}) Z=qmaxRound(Srmax)

r m a x r_{max} rmax r m i n r_{min} rmin表示真实数据的最大值和最小值, q m a x q_{max} qmax q m i n q_{min} qmin表示量化后的最大值和最小值,例如uint8就是0和256。 Round()表示取整,如果是量化为int型。

1.1.1 量化

q = R o u n d ( r S + Z ) q = Round(\frac{r}{S} + Z) q=Round(Sr+Z)

1.1.2 反量化

r = ( q − Z ) ∗ S r = (q - Z)*S r=(qZ)S

1.2 对称量化(int8 -128-127)

对称算法是通过一个收缩因子,将FP32中的最大绝对值映射到8比特的最大值,最大绝对值的负值(注意此值不是fp32的最小值,是最大绝对值的相反数,故对称)映射到8比特的最小值。对称量化在量化前和量化后的零点保持一致,即零点对应,因此无需像非对称量化那样引入一个偏移量Z。 对称量化的一般公式为:

S = ∣ r m a x ∣ ∣ q m a x ∣ S = \frac{|r_{max}|}{|q_{max}|} S=qmaxrmax

1.2.1量化

q = R o u n d ( r S ) q = Round(\frac{r}{S}) q=Round(Sr)
Round()表示取整,如果是量化为int型。

1.2.2 反量化

r = q ∗ S r = q*S r=qS



2. 量化的优缺点

2.1 量化的优点

  1. 减小模型尺寸,如8位整型量化可减少75%的模型大小
  2. 减少存储空间,在边缘侧存储空间不足时更具有意义
  3. 易于在线升级,模型更小意味着更加容易传输
  4. 减少内存耗用,更小的模型大小意味着不需要更多的内存
  5. 加快推理速度,访问一次32位浮点型可以访问四次int8整型,整型运算比浮点型运算更快
  6. 减少设备功耗,内存耗用少了推理速度快了自然减少了设备功耗
  7. 支持微处理器,有些微处理器属于8位的,低功耗运行浮点运算速度慢,需要进行8bit量化

2.2 量化的缺点

  1. 模型量化增加了操作复杂度,在量化时需要做一些特殊的处理,否则精度损失更严重
  2. 模型量化会损失一定的精度,虽然在微调后可以减少精度损失,但推理精度确实下降

3. 对称和非对称使用

对称量化无需引入偏移量Z,因此计算量低,缺点是量化后的数据是非饱和的,即有一部分区域不存在量化的数据。

非对称量化因为额外引入了一个偏移量来修正零点,因此需要的计算量会大一点。优点是其量化后的数据是饱和的,即量化前的最小值对应量化范围的最小值,量化后的最大值对应量化范围的最大值。
在这里插入图片描述

对于fp32的值若均匀分布在0左右,映射后的值也会均匀分布,若fp32的值分布不均匀,映射后不能充分利用。所以非对称可以处理好FP32数据分布不均匀的情况

…详情请参照古月居

若对称算法产生的量化后数据很多都是在【0,127】内,左边的范围利用很少,减弱了量化数据的表示能力,影响模型精度。

此外还有很多其他的魔改版本,比如激活值饱和量化,通过选择合适的阈值T来将一些范围利用少的情况去除,然后再做对称量化。从而也实现对应的饱和量化的操作。下图为魔改版本激活值饱和量化(右图),选择合适的阈值T。以及原始版本权值非饱和量化(左图)

4. 参考链接

https://www.cnblogs.com/ywheunji/p/13348190.html

https://errolyan.medium.com/1-%E6%A8%A1%E5%9E%8B%E4%B8%BA%E5%95%A5%E9%9C%80%E8%A6%81%E9%87%8F%E5%8C%96-1b6c49dbe621

http://www.yindaheng98.top/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/quant.html#%E5%AF%B9%E7%A7%B0%E9%87%8F%E5%8C%96-uniform-affine-quantizer

https://blog.csdn.net/weixin_43863869/article/details/133893699


http://www.ppmy.cn/news/1523316.html

相关文章

MySQL表的操作与数据类型

目录 前言 一、表的操作 1.创建一个表 2.查看表的结构 3.修改表 4.删除一个表 二、 MySQL的数据类型 0.数据类型一览: 1.整数类型 2.位类型 3.小数类型 4.字符类型 前言 在MySQL库的操作一文中介绍了有关MySQL库的操作,本节要讲解的是由库管理的结构——…

TinyWebSever源码逐行注释(三)_ thread_pool.cpp

前言 项目源码地址 项目详细介绍 项目简介: Linux下C轻量级Web服务器,助力初学者快速实践网络编程,搭建属于自己的服务器. 使用 线程池 非阻塞socket epoll(ET和LT均实现) 事件处理(Reactor和模拟Proactor均实现) 的并发模型使用状态机…

python基础语法四-数据可视化

书接上回: python基础语法一-基本数据类型 python基础语法二-多维数据类型 python基础语法三-类 1. plot函数绘制简单折线图 (1)需要的模块:matplotlib.pyplot (2)语法:matplotlib.pyplot.plot(x, y, format_string, **kwargs) x: x轴数…

C语言程序设计-练习篇

不知道结果仍义无反顾地才是勇士。 三&#xff0c;打印整数二进制的奇数位和偶数位 题目内容&#xff1a; 获取一个整数二进制序列中所有的奇数位和偶数位&#xff0c;分别打印出二进制序列 #include <stdio.h>//打印整数二进制的奇数位和偶数位 int main() {int i 0…

C语言从头学55——学习头文件errno.h、float.h

1、头文件 errno.h 中的变量 errno 的使用 在 errno.h 定义了一个 int 类型的变量 errno&#xff08;错误码&#xff09;&#xff0c;如果发现这个变量出现非零值&#xff0c;表示已经执行的函数发生了错误。这个变量一般多用于检查数学函数运算过程中发生的错误。 …

Vue面试题——项目介绍以及SPA介绍

谈谈你开发的项目背景与、架构和技术栈 项目背景 假设我们正在开发一个名为“智慧旅游助手”的Web平台。该平台旨在为用户提供一站式的旅游服务&#xff0c;包括目的地推荐、酒店预订、行程规划、在线购票&#xff08;如门票、机票&#xff09;、旅游攻略分享以及基于地理位置…

不到200行代码,一键写出简单贪吃蛇网页游戏!附详细代码!快来看看吧!

​哈喽大家好&#xff0c;这里是大白百宝阁&#xff0c;每天分享一段小代码~ 今天要分享的是&#xff0c;不到200行代码&#xff0c;制作html版贪吃蛇&#xff0c;效果如下&#xff1a; 游戏结束后&#xff0c;还会显示&#xff1a; 代码如下&#xff1a; <!DOCTYPE html&g…

传统CV算法——边缘算子与图像金字塔算法介绍

边缘算子 图像梯度算子 - Sobel Sobel算子是一种用于边缘检测的图像梯度算子&#xff0c;它通过计算图像亮度的空间梯度来突出显示图像中的边缘。Sobel算子主要识别图像中亮度变化快的区域&#xff0c;这些区域通常对应于边缘。它是通过对图像进行水平和垂直方向的差分运算来…

基于Java+SpringBoot+Vue+MySQL的美容美发管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于SpringBootVue的美容美发管理系统【附源码文档】、前后…

【Visual Studio 报错】vs 在使用二进制写入文件时弹窗报错:使用简体中文 gb2312 编码加载文件

如以下报错 解决办法 解决方法&#xff1a;文件->高级保存选项->将文件编码形式改为“UTF-8带签名” 若找不到高级保存选项&#xff0c;可以跟着下面路径把该选项调出来 &#xff1a;工具->自定义->命令->菜单栏中改成文件->预览右边点添加命令->类别中…

第二证券:涨停潮!传手机将使用钛金属外壳?

今天早盘&#xff0c;银行股再度重挫&#xff0c;导致上证指数、上证50纷乱创出阶段性新低&#xff0c;上证指数跌破2800点&#xff0c;小盘成长股则大面积反弹&#xff0c;创业板指、科创50等股指飘红。 盘面上&#xff0c;新式烟草、钛金属、锂矿、玻璃基板等板块涨幅居前&a…

全球性“微软蓝屏”事件的深思:网络安全与系统稳定性的挑战与应对

近日&#xff0c;由于微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;成为科技领域的热点新闻。这次事件不仅影响了全球约850万台设备&#xff0c;波及航空、医疗、传媒等关键行业&#xff0c;还导致美国超过2.3万架次航班延误。如此规模的系统中断&#xff0c;…

【Shiro】Shiro 的学习教程(三)之 SpringBoot 集成 Shiro

目录 1、环境准备2、引入 Shiro3、实现认证、退出3.1、使用死数据实现3.2、引入数据库&#xff0c;添加注册功能后端代码前端代码 3.3、MD5、Salt 的认证流程 4.、实现授权4.1、基于角色授权4.2、基于资源授权 5、引入缓存5.1、EhCache 实现缓存5.2、集成 Redis 实现 Shiro 缓存…

qt怎么格式化字符串?

在Qt中&#xff0c;格式化字符串可以通过多种方式实现&#xff0c;主要依赖于你的具体需求和上下文。下面列出了一些常见的方法&#xff1a; 1. 使用QString的arg()方法 QString类提供了arg()方法&#xff0c;这个方法允许你插入值到字符串中的占位符位置。占位符由%1、%2等表…

详细步骤!分享6款AI论文写作助手自动生成器实例操作!

在当今学术研究和写作领域&#xff0c;AI论文生成工具的出现极大地提高了写作效率和质量。这些工具不仅能够帮助研究人员快速生成论文草稿&#xff0c;还能进行内容优化、查重和排版等操作。以下是6款推荐的AI论文写作助手自动生成器实例操作&#xff0c;特别推荐千笔-AIPassPa…

pytorch张量运算的广播机制

PyTorch 的广播机制&#xff08;broadcasting&#xff09;是指在进行张量运算时&#xff0c;自动扩展较小张量的形状以匹配较大张量的形状&#xff0c;使它们能够进行逐元素运算。广播机制避免了手动扩展张量的繁琐过程&#xff0c;并且在不增加内存开销的情况下进行高效计算。…

黑马点评16——多级缓存-JVM进程缓存

文章目录 什么是多级缓存导入商品案例初识Caffeine实现进程缓存 什么是多级缓存 但是现在的nginx的压力太大了&#xff0c;所以nginx也要部署成集群 当然我们的redis、tomcat都可以部署成集群 导入商品案例 我们在docker中开启了一个mysql的数据库&#xff0c;里面配置了一个…

如何从 Bak 文件中恢复 SQL数据库?(3种方法)

如何从 .bak 文件恢复 SQL数据库&#xff1f; 在数据库管理和维护过程中&#xff0c;数据的安全性和完整性至关重要。备份文件&#xff08;.bak 文件&#xff09;是 SQL Server 中常用的数据库备份格式&#xff0c;它包含了数据库的完整副本&#xff0c;用于在数据丢失、系统故…

为什么有的单位将SCI-E看作EI核心?

将SCI-E&#xff08;Science Citation Index Expanded&#xff0c;即SCI扩展版&#xff09;看作EI&#xff08;Engineering Index&#xff0c;工程索引&#xff09;核心期刊的现象&#xff0c;主要源于不同单位对学术成果评价标准和体系的差异&#xff0c;以及对国际学术数据库…

QWidget(c++)嵌入window环境的exe

QWidget(c)嵌入window环境的exe 我用的msvc2017 64bit编译器会报这个错误 visual.obj:-1: error: LNK2019: __imp_FindWindowW "public: __cdecl Visual::Visual(class QWidget *)" (??0VisualQEAAPEAVQWidgetZ)然后改成minGw 64bit 就不会报错 #ifndef VISUAL_…