Repository: tensorflow
Issue: Full integer quantization not possible with grouped convolution
Labels: stat:awaiting tensorflower,type:bug,TFLiteConverter,ModelOptimizationToolkit,TF 2.13

### 1. System information

- OS Platform and Distribution (e.g., Linux Ubuntu 16.04): MacOS 12.5
- TensorFlow installation (pip package or built from source): pip
- TensorFlow library (version, if pip package or github SHA, if built from source): 2.13

### 2. Code

Provide code to help us reproduce your issues using one of the following options:

```
train_ds = tf.keras.utils.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

def representative_data_gen():
  for input_value, labels in train_ds:
    yield [input_value]

converter = tf.lite.TFLiteConverter.from_saved_model('./model.pb')
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_data_gen

tflite_model = converter.convert()

with open('model.tflite', 'wb') as f:
    f.write(tflite_model)
```

The error that I get is 

```
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[15], line 8
      3 #converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8, tf.lite.OpsSet.SELECT_TF_OPS]
      4 #converter.inference_input_type = tf.int8
      5 #converter.inference_output_type = tf.int8
      6 converter.representative_dataset = representative_data_gen
----> 8 tflite_model = converter.convert()
     10 with open('model.tflite', 'wb') as f:
     11     f.write(tflite_model)

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/lite.py:1065, in _export_metrics.<locals>.wrapper(self, *args, **kwargs)
   1062 @functools.wraps(convert_func)
   1063 def wrapper(self, *args, **kwargs):
   1064   # pylint: disable=protected-access
-> 1065   return self._convert_and_export_metrics(convert_func, *args, **kwargs)

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/lite.py:1042, in TFLiteConverterBase._convert_and_export_metrics(self, convert_func, *args, **kwargs)
   1040 self._save_conversion_params_metric()
   1041 start_time = time.process_time()
-> 1042 result = convert_func(self, *args, **kwargs)
   1043 elapsed_time_ms = (time.process_time() - start_time) * 1000
   1044 if result:

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/lite.py:1390, in TFLiteSavedModelConverterV2.convert(self)
   1384 else:
   1385   self._debug_info = _get_debug_info(
   1386       _convert_debug_info_func(self._trackable_obj.graph_debug_info),
   1387       graph_def,
   1388   )
-> 1390 return self._convert_from_saved_model(graph_def)

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/lite.py:1257, in TFLiteConverterBaseV2._convert_from_saved_model(self, graph_def)
   1254 converter_kwargs.update(quant_mode.converter_flags())
   1256 result = _convert_saved_model(**converter_kwargs)
-> 1257 return self._optimize_tflite_model(
   1258     result, quant_mode, quant_io=self.experimental_new_quantizer
   1259 )

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/convert_phase.py:215, in convert_phase.<locals>.actual_decorator.<locals>.wrapper(*args, **kwargs)
    213 except Exception as error:
    214   report_error_message(str(error))
--> 215   raise error from None

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/convert_phase.py:205, in convert_phase.<locals>.actual_decorator.<locals>.wrapper(*args, **kwargs)
    202 @functools.wraps(func)
    203 def wrapper(*args, **kwargs):
    204   try:
--> 205     return func(*args, **kwargs)
    206   except ConverterError as converter_error:
    207     if converter_error.errors:

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/lite.py:991, in TFLiteConverterBase._optimize_tflite_model(self, model, quant_mode, quant_io)
    989   q_allow_float = quant_mode.is_allow_float()
    990   q_variable_quantization = quant_mode.enable_mlir_variable_quantization
--> 991   model = self._quantize(
    992       model,
    993       q_in_type,
    994       q_out_type,
    995       q_activations_type,
    996       q_bias_type,
    997       q_allow_float,
    998       q_variable_quantization,
    999   )
   1001 m_in_type = in_type if in_type else _dtypes.float32
   1002 m_out_type = out_type if out_type else _dtypes.float32

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/lite.py:710, in TFLiteConverterBase._quantize(self, result, input_type, output_type, activations_type, bias_type, allow_float, enable_variable_quantization)
    706 calibrate_quantize = _calibrator.Calibrator(
    707     result, custom_op_registerers_by_name, custom_op_registerers_by_func
    708 )
    709 if self._experimental_calibrate_only or self.experimental_new_quantizer:
--> 710   calibrated = calibrate_quantize.calibrate(
    711       self.representative_dataset.input_gen
    712   )
    714 if self._experimental_calibrate_only:
    715   return calibrated

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/convert_phase.py:215, in convert_phase.<locals>.actual_decorator.<locals>.wrapper(*args, **kwargs)
    213 except Exception as error:
    214   report_error_message(str(error))
--> 215   raise error from None

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/convert_phase.py:205, in convert_phase.<locals>.actual_decorator.<locals>.wrapper(*args, **kwargs)
    202 @functools.wraps(func)
    203 def wrapper(*args, **kwargs):
    204   try:
--> 205     return func(*args, **kwargs)
    206   except ConverterError as converter_error:
    207     if converter_error.errors:

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/optimize/calibrator.py:254, in Calibrator.calibrate(self, dataset_gen)
    244 @convert_phase(Component.OPTIMIZE_TFLITE_MODEL, SubComponent.CALIBRATE)
    245 def calibrate(self, dataset_gen):
    246   """Calibrates the model with specified generator.
    247 
    248   Returns:
   (...)
    252     dataset_gen: A generator that generates calibration samples.
    253   """
--> 254   self._feed_tensors(dataset_gen, resize_input=True)
    255   return self._calibrator.Calibrate()

File ~/miniforge3/envs/tf213/lib/python3.10/site-packages/tensorflow/lite/python/optimize/calibrator.py:143, in Calibrator._feed_tensors(self, dataset_gen, resize_input)
    139     self._calibrator.Prepare(
    140         [list(s.shape) for s in input_array], signature_key
    141     )
    142   else:
--> 143     self._calibrator.Prepare([list(s.shape) for s in input_array])
    144 else:
    145   if signature_key is not None:

RuntimeError: tensorflow/lite/kernels/conv.cc:352 input_channel % filter_input_channel != 0 (2 != 0)Node number 6 (CONV_2D) failed to prepare.
```

The model itself got converted from pytorch to onnx and then to pb. The issue here is that the model has a grouped convolutional layers. This is fixed for dynamic range quantisation but for full integer quantisation using a representative dataset this still seems to fail. Any quick fix possible?