Full integer quantization not possible with grouped convolution
@justlike-prog Could you have a look at this [page](https://www.tensorflow.org/lite/performance/post_training_quantization) and let me know if it gives enough information regarding integer quantization?
In order to expedite the trouble-shooting process, please provide a code snippet to reproduce the issue reported here. Thank you!
 @sushreebarsa Code snippet is above. Yes, I check that page already (obviously), but it doesn't help me with my issue. Basically the issue is that the number of input channels is not divisible by number of channels in one group, hence the number of groups cannot be determined. Apparently this is not a problem when doing dynamic range quantization and in this case the tflite model works fine. For Full integer quantiation this doesn't work though. Hi @justlike-prog 

Thanks for bringing this issue.

Will it possible to share the .pb file so that it will help us to reproduce the issue and investigate further?

Thanks. @pjpratik yeah sure. here is a link to the pb [https://drive.google.com/file/d/1jFBdUAbEEZdgImt6DHiXOwNLQx9w2pUv/view?usp=sharing](url) Hi @justlike-prog 

Thanks for sharing the model. I have tried to reproduce with different conversions criteria including dynamic range quantization and full integer quantization and I was successfully able to convert it into TFLite model.

Please find this [gist](https://colab.research.google.com/gist/pjpratik/3fe6f84376642f50d3fc9fbd6fe870a0/61760.ipynb).

The representative dataset generator might be causing the problem. The model expects the input shape of `[1,3,224,224]` and we need to provide the representative data accordingly.

Thanks. This issue is stale because it has been open for 7 days with no activity. It will be closed if no further activity occurs. Thank you. > Hi @justlike-prog
> 
> Thanks for sharing the model. I have tried to reproduce with different conversions criteria including dynamic range quantization and full integer quantization and I was successfully able to convert it into TFLite model.
> 
> Please find this [gist](https://colab.research.google.com/gist/pjpratik/3fe6f84376642f50d3fc9fbd6fe870a0/61760.ipynb).
> 
> The representative dataset generator might be causing the problem. The model expects the input shape of `[1,3,224,224]` and we need to provide the representative data accordingly.
> 
> Thanks.

Thank you, you were right about the input shape. Somehow I missed this. Now I am running into the problem that when I load the model in the interpreter the jupyter notebook kernel crashes. Also if I try to run it on Android I get problems that look like a memory leak. Can you try to reproduce this issue with the model crashing after full integer quantization on your side? This does not happen with dynamic range quantization. Thank you! @pjpratik  Hi @justlike-prog 

This seems to be an issue with pytorch->tflite conversion. I was able to reproduce this. Please find this [gist](https://colab.research.google.com/gist/pjpratik/c5f0775a22bbb88511359c47e586bafb/61760.ipynb).

@pkgoogle Could you please look into this issue?

Thanks. Reproducible with Pratik's [gist](https://colab.sandbox.google.com/gist/pjpratik/c5f0775a22bbb88511359c47e586bafb/61760.ipynb), Hi @abattery, can you please take a look? Thanks.


### 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?
