---
tags: [量化, W8A8, CANN]
doc_type: knowledge-note
abstract: "从数值映射与误差理解低精度格式、量化算法、校准及部署链路。"
creation: 2026-10-15
返回目录: "[[计算机系/昇腾与CANN/大模型与算子专题学习导航|大模型与算子专题学习导航]]"
上一篇: "[[计算机系/昇腾与CANN/大模型推理优化|大模型推理优化]]"
下一篇: "[[计算机系/昇腾与CANN/大模型结构解析与NPU迁移诊断|大模型结构解析与NPU迁移诊断]]"
后续学习: ["[[计算机系/昇腾与CANN/低比特量化优化与AMCT实践|低比特量化优化与AMCT实践]]"]
---

# 大模型量化原理与部署

前置：[推理系统](大语言模型与推理系统.md) · 关联：[推理优化](大模型推理优化.md)

## 1. 量化为什么有用

量化将高精度数据映射为更低位宽的表示，降低权重、激活或 KV Cache 的存储与传输成本，并在硬件和算子支持时使用更高吞吐的低精度计算。

例如 2350 亿参数按每参数 2 字节存储，权重本体约为 470 GB（十进制），不含缓存、临时张量和其他元数据。MoE 激活参数少，也不意味着所有专家权重不需要存储。

16 bit 改为 8 bit，数据本体减半；16 bit 改为 4 bit，数据本体约为原来的四分之一。实际还需要 scale、zero point、打包对齐和未量化层。

**位宽减半不代表端到端速度必然翻倍。**反量化成本、带宽、算子覆盖和瓶颈位置都会改变收益。模型质量损失也没有通用的“低于 1%”保证。

## 2. 数值格式、对象与粒度

| 格式 | 位宽 | 主要特点 |
| --- | --- | --- |
| FP32 | 32 | 1 位符号、8 位指数、23 位尾数 |
| FP16 | 16 | 5 位指数、10 位尾数，动态范围小于 BF16 |
| BF16 | 16 | 8 位指数、7 位尾数，动态范围接近 FP32 |
| FP8 E4M3 | 8 | 相对强调有效精度 |
| FP8 E5M2 | 8 | 相对强调动态范围 |
| INT8 | 8 | 整数表示，通常需要缩放参数 |
| INT4 | 4 | 更强压缩，对误差和内核支持更敏感 |
| FP4 | 4 | 低位浮点，具体范围和精度取决于格式 |

指数决定可表示的范围，尾数影响有效精度。不能仅凭位数判断两种格式谁对所有数据都更准确。

### 量化对象

![量化对象与粒度](.assets/大模型与算子专题/量化对象与粒度.png)

| 对象 | 含义 | 常见配置 |
| --- | --- | --- |
| 权重 W | 固定的模型参数，可离线转换 | W8A16、W4A16 |
| 激活 A | 随输入改变的中间结果 | W8A8 |
| KV Cache | 随生成增长的历史 K/V | KV INT8 |

`W8A8` 表示权重和激活使用 8 bit，不代表全部中间结果、累加器、输出和 KV 都是 8 bit。`W4A16` 表示 4 bit 权重、16 bit 激活。

图中“权重静态、激活动态”描述数据是否随输入变化；激活的量化参数既可以离线校准得到，也可以在线计算。权重离线量化后仍需要运行时理解其打包格式和 scale。

### 量化粒度

粒度是共享同一组量化参数的数值范围。

| 粒度 | 共享范围 |
| --- | --- |
| Per-tensor | 整个张量 |
| Per-channel | 一个通道 |
| Per-token | 一个 token 的表示 |
| Per-group | 某个轴上的一组元素 |
| Per-block | 一个数据块 |

粒度变细通常能适应局部分布，但增加参数、索引与计算成本。Group 和 block 的具体形状需要读取配置，不能只看名称。

## 3. 对称 INT8 量化

采用整数范围 $[-127,127]$，令 $a=\max_i|x_i|$：

$$
s=\frac{a}{127},\qquad
q_i=\operatorname{clip}\left(\operatorname{round}\left(\frac{x_i}{s}\right),-127,127\right)
$$

$$
\hat{x}_i=q_i s
$$

$s$ 是 scale，$q$ 是量化整数，$\hat{x}$ 是重建近似值。全零张量需要单独处理 scale，避免除零。

取：

```text
x = [5.47, 3.08, -7.59, 0, -1.95, -4.57, 10.8]
```

得到 $s=10.8/127\approx0.08503937$。对于 $x=5.47$：

$$
q=\operatorname{round}(5.47/0.08503937)=64
$$

$$
\hat{x}=64\times0.08503937\approx5.44252
$$

整组整数约为 `[64, 36, -89, 0, -23, -54, 127]`。误差来自离散网格，反量化无法恢复全部原始信息。

![对称量化示意](.assets/大模型与算子专题/对称量化原始示例.png)

图中代入式的 `0.039` 与 scale 不一致，应使用 `10.8/127`；按近似 scale `0.085` 计算会得到约 `5.44`。

## 4. 非对称量化与 Zero Point

非对称量化用偏移量适应不以零对称的数据分布。对于 unsigned 8 bit 范围 $[0,255]$，一组包含零的数据可采用：

$$
s=\frac{x_{\max}-x_{\min}}{255},\qquad
z=\operatorname{clip}\left(\operatorname{round}\left(-\frac{x_{\min}}s\right),0,255\right)
$$

$$
q=\operatorname{clip}\left(\operatorname{round}\left(\frac{x}s\right)+z,0,255\right),\qquad
\hat{x}=(q-z)s
$$

这里 $z$ 是整数 zero point。若使用 signed INT8，整数范围和 zero point 要一起调整，不能混用。

继续使用上一组数据：

$$
x_{\max}-x_{\min}=10.8-(-7.59)=18.39
$$

$$
s=18.39/255\approx0.07211765,\quad z=105
$$

当 $x=5.47$ 时，$q=76+105=181$，$\hat{x}=76s\approx5.48094$。

![非对称量化示意](.assets/大模型与算子专题/非对称量化原始示例.png)

图中的极差 `10.39` 是算术错误，正确值为 `18.39`；图中又混用了 signed 与 unsigned 范围。实际推导应采用正文这一套一致的范围、整数 zero point 和反量化公式。

## 5. 舍入、截断与离群值

| 来源 | 原因 | 应对方向 |
| --- | --- | --- |
| 舍入 | 连续值只能落在离散网格上 | 改善粒度、位宽或分布 |
| 截断 | 数值超出可表示区间 | 改善校准范围，权衡截断与分辨率 |
| Outlier | 少数极值拉大量化范围 | 分组、平滑、旋转或保留部分高精度路径 |

扩大范围可以减少截断，却会增大网格间距；缩小范围可以提高普通值的分辨率，却会截断尾部。量化参数需要针对任务分布优化。

## 6. W8A8 的静态与动态路径

### 静态激活量化

1. 用代表性输入执行校准，收集激活分布。
2. 根据统计确定激活 scale，并从权重计算权重 scale。
3. 保存低精度权重、scale 和量化配置。
4. 推理时使用保存的激活参数转换输入，调用低精度矩阵乘，并按规则缩放结果。

校准数据应覆盖实际语言、任务和长度。校准集与实际输入分布不同可能明显降低质量。

### 动态激活量化

权重可离线处理，激活 scale 根据当前真实输入在线计算。它能更好适应某些分布变化，但增加统计和量化成本，不能保证对所有任务都比静态方法更准确。

权重与激活在简单对称、标量 scale 情形下满足：

$$
XW\approx(s_Xs_W)(Q_XQ_W)
$$

整数乘法常使用更宽的累加类型；如果有 per-channel 参数或 zero point，还需相应广播与偏移修正。

## 7. SmoothQuant 与其他路线

![SmoothQuant](.assets/大模型与算子专题/SmoothQuant.png)

设 $S$ 是可逆的通道缩放对角矩阵：

$$
Y=XW=(XS^{-1})(SW)
$$

缩小难以量化的激活通道，同时将相应幅度转移到权重，使两侧分布更容易处理。**变换前后的浮点表达式等价，之后的量化仍会产生误差。**缩放强度需要平衡激活与权重两侧。

令 $X$ 的形状为 $T\times K$、$W$ 为 $K\times N$，对输入通道 $j$，可按校准数据统计构造：

$$
s_j=\frac{\max_t|X_{tj}|^{\alpha}}{\max_n|W_{jn}|^{1-\alpha}},\qquad S=\operatorname{diag}(s_1,\ldots,s_K).
$$

实现时需要为全零通道设置下界，避免除零。$\alpha$ 调整激活与权重之间的负担转移，不是越大越好。这里 $X/S$ 应理解为按通道缩放，即 $XS^{-1}$，不是任意矩阵之间的除法。

| 方法 | 核心思想 | 关注点 |
| --- | --- | --- |
| RTN | 直接舍入 | 简单基线 |
| GPTQ | 逐层处理并补偿量化误差 | 权重量化与低位宽重建 |
| AWQ | 利用激活识别重要通道并缩放 | 保护对输出重要的权重通道 |
| SmoothQuant | 将激活离群值负担迁移到权重 | W8A8 的误差平衡 |
| QuaRot | 用旋转分散离群分量 | 改善低位宽量化条件 |

QuaRot 的旋转目的是让分布更易量化，不是“旋转后更难量化”。不同方法的优劣要在相同模型、位宽和任务下比较。

这些方法可以沿“直接舍入 → 误差补偿 → 分布变换”理解，但不是固定的质量排名。RTN 在合适的数据与位宽下也可能足够好。GPTQ 的补偿针对权重量化对输出造成的重建误差，不是对所有算子融合误差的通用修复器；融合通常保持数学语义，浮点舍入差异应另行验证。

### PTQ 与 QAT

PTQ 在预训练之后进行量化转换，可包含校准、局部重建和误差补偿，通常避免完整重新训练。QAT 在训练或微调中模拟量化误差，让参数适应低精度执行。

PTQ 更便于快速部署，QAT 增加训练成本，在极低位宽或严格质量要求下可能更合适。

### FP8 与 Microscaling

FP8 是数值格式，不等同于一种量化算法。MXFP8/MXFP4 使用块级共享缩放表示，可能在局部动态范围与存储成本间取得更好的平衡，但效果与块大小、内核和硬件有关。

硬件支持应区分“能加载这种格式”“能转换执行”与“原生高效矩阵计算”。A2/A3 的 FP8 原生能力，以及 A5/A6 的新格式支持，需按具体产品、指令与 CANN 版本核对，不能仅凭系列名保证可部署。

## 8. CANN 中的量化部署链路

![量化配置与产物](.assets/大模型与算子专题/量化配置与产物.png)

Qwen3-8B 的示例使用 AMCT（Ascend Model Compression Toolkit）导出量化产物。量化配置位于 `models/qwen/config/`，与推理配置分开管理。

| 配置项 | 作用 |
| --- | --- |
| `act` / `weight` | 数据类型、粒度、静态或动态方式 |
| `include` / `ignore` | 选择量化或保持高精度的模块 |
| `save` | 指定量化产物保存路径 |

部署不只是保存一个 INT8 张量，还需要 scale、模型结构、量化配置、tokenizer 及运行时支持。

这个 Qwen3-8B 配置采用 per-channel INT8 权重与动态 INT8 激活，量化位置包括 Attention 的 `q/k/v/o_proj` 和 MLP 的 `gate/up/down_proj`。产物采用 Hugging Face 风格目录，包含 `layer_*.safetensors`、`rest_*.safetensors`、权重索引和更新后的 `config.json`。

`ignore` 使用原始 HF 层名，运行时可能通过 `fused_mapping` 映射到 `merged_qkv_proj`、`gate_up_proj` 等融合层。设置排除项时要核对这一映射，避免只排除了错误名称而实际仍执行量化。

![量化运行链路](.assets/大模型与算子专题/量化运行链路.png)

`config.json` 中的 `quantization_config` 描述量化方式。示例工程通过 `compressed_tensors.py` 等适配入口识别 compressed-tensors 产物，对接 Linear W8A8、MoE Grouped MatMul 和 KV Cache 等路径。并非所有格式或模型都必然支持全部路径。

完整闭环是：选定配置与校准数据、导出产物、加载适配的算子、验证质量，再测性能。不能把“文件导出成功”当作量化部署完成。

## 9. 验证与复习

比较时固定模型、任务、输入输出长度、batch、并发和硬件，记录质量指标、峰值显存、TTFT、TPOT、吞吐与冷启动开销。对长上下文任务单独检查 KV 量化影响。

- 为什么要保存 scale？整数本身不能表达原浮点范围。
- 为什么更多 bit 不一定解决所有问题？校准不匹配、错误范围和运行时适配也会损害结果。
- W4A16 是否一定比 W8A8 快？不一定，取决于带宽、反量化、计算支持和 batch。
- SmoothQuant 是否无损？浮点等价变换可以保持输出，低精度舍入仍有误差。

实践：[Qwen3 量化配置说明](https://gitcode.com/cann/cann-recipes-infer/blob/master/models/qwen/README.md)、[Qwen3-8B 量化实验](https://gitcode.com/cann/cann-learning-hub/blob/master/tutorials/llm_inference/qwen3_8b/05_quantization_qwen3_8b.ipynb)、[SmoothQuant 论文](https://arxiv.org/abs/2211.10438)。
