全部术语

GLOSSARY ENTRY

GPTQ、AWQ、SmoothQuant 与 FP8 的方法边界

  • GPTQ
  • AWQ
  • SmoothQuant
  • FP8

GPTQ/AWQ 主要面向低比特 weight-only 的误差补偿与显著通道保护,SmoothQuant 通过等价通道缩放把 activation outlier 难度迁移到权重,FP8 则是浮点格式与 scaling/累加体系;名称不能替代具体 checkpoint、kernel 和校准配置。

先定位到量化基础的哪一层

推理量化基础定义 q,s,zq,s,z、granularity、weight-only 与 W8A8;本页只解释几类方法如何选择/变换这些表示,不把品牌名当统一格式。

方法主要对象核心思想推理时仍需什么
GPTQ低比特 weight-only,常见 INT4用 calibration/Hessian 近似按列/块量化并补偿后续权重误差packed weights、group scales/zeros、匹配 GEMM/GEMV kernel
AWQ低比特 weight-only用 activation 统计识别 salient weight channels,并搜索缩放使它们更耐量化缩放后的 packed checkpoint + 支持对应 layout 的 kernel
SmoothQuantW8A8 activation+weight等价通道缩放,把 activation outlier 难度迁移到 weightsactivation quantization、INT8 kernel、校准 scale 与模型变换
FP8权重/activation/KV 的低精度浮点格式族E4M3/E5M2 等 exponent/mantissa tradeoff,配合 tensor/channel scaling 与更高精度累加GPU/backend 格式支持、scale recipe、amax history/校准、accumulator

SmoothQuant:用等价缩放迁移 outlier

线性层:

Y=XWY=XW

对 hidden/input channel 选择正 scale sRKs\in\mathbb{R}^{K}

X=Xdiag(s)1,W=diag(s)WX'=X\operatorname{diag}(s)^{-1},\qquad W'=\operatorname{diag}(s)W

则未量化时:

XW=Xdiag(s)1diag(s)W=XWX'W'=X\operatorname{diag}(s)^{-1}\operatorname{diag}(s)W=XW

SmoothQuant 常由 calibration activation max aja_j 与 weight max wjw_j 选择:

sj=ajαwj1αs_j=\frac{a_j^\alpha}{w_j^{1-\alpha}}

α\alpha 控制把量化难度从 activation 移到 weight 的程度。它不是“让误差消失”;变换后权重某些 channels 变大,W8A8 的两边误差与 kernel scale granularity共同决定结果。Scale 可 fold 到前一 norm/weight 或保存在转换后的 checkpoint,必须避免部署时重复应用。

本页构造 X:[64,8]X:[64,8],令 activation channel 0/1 分别含 40×/10× outliers。alpha=0.5alpha=0.5 后未量化输出最大差仅浮点级 1.907e-06;per-tensor W8A8 fake quant MAE 从 0.453008 降至 0.029458。这是教学反例,不能推广成真实模型精度保证。

GPTQ:逐步量化并用二阶近似补偿

给 calibration inputs XX,常见目标是最小化层输出重构误差:

minW^XWXW^22\min_{\hat W}\lVert XW-X\hat W\rVert_2^2

其曲率近似与 HXTXH\propto X^\mathsf TX 相关。GPTQ 类算法按列/块量化某部分权重后,利用 inverse-Hessian 信息更新尚未量化权重,补偿已引入误差。核心不是简单 round(W/s),而是顺序、分组与误差传播

本页不实现完整 GPTQ:稳定 Cholesky/inverse、damping、block updates、act-order、packing 都会使示例超过一个可靠术语实验。生产正确性应验证转换 checkpoint 的 layer outputs/perplexity 与 loader/kernel schema,而不是只打印权重 MSE。

成本主要在离线 calibration/quantization;推理 payload 可接近 INT4+metadata,但真实速度依赖 low-bit kernel。小 batch decode 更可能受权重带宽收益,prefill 大 GEMM 则受 dequant/Tensor Core path 影响。

AWQ:activation-aware 的 salient channel 保护

仅看每个 weight channel 的平均 quantization error,可能把业务重要性判断错。若 calibration activation 第 jj 通道幅值/能量很大,小权重误差也会被放大到输出:

ΔY=XΔW\Delta Y=X\Delta W

粗略 channel salience 可用 E[Xj2]E[X_j^2] 加权:

IjE[Xj2]E[(ΔWj)2]I_j\propto E[X_j^2]\cdot E[(\Delta W_j)^2]

AWQ 使用 activation 分布寻找少量 salient weights/channels,并通过 per-channel scaling 降低低比特误差,而不是把这些 weights 永久保留为 FP16 的唯一策略。具体搜索、clipping、grouping 以实现为准。

实验里仅看权重误差时最差 input channel 是 2;乘 calibration activation energy 后最差变为 outlier channel 0。这个结果只证明“activation-aware 排序可能不同”,不是 AWQ 完整复现。

FP8:格式/scale recipe,不是 INT8 的别名

FP8 保留 sign、exponent、mantissa,常见 E4M3 与 E5M2 在动态范围/精度间取舍。与整数 affine quantization 不同,FP8 值本身有浮点编码,但生产仍常使用外部 scale:

