class_docstr: GLUE benchmark model, using Keras/TF2 and Huggingface Transformers.
  
  This is a general-purpose classification or regression model. It works for
  one- or two-segment input, and predicts either a multiclass label or
  a regression score. See GlueModelConfig for available options.
  
  This implements the LIT API for inference (e.g. input_spec(), output_spec(),
  and predict()), but also provides a train() method to run fine-tuning.
  
  This is a full-featured implementation, which includes embeddings, attention,
  gradients, as well as support for the different input and output types above.
  For a more minimal example, see ../simple_tf2_demo.py.
class_docstr_tok: ["GLUE","benchmark","model",",","using","Keras\/TF2","and","Huggingface","Transformers",".","This","is","a","general-purpose","classification","or","regression","model",".","It","works","for","one-","or","two-segment","input",",","and","predicts","either","a","multiclass","label","or","a","regression","score",".","See","GlueModelConfig","for","available","options",".","This","implements","the","LIT","API","for","inference","(","e.g",".","input_spec","(",")",",","output_spec","(",")",",","and","predict","(",")",")",",","but","also","provides","a","train","(",")","method","to","run","fine-tuning",".","This","is","a","full-featured","implementation",",","which","includes","embeddings",",","attention",",","gradients",",","as","well","as","support","for","the","different","input","and","output","types","above",".","For","a","more","minimal","example",",","see","..","\/simple_tf2_demo.py","."]
code: def predict_minibatch(self, inputs: Iterable[JsonDict]):
      # Use watch_accessed_variables to save memory by having the tape do nothing
      # if we don't need gradients.
      with tf.GradientTape(
          watch_accessed_variables=self.config.compute_grads
      ) as tape:
          encoded_input = self._preprocess(inputs)
  
          # Gathers word embeddings from BERT model embedding layer using input ids
          # of the tokens.
          input_ids = encoded_input["input_ids"]
          # TODO(b/236276775): Unify on the TFBertEmbeddings.weight API after
          # transformers is updated to v4.25.1 (or newer).
          if hasattr(self.model.bert.embeddings, "word_embeddings"):
              word_embeddings = (
                  self.model.bert.embeddings.word_embeddings
              )
          else:
              word_embeddings = self.model.bert.embeddings.weight
          # <tf.float32>[batch_size, num_tokens, emb_size]
          input_embs = tf.gather(word_embeddings, input_ids)
  
          # Scatter in any passed in embeddings.
          # <tf.float32>[batch_size, num_tokens, emb_size]
          input_embs = self.scatter_all_embeddings(inputs, input_embs)
  
          tape.watch(
              input_embs
          )  # Watch input_embs for gradient calculation.
  
          model_inputs = encoded_input.copy()
          model_inputs["input_ids"] = None
          out: TFSequenceClassifierOutput = self.model(
              model_inputs,
              inputs_embeds=input_embs,
              training=False,
              output_hidden_states=True,
              output_attentions=True,
              return_dict=True,
          )
  
          batched_outputs = {
              "input_ids": encoded_input["input_ids"],
              "ntok": tf.reduce_sum(
                  encoded_input["attention_mask"], axis=1
              ),
              "cls_emb": out.hidden_states[-1][
                  :, 0
              ],  # last layer, first token
          }
  
          if self.config.output_embeddings:
              batched_outputs["input_embs"] = input_embs
  
              self._verify_num_layers(out.hidden_states)
  
              # <float32>[batch_size, num_tokens, 1]
              token_mask = tf.expand_dims(
                  tf.cast(encoded_input["attention_mask"], tf.float32),
                  axis=2,
              )
              # <float32>[batch_size, 1]
              denom = tf.reduce_sum(token_mask, axis=1)
              for i, layer_output in enumerate(out.hidden_states):
                  # layer_output is <float32>[batch_size, num_tokens, emb_dim]
                  # average over tokens to get <float32>[batch_size, emb_dim]
                  batched_outputs[f"layer_{i}/avg_emb"] = (
                      tf.reduce_sum(layer_output * token_mask, axis=1)
                      / denom
                  )
  
          if self.config.output_attention:
              if (
                  len(out.attentions)
                  != self.model.config.num_hidden_layers
              ):
                  raise ValueError(
                      "Unexpected size of attentions. Should be the same "
                      "size as the number of hidden layers. Expected "
                      f"{self.model.config.num_hidden_layers}, got "
                      f"{len(out.attentions)}."
                  )
              for i, layer_attention in enumerate(out.attentions):
                  batched_outputs[
                      f"layer_{i+1}/attention"
                  ] = layer_attention
  
          if self.is_regression:
              # <tf.float32>[batch_size]
              batched_outputs["score"] = tf.squeeze(out.logits, axis=-1)
              # <tf.float32>[batch_size], a single target per example
              scalar_targets = batched_outputs["score"]
          else:
              # <tf.float32>[batch_size, num_labels]
              batched_outputs["probas"] = tf.nn.softmax(
                  out.logits, axis=-1
              )
              # <tf.float32>[batch_size], a single target per example
              scalar_targets, grad_idxs = self.get_target_scores(
                  inputs, batched_outputs["probas"]
              )
              # TODO(b/294613507): remove once TCAV updated.
              if self.config.compute_grads:
                  batched_outputs[
                      self.config.label_name
                  ] = tf.convert_to_tensor(grad_idxs)
  
      # Request gradients after the tape is run.
      # Note: embs[0] includes position and segment encodings, as well as subword
      # embeddings.
      if self.config.compute_grads:
          # <tf.float32>[batch_size, num_tokens, emb_dim]
          batched_outputs["input_emb_grad"] = tape.gradient(
              scalar_targets, input_embs
          )
  
      detached_outputs = {
          k: v.numpy() for k, v in batched_outputs.items()
      }
      # Sequence of dicts, one per example.
      unbatched_outputs = utils.unbatch_preds(detached_outputs)
      return map(self._postprocess, unbatched_outputs)
  
imports: import os
  from collections.abc import Iterable, Sequence
  import re
  import threading
  from typing import Any, Optional
  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 numpy
  import tensorflow
  import transformers
label_desc: Use image node_id 17 for calling the GlueModel obj's underlying member method code with example usage: obj.predict_minibatch(inputs) and returns: map