因为硬件资源问题,硬件无法和软件一样进行高精度的浮点运算,所以用软件来模拟硬件计算时需要按硬件所能支持的位宽,将数据量化为低精度。
通常软件上量化其实是一种等分归类操作,即将原值域按照要求划分为若干份,然后将落到同一个区间的当成一个值即可。
由于硬件需用二进制表示,因此因此除了需满足软件上的等分操作外,还需根据Qn量化,将步长设为x**(-n)
eg:进行8位量化,及范围是-2**(n) ~ 2**(n)-1
(1)软件
S = max(|max(x)|, |min(x)|)/(2**(n)-1)
x = round(x/S)
x = clamp(x, -2**(n), 2**(n)-1)
(2)硬件
MAX = math.floor(max(|max(x)|, |min(x)|))
div = math.floor(math.log(MAX, 2)) + 1 //整数位宽,若MAX为0,则div=0
Q_number = n_bits -div //加边界保护,Q_number小于0的时候取0
x = x.mul(2 ** Q_number).trunc().div(2 ** Q_number) //量化将超出部分砍掉,然后变为2 ** Q_number的倍数