mct-nightly 1.8.0.20052023.post401__py3-none-any.whl → 1.8.0.20230610.post356__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mct_nightly-1.8.0.20052023.post401.dist-info → mct_nightly-1.8.0.20230610.post356.dist-info}/METADATA +10 -7
- {mct_nightly-1.8.0.20052023.post401.dist-info → mct_nightly-1.8.0.20230610.post356.dist-info}/RECORD +68 -115
- model_compression_toolkit/__init__.py +23 -3
- model_compression_toolkit/core/common/framework_info.py +1 -1
- model_compression_toolkit/core/keras/back2framework/instance_builder.py +16 -9
- model_compression_toolkit/core/keras/back2framework/keras_model_builder.py +8 -34
- model_compression_toolkit/core/pytorch/back2framework/instance_builder.py +5 -1
- model_compression_toolkit/core/pytorch/back2framework/pytorch_model_builder.py +103 -28
- model_compression_toolkit/exporter/model_exporter/keras/fakely_quant_keras_exporter.py +39 -44
- model_compression_toolkit/exporter/model_exporter/keras/fakely_quant_tflite_exporter.py +1 -1
- model_compression_toolkit/exporter/model_exporter/keras/int8_tflite_exporter.py +20 -18
- model_compression_toolkit/exporter/model_exporter/pytorch/fakely_quant_onnx_pytorch_exporter.py +3 -3
- model_compression_toolkit/exporter/model_exporter/pytorch/fakely_quant_torchscript_pytorch_exporter.py +1 -1
- model_compression_toolkit/exporter/model_wrapper/keras/builder/fully_quantized_model_builder.py +36 -9
- model_compression_toolkit/exporter/model_wrapper/keras/builder/node_to_quantizer.py +4 -4
- model_compression_toolkit/exporter/model_wrapper/keras/validate_layer.py +24 -32
- model_compression_toolkit/exporter/model_wrapper/pytorch/builder/fully_quantized_model_builder.py +31 -8
- model_compression_toolkit/exporter/model_wrapper/pytorch/builder/node_to_quantizer.py +5 -5
- model_compression_toolkit/exporter/model_wrapper/pytorch/validate_layer.py +34 -8
- model_compression_toolkit/gptq/keras/gptq_training.py +15 -16
- model_compression_toolkit/gptq/keras/graph_info.py +2 -2
- model_compression_toolkit/gptq/keras/quantizer/base_keras_gptq_quantizer.py +4 -5
- model_compression_toolkit/gptq/keras/quantizer/quantization_builder.py +5 -7
- model_compression_toolkit/gptq/keras/quantizer/soft_rounding/soft_quantizer_reg.py +1 -1
- model_compression_toolkit/gptq/keras/quantizer/soft_rounding/symmetric_soft_quantizer.py +6 -6
- model_compression_toolkit/gptq/keras/quantizer/soft_rounding/uniform_soft_quantizer.py +7 -7
- model_compression_toolkit/gptq/keras/quantizer/ste_rounding/symmetric_ste.py +6 -6
- model_compression_toolkit/gptq/pytorch/gptq_training.py +30 -10
- model_compression_toolkit/gptq/pytorch/graph_info.py +5 -2
- model_compression_toolkit/gptq/pytorch/quantization_facade.py +4 -2
- model_compression_toolkit/gptq/pytorch/quantizer/base_pytorch_gptq_quantizer.py +4 -4
- model_compression_toolkit/gptq/pytorch/quantizer/quantization_builder.py +5 -7
- model_compression_toolkit/gptq/pytorch/quantizer/soft_rounding/soft_quantizer_reg.py +1 -1
- model_compression_toolkit/gptq/pytorch/quantizer/soft_rounding/symmetric_soft_quantizer.py +7 -7
- model_compression_toolkit/gptq/pytorch/quantizer/soft_rounding/uniform_soft_quantizer.py +7 -8
- model_compression_toolkit/gptq/pytorch/quantizer/ste_rounding/symmetric_ste.py +7 -8
- model_compression_toolkit/qat/common/__init__.py +2 -1
- model_compression_toolkit/qat/common/qat_config.py +2 -2
- model_compression_toolkit/qat/keras/quantization_facade.py +18 -8
- model_compression_toolkit/qat/keras/quantizer/base_keras_qat_quantizer.py +1 -1
- model_compression_toolkit/qat/keras/quantizer/quantization_builder.py +11 -11
- model_compression_toolkit/qat/keras/quantizer/ste_rounding/symmetric_ste.py +11 -12
- model_compression_toolkit/qat/keras/quantizer/ste_rounding/uniform_ste.py +12 -13
- model_compression_toolkit/qat/pytorch/quantization_facade.py +27 -16
- model_compression_toolkit/qat/pytorch/quantizer/base_pytorch_qat_quantizer.py +2 -2
- model_compression_toolkit/qat/pytorch/quantizer/quantization_builder.py +31 -4
- model_compression_toolkit/qat/pytorch/quantizer/ste_rounding/symmetric_ste.py +10 -9
- model_compression_toolkit/qat/pytorch/quantizer/ste_rounding/uniform_ste.py +11 -10
- model_compression_toolkit/target_platform_capabilities/target_platform/__init__.py +2 -1
- model_compression_toolkit/target_platform_capabilities/target_platform/op_quantization_config.py +1 -25
- model_compression_toolkit/{quantizers_infrastructure/inferable_infrastructure/keras/quantizers/constants.py → trainable_infrastructure/__init__.py} +3 -10
- model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/common/base_trainable_quantizer.py +3 -3
- model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/common/get_quantizer_config.py +1 -1
- model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/common/get_quantizers.py +3 -3
- model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/keras/base_keras_quantizer.py +4 -4
- model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/keras/config_serialization.py +2 -2
- model_compression_toolkit/{quantizers_infrastructure/inferable_infrastructure → trainable_infrastructure}/keras/load_model.py +16 -23
- model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/pytorch/base_pytorch_quantizer.py +3 -3
- model_compression_toolkit/quantizers_infrastructure/__init__.py +0 -23
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/common/base_inferable_quantizer.py +0 -87
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/common/constants.py +0 -46
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/common/get_all_subclasses.py +0 -31
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/common/get_quantizers.py +0 -53
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/common/quant_utils.py +0 -49
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/activation_quantization_holder.py +0 -147
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantize_wrapper.py +0 -345
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizer_utils.py +0 -85
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/__init__.py +0 -27
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/activation_inferable_quantizers/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/activation_inferable_quantizers/activation_lut_pot_inferable_quantizer.py +0 -148
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/activation_inferable_quantizers/activation_pot_inferable_quantizer.py +0 -65
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/activation_inferable_quantizers/activation_symmetric_inferable_quantizer.py +0 -86
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/activation_inferable_quantizers/activation_uniform_inferable_quantizer.py +0 -111
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/base_keras_inferable_quantizer.py +0 -56
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/weights_inferable_quantizers/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/weights_inferable_quantizers/weights_lut_pot_inferable_quantizer.py +0 -79
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/weights_inferable_quantizers/weights_lut_symmetric_inferable_quantizer.py +0 -179
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/weights_inferable_quantizers/weights_pot_inferable_quantizer.py +0 -67
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/weights_inferable_quantizers/weights_symmetric_inferable_quantizer.py +0 -87
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/quantizers/weights_inferable_quantizers/weights_uniform_inferable_quantizer.py +0 -163
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/keras/validation_functions.py +0 -66
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantize_wrapper.py +0 -269
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizer_utils.py +0 -152
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/__init__.py +0 -35
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/activation_inferable_quantizers/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/activation_inferable_quantizers/activation_lut_pot_inferable_quantizer.py +0 -96
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/activation_inferable_quantizers/activation_pot_inferable_quantizer.py +0 -62
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/activation_inferable_quantizers/activation_symmetric_inferable_quantizer.py +0 -83
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/activation_inferable_quantizers/activation_uniform_inferable_quantizer.py +0 -100
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/base_lut_symmetric_inferable_quantizer.py +0 -95
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/base_pytorch_inferable_quantizer.py +0 -48
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/base_symmetric_inferable_quantizer.py +0 -70
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/base_uniform_inferable_quantizer.py +0 -57
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/constants.py +0 -26
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/weights_inferable_quantizers/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/weights_inferable_quantizers/weights_lut_pot_inferable_quantizer.py +0 -77
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/weights_inferable_quantizers/weights_lut_symmetric_inferable_quantizer.py +0 -106
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/weights_inferable_quantizers/weights_pot_inferable_quantizer.py +0 -66
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/weights_inferable_quantizers/weights_symmetric_inferable_quantizer.py +0 -104
- model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/quantizers/weights_inferable_quantizers/weights_uniform_inferable_quantizer.py +0 -109
- model_compression_toolkit/quantizers_infrastructure/trainable_infrastructure/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/trainable_infrastructure/common/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/trainable_infrastructure/keras/__init__.py +0 -14
- model_compression_toolkit/quantizers_infrastructure/trainable_infrastructure/pytorch/__init__.py +0 -14
- {mct_nightly-1.8.0.20052023.post401.dist-info → mct_nightly-1.8.0.20230610.post356.dist-info}/LICENSE.md +0 -0
- {mct_nightly-1.8.0.20052023.post401.dist-info → mct_nightly-1.8.0.20230610.post356.dist-info}/WHEEL +0 -0
- {mct_nightly-1.8.0.20052023.post401.dist-info → mct_nightly-1.8.0.20230610.post356.dist-info}/top_level.txt +0 -0
- /model_compression_toolkit/{quantizers_infrastructure/inferable_infrastructure → trainable_infrastructure/common}/__init__.py +0 -0
- /model_compression_toolkit/{quantizers_infrastructure → trainable_infrastructure/common}/constants.py +0 -0
- /model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/common/quant_utils.py +0 -0
- /model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/common/trainable_quantizer_config.py +0 -0
- /model_compression_toolkit/{quantizers_infrastructure/inferable_infrastructure/common → trainable_infrastructure/keras}/__init__.py +0 -0
- /model_compression_toolkit/{quantizers_infrastructure/trainable_infrastructure → trainable_infrastructure}/keras/quantizer_utils.py +0 -0
- /model_compression_toolkit/{quantizers_infrastructure/inferable_infrastructure/keras → trainable_infrastructure/pytorch}/__init__.py +0 -0
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
# ==============================================================================
|
|
15
|
-
import warnings
|
|
16
|
-
from typing import List
|
|
17
|
-
|
|
18
|
-
import numpy as np
|
|
19
|
-
|
|
20
|
-
from model_compression_toolkit.constants import FOUND_TF
|
|
21
|
-
from model_compression_toolkit.target_platform_capabilities.target_platform import QuantizationMethod
|
|
22
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.common.base_inferable_quantizer import mark_quantizer, \
|
|
23
|
-
QuantizationTarget
|
|
24
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.common.constants import MULTIPLIER_N_BITS, EPS
|
|
25
|
-
|
|
26
|
-
if FOUND_TF:
|
|
27
|
-
import tensorflow as tf
|
|
28
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.keras.quantizers.base_keras_inferable_quantizer import \
|
|
29
|
-
BaseKerasInferableQuantizer
|
|
30
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.keras.quantizer_utils import \
|
|
31
|
-
lut_quantizer
|
|
32
|
-
|
|
33
|
-
@mark_quantizer(quantization_target=QuantizationTarget.Weights,
|
|
34
|
-
quantization_method=[QuantizationMethod.LUT_SYM_QUANTIZER],
|
|
35
|
-
quantizer_type=None)
|
|
36
|
-
class WeightsLUTSymmetricInferableQuantizer(BaseKerasInferableQuantizer):
|
|
37
|
-
"""
|
|
38
|
-
Class for quantizing weights using a lut symmetric quantizer
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
def __init__(self,
|
|
42
|
-
num_bits: int,
|
|
43
|
-
cluster_centers: np.ndarray,
|
|
44
|
-
threshold: List[float],
|
|
45
|
-
per_channel: bool,
|
|
46
|
-
channel_axis: int = None,
|
|
47
|
-
input_rank: int = None,
|
|
48
|
-
multiplier_n_bits: int = MULTIPLIER_N_BITS,
|
|
49
|
-
eps: float = EPS):
|
|
50
|
-
"""
|
|
51
|
-
Initialize the quantizer with the specified parameters.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
num_bits: number of bits to use for quantization
|
|
55
|
-
cluster_centers: the cluster centers to assign the weights
|
|
56
|
-
threshold: threshold for quantizing weights
|
|
57
|
-
per_channel: whether to use per-channel quantization
|
|
58
|
-
channel_axis: axis along which to apply per-channel quantization
|
|
59
|
-
input_rank: number of dimensions of input tensor the quantizer quantizes
|
|
60
|
-
multiplier_n_bits: Number of bits that determines the quantization range
|
|
61
|
-
eps: Small value for numerical stability in division
|
|
62
|
-
"""
|
|
63
|
-
|
|
64
|
-
super(WeightsLUTSymmetricInferableQuantizer, self).__init__()
|
|
65
|
-
|
|
66
|
-
assert isinstance(threshold, list), f'Expected threshold to be of type list but is {type(threshold)}'
|
|
67
|
-
assert all([isinstance(x, (float, np.float32, np.float64)) for x in
|
|
68
|
-
threshold]), f'Expected threshold list to contain float or np.float values but found ' \
|
|
69
|
-
f'{[type(x) for x in threshold]}'
|
|
70
|
-
|
|
71
|
-
self.threshold = np.asarray(threshold)
|
|
72
|
-
|
|
73
|
-
if per_channel:
|
|
74
|
-
assert input_rank is not None, f'Input rank is missing in per channel quantization'
|
|
75
|
-
assert channel_axis is not None, f'Channel axis is missing in per channel quantization'
|
|
76
|
-
assert len(threshold) >= 1, f'In per-channel quantization threshold list should be of length >= 1 ' \
|
|
77
|
-
f'but is {len(threshold)} '
|
|
78
|
-
else:
|
|
79
|
-
assert len(threshold) == 1, f'In per-tensor quantization threshold should be of length 1 but is' \
|
|
80
|
-
f' {len(threshold)}'
|
|
81
|
-
self.threshold = self.threshold[0]
|
|
82
|
-
|
|
83
|
-
assert len(np.unique(cluster_centers)) <= 2 ** num_bits, \
|
|
84
|
-
f'Expected num of cluster centers to be less or equal than {2 ** num_bits} ' \
|
|
85
|
-
f'but got {len(cluster_centers)}'
|
|
86
|
-
|
|
87
|
-
assert not np.any(cluster_centers - cluster_centers.astype(int)), f'Expected cluster centers to be integers'
|
|
88
|
-
|
|
89
|
-
# Weight quantization is signed, hence the quantization range is
|
|
90
|
-
# [-2**(multiplier_n_bits - 1), 2**(multiplier_n_bits - 1) - 1]
|
|
91
|
-
assert np.all((-1 * (2 ** (multiplier_n_bits - 1)) <= cluster_centers) &
|
|
92
|
-
(cluster_centers <= (2 ** (multiplier_n_bits - 1) - 1))), \
|
|
93
|
-
f'Expected cluster centers in the quantization range'
|
|
94
|
-
|
|
95
|
-
# num_bits must be less than multiplier_n_bits
|
|
96
|
-
assert num_bits <= multiplier_n_bits, f'Look-Up-Table bit configuration has {num_bits} bits. It must be ' \
|
|
97
|
-
f'less then {multiplier_n_bits}'
|
|
98
|
-
if num_bits == multiplier_n_bits:
|
|
99
|
-
warnings.warn("Num of bits equal to multiplier n bits, Please be aware LUT quantizier may be "
|
|
100
|
-
"inefficient in that case, consider using SymmetricInferableQuantizer instead")
|
|
101
|
-
|
|
102
|
-
self.num_bits = num_bits
|
|
103
|
-
self.cluster_centers = cluster_centers
|
|
104
|
-
self.multiplier_n_bits = multiplier_n_bits
|
|
105
|
-
self.eps = eps
|
|
106
|
-
self.per_channel = per_channel
|
|
107
|
-
self.channel_axis = channel_axis
|
|
108
|
-
self.input_rank = input_rank
|
|
109
|
-
|
|
110
|
-
# Tensorflow's fake_quant_with_min_max_vars_per_channel only works on last axis, so
|
|
111
|
-
# need to move the quantization axis to the last axis
|
|
112
|
-
if per_channel and channel_axis not in [-1, self.input_rank - 1]:
|
|
113
|
-
# If per-channel quantization is being used and the channel axis is not the last axis,
|
|
114
|
-
# create a permutation vector to move the channel axis to the last position
|
|
115
|
-
self.perm_vec = list(np.arange(self.input_rank))
|
|
116
|
-
self.perm_vec[channel_axis] = self.input_rank - 1
|
|
117
|
-
self.perm_vec[self.input_rank - 1] = channel_axis
|
|
118
|
-
else:
|
|
119
|
-
# If per-channel quantization is not being used or the channel axis is already the last axis,
|
|
120
|
-
# set the permutation vector to None
|
|
121
|
-
self.perm_vec = None
|
|
122
|
-
|
|
123
|
-
def __call__(self, inputs: tf.Tensor) -> tf.Tensor:
|
|
124
|
-
"""
|
|
125
|
-
Quantize the given inputs using the quantizer parameters.
|
|
126
|
-
|
|
127
|
-
Args:
|
|
128
|
-
inputs: input tensor to quantize
|
|
129
|
-
|
|
130
|
-
Returns:
|
|
131
|
-
quantized tensor.
|
|
132
|
-
"""
|
|
133
|
-
assert inputs.dtype == tf.float32, f'Input tensor was expected to be a float tensor but is of type ' \
|
|
134
|
-
f'{inputs.dtype}'
|
|
135
|
-
|
|
136
|
-
# If per-channel quantization is being used
|
|
137
|
-
if self.per_channel:
|
|
138
|
-
# If a permutation vector has been created to move the channel axis to the last position
|
|
139
|
-
if self.perm_vec:
|
|
140
|
-
# Transpose the input tensor to move the channel axis to the last position
|
|
141
|
-
inputs = tf.transpose(inputs, perm=self.perm_vec)
|
|
142
|
-
|
|
143
|
-
# Quantize the input tensor using per-channel quantization
|
|
144
|
-
q_tensor = lut_quantizer(inputs, cluster_centers=self.cluster_centers, signed=True,
|
|
145
|
-
threshold=self.threshold, multiplier_n_bits=self.multiplier_n_bits,
|
|
146
|
-
eps=self.eps)
|
|
147
|
-
if self.perm_vec:
|
|
148
|
-
# Transpose the quantized tensor back to its original shape
|
|
149
|
-
q_tensor = tf.transpose(q_tensor, perm=self.perm_vec)
|
|
150
|
-
|
|
151
|
-
# Return the quantized tensor
|
|
152
|
-
return q_tensor
|
|
153
|
-
else:
|
|
154
|
-
return lut_quantizer(inputs, cluster_centers=self.cluster_centers, signed=True,
|
|
155
|
-
threshold=self.threshold, multiplier_n_bits=self.multiplier_n_bits, eps=self.eps)
|
|
156
|
-
|
|
157
|
-
def get_config(self):
|
|
158
|
-
"""
|
|
159
|
-
Return a dictionary with the configuration of the quantizer.
|
|
160
|
-
|
|
161
|
-
Returns:
|
|
162
|
-
Dictionary with the following keys: 'per_channel', 'num_bits', 'cluster_centers', 'threshold',
|
|
163
|
-
'channel_axis', 'input_rank', 'multiplier_n_bits', 'eps'
|
|
164
|
-
"""
|
|
165
|
-
return {'per_channel': self.per_channel,
|
|
166
|
-
'num_bits': self.num_bits,
|
|
167
|
-
'cluster_centers': self.cluster_centers,
|
|
168
|
-
'threshold': self.threshold,
|
|
169
|
-
'channel_axis': self.channel_axis,
|
|
170
|
-
'input_rank': self.input_rank,
|
|
171
|
-
'multiplier_n_bits': self.multiplier_n_bits,
|
|
172
|
-
'eps': self.eps}
|
|
173
|
-
|
|
174
|
-
else:
|
|
175
|
-
class WeightsLUTSymmetricInferableQuantizer: # pragma: no cover
|
|
176
|
-
def __init__(self, *args, **kwargs):
|
|
177
|
-
raise Exception('Installing tensorflow and tensorflow_model_optimization is mandatory '
|
|
178
|
-
'when using WeightsLUTSymmetricInferableQuantizer. '
|
|
179
|
-
'Could not find Tensorflow package.')
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
# ==============================================================================
|
|
15
|
-
from typing import List
|
|
16
|
-
|
|
17
|
-
import numpy as np
|
|
18
|
-
|
|
19
|
-
from model_compression_toolkit.constants import FOUND_TF
|
|
20
|
-
from model_compression_toolkit.target_platform_capabilities.target_platform import QuantizationMethod
|
|
21
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.common.base_inferable_quantizer import mark_quantizer, QuantizationTarget
|
|
22
|
-
|
|
23
|
-
if FOUND_TF:
|
|
24
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.keras.quantizers.weights_inferable_quantizers.weights_symmetric_inferable_quantizer \
|
|
25
|
-
import WeightsSymmetricInferableQuantizer
|
|
26
|
-
|
|
27
|
-
@mark_quantizer(quantization_target=QuantizationTarget.Weights,
|
|
28
|
-
quantization_method=[QuantizationMethod.POWER_OF_TWO],
|
|
29
|
-
quantizer_type=None)
|
|
30
|
-
class WeightsPOTInferableQuantizer(WeightsSymmetricInferableQuantizer):
|
|
31
|
-
"""
|
|
32
|
-
Class for quantizing weights using power-of-two quantizer
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
def __init__(self,
|
|
36
|
-
num_bits: int,
|
|
37
|
-
threshold: List[float],
|
|
38
|
-
per_channel: bool,
|
|
39
|
-
channel_axis: int = None,
|
|
40
|
-
input_rank: int = None):
|
|
41
|
-
"""
|
|
42
|
-
Initialize the quantizer with the specified parameters.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
num_bits: number of bits to use for quantization
|
|
46
|
-
threshold: threshold for quantizing activations
|
|
47
|
-
per_channel: whether to use per-channel quantization
|
|
48
|
-
channel_axis: axis along which to apply per-channel quantization
|
|
49
|
-
input_rank: number of dimensions of input tensor the quantizer quantizes
|
|
50
|
-
"""
|
|
51
|
-
# Call the superclass constructor with the given parameters, along with the target of Weights quantization
|
|
52
|
-
super(WeightsPOTInferableQuantizer, self).__init__(num_bits=num_bits,
|
|
53
|
-
threshold=threshold,
|
|
54
|
-
per_channel=per_channel,
|
|
55
|
-
channel_axis=channel_axis,
|
|
56
|
-
input_rank=input_rank)
|
|
57
|
-
|
|
58
|
-
is_threshold_pot = np.all([int(np.log2(x)) == np.log2(x) for x in self.threshold.flatten()])
|
|
59
|
-
assert is_threshold_pot, f'Expected threshold to be power of 2 but is {self.threshold}'
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
else:
|
|
63
|
-
class WeightsPOTInferableQuantizer: # pragma: no cover
|
|
64
|
-
def __init__(self, *args, **kwargs):
|
|
65
|
-
raise Exception('Installing tensorflow and tensorflow_model_optimization is mandatory '
|
|
66
|
-
'when using WeightsPOTInferableQuantizer. '
|
|
67
|
-
'Could not find Tensorflow package.')
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
# ==============================================================================
|
|
15
|
-
from typing import List
|
|
16
|
-
|
|
17
|
-
import numpy as np
|
|
18
|
-
|
|
19
|
-
from model_compression_toolkit.constants import FOUND_TF
|
|
20
|
-
|
|
21
|
-
from model_compression_toolkit.target_platform_capabilities.target_platform import QuantizationMethod
|
|
22
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.common.base_inferable_quantizer import mark_quantizer, QuantizationTarget
|
|
23
|
-
|
|
24
|
-
if FOUND_TF:
|
|
25
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.keras.quantizers.weights_inferable_quantizers.weights_uniform_inferable_quantizer \
|
|
26
|
-
import WeightsUniformInferableQuantizer
|
|
27
|
-
|
|
28
|
-
@mark_quantizer(quantization_target=QuantizationTarget.Weights,
|
|
29
|
-
quantization_method=[QuantizationMethod.SYMMETRIC],
|
|
30
|
-
quantizer_type=None)
|
|
31
|
-
class WeightsSymmetricInferableQuantizer(WeightsUniformInferableQuantizer):
|
|
32
|
-
"""
|
|
33
|
-
Class for quantizing weights using a symmetric quantizer
|
|
34
|
-
"""
|
|
35
|
-
def __init__(self,
|
|
36
|
-
num_bits: int,
|
|
37
|
-
threshold: List[float],
|
|
38
|
-
per_channel: bool,
|
|
39
|
-
channel_axis: int = None,
|
|
40
|
-
input_rank: int = None
|
|
41
|
-
):
|
|
42
|
-
"""
|
|
43
|
-
Initialize the quantizer with the specified parameters.
|
|
44
|
-
|
|
45
|
-
Args:
|
|
46
|
-
num_bits: number of bits to use for quantization
|
|
47
|
-
threshold: threshold for quantizing weights
|
|
48
|
-
per_channel: whether to use per-channel quantization
|
|
49
|
-
channel_axis: axis along which to apply per-channel quantization
|
|
50
|
-
input_rank: number of dimensions of input tensor the quantizer quantizes
|
|
51
|
-
"""
|
|
52
|
-
assert isinstance(threshold, list), f'Expected threshold to be of type list but is {type(threshold)}'
|
|
53
|
-
assert all([isinstance(x, (float, np.float32, np.float64)) for x in
|
|
54
|
-
threshold]), f'Expected threshold list to contain float or np.float values but found ' \
|
|
55
|
-
f'{[type(x) for x in threshold]}'
|
|
56
|
-
|
|
57
|
-
self.threshold = np.asarray(threshold)
|
|
58
|
-
|
|
59
|
-
_min_range = -self.threshold
|
|
60
|
-
_max_range = self.threshold - self.threshold / (2 ** (num_bits - 1))
|
|
61
|
-
|
|
62
|
-
super(WeightsSymmetricInferableQuantizer, self).__init__(num_bits=num_bits,
|
|
63
|
-
min_range=list(_min_range),
|
|
64
|
-
max_range=list(_max_range),
|
|
65
|
-
per_channel=per_channel,
|
|
66
|
-
channel_axis=channel_axis,
|
|
67
|
-
input_rank=input_rank)
|
|
68
|
-
|
|
69
|
-
def get_config(self):
|
|
70
|
-
"""
|
|
71
|
-
Return a dictionary with the configuration of the quantizer.
|
|
72
|
-
|
|
73
|
-
Returns:
|
|
74
|
-
Dictionary with the following keys: 'num_bits', 'threshold', 'per_channel', 'channel_axis'
|
|
75
|
-
"""
|
|
76
|
-
return {'num_bits': self.num_bits,
|
|
77
|
-
'threshold': self.threshold,
|
|
78
|
-
'per_channel': self.per_channel,
|
|
79
|
-
'channel_axis': self.channel_axis,
|
|
80
|
-
'input_rank': self.input_rank}
|
|
81
|
-
|
|
82
|
-
else:
|
|
83
|
-
class WeightsSymmetricInferableQuantizer: # pragma: no cover
|
|
84
|
-
def __init__(self, *args, **kwargs):
|
|
85
|
-
raise Exception('Installing tensorflow and tensorflow_model_optimization is mandatory '
|
|
86
|
-
'when using WeightsPOTInferableQuantizer. '
|
|
87
|
-
'Could not find Tensorflow package.')
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
# ==============================================================================
|
|
15
|
-
from typing import List
|
|
16
|
-
|
|
17
|
-
import numpy as np
|
|
18
|
-
|
|
19
|
-
from model_compression_toolkit.constants import FOUND_TF
|
|
20
|
-
from model_compression_toolkit.target_platform_capabilities.target_platform import QuantizationMethod
|
|
21
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.common.base_inferable_quantizer import mark_quantizer, QuantizationTarget
|
|
22
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.common.quant_utils import \
|
|
23
|
-
adjust_range_to_include_zero
|
|
24
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.keras.validation_functions import \
|
|
25
|
-
validate_uniform_min_max_ranges, validate_adjusted_min_max_ranges
|
|
26
|
-
|
|
27
|
-
if FOUND_TF:
|
|
28
|
-
import tensorflow as tf
|
|
29
|
-
from model_compression_toolkit.quantizers_infrastructure.inferable_infrastructure.keras.quantizers.base_keras_inferable_quantizer import BaseKerasInferableQuantizer
|
|
30
|
-
|
|
31
|
-
@mark_quantizer(quantization_target=QuantizationTarget.Weights,
|
|
32
|
-
quantization_method=[QuantizationMethod.UNIFORM],
|
|
33
|
-
quantizer_type=None)
|
|
34
|
-
class WeightsUniformInferableQuantizer(BaseKerasInferableQuantizer):
|
|
35
|
-
"""
|
|
36
|
-
Class for quantizing weights using a uniform quantizer
|
|
37
|
-
"""
|
|
38
|
-
def __init__(self,
|
|
39
|
-
num_bits: int,
|
|
40
|
-
min_range: List[float],
|
|
41
|
-
max_range: List[float],
|
|
42
|
-
per_channel: bool,
|
|
43
|
-
channel_axis: int = None,
|
|
44
|
-
input_rank: int = None
|
|
45
|
-
):
|
|
46
|
-
"""
|
|
47
|
-
Initialize the quantizer with the specified parameters.
|
|
48
|
-
|
|
49
|
-
Args:
|
|
50
|
-
num_bits: number of bits to use for quantization
|
|
51
|
-
min_range: min quantization range for quantizing weights
|
|
52
|
-
max_range: max quantization range for quantizing weights
|
|
53
|
-
per_channel: whether to use per-channel quantization
|
|
54
|
-
channel_axis: axis along which to apply per-channel quantization
|
|
55
|
-
input_rank: number of dimensions of input tensor the quantizer quantizes
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
super(WeightsUniformInferableQuantizer, self).__init__()
|
|
59
|
-
|
|
60
|
-
# Validate inputs properties
|
|
61
|
-
validate_uniform_min_max_ranges(min_range,
|
|
62
|
-
max_range)
|
|
63
|
-
|
|
64
|
-
# Convert min/max to numpy arrays
|
|
65
|
-
min_range, max_range = np.asarray(min_range), np.asarray(max_range)
|
|
66
|
-
_min_range, _max_range = adjust_range_to_include_zero(min_range, max_range, num_bits)
|
|
67
|
-
validate_adjusted_min_max_ranges(min_range=min_range,
|
|
68
|
-
max_range=max_range,
|
|
69
|
-
adj_min=_min_range,
|
|
70
|
-
adj_max=_max_range)
|
|
71
|
-
|
|
72
|
-
self.num_bits = num_bits
|
|
73
|
-
self.max_range = _max_range
|
|
74
|
-
self.min_range = _min_range
|
|
75
|
-
|
|
76
|
-
if per_channel:
|
|
77
|
-
assert input_rank is not None, f'Input rank is missing in per channel quantization'
|
|
78
|
-
assert channel_axis is not None, f'Channel axis is missing in per channel quantization'
|
|
79
|
-
assert len(self.min_range) >= 1, f'In per-channel quantization min ranges list should be of length >= 1 but is {len(self.min_range)}'
|
|
80
|
-
assert len(self.max_range) >= 1, f'In per-channel quantization max ranges list should be of length >= 1 but is {len(self.max_range)}'
|
|
81
|
-
else:
|
|
82
|
-
assert len(self.min_range) == 1, f'In per-tensor quantization min/max should be of length 1 but is {len(min_range)}'
|
|
83
|
-
assert len(self.min_range) == 1, f'In per-tensor quantization min_range should be of length 1 but is {len(self.min_range)}'
|
|
84
|
-
assert len(self.max_range) == 1, f'In per-tensor quantization max_range should be of length 1 but is {len(self.max_range)}'
|
|
85
|
-
self.min_range = self.min_range[0]
|
|
86
|
-
self.max_range = self.max_range[0]
|
|
87
|
-
|
|
88
|
-
self.per_channel = per_channel
|
|
89
|
-
self.channel_axis = channel_axis
|
|
90
|
-
self.input_rank = input_rank
|
|
91
|
-
|
|
92
|
-
# Tensorflow's fake_quant_with_min_max_vars_per_channel only works on last axis, so
|
|
93
|
-
# need to move the quantization axis to the last axis
|
|
94
|
-
if per_channel and channel_axis not in [-1, self.input_rank - 1]:
|
|
95
|
-
# If per-channel quantization is being used and the channel axis is not the last axis,
|
|
96
|
-
# create a permutation vector to move the channel axis to the last position
|
|
97
|
-
self.perm_vec = list(np.arange(self.input_rank))
|
|
98
|
-
self.perm_vec[channel_axis] = self.input_rank - 1
|
|
99
|
-
self.perm_vec[self.input_rank - 1] = channel_axis
|
|
100
|
-
else:
|
|
101
|
-
# If per-channel quantization is not being used or the channel axis is already the last axis,
|
|
102
|
-
# set the permutation vector to None
|
|
103
|
-
self.perm_vec = None
|
|
104
|
-
|
|
105
|
-
def __call__(self, inputs: tf.Tensor) -> tf.Tensor:
|
|
106
|
-
"""
|
|
107
|
-
Quantize the given inputs using the quantizer parameters.
|
|
108
|
-
|
|
109
|
-
Args:
|
|
110
|
-
inputs: input tensor to quantize
|
|
111
|
-
|
|
112
|
-
Returns:
|
|
113
|
-
quantized tensor.
|
|
114
|
-
"""
|
|
115
|
-
assert inputs.dtype==tf.float32, f'Input tensor was expected to be a float tensor but is of type {inputs.dtype}'
|
|
116
|
-
|
|
117
|
-
# If per-channel quantization is being used
|
|
118
|
-
if self.per_channel:
|
|
119
|
-
# If a permutation vector has been created to move the channel axis to the last position
|
|
120
|
-
if self.perm_vec:
|
|
121
|
-
# Transpose the input tensor to move the channel axis to the last position
|
|
122
|
-
inputs = tf.transpose(inputs, perm=self.perm_vec)
|
|
123
|
-
|
|
124
|
-
# Quantize the input tensor using per-channel quantization
|
|
125
|
-
q_tensor = tf.quantization.fake_quant_with_min_max_vars_per_channel(inputs,
|
|
126
|
-
min=self.min_range,
|
|
127
|
-
max=self.max_range,
|
|
128
|
-
num_bits=self.num_bits)
|
|
129
|
-
if self.perm_vec:
|
|
130
|
-
# Transpose the quantized tensor back to its original shape
|
|
131
|
-
q_tensor = tf.transpose(q_tensor, perm=self.perm_vec)
|
|
132
|
-
|
|
133
|
-
# Return the quantized tensor
|
|
134
|
-
return q_tensor
|
|
135
|
-
else:
|
|
136
|
-
# If per-channel quantization is not being used, quantize the input tensor using regular quantization
|
|
137
|
-
return tf.quantization.fake_quant_with_min_max_vars(inputs,
|
|
138
|
-
min=self.min_range,
|
|
139
|
-
max=self.max_range,
|
|
140
|
-
num_bits=self.num_bits)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def get_config(self):
|
|
144
|
-
"""
|
|
145
|
-
Return a dictionary with the configuration of the quantizer.
|
|
146
|
-
|
|
147
|
-
Returns:
|
|
148
|
-
Dictionary with the following keys: 'num_bits', 'min_range', 'max_range', 'per_channel', 'channel_axis'
|
|
149
|
-
"""
|
|
150
|
-
return {'per_channel': self.per_channel,
|
|
151
|
-
'num_bits': self.num_bits,
|
|
152
|
-
'max_range': self.max_range,
|
|
153
|
-
'min_range': self.min_range,
|
|
154
|
-
'channel_axis': self.channel_axis,
|
|
155
|
-
'input_rank': self.input_rank}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
else:
|
|
159
|
-
class WeightsUniformInferableQuantizer: # pragma: no cover
|
|
160
|
-
def __init__(self, *args, **kwargs):
|
|
161
|
-
raise Exception('Installing tensorflow and tensorflow_model_optimization is mandatory '
|
|
162
|
-
'when using WeightsUniformInferableQuantizer. '
|
|
163
|
-
'Could not find Tensorflow package.')
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
# ==============================================================================
|
|
15
|
-
from typing import Any
|
|
16
|
-
|
|
17
|
-
import numpy as np
|
|
18
|
-
|
|
19
|
-
from model_compression_toolkit.logger import Logger
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def validate_uniform_min_max_ranges(min_range: Any, max_range: Any) -> None:
|
|
23
|
-
"""
|
|
24
|
-
Validate min/max ranges in uniform quantizers are valid
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
min_range: min range list to check
|
|
28
|
-
max_range: max range list to check
|
|
29
|
-
|
|
30
|
-
"""
|
|
31
|
-
assert isinstance(min_range, list), f'Expected min_range to be of type list but is {type(min_range)}'
|
|
32
|
-
assert isinstance(max_range, list), f'Expected max_range to be of type list but is {type(max_range)}'
|
|
33
|
-
|
|
34
|
-
assert all([isinstance(x, (float, np.float32, np.float64)) for x in
|
|
35
|
-
min_range]), f'Expected min_range list to contain float values but found {[type(x) for x in min_range]}'
|
|
36
|
-
assert all([isinstance(x, (float, np.float32, np.float64)) for x in
|
|
37
|
-
max_range]), f'Expected max_range list to contain float values but found {[type(x) for x in max_range]}'
|
|
38
|
-
|
|
39
|
-
assert len(min_range) == len(
|
|
40
|
-
max_range), f'Expected min/max values to have the same length but min shape: {len(min_range)} and max shape: ' \
|
|
41
|
-
f'{len(max_range)}'
|
|
42
|
-
|
|
43
|
-
# Convert min/max to numpy arrays
|
|
44
|
-
min_range, max_range = np.asarray(min_range), np.asarray(max_range)
|
|
45
|
-
assert np.all(max_range > min_range), f'Expected max_range to be bigger than min_range!'
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def validate_adjusted_min_max_ranges(min_range: Any,
|
|
49
|
-
max_range: Any,
|
|
50
|
-
adj_min:Any,
|
|
51
|
-
adj_max:Any) -> None:
|
|
52
|
-
"""
|
|
53
|
-
Validate adjusted min/max ranges in uniform quantization are valid
|
|
54
|
-
|
|
55
|
-
Args:
|
|
56
|
-
min_range: original min range
|
|
57
|
-
max_range: original max range
|
|
58
|
-
adj_min: adjusted min range
|
|
59
|
-
adj_max: adjusted max range
|
|
60
|
-
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
assert np.all(adj_min <= 0) and np.all(
|
|
64
|
-
adj_max >= 0), f'Expected zero to be in the range, got min_range={adj_min}, max_range={adj_max}'
|
|
65
|
-
if not np.isclose(np.linalg.norm(adj_min - min_range), 0, atol=1e-6) or not np.isclose(np.linalg.norm(adj_max - max_range), 0, atol=1e-6):
|
|
66
|
-
Logger.warning(f"Adjusting (min_range, max_range) from ({min_range},{max_range}) to ({adj_min},{adj_max})") # pragma: no cover
|
model_compression_toolkit/quantizers_infrastructure/inferable_infrastructure/pytorch/__init__.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
# ==============================================================================
|