code: def palettize_weights(mlmodel: _MLModel, config: _OptimizationConfig):
      """
      Utility function to convert a float precision MLModel of type ``mlprogram`` to a
      compressed MLModel by reducing the overall number of weights using a lookup table
      (LUT). A LUT contains a list of float values. An `nbit` LUT has 2\ :sup:`nbits` entries.
  
      For example, a float weight vector such as ``{0.3, 0.3, 0.5, 0.5}`` can be compressed
      using a 1-bit LUT: ``{0.3, 0.5}``. In this case the float vector can be replaced
      with a 1-bit vector ``{0, 0, 1, 1}``.
  
      This function iterates over all the weights in the ``mlprogram``, discretizes its values,
      and constructs the LUT according to the algorithm specified in ``mode``. The float
      values are then converted to the `nbit` values, and the LUT is saved alongside each
      weight. The ``const`` ops storing weight values are replaced by
      ``constexpr_lut_to_dense`` ops.
  
      At runtime, the LUT and the `nbit` values are used to reconstruct the float weight
      values, which are then used to perform the float operation the weight is feeding into.
  
      Consider the following example of ``"uniform"`` mode (a linear histogram):
  
          * ``nbits = 4``
          * ``mode = "uniform"``
          * ``weight = [0.11, 0.19, 0.3, 0.08, 0.0, 0.02]``
  
      The weight can be converted to a palette with indices ``[0, 1, 2, 3]`` (2 bits). The
      indices are a byte array.
  
      The data range ``[0.0, 0.3]`` is divided into 4 partitions linearly, which is
      ``[0.0, 0.1, 0.2, 0.3]``.
  
          * The LUT would be ``[0.0, 0.1, 0.2, 0.3]``.
  
          * The weight is rounded to ``[0.1, 0.2, 0.3, 0.1, 0.0, 0.0]``, and represented in
            the palette as indices ``[01b, 10b, 11b, 01b, 00b, 00b]``.
  
      Parameters
      ----------
      mlmodel: MLModel
          Model to be converted by a LUT. This MLModel should be of type ``mlprogram``.
  
      config: OptimizationConfig
          An :py:class:`OptimizationConfig` object that specifies the parameters for weight palettization.
  
      Returns
      -------
      model: MLModel
          The palettized MLModel instance.
  
      Examples
      --------
      .. sourcecode:: python
  
          import coremltools as ct
          import coremltools.optimize as cto
  
          model = ct.models.MLModel("my_model.mlpackage")
          config = cto.coreml.OptimizationConfig(
              global_config=cto.coreml.OpPalettizerConfig(mode="kmeans", nbits=4)
          )
          compressed_model = cto.coreml.palettize_weights(model, config)
  
      """
  
      weight_palettizer = _palettize_weights(
          config, fake_compression=False
      )
      return _apply_graph_pass(mlmodel, weight_palettizer)
  
imports: from collections import OrderedDict
  from typing import Callable, Dict, List, Optional
  import numpy
  from attrs import define, field, validators
  from tqdm import tqdm
  from coremltools import _SPECIFICATION_VERSION_IOS_16
  from coremltools.converters.mil.converter import mil_convert
  from coremltools.converters.mil.frontend.milproto import load
  from coremltools.converters.mil.mil.passes.defs.quantization import AbstractQuantizationPass
  from coremltools.models import MLModel
  from coremltools.optimize.coreml import OptimizationConfig
  from coremltools.optimize.coreml._config import _MetaDataDict
  from ._quantization_passes import WeightDecompressor
  from ._quantization_passes import linear_quantize_weights
  from ._quantization_passes import palettize_weights
  from ._quantization_passes import prune_weights
label_desc: Use image node_id 5 for calling a global function with example usage: palettize_weights(mlmodel, config) and returns: _apply_graph_pass