def test_per_channel_qtensor_creation(self): numel = 10 ch_axis = 0 scales = torch.rand(numel) zero_points = torch.randint(0, 10, size=(numel, )) for dtype in [torch.qint8, torch.quint8]: q = torch._empty_per_channel_affine_quantized( [numel], scales=scales, zero_points=zero_points, axis=ch_axis, dtype=dtype) # TODO(#38095): Replace assertEqualIgnoreType. See issue #38095 self.assertEqualIgnoreType(scales, q.q_per_channel_scales()) self.assertEqual(zero_points, q.q_per_channel_zero_points()) self.assertEqual(ch_axis, q.q_per_channel_axis()) # create Tensor from uint8_t Tensor, scales and zero_points int_tensor = torch.randint(0, 100, size=(numel, ), dtype=torch.uint8) q = torch._make_per_channel_quantized_tensor(int_tensor, scales, zero_points, ch_axis) self.assertEqual(int_tensor, q.int_repr()) # TODO(#38095): Replace assertEqualIgnoreType. See issue #38095 self.assertEqualIgnoreType(scales, q.q_per_channel_scales()) self.assertEqual(zero_points, q.q_per_channel_zero_points()) self.assertEqual(ch_axis, q.q_per_channel_axis())
def __init__(self, num_embeddings: int, embedding_dim: int, padding_idx: Optional[int] = None, max_norm: Optional[float] = None, norm_type: float = 2., scale_grad_by_freq: bool = False, sparse: bool = False, _weight: Optional[Tensor] = None, dtype=torch.quint8) -> None: super(Embedding, self).__init__() self.num_embeddings = num_embeddings self.embedding_dim = embedding_dim if _weight is None: scales = torch.ones(num_embeddings, dtype=torch.float) zero_points = torch.zeros(num_embeddings, dtype=torch.float) self.qweight = torch._empty_per_channel_affine_quantized( [num_embeddings, embedding_dim], scales=scales, zero_points=zero_points, axis=0, dtype=torch.quint8) else: assert list(_weight.shape) == [num_embeddings, embedding_dim], \ 'Shape of weight does not match num_embeddings and embedding_dim' self.qweight = _weight self._packed_params = EmbeddingPackedParams(num_embeddings, embedding_dim, dtype) self._packed_params.set_weight(self.qweight)
def _rebuild_qtensor(storage, storage_offset, size, stride, quantizer_params, requires_grad, backward_hooks): qscheme = quantizer_params[0] if qscheme == torch.per_tensor_affine: _, scale, zero_point = quantizer_params tensor = torch._empty_affine_quantized(size, scale=scale, zero_point=zero_point, dtype=storage.dtype) elif qscheme in (torch.per_channel_affine, torch.per_channel_affine_float_qparams): _, scales, zero_points, axis = quantizer_params if type(scales) is list and type(zero_points) is list: if qscheme == torch.per_channel_affine: scales = torch.tensor(scales, dtype=torch.double) zero_points = torch.tensor(zero_points, dtype=torch.long) else: scales = torch.tensor(scales, dtype=torch.float) zero_points = torch.tensor(zero_points, dtype=torch.float) tensor = torch._empty_per_channel_affine_quantized( size, scales=scales, zero_points=zero_points, axis=axis, dtype=storage.dtype) else: raise RuntimeError("Can't deserialize quantized tensor with qscheme {}".format(qscheme)) tensor.set_(storage, storage_offset, size, stride) tensor.requires_grad = requires_grad # NB: This line exists only for backwards compatibility; the # general expectation is that backward_hooks is an empty # OrderedDict. See Note [Don't serialize hooks] tensor._backward_hooks = backward_hooks return tensor
def test_clone(self): numel = 10 scale = 0.5 zero_point = 10 options = itertools.product(get_supported_device_types(), [torch.qint8, torch.quint8, torch.qint32]) for device, dtype in options: per_tensor_quantized = torch._empty_affine_quantized( [numel], scale=scale, zero_point=zero_point, device=device, dtype=dtype) per_channel_quantized = torch._empty_per_channel_affine_quantized( [numel], scales=torch.tensor([scale]), zero_points=torch.tensor([zero_point]), axis=0, device=device, dtype=dtype) qtensors = [per_tensor_quantized, per_channel_quantized] for q in qtensors: q2 = q.clone() # Check to make sure the scale and zero_point has been copied. self.assertEqual(q, q2)
def __init__(self, num_embeddings, embedding_dim, dtype=torch.quint8): super(EmbeddingPackedParams, self).__init__() self.dtype = dtype if self.dtype in [torch.quint8, torch.quint4x2]: scales = torch.ones(num_embeddings, dtype=torch.float) zero_points = torch.zeros(num_embeddings, dtype=torch.float) wq = torch._empty_per_channel_affine_quantized([num_embeddings, embedding_dim], scales=scales, zero_points=zero_points, axis=0, dtype=self.dtype) self.set_weight(wq) else: raise NotImplementedError('Unsupported dtype on quantized embedding! Supports quint8 and quint4x2.')
def __init__(self, num_embeddings, embedding_dim, dtype=torch.quint8): super(EmbeddingPackedParams, self).__init__() self.dtype = dtype if self.dtype == torch.quint8: scales = torch.ones(num_embeddings, dtype=torch.float) zero_points = torch.zeros(num_embeddings, dtype=torch.float) wq = torch._empty_per_channel_affine_quantized( [num_embeddings, embedding_dim], scales=scales, zero_points=zero_points, axis=0, dtype=torch.quint8) self.set_weight(wq) else: raise RuntimeError('Unsupported dtype on quantized embedding!')
def test_per_channel_qtensor_creation(self): numel = 10 ch_axis = 0 scales = torch.rand(numel) zero_points = torch.randint(0, 10, size=(numel,)) q = torch._empty_per_channel_affine_quantized( [numel], scales=scales, zero_points=zero_points, axis=ch_axis, dtype=torch.quint8) self.assertEqual(scales, q.q_per_channel_scales()) self.assertEqual(zero_points, q.q_per_channel_zero_points()) self.assertEqual(ch_axis, q.q_per_channel_axis()) # create Tensor from uint8_t Tensor, scales and zero_points int_tensor = torch.randint(0, 100, size=(numel,), dtype=torch.uint8) q = torch._make_per_channel_quantized_tensor(int_tensor, scales, zero_points, ch_axis) self.assertEqual(int_tensor, q.int_repr()) self.assertEqual(scales, q.q_per_channel_scales()) self.assertEqual(zero_points, q.q_per_channel_zero_points()) self.assertEqual(ch_axis, q.q_per_channel_axis())