Skip to content

Commit ab5da23

Browse files
elad-cOfir Gordon
andauthored
Fix FQ exporter for 16bit act quant and constant quantization (#1463)
Remove _replace_wrapped_with_unwrapped from FQ exporter as it's not needed. Remove PytorchActivationQuantizationHolder with num_bits > 8, because ONNX doesn't support it. --------- Co-authored-by: Ofir Gordon <ofirgo@sony.com>
1 parent de182fb commit ab5da23

3 files changed

Lines changed: 19 additions & 8 deletions

File tree

model_compression_toolkit/exporter/model_exporter/pytorch/base_pytorch_exporter.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def _search(m):
5656
f"Only the first one was assigned to 'model.metadata'.")
5757

5858

59-
def _set_quantized_weights_in_wrapper(layer:PytorchQuantizationWrapper):
59+
def _set_quantized_weights_in_wrapper(layer: PytorchQuantizationWrapper):
6060
"""
6161
Sets the quantized weights in the provided PytorchQuantizationWrapper layer.
6262
Replaces the original weights in the layer with the quantized weights.
@@ -124,7 +124,7 @@ def __init__(self,
124124
self.model = copy.deepcopy(self.model)
125125
self.repr_dataset = repr_dataset
126126

127-
def _substitute_fully_quantized_model(self):
127+
def _substitute_fully_quantized_model(self, replace_wrapped=True):
128128
"""
129129
Substitution for pytorch "fully-quantized" models. It first uses the weight quantizers
130130
in PytorchQuantizationWrapper layers to quantize the weights and set them in the layer.
@@ -136,8 +136,9 @@ def _substitute_fully_quantized_model(self):
136136
if isinstance(layer, PytorchQuantizationWrapper):
137137
_set_quantized_weights_in_wrapper(layer)
138138

139-
# Replace PytorchQuantizationWrapper layers with their internal layers
140-
self._replace_wrapped_with_unwrapped()
139+
if replace_wrapped:
140+
# Replace PytorchQuantizationWrapper layers with their internal layers
141+
self._replace_wrapped_with_unwrapped()
141142

142143
def _replace_wrapped_with_unwrapped(self):
143144
"""
@@ -148,3 +149,4 @@ def _replace_wrapped_with_unwrapped(self):
148149
for name, module in self.model.named_children():
149150
if isinstance(module, PytorchQuantizationWrapper):
150151
setattr(self.model, name, module.layer)
152+

model_compression_toolkit/exporter/model_exporter/pytorch/fakely_quant_onnx_pytorch_exporter.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ def export(self, output_names=None) -> None:
7373
Returns:
7474
Fake-quant PyTorch model.
7575
"""
76+
# List all activation quantization holders with num_bits>8 and replace them with Identity, because
77+
# ONNX doesn't support quantization of more than 8 bits for torch.fake_quantize_per_tensor_affine.
78+
act_holder_list = [n for n, m in self.model.named_modules()
79+
if isinstance(m, PytorchActivationQuantizationHolder) and
80+
m.activation_holder_quantizer.num_bits > 8]
81+
for act_holder in act_holder_list: # pragma: no cover
82+
delattr(self.model, act_holder)
83+
setattr(self.model, act_holder, torch.nn.Identity())
84+
7685
for layer in self.model.children():
7786
self.is_layer_exportable_fn(layer)
7887
# Set reuse for weight quantizers if quantizer is reused
@@ -89,7 +98,7 @@ def export(self, output_names=None) -> None:
8998
if self._use_onnx_custom_quantizer_ops:
9099
self._enable_onnx_custom_ops_export()
91100
else:
92-
self._substitute_fully_quantized_model()
101+
self._substitute_fully_quantized_model(replace_wrapped=False)
93102

94103
if self._use_onnx_custom_quantizer_ops:
95104
Logger.info(f"Exporting onnx model with MCTQ quantizers: {self.save_model_path}")
@@ -166,6 +175,6 @@ def _enable_onnx_custom_ops_export(self):
166175
wq.enable_custom_impl()
167176

168177
else:
169-
def FakelyQuantONNXPyTorchExporter(*args, **kwargs):
178+
def FakelyQuantONNXPyTorchExporter(*args, **kwargs): # pragma: no cover
170179
Logger.critical("ONNX must be installed to use 'FakelyQuantONNXPyTorchExporter'. "
171-
"The 'onnx' package is missing.") # pragma: no cover
180+
"The 'onnx' package is missing.")

tests/pytorch_tests/function_tests/test_export_pytorch_fully_quantized_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def to_numpy(tensor):
9898
return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy()
9999

100100
# get onnx conv weight
101-
conv_weight_name = 'conv1.weight'
101+
conv_weight_name = 'conv1.layer.weight'
102102
from onnx import numpy_helper
103103
INTIALIZERS = self.exported_model_onnx.graph.initializer
104104
Weight = []

0 commit comments

Comments
 (0)