code: def convert_slice_attributions_to_proto(
      attributions: Tuple[
          slicer.SliceKeyOrCrossSliceKeyType, Dict[Any, Dict[str, Any]]
      ]
  ) -> metrics_for_slice_pb2.AttributionsForSlice:
      """Converts the given slice attributions into serialized AtributionsForSlice.
  
      Args:
        attributions: The slice attributions.
  
      Returns:
        The AttributionsForSlice proto.
  
      Raises:
        TypeError: If the type of the feature value in slice key cannot be
          recognized.
      """
      result = metrics_for_slice_pb2.AttributionsForSlice()
      slice_key, slice_attributions = attributions
  
      if slicer.is_cross_slice_key(slice_key):
          result.cross_slice_key.CopyFrom(
              slicer.serialize_cross_slice_key(slice_key)
          )
      else:
          result.slice_key.CopyFrom(
              slicer.serialize_slice_key(slice_key)
          )
  
      slice_attributions = slice_attributions.copy()
      for key in sorted(slice_attributions):
          key_and_value = result.attributions_keys_and_values.add()
          key_and_value.key.CopyFrom(key.to_proto())
          for feature, value in slice_attributions[key].items():
              attribution_value = metrics_for_slice_pb2.MetricValue()
              if isinstance(value, bytes):
                  # Convert textual types to string metrics.
                  attribution_value.bytes_value = value
              elif isinstance(value, str):
                  # Convert textual types to string metrics.
                  attribution_value.bytes_value = value.encode("utf8")
              elif isinstance(value, np.ndarray) and value.size != 1:
                  # Convert NumPy arrays to ArrayValue.
                  attribution_value.array_value.CopyFrom(
                      _convert_to_array_value(value)
                  )
              else:
                  # We try to convert to float values.
                  try:
                      attribution_value.double_value.value = float(
                          value
                      )
                  except (TypeError, ValueError) as e:
                      attribution_value.unknown_type.value = str(value)
                      attribution_value.unknown_type.error = (
                          e.message
                      )  # pytype: disable=attribute-error
              key_and_value.values[feature].CopyFrom(attribution_value)
  
      return result
  
imports: import itertools
  import os
  from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple, Union
  from absl import logging
  import apache_beam
  import numpy
  import pyarrow
  import tensorflow
  from tensorflow_model_analysis import constants
  from tensorflow_model_analysis.api import types
  from tensorflow_model_analysis.evaluators import evaluator
  from tensorflow_model_analysis.evaluators import metrics_validator
  from tensorflow_model_analysis.metrics import calibration_plot
  from tensorflow_model_analysis.metrics import confusion_matrix_plot
  from tensorflow_model_analysis.metrics import metric_specs
  from tensorflow_model_analysis.metrics import metric_types
  from tensorflow_model_analysis.post_export_metrics import metric_keys
  from tensorflow_model_analysis.proto import config_pb2
  from tensorflow_model_analysis.proto import metrics_for_slice_pb2
  from tensorflow_model_analysis.proto import validation_result_pb2
  from tensorflow_model_analysis.slicer import slicer_lib
  from tensorflow_model_analysis.utils import math_util
  from tensorflow_model_analysis.writers import writer
  from google.protobuf import wrappers_pb2
label_desc: Use image node_id 12 for calling a global function with example usage: convert_slice_attributions_to_proto(attributions) and returns: result