xfp8=castF8(x/s),x^=sxfp8x_{fp8}=\operatorname{cast}_{F8}(x/s),\qquad \hat x=s\cdot x_{fp8}
  • E4M3 通常精度较高、范围较窄;E5M2 范围更大、精度更低,具体 finite/NaN 语义依标准/硬件格式。
  • GEMM 通常以更高精度累加,输出/epilogue dtype 另定。
  • Dynamic scaling 要计算/更新 amax,增加 reduction/state;static scale 依赖 calibration 覆盖分布。
  • GPU generation/backend 若无 native FP8 path,可能 cast/fallback,文件更小但算子不快。

FP8 weights、W8A8 activations 与 FP8 KV cache 是不同路径;不能从模型“FP8”标签推断所有 tensors 都是 8-bit 或统一 scale。

可运行的等价缩放与 salience 实验

import platform,torch

torch.manual_seed(239)
DEVICE=torch.device("cuda" if torch.cuda.is_available() else "cpu")

def fake_quant_per_tensor(x,qmax=127):
    scale=x.abs().amax().clamp_min(1e-8)/qmax
    return torch.round(x/scale).clamp(-qmax,qmax)*scale

def main():
    tokens,hidden,output=64,8,6
    x=torch.randn(tokens,hidden,device=DEVICE); x[:,0]*=40; x[:,1]*=10
    weight=torch.randn(hidden,output,device=DEVICE); weight[0]*=.08; weight[1]*=.2
    reference=x@weight
    activation_max=x.abs().amax(0).clamp_min(1e-8)
    weight_max=weight.abs().amax(1).clamp_min(1e-8)
    alpha=.5; smooth_scale=activation_max.pow(alpha)/weight_max.pow(1-alpha)
    x_smooth=x/smooth_scale; weight_smooth=weight*smooth_scale[:,None]
    torch.testing.assert_close(x_smooth@weight_smooth,reference,rtol=1e-5,atol=1e-5)

    baseline=fake_quant_per_tensor(x)@fake_quant_per_tensor(weight)
    smoothed=fake_quant_per_tensor(x_smooth)@fake_quant_per_tensor(weight_smooth)
    baseline_mae=(baseline-reference).abs().mean()
    smoothed_mae=(smoothed-reference).abs().mean()
    assert smoothed_mae<baseline_mae

    calibration=torch.randn(tokens,hidden,device=DEVICE); calibration[:,0]*=20
    importance=calibration.square().mean(0)
    step=weight.abs().amax()/7
    rounded=torch.round(weight/step).clamp(-7,7)*step
    quant_error=(rounded-weight).square()
    unweighted=quant_error.mean(1)
    weighted=(quant_error*importance[:,None]).mean(1)
    assert int(weighted.argmax())!=int(unweighted.argmax())
    print(f"python={platform.python_version()} torch={torch.__version__}")
    print(f"device={DEVICE} X={tuple(x.shape)} W={tuple(weight.shape)} alpha={alpha}")
    print(f"smooth_equivalence_max_abs_diff={(x_smooth@weight_smooth-reference).abs().max():.3e}")
    print(f"baseline_W8A8_fake_quant_MAE={baseline_mae:.6f}")
    print(f"smoothed_W8A8_fake_quant_MAE={smoothed_mae:.6f}")
    print(f"activation_range_before_max={activation_max.max():.3f} after_max={x_smooth.abs().amax(0).max():.3f}")
    print(f"unweighted_worst_input_channel={int(unweighted.argmax())} activation_weighted_worst_channel={int(weighted.argmax())}")
    print(f"importance={importance.tolist()}")

if __name__=="__main__":
    with torch.inference_mode(): main()

完整文件位于 examples/quantization_methods.py。实际 activation 最大范围从 97.099 降到 3.531;W8A8 fake-quant MAE 从 0.4530080.029458;unweighted/activation-weighted 最差 channels 分别为 2/0。

脚本用 per-tensor fake INT8,既没有 GPTQ Hessian update、AWQ scale search,也没有 native FP8 tensor/kernel。它提供的是方法动机的可检查数学证据,而非算法性能或模型精度复现。

生产验收与失败场景

方法级量化至少核对:

  • checkpoint schema:bit width、packing、group size、scale/zero shape、transpose/order;
  • loader 后实际 GPU allocated 与 weight dtype/layout,防止展开;
  • profiler 中真实 kernel/backend,而非 config 名;
  • layer-wise output error、perplexity/任务/长上下文、不同 prompt 分布;
  • prefill/decode 分开性能、batch/shape sweep、compile/graph compatibility;
  • TP/EP shards 与 quant groups/scale ownership一致;
  • 未量化 layers(embedding/norm/lm head)与 workspace 计入容量。

常见失败:calibration 太窄;SmoothQuant scale 应用两次/漏应用;GPTQ/AWQ checkpoint 与 runtime packing variant 不匹配;FP8 scale overflow/underflow 或 amax history跨请求错误;低比特 kernel只支持特定 GPU;weight-only decode 加速但 prefill fallback 变慢。

Backend Dispatch给出 profiler/fallback 证据层;模型加载负责 schema、TP slicing 与不展开;KV 量化是独立 cache 表示,不能把 weight method 名直接套到 K/V。

参考资料