量化QAT QLoRA OBD OBS GPTQ

模型量化的思路可以分为PTQ(Post-Training Quantization,训练后量化)和QAT(Quantization Aware Training,在量化过程中进行梯度反传更新权重,例如QLoRA),GPTQ是一种PTQ的思路。

QAT(Quantization Aware Training)

BN需要先融合掉:
在这里插入图片描述
伪量化节点是根据融合图来决定的

量化过程中不可导的部分是Round函数,Hinton论文中把他的导数置为1,这就解决了量化框架中梯度反向传播的问题,图片截取自https://www.bilibili.com/video/BV13s4y1D73L/:
在这里插入图片描述
在这里插入图片描述
AdaRound和AdaQuant这些论文都是一层层训练的,QAT需要把某些层切成子图,对子图量化即可。

QLoRA

几个关键点:

  • 4bit NormalFloat 量化
  • 双重量化
  • Page Optimizer:Page Optimizer机制使得在GPU显存吃紧的时候可以把optimizer转移到内存上,在需要更新optimizer状态时再加载回来,据说可以有效减少GPU显存的峰值占用,文章称想要达到在24gb上训练33B 参数模型这个机制是必须的

QLoRA实现中用了bitsandbytes这个库

GPT

例如TensorRT的后量化,paddlepaddle的后量化,推理框架最清楚网络做哪些图融合,但是GPT不会训练,不会梯度反传。PPQ是商汤出的量化框架
在这里插入图片描述

OBD(Optimal Brain Damage)

截图自 https://readpaper.feishu.cn/docx/HaM7d7uGhoQ2VPxxZBacpduDny7
在这里插入图片描述

OBS(Optimal Brain Surgeon)

简单来说就是把权重直接展开,计算对应的海森矩阵,然后按照顺序进行量化。时间复杂度 O ( ( d row ⋅ d col ) 3 ) O\left( \left( d_{\text{row}} \cdot d_{\text{col}} \right)^3 \right) O((drowdcol)3)
在这里插入图片描述
在这里插入图片描述
以下截图来自 https://readpaper.feishu.cn/docx/HaM7d7uGhoQ2VPxxZBacpduDny7
在这里插入图片描述

OBQ(Optimal Brain Quantization)

权重分行计算,但是贪心算法,每次找量化误差最小的进行量化。时间复杂度:
O ( d row ⋅ d col 3 ) O\left( d_{\text{row}} \cdot d_{\text{col}}^3 \right) O(drowdcol3)
在这里插入图片描述

GPTQ(Gradient Post Training Quantization)

  • GPTQ并不是完全凭空头脑风暴出来的想法,而是经过OBD(Optimal Brain Damage)->OBS(Optimal Brain Surgeon,Second Order Derivatives for Network Pruning)-> OBQ(Optimal Brain Quantization)->GPTQ逐渐演化过来的。这一类思路基本的出发点在于先考虑一个单层的网络W,如何找到一个量化后的网络Wq,使得W和Wq之间的差别最小?OBD方法是Lecun在1989年就在搞的方法,主要思路用W和Wq之间的误差进行泰勒展开,展开后舍弃一些项,得到利用海森矩阵进行迭代更新;OBS方法发现OBD方法在进行权重剪切的过程中并不完全合理,所以新增了权重删除补偿的策略;OBS在执行中是直接把权重展开计算对应的海森矩阵,然后按照顺序进行量化;OBQ对量化的顺序进行了调整,将权重分行进行计算,利用贪心算法每次找到量化误伤最小的行进行量化,量化复杂度显著降低;GPTQ在OBQ基础上使用相同顺序,各行并行计算,分批 BatchUpdate,分组量化,时间复杂度 O ( max ⁡ { d row ⋅ d col 2 , d col 3 } ) O\left( \max \left\{ d_{\text{row}} \cdot d_{\text{col}}^2, d_{\text{col}}^3 \right\} \right) O(max{drowdcol2,dcol3})
  • GPTQ在实现中用Cholesky分解来稳定了数值计算

在这里插入图片描述

GPTQ的reorder原理(核心思想:​分组优化与权重删除补偿、并行)

在量化过程中,GPTQ 将权重矩阵按列划分为多个子块(Block),例如每组 128 列。其核心目标是通过调整量化顺序和参数更新方式,减少量化误差的累积。具体来说:

  • ​分组优化:将权重矩阵按列分组,逐个子块量化。例如,先量化当前子块中的某一列,再调整该子块内其他未量化的列以补偿误差。
  • 权重删除补偿:量化某一列后,通过数学方法(如 Cholesky 分解)计算量化误差对后续列的影响,并动态更新剩余权重,以最小化整体输出误差。
  • 并行:GPTQ在OBQ基础上使用相同顺序,各行并行计算,分批 BatchUpdate,分组量化

参考文档

  1. https://readpaper.feishu.cn/docx/HaM7d7uGhoQ2VPxxZBacpduDny7
  2. https://readpaper.feishu.cn/docx/OPP2dTuXAoaO0oxWhQAcC05Wnpc
### PyTorch 中量化感知训练 (QAT) 的教程与最佳实践 #### 准备工作 为了在 PyTorch 中实现量化感知训练,需先安装必要的依赖库并导入所需模块。确保环境已配置好支持量化操作的版本。 ```python import torch from torchvision import models, transforms, datasets ``` #### 构建模型 创建用于训练的基础浮点数模型结构。此阶段不涉及任何量化处理[^1]。 ```python model = models.resnet18(pretrained=True) ``` #### 配置量化设置 通过调用 `quantize.prepare_qat` 方法来准备网络以接受伪量化参数更新。这一步骤会向模型中插入观察者节点以便收集统计信息,并允许权重激活函数同时被量化模拟。 ```python model.train() model.fuse_model() # 如果适用的话融合某些层可以提高性能 model.qconfig = torch.quantization.get_default_qat_qconfig('fbgemm') torch.quantization.prepare_qat(model, inplace=True) ``` #### 训练过程调整 启动常规训练循环,在每次迭代期间执行前向传播、损失计算以及反向传播步骤的同时也完成了对量化的估计。注意保持足够的epoch数量让模型适应新的约束条件。 ```python for epoch in range(num_epochs): for inputs, labels in dataloader: optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() ``` #### 完成量化转换 当完成全部训练周期之后停止追踪梯度变化并将最终得到的状态保存下来作为整型推理使用的依据。 ```python torch.quantization.convert(model.eval(), inplace=True) torch.save(model.state_dict(), 'qat_resnet18.pth') ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值