<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hessian on Lorn</title><link>https://july-h5kf3.github.io/tags/hessian/</link><description>Recent content in Hessian on Lorn</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Wed, 26 Aug 2026 08:27:00 +0800</lastBuildDate><atom:link href="https://july-h5kf3.github.io/tags/hessian/index.xml" rel="self" type="application/rss+xml"/><item><title>VLMQ: Efficient Post-Training Quantization for Large Vision-Language Models via Hessian Augmentation</title><link>https://july-h5kf3.github.io/p/vlmq/</link><pubDate>Wed, 26 Aug 2026 08:27:00 +0800</pubDate><guid>https://july-h5kf3.github.io/p/vlmq/</guid><description>&lt;div style="background-color:#f9f9f9; padding:8px; border-radius:6px;"&gt;&#10; &lt;b&gt;个人评价&lt;/b&gt;:文章引出给不同token分配重要性的方式特别好，值得学习！后面的方法就和MBQ，QIG大同小异了&#10;&lt;/div&gt;&#10;&lt;p&gt;文章提出在VLM中，视觉被过度表征是一个被广泛接受的观点，然而目前基于Hessian的PTQ方法没有利用这种冗余性，而我们知道在GPTQ中近似Hessian是通过激活值的内积近似得到的，这就会导致GPTQ等基于Hessian的量化方法直接应用于VLM上时，构建的Hessian矩阵大部分贡献来自于视觉冗余Token，从而表现不佳。因此，给各个Token分配不同的重要性是至关重要的。&lt;/p&gt;&#10;&lt;p&gt;那么视觉token是如何影响Hessian的估计和模型精度的呢？&lt;/p&gt;&#10;&lt;p&gt;论文作者发现：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;在对VLM进行量化时，视觉Token的纳入是必要的&lt;/li&gt;&#10;&lt;li&gt;过量的视觉Token可能会导致量化性能下降，为冗余token赋予较低的重要性，可以缓解由此带来的性能衰退&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;作者对这两个发现给出了一定的解释：&lt;/p&gt;&#10;&lt;p&gt;性能的波动实际上可以归因于Hessian的特征偏移，如下图所示&lt;/p&gt;&#10;&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="784px" data-flex-grow="326" height="408" 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/vlmq/VLMQ_fig1.png" srcset="https://july-h5kf3.github.io/p/vlmq/VLMQ_fig1_hu_8e8273033c57a67c.png 800w, https://july-h5kf3.github.io/p/vlmq/VLMQ_fig1.png 1334w" width="1334"&gt;可以看到，当仅有文本输入时，Hessian矩阵的主成分空间中的分布较为紧凑，而加入了视觉Token后，校准分布变得更加多样化，这有助于缓解量化与推理之间的差距。然而，由于视觉过度表征问题，过量引入视觉 token 会带来 Hessian 向冗余视觉特征偏置的风险（即周围稀疏的点)。&lt;/p&gt;&#10;&lt;p&gt;为了解决这个问题，作者提出了一种面向VLM的精确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;重要性感知的量化目标实际上就是我们先前阅读过的MBQ，QIG等方法使用的量化目标，即Token-Wise的加权。VLMQ的Token重要性通过矩阵形式给出:&lt;/p&gt;&#10;&lt;p&gt;令$G\in \mathbb{R}^{N\times N}$,其中G为对角矩阵，第i个对角元素表示分配给输出token$Z_{:,i}$的重要性。&lt;/p&gt;&#10;&lt;p&gt;将其纳入目标函数后，我们得到了如下改进形式的目标函数：&#10;&lt;/p&gt;&#10;$$&#10;\arg \min_{\hat w} ||(\Delta w X-r)\sqrt{G}||_2^2 \quad s.t. \Delta w e_q^\top +w_q - \hat w_q = 0&#10;$$&lt;p&gt;&#10;利用拉格朗日算子法，我们有：&#10;&lt;/p&gt;&#10;$$&#10;L = ||(\Delta w X -r)\sqrt{G}||_2^2 +\lambda(\Delta w e_q^\top + w_q - \hat w_q)&#10;$$&lt;p&gt;&#10;解得:&#10;&lt;/p&gt;&#10;$$&#10;\Delta w = \frac{\hat w_q - w_q}{\hat H_{qq}^{-1}}\cdot \hat H_{q,:}^{-1} + \hat r \hat X^\top \hat H_{-q,:}^{-1}&#10;$$&lt;p&gt;&#10;其中$\hat H = XGX^\top ,\quad \hat r = r\sqrt{G} ,\quad \hat X = X\sqrt{G}$&lt;/p&gt;&#10;&lt;p&gt;该形式与原始的GPTAQ方式对齐，因此可以复用其中的效率技巧如Cholesky等。&lt;/p&gt;&#10;&lt;p&gt;那么重要性是如何得到的呢？&lt;/p&gt;&#10;&lt;p&gt;参见MBQ中的推导，可以得知，最终使用的是:&#10;&lt;/p&gt;&#10;$$&#10;G = \text{diag}([\overline{|P|}_0,\overline{|P|}_1,\dots,\overline{|P|}_{N-1}])&#10;$$&lt;p&gt;&#10;其中第 n个 token 的重要性定义为梯度中第 n 列的 ℓ1 范数&#10;&lt;/p&gt;&#10;$$&#10;|P|_n = \sum_{i=0}^{C_0 - 1}|P|_{i,n}&#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>[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>Hessian矩阵系列串讲</title><link>https://july-h5kf3.github.io/p/hessian-series/</link><pubDate>Mon, 24 Nov 2025 13:28:52 +0800</pubDate><guid>https://july-h5kf3.github.io/p/hessian-series/</guid><description>&lt;h3 id="定义"&gt;定义&#10;&lt;/h3&gt;&lt;p&gt;假设有一实值函数$f(x_1,x_2,\dots,x_n)$，若$f$的所有二阶偏导数都存在且在定义域里连续，那么我们定义函数$f$的Hessian矩阵为如下一个$n\times n$的方阵:&#10;&lt;/p&gt;&#10;$$&#10;\mathbf{H} = \left[&#10;\begin{matrix}&#10;\frac{\partial^2 f}{\partial x_1^2} &amp; \frac{\partial^2 f}{\partial x_1\partial x_2} &amp; \dots&amp;\frac{\partial^2 f}{\partial x_1 \partial x_n}\\&#10;\frac{\partial^2 f}{\partial x_2 \partial x_1} &amp; \frac{\partial^2 f}{\partial x_2^2} &amp;&#10;\dots&amp; \frac{\partial^2 f}{\partial x_2 \partial x_n}\\&#10;\vdots &amp; \vdots &amp; \ddots &amp; \vdots\\&#10;\frac{\partial^2 f}{\partial x_n \partial x_1} &amp; \frac{\partial^2 f}{\partial x_n \partial x_2} &amp; \dots &amp; \frac{\partial^2 f}{\partial x_n^2}&#10;\end{matrix}&#10;\right]&#10;$$&lt;p&gt;或使用下标标记表示为:&#10;&lt;/p&gt;&#10;$$&#10;\mathbf{H}_{ij} = \frac{\partial^2 f}{\partial x_i \partial x_j}&#10;$$&lt;h3 id="一般性质"&gt;一般性质&#10;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;对称性&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;p&gt;对于机器学习中遇到的大多数函数(特别是那些具有连续二阶偏导数的函数),混合偏导数的求导顺序无关紧要。这被称为克莱罗定理或施瓦茨定理,它说明了混合偏导数的相等性:&#10;&lt;/p&gt;&#10;$$&#10;\frac{\partial^2 f}{\partial x_i\partial x_j} = \frac{\partial^2 f}{\partial x_j \partial x_i}&#10;$$&lt;p&gt;&#10;这意味着Hessian矩阵是对称的，即$\mathbf{H} = \mathbf{H}^\top$&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;正定性与局部最优值的相关性&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;通过Hessian矩阵的正定性，我们可以判断该点是局部最小值，局部最大值还是鞍点&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;正定:若Hessian矩阵$H(x^*)$是正定的(意味着$\forall v \neq 0,v^\top\mathbf{H}v&gt;0$)，则函数在$x^*$处有局部最小值。函数在该点周围向所有方向向上弯曲，类似于碗的底部&lt;/li&gt;&#10;&lt;li&gt;负定:若Hessian矩阵$H(x^{*})$是负定的(意味着$\forall v \neq 0,v^\top\mathbf{H}v&lt;0$),则函数在$x^*$处有局部最大值。函数在该点周围向所有方向向下弯曲，类似于圆顶的顶部&lt;/li&gt;&#10;&lt;li&gt;不定:若Hessian矩阵$H(x^{*})$是不定的,则函数在$x^*$处有鞍点。函数在某些方向向上弯曲，在另一些方向向下弯曲，就像马鞍&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="hessian在神经网络中的计算"&gt;Hessian在神经网络中的计算&#10;&lt;/h3&gt;&lt;p&gt;Hessian矩阵在神经网络计算的许多方面有着重要作用，包括:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;⼀些⽤来训练神经⽹络的⾮线性最优化算法是基于误差曲⾯的⼆阶性质的，这些性质&lt;/p&gt;&#10;&lt;p&gt;由Hessian矩阵控制(比如牛顿法和拟牛顿法)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;对于训练数据的微⼩改变，Hessian矩阵构成了快速重新训练前馈⽹络的算法的基础&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Hessian矩阵的逆矩阵⽤来鉴别神经⽹络中最不重要的权值，这是⽹络“剪枝”算法的⼀部分(LeCun的OBD)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;对于Hessian矩阵的众多应用而言，一个重要的需要考虑的问题是计算效率。在神经网络中有$W$个参数(包括权值和偏置),那么Hessian矩阵的大小就是$W\times W$,那么计算Hessian矩阵的计算量为$O(W^2)$。这在具有大量参数的神经网络中是难以接受的，因此我们需要进行一些高效的近似。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;对角近似&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;这个方法最早由Yan LeCun在OBD剪枝方法中提出&lt;/p&gt;&#10;&lt;p&gt;我们只保留Hessian矩阵的对角线元素$H_{i,i}$，把非对角线元素置为0.(这个方法在很大程度可以可以方便求逆)&lt;/p&gt;&#10;&lt;p&gt;对于神经网络中的第j个神经元的输入$a_j$对应权重为$w_{ji}$:&#10;&lt;/p&gt;&#10;$$&#10;\frac{\partial^2 E_n}{\partial w_{ji}^2} = \frac{\partial^2 E_n}{\partial a_j^2}z_i^2&#10;$$&lt;p&gt;&#10;其中$z_i$是上一层神经元的输出。&lt;/p&gt;&#10;&lt;p&gt;而$\frac{\partial^2 E_n}{\partial a_j^2}$可以通过链式法则递归计算(类似于反向传播):&#10;&lt;/p&gt;&#10;$$&#10;\frac{\partial^2 E_n}{\partial a_j^2} = \underbrace{\frac{\partial}{\partial a_j}[h'(a_j)\sum_{k}w_{kj}\frac{\partial E_n}{\partial a_k}]}_{链式法则}=h'(a_j)^2 \sum_{k,k'}w_{kj}w_{k'j}\frac{\partial^2 E_n}{\partial w_k\partial w_{k'}} + h''(a_j)\sum_k w_{kj}\frac{\partial E_n}{\partial a_n}&#10;$$&lt;p&gt;&#10;忽略二阶导中的非对角线项$k\neq k'$:&#10;&lt;/p&gt;&#10;$$&#10;\frac{\partial^2 E_n}{\partial a_j^2}\approx \underbrace{h'(a_j)^2\sum_k w_{kj}^2 \frac{\partial^2 E_n}{\partial a_k^2}}_{链式法则} + \underbrace{h''(a_j)\sum_{k}w_{kj}\frac{\partial E_n}{\partial a_k}}_{链式法则}&#10;$$&lt;p&gt;&#10;从而一次反向传播便可以计算出来，时间复杂度为$O(W)$&lt;/p&gt;&#10;&lt;p&gt;但是如你所见，在这个方法下，Hessian矩阵完全退化为了一个diag，这在神经网络中是不合理的，因为非线性层的引入会让Hessian矩阵的交叉项不为0，更重要的是这种误差会随着网络层数的堆砌不断放大。&lt;/p&gt;&#10;&lt;p&gt;因此针对这个问题在对角近似上近年来不断有相关文章发表，下面对我阅读过的一些进行简单介绍:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;HesScale:在LeCun的方法的骨架上，针对常见网络的最后一层的softmax+CE结构可以通过一个简单的公式求出diag(H)的精确值:&#10;&lt;/p&gt;&#10;$$&#10; \frac{\partial^2 E_n}{\partial^2 a_j^2} = p - p\circ p&#10; $$&lt;p&gt;&#10;其中p为$\text{softmax}(a_j)$,$\circ$表示向量的逐元素乘积,为方便书写我们将$\{a_1,\dots,a_n\}$写作z&lt;/p&gt;&#10;&lt;p&gt;证明如下:&lt;/p&gt;&#10;&lt;p&gt;​&#9;预测$\mathbf{p} = \text{softmax}(z)$,即$p_i = \frac{\exp(z_i)}{\sum_{j = 1}^k \exp(z_j)}$,设目标分布为$t\in \Delta^{K-1},\sum_{i}t_i = 1$，对于单样本而言，其损失可以写作:&#10;&lt;/p&gt;&#10;$$&#10; \mathcal{L}(z) = -\sum_{j=1}^Kt_i\log p_i = -t^\top z + \log \sum_{j=1}^K \exp(z_j)&#10; $$&lt;p&gt;&#10;求一阶导我们有:&#10;&lt;/p&gt;&#10;$$&#10; \nabla_z \mathcal{L} = -t + \nabla_z \log \sum_{j=1}^K \exp{z_j} = -t + \mathbf{p}&#10; $$&lt;p&gt;&#10;求二阶导相当于$\mathbf{p}$对z求导。我们知道$\text{softmax}$的Jocobian为&#10;&lt;/p&gt;&#10;$$&#10; \frac{\partial p_i}{\partial z_j} = p_i(\delta_{ij} - p_j),J_{\text{softmax}}(z) = \text{diag}(\mathbf{p}) - \mathbf{p}\mathbf{p}^\top &#10; $$&lt;p&gt;&#10;其中$\delta_{i,j}$为Kronecker函数，写成矩阵形式，则只有对角线元素为1，其余为0.&lt;/p&gt;&#10;&lt;p&gt;因此我们有:&#10;&lt;/p&gt;&#10;$$&#10; \nabla^2_z\mathcal{L} = \text{diag}(\mathbf{p}) - \mathbf{pp}^\top&#10; $$&lt;p&gt;&#10;于是我们可以得到:&#10;&lt;/p&gt;&#10;$$&#10; \frac{\partial^2 L}{\partial^2 a_j} = p_j(1-p_j)&#10; $$&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;AdaHessian:&lt;/p&gt;&#10;&lt;p&gt;具体而言，AdaHessian在进行Hessian矩阵的对角近似的时候利用了Hutchinson估计，它通常也被用来对矩阵的迹进行估计:&lt;/p&gt;&#10;&lt;p&gt;​&#9;对任意矩阵$\mathbf{A}\in\mathbb{R}^{d\times d}$,若随机向量$z = (z_1,\dots,z_d)^\top$满足:&#10;&lt;/p&gt;&#10;$$&#10; \mathbb{E}[z_i] = 0\\&#10; \mathbb{E}[z_iz_j] = \delta_{ij}&#10; $$&lt;p&gt;&#10;​&#9;那么有:&#10;&lt;/p&gt;&#10;$$&#10; \mathbb{E}[z\odot (Az)] = \text{diag}(A)&#10; $$&lt;p&gt;&#10;​&#9;下面进行证明:&lt;/p&gt;&#10;&lt;p&gt;​&#9;&#9;记估计量$d = z\odot (Az)$的第i个分量:&#10;&lt;/p&gt;&#10;$$&#10; d_i = z_i(Az)_i = z_i\sum_{j=1}^d A_{ij}z_j = \sum_{j = 1}^d A_{ij}z_iz_j\\&#10; \mathbb{E}[d_i] = \sum_{j=1}^dA_{ij}\mathbb{E}[z_iz_j] = \sum_{j=1}^d A_{ij}\delta_{ij} = A_{ii}&#10; $$&lt;p&gt;&#10;​&#9;&#9;由此我们证明了$\mathbb{E}[z\odot(Az)] = \text{diag}(A)$&lt;/p&gt;&#10;&lt;p&gt;在神经网络中，相较于直接计算完整的Hessian矩阵以及其OBD方式的对角近似，计算其矩阵向量积(HVP,Hessian Vector product)是并不困难的，它只需要一次反向传播：&#10;&lt;/p&gt;&#10;$$&#10; Hz = \frac{\partial (g^\top z)}{\partial \theta} = \frac{\partial g^\top}{\partial \theta}z + g^\top \frac{\partial z}{\partial \theta} = \frac{\partial g^\top}{\partial \theta}z&#10; $$&lt;p&gt;&#10;由此，我们可以通过多次在满足Rademacher分布的向量取样计算$z\odot (Az)$的期望就能得到$\text{diag}(A)$的&lt;strong&gt;无偏估计&lt;/strong&gt;，在实际的应用中，只进行一次取样就能得到较为不错的结果。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;strong&gt;外积近似&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;在神经网络应用于回归问题时，通常采用下面形式的平方和误差&#10;&lt;/p&gt;&#10;$$&#10;E = \frac{1}{2}\sum_{n=1}^N(y_n-t_n)^2&#10;$$&lt;p&gt;&#10;​&#9;那么Hessian矩阵可以写成如下形式:&#10;&lt;/p&gt;&#10;$$&#10;H = \nabla\nabla E = \nabla(\sum_{n=1}^N (y_n-t_n)\nabla y_n) = \sum_{n = 1}^N \nabla y_n(\nabla y_n)^\top + \sum_{n=1}^N(y_n-t)\nabla\nabla y_n&#10;$$&lt;p&gt;&#10;​&#9;在网络已经训练好的情况下，输出$y_n$与$t_n$接近，因此第二项可以忽略，由此我们得到了Hessian矩阵的外积近似&#10;&lt;/p&gt;&#10;$$&#10;H\approx \sum_{n=1}^N b_n b_n^\top&#10;$$&lt;p&gt;&#10;​&#9;其中，$b_n = \nabla y_n = \nabla a_n$(输出单元的激活函数就是恒等函数)。这种方法中的Hessian矩阵可以跟随反向传播算法在$O(W)$个步骤内高效地求出误差函数地一阶导数。再通过简单地乘法就可以在$O(W^2)$步骤内求出矩阵元素。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Hessian矩阵逆的计算&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;使用外积近似，我们可以提出一个计算Hessian矩阵的逆的高效办法,首先我们有:&#10;&lt;/p&gt;&#10;$$&#10;\mathbf{H}_N = \sum_{i=1}^n b_n b_n^\top&#10;$$&lt;p&gt;&#10;其中，$b_n = \nabla w a_n$时数据点n产生的输出单元激活对梯度的贡献。我们现在推导一个建立Hessian矩阵的顺序步骤，每次处理一个数据点。假设我们已经使用了前L个数据点得到了Hessian矩阵的逆。通过将第L+1个数据点的贡献单独写出来，我们有:&#10;&lt;/p&gt;&#10;$$&#10;\mathbf{H}_{L+1} = \mathbf{H}_L + b_{L+1}b_{L+1}^\top&#10;$$&lt;p&gt;&#10;为了计算Hessian矩阵的逆，我们考虑下面这个矩阵的恒等式:&#10;&lt;/p&gt;&#10;$$&#10;(M + vv^\top)^{-1} = M^{-1} - \frac{(M^{-1}v)(v^\top M^{-1})}{1+v^\top M^{-1}v}&#10;$$&lt;p&gt;&#10;若我们令$H_L = M$,且$b_{L+1} = v$,我们有:&#10;&lt;/p&gt;&#10;$$&#10;H_{L+1}^{-1} = H_{L}^{-1} - \frac{H_L^{-1}b_{L+1}b_{L+1}^\top H_{L}^{-1}}{1 + b_{L+1}^\top H_L^{-1}b_{L+1}}&#10;$$&lt;p&gt;&#10;通过这种方式，数据点可以依次使用，直到L+1=N,整个数据集处理完毕。于是，这个结果表示一个计算Hessian矩阵的逆的算法。这个算法只需对数据集扫描一次。最开始的矩阵$\mathbf{H_0}$被选为$\alpha I$,其中$\alpha$是一个较小的量，从而算法实际找的是$\mathbf{H} + \alpha I$的逆。结果对于$\alpha$的精确值不敏感。&lt;/p&gt;&#10;&lt;p&gt;​&#9;&lt;strong&gt;Hessian矩阵的逆计算的K-FAC分解方法&lt;/strong&gt;：&lt;/p&gt;&#10;&lt;p&gt;​&#9;在特定场景下，Hessian矩阵的逆有一个利用Kronecker分解的近似方法，它利用了在loss为log-like形式下$\mathbb{E}[H] = F$的特点，其中$F$为Fisher信息矩阵:&#10;&lt;/p&gt;&#10;$$&#10;F = \mathbb{E}[\nabla \log p(x)\nabla \log p(x)^\top]&#10;$$&lt;p&gt;&#10;其中上式中做了如下形式的简写:&#10;&lt;/p&gt;&#10;$$&#10;\nabla \log{p(x)} = \nabla_\theta \log{(p|\theta)}\\&#10;\mathbb{E}[p(x)] = E_{x\sim p(x|\theta)}&#10;$$&lt;p&gt;&#10;首先我们有:&#10;&lt;/p&gt;&#10;$$&#10;\mathbb{E}[\nabla \log p(x)] = \int (\nabla \log p(x))p(x) dx\\&#10;=\int \frac{\nabla \log p(x)}{p(x)}p(x) dx\\&#10;=\int \nabla \log p(x)dx\\&#10;=\nabla 1 = 0&#10;$$&lt;p&gt;&#10;那么当loss为log-like形式下时:&#10;&lt;/p&gt;&#10;$$&#10;L = -\log p(x)&#10;$$&lt;p&gt;&#10;我们求它的Hessian:&#10;&lt;/p&gt;&#10;$$&#10;\nabla^2 L = -\nabla^2 \log p(x)\\&#10;=-\nabla \frac{\nabla p(x)}{p(x)}\\&#10;=\frac{\nabla p(x)}{p(x)}^\top \frac{\nabla P(x)}{p(x)} - \frac{P(x)^2}{p(x)}\\&#10;=\nabla \log p(x)^\top \nabla \log p(x) - \frac{\nabla^2 P(x)}{p(x)}&#10;$$&lt;p&gt;&#10;对该式求期望，我们有:&#10;&lt;/p&gt;&#10;$$&#10;\mathbb{E}[H]=\mathbb{E}[\nabla \log p(x)^\top \nabla \log p(x)] - \mathbb{E}[\frac{\nabla^2 p(x)}{p(x)}] = F - \int \frac{\nabla^2 p(x)}{p(x)} p(x) dx\\&#10;=F - \int \nabla^2 p(x)dx\\&#10;=F - \nabla^2 \int p(x)\\&#10;=F&#10;$$&lt;p&gt;&#10;由于$\theta$本质为所有层$\mathbf{W}$的拼接，我们有:&#10;&lt;/p&gt;&#10;$$&#10;d\theta = \nabla_{\theta}L(x)\\&#10;F = \mathbb{E}[\nabla L(x)\nabla L(x)^\top] = \mathbb{E}[d\theta d\theta^\top]\\&#10;\theta = [\text{vec}(W_0)^\top,\text{vec}(W_1)^\top,\dots,\text{vec}(W_n)^\top]^\top&#10;$$&lt;p&gt;&#10;带入展开得到:&#10;&lt;/p&gt;&#10;$$&#10;F_{ij} = \mathbb{E}[\text{vec}(dW_i)\text{vec}(dW_j)^\top]&#10;$$&lt;p&gt;&#10;令$a_i,g_i$分别为第i层的前向输入和反向传播梯度，由反向传播算法有:&#10;&lt;/p&gt;&#10;$$&#10;d W_i = g_ia_i^\top&#10;$$&lt;p&gt;&#10;带入有:&#10;&lt;/p&gt;&#10;$$&#10;\text{vec}(dW_i) = \text{vec}(g_ia_i^\top) = a_i\otimes g_i&#10;$$&lt;p&gt;&#10;这里可能不太直观，这是因为平常对kronecker积($\otimes$)的接触较少，具体而言，我们这样定义Kronecker积:&#10;&lt;/p&gt;&#10;$$&#10;A\otimes B = \left[&#10;\begin{matrix}&#10;a_{11}B &amp;\dots &amp;a_{1n}B\\&#10;\vdots &amp; \ddots&amp; \vdots\\&#10;a_{m1}B &amp; \dots &amp; a_{mn}B&#10;\end{matrix}&#10;\right]&#10;$$&lt;p&gt;&#10;在这里，由于我们将$dW_i$即$\nabla W_i$第i层参数的梯度进行了向量化，原本的$\nabla W_i$ 是如下形式:&#10;&lt;/p&gt;&#10;$$&#10;\nabla W_i = g_i a_{i}^\top = \left[\begin{matrix}g_1a_1 &amp; \dots &amp;g_1a_n\\ \vdots &amp; \ddots &amp; \vdots\\ g_ma_1 &amp;\dots&amp;g_ma_n\end{matrix} \right]&#10;$$&lt;p&gt;&#10;按列堆叠(vec)就有:&#10;&lt;/p&gt;&#10;$$&#10;\text{vec}(dW_i) = \left[&#10;\begin{matrix}&#10;g_1a_1\\&#10;\vdots\\&#10;g_1a_n\\&#10;\vdots\\&#10;g_ma_n&#10;\end{matrix}&#10;\right] = a_i\otimes g_i&#10;$$&lt;p&gt;&#10;那么我们可以将Fisher矩阵写作如下形式:&#10;&lt;/p&gt;&#10;$$&#10;F_{ij} = \mathbb{E}[\text{vec}(dW_i)\text{vec}(dW_j)]\\&#10;=\mathbb{E}[(a_i\otimes g_i)(a_j\otimes g_j)^\top]\\&#10;=\mathbb{E}[(a_ia_j^\top)\otimes (g_ig_j^\top)]\\&#10;\approx \mathbb{E}[a_ia_j^\top]\otimes\mathbb{E}[g_ig_j^\top]&#10;$$&lt;p&gt;&#10;这个近似相当于我们忽略了$\text{Cov}_\otimes(a_ia_j^\top,g_ig_j^\top)$,这实际上是合理的，尤其是在网络较深的情况下。这里给出一个&lt;a class="link" href="https://truenobility303.github.io/KFAC/" target="_blank" rel="noopener"&#10; &gt;链接&lt;/a&gt;提供一个比较详细的说明。&lt;/p&gt;&#10;&lt;p&gt;虽然直接求$F_{ij}$的复杂度仍然不变，但是利用Kronecker积的性质，我们在求逆时可以得到较大的性能提升:&#10;&lt;/p&gt;&#10;$$&#10;(A\otimes B)^{-1} = A^{-1}\otimes G^{-1}&#10;$$&lt;p&gt;&#10;并且在实际运算中，并不是整个网络的Fisher进行计算，而是按层做块对角运算:&#10;&lt;/p&gt;&#10;$$&#10;\mathbf{F} = \text{blockdiag}(F_1,F_2,\dots),F_l\approx A_l\otimes G_l&#10;$$&lt;p&gt;&#10;这样每层求逆的时候只需要求两个小矩阵的逆。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;一些统计量的计算&lt;/strong&gt;：&lt;/p&gt;&#10;&lt;p&gt;​&#9;除了直接对Hessian矩阵的近似计算，我们有时候仅仅需要对Hessian矩阵的统计量进行计算，例如矩阵的迹，最大特征值等。&lt;/p&gt;&#10;&lt;p&gt;​&#9;在计算这些统计量时，我们需要一个重要的算子:Hv,即Hessian矩阵与任意向量的乘积，这个乘积我们在上面已经证明了通过一次简单的反向传播算法可以得到。(PyHessian是一个Python库，它实现了这个算子的高效计算)&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;顶部若干特征值&lt;/p&gt;&#10;&lt;p&gt;利用幂迭代法 + HVP可以高效地求解特征值。&lt;/p&gt;&#10;&lt;p&gt;简单来说幂迭代法的流程很简单:&lt;/p&gt;&#10;&lt;p&gt;给定矩阵A以及初始非零向量$x_0$,&lt;/p&gt;&#10;&lt;p&gt;迭代:&#10;&lt;/p&gt;&#10;$$&#10; y_{k+1} = Ax_k\\&#10; x_{k+1} = \frac{y_{k+1}}{||y_{k+1}||}\\&#10; \mu_{k+1} = \frac{x_{k+1}Ax_{k+1}^\top}{x_{k+1}x_{k+1}^\top}&#10; $$&lt;p&gt;&#10;具体的收敛性证明见&lt;a class="link" href="https://link.zhihu.com/?target=https%3A//ergodic.ugr.es/cphys/lecciones/fortran/power_method.pdf" target="_blank" rel="noopener"&#10; &gt;教材&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;矩阵的迹&lt;/p&gt;&#10;&lt;p&gt;在上面近似计算中，我们曾用Hutchinson估计对Hessian矩阵进行了对角近似，事实上，我们还可以进行迹的估计。&lt;/p&gt;&#10;&lt;p&gt;简单来说，方法一样，从Rademacher分布中取一随机向量$v$,然后有恒等式:&#10;&lt;/p&gt;&#10;$$&#10; \text{Tr}(H) = \text{Tr}(HI) = \text{Tr}(H\mathbb{E}[vv^\top]) = \mathbb{E}[\text{Tr}(Hvv^\top)] = \mathbb{E}[v^\top H v]&#10; $$&lt;h3 id="hessian矩阵在神经网络下的特殊结构"&gt;Hessian矩阵在神经网络下的特殊结构&#10;&lt;/h3&gt;&lt;p&gt;本小节内容主要基于&lt;a class="link" href="https://arxiv.org/pdf/2505.02809" target="_blank" rel="noopener"&#10; &gt;Towards Quantifying the Hessian Structure of Neural Networks&lt;/a&gt;,B站上有作者的讲解视频&lt;a class="link" href="https://www.bilibili.com/video/BV1To3TzmEX3/?spm_id_from=333.1387.homepage.video_card.click&amp;amp;vd_source=76e54ba50c020fb612c90d28c211c638" target="_blank" rel="noopener"&#10; &gt;[FAI] 港中深 张雨舜 | 浅谈神经网络Hessian矩阵的特殊结构&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;​&#9;这篇文章主要说明了在神经网络中，Hessian矩阵往往具有近块对角结构，这表明曲率信息(二阶信息)主要在层内耦合，层与层的二阶交互很弱。这间接的说明了Layer-wise的量化/剪枝的合理性。&lt;/p&gt;&#10;&lt;p&gt;​&#9;此外，文章还进一步从理论和实验上阐释了造成这个现象的原因：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;静态力量:即使在随机初始化阶段，即在训练开始之前，神经网络的Hessian矩阵就已经呈现出近块对角结构。这种结构的形成与网络的架构设计有关，因此被称为“静态力量”。具体来说，对于线性模型和单隐藏层网络，无论是使用均方误差（MSE）损失还是交叉熵（CE）损失，Hessian矩阵的对角块和非对角块在随机初始化时就已经表现出明显的差异。&lt;/li&gt;&#10;&lt;li&gt;动态力量:在训练过程中，Hessian矩阵的结构会进一步发生变化。特别是在使用CE损失时，训练过程会逐渐消除初始时存在于跨层Hessian分量（Hwv）中的“块循环”（block-circulant）模式，而对角块和非对角块的近块对角结构则保持稳定。这种由训练过程引起的结构变化被称为“动态力量”。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;另外一点，文章证明了类别数C是影响Hessian矩阵结构的主要因素。(在实验中，隐藏层Hessian的非对角块与对角块的比值以$\frac{1}{\sqrt{C}}$的速度衰减，输出层Hessian的衰减速率为$\frac{1}{C}$).这个结果对于大模型而言是友好的，因为在神经网络中C的大小往往是$1e3\sim 1e4$级别的，这说明大模型的Hessian是具有强对角块的结构的！这一点实际上在传统的方法上人们意识or无意识的用到了(对角近似)，但是更丰富层面以及基于这个发现的在计算的可行性和性能的Trade-off做的工作是比较少的，在优化器那边做的比较多。&lt;/p&gt;&#10;&lt;p&gt;此外还有不少文献揭露了Hessian矩阵具有低秩特征谱，即只有少数的特征值显著大，其余大多接近0.&lt;/p&gt;&#10;</description></item></channel></rss>