code: def _backward_hook(
      grad_output: Tensor,
      sentence_features: Iterable[Dict[str, Tensor]],
      loss_obj: CachedMultipleNegativesRankingLoss,
  ):
      """A backward hook to backpropagate the cached gradients mini-batch by mini-batch."""
      assert loss_obj.cache is not None
      assert loss_obj.random_states is not None
      with torch.enable_grad():
          for sentence_feature, grad, random_states in zip(
              sentence_features, loss_obj.cache, loss_obj.random_states
          ):
              for (reps_mb, _), grad_mb in zip(
                  loss_obj.embed_minibatch_iter(
                      sentence_feature=sentence_feature,
                      with_grad=True,
                      copy_random_state=False,
                      random_states=random_states,
                  ),
                  grad,
              ):
                  surrogate = (
                      torch.dot(reps_mb.flatten(), grad_mb.flatten())
                      * grad_output
                  )
                  surrogate.backward()
  
imports: from __future__ import annotations
  from contextlib import nullcontext
  from functools import partial
  import torch
  from torch import nn, Tensor
  from torch.utils.checkpoint import get_device_states, set_device_states
  from typing import Iterable, Dict, Iterator, List, Optional, Tuple
  from sentence_transformers import SentenceTransformer
  from sentence_transformers import util
  import tqdm
label_desc: Use image node_id 1 for calling a global function with example usage: _backward_hook(grad_output, sentence_features, loss_obj) without return types