code: def forward(
      model: TransformerModel, docs: List[Doc], is_train: bool
  ) -> Tuple[FullTransformerBatch, Callable]:
      tokenizer = model.tokenizer
      get_spans = model.attrs["get_spans"]
      transformer = model.layers[0]
  
      nested_spans = get_spans(docs)
      flat_spans = []
      for doc_spans in nested_spans:
          flat_spans.extend(doc_spans)
      # Flush the PyTorch cache every so often. It seems to help with memory :(
      # This shouldn't be necessary, I'm not sure what I'm doing wrong?
      maybe_flush_pytorch_cache(
          chance=model.attrs.get("flush_cache_chance", 0)
      )
      if "logger" in model.attrs:
          log_gpu_memory(model.attrs["logger"], "begin forward")
      batch_encoding = huggingface_tokenize(
          tokenizer, [span.text for span in flat_spans]
      )
      wordpieces = WordpieceBatch.from_batch_encoding(batch_encoding)
      if "logger" in model.attrs:
          log_batch_size(model.attrs["logger"], wordpieces, is_train)
      if "offset_mapping" in batch_encoding:
          align = get_alignment_via_offset_mapping(
              flat_spans,
              batch_encoding["offset_mapping"],
          )
      else:
          align = get_alignment(
              flat_spans,
              wordpieces.strings,
              tokenizer.all_special_tokens,
          )
      wordpieces, align = truncate_oversize_splits(
          wordpieces, align, tokenizer.model_max_length
      )
      model_output, bp_tensors = transformer(wordpieces, is_train)
      if "logger" in model.attrs:
          log_gpu_memory(model.attrs["logger"], "after forward")
      output = FullTransformerBatch(
          spans=nested_spans,
          wordpieces=wordpieces,
          model_output=model_output,
          align=align,
      )
      if "logger" in model.attrs:
          log_gpu_memory(model.attrs["logger"], "return from forward")
  
      def backprop_transformer(
          d_output: FullTransformerBatch,
      ) -> List[Doc]:
          if "logger" in model.attrs:
              log_gpu_memory(model.attrs["logger"], "Begin backprop")
          _ = bp_tensors(d_output.model_output)
          if "logger" in model.attrs:
              log_gpu_memory(model.attrs["logger"], "After backprop")
          return docs
  
      return output, backprop_transformer
  
imports: from typing import List, Tuple, Callable, Union, Dict
  import copy
  from pathlib import Path
  from transformers.file_utils import ModelOutput
  from transformers import AutoConfig, AutoModel, AutoTokenizer
  from transformers.tokenization_utils_fast import PreTrainedTokenizerFast
  from transformers.tokenization_utils import BatchEncoding
  from spacy.tokens import Doc
  from thinc.api import Model, get_torch_default_device, xp2torch
  from thinc.types import ArgsKwargs
  import logging
  from ..data_classes import FullTransformerBatch, WordpieceBatch, HFObjects
  from ..util import maybe_flush_pytorch_cache
  from ..util import log_gpu_memory, log_batch_size
  from ..layers._util import replace_listener, replace_listener_cfg
  from ..truncate import truncate_oversize_splits
  from ..align import get_alignment, get_alignment_via_offset_mapping
  from .hf_wrapper import HFWrapper
label_desc: Use image node_id 4 for calling a global function with example usage: forward(model, docs, is_train) and returns: output,  backprop_transformer, docs