<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PTQ on Lorn</title><link>https://july-h5kf3.github.io/tags/ptq/</link><description>Recent content in PTQ on Lorn</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Wed, 26 Aug 2026 08:39:00 +0800</lastBuildDate><atom:link href="https://july-h5kf3.github.io/tags/ptq/index.xml" rel="self" type="application/rss+xml"/><item><title>[2026 ICLR] SliderQuant: Accurate Post-Training Quantization for LLMs</title><link>https://july-h5kf3.github.io/p/sliderquant/</link><pubDate>Wed, 26 Aug 2026 08:39:00 +0800</pubDate><guid>https://july-h5kf3.github.io/p/sliderquant/</guid><description>&lt;p&gt;现有的PTQ通常采用顺序量化框架，将预训练模型分割为相同大小的部分并依次量化，且对所有层一视同仁。在低比特情况下，这种平等处理方式存在如下缺陷：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;层间敏感度差异被忽略:实证研究表明，浅层和深层通常比中间层对量化更敏感，且第一层和最后一层的量化误差显著大于其他层&lt;/li&gt;&#10;&lt;li&gt;量化误差跨层累积:随着逐层量化进行，误差逐渐放大，而现有方法缺乏有效的跨层协同机制来抑制此问题&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;具体而言，作者做了两个简单的实验&lt;/p&gt;&#10;&lt;p&gt;将某个模型的特定层量化，来比较量化不同层带来的影响，以及量化不同数量的层数，来比较量化误差的积累效应，结果如下：&lt;/p&gt;&#10;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="491px" data-flex-grow="204" height="454" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://july-h5kf3.github.io/p/sliderquant/SliderQuant_fig1.png" srcset="https://july-h5kf3.github.io/p/sliderquant/SliderQuant_fig1_hu_4c0334c11448a05d.png 800w, https://july-h5kf3.github.io/p/sliderquant/SliderQuant_fig1.png 930w" width="930"&gt;&lt;/p&gt;&#10;&lt;p&gt;可以看到无论模型大小，对量化最敏感的永远是第一层和最后一层，且随着量化层数的增加，量化误差的积累也越来越明显。&lt;/p&gt;&#10;&lt;p&gt;为了解决上述问题，论文提出了SliderQuant框架，其核心包括:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Inter-layer sliding quantization: 针对浅层，中间层和深层分别设计自适应滑动窗口，建立跨层的智能化接力机制&lt;/li&gt;&#10;&lt;li&gt;Intra-layer sliding quantization: 在每个量化窗口内采用增量式量化策略，实现局部到全局的参数协同。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;strong&gt;Inter-layer sliding quantization&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;一般的PTQ量化普遍选择Layer-Wise的量化，因此误差会随着层数加深而逐渐累积。作者选择使用滑动窗口的方式进行量化，每次在整个窗口中的layer会被当作一个block进行量化。为了减少跨层量化误差，总会保证两个连续的窗口之间存在重叠即$s-i\geq 1$。（size，stride）&lt;/p&gt;&#10;&lt;p&gt;然而使用固定大小的滑动窗口时，预训练大语言模型的所有层都会以相同的窗口大小和每一步相同的移动间隔进行量化。也就是说，浅层、中间层和深层在很大程度上仍然被同等对待，这与我们期望的量化设计之间仍存在较大差距。&lt;/p&gt;&#10;&lt;p&gt;因此SliderQuant选用的方式为:&lt;/p&gt;&#10;&lt;p&gt;对于$L_s$个浅层，采用渐进扩展滑动窗口。具体而言，从仅量化第一层开始，窗口大小被设置为1；随后以第一层作为锚定层，每一步将窗口大小增加1，直到窗口覆盖所有浅层$L_s$&lt;/p&gt;&#10;&lt;p&gt;对于$L_D$个深层，采用渐进收缩滑动窗口。具体而言，从量化所有深层开始，然后每一步将窗口大小减少 1，直到窗口中只包含最后一层。最后一层始终作为锚定层，并参与每一个收缩后的滑动窗口的量化过程。&lt;/p&gt;&#10;&lt;p&gt;对于中间$L_i$个中间层，采用固定大小的滑动窗口，其中设置$\{s=2,i=1\}$,并保证各层具有均匀的优化频率。具体而言，在浅层和中间层之间设置一个重叠层，同时在中间层和深层之间也设置一个重叠层。&lt;/p&gt;&#10;&lt;p&gt;根据消融实验得到$L_s = L_D =4$可以在效率和精度之间达到平衡&lt;/p&gt;&#10;&lt;p&gt;可以参考下面的gif&lt;/p&gt;&#10;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="1269px" data-flex-grow="528" height="225" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://july-h5kf3.github.io/p/sliderquant/sliderquant_gif2.gif" srcset="https://july-h5kf3.github.io/p/sliderquant/sliderquant_gif2_hu_2dd1cc0425a6d39c.gif 800w, https://july-h5kf3.github.io/p/sliderquant/sliderquant_gif2.gif 1190w" width="1190"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Intra-Layer Sliding Quantization&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;为了进一步利用之前发现两个性质，论文提出了一个与Inter-layer sliding 互补的组件。&lt;/p&gt;&#10;&lt;p&gt;具体而言，它将逐步扩展的滑动设计进一步扩展到层间滑动量化的每一个窗口内部。在窗口内，s个层会沿着权重和激活维度，以比例$\gamma$并行地执行逐步扩展滑动。因此，所有 s个层的联合量化会在$N = \frac{1}{\gamma}$个滑动阶段完成。&lt;/p&gt;&#10;&lt;p&gt;这里从语言上描述比较抽象，可以参考下面的GIF，简单来说就是对于权重/激活值矩阵，沿着某个维度逐渐进行量化（而非一次性量化）。&lt;/p&gt;&#10;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="720px" data-flex-grow="300" height="360" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://july-h5kf3.github.io/p/sliderquant/sliderquant_gif1.gif" srcset="https://july-h5kf3.github.io/p/sliderquant/sliderquant_gif1_hu_438d56a7f7703948.gif 800w, https://july-h5kf3.github.io/p/sliderquant/sliderquant_gif1.gif 1080w" width="1080"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="622px" data-flex-grow="259" height="370" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://july-h5kf3.github.io/p/sliderquant/SliderQuant_fig2.png" srcset="https://july-h5kf3.github.io/p/sliderquant/SliderQuant_fig2_hu_226108b3885c0fc1.png 800w, https://july-h5kf3.github.io/p/sliderquant/SliderQuant_fig2.png 960w" width="960"&gt;&lt;/p&gt;&#10;&lt;p&gt;层内滑动量化在层间滑动量化当前滑动窗口内部，建立了一种从局部到全局的跨层参数协同关系，从而降低量化误差。&lt;/p&gt;&#10;&lt;p&gt;在层内对激活值和权重进行量化时，采用如下策略，该策略参考了目前主流的通道缩放以及低秩近似：&lt;/p&gt;&#10;&lt;p&gt;设$W_i \in \mathbb{R}^{n\times m}$表示滑动窗口中第i层的权重矩阵，$X_i \in \mathbb{R}^{k\times n}$表示其对应于一小组校准样本的输入特征，其中校准样本数为c，默认设置c=128,那么，量化过程定义为:&#10;&lt;/p&gt;&#10;$$&#10;\hat{X_i} = X_i \oslash \alpha_i\\&#10;\hat{W_i} = W_i \odot \alpha_i + A_iB_i \\&#10;\hat{X_{i+1}} = \text{quantizer}(\hat X_i)\cdot \text{quantizer}(\hat{W_i})&#10;$$&lt;p&gt;&#10;其中$\alpha_i$表示一个可学习的通道缩放参数，$A_i,B_i$为两个低秩矩阵。&lt;/p&gt;&#10;</description></item><item><title>[2026 CVPR] Fine-Grained Post-Training Quantization for Large Vision Language Models with Quantization-Aware Integrated Gradients</title><link>https://july-h5kf3.github.io/p/fine-grained-vlm-ptq/</link><pubDate>Wed, 26 Aug 2026 08:24:00 +0800</pubDate><guid>https://july-h5kf3.github.io/p/fine-grained-vlm-ptq/</guid><description>&lt;div style="background-color:#f9f9f9; padding:8px; border-radius:6px;"&gt;&#10; &lt;b&gt;个人评价&lt;/b&gt;:比较有意思的研究思路，从MBQ的Modality-Specific出发，通过实验发现，相较于Modality-Specific，更加细粒度的Token-Wise进行区分效果会更好。基于此研究了多种Token敏感度估计方法，最终采用基于公理化归因的积分梯度方法进行规约，取得不错的效果。但是问题在于文章对理论的分析严重不足！&#10;&lt;/div&gt;&#10;&lt;p&gt;假设你阅读过MBQ，它是按照模态去对优化目标进行加权的，那么我们可以仔细想想，不同模态最终都会以Token的形式输入模型，既然不同模态之间存在对量化噪声敏感性差异，那么我们其实可以说本质上是Token内部就存在差异，这个差异不仅仅存在于不同模态之间，还可能存在同一个模态之中。那么也就是说，我们完全可以仿照MBQ的思路去做更加细粒度的加权。&lt;/p&gt;&#10;&lt;p&gt;一般而言，衡量这种Token之间的差异，可以通过敏感性估计进行。作者在文章中尝试了三种敏感性估计方式:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;基于梯度:和MBQ一致，依据Token关于量化损失的梯度&lt;/li&gt;&#10;&lt;li&gt;基于注意力:用Attention Score&lt;/li&gt;&#10;&lt;li&gt;基于扰动:人为扰动token，然后观察block输出变化有多大。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;注:实验方法大概是像MBQ一样对不同的Token对量化损失进行加权，然后在VizWiz数据集上进行测试。&lt;/p&gt;&#10;&lt;p&gt;最后结果表明，Token-Level的扰动法的效果在不同敏感度估计下表现最优(0.36%的微弱优势)&lt;/p&gt;&#10;&lt;p&gt;基于上述分析，我们知道，按Token的细粒度量化方法可能会有更好的效果。因此作者声称基于公理化归因的启发。下面简单介绍一下公理化归因，这个方法来源于可解释AI。&lt;/p&gt;&#10;&lt;p&gt;我们从经典的积分梯度（IG）出发。IG用来衡量从参考输入x&amp;rsquo;到真实输入x的真实路径上，每个Token的累积贡献，其中$f(\cdot,\cdot)$表示该Block的输出：&#10;&lt;/p&gt;&#10;$$&#10;\text{IG}(x) = (x - x')\int_{0}^{1}\frac{\partial f(x^\alpha ,w)}{\partial x^{\alpha}}d\alpha \tag{QIG 1}&#10;$$&lt;p&gt;&#10;其中$x^\alpha = \alpha(x-x')$,而$f(\cdot,w)$表示全精度模型。&lt;/p&gt;&#10;&lt;p&gt;我简单介绍一下这个是怎么来的吧，本质上我们是想知道某个输入的Token发生变化后会对模型的输出产生怎样的变化。由导数的定义我们知道:&#10;&lt;/p&gt;&#10;$$&#10;f(x)-f(x') = \int_{x'}^x\frac{\partial f(t)}{\partial t}dt&#10;$$&lt;p&gt;&#10;在一维的情况下，因为只有一个变量，因此我们上式就是该Token的归约。当我们将输入扩展到多维，我们自然想知道每个维度对变化的贡献。&lt;/p&gt;&#10;&lt;p&gt;IG的做法是，我们从参考输入x‘出发，沿一条直线走到真实输入x，可以将这条路径写作:&#10;&lt;/p&gt;&#10;$$&#10;x^\alpha = x' + \alpha(x - x'),\quad \alpha \in [0,1]&#10;$$&lt;p&gt;&#10;那么此时，我们可以把函数写作按照路径变化的形式:&#10;&lt;/p&gt;&#10;$$&#10;F(\alpha) = f(x^\alpha)&#10;$$&lt;p&gt;&#10;这是一个一维函数，自变量只有$\alpha$，于是输入变化带来的变化可以写作:&#10;&lt;/p&gt;&#10;$$&#10;f(x)-f(x') = F(1)-F(0)&#10;$$&lt;p&gt;&#10;写作积分形式:&#10;&lt;/p&gt;&#10;$$&#10;F(1)-F(0) = \int_0^1 \frac{dF(\alpha)}{d\alpha}d\alpha = \int_{0}^1 \frac{\partial f(x^\alpha)}{\partial x^\alpha}\cdot \frac{\partial x^\alpha}{\partial \alpha}&#10;$$&lt;p&gt;&#10;而:&#10;&lt;/p&gt;&#10;$$&#10;x_i^\alpha = x_i' + \alpha(x_i-x_i')&#10;$$&lt;p&gt;&#10;故:&#10;&lt;/p&gt;&#10;$$&#10;\frac{\partial x_i^\alpha}{\partial \alpha} = x_i-x_i'&#10;$$&lt;p&gt;&#10;代入有：&#10;&lt;/p&gt;&#10;$$&#10;\frac{dF(\alpha)}{d\alpha} = \sum_{i=1}^n \frac{\partial f(x^\alpha)}{\partial x^\alpha}(x_i-x_i')&#10;$$&lt;p&gt;&#10;因此:&#10;&lt;/p&gt;&#10;$$&#10;f(x)-f(x') = \int_{0}^1 \sum_{i=1}^n\frac{\partial f(x^\alpha)}{\partial x^\alpha}(x_i-x_i') d\alpha = \sum_{i=1}^n (x_i-x_i')\int_{0}^1 \frac{\partial f(x^\alpha)}{\partial x^\alpha}d\alpha&#10;$$&lt;p&gt;&#10;那么IG就定义第i维的规约为:&#10;&lt;/p&gt;&#10;$$&#10;\text{IG}_i(x) = (x_i-x_i')\int_{0}^1 \frac{\partial f(x^\alpha)}{\partial x^\alpha}d\alpha&#10;$$&lt;p&gt;&#10;写作向量形式就是式子QIG(1)中的形式。&lt;/p&gt;&#10;&lt;p&gt;对应到量化场景，我们取原始输入$x'$为量化后的输入$x'=x^q$,那么可以写出量化感知积分梯度:&#10;&lt;/p&gt;&#10;$$&#10;\text{QIG} = (x-x_q)\int_{0}^1 \frac{\partial f(x^\alpha)}{\partial x^\alpha}d\alpha&#10;$$&lt;p&gt;&#10;不过我们不能直接将QIG作为优化的权，因为它呈现了重尾分布，这会导致极少部分token主导优化过程。为了抑制这种现象，作者选择按照四分位距(IQR)进行裁剪，从而得到裁剪后的分数:&#10;&lt;/p&gt;&#10;$$&#10;C(QIG_i) = clip(QIG_i,Q_1-1.5\cdot IQR,Q_3+1.5\cdot IQR)&#10;$$&lt;p&gt;&#10;其中$Q_1,Q_3$分别表示第一和第三四分位数，且$IQR=Q_3-Q_1$.随后对这些分数进行归一化，得到最终的token重要系数:&#10;&lt;/p&gt;&#10;$$&#10;\lambda_i = \frac{C(QIG_i)}{\sum C(QIG_i)}&#10;$$&lt;p&gt;&#10;之后按照类似于MBQ的思路，将这个加权融入量化优化的目标函数即可。&lt;/p&gt;&#10;</description></item><item><title>[2023 ICLR] GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers</title><link>https://july-h5kf3.github.io/p/gptq/</link><pubDate>Wed, 26 Aug 2026 08:12:00 +0800</pubDate><guid>https://july-h5kf3.github.io/p/gptq/</guid><description>&lt;p&gt;这个文章是OWQ的前身，借着对这篇文章的分析，我们梳理一下这一系列的文章的intuition。&#10;大概的分析顺序为:&#10;&lt;/p&gt;&#10;$$&#10;\text{OBD} \to \text{OBS} \to \text{OBC} \to \text{GPTQ}&#10;$$&lt;p&gt;首先是OBD，这是由Yann LeCun在1990年提出的神经网络剪枝算法。该算法基于二阶导数信息，旨在通过去除目标函数影响较小的参数来降低模型复杂度，提高泛化能力。&lt;/p&gt;&#10;&lt;p&gt;具体而言，就是希望去除目标函数对目标函数E(即Loss)影响小的参数，我们记去除了若干参数的模型的参数为$\hat W = W + \Delta w$,有:&#10;&lt;/p&gt;&#10;$$&#10;\Delta E = L(x,y,W) - L(x,y,W + \Delta w) = &#10;\sum_{i}g_i \Delta w_i + \frac{1}{2}\sum_{i}h_{i,i}\Delta w_{i}^2 + \frac{1}{2}\sum_{i\neq j}h_{i,j}\Delta w_i\Delta w_j + O(\Delta w^3)&#10;$$&lt;p&gt;&#10;其中$g_i = \nabla L$,$h_{i,j}$为Hessian矩阵$H_{L}$的一个元素&lt;/p&gt;&#10;&lt;p&gt;其中由于剪枝发生在对于已经训练好的神经网络，因此一阶导项可以忽略不计，而高阶项由于模型会进行归一化，因此$\Delta w$较小，可以忽略不计。&lt;/p&gt;&#10;&lt;p&gt;此外，OBD做了一个有争议的假设，即删除任意一个参数后，其他参数对目标函数的影响不变，也就是说每个参数对目标函数的影响是独立的，因此可以忽略交叉项:&lt;/p&gt;&#10;&lt;p&gt;那么我们可以得到简化后的公式:&#10;&lt;/p&gt;&#10;$$&#10;\Delta E = \frac{1}{2}\sum_{i}h_{i,i}\Delta w_i^2&#10;$$&lt;p&gt;&#10;因此，对神经网络进行剪枝，删除参数时，参数对目标函数的影响可以通过海森矩阵的对角项进行衡量。我们只需要在剪枝时求出海森矩阵，按对角项从小到大排序，即可确定参数剪枝的次序。&lt;/p&gt;&#10;&lt;p&gt;可以注意到，OBD的这个认为参数对目标函数的影响是独立的假设是很强的。OBS认为参数之间的独立性不成立，如果考虑交叉项，可以写作矩阵形式&#10;&lt;/p&gt;&#10;$$&#10;\Delta E = \frac{1}{2}\Delta w^\top H\Delta w&#10;$$&lt;p&gt;&#10;OBS希望在W每次迭代找到一个位置q(即准备剪枝的位置，后续会将该位置的$w_q = 0$),以及在获得位置q的同时，计算处一个与之相关的$\Delta w$对w进行补偿，使得$L(w+\Delta w)-L(w)$尽量小。&lt;/p&gt;&#10;&lt;p&gt;那么这个流程可以描述为一个带约束的凸优化问题:&#10;&lt;/p&gt;&#10;$$&#10;\arg \min_q \frac{1}{2}\Delta w^\top H \Delta w\\&#10;s.t.\ e_q^\top\Delta w + w_q = 0&#10;$$&lt;p&gt;&#10;这里$e^\top_q$是第q个值为1的列向量。&lt;/p&gt;&#10;&lt;p&gt;采用Lagrange乘子法进行求解:&#10;&lt;/p&gt;&#10;$$&#10;\mathcal{L} = \frac{1}{2}\Delta w^\top H \Delta w + \lambda(e^\top_q \Delta w + w_q)&#10;$$&lt;p&gt;&#10;对$\lambda$并置为0得到:&#10;&lt;/p&gt;&#10;$$&#10;e_q^\top \Delta w + w_q = 0\\&#10;\Delta w^\top e_q + w_q = 0&#10;$$&lt;p&gt;&#10;对$\Delta w$求导并置为0有:&#10;&lt;/p&gt;&#10;$$&#10;\Delta w^\top H + \lambda e^\top_q = 0\\&#10;\Delta w^\top H H^{-1} + \lambda e_q^\top H^{-1}=0\\&#10;\Delta w^\top + \lambda e^\top_q H^{-1} = 0&#10;$$&lt;p&gt;&#10;有&#10;&lt;/p&gt;&#10;$$&#10;w_q = \lambda e_q^\top H^{-1} e_q\\&#10;\lambda = \frac{w_q}{[H^{-1}]_{qq}}&#10;$$&lt;p&gt;&#10;其中用到了等式$e_q^\top H^{-1}e_q = [H^{-1}]_{qq}$&lt;/p&gt;&#10;&lt;p&gt;将$\lambda = \frac{w_q}{[H^{-1}]_{qq}}$带入等式$\Delta w^\top H + \lambda e_q^\top = 0$,得到&#10;&lt;/p&gt;&#10;$$&#10;\Delta w^{\top} = -\frac{w_q}{[H^{-1}]_{qq}}e_{q}^\top H^{-1}\\&#10;\Delta w = -\frac{w_q}{[H^{-1}]_{qq}}(H^{-1})^\top e_q \\&#10;\Delta w = -\frac{w_q}{[H^{-1}]_{qq}}H_{:,q}^{-1}&#10;$$&lt;p&gt;&#10;其中$H_{:,q}^{-1}$表示$H^{-1}$的第q列,且Hessian矩阵是一个对称矩阵.&lt;/p&gt;&#10;&lt;p&gt;将$\Delta w$带入$\Delta \mathcal{L}$我们有:&#10;&lt;/p&gt;&#10;$$&#10;\Delta\mathcal{L} = \frac{1}{2}\Delta w^\top H \Delta w = \frac{1}{2}(-\frac{w_q}{[H^{-1}]_{qq}}e_q^\top H^{-1})H(-\frac{w_q}{[H^{-1}]_{qq}}H^{-1}e_q)\\&#10;=\frac{1}{2}(\frac{w_q}{[H^{-1}]_{qq}})^2e_q^\top H^{-1}e_q\\&#10;=\frac{1}{2}(\frac{w_q}{[H^{-1}]_{qq}})^2[H^{-1}]_{qq}\\&#10;=\frac{1}{2}\frac{w_q^2}{[H^{-1}]_{qq}}&#10;$$&lt;p&gt;&#10;由此我们得到:&#10;&lt;/p&gt;&#10;$$&#10;q = \arg \min_q \frac{w_q^2}{[H^{-1}]_{qq}}&#10;$$&lt;p&gt;我们不难发现，要进行k次剪枝，每一次剪枝都要求一次Hessian矩阵的逆(时间复杂度为$O(d^3)$),这样的时间复杂度明显是不能实际应用的，因此OBC对其进行了进一步的优化。&lt;/p&gt;&#10;&lt;p&gt;OBC主要做了两点优化，一个是对原始问题进行了拆分，另一个是对Hessian矩阵的计算进行了简化。&lt;/p&gt;&#10;&lt;p&gt;首先是对原始问题的拆分，对于Layer-wise的量化/剪枝而言，通常将对整个网络进行的量化/剪枝拆分为每一层独立的子问题。在先前对AdaQuant的分析中我们有提到，这种Layer-wise的拆分是高度可并行的。&lt;/p&gt;&#10;&lt;p&gt;在Layer-wise的量化/剪枝下，参数变化带来的损失可以描述为以下形式:&#10;&lt;/p&gt;&#10;$$&#10;\Delta \mathcal{L} = ||W_lX_l - \hat W_l X_l||_2^2&#10;$$&lt;p&gt;&#10;其中$\hat W$表示经过量化/剪枝后的参数。&lt;/p&gt;&#10;&lt;p&gt;OBC将这个损失函数进行了按行拆分，即认为删掉某个权重$w_{ij}$只影响该行的输出，行与行之间的Hessian矩阵元素是没有耦合的。(这两个都是对按行拆分合理性的解释，前者是直观解释，后者是数学解释)&lt;/p&gt;&#10;&lt;p&gt;对于第一点，我们知道，改变某个权重$w_{ij}$它只会对输出的某一行的结果产生影响，即$Y_{i,:} = W_{i,:}X$,那么既然只对某一行的输出产生影响,那么对于整体误差而言,也只对这一行的误差产生影响,而误差是可以按行拆分的:&#10;&lt;/p&gt;&#10;$$&#10;\Delta \mathcal{L} = ||WX - \hat W X||_2^2 = \sum_{i=1}^{d_{row}}||W_{i,:}X-\hat W_{i,:}X||_2^2&#10;$$&lt;p&gt;&#10;因此剪枝/量化是可以按行拆分并行处理的。&lt;/p&gt;&#10;&lt;p&gt;由于是Layer-wise的量化/剪枝，我们在这个尺度下的进行单行损失函数(二阶范数)的Hessian矩阵的计算从而对第二点进行证明，我们有:&#10;&lt;/p&gt;&#10;$$&#10;H_{pq} = \frac{\partial^2\Delta \mathcal{L}_l}{\partial w_{lp}\partial{w_{lq}}} = \frac{\partial}{\partial w_{lp}}\sum_{k=1}^N 2(\sum_{j=1}^{d_{col}}(w_{lj}-\hat w_{lj})x_{jk})\frac{\partial}{\partial w_{lq}} \sum_{j = 1}^{d_{col}}(w_{lj}-\hat{w_{lj}})x_{jk}\\&#10;=\frac{\partial}{\partial w_{lp}}\sum_{k=1}^N2(\sum_{j=1}^{d_{col}}(w_{lj}-\hat w_{lj})x_{jk})x_{qk}\\&#10;=2\sum_{k=1}^N x_{pk}x_{qk}&#10;$$&lt;p&gt;&#10;写成矩阵的形式就是&#10;&lt;/p&gt;&#10;$$&#10;H = 2XX^\top&#10;$$&lt;p&gt;&#10;发现每一行的损失的Hessian矩阵只跟输入数据X有关且相等，而与模型权重无关，因此我们认为行与行之间的Hessian矩阵元素是没有耦合的。&lt;/p&gt;&#10;&lt;p&gt;而我们知道通过泰勒展开可以得到参数变化对损失函数的影响的近似表示$\Delta w^\top H \Delta w$,那么结合上式我们可以知道行与行之间的损失是相互独立的(对于行而言$\Delta w$,行与行之间互相独立,对于Hessian矩阵而言，行与行之间相等且互不影响),由此可以从数学上说明按行拆分进行单独处理的方式是合理的。&lt;/p&gt;&#10;&lt;p&gt;有了这个证明，我们可以对每行进行单独处理进行量化剪枝。这种方式为我们提供了一个更加简单的Hessian矩阵形式$2X^\top X$但是每次更新参数仍然需要对其求逆，因此OBC提供了一个高效的求逆方法:&lt;/p&gt;&#10;&lt;p&gt;给定一个可逆矩阵H以及其逆矩阵$H^{-1}$,我们希望高效地计算删除H第q行第q列(删除权重$w_q$)后的逆矩阵$H^{-1}_{-q}$:&#10;&lt;/p&gt;&#10;$$&#10; H_{-q}^{-1} = (H^{-1} - \frac{1}{[H^{-1}]_{qq}}H^{-1}_{:,q}H^{-1}_{q,:})_{-q}&#10;$$&lt;p&gt;&#10;这个定理证明较为复杂，将在博客上更新详细证明与intuition。&lt;/p&gt;&#10;&lt;p&gt;接下来我们来描述OBC剪枝的完整流程:&lt;/p&gt;&#10;&lt;p&gt;给定一个神经网络层的权重行向量$w \in \mathbb{R}^d$,以及其对应的Hessian矩阵的逆$H^{-1}\in \mathbb{R}^{d\times d}$,要求切除其中k个权重，同时最小化输出误差。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;初始化&#10;$M \leftarrow \{0,1,2,\dots,d-1\}$,为尚未被剪枝的权重索引集合。&lt;/li&gt;&#10;&lt;li&gt;重复执行k次:&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;pre&gt;&lt;code&gt;首先选择当前最优的剪枝目标q:$q \leftarrow \arg\min_{q\in M}\frac{w_q^2}{[H^{-1}]_{qq}}$,接着弥补剪掉$w_p$带来的误差$\Delta w \leftarrow \Delta w - \frac{w_q}{[H^{-1}]_{qq}}(H^{-1}_{:,q})^\top$,然后更新$H^{-1}\leftarrow H^{-1}_{-q}$,从候选集中移除该索引$M\leftarrow M - \{q\}$&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;而对于量化而言(OBQ)，相对剪枝我们需要做一些调整。首先是之前的最优化问题的限制条件需要改为:&#10;&lt;/p&gt;&#10;$$&#10; \Delta w \cdot e_q + w_q - \text{quant}(w_q) = 0&#10;$$&lt;p&gt;&#10;同样使用Lanrange乘子法进行求解:&#10;&lt;/p&gt;&#10;$$&#10; \mathcal{L} = \frac{1}{2}\Delta w^\top H \Delta w + \lambda(\Delta w \cdot e_q + w_q - \text{quant}(w_q))&#10;$$&lt;p&gt;&#10;对$\Delta w$求导并置为0可以得到:&#10;&lt;/p&gt;&#10;$$&#10; \Delta w^\top H + \lambda e_q = 0\\&#10; \Delta w^\top = -\lambda e_q H^{-1}\\&#10; \Delta w = -\lambda H^{-1}e_{q}^\top&#10;$$&lt;p&gt;&#10;对$\lambda$求导并置为0可以得到:&#10;&lt;/p&gt;&#10;$$&#10; \Delta w\cdot e_q + w_q - \text{quant}(w_q) = 0\\&#10; w_q - \text{quant}(w_q) = \lambda H^{-1}e_q^\top e_q\\&#10; \lambda = \frac{w_q - \text{quant}(w_q)}{[H^{-1}]_{qq}}&#10;$$&lt;p&gt;&#10;得到:&#10;&lt;/p&gt;&#10;$$&#10; \Delta w = -\frac{w_q - \text{quant}(w_q)}{[H^{-1}]_{qq}}(H^{-1}_{:,q})^\top\\&#10; q = \arg \min_{q} \frac{(w_q-\text{quant}(w_q))^2}{[H^{-1}]_{qq}}&#10;$$&lt;p&gt;&#10;用上式替换OBC剪枝的流程，便可以得到量化流程。&lt;/p&gt;&#10;&lt;p&gt;GPTQ则是对OBQ进行了改进，GPTQ发现，在对权重的每一行量化时，按照贪心策略选择量化的q和按照任意固定顺序来量化每一行的权重最终的误差是相差不大的，那么可以直接让所有行都按照列序(0 $\rightarrow$ col),这样可以提高计算效率与存储效率。&lt;/p&gt;&#10;&lt;p&gt;这样做的另一个好处在于：每行的顺序一样，那么每一行对应的Hessian矩阵都是相同的，每次Hessian矩阵的逆只需要计算一次！&lt;/p&gt;&#10;&lt;p&gt;在固定量化顺序的前提下，我们不再需要求解$q = \arg\min_q$只需要关心$\Delta w$,此时$\Delta w$的更新公式为:&#10;&lt;/p&gt;&#10;$$&#10; \Delta w = -\frac{w_q - \text{quant}(w_q)}{[H_{q:,q:}]^{-1}_{0,0}}([H_{q:,q:}]^{-1}_{:,0})^\top&#10;$$&lt;p&gt;&#10;这个式子我们对比在贪心策略下的式子便不难发现，这个式子就是贪心策略式子在每次删除当前候选集里的第一个q时的式子的等价形式，同样地我们也能给出Hessian矩阵的逆的更新形式:&#10;&lt;/p&gt;&#10;$$&#10; [H_{q:,q:}]^{-1} = ([H_{q-1:,q-1:}]^{-1} - \frac{1}{[H_{q-1:,q-1:}^{-1}]_{0,0}}[H^{-1}_{q-1:,q-1:}]_{:,0}[H_{q-1:,q-1:}^{-1}]_{0,:})_{1:,1:}&#10;$$&lt;p&gt;&#10;从矩阵的角度来看我们在做的是这样一个变换:&#10;&lt;/p&gt;&#10;$$&#10; (H^{-1})^{(k)} = &#10; \left[&#10; \begin{matrix}&#10; I_{k-1} &amp; 0 &amp; 0^\top\\&#10; 0 &amp; a_{k,k} &amp; b_{k}^\top\\&#10; 0 &amp; b_k &amp; B'^{(k)}&#10; \end{matrix}&#10; \right]\to (H^{-1})^{(k+1)} = &#10; \left[&#10;\begin{matrix}&#10;I_{k} &amp; 0 &amp; 0\\&#10;0 &amp; a_{k+1,k+1} &amp; b_{k+1}^\top\\&#10;0 &amp; b_{k+1} &amp; B''^{(k+1)} &#10;\end{matrix}&#10; \right]&#10;$$&lt;p&gt;若我们不断更新Hessian的逆总会产生非正定的Hessian逆矩阵,其原因可能是由于数值误差的累积。为了解决这个问题，作者注意到每次从$H^{(-1)}$中删除一行一列，本质上和对称正定矩阵的Cholesky分解的逐步过程类似，因此作者对初始的$H^{-1}$进行了Cholesky分解，得到了一个上三角矩阵$T$。&lt;/p&gt;&#10;&lt;p&gt;Cholesky分解:假设一个正定矩阵$A\in \mathbb{R}^{n\times n}$是正定对称矩阵，那么必然存在一个对角元素为正数的下三角矩阵$L\in \mathbb{R}^{n\times n}$满足$A = LL^\top$&lt;/p&gt;&#10;&lt;p&gt;我们尝试模拟一次这个分解过程:&#10;&lt;/p&gt;&#10;$$&#10;A = \left[&#10; \begin{matrix}&#10; a_{11} &amp; A_{21}^\top\\&#10; A_{21} &amp; A_{22}&#10; \end{matrix}&#10;\right],L = \left[&#10;\begin{matrix}&#10;l_{11} &amp; 0\\&#10;L_{21} &amp; L_{22}&#10;\end{matrix}&#10;\right],L^\top = \left[&#10; \begin{matrix}&#10; l_{11} &amp; L_{21}^\top\\&#10; 0 &amp; L_{22}^\top&#10; \end{matrix}&#10;\right]&#10;$$&lt;p&gt;&#10;由于$A = LL^\top$,我们有:&#10;&lt;/p&gt;&#10;$$&#10;l_{11} = \sqrt{a_{11}},L_{21} = \frac{1}{l_{11}}A_{21},L_{22}L_{22}^\top = A_{22} - L_{21}L_{21}^\top&#10;$$&lt;p&gt;于是我们可以惊奇地发现$L_{22}L_{22}^\top$就是我们想要的$H_{q:,q:}^{-1}$!因此我们可以认为删去$[H_{q:,q:}^{-1}]$的第一行和第一列的过程与对该矩阵进行一次Cholesky分解是等价的。因为我们进行Cholesky分解得到的$L_{22}$恰好是更新了之后的$H^{-1}$进行Cholesky分解得到的下三角矩阵。&lt;/p&gt;&#10;&lt;p&gt;进一步地，GPTQ对初始的Hessian矩阵的逆进行了Cholesky分解得到一个上三角矩阵$L^\top$,这个矩阵还有一个特点在于，它的每一行刚好就等于逆矩阵每次更新迭代后的第一行乘以一个常数:&#10;&lt;/p&gt;&#10;$$&#10;C_qL_{q,q:}^\top = [H_{q:,q:}]^{-1}_{0,:}&#10;$$&lt;p&gt;&#10;这个我们可以通过Cholesky分解的式子知道，因为分解得到的$L$是一个下三角矩阵，那么它的第一行就只有一个常数，而这个常数乘以$L^\top$便可以得到A的第一行。&lt;/p&gt;&#10;&lt;p&gt;而恰好我们发现，$\Delta w$的更新公式只需要用到当前Hessian矩阵的逆的第一行，那么我们有:&#10;&lt;/p&gt;&#10;$$&#10;\Delta w = -\frac{w_{:,q}- \text{quant}(w_{:,q})}{C_q T_{qq}}C_qT_{q,q:}&#10;$$&lt;p&gt;&#10;其中常数可以直接约掉:&#10;&lt;/p&gt;&#10;$$&#10;\Delta w = -\frac{w_{:,q} - \text{quant}(w_{:,q})}{T_{qq}}T_{q,q:}&#10;$$&lt;p&gt;&#10;因此我们在进行量化时不用每次都更新Hessian矩阵的逆，而是直接对$H^{-1}$进行Cholesky分解，得到它的每一行便可以进行参数的量化。&lt;/p&gt;&#10;&lt;p&gt;此外，如果每行的量化并行计算，那么每次更新都要读写一次参数矩阵。若参数矩阵的维度为$d_{row}\times d_{col}$，那么量化这个参数矩阵就要读写$d_{col}$次参数，总共的读写量高达$d_{row}\times d_{col}^2$.(因为我们量化第i列的时候，后面的列相应地也要补偿更新)&lt;/p&gt;&#10;&lt;p&gt;那这样大量的IO开销将会成为瓶颈，因此GPTQ采用了Lazy Batch-Update技术。我们注意到对于列i，最终的量化决策并不会受到尚未更新的列的影响。这使得我们可以将后续列的更新推迟到后续步骤中，从而减少不必要的内存操作。&lt;/p&gt;&#10;&lt;p&gt;具体步骤如下:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;每次处理B列的一个小块，限制该列更新的补偿更新只影响块内的列&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;当前块的权重会在量化过程中被更新，而其影响暂时不传播到矩阵的其他部分&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;对当前块中的每一列进行量化，同时计算误差并更新当前块剩余的列&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;这些更新仅在当前块内进行，而不会影响整个矩阵&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;当一个块内的所有列完成量化后，将该块的更新结果批量应用到矩阵的剩余部分&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;这部分通过语言可能难以描述清楚，可以见下图:&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="GPTQ 的 lazy batch-update 示意" class="gallery-image" data-flex-basis="287px" data-flex-grow="119" height="1144" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://july-h5kf3.github.io/p/gptq/lazy-batch-update.jpg" srcset="https://july-h5kf3.github.io/p/gptq/lazy-batch-update_hu_9a06e5a9407335b0.jpg 800w, https://july-h5kf3.github.io/p/gptq/lazy-batch-update.jpg 1372w" width="1372"&gt;&lt;/p&gt;&#10;</description></item><item><title>[2022 NeurIPS] ZeroQuant: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers</title><link>https://july-h5kf3.github.io/p/zeroquant/</link><pubDate>Wed, 26 Aug 2026 08:06:00 +0800</pubDate><guid>https://july-h5kf3.github.io/p/zeroquant/</guid><description>&lt;div style="background-color:#f9f9f9; padding:8px; border-radius:6px;"&gt;&#10;&lt;b&gt;评价:&lt;/b&gt; 这篇文章比较Solid，考虑了硬件适配的问题，这是模型量化中一个老大难的问题尤其是混合精度。但是实验的模型都是参数规模较小的模型，在大模型上的效果有待考究。&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;：这篇文章指出，低比特量化在大型 Transformer 架构模型中精度受限的主要原因是激活值和权重矩阵的值分布方差较大。针对这一问题，提出了 ZeroQuant 方案。该方案主要包括：对权重采用 Group-wise 量化、对激活值采用 Token-wise 量化，这种方法既能适配硬件架构，又能保持较高的精度；同时，通过 Layer-wise 知识蒸馏方法来减少量化带来的精度损失。&lt;/p&gt;&#10;&lt;p&gt;文章指出，在大模型的量化中，采用PTQ会面临以下挑战。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;激活分布动态性强&lt;/p&gt;&#10;&lt;p&gt;论文通过展示每一层的激活值在不同Token语义下的分布，发现了其范围随输入token的语义上下文变化极大的特点。这一特点使得难以对所有的token使用固定的量化范围。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;权重矩阵范围差异大&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;​&#9;通过同样的方式，展示了不同层行权重的范围。同样可以看到权重矩阵的神经元范围差异较大。&lt;/p&gt;&#10;&lt;p&gt;这两个挑战使得Per-Tensor粒度的量化很难在大模型的量化中使用，而采用Per-channel粒度的量化会面临大的计算存储开销，且会导致在硬件级别的矩阵乘法优化难以执行。基于此作者提出采用Group-wise量化旨在对精度和实用性做出权衡。&lt;/p&gt;&#10;&lt;p&gt;对于权重矩阵而言，Group-wise量化就是将$W\in R^{n\times m}$划分为g个组，每个组单独量化。但是在最先提出这个量化方法的Q-BERT中仅将其用于QAT且没有考虑硬件效率约束，以及系统后端支持。基于此作者团队考虑了GPU的架构（Ampere架构）的硬件约束，特别是将Group-size与Tensor Core中的计算单元对齐。&lt;/p&gt;&#10;&lt;p&gt;具体而言，Tensor Core允许16*16大小的矩阵块在一个warp中并行处理，从而加速矩阵乘法和其他张量操作。如果我们让Group-size为16或32这样与Tensor core中矩阵乘法相适配的大小，这样就能在降低延迟的同时保持模型精度。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;注&lt;/strong&gt;：这部分文章在附录D中有详细介绍，简单来说Group-wise的group size是通过CUTLASS库和Profiler工具，根据输入尺寸和硬件特性动态确定的，以优化Tensor Core的计算效率。&lt;/p&gt;&#10;&lt;p&gt;对于激活值而言，在挑战中我们已经阐明了在不同的Token上下文语义下，激活值的范围存在巨大方差，因此解决这个问题的一个自然而然的想法是采用Token-wise的量化策略。但是直接采用DL框架中的Token级量化会导致显著的量化和反量化成本，因为引入了额外的操作。基于此作者采用了算子融合的方法等一系列优化。&lt;/p&gt;&#10;&lt;p&gt;知识蒸馏是缓解模型压缩后精度下降的最强大的办法之一。因此，论文提出了一种逐层的知识蒸馏技术来避免低比特量化带来的精度损失。&lt;/p&gt;&#10;&lt;p&gt;具体而言，在传统的知识蒸馏中，教师模型和学生模型的输出通常是整个模型的输出，但在逐层知识蒸馏(LKD)中，蒸馏的学习目标是逐层的，即学生模型要学习教师模型每一层的中间激活值。&lt;/p&gt;&#10;&lt;p&gt;假设我们要量化的是$L_k$层，其量化版本为$\hat L_k$,然后我们使用$L_{k-1}$层的输出作为$L_k,\hat L_k$的输入，测量差异，并更新模型&#10;&lt;/p&gt;&#10;$$&#10;L_{LKD,k} = MSE(L_kL_{k-1}\dots L_1(X)-\hat L_k L_{k-1}\dots L_1(X))&#10;$$&lt;p&gt;&#10;因为使用相同的前k-1层，所以无需单独保留一个单独的教师模型，因此额外的模型成本仅仅是$L_k$。而每次只对一层进行蒸馏，所以内存和计算开销非常小，并且无需原始训练数据。&lt;/p&gt;&#10;&lt;p&gt;在前面Token-wise的量化处我们提到，作者对Kernel做了对应的优化，下面我们详细展开。&lt;/p&gt;&#10;&lt;p&gt;首先是针对Token-wise 的激活值量化做了一系列的kernel融合。作者将激活值量化与其相关的逐元素和或基于reduction的操作（如bias，GELU,LayerNorm等）的kernel进行了融合。这样减少了数据转移的开销。而将反量化与矩阵乘法做了相应的融合。具体而言见下面的流程图&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR&#10;x --&gt;B((LN/GeLU))&#10;B --&gt; C(Quantize)&#10;C --&gt; D[GEMM]&#10;D --&gt; E(DeQuantize)&lt;/pre&gt;&lt;p&gt;经优化后&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR&#10;x --&gt; A((LN/GeLU + Quantize))&#10;A --&gt; B[GeMM + DeQuantize]&lt;/pre&gt;</description></item><item><title>[2020 ICML] AdaRound: Up or Down? Adaptive Rounding for Post-Training Quantization</title><link>https://july-h5kf3.github.io/p/adaround/</link><pubDate>Wed, 26 Aug 2026 08:03:00 +0800</pubDate><guid>https://july-h5kf3.github.io/p/adaround/</guid><description>&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;:本篇文章作者首先从数学角度证明了在模型量化过程中，直接将浮点数进行四舍五入round到最近定点数的方法并不是精度最优的。并且通过了一个简单的实验验证了猜想，随后基于此作者进行一系列的数学推导和数学近似推导除了最终的优化目标:最小化由于量化在预激活值中引入的均方误差，从而提出了自适应的Round方法:AdaRound.这种方法在进行量化时，自适应地决定将浮点值转到最近右定点还是左定点值。AdaRound可以在不需要QAT or finetune的情况下仅使用少量无标签的校准数据在精度上达到SOTA，甚至4bit量化也可以保留较好的精度。&lt;/p&gt;&#10;&lt;div style="background-color:#f9f9f9; padding:8px; border-radius:6px;"&gt;&#10; &lt;b&gt;个人评价&lt;/b&gt;:这篇文章的行文流惯，公式推导顶级，从完全理论的方式推导出了大部分量化论文中量化目标函数。&#10;&lt;/div&gt;&#10;&lt;p&gt;首先作者将量化过程定义为了一个对预训练模型权重w的微小扰动$\Delta w$.我们的目标为最小化这个扰动对损失函数$L(w)$造成的影响，即最小化$E[L(w+\Delta w)-L(w)]$,为了近似这个损失，采用了二阶泰勒展开有:&#10;&lt;/p&gt;&#10;$$&#10;L(w + \Delta w)\approx L(w) + \nabla L(w)^\top \Delta w + \frac{1}{2}\Delta w^{\top} H(w)\Delta w\\&#10;\Delta L \approx \nabla L^{\top}\Delta w + \frac{1}{2}\Delta w^\top H\Delta w&#10;$$&lt;p&gt;&#10;由于模型经过预训练损失函数的梯度很小，可以忽略，而高阶项只要扰动$\Delta w$不是特别大，二阶近似往往就是准确的。对于4-bit或更高精度而言这个是成立的。&lt;/p&gt;&#10;&lt;p&gt;因此我们可以认为影响模型精度的主要是$\Delta w$以及损失函数的曲率$H(w)$相关。&lt;/p&gt;&#10;&lt;p&gt;令$\Delta w^\top = [\Delta w_1,\Delta w_2]$,$H^{(w)} = \begin{bmatrix}1 &amp; 0.5\\0.5 &amp;1\end{bmatrix} $,那么由此我们可以计算出，量化导致的损失为:&#10;&lt;/p&gt;&#10;$$&#10;\Delta w^\top H^{(w)}\Delta w = \Delta w_1^2 + \Delta w_2^2 + \Delta w_1\Delta w_2&#10;$$&lt;p&gt;&#10;对于对角线项$\Delta w_1^2,\Delta w_2^2$而言四舍五入是最优的，最小化了误差，但是对于非对角线项$\Delta w_1\Delta w_2$采用四舍五入就不一定最优了。例如若二者符号取反乘积为负就可以抵消一部分损失的增量。&lt;/p&gt;&#10;&lt;p&gt;因此从理论上分析出了四舍五入方法的局限性。后续也从实验上进行了论证，作者采用四舍五入，全部向上，全部向下，随机舍入进行比较，发现在随机舍入中存在比四舍五入高出10%的取舍法，说明在取舍办法中，存在更优的方法。&lt;/p&gt;&#10;&lt;p&gt;这个取舍办法的选取可以通过如下问题描述。&lt;/p&gt;&#10;&lt;p&gt;假设每层权重量化，量化后的权重为$\hat w_i^{(l)}$&#10;&lt;/p&gt;&#10;$$&#10;\hat w_i^{(l)}\in \{w_i^{(l),floor},w_i^{(l),ceil}\}&#10;$$&lt;p&gt;&#10;$\Delta w_i^{(l)} = w^{(l)} - \hat w_i^{(l)}$,由此，最优的舍入过程可以描述为以下二元优化问题:&#10;&lt;/p&gt;&#10;$$&#10;\arg \min_{\Delta w} \mathbb{E}[L(x,y,w+\Delta w) - L(x,y,w)]&#10;$$&lt;p&gt;&#10;直接对这个式子进行优化并不现实，因为，每次调整$\Delta w$都需要进行一次前向传播，计算成本太高，我们采用前面理论分析时的泰勒展开近似。此外，忽略属于不同层之间权重的交互。优化目标近似为：&#10;&lt;/p&gt;&#10;$$&#10;\arg \min_{\Delta w^{(l)}} \mathbb{E}[\Delta w^{(l)}H^{(w^{(l)})}\Delta w^{(l)}] &#10;$$&lt;p&gt;&#10;但是这个优化过程受限于Hessian矩阵的计算困难以及问题本身是一个NP-Hard问题。因此无法将这个作为最终的优化目标。&lt;/p&gt;&#10;&lt;p&gt;我们从Hessian矩阵计算的复杂性来分析&#10;&lt;/p&gt;&#10;$$&#10;\frac{\partial^2 L}{\partial W^{(l)}_{i,j}\partial W^{(l)}_{m,o}} = \frac{\partial}{\partial W_{m,o}^{(l)}}[\frac{\partial L}{\partial z_i^{(l)}}\cdot x_j^{(l-1)}] = \frac{\partial^2 L}{\partial z^{(l)}_i\partial z_m^{(l)}}\cdot x_j^{(l-1)}x_i^{(l-1)}&#10;$$&lt;p&gt;&#10;写作矩阵的形式&#10;&lt;/p&gt;&#10;$$&#10;H(w^{(l)}) = \mathbb{E}[x^{(l-1)} x^{(l-1)\top}⊗ \nabla^2_{z^{(l)}}L]&#10;$$&lt;p&gt;&#10;其中⊗为Kronecker积。由此看出Hessian矩阵的复杂性主要来于二阶导的求取，它需要通过网路的后续层反向传播二阶导数(见对角近似)。&lt;/p&gt;&#10;&lt;p&gt;为了解决这个问题，我们采用Hessian矩阵的对角近似，即将其近似为对角矩阵，记作$diag(\Delta^2_{z^{(l)}}L)$。&#10;&lt;/p&gt;&#10;$$&#10;H(w^{(l)}) = \mathbb{E}[x^{(l-1)} x^{(l-1)\top}⊗ diag(\nabla^2_{z^{(l)}}L)]&#10;$$&lt;p&gt;&#10;将这个近似带入优化方程中有：&#10;&lt;/p&gt;&#10;$$&#10;\arg \min_{\Delta W_{k,:}^{(l)}} \mathbb{E}[\nabla^2_{z^{(l)}}L_{k,k}\cdot \Delta W_{k,:}^{(l)}x^{(l-1)}x^{(l-1)\top}\Delta W_{k,:}^{(l)\top}]\\&#10;=\arg\min_{\Delta W_{k,:}^{(l)}} \Delta W_{k,:}^{(l)}\mathbb{E}[x^{(l-1)}x^{(l-1)\top}]\Delta W_{k,:}^{(l)\top}\\&#10;=\arg \min_{\Delta W_{k,:}^{(l)}} \mathbb{E}[(\Delta W_{k,:}^{(l)}x^{(l-1)})^2]&#10;$$&lt;p&gt;&#10;这里是认为$\nabla^2_{z^{(l)}}L_{i,i}$是一个与输入样本数据无关的常量结果。&lt;/p&gt;&#10;&lt;p&gt;由此我们推导出，我们只要最小化由于量化而在激活函数$z^{(l)}$中引入的均方误差。这与大部分量化的论文中的结论一致（如AdaQuant）&lt;/p&gt;&#10;&lt;p&gt;想要通过直接求解上面的优化方程仍然是一件困难的事情，因为它是NP-Hard的，因此作者将优化目标放宽为如下形式&#10;&lt;/p&gt;&#10;$$&#10;\arg \min_{V}||Wx-\hat Wx||^2_{F}+\lambda f_{reg}(V)&#10;$$&lt;p&gt;&#10;其中$||\cdot||^2_F$为F范数，$\hat W$为优化的软量化权重&#10;&lt;/p&gt;&#10;$$&#10;\hat W = s\cdot clip([\frac{W}{s}] + h(V),n,p)&#10;$$&lt;p&gt;&#10;$h(V_{i,j})$可以是任何在0和1之间取值的可微函数，$f_{reg}(V)$是一个可微正则项，用于鼓励$h(V_{i,j})$收敛到0或1.&lt;/p&gt;&#10;&lt;p&gt;但是这个方法存在一个缺陷，无法避免量化误差的不断积累且没有考虑到激活函数，所以做了进一步优化&#10;&lt;/p&gt;&#10;$$&#10;\arg \min_{V}||f_a(Wx)-f_a(\hat W\hat x)||_F^2 + \lambda f_{reg}(V)&#10;$$&lt;p&gt;&#10;其中$fa(\cdot)$为激活函数$\hat x$为当前层的反量化输入，x为当前层的浮点输入&lt;/p&gt;&#10;</description></item><item><title>[2021 ICML] AdaQuant: Accurate Post Training Quantization With Small Calibration Sets</title><link>https://july-h5kf3.github.io/p/adaquant/</link><pubDate>Wed, 26 Aug 2026 08:00:00 +0800</pubDate><guid>https://july-h5kf3.github.io/p/adaquant/</guid><description>&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;：本篇文章的主要贡献在于提出了一个基于小数据集（校验集）的训练后量化方法AdaQuant，AdaQuant通过提出一个block/layer-wise的损失函数，通过在校验集上的训练学习量化参数(重点包括了一个最优的权重扰动，类似于AdaRound来避免四舍五入的不足),实现了减少量化的精度损失；提出了基于PI(整数规划)的bit精度分配方案，但是并没有解释精确损失的累加合理性；提出量化对BN融合造成的统计量偏移问题，并提出了PN(Para-Normalization)来解决这个问题。并在Bert-base网络上实现了不到1%的损失(4-8bit)&lt;/p&gt;&#10;&lt;div style="background-color:#f9f9f9; padding:8px; border-radius:6px;"&gt;&#10;&lt;b&gt;吐槽:&lt;/b&gt; 这篇文章作者(符号和表达)有点混乱，得多读几遍才能理解作者想表达什么.中间bit分配假设成立存疑&#10;&lt;/div&gt;&#10;&lt;p&gt;在一般的Post-training 量化中，我们的优化目标可以用下式表示:&#10;&lt;/p&gt;&#10;$$&#10;\hat\Delta = \arg \min_{\Delta}||X - Q_{\Delta}(X)||^2\\&#10;Q_{\Delta}(x) = \Delta[\frac{X}{\Delta}]&#10;$$&lt;p&gt;&#10;其中，$Q(\cdot)$是量化方程。这种方法对所有的量化损失都是平等处罚的，但是事实上我们更应该对影响分类的量化损失进行更多的惩罚。量化感知训练可以缓解这个问题但是它存在计算开销大的问题。&lt;/p&gt;&#10;&lt;p&gt;基于此，作者提出了AdaQuant，其核心思想是采用一个block/layer-wise的优化误差函数:&#10;&lt;/p&gt;&#10;$$&#10;(\hat\Delta_{w}\hat\Delta_x,\hat V) = \arg\min_{\Delta_w,\Delta_x,V}||WX-Q_{\Delta_w}(W')Q_{\Delta_x}(X)||^2&#10;$$&lt;p&gt;&#10;其中，$W' = W + V$,这里V是引入的一个连续的可学习的“补偿”张量。被量化的对象是进行补偿后的权重W&amp;rsquo;:$W_q = Q_{\Delta_w}(W') = Q_{\hat\Delta_w}(W+V)$.&lt;/p&gt;&#10;&lt;p&gt;这里其实有点类似于AdaRound的思想了，因为AdaRound主张的是在量化时直接采用四舍五入是一个不明智地选择，因此这里采用一个补偿张量V来做这个选择&lt;/p&gt;&#10;&lt;p&gt;由于量化参数的得到依赖的是上一层全精度的激活值输出作为输入，因此各个网络之间互不干扰，所以可以并行处理。&lt;/p&gt;&#10;&lt;p&gt;但是在实际的推理过程中，网络的输入是上一层量化后的激活值（见训练后静态量化），因此，作者提出了串行版本的AdaQuant，此时它的优化误差函数为&#10;&lt;/p&gt;&#10;$$&#10;(\hat\Delta_{w_l},\hat\Delta_{x_l},\hat V_l) = \arg\min_{\Delta_{w_l},\Delta_{x_l},V_l}||W_lX_l - Q_{\Delta_{w_l}}(W_l')\cdot Q_{\Delta_{x_l}}(X_l^q)||^2\\&#10;X^q_l = \sigma(Q_{\Delta_{w_{l-1}}}(W'_{l-1})\cdot Q_{\Delta_{x_l}}(X_{l-1}^q) )&#10;$$&lt;p&gt;&#10;其中，$\sigma(\cdot)$是激活函数&lt;/p&gt;&#10;&lt;p&gt;需要注意的是，串行版本的AdaQuant得在比特分配之后进行，这是因为它的优化依赖于上一层的输入。&lt;/p&gt;&#10;&lt;p&gt;为了在性能和精度之间做权衡，在量化时我们往往会给不同层的网络分配不同的bit精度。AdaQuant在此思想上，提出了采用整数规划(PI)的方式。&lt;/p&gt;&#10;&lt;p&gt;作者将网路的bit分配描述为这样一个问题：&lt;/p&gt;&#10;&lt;p&gt;给定L层的神经网络。对于每一层l，我们都有需要与前一层$X_{l-1}$的激活值相乘的权重$W_l$。令$W_l^k$和$X_{l-1}^n$表示$W_l,X_{l-1}$精度为k和n位的量化版本。对于每一层i，低位宽乘法$W_l^k X_{l-1}^k$会带来$\Delta L_l^{k,n}$的准确损失和$\Delta P_{l}^{k,n}$的性能提升。&lt;/p&gt;&#10;&lt;p&gt;作者假设了准确损失以及性能提升是满足可加性的。&lt;/p&gt;&#10;&lt;div style="background-color:#f9f9f9; padding:8px; border-radius:6px;"&gt;&#10;这里存疑，因为l-1层的准确损失势必会影响l层的准确损失，不能简单做加法来描述整个网络的准确性退化&#10;&lt;/div&gt;&#10;&lt;p&gt;那么问题可以描述为，在不超过总网络退化$\Delta L$的前提下，最大化总性能提升。我们设示性函数$I_l^{k,n}$来表示第l层是否采用k，n位量化版本（1表示使用）。问题可以被符号表示为:&#10;&lt;/p&gt;&#10;$$&#10;\max \sum_{l = 0}^{L-1}\Delta P_l\\&#10;Subject\ to\ \sum_{l}\Delta L_{l}\leq \Delta L\\&#10;\forall l\in \{1,\dots,L\}:\Delta P_l = \sum_{k,n}I_l^{k,n}\cdot \Delta P_{l}^{k,n},\Delta L_l = \sum_{k,n}I_{l}^{k,n}\cdot L_{l}^{k,n}\\&#10;\forall l\in \{1,\dots,L\}:\sum_{k,n}I_l^{k,n}=1,I_l^{k,n}\in\{0,1\}&#10;$$&lt;p&gt;BatchNormalization在部署时，通常会与前面的卷积/全连接层进行融合，这样可以减少推理时的计算量。(这是因为BN的线性变换乘$\gamma/\sqrt{\sigma^2+\epsilon}$，加$\beta-\gamma\mu/\sqrt{\sigma^2+\epsilon}$可以直接合并到权重和偏置中)&lt;/p&gt;&#10;&lt;p&gt;然而当网络量化后，会导致激活值的分布发生偏移，即统计量均值$\mu$和方差$\sigma^2$会偏离在全精度模型中应有的值。但是由于BN层已经被融合到了前面的层中，这个偏移无法被校准。基于此，作者采用了一个名为Para-Normalization(PN)的方法来更新BN的统计量，以补偿这种偏差。&lt;/p&gt;&#10;&lt;p&gt;具体而言，假设我们知道了原始的BN参数$\gamma_0,\beta_0$.然后我们初始化一个新的BN层，初始化$\mu,\sigma^2$以及BN参数$\gamma_r,\beta_r$以便重建BN，使其满足:&#10;&lt;/p&gt;&#10;$$&#10;BN_r(x) = \gamma_r \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta_r \approx x\\&#10;\mu = \beta_r = \beta_0;\sigma^2 = \gamma_0^2;\gamma_r = \sqrt{\gamma_0^2+\epsilon}&#10;$$&lt;p&gt;&#10;然后在校准集上收集运行时均值和方差更新$\mu,\sigma^2$,需要注意的是$\beta_r,\gamma_r$是不变的，因为不进行反向传播。&lt;/p&gt;&#10;&lt;p&gt;收集到新的均值和方差后，我们重新将BN进行融合，收集到的统计数据可以按以下方式融合回当前的量化尺度：&#10;&lt;/p&gt;&#10;$$&#10;W_i' = W_i\frac{\gamma_r}{\sigma};b_i' = \frac{\gamma_r}{\sigma}(b_i - \mu) + \beta_r;\Delta_{w_i}' = \frac{\gamma_r}{\sigma}\Delta_{w_i}&#10;$$</description></item></channel></rss>