class_docstr: TorchAudio Hubert Pretrain model
class_docstr_tok: ["TorchAudio","Hubert","Pretrain","model"]
docstr: Frontend + Encoder + Calc loss
  
  Args:
      speech: (Batch, Length, ...)
      speech_lengths: (Batch, )
      text: (Batch, Length)
      text_lengths: (Batch,)
      kwargs: "utt_id" is among the input.
docstr_tok: ["Frontend","+","Encoder","+","Calc","loss","Args",":","speech",":","(","Batch",",","Length",",","...",")","speech_lengths",":","(","Batch",",",")","text",":","(","Batch",",","Length",")","text_lengths",":","(","Batch",",",")","kwargs",":","``","utt_id","''","is","among","the","input","."]
code: def forward(
      self,
      speech: torch.Tensor,
      speech_lengths: torch.Tensor,
      text: torch.Tensor,
      text_lengths: torch.Tensor,
      **kwargs,
  ) -> Tuple[torch.Tensor, Dict[str, torch.Tensor], torch.Tensor]:
      """Frontend + Encoder + Calc loss
  
      Args:
          speech: (Batch, Length, ...)
          speech_lengths: (Batch, )
          text: (Batch, Length)
          text_lengths: (Batch,)
          kwargs: "utt_id" is among the input.
      """
      assert text_lengths.dim() == 1, text_lengths.shape
      # Check that batch_size is unified
      assert (
          speech.shape[0]
          == speech_lengths.shape[0]
          == text.shape[0]
          == text_lengths.shape[0]
      ), (
          speech.shape,
          speech_lengths.shape,
          text.shape,
          text_lengths.shape,
      )
      batch_size = speech.shape[0]
  
      # for data-parallel
      text = text[:, : text_lengths.max()]
  
      # 1. Encoder
      logit_m, logit_u, feature_penalty = self.encode(
          speech, speech_lengths, text, text_lengths
      )
  
      # 2a. Hubert criterion
      loss = self._calc_hubert_loss(
          logit_m,
          logit_u,
          feature_penalty,
      )
  
      if not torch.isinf(loss) and not torch.isnan(loss):
          pass
          # logging.warning(f"loss, {loss.item() / logit_m.size(0)}")
      else:
          self.nan_loss_count += 1
          logging.warning(f"nan_loss_count, {self.nan_loss_count}")
  
      # log accuracies of masked and unmasked frames
      correct_m, count_m = self._compute_correct(logit_m)
      correct_u, count_u = self._compute_correct(logit_u)
  
      stats = dict(
          loss=loss.detach(),
          correct_m=correct_m,
          count_m=count_m,
          acc_m=correct_m / count_m,
          correct_u=correct_u,
          count_u=count_u,
          acc_u=correct_u / count_u,
      )
  
      # force_gatherable: to-device and to-tensor if scalar for DataParallel
      loss, stats, weight = force_gatherable(
          (loss, stats, batch_size), loss.device
      )
      return loss, stats, weight
  
imports: import logging
  from contextlib import contextmanager
  from typing import Dict, List, Optional, Tuple, Union
  import torch
  from packaging.version import parse
  from typeguard import check_argument_types
  from espnet2.asr.encoder.abs_encoder import AbsEncoder
  from espnet2.asr.frontend.abs_frontend import AbsFrontend
  from espnet2.asr.preencoder.abs_preencoder import AbsPreEncoder
  from espnet2.asr.specaug.abs_specaug import AbsSpecAug
  from espnet2.hubert.hubert_loss import HubertPretrainLoss
  from espnet2.layers.abs_normalize import AbsNormalize
  from espnet2.torch_utils.device_funcs import force_gatherable
  from espnet2.train.abs_espnet_model import AbsESPnetModel
  from espnet.nets.e2e_asr_common import ErrorCalculator
label_desc: Use image node_id 2 for calling the TorchAudioHubertPretrainModel obj's underlying member method code with example usage: obj.forward(speech, speech_lengths, text, text_lengths) and returns: loss,  stats,  weight