Skip to content

Commit 1092071

Browse files
authored
[SSS Review] Bug fixes during verification & Exclude Python 3.9 from support (#140)
1 parent d53570b commit 1092071

File tree

8 files changed

+65
-31
lines changed

8 files changed

+65
-31
lines changed

.github/workflows/publish_release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
- name: Install Python 3
1111
uses: actions/setup-python@v5
1212
with:
13-
python-version: 3.8
13+
python-version: 3.11
1414
- name: Install dependencies
1515
run: |
1616
python -m pip install --upgrade pip

.github/workflows/run_tests_suite_pip.yml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@ name: Test pip install
22
on:
33
workflow_dispatch: # Allow manual triggers
44
inputs:
5-
mct_quantizers_version:
6-
description: 'MCT Quantizers version'
7-
required: true
8-
default: 'v1.6.0'
95
python_version:
106
description: 'Python version'
117
required: false
@@ -24,7 +20,6 @@ jobs:
2420
python-version: ${{ inputs.python_version }}
2521
- name: Install dependencies
2622
run: |
27-
git checkout tags/${{ inputs.mct_quantizers_version }}
2823
python -m pip install --upgrade pip
2924
pip install -r requirements.txt
3025
pip install twine wheel
@@ -58,5 +53,4 @@ jobs:
5853
pip install torch==2.6.* torchvision "onnx<1.18" "onnxruntime<1.22" "onnxruntime-extensions<0.14"
5954
- name: Run Torch Tests
6055
run: |
61-
python -m unittest discover tests/pytorch_tests --verbose
62-
56+
python -m unittest discover tests/pytorch_tests --verbose

.github/workflows/run_various_python_versions_tf.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
timeout-minutes: 10
1717
strategy:
1818
matrix:
19-
python-version: ["3.9", "3.10", "3.11"]
19+
python-version: ["3.10", "3.11"]
2020
steps:
2121
- uses: actions/checkout@v4
2222
- name: Install Python ${{ matrix.python-version }}

.github/workflows/run_various_python_versions_torch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
timeout-minutes: 10
1717
strategy:
1818
matrix:
19-
python-version: ["3.9", "3.10", "3.11", "3.12"]
19+
python-version: ["3.10", "3.11", "3.12"]
2020
steps:
2121
- uses: actions/checkout@v4
2222
- name: Install Python ${{ matrix.python-version }}

README.md

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,22 @@ Users can set the quantizers and all the quantization information for each layer
1515

1616
Please note that the quantization wrapper and the quantizers are framework-specific.
1717

18-
<img src="https://github.com/sony/mct_quantizers/raw/main/quantization_infra.png" width="700">
18+
<img src="https://github.com/SonySemiconductorSolutions/mct-quantization-layers/raw/main/quantization_infra.png" width="700">
1919

2020
## Quantizers:
2121

2222
The library provides the "Inferable Quantizer" interface for implementing new quantizers.
23-
This interface is based on the [`BaseInferableQuantizer`](https://github.com/sony/mct_quantizers/blob/main/mct_quantizers/common/base_inferable_quantizer.py) class, which allows the definition of quantizers used for emulating inference-time quantization.
23+
This interface is based on the [`BaseInferableQuantizer`](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/blob/main/mct_quantizers/common/base_inferable_quantizer.py) class, which allows the definition of quantizers used for emulating inference-time quantization.
2424

2525
On top of `BaseInferableQuantizer` the library defines a set of framework-specific quantizers for both weights and activations:
26-
1. [Keras Quantizers](https://github.com/sony/mct_quantizers/tree/main/mct_quantizers/keras/quantizers)
27-
2. [Pytorch Quantizers](https://github.com/sony/mct_quantizers/tree/main/mct_quantizers/pytorch/quantizers)
26+
1. [Keras Quantizers](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/tree/main/mct_quantizers/keras/quantizers)
27+
2. [Pytorch Quantizers](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/tree/main/mct_quantizers/pytorch/quantizers)
2828

2929
### The mark_quantizer Decorator
3030

31-
The [`@mark_quantizer`](https://github.com/sony/mct_quantizers/blob/main/mct_quantizers/common/base_inferable_quantizer.py) decorator is used to assign each quantizer with static properties that define its task compatibility. Each quantizer class should be decorated with this decorator, which defines the following properties:
32-
- [`QuantizationTarget`](https://github.com/sony/mct_quantizers/blob/main/mct_quantizers/common/base_inferable_quantizer.py): An Enum that indicates whether the quantizer is intended for weights or activations quantization.
33-
- [`QuantizationMethod`](https://github.com/sony/mct_quantizers/blob/main/mct_quantizers/common/quant_info.py): A list of quantization methods (Uniform, Symmetric, etc.).
31+
The [`@mark_quantizer`](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/blob/main/mct_quantizers/common/base_inferable_quantizer.py) decorator is used to assign each quantizer with static properties that define its task compatibility. Each quantizer class should be decorated with this decorator, which defines the following properties:
32+
- [`QuantizationTarget`](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/blob/main/mct_quantizers/common/base_inferable_quantizer.py): An Enum that indicates whether the quantizer is intended for weights or activations quantization.
33+
- [`QuantizationMethod`](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/blob/main/mct_quantizers/common/quant_info.py): A list of quantization methods (Uniform, Symmetric, etc.).
3434
- `identifier`: A unique identifier for the quantizer class. This is a helper property that allows the creation of advanced quantizers for specific tasks.
3535

3636
## Getting Started
@@ -45,16 +45,11 @@ To install the latest stable release of MCT Quantizer from PyPi, run the followi
4545
pip install mct-quantizers
4646
```
4747

48-
If you prefer to use the nightly package (unstable version), you can install it with the following command:
49-
```
50-
pip install mct-quantizers-nightly
51-
```
52-
5348
#### From Source
5449
To work with the MCT Quantizers source code, follow these steps:
5550
```
56-
git clone https://github.com/sony/mct_quantizers.git
57-
cd mct_quantizers
51+
git clone https://github.com/SonySemiconductorSolutions/mct-quantization-layers.git
52+
cd mct-quantization-layers
5853
python setup.py install
5954
```
6055

@@ -68,7 +63,7 @@ For use with Tensorflow, please install the following package:
6863
For use with PyTorch, please install the following package:
6964
[torch](https://pytorch.org/)
7065

71-
You can also use the [requirements](https://github.com/sony/mct_quantizers/blob/main/requirements.txt) file to set up your environment.
66+
You can also use the [requirements](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/blob/main/requirements.txt) file to set up your environment.
7267

7368
## License
74-
[Apache License 2.0](https://github.com/sony/mct_quantizers/blob/main/LICENSE.md).
69+
[Apache License 2.0](https://github.com/SonySemiconductorSolutions/mct-quantization-layers/blob/main/LICENSE.md).

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@ def get_release_arguments():
5252
"Topic :: Scientific/Engineering :: Artificial Intelligence"
5353
],
5454
install_requires=read_install_requires(),
55-
python_requires='>=3.9'
55+
python_requires='>=3.10'
5656
)

tests/compatibility_tests/keras_comp_tests/base_activation_compatibility_test.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,34 @@
5757

5858
def _build_model_with_quantization_holder(act_layer, quant_activation_holder, input_shape, model_name):
5959
inputs = tf.keras.layers.Input(shape=input_shape)
60-
x = tf.keras.layers.Conv2D(filters=3, kernel_size=4)(inputs)
60+
# If all conv outputs are negative, the ReLU output will be 0, causing a quantizer validation error.
61+
# To include positive and negative values ​​in the conv outputs, we set the conv weights to positive values.
62+
# Also set the upper half of the input tensor to positive and the lower half to negative.
63+
conv = tf.keras.layers.Conv2D(filters=3, kernel_size=4)
64+
conv.build(input_shape=input_shape)
65+
kernel, bias = conv.get_weights()
66+
conv.set_weights([np.abs(kernel), bias])
67+
x = conv(inputs)
6168
act_output = act_layer(x)
6269
quant_output = quant_activation_holder(act_output)
6370
return tf.keras.Model(inputs=inputs, outputs=[quant_output, act_output], name=model_name)
6471

6572

6673
def _build_model_with_operator_quantization_holder(act_layer, quant_activation_holder, input_shape, model_name):
6774
inputs = tf.keras.layers.Input(shape=input_shape)
68-
x = tf.keras.layers.Conv2D(filters=3, kernel_size=4)(inputs)
69-
y = tf.keras.layers.Conv2D(filters=3, kernel_size=4)(inputs)
75+
# If all conv outputs are negative, the ReLU output will be 0, causing a quantizer validation error.
76+
# To include positive and negative values ​​in the conv outputs, we set the conv weights to positive values.
77+
# Also set the upper half of the input tensor to positive and the lower half to negative.
78+
conv1 = tf.keras.layers.Conv2D(filters=3, kernel_size=4)
79+
conv1.build(input_shape=input_shape)
80+
kernel1, bias1 = conv1.get_weights()
81+
conv1.set_weights([np.abs(kernel1), bias1])
82+
conv2 = tf.keras.layers.Conv2D(filters=3, kernel_size=4)
83+
conv2.build(input_shape=input_shape)
84+
kernel2, bias2 = conv2.get_weights()
85+
conv2.set_weights([np.abs(kernel2), bias2])
86+
x = conv1(inputs)
87+
y = conv2(inputs)
7088
act_output = act_layer([x, y])
7189
quant_output = quant_activation_holder(act_output)
7290
return tf.keras.Model(inputs=inputs, outputs=[quant_output, act_output], name=model_name)
@@ -98,7 +116,14 @@ def build_and_save_model(self, quantizer, quantizer_params, layer, model_name, i
98116
self.assertEqual(len(quant_holder_layer), 1)
99117

100118
# Verifying activation quantization after holder
101-
output = model(np.random.randn(1, *input_shape))
119+
# If all conv outputs are negative, the ReLU output will be 0, causing a quantizer validation error.
120+
# To include positive and negative values ​​in the conv outputs, we set the conv weights to positive values.
121+
# Also set the upper half of the input tensor to positive and the lower half to negative.
122+
rand_inp = np.random.randn(1, *input_shape)
123+
sign = np.ones((1, *input_shape))
124+
sign[:, rand_inp.shape[1]//2:, :, :] = -1
125+
rand_inp = rand_inp * sign
126+
output = model(rand_inp)
102127
self.assertTrue(np.any(output[0] != output[1]), "Expecting activation layer output to be different "
103128
"from the activation holder layer output, which should be "
104129
"quantized.")

tests/compatibility_tests/torch_comp_tests/base_activation_compatibility_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@ def _build_model_with_quantization_holder(act_layer, quant_activation_holder, in
5757
class Model(torch.nn.Module):
5858
def __init__(self):
5959
super(Model, self).__init__()
60+
# If all conv outputs are negative, the ReLU output will be 0, causing a quantizer validation error.
61+
# To include positive and negative values ​​in the conv outputs, we set the conv weights to positive values.
62+
# Also set the upper half of the input tensor to positive and the lower half to negative.
6063
self.conv = torch.nn.Conv2d(in_channels=3, out_channels=3, kernel_size=4)
64+
with torch.no_grad():
65+
weight = self.conv.weight.abs()
66+
self.conv.weight.copy_(weight)
6167
self.act_layer = act_layer
6268
self.quant_activation_holder = quant_activation_holder
6369

@@ -74,8 +80,16 @@ def _build_model_with_operator_quantization_holder(act_layer, quant_activation_h
7480
class Model(torch.nn.Module):
7581
def __init__(self):
7682
super(Model, self).__init__()
83+
# If all conv outputs are negative, the ReLU output will be 0, causing a quantizer validation error.
84+
# To include positive and negative values ​​in the conv outputs, we set the conv weights to positive values.
85+
# Also set the upper half of the input tensor to positive and the lower half to negative.
7786
self.conv1 = torch.nn.Conv2d(in_channels=3, out_channels=3, kernel_size=4)
7887
self.conv2 = torch.nn.Conv2d(in_channels=3, out_channels=3, kernel_size=4)
88+
with torch.no_grad():
89+
weight1 = self.conv1.weight.abs()
90+
self.conv1.weight.copy_(weight1)
91+
weight2 = self.conv2.weight.abs()
92+
self.conv2.weight.copy_(weight2)
7993
self.act_layer = act_layer
8094
self.quant_activation_holder = quant_activation_holder
8195

@@ -115,7 +129,13 @@ def build_and_save_model(self, quantizer, quantizer_params, layer, model_name, i
115129
quant_holder_layer = [_l for _, _l in model.named_modules() if isinstance(_l, PytorchActivationQuantizationHolder)]
116130
self.assertEqual(len(quant_holder_layer), 1)
117131

132+
# If all conv outputs are negative, the ReLU output will be 0, causing a quantizer validation error.
133+
# To include positive and negative values ​​in the conv outputs, we set the conv weights to positive values.
134+
# Also set the upper half of the input tensor to positive and the lower half to negative.
118135
rand_inp = torch.rand(1, *input_shape).to(BaseActivationQuantizerBuildAndSaveTest.device)
136+
sign = torch.ones(1, *input_shape)
137+
sign[:, :, rand_inp.shape[2]//2:, :] = -1
138+
rand_inp = rand_inp * sign
119139
model = model.to(BaseActivationQuantizerBuildAndSaveTest.device)
120140

121141
# Verifying activation quantization after holder

0 commit comments

Comments
 (0)