[PT FE] Add aten::quantize_per_tensor, aten::quantize_per_channel, aten::dequantize (#18266)

* Support GetAttr with packed params

* Apply suggestions from code review

* [PT FE] Add quantized types as normal types to decoder

* [PT FE] Add decoder dequantize, add dtypes to quantize

* [PT FE] Add dequantize example

* [PT FE] Implement replacer for quantized nodes

* [PT FE] Register replacer for quantize/dequantize

* [PT FE] Remove unwanted junk from previous version

* [PT FE] Fix building mistakes for frontend

* [PT FE] Clang fix

* [PT FE] Ease of use upgrade to quantize funcs

* [PT FE] Clang format

* [PT FE] Introduce new version of quantize/dequantize

* [PT FE] Remove unwanted files from new version

* [PT FE] Fix style

* [PT FE] Add QuantizedPtNode replacer, fix accuracy error

* [PT FE] Add improved version of quantize/dequantize with shared_ptrs

* [PT FE] Fix utils shared ptr reference error

* [PT FE] Quantize now takes correct input for operations

* [PT FE] Upgrade quantize method

* [PT FE] Add BFS for dequantize, add quantize_per_channel

* [PT FE] Add missing replacer to frontend, improve tests

* [PT FE] Rename replacer -> remover, remove unwanted header files

* [PT FE] Change function declarations to return ov::Output instead of shared ptr

* [PT FE] Add missing context mark node

* [PT FE] Remove unknown modifications to ie_c_api

* [PT FE] Remove fp16 support, turn off int32 tests

* [PT FE] Clang format

* [PT FE] Fix quantize_per_tensor

* [PT FE] Minor fixes from review

* [PT FE] Remove dequantize, remove helpers, replacer now removes nodes instead

* [PT FE] Rename Replacer to Remover for dequantize nodes

* [PT FE] Clang format

* [PT FE] Move comments to header files, minor import fixes

* [PT FE] Fix clang format

* [PT FE] Fix dtype issue

* [PT FE] Fix quantize_per_channel tests

* Apply suggestions from code review

Removing sporadic tests from precommit

* Apply suggestions from code review

---------

Co-authored-by: Maxim Vafin <maxim.vafin@intel.com>
This commit is contained in:
Piotr Krzemiński
2023-07-17 02:30:02 +02:00
committed by GitHub
parent 8defcef3f1
commit d7984f3ec2
12 changed files with 587 additions and 9 deletions

View File

@@ -0,0 +1,87 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import numpy as np
import pytest
import torch
from pytorch_layer_test_class import PytorchLayerTest
class aten_quantize_per_tensor_aten_dequantize(torch.nn.Module):
def __init__(self, scale, zero_point, dtype) -> None:
torch.nn.Module.__init__(self)
self.scale = scale
self.zero_point = zero_point
self.dtype = dtype
def forward(self, input_tensor):
quantized_tensor = torch.quantize_per_tensor(input_tensor, self.scale, self.zero_point, self.dtype)
dequantized_tensor = torch.dequantize(quantized_tensor)
return dequantized_tensor
class aten_quantize_per_channel_aten_dequantize(torch.nn.Module):
def __init__(self, scales, zero_points, dtype, axis) -> None:
torch.nn.Module.__init__(self)
self.scales = torch.Tensor(scales)
self.zero_points = torch.Tensor(zero_points)
self.dtype = dtype
self.axis = axis
def forward(self, input_tensor):
quantized_tensor = torch.quantize_per_channel(input_tensor, self.scales, self.zero_points, self.axis, self.dtype)
dequantized_tensor = torch.dequantize(quantized_tensor)
return dequantized_tensor
class TestQuantizePerTensorDequantize(PytorchLayerTest):
def _prepare_input(self):
return (np.array(5.00 * np.random.rand(100, 100) + 5.00, dtype=np.float32),)
@pytest.mark.parametrize("scale", [
1.0, 0.21, 0.62
])
@pytest.mark.parametrize("zero_point", [
0, 4, -7
])
@pytest.mark.parametrize("dtype", [
torch.quint8,
torch.qint8,
pytest.param(torch.qint32, marks=pytest.mark.skip(
reason="Not supported with FakeQuantize."))
])
@pytest.mark.nightly
# @pytest.mark.precommit - sporadic issue
def test_quantize_per_tensor_dequantize(self, scale, zero_point, dtype, ie_device, precision, ir_version):
if dtype == torch.quint8: zero_point = abs(zero_point)
self._test(aten_quantize_per_tensor_aten_dequantize(scale, zero_point, dtype), None, ["aten::quantize_per_tensor", "aten::dequantize"],
ie_device, precision, ir_version, )
class TestQuantizePerChannelDequantize(PytorchLayerTest):
def _prepare_input(self):
return (np.array(5.00 * np.random.rand(5, 6, 7, 8) + 5.00, dtype=np.float32),)
@pytest.mark.parametrize("scales", [
np.array([1.0, 0.21, 0.62, 0.5], dtype=np.float32),
np.array([0.21, 0.62, 0.5, 1.0], dtype=np.float32),
np.array([0.62, 0.5, 1.0, 0.21], dtype=np.float32),
np.array([0.5, 1.0, 0.21, 0.62], dtype=np.float32),
])
@pytest.mark.parametrize("zero_points", [
np.array([0, 4, 2, 1], dtype=np.int32),
np.array([0, 1, 2, 3], dtype=np.int32),
np.array([0, 0, 0, 0], dtype=np.int32),
np.array([-1, 0, -4, 5], dtype=np.int32),
])
@pytest.mark.parametrize("dtype", [
torch.quint8,
torch.qint8,
pytest.param(torch.qint32, marks=pytest.mark.skip(
reason="Not supported with FakeQuantize."))
])
@pytest.mark.parametrize("axis", [
0, 1, 2, 3
])
@pytest.mark.nightly
# @pytest.mark.precommit - conversion issue
def test_quantize_per_channel_dequantize(self, scales, zero_points, dtype, axis, ie_device, precision, ir_version):
if dtype == torch.quint8: zero_points = abs(zero_points)
self._test(aten_quantize_per_channel_aten_dequantize(scales, zero_points, dtype, axis), None, ["aten::quantize_per_channel", "aten::dequantize"],
ie_device, precision, ir_version, )