转自AI Studio,原文链接:模型量化(1):模型量化简介 - 飞桨AI Studio

引入

  • 在 AI 模型训练时,通常使用浮点数(Float32 等)进行计算,这样能够确保更好的精度表现

  • 当然浮点数运算也是一把双刃剑,在提升了计算精度的同时带来了更多的计算量和储存空间占用

  • 具体的表现就是模型的计算速度较慢、模型的文件体积较大

  • 在模型推理的时候,大多数时候并不需要如此高的计算精度,或者说低精度的运算不会对模型精度产生太大的影响

  • 这个时候就可以将模型映射到较低精度的运算上,降低计算量,提升运行速度,减少模型文件的体积,方便传输

  • 这样的将模型从高精度运算(一般是浮点运算)转换到低精度运算(一般是整数运算)的过程叫做模型量化

2. 量化原理

  • 模型量化桥接了定点与浮点,建立了一种有效的数据映射关系,使得以较小的精度损失代价获得了较好的收益

  • 要弄懂模型量化的原理就是要弄懂这种数据映射关系,浮点与定点数据的转换公式如下:

    Q=RS+ZQ=\frac{R}{S}+ZQ=SR​+Z

    R=(Q−Z)∗SR=(Q-Z) * SR=(Q−Z)∗S

    • R 表示输入的浮点数据
    • Q 表示量化之后的定点数据
    • Z 表示零点(Zero Point)的数值
    • S 表示缩放因子(Scale)的数值
  • 我们可以根据 S 和 Z 这两个参数来确定这个映射关系

  • 求解 S 和 Z 有很多种方法,这里列举中其中的一种求解方式(MinMax)如下:

    S=Rmax⁡−Rmin⁡Qmax⁡−Qmin⁡S=\frac{R_{\max }-R_{\min }}{Q_{\max }-Q_{\min }}S=Qmax​−Qmin​Rmax​−Rmin​​

    Z=Qmax⁡−Rmax⁡÷SZ=Q_{\max }-R_{\max } \div SZ=Qmax​−Rmax​÷S

    • Rmax⁡R_{\max }Rmax​ 表示输入浮点数据中的最大值
    • Rmin⁡R_{\min }Rmin​ 表示输入浮点数据中的最小值
    • Qmax⁡Q_{\max }Qmax​ 表示最大的定点值(127 / 255)
    • Qmin⁡Q_{\min }Qmin​ 表示最小的定点值(-128 / 0)
  • 当然这不是模型量化的全部,这里只是简单的介绍一下线性量化的基本原理和思想

3. 量化类型

  • 线性量化可分为对称量化和非对称量化

3.1 对称量化

  • 对称量化即使用一个映射公式将输入数据映射到 [-128,127] 的范围内

  • 映射公式需要保证原始的输入数据中的零点通过映射公式后仍然对应 [-128,127] 区间的零点

3.2 非对称量化

  • 即使用一个映射公式将输入数据映射到[0,255]的范围内

4. 量化实例

  • 上面介绍了量化的基本原理和思想

  • 下面通过代码来实现一个简单的量化过程

4.1 数据量化

  • 使用上面介绍的那种方法,对随机生成的浮点数据进行量化,转换为定点数据

In [1]

import sys
import time
import numpy as np# 随机生成一些浮点数据(Float32)
data_float32 = np.random.randn(10).astype('float32')# 量化上下限(UInt8)
Qmin = 0
Qmax = 255# 计算缩放因子(Scale)
S = (data_float32.max() - data_float32.min()) / (Qmax - Qmin)# 计算零点(Zero Point)
Z = Qmax - data_float32.max() / S# 将浮点数据(Float32)量化为定点数据(UInt8)
data_uint8 = np.round(data_float32 / S + Z).astype('uint8')# 将定点数据(UInt8)反量化为浮点数据(Float32)
data_float32_ = ((data_uint8 - Z) * S).astype('float32')

4.2 数据对比

  • 将原始输出,量化后的数据,反量化后的数据进行对比
  • 可以看出,通过量化、反量化之后数据会略有变化,但是差异较小,在可接受范围内

In [2]

