class_docstr: T5 using HuggingFace Transformers and Keras.
  
  This version supports embeddings, attention, and force-decoding of the target
  text, as well as more options to control decoding (such as beam search).
docstr: Post-process single-example preds. Operates on numpy arrays.
docstr_tok: ["Post-process","single-example","preds",".","Operates","on","numpy","arrays","."]
code: def _postprocess(self, preds):
      """Post-process single-example preds. Operates on numpy arrays."""
      # Return tokenization for input text.
      input_ntok = preds.pop("input_ntok")
      input_ids = preds.pop("input_ids")[:input_ntok]
      preds["input_tokens"] = self.tokenizer.convert_ids_to_tokens(
          input_ids
      )
      # Return tokenization for target text.
      target_ntok = preds.pop("target_ntok")
      target_ids = preds.pop("target_ids")[:target_ntok]
      preds["target_tokens"] = self.tokenizer.convert_ids_to_tokens(
          target_ids
      )
  
      # Decode predicted top-k tokens.
      # token_topk_preds will be a list[list[(word, prob)]]
      # Initialize prediction for 0th token as N/A.
      token_topk_preds = [[("N/A", 1.0)]]
      pred_ids = preds.pop("top_k_indices")[
          :target_ntok
      ]  # <int>[num_tokens, k]
      pred_probs = preds.pop("top_k_probs")[
          :target_ntok
      ]  # <float32>[num_tokens, k]
      for token_pred_ids, token_pred_probs in zip(pred_ids, pred_probs):
          token_pred_words = self.tokenizer.convert_ids_to_tokens(
              token_pred_ids
          )
          token_topk_preds.append(
              list(zip(token_pred_words, token_pred_probs))
          )
      preds["pred_tokens"] = token_topk_preds
  
      # Decode generated ids
      candidates = [
          self.tokenizer.decode(ids, skip_special_tokens=True)
          for ids in preds.pop("generated_ids")
      ]
      if self.config.num_to_generate > 1:
          preds["output_text"] = [(s, None) for s in candidates]
      else:
          preds["output_text"] = candidates[0]
  
      # Process attention fields, if present.
      for key in preds:
          if not re.match(r"\w+_layer_(\d+)/attention", key):
              continue
          if key.startswith("encoder_"):
              ntok = input_ntok
          elif key.startswith("decoder_"):
              ntok = target_ntok
          else:
              raise ValueError(f"Invalid attention key: '{key}'")
          # Select only real tokens, since most of this matrix is padding.
          # <float32>[num_heads, max_seq_length, max_seq_length]
          # -> <float32>[num_heads, num_tokens, num_tokens]
          preds[key] = preds[key][:, :ntok, :ntok].transpose((0, 2, 1))
          # Make a copy of this array to avoid memory leaks, since NumPy otherwise
          # keeps a pointer around that prevents the source array from being GCed.
          preds[key] = preds[key].copy()
  
      return preds
  
imports: import re
  import attr
  from lit_nlp.api import model
  from lit_nlp.api import types
  from lit_nlp.examples.models import model_utils
  from lit_nlp.lib import file_cache
  from lit_nlp.lib import utils
  import tensorflow
  import tensorflow_text
  import transformers
  from rouge_score import rouge_scorer
label_desc: Use image node_id 5 for calling the T5HFModel obj's underlying member method code with example usage: obj._postprocess(preds) and returns: preds