code: def quantize_model(
      sym,
      arg_params,
      aux_params,
      data_names=("data",),
      device=cpu(),
      excluded_sym_names=None,
      excluded_op_names=None,
      calib_mode="entropy",
      calib_data=None,
      num_calib_batches=None,
      quantized_dtype="int8",
      quantize_mode="smart",
      quantize_granularity="tensor-wise",
      logger=None,
  ):
      """User-level API for generating a quantized model from a FP32 model w/ or w/o calibration.
      The backend quantized operators are only enabled for Linux systems. Please do not run
      inference using the quantized models on Windows for now.
      The quantization implementation adopts the TensorFlow's approach:
      https://www.tensorflow.org/lite/performance/post_training_quantization.
      The calibration implementation borrows the idea of Nvidia's 8-bit Inference with TensorRT:
      http://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf
      and adapts the method to MXNet.
  
      .. _`quantize_model_params`:
  
      Parameters
      ----------
      sym : Symbol
          Defines the structure of a neural network for FP32 data types.
      arg_params : dict
          Dictionary of name to `NDArray`.
      aux_params : dict
          Dictionary of name to `NDArray`.
      data_names : list of strings
          Data names required for creating a Module object to run forward propagation on the
          calibration dataset.
      device : Device
          Defines the device that users want to run forward propagation on the calibration
          dataset for collecting layer output statistics. Currently, only supports single device.
      excluded_sym_names : list of strings
          A list of strings representing the names of the symbols that users want to excluding
          from being quantized.
      excluded_op_names : list of strings
          A list of strings representing the names of the operators that users want to excluding
          from being quantized.
      calib_mode : str
          If calib_mode='none', no calibration will be used and the thresholds for
          requantization after the corresponding layers will be calculated at runtime by
          calling min and max operators. The quantized models generated in this
          mode are normally 10-20% slower than those with calibrations during inference.
          If calib_mode='naive', the min and max values of the layer outputs from a calibration
          dataset will be directly taken as the thresholds for quantization.
          If calib_mode='entropy' (default mode), the thresholds for quantization will be
          derived such that the KL divergence between the distributions of FP32 layer outputs and
          quantized layer outputs is minimized based upon the calibration dataset.
      calib_data : DataLoader
          A DataLoader initialized by the calibration dataset.
      num_calib_batches : int or None
          The maximum number of batches that user would like to use for calibration. If not provided,
          the whole calibration dataset will be used.
      quantized_dtype : str
          The quantized destination type for input data. Currently support 'int8', 'uint8' and 'auto'.
          'auto' means automatically select output type according to calibration result.
          Default value is 'int8'.
      quantize_mode : str
          The mode that quantization pass to apply. Support 'full' and 'smart'.
          'full' means quantize all operator if possible.
          'smart' means quantization pass will smartly choice which operator should be quantized.
      quantize_granularity : str
          The granularity of quantization, currently supports 'tensor-wise' and 'channel-wise'
          quantization. The default value is 'tensor-wise'.
      logger : Object
          A logging object for printing information during the process of quantization.
  
      Returns
      -------
      quantized_model : tuple
          A tuple of quantized symbol, quantized arg_params, and aux_params.
      """
      warnings.warn(
          "WARNING: This will be deprecated please use quantize_net with Gluon models"
      )
      if excluded_sym_names is None:
          excluded_sym_names = []
      if not isinstance(excluded_sym_names, list):
          raise ValueError(
              "excluded_sym_names must be a list of strings representing"
              " the names of the symbols that will not be quantized,"
              f" while received type {str(type(excluded_sym_names))}"
          )
  
      if excluded_op_names is None:
          excluded_op_names = []
      if not isinstance(excluded_op_names, list):
          raise ValueError(
              "excluded_op_names must be a list of strings representing"
              " the names of the operators that will not be quantized,"
              f" while received type {str(type(excluded_op_names))}"
          )
  
      if logger:
          os.environ["MXNET_QUANTIZATION_VERBOSE"] = "1"
          logger.info("Quantizing symbol")
      if quantized_dtype not in ("int8", "uint8", "auto"):
          raise ValueError(
              f"unknown quantized_dtype {quantized_dtype} received,"
              " expected `int8`, `uint8` or `auto`"
          )
      if quantize_granularity not in ("tensor-wise", "channel-wise"):
          raise ValueError(
              f"unkonwn quantize_granularity {quantize_granularity} received,"
              " expected `tensor-wise` or `channel-wise`."
          )
      qsym, calib_layers = _quantize_symbol(
          sym,
          device,
          excluded_symbols=excluded_sym_names,
          excluded_operators=excluded_op_names,
          offline_params=list(arg_params.keys()),
          quantized_dtype=quantized_dtype,
          quantize_mode=quantize_mode,
          quantize_granularity=quantize_granularity,
      )
      min_max_dict = {}
      if calib_mode is not None and calib_mode != "none":
          if not isinstance(device, Device):
              raise ValueError(
                  f"currently only supports single device, while received {str(device)}"
              )
          if calib_data is None:
              raise ValueError(
                  f"calib_data must be provided when calib_mode={calib_mode}"
              )
          if not isinstance(calib_data, mx.gluon.data.DataLoader):
              raise ValueError(
                  f"calib_data must be of DataLoader type when calib_mode={calib_mode},"
                  f" while received type {str(type(calib_data))}"
              )
  
          inputs = [mx.sym.var(dname) for dname in data_names]
          param_dict = arg_params
          param_dict.update(aux_params)
          sym_block = mx.gluon.SymbolBlock(sym, inputs)
          sym_block.load_dict(param_dict)
  
          if calib_mode == "entropy":
              collector = _LayerHistogramCollector(
                  quantized_dtype=quantized_dtype,
                  include_layers=calib_layers,
                  logger=logger,
              )
          elif calib_mode == "naive":
              collector = _LayerOutputMinMaxCollector(
                  quantized_dtype=quantized_dtype,
                  include_layers=calib_layers,
                  logger=logger,
              )
  
          else:
              raise ValueError(
                  f"unknown calibration mode {calib_mode} received,"
                  " expected `none`, `naive`, or `entropy`"
              )
  
          num_batches = _collect_layer_statistics(
              sym_block,
              calib_data,
              collector,
              len(inputs),
              num_calib_batches,
              logger,
          )
          if logger:
              logger.info(
                  f"Collected layer output min/max values from FP32 model using {num_batches} batches"
              )
              logger.info(
                  "Performing calibration post collecting operations"
              )
  
          min_max_dict = collector.post_collect()
          qsym = _calibrate_quantized_sym(qsym, min_max_dict)
  
      if logger:
          logger.info("Quantizing parameters")
      qarg_params = _quantize_params(qsym, arg_params, min_max_dict)
  
      if is_np_array():
          qsym = qsym.as_np_ndarray()
  
      return qsym, qarg_params, aux_params
  
imports: import abc
  import ctypes
  import logging
  import os
  import warnings
  import numpy
  import mxnet
  from ..base import _LIB, check_call, py_str
  from ..base import c_array, c_str, mx_uint, mx_real_t, c_str_array
  from ..base import SymbolHandle
  from ..symbol import Symbol
  from ..None import ndarray
  from ..io import DataDesc
  from ..device import cpu, Device
  from ..util import is_np_array, wrap_ctx_to_device_func
label_desc: Use image node_id 7 for calling a global function with example usage: quantize_model(sym, arg_params, aux_params, data_names, device, excluded_sym_names, excluded_op_names, calib_mode, calib_data, num_calib_batches, quantized_dtype, quantize_mode, quantize_granularity, logger) and returns: qsym,  qarg_params,  aux_params