class_docstr: Transformer-based (duplex) decoder model for TN/ITN.
docstr: Lightning calls this inside the validation loop with the data from the validation dataloader
  passed in as `batch`.
code: def validation_step(
      self, batch, batch_idx, dataloader_idx=0, split="val"
  ):
      """
      Lightning calls this inside the validation loop with the data from the validation dataloader
      passed in as `batch`.
      """
      # Apply Transformer
      val_loss = self.forward(
          input_ids=batch["input_ids"],
          decoder_input_ids=batch["decoder_input_ids"],
          attention_mask=batch["attention_mask"],
          labels=batch["labels"],
      )
  
      labels_str = self.tokenizer.batch_decode(
          torch.ones_like(batch["labels"])
          * ((batch["labels"] == -100) * 100)
          + batch["labels"],
          skip_special_tokens=True,
      )
      generated_texts, _, _ = self._generate_predictions(
          input_ids=batch["input_ids"],
          model_max_len=self.max_sequence_len,
      )
      results = defaultdict(int)
      for idx, class_id in enumerate(batch["semiotic_class_id"]):
          direction = constants.TASK_ID_TO_MODE[
              batch["direction"][idx][0].item()
          ]
          class_name = self._val_id_to_class[dataloader_idx][
              class_id[0].item()
          ]
  
          pred_result = TextNormalizationTestDataset.is_same(
              generated_texts[idx],
              labels_str[idx],
              constants.DIRECTIONS_TO_MODE[direction],
          )
  
          results[f"correct_{class_name}_{direction}"] += torch.tensor(
              pred_result, dtype=torch.int
          ).to(self.device)
          results[f"total_{class_name}_{direction}"] += torch.tensor(
              1
          ).to(self.device)
  
      results[f"{split}_loss"] = val_loss
      return dict(results)
  
imports: import json
  import os
  from collections import defaultdict
  from math import ceil
  from typing import Dict, List, Optional, Union
  import torch
  from omegaconf import DictConfig
  from pytorch_lightning import Trainer
  from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, DataCollatorForSeq2Seq
  import nemo.collections.nlp.data.text_normalization.constants
  from nemo.collections.common.tokenizers.moses_tokenizers import MosesProcessor
  from nemo.collections.nlp.data.text_normalization import TextNormalizationTestDataset
  from nemo.collections.nlp.data.text_normalization.decoder_dataset import TarredTextNormalizationDecoderDataset, TextNormalizationDecoderDataset
  from nemo.collections.nlp.models.duplex_text_normalization.utils import get_formatted_string
  from nemo.collections.nlp.models.nlp_model import NLPModel
  from nemo.core.classes.common import PretrainedModelInfo, typecheck
  from nemo.core.neural_types import ChannelType, LabelsType, LossType, MaskType, NeuralType
  from nemo.utils import logging
label_desc: Use image node_id 7 for calling the DuplexDecoderModel obj's underlying member method code with example usage: obj.validation_step(batch, batch_idx, dataloader_idx, split) and returns: dict