class_docstr: a `Predictor` is a thin wrapper around an AllenNLP model that handles JSON -> JSON predictions
  that can be used for serving models through the web API or making predictions in bulk.
docstr: Registers a backward hook on the embedding layer of the model.  Used to save the gradients
  of the embeddings for use in get_gradients()
  
  When there are multiple inputs (e.g., a passage and question), the hook
  will be called multiple times. We append all the embeddings gradients
  to a list.
  
  We additionally add a hook on the _forward_ pass of the model's `TextFieldEmbedder` to save
  token offsets, if there are any.  Having token offsets means that you're using a mismatched
  token indexer, so we need to aggregate the gradients across wordpieces in a token.  We do
  that with a simple sum.
docstr_tok: ["Registers","a","backward","hook","on","the","embedding","layer","of","the","model",".","Used","to","save","the","gradients","of","the","embeddings","for","use","in","get_gradients","(",")","When","there","are","multiple","inputs","(","e.g.",",","a","passage","and","question",")",",","the","hook","will","be","called","multiple","times",".","We","append","all","the","embeddings","gradients","to","a","list",".","We","additionally","add","a","hook","on","the","_forward_","pass","of","the","model","'s","`","TextFieldEmbedder","`","to","save","token","offsets",",","if","there","are","any",".","Having","token","offsets","means","that","you","'re","using","a","mismatched","token","indexer",",","so","we","need","to","aggregate","the","gradients","across","wordpieces","in","a","token",".","We","do","that","with","a","simple","sum","."]
code: def _register_embedding_gradient_hooks(self, embedding_gradients):
      """
      Registers a backward hook on the embedding layer of the model.  Used to save the gradients
      of the embeddings for use in get_gradients()
  
      When there are multiple inputs (e.g., a passage and question), the hook
      will be called multiple times. We append all the embeddings gradients
      to a list.
  
      We additionally add a hook on the _forward_ pass of the model's `TextFieldEmbedder` to save
      token offsets, if there are any.  Having token offsets means that you're using a mismatched
      token indexer, so we need to aggregate the gradients across wordpieces in a token.  We do
      that with a simple sum.
      """
  
      def hook_layers(module, grad_in, grad_out):
          grads = grad_out[0]
          if self._token_offsets:
              # If you have a mismatched indexer with multiple TextFields, it's quite possible
              # that the order we deal with the gradients is wrong.  We'll just take items from
              # the list one at a time, and try to aggregate the gradients.  If we got the order
              # wrong, we should crash, so you'll know about it.  If you get an error because of
              # that, open an issue on github, and we'll see what we can do.  The intersection of
              # multiple TextFields and mismatched indexers is pretty small (currently empty, that
              # I know of), so we'll ignore this corner case until it's needed.
              offsets = self._token_offsets.pop(0)
              span_grads, span_mask = util.batched_span_select(
                  grads.contiguous(), offsets
              )
              span_mask = span_mask.unsqueeze(-1)
              span_grads *= span_mask  # zero out paddings
  
              span_grads_sum = span_grads.sum(2)
              span_grads_len = span_mask.sum(2)
              # Shape: (batch_size, num_orig_tokens, embedding_size)
              grads = span_grads_sum / torch.clamp_min(
                  span_grads_len, 1
              )
  
              # All the places where the span length is zero, write in zeros.
              grads[(span_grads_len == 0).expand(grads.shape)] = 0
  
          embedding_gradients.append(grads)
  
      def get_token_offsets(module, inputs, outputs):
          offsets = util.get_token_offsets_from_text_field_inputs(
              inputs
          )
          if offsets is not None:
              self._token_offsets.append(offsets)
  
      hooks = []
      text_field_embedder = self.get_interpretable_text_field_embedder()
      hooks.append(
          text_field_embedder.register_forward_hook(get_token_offsets)
      )
      embedding_layer = self.get_interpretable_layer()
      hooks.append(embedding_layer.register_backward_hook(hook_layers))
      return hooks
  
imports: from typing import List, Iterator, Dict, Tuple, Any, Type, Union, Optional
  import logging
  from os import PathLike
  import json
  import re
  from contextlib import contextmanager
  import numpy
  import torch
  from torch.utils.hooks import RemovableHandle
  from torch import Tensor
  from torch import backends
  from allennlp.common import Registrable, plugins
  from allennlp.common.util import JsonDict, sanitize
  from allennlp.data import DatasetReader, Instance
  from allennlp.data.batch import Batch
  from allennlp.models import Model
  from allennlp.models.archival import Archive, load_archive
  from allennlp.nn import util
label_desc: Use image node_id 9 for calling the Predictor obj's underlying member method code with example usage: obj._register_embedding_gradient_hooks(embedding_gradients) and returns: hooks