先定标尺:用 absmax 把浮点范围对齐到 INT8
🎯 先猜一猜
输入 x 是一个全 0 张量,此时 torch.abs(x).max() 也是 0。
如果不做保护就计算 127.0 / absmax,最可能发生什么?
先补的知识
- 张量中的每个权重原本是浮点数;量化不是直接改类型,而是先决定浮点数与整数之间的换算比例。
- 本页采用 per-tensor 对称量化:整个 x 共享一个标量 scale,正负两侧都围绕 0。
- torch.abs(x) 逐元素取绝对值,torch.max(...) 再从所有元素中找出最大的幅度。
- 如果 x 全为 0,absmax 也是 0;直接计算 127 / absmax 会产生 Inf,所以必须先做除零保护。
图解原理
把 INT8 的 -127 到 127 想成一把只有 255 个刻度的尺子。absmax 告诉我们原张量最远离 0 的位置,scale 则说明每 1 个浮点单位要放大成多少个整数刻度。先把尺子定好,后面才能舍入和存储。
变量先翻译成人话
x任意 shape 的浮点权重张量
absmax标量张量,表示最大绝对幅度
scale标量张量,表示浮点值到整数刻度的放大倍数
一个只算标尺的小例子
若权重是 [-2.0, 0.5, 1.0],最大的绝对值是 2.0。
[2.0, 0.5, 1.0] absmax
2.0 scale
127 / 2
最大幅度 2.0 会被放大到 127;其他数按同一比例缩放,所以相对大小仍被保留。
全 0 是测试里的明确边界
全 0 张量没有可用范围。把 absmax 临时替换成很小的正数后,scale 保持有限,0 乘任何有限 scale 仍是 0。
为什么使用 127
Notebook 要做对称量化,让最大正幅度落在 127。虽然 int8 还能表示 -128,但这里的正负有效刻度围绕 0 对称。
语法热身:用温度读数练习 absmax、标量判断和安全 scale
readings = torch.tensor([-1.2, 0.0, 0.8])
largest = torch.abs(readings).max()
if largest == 0:
largest = torch.tensor(1e-8, device=readings.device)
gain = 31.0 / largest # 练习映射到另一套整数刻度
print(largest.shape) # torch.Size([]),标量张量例子中的变量 -> Notebook TODO 变量/操作
readings->x:输入数据不同,但都先保留原 shape。largest->absmax:先逐元素取绝对值,再做全局最大值归约。31.0-> Notebook 的 INT8 正上界127.0。gain->scale:都是“整数上界 / 最大绝对值”。
巩固一下
对张量 [-0.8, 1.5, -3.0, 2.5, 0.0] 做本页对称量化时,absmax 应是多少?
学完这一段,试着做
用一个小动作确认自己理解了;最后再进入官方题目。