# 使用均方误差计算差异
mse = ((data_float32-data_float32_)**2).mean()print("原始数据:", data_float32)
print("反量化后数据:", data_float32_)
print("量化后数据:", data_uint8)
print("原始数据和反量化后数据的均方误差:", mse)
原始数据: [-0.47069794  0.8608386  -0.947035   -1.0697421   0.10035864  0.00134370.6782814   0.7141242  -0.09668107  0.4391506 ]
反量化后数据: [-0.4716406   0.8608386  -0.94860756 -1.069742    0.10374816 -0.002244510.6791369   0.7169914  -0.09309536  0.43686795]
量化后数据: [ 79 255  16   0 155 141 231 236 129 199]
原始数据和反量化后数据的均方误差: 5.4746083e-06

4.3 内存对比

  • 对比量化前后的数据内存占用情况

  • 可以看到从数据从 Float32 转换为 UInt8 格式,内存占用可以缩小至原来的 1/4

In [3]

# 空数组的内存占用
empty_size = sys.getsizeof(np.array([]))# 计算实际数据的内存占用
float32_size = (sys.getsizeof(data_float32) - empty_size)
uint8_size = (sys.getsizeof(data_uint8) - empty_size)print("原始数据内存占用:%d Bytes" % float32_size)
print("量化后数据内存占用:%d Bytes" % uint8_size)
print("量化后数据与原始数据内存占用之比:", uint8_size / float32_size)
原始数据内存占用:40 Bytes
量化后数据内存占用:10 Bytes
量化后数据与原始数据内存占用之比: 0.25

4.4 速度对比

  • 通过数据自身求和 n 次来测试运算速度

  • 可以看到在这样的运算中,UInt8 相比 Float32 可以有两倍左右的加速比

In [5]

# 预热次数
warmup = 100# 重复次数
repeat = 10000# 预热
sum = data_float32
for i in range(warmup):sum += data_float32sum = data_uint8
for i in range(warmup):sum += data_uint8# 速度测试
start = time.time()
sum = data_float32
for i in range(repeat):sum += data_float32
float32_time = time.time() - startstart = time.time()
sum = data_uint8
for i in range(repeat):sum += data_uint8
uint8_time = time.time() - startprint("原始数据求和 %d 次耗时 :%f s" % (repeat, float32_time))
print("量化后数据求和 %d 次耗时:%f s" % (repeat, uint8_time))
print("量化后数据与原始数据计算耗时之比:", uint8_time / float32_time)
原始数据求和 10000 次耗时 :0.017538 s
量化后数据求和 10000 次耗时:0.008749 s
量化后数据与原始数据计算耗时之比: 0.49884448069603043

5. 量化特点

  • 从上面的实例中可以看出量化操作的几个优点:

    • 计算快,效率高,计算时的耗能降低
    • 内存占用小,方便数据文件的储存和传输
  • 当然缺点也是有的,也很显而易见,就是计算精度会有一定程度的下降

6. 量化分类

  • 根据执行模型量化的时机,可将常用的模型量化方法分为如下两类:

    • 训练时量化:

      • 感知量化训练:量化训练让模型感知量化运算对模型精度带来的影响,使用大量有标签的数据,通过 finetune 训练降低量化误差。
    • 训练后量化:

      • 静态量化:使用少量无标签校准数据,采用KL散度等方法计算量化比例因子。
      • 动态量化:无需额外数据,仅将模型中特定算子的权重从浮点类型映射成整数类型。
  • 各种量化方法之间的关系图如下:

  • 各种量化方法之间的对比图如下:

7. 量化实践

  • 模型量化已经是相对成熟的技术了,有很多好用的工具可以快速地对 AI 模型进行量化操作

  • 比如 Paddle 官方开发的 PaddleSlim 就包含模型量化的功能

  • 对于 ONNX 模型而言,也可以使用 ONNXRuntime 内置的量化工具对模型进行量化

  • 光说不练假把式,本文为系列文章,接下来的几篇将介绍模型量化的实践操作

  • 感兴趣的可点击下方链接,跳转至对应文章:

    • 模型量化(2):Paddle 模型的静态量化和动态量化

    • 模型量化(3):ONNX 模型的静态量化和动态量化

