|
|
|
@ -19,6 +19,7 @@ import numpy as np
|
|
|
|
|
|
|
|
|
|
def cal_quantization_params(input_min,
|
|
|
|
|
input_max,
|
|
|
|
|
data_type,
|
|
|
|
|
num_bits=8,
|
|
|
|
|
symmetric=False,
|
|
|
|
|
narrow_range=False):
|
|
|
|
@ -28,6 +29,7 @@ def cal_quantization_params(input_min,
|
|
|
|
|
Args:
|
|
|
|
|
input_min (int, list): The dimension of channel or 1.
|
|
|
|
|
input_max (int, list): The dimension of channel or 1.
|
|
|
|
|
data_type (numpy type) : Can ben numpy int8, numpy uint8.
|
|
|
|
|
num_bits (int): Quantization number bit, support 4 and 8bit. Default: 8.
|
|
|
|
|
symmetric (bool): Quantization algorithm use symmetric or not. Default: False.
|
|
|
|
|
narrow_range (bool): Quantization algorithm use narrow range or not. Default: False.
|
|
|
|
@ -52,7 +54,7 @@ def cal_quantization_params(input_min,
|
|
|
|
|
# scale = 1.0, zp = 0.0
|
|
|
|
|
return np.ones(input_min.shape), np.zeros(input_min.shape)
|
|
|
|
|
|
|
|
|
|
if symmetric:
|
|
|
|
|
if data_type == np.int8:
|
|
|
|
|
quant_min = 0 - 2 ** (num_bits - 1)
|
|
|
|
|
quant_max = 2 ** (num_bits - 1)
|
|
|
|
|
else:
|
|
|
|
@ -84,3 +86,33 @@ def cal_quantization_params(input_min,
|
|
|
|
|
zp = np.floor(zp_double + 0.5)
|
|
|
|
|
|
|
|
|
|
return scale, zp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def weight2int(data,
|
|
|
|
|
scale,
|
|
|
|
|
zero_point):
|
|
|
|
|
r"""
|
|
|
|
|
calculate int8/uint8 weight from fp32. the formula is defined as:
|
|
|
|
|
|
|
|
|
|
.. math::
|
|
|
|
|
|
|
|
|
|
int8/uint8 = round(float/scale) + offset
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
data (int, list): The dimension of channel or 1. Should be NCHW.
|
|
|
|
|
scale (int, list): The dimension of channel or 1.
|
|
|
|
|
zero_point (int, list): The dimension of channel or 1.
|
|
|
|
|
|
|
|
|
|
Outputs:
|
|
|
|
|
weight (int, list): The dimension of channel or 1.
|
|
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
>>> weight = weight2int([1, 2, 1], 1, 0)
|
|
|
|
|
"""
|
|
|
|
|
if scale.shape != zero_point.shape:
|
|
|
|
|
raise ValueError("scale and zero_point should have the same shape.")
|
|
|
|
|
if scale.shape[0] > 0:
|
|
|
|
|
scale = scale.reshape(1, -1, 1, 1)
|
|
|
|
|
zero_point = zero_point.reshape(1, -1, 1, 1)
|
|
|
|
|
|
|
|
|
|
return np.round((data/scale) + zero_point)
|
|
|
|
|