code: def _quantize_wp_field(wp, nbits, qm, shape, axis=0, **kwargs):
      """
      Quantize WeightParam field in Neural Network Protobuf
  
      wp: MLModel.NeuralNetwork.WeightParam
          WeightParam field
      nbits: int
          Number of bits to be quantized
      qm: str
          Quantization mode
      shape: tuple
          Tensor shape held by wp
      axis: int
          Axis over which quantization is performed on, can be either 0 or 1
      lut_function: (``callable function``)
          Python callable representing a LUT table function
      """
  
      # De-quantization
      if qm == _QUANTIZATION_MODE_DEQUANTIZE:
          return _dequantize_wp(wp, shape, axis)
  
      # If the float32 field is empty do nothing and return
      if len(wp.floatValue) == 0:
          return
  
      # Half precision (16-bit) quantization
      if nbits == 16:
          return _wp_to_fp16wp(wp)
  
      if nbits > 8:
          raise Exception(
              "Only 8-bit and lower quantization is supported"
          )
  
      if qm not in _SUPPORTED_QUANTIZATION_MODES:
          raise Exception(
              "Quantization mode {} not supported".format(qm)
          )
  
      # axis parameter check
      if axis == 1 and len(shape) != 4:
          raise Exception(
              "Quantization on second axis is only supported "
              "for rank-4 weight blob."
          )
      if axis != 0 and axis != 1:
          raise Exception(
              "Invalid quantization axis {} passed in. Allowed"
              "values are 0 (first axis) and 1 (second axis)".format(
                  axis
              )
          )
  
      # WeightParam size check - non-linear quantizations are applied on layer level
      num_channels = (
          shape[axis]
          if qm
          in [
              _QUANTIZATION_MODE_LINEAR_QUANTIZATION,
              _QUANTIZATION_MODE_LINEAR_SYMMETRIC,
          ]
          else 1
      )
      if len(wp.floatValue) % num_channels:
          raise Exception(
              "Number of quantization channels does not divide evenly into weights"
          )
  
      qparams = wp.quantization
      qparams.numberOfBits = nbits
  
      weights = _np.array(wp.floatValue).reshape(shape)
      scale, bias, lut, uint8_weights = _quantize_wp(
          weights, nbits, qm, axis, **kwargs
      )
      uint8_weights = uint8_weights.flatten()
      if qm in [
          _QUANTIZATION_MODE_LINEAR_QUANTIZATION,
          _QUANTIZATION_MODE_LINEAR_SYMMETRIC,
      ]:
          qparams.linearQuantization.scale.extend(scale)
          qparams.linearQuantization.bias.extend(bias)
      else:
          qparams.lookupTableQuantization.floatValue.extend(lut)
  
      wp.rawValue = bytes()
      if nbits == 8:
          wp.rawValue += uint8_weights.tobytes()
      else:
          wp.rawValue += _convert_array_to_nbit_quantized_bytes(
              uint8_weights, nbits
          ).tobytes()
      del wp.floatValue[:]
  
imports: from os import listdir
  from sys import stdout
  import numpy
  from coremltools import ComputeUnit, _logger
  from coremltools._deps import _HAS_KMEANS1D, _kmeans1d
  from coremltools.models import _QUANTIZATION_MODE_CUSTOM_LOOKUP_TABLE, _QUANTIZATION_MODE_DEQUANTIZE, _QUANTIZATION_MODE_LINEAR_QUANTIZATION, _QUANTIZATION_MODE_LINEAR_SYMMETRIC, _QUANTIZATION_MODE_LOOKUP_TABLE_KMEANS, _QUANTIZATION_MODE_LOOKUP_TABLE_LINEAR, _SUPPORTED_QUANTIZATION_MODES, MLModel
  from ...None import _MINIMUM_FP16_SPEC_VERSION, _MINIMUM_QUANTIZED_MODEL_SPEC_VERSION, _SPECIFICATION_VERSION_IOS_14
  from ..utils import _get_model, _macos_version, _wp_to_fp16wp
  from .optimization_utils import _optimize_nn
label_desc: Use image node_id 8 for calling a global function with example usage: _quantize_wp_field(wp, nbits, qm, shape, axis) and returns: _dequantize_wp, _wp_to_fp16wp