模型量化(1):模型量化简介相关推荐

  1. 【视频课】模型优化拆分!分别学习模型剪枝与模型量化理论与实践

    前言 好的模型结构是深度学习成功的关键因素之一,不仅是非常重要的学术研究方向,在工业界实践中也是模型是否能上线的关键.对各类底层深度学习模型设计和优化技术理解的深度是决定我们能否在深度学习项目中游刃有 ...

  2. 多因子选股模型python_什么是多因子量化选股模型?

    引言 量化投资中经常听到的"多因子模型"是个什么鬼?因子是影响因素的简称,或简单理解成指标.我们都知道股票收益受到多重因素的影响,比如宏观.行业.流动性.公司基本面.交易情绪等等. ...

  3. 基于YOLOv5模型压缩、模型量化、模型剪枝

    基于YOLOv5模型压缩.模型量化.模型剪枝 代码下载地址:下载地址 Requirements pip install -r requirements.txt Pruning for YOLOs Mo ...

  4. 模型压缩:模型量化打怪升级之路-工具篇

    本文转载自商汤泰坦公开课. 1/ 最近发现一些还在学校读书的同学非常关注一个量化工作精度的高低,读过我上篇分享(模型压缩:模型量化打怪升级之路 - 0 序章)的同学应该知道,部分学术界的工作与工业界的 ...

  5. 什么是多因子量化选股模型?

    量化投资中经常听到的"多因子模型"是个什么鬼?因子是影响因素的简称,或简单理解成指标.我们都知道股票收益受到多重因素的影响,比如宏观.行业.流动性.公司基本面.交易情绪等等.所谓& ...

  6. 基于支持向量机的量化选股模型

    要求开发一个基于支持向量机技术的多因子量化投资模型,以近五年沪深300成分股的交易与财务数据为样本,结合大数据相关技术进行数据清洗,整理,存储,并构建投资策略与回测框架,输出量化投资模型的结果,为投资 ...

  7. 2021极术通讯-CSL-YOLO | 超越Tiny-YOLO V4,全新设计轻量化YOLO模型实现边缘实时检测

    首发极术社区 如对Arm相关技术感兴趣,欢迎私信aijishu20加入技术微信群. 导读:极术社区与E-learning平台联合推出极术通讯,引入行业媒体和技术社区.咨询机构优质内容,定期分享产业技术 ...

  8. 模型加速之轻量化网络

    模型加速之轻量化网络 当前物体检测结构大都依赖使用卷积网络进行特征提取,即 Backbone,通常使用 VGGNet.ResNet 等优秀的基础网络,但是这些网络往往计算量巨大,依赖这些基础网络的检测 ...

  9. bim webgl 模型 轻量化_WebGL轻量化BIM引擎如何加载大体量BIM模型

    当前,国内的BIM应用如火如荼!在前几年住建部.交通部.铁总及各个省市住建厅推出各类鼓励BIM应用的政策后,湖南省强制推进的BIM审图更是为BIM应用添加了一把火! 不论BIM当前在国内推进的过程中是 ...

  10. C++:实现量化ODE模型测试实例

    C++:实现量化ODE模型测试实例 #include "ode.hpp" #include "utilities.hpp" #include <ql/ex ...

最新文章

  1. [转]ASP.NET中常用输出JS脚本的类
  2. java {@link},Javadoc @see或{@link}?
  3. 【完整代码】使用Semaphore实现线程的交替执行打印 A1B2C3D4E5
  4. shell中$*和$@ 两个都区别
  5. 谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?
  6. android navigation bar高度,Android获取屏幕真实高度包含NavigationBar(底部虚拟按键)
  7. android WebView总 结
  8. 通过深度优先搜索(DFS)对图的边进行分类
  9. mvc表单Form提交 --实体
  10. springboot实现任务调度的第三种方式------使用第三方quartz插件调度(springBoot+quartz+cronTrigger进行任务调度)
  11. Oracle排序查询语句
  12. 不知道CAD坐标系,如何做到CAD与卫星影像无偏叠加?
  13. android 照片同步到iphone,简明教程教你同步安卓设备照片到iCloud照片流
  14. 别拿学历说事,这些天王中学没毕业,最低的是成龙
  15. getBytes()方法详解
  16. 肖秀荣真的是“yyds”吗?会被反押题吗?今年还会押中原题吗
  17. python获取上一级目录
  18. element搜索框实现数据搜索
  19. 两个优惠券CSS样式
  20. 无领导小组讨论面试真题解析(三)

热门文章

  1. Bowtie2的安装与使用
  2. 算法小白理解最大流最小割(Maximum flow Minimum cut)问题
  3. 安装cnpm淘宝镜像过程报错
  4. swfobject 的一些参数介绍
  5. python+selenium环境安装及配置以及示例
  6. 12个优雅的 python 代码使用案例
  7. 推荐一款绝对不能错过的 ORM 框架 dbVisitor,目前版本 4.3.0
  8. 游戏装备mysql表设计_Game游戏数据库人物表,装备表,技能表
  9. T100——q查询,子母查询(汇总——明细)练习笔记
  10. 市净率|介绍|解释|计算方法