跳到主要内容
TileLang 系统教程

tilelang-tutorial.huandu.me

第 27 章 低精度、量化与数值正确性

/code/27-low-precision-quantization/

04-vs-reference/README.md2507 字节
# 示例 04:对拍时「参照选错」会怎样

## 目的

低精度算子的对拍有一个独有的陷阱:**被测 kernel 与参照实现必须共享同一套量化规则**。
脚本用一个最小的 int4 per-group 反量化 GEMM(X 是 int8、W 是 int4、group=64)
演示六种参照,其中两种会让判断失准:

| 编号 | 参照 | 应该是什么结果 |
| --- | --- | --- |
| A | 量化感知的 fp64 参照(同样的量化规则) | **通过** |
| B | 反量化位置错:把 group 循环里的 scale 提到循环外,只乘最后一组 | 失败(逻辑错误) |
| C | 参照漏乘权重 scale | 失败(逻辑错误) |
| D | 拿量化前的 fp32 权重当参照 | 失败,但**不是 bug** |
| E | 被测与参照 C 犯同一个错 | **通过**(假阳性) |
| E' | 同一个错误实现相对正确参照 A | 失败(证明 E 的通过是假的) |

## 运行前提

Python 3.9+ 与 numpy。**不需要 GPU / NPU**。

## 运行命令

```bash
python3 reference_matching.py
python3 reference_matching.py --m 256 --n 256 --k 1024 --group 64
```

## 期望输出

作者在写作机上的实际输出(2026-10-01,Python 3.11.7 + numpy 1.24.1,默认参数):

```text
形状:X[128,512] int8,W[256,512] int4,group=64
判据:rtol=0.01, atol=0.001, max_mismatched_ratio=0.001

参照                                          相对 L2         max abs err     不匹配元素数      不匹配比例       结论
A 量化感知参照(fp64)                            3.837e-16     5.329e-15       0           0.000e+00   通过
B 反量化位置错(只乘最后一组 scale)                    2.097e-01     4.811e+00       31673       9.666e-01   失败
C 参照漏乘 scale(逻辑错误)                        9.643e-01     2.503e+02       32765       9.999e-01   失败
D 用量化前的 fp32 权重当参照                        1.078e-01     1.043e+00       30793       9.397e-01   失败
E 被测与参照 C 犯同一个错                           9.906e-13     5.045e-10       0           0.000e+00   通过
E' 同一个错误的实现 vs 正确的 A                      2.668e+01     2.503e+02       32765       9.999e-01   失败
```

判据与锁定版本的两个工具一致:`torch_assert_close(rtol=1e-2, atol=1e-3,
max_mismatched_ratio=1e-3)`(`tilelang/utils/tensor.py:205`)与
`Profiler.assert_allclose(atol=1e-2, rtol=1e-2, max_mismatched_ratio=1e-2)`
(`tilelang/profiler/__init__.py:104`)。

## 三条可直接执行的判据

1. **逻辑错误的签名是「误差是结果的量级」**:B、C、E' 的相对 L2 是 0.21 / 0.96 / 26.7,
   不匹配比例是 94%–99.99%。这类问题改容差解决不了,也不该改。
2. **数值误差的签名是「相对 L2 小、不匹配比例高、但 max err 有限」**:D 是
   `1.08e-1` 的相对 L2 加 94% 不匹配——正好是 int4 权重应有的量化误差。
   遇到 D 这种结果,要回去检查**参照的量化规则**,不是 kernel。
3. **只看一个指标不够**:A 与 E 都「通过」,但只有 A 是对的。所以
   `max_mismatched_ratio` 这类统计判据必须配一个**绝对参照**(fp64 或 fp32 的
   量化感知实现),否则两个都错、错得一致的实现会一路绿灯。

## 注意事项

* 这里把「激活 scale × 权重 group scale」在 epilogue 一次乘完;真实实现先在 int32
  累加器里算整数积,再乘 scale。整数累加是精确的,两者只差浮点乘法的结合顺序
  (A 行的 3.8e-16 就是这个量级)。
* 没有实现 zero point。加上 zero point 后,「参照忘了减 zero」会变成另一类常见错误,
  误差结构与本例的 C 相同。
* 例子用的是 numpy 而不是 TileLang 的 profiler;对拍判据取自锁定版本的默认值。

## 作者实际做到的验证级别

**CPU 逻辑验证**:在 macOS (Apple Silicon)、Python 3.11.7 + numpy 1.24.1 上实际运行过,
退出码 0。未在任何加速器上运行过任何 kernel。

← 浏览本章全部代码