从 Smooth Quant 到 SVD Quant
最近在尝试给公司的 DiT 生图模型做推理加速的过程中,了解到 SVDQuant 这种较新的扩散模型量化方案,在此记录一下学习心得。
首先需要明确的是,LLM 由于瓶颈通常在于 decode 部分的权重搬运,所以只量化权重就能拿到性能收益;但 diffusion model 往往是 compute bound,想加速是绕不开激活量化的,同时对权重和激活进行量化会带来很多精度挑战。
Smooth Quant(W8A8)
Smooth Quant 可以看作是 SVDQuant 的科技树前置,它本身是对静态量化方案的一种改进。
W8A8 面临的主要问题是激活的 outlier 带来的精度损失,一个离群值会导致 block 内的其他正常值全部被映射到 zero point 附近,从而失去彼此之间的差异。Smooth Quant 的提出者统计了激活的 outlier 分布,他们发现离群值的分布并不是随机的,而是固定在少数几个 channel 中:
基于这一现象,他们进一步提出,可以给激活的每个 channel 寻找一个缩放因子,然后通过下面的运算把 outlier 带来的影响转移到权重中:
其中第 j 个 channel 的缩放因子通过下面的公式计算得到:
$\alpha$ 是一个超参,用来分配 W 和 A 之间的量化难度,论文中提到:
$\alpha=0.5$ is a general sweet spot for all the OPT and BLOOM models, and $\alpha=0.75$ for GLM-130B since its activations are more difficult to quantize.
SVDQuant(W4A4)
Smooth Quant 本质是把激活的 outlier 影响部分转移到权重侧承担,这种方案在 W8A8 的场景下被证实是有效的。
当量化推进到 4 bit 领域后,权重和激活的表示范围都只有 16 个值,此时权重也无法再承担激活的 outlier,于是 Smooth Quant 的提出者另辟蹊径,又提出了基于 SVD 分解的量化方案。
SVD 分解
SVD(Singular Value Decomposition,奇异值分解)本身是线性代数中的一种运算。我们知道任意矩阵 $A\in\R^{M\times N}$ 都可以写成如下形式:
其中:
- $U\in\R^{M\times M}$ 是 $AA^T$ 的特征向量构成的正交矩阵;
- $V\in\R^{N\times N}$ 是 $A^TA$ 的特征向量构成的正交矩阵;
- $\Sigma\in\R^{M\times N}$ 对角线上的元素称为奇异值,从大到小排列,其余元素为 0。奇异值是 $AA^T$ 特征值的平方根;
SVD 分解可以把一个矩阵拆分成若干秩为 1 的矩阵之和,这种思想本质上类似于傅里叶变换。
低秩矩阵的奇异值谱会出现快速的下降,所以可以通过 SVD 截断对这种矩阵进行压缩。
量化方案
还是基于前面提到的经验事实:激活的 outlier 会集中分布在几个 channel 中。
SVDQuant 的第一步是利用 Smooth Quant 中的方案将激活的 outlier 全部抹平到权重,这会让激活变得易于量化,但会让权重中的特定列被明显放大。
接下来对已被缩放因子影响的权重做 SVD 分解。由于权重的特定列已被放大(变得低秩),所以可以做 SVD 截断将其分为低秩分支(论文中默认截断前 32 个 rank)和残差:
“特定列被放大”这件事可以让残差 $R$ 中的 outlier 更少、更小,这正是量化最关心的问题。因此,对残差做 4 bit 量化,而低秩分支保持 16 bit 这种方案就能够 work。
从下图中可以看到,经过处理的激活和残差中 outlier 都明显变少、变小,利于量化:
总结
Smooth Quant 和 SVD Quant 都是面向激活量化的算法,而激活量化本身对于 compute bound 的模型来说是非常重要的一环。从硬件发展趋势的角度来看,4 bit 量化大概会渐渐成为主流方案,所以 SVD Quant 还是很有必要被好好实现、改进的。