【量化】量化原理浅析

news2025/1/12 19:02:36

前言

模型在端侧运行时,会追求模型保持原有精度的同时,让模型的运行速度更快。基本方向为模型压缩和加速,着力于减少网络参数量、降低计算复杂度。可通过以下方式实现:

  • 针对网络结构本身进行改进,常用的3x3的卷积的叠加代替大卷积;average-pooling 代替 full-connection layers; MobileNets中使用的 depth-wise convolution 代替传统的卷积方式;等。
  • 剪枝:除去神经网络结构中不重要的部分
    量化:调整网络结构中的权重和激活值的表达精度
    蒸馏:把复杂网络结构的只是转移到较小网络结构上
  • 推理框架上的优化:成熟的轻量化框(TensorRT、TF-lite、NCNN、MNN)。这些框架能够实现编译优化、缓存优化、算子优化、稀疏存储与计算、加速指令集应用等,能够显著的提升模型推理速度
  • 硬件层级:硬件厂商通常会为特定深度学习任务或者框架做针对性设计优化,使得模型在匹配的硬件平台上获得最大的加速效果。目前主流的硬件平台有GPU、FPGA、ASIC等。
    GPU通用性好,计算能力强,但功耗较大,主要 用在云端训练和推理;
    ASIC这种定制程度较高的芯片通用性较低,但在专属任务上性能较高,主要用于前端计算设备上。TPU和NPU属于ASIC的范畴。

本篇博客主要记录量化的原理

1 量化简介

在信号处理领域中,量化是指将连续的信号近似为有限多个离散值的过程。
在深度学习领域中,模型量化是指:将高比特的权重和特征值用更低比特来表示 的方法。当量化后的数值是2的幂次时(如1/2/4/8 bit等),量化也可以成为定点化。量化后的值成为定点值。
在深度模型训练和推理过程中,最常使用的是32bit浮点型精度。但高比特意味着模型的体积更大,推理速度更慢,硬件资源消耗更多。这对于部署在计算和存储资源有限的边缘设备上是很不友好的。通过使用更低比特的精度,在尽量保持元模型效果的同时,获得尺寸更小、推理速度更快、硬件资源占用更少的模型是目前研究的重点方向。

2 量化基本原理

模型量化方法本质上是函数映射。建立了高精度的浮点数据 和量化后低精度的定点数据 之间的数据映射。
根据映射函数是否为线性,将其分为线性量化和非线性量化。

  • 线性量化:8bit量化(又分为对称量化、非对称量化)
  • 非线性量化:二值量化 (1 bit量化)、聚类量化、对数量化

其中最常用的是8bit量化,已在工业界中成熟使用。


2.1 线性量化

浮点模型参数与定点模型参数之间如何转换呢?

  • 浮点转定点(量化)公式为: Q = r o u n d ( R S + Z ) Q=round (\frac{R}{S}+Z) Q=round(SR+Z)定点转浮点(反量化)公式为: R = ( Q − Z ) ∗ S R=(Q-Z)*S R=(QZ)S【R】原始的浮点数据
    【Q】量化后的定点数据
    【Z】偏移量(或零点/最小值对应的量化数值),又被称为 Zero Point
    【S】缩放系数,又被成为Scale

那S和Z如何获取呢?

  • 可以知道浮点和定点参数的最值 R m a x 、 R m i n 、 Q m a x 、 Q m i n R_{max}、R_{min}、Q_{max}、Q_{min} RmaxRminQmaxQmin,则有:
    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 m a x S Z=Q_{max} - \frac{R_{max}}{S} Z=QmaxSRmax
2.1.1 8bit量化

(对上面的公式分情况细化)
8bit量化是目前工程上应用最为成熟的方案。该方案非常好的平衡了推理速度和精度之间的矛盾。Google的Tensorflow采用的是非对称量化,NVIDIA采用的是堆成量化。
对称量化和非对称量化,都属于线性量化,具有相同的量化公式和反量化公式(如上公式)。
但对于量化时的 S 、 Z S、Z SZ,可将其计算方式具体化。

  • 【对称量化】
    在这里插入图片描述
    操作:如上图所示,对称量化将输入数据映射到 [-128,127] 的范围内,但在实际使用中使用的是 [-127,127]。
    问题:如果将输入数据中存在偏离正常分布的较远离群点,则会导致较大的量化精度损失。
    解决:实际使用中,通常会选择介于127和 m a x ( ∣ x f ∣ ) max(|x_f|) max(xf) 之间的一个阈值T 对输入数据进行截断,以免离群点对量化精度的影响。即 量化的输入区间从 [ − m a x ( ∣ x f ∣ ) , m a x ( ∣ x f ∣ ) ] [-max(|x_f|), max(|x_f|)] [max(xf),max(xf)] 变为 [ − ∣ T ∣ , + ∣ T ∣ ] [-|T|, +|T|] [T,+T]

    对称量化需要保证【原始的输入数据中零点】通过映射公式后仍对应 [-127, 127] 区间的零点。所以Z=0,且Q=0时恰好有R=0。则整个计算过程如下,其中 R ′ R^{'} R为反量化结果
    Z = 0 S = ∣ R m a x ∣ ∣ Q m a x ∣ Q = r o u n d ( R S ) Q = c l i p ( Q , − 127 , 127 ) R ′ = Q ∗ S \begin{aligned} Z&=0 \\ S&=\frac{|R_{max}|}{|Q_{max}|} \\ Q&=round (\frac{R}{S}) \\ Q&=clip(Q, -127, 127) \\ R^{'}&=Q*S\\ \end{aligned} ZSQQR=0=QmaxRmax=round(SR)=clip(Q,127,127)=QS

  • 【非对称量化】
    在这里插入图片描述
    如上图所示,非对称量化将输入数据映射到[0,255] 的范围内。此时 Z = Q m a x − R m a x S = Q m i n Z=Q_{max}-\frac{R_{max}}{S}=Q_{min} Z=QmaxSRmax=Qmin。则整个计算过程如下,其中 R ‘ R^{`} R为反量化结果
    S = R m a x − R m i n Q m a x − Q m i n = 255 Q m a x − Q m i n Z = Q m a x − R m a x S = Q m i n Q = r o u n d ( R S + Z ) Q = c l i p ( Q , − 128 , 127 ) R ′ = ( Q − Z ) ∗ S \begin{aligned} S&=\frac{R_{max}-R_{min}}{Q_{max}-Q_{min}}=\frac{255}{Q_{max}-Q_{min}} \\ Z&=Q_{max}-\frac{R_{max}}{S}=Q_{min}\\ Q&=round (\frac{R}{S}+Z) \\ Q&=clip(Q, -128, 127) \\ R^{'}&=(Q-Z)*S\\ \end{aligned} SZQQR=QmaxQminRmaxRmin=QmaxQmin255=QmaxSRmax=Qmin=round(SR+Z)=clip(Q,128,127)=(QZ)S


2.2 线性量化步骤

当前支持神经网络模型的芯片,都会提供一整套方案,其中就包括模型转换时的量化,使用者只需要按照相应文档进行操作即可。但若自己代码实现线性量化,具体过程:

  • 选择合适的量化方法,确定选用对称量化或非对称量化;
  • 统计输入数据的数值区间[min_value, max_value];
  • 根据量化方式,以及输入区间计算量化参数:零点值Z和缩放系数S;
  • 根据转换公式,对输入的float32 精度的数据转换为int8精度的数据

2.3 非线性量化

2.3.1 二值量化(1bit)

二值量化是目前压缩率最高的量化方法。有两种方法实现权重的二值化。一种是使用符号函数: w b = { + 1 i f      w ⩾ 0 − 1      o t h e r w i s e w_b=\left\{\begin{matrix} +1 &if \,\,\,\,w\geqslant0 & \\ -1 & \,\,\,\, otherwise& \end{matrix}\right. wb={+11ifw0otherwise另一种是以一定概率随机量化,如下公式: w b = { + 1      w i t h    p r o b a b i l i t y    p = σ ( w ) − 1      w i t h    p r o b a b i l i t y    1 − p w_b=\left\{\begin{matrix} +1 & \,\,\,\,with\,\,probability\,\,p=\sigma(w) & \\ -1 & \,\,\,\, with\,\,probability\,\,1-p& \end{matrix}\right. wb={+11withprobabilityp=σ(w)withprobability1p其中,概率的计算方式如下: σ ( x ) = c l i p ( x + 1 2 , 0 , 1 ) = max ⁡ ( 0 , min ⁡ ( 1 , x + 1 2 ) ) \sigma(x)=clip(\frac{x+1}{2},0,1)=\max(0,\min(1,\frac{x+1}{2})) σ(x)=clip(2x+1,0,1)=max(0,min(1,2x+1))
为了保持精度,权重在前向传播和反向传播计算的时候进行二值化,但是在进行参数更新的时候使用浮点类型。
虽然二值量化的效率非常高,但是模型精度非常大,落地困难。

2.3.2 聚类量化

典型代表,MIT的Deep Compression,这篇论文中综合使用了剪枝、量化、编码等技术实现模型的轻量化。其中量化这一部分的基本操作如下图所示
在这里插入图片描述
如上图所示,

  • 确定参数范围:4x4的矩阵中,所有权值大小在[-1.08,2.12] 之间
  • 聚类:如果以-1,0,1,2 这几个离散整数作为聚类中心,然后对矩阵中所有的权值进行聚类,并把同一类的所有权值四舍五入为聚类中心的值。
  • 同一类的权值梯度相加作为量化后聚类中心的梯度用于更新权重,图中相同颜色的权值表示属于同一聚类组

    作者采用 Kmeans聚类方法,把原始的m个权重 w = { W 1 , W 2 , . . . , W m } w=\{W_1,W_2,...,W_m\} w={W1,W2,...,Wm}量化为k个聚类中心 C = { C 1 , C 2 , . . . , C m } C=\{C_1,C_2,...,C_m\} C={C1,C2,...,Cm}。聚类算法最小化组内误差,目标函数: arg ⁡ min ⁡ C ∑ i = 1 k ∑ w ∈ c i ∣ w − c i ∣ 2 \arg \min_C \sum^{k}_{i=1}\sum_{w\in c_i}|w-c_i|^2 argCmini=1kwciwci2K-means 的初始聚类中心的选择非常关键。常用初始方法:均匀初始化、随机初始化、按密度初始化。论文中推荐使用均匀初始化,具体方法时统计权值的最小值和最大值,并把数值区间平分为 K 份,以每一份的分界点处的权值作为聚类的中心。
2.3.3 对数量化

INCREMENTAL NETWORK QUANTIZATION中有提出,对数量化后的定点值为2的幂次方,即两个临近点数值之间是以2为底的对数域上均匀分布的。如量化定点值为 2 − 1 , 2 − 2 , 2 − 3 2^{-1}, 2^{-2}, 2^{-3} 21,22,23,在对数域上的分布为-1,-2,-3。这种量化特性使得模型在推理时可以通过移位运算来实现快速的计算。
下图展示了对数量化的一种方式,权重矩阵中的权值量化到2的幂次的定点值上。与聚类量化方法不同的是,对每层的权重采用分批量化,而不是一次量化整个权重。这样分批量化的方式能够让部分权重保持高精度,更方便的进行训练优化。
在这里插入图片描述

3 训练感知量化、训练后量化

  • 训练感知量化:量化不可避免带来模型的精度损失,为了能够尽量保持原模型的精度,通常会对量化后模型做fine tuning,或者进行重新训练,这个方式称作为"训练感知量化"。
  • 训练后量化:如果模型量化的精度满足使用需求,则可以忽略finetuning和重训练过程,这种方式称作为"训练后量化"。若模型规模较小,有可能会导致无法使用。

3.1 训练感知量化主要流程:


3.2 训练后量化主要流程:

  • 准备Calibration Data,用于对量化模型进行量化参数校正。
  • 以训练好的高精度模型为基准,使用校正数据集对其进行量化
  • 统计权重和激活值的数值范围,确定量化参数
    • 权重量化:对模型中的weights进行量化。由于网络权重在训练结束后都是确定的值,因而通过对每一层权重统计就可以得到量化参数。此时不需要Calibaration Data参与的,既Data Free
    • 激活量化:对网络的激活值进行量化,既卷积权重的输出,可以能是激活函数后的输出。由于feature的数值范围需要动态的获取,因而就需要Calibaration Data作为数据输入,通过前向推理产生的各层的feature统计量化参数。
  • 使用量化参数对模型进行量化
    对激活值量化时,需要根据输入的Calibration Data动态的统计量化参数。通常会采用一些策略来确定更有效的量化参数:
    1. 统计每个batch的量化参数,通过指数平滑方法更新参数值。
    2. 统计量化参数时,需要去除偏离数据正常分布较远的离群点,以免造成大的量化误差。
    3. 使用KL散度评估模型量化产生的信息损失,选用KL散度最小时的量化参数来量化模型。如TensorRT使用该方法度量INT8的信息损失

3.3 总结


性能表现

  • 在CPU上,8bit量化推理能够获取2~3倍的速度提升。在专为低精度向量计算优化过的特定处理器上,如支持HVX的小龙DSP,和原浮点型模型推理速度相比能够加速10倍。
  • 使用线性量化可以在基本保持精度不变的情况下缩小4倍的模型大小。使用非线性量化则能够实现更高的压缩比,比如K-means聚类量化。

模型结构和量化关系

  • 模型大小和压缩率之间存在明确的这种关系。模型规模越大对量化误差的容忍程度越高
  • 对于某一个模型结构,可以在特征数量(权重激活数量)和量化之间进行折中,使用越多的特征数量参与量化,则卷积核可以相应支持更低的比特位宽
  • 训练过程中不约束激活函数的输出范围,而是直接对输出进行量化,这样能进一步提升精度。

参考:https://laiye.com/tech-blog/2391

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1058223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

已解决 Bug——SyntaxError: Unexpected token o in JSON at position 1问题

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页: 🐅🐾猫头虎的博客🎐《面试题大全专栏》 🦕 文章图文并茂&#x1f996…

读书笔记|《数据压缩入门》—— 柯尔特·麦克安利斯 亚历克斯·海奇

前言:在接触文本隐写研究领域时了解到这本书。本书可算作《数据压缩》的入门书籍之一,这本书对熵编码、变长编码、统计编码、自适应统计编码、字典编码、上下文编码等常用编码方式的定义及来源进行介绍,对不同场景下不同格式的压缩数据有针对…

2023-10-03 LeetCode每日一题(买卖股票的最佳时机 III)

2023-10-03每日一题 一、题目编号 123. 买卖股票的最佳时机 III二、题目链接 点击跳转到题目位置 三、题目描述 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 **注意…

【考研英语】2011 年英语(一)排序题思路复盘(费曼学习法)

文章目录 引言一、找语段特征词二、确定位置写在最后 引言 英语一中的新题型之一 —— 排序题,我是看的刘琦老师的方法课,她用的 2011 年的真题来讲解方法。讲完让我们回去用“费曼学习法”复盘以下,我个人感觉是一个不错的方法,…

leetCode 45.跳跃游戏 II 贪心算法

45. 跳跃游戏 II - 力扣(LeetCode) 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 &…

踩坑笔记 MySQL分页排序查询(Order by limit)导致数据丢失和重复

文章目录 背景现象原因解决方案 背景 分页查询排序后的数据,是一个非常常见的业务场景;但当使用不唯一的字段排序时,分两页查询的数据可能出现数据重复和丢失的错觉。 在执行查询时,MySQL会根据查询优化器的决策来确定数据的检索…

RabbitMQ安装与简单使用

安装 下载资源 可以访问官网查看下载信息rabbitmq官网 选择合适的版本,注意:rabbitmq需要下载一个Erlang才能使用 我自己是在一下两个连接中下载的 rabbitmq 3.8.8 erlang 21.3.8.15 需要下载其他版本的同学注意erlang版本是否匹配,可以访…

axb_2019_brop64

axb_2019_brop64 Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)64位,只开了NX __int64 repeater() {size_t v1; // raxchar s[208]; // [rsp0h] [rbp-D0h] BYREFprintf("…

1200*C. Make It Good(二分 || 贪心)

Make It Good - 洛谷 Problem - 1385C - Codeforces 思路一&#xff1a; 二分答案&#xff0c;每次check从mid1开始&#xff0c;判断能否形成要求的序列。 #include<bits/stdc.h> using namespace std; #define int long long const int N2e55; int t,n,a[N]; bool che…

栈的应用场景(三)

最小栈 1.题目2.画图分析3.代码实现 1.题目 2.画图分析 3.代码实现 package Stack;import java.util.Stack; public class MinStack {private Stack <Integer> stack;private Stack <Integer> MinStack;public MinStack() {stack new Stack<>();MinStack …

JAVA学习(2)-全网最详细~

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

jarvisoj_level5

jarvisoj_level5 Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x3fe000)64位&#xff0c;只开了NX ssize_t vulnerable_function() {char buf[128]; // [rsp0h] [rbp-80h] BYREFwrite(1, "Input:\…

【网络通信三要素】TCP与UDP快速入门

网络通信三要素 1.什么是网络编程&#xff1f; 可以让设备中的程序&#xff0c;与网络上其他设备中的程序进行数据交互&#xff0c;从而实现网络通信的手段&#xff0c;java.net.*包下提供了网络编程的解决方案 2.基本的通信架构 基本的通信架构有2种形式&#xff1a;CS架构…

【Spring MVC】MVC如何浏览器请求(service方法)

文章目录 1. DispatcherServlet 的 service 方法1.1. processRequest 方法1.2. doService 方法 背景&#xff1a;平时我们学习 MVC 重点关注的时DispatcherServlet 的 doDispatcher 方法&#xff0c;但是在 doDispatcher 方法之前 还有请求处理的前置过程&#xff0c;这个过程…

javaWeb学生信息管理

一、引言 学生信息管理系统是基于Java Web技术开发的一个全栈应用&#xff0c;用于管理学生的基本信息。本系统采用Eclipse作为开发工具&#xff0c;Navicat用于MySQL数据库管理&#xff0c;运行在JDK1.8、Tomcat9.0、MySQL8.0环境下。前端采用JavaScript、jQuery、Bootstrap4…

大语言模型之十四-PEFT的LoRA

在《大语言模型之七- Llama-2单GPU微调SFT》和《大语言模型之十三 LLama2中文推理》中我们都提到了LoRA&#xff08;低秩分解&#xff09;方法&#xff0c;之所以用低秩分解进行参数的优化的原因是为了减少计算资源。 我们以《大语言模型之四-LlaMA-2从模型到应用》一文中的图…

14:00面试,14:06就出来了,这问的过于变态了。。。

前言 刚从小厂出来&#xff0c;没想到在另一家公司我又寄了。 在这家公司上班&#xff0c;每天都要加班&#xff0c;但看在钱给的比较多的份上&#xff0c;也就不太计较了。但万万没想到5月一纸通知&#xff0c;所有人不准加班了&#xff0c;不仅加班费没有了&#xff0c;薪资…

Linux: 进程(控制)

目录 1.进程的创建 1.1fork函数 1.2fork创建子进程,OS做了什么&#xff1f; 1.3为什么要写实拷贝&#xff1f; 2.进程的终止 2.1进程终止&#xff0c;操作系统做了什么&#xff1f; 2.2进程常见的退出方式 2.3进程常见的退出方法 3.进程的等待 3.1为什么进行进程等待…

SpringCloud Alibaba - Seata 部署 TC 服务,并集成微服务

目录 一、Seata 架构 1.1、Seata 架构重要角色 1.2、部署 TC 服务 1.2.1、前言 1.2.2、下载 seata-server 包&#xff0c;解压 1.2.3、修改配置 1.2.4、在 nacos 中添加配置 1.2.5、创建数据库表 1.2.6、启动 TC 服务 1.3、微服务集成 Seata 1.3.1、引入依赖 1.3.2、…

面试题:熟悉设计模式吗?谈谈简单工厂模式和策略模式的区别

刚刚接触设计模式的时候&#xff0c;我相信单例模式和工厂模式应该是用的最多的&#xff0c;毕竟很多的底层代码几乎都用了这些模式。自从接触了一次阿里的公众号发的一次文章关于 DDD的使用 以后&#xff0c;就逐渐接触了策略模式。现在在项目中运用最多的也是这几种设计模式了…