W8 量化:用绝对最大值确定刻度尺
先补的知识
- int8 的有效范围通常看作 [-127, 127],对称量化会尽量让正负两侧共用同一把刻度尺。
- 这里的 scale 表示整数刻度密度:scale = 127 / absmax。absmax 越大,每个浮点单位对应的 int8 刻度越少。
- 量化不是简单 to(torch.int8):要先乘 scale,把浮点数放大到整数刻度,再 round 到最近整数。
- round 后还要 clamp,防止极端值越界;最后才转成 torch.int8 存储。
图解原理
把浮点权重压成 int8,像把真实长度画到一把只有 127 格的尺子上。先找最大绝对值 absmax,决定“最远的点”应该贴到 int8 边界;再用同一把尺子把所有权重换算成整数刻度。
输入是一块浮点权重,输出不是一个张量,而是两样东西:压缩后的 int8 权重,以及以后反量化要用的 scale。
量化时乘 scale,反量化时除 scale。这个 notebook 的 scale 不是每个整数代表多少浮点值,而是 1 个浮点单位对应多少 int8 格。
q = round(w * scale),所以还原就是 w ≈ q / scale。这条线就是 TODO 1/2/3 的顺序。不要先转 int8,否则小数会直接被截断,量化误差会变得不可控。
把 scale 写反、忘记 round、忘记 clamp,都会让测试里的误差或 dtype 检查失败。
语法热身:量化三步
absmax = weight.abs().max()
scale = 127.0 / absmax
q = torch.round(weight * scale)
q = q.clamp(-128, 127)
q = q.to(torch.int8)举一反三:对应 notebook TODO
迁移口诀:量化乘 scale,反量化除 scale;scale 方向别写反。
闯关题
这个 notebook 中为什么 scale 常用 127 / absmax?
回到 notebook 的作业
这里不直接写答案。你已经拿到足够输入,最后用 notebook 的 TODO 做举一反三。