class_docstr: Speech-to-text alignment model (https://arxiv.org/pdf/2108.10447.pdf) that is used to learn alignments between mel spectrogram and text.
class_docstr_tok: ["Speech-to-text","alignment","model","(","https",":","\/\/arxiv.org\/pdf\/2108.10447.pdf",")","that","is","used","to","learn","alignments","between","mel","spectrogram","and","text","."]
code: def validation_step(self, batch, batch_idx):
      audio, audio_len, text, text_len, attn_prior = batch
      spec, spec_len = self.preprocessor(
          input_signal=audio, length=audio_len
      )
      attn_soft, attn_logprob = self(
          spec=spec,
          spec_len=spec_len,
          text=text,
          text_len=text_len,
          attn_prior=attn_prior,
      )
  
      loss, forward_sum_loss, bin_loss, attn_hard = self._metrics(
          attn_soft, attn_logprob, spec_len, text_len
      )
  
      # plot once per epoch
      if (
          batch_idx == 0
          and isinstance(self.logger, WandbLogger)
          and HAVE_WANDB
      ):
          if attn_hard is None:
              attn_hard = binarize_attention(
                  attn_soft, text_len, spec_len
              )
  
          attn_matrices = []
          for i in range(min(5, audio.shape[0])):
              attn_matrices.append(
                  wandb.Image(
                      plot_alignment_to_numpy(
                          np.fliplr(
                              np.rot90(
                                  attn_soft[
                                      i, 0, : spec_len[i], : text_len[i]
                                  ]
                                  .data.cpu()
                                  .numpy()
                              )
                          )
                      ),
                      caption=f"attn soft",
                  ),
              )
  
              attn_matrices.append(
                  wandb.Image(
                      plot_alignment_to_numpy(
                          np.fliplr(
                              np.rot90(
                                  attn_hard[
                                      i, 0, : spec_len[i], : text_len[i]
                                  ]
                                  .data.cpu()
                                  .numpy()
                              )
                          )
                      ),
                      caption=f"attn hard",
                  )
              )
  
          self.logger.experiment.log({"attn_matrices": attn_matrices})
  
      val_log = {
          "val_loss": loss,
          "val_forward_sum_loss": forward_sum_loss,
          "val_bin_loss": torch.tensor(1.0).to(forward_sum_loss.device)
          if bin_loss is None
          else bin_loss,
      }
      self.log_dict(
          val_log,
          prog_bar=False,
          on_epoch=True,
          logger=True,
          sync_dist=True,
      )
  
imports: from typing import List
  import numpy
  import omegaconf
  import torch
  from hydra.utils import instantiate
  from omegaconf import DictConfig
  from pytorch_lightning import Trainer
  from pytorch_lightning.loggers import WandbLogger
  from torch import nn
  from nemo.collections.tts.losses.aligner_loss import BinLoss, ForwardSumLoss
  from nemo.collections.tts.parts.utils.helpers import binarize_attention, g2p_backward_compatible_support, get_mask_from_lengths, plot_alignment_to_numpy
  from nemo.core.classes import ModelPT
  from nemo.core.classes.common import PretrainedModelInfo
  from nemo.utils import logging, model_utils
label_desc: Use image node_id 8 for calling the AlignerModel obj's underlying member method code with example usage: obj.validation_step(batch, batch_idx) without return types