code: def forward(self, log_probs, targets, input_lengths, target_lengths):
      # Cast to int 64
      targets = targets.long()
      input_lengths = input_lengths.long()
      target_lengths = target_lengths.long()
  
      max_logit_len = input_lengths.max()
      max_targets_len = target_lengths.max()
  
      # Force cast joint to float32
      if (
          not self._force_float32
          and numba_utils.is_numba_cuda_fp16_supported()
      ):
          # Execute the kernel in fp16
          pass
      elif self._force_float32 and log_probs.dtype != torch.float32:
          # Log just once if fp16 tensor was passed and fp16 Numba CUDA loss could not be used.
          if (
              log_probs.dtype == torch.float16
              and not self._fp16_compat_checked
          ):
              _, reason = numba_utils.is_numba_cuda_fp16_supported(
                  return_reason=True
              )
              logging.warning(
                  f"Provided RNNT Joint tensor is of dtype {log_probs.dtype}, but RNNT loss could not be calculated "
                  f"in fp16 due to following reason stated below. Loss will be calculated in fp32. \n\n"
                  f"{reason}",
                  mode=logging_mode.ONCE,
              )
              self._fp16_compat_checked = True
  
          # Upcast the activation tensor and compute loss and grads in fp32
          logits_orig = log_probs
          log_probs = log_probs.float()
          del logits_orig  # save memory *before* computing the loss
  
      # Ensure that shape mismatch does not occur due to padding
      # Due to padding and subsequent downsampling, it may be possible that
      # max sequence length computed does not match the actual max sequence length
      # of the log_probs tensor, therefore we increment the input_lengths by the difference.
      # This difference is generally small.
      if log_probs.shape[1] != max_logit_len:
          log_probs = log_probs.narrow(
              dim=1, start=0, length=max_logit_len
          ).contiguous()
  
      # Reduce transcript length to correct alignment if additional padding was applied.
      # Transcript: [B, L] -> [B, L']; If L' < L
      if not targets.is_contiguous():
          targets = targets.contiguous()
  
      if targets.shape[1] != max_targets_len:
          targets = targets.narrow(
              dim=1, start=0, length=max_targets_len
          ).contiguous()
  
      # Temporarily override loss reduction
      loss_reduction = self._loss.reduction
      self._loss.reduction = None
  
      # Compute RNNT loss
      loss = self._loss(
          acts=log_probs,
          labels=targets,
          act_lens=input_lengths,
          label_lens=target_lengths,
      )
  
      # Loss reduction can be dynamic, so reset it after call
      self._loss.reduction = loss_reduction
  
      # reduce here using our own reduction function
      if self.reduction is not None:
          loss = self.reduce(loss, target_lengths)
  
      # del new variables that may have been created
      del (
          log_probs,
          targets,
          input_lengths,
          target_lengths,
      )
  
      return loss
  
imports: import inspect
  import operator
  from dataclasses import dataclass
  from typing import Any, Callable, Dict, List, Optional, Set
  import torch
  from omegaconf import DictConfig, OmegaConf
  from nemo.collections.asr.losses.rnnt_pytorch import MultiblankRNNTLossPytorch, RNNTLossPytorch, TDTLossPytorch
  from nemo.core.classes import Loss, typecheck
  from nemo.core.neural_types import LabelsType, LengthsType, LogprobsType, LossType, NeuralType
  from nemo.core.utils import numba_utils
  from nemo.core.utils.k2_utils import K2_INSTALLATION_MESSAGE
  from nemo.core.utils.numba_utils import NUMBA_INSTALLATION_MESSAGE
  from nemo.utils import logging, logging_mode, model_utils
label_desc: Use image node_id 5 for calling the RNNTLoss obj's underlying member method code with example usage: obj.forward(log_probs, targets, input_lengths, target_lengths) and returns: loss