class_docstr: Machine translation model which supports bottleneck architecture,
  NLL, VAE, and MIM loss.
  
  Supported losses:
    1) nll - Conditional cross entropy (the usual NMT loss)
    2) mim - MIM learning framework. A latent variable model with good
                    reconstruction and compressed latent representation.
                    https://arxiv.org/pdf/2003.02645.pdf
    3) vae - VAE learning framework. A latent variable model which learns
                    good probability estimation over observations and
                    a regularized latent representation.
                    https://arxiv.org/pdf/1312.6114.pdf
class_docstr_tok: ["Machine","translation","model","which","supports","bottleneck","architecture",",","NLL",",","VAE",",","and","MIM","loss",".","Supported","losses",":","1",")","nll","-","Conditional","cross","entropy","(","the","usual","NMT","loss",")","2",")","mim","-","MIM","learning","framework",".","A","latent","variable","model","with","good","reconstruction","and","compressed","latent","representation",".","https",":","\/\/arxiv.org\/pdf\/2003.02645.pdf","3",")","vae","-","VAE","learning","framework",".","A","latent","variable","model","which","learns","good","probability","estimation","over","observations","and","a","regularized","latent","representation",".","https",":","\/\/arxiv.org\/pdf\/1312.6114.pdf"]
code: def eval_step(self, batch, batch_idx, mode, dataloader_idx=0):
      if self.log_timing:
          timer = timers.NamedTimer()
      else:
          timer = None
  
      for i in range(len(batch)):
          if batch[i].ndim == 3:
              # Dataset returns already batched data and the first dimension of size 1 added by DataLoader
              # is excess.
              batch[i] = batch[i].squeeze(dim=0)
  
      if self.multilingual:
          self.source_processor = self.source_processor_list[
              dataloader_idx
          ]
          self.target_processor = self.target_processor_list[
              dataloader_idx
          ]
  
      src_ids, src_mask, tgt_ids, tgt_mask, labels = batch
      z, z_mean, z_logv, z_mask, tgt_log_probs = self(
          src_ids, src_mask, tgt_ids, tgt_mask, timer=timer
      )
      eval_loss, info_dict = self.loss(
          z=z,
          z_mean=z_mean,
          z_logv=z_logv,
          z_mask=z_mask,
          tgt_log_probs=tgt_log_probs,
          tgt=tgt_ids,
          tgt_mask=tgt_mask,
          tgt_labels=labels,
          train=False,
          return_info=True,
      )
      # pass cache to sampler in order to reuse encoder's output
      cache = dict(
          z=z,
          z_mean=z_mean,
          z_mask=z_mask,
          timer=timer,
      )
  
      inputs, translations = self.batch_translate(
          src=src_ids, src_mask=src_mask, cache=cache
      )
  
      num_measurements = labels.shape[0] * labels.shape[1]
      if dataloader_idx == 0:
          getattr(self, f"{mode}_loss")(
              loss=eval_loss,
              num_measurements=num_measurements,
          )
      else:
          getattr(self, f"{mode}_loss_{dataloader_idx}")(
              loss=eval_loss,
              num_measurements=num_measurements,
          )
      np_tgt = tgt_ids.detach().cpu().numpy()
      ground_truths = [
          self.decoder_tokenizer.ids_to_text(tgt) for tgt in np_tgt
      ]
      ground_truths = [
          self.target_processor.detokenize(tgt.split(" "))
          for tgt in ground_truths
      ]
      num_non_pad_tokens = (
          np.not_equal(np_tgt, self.decoder_tokenizer.pad_id)
          .sum()
          .item()
      )
  
      # collect logs
      log_dict = {
          k: v.detach().cpu().numpy() if torch.is_tensor(v) else v
          for k, v in info_dict.items()
      }
      # add timing if required
      if timer is not None:
          for k, v in timer.export().items():
              log_dict[f"{k}_timing"] = v
  
      return {
          "inputs": inputs,
          "translations": translations,
          "ground_truths": ground_truths,
          "num_non_pad_tokens": num_non_pad_tokens,
          "log": log_dict,
      }
  
imports: from typing import Dict, Optional
  import numpy
  import torch
  from pytorch_lightning import Trainer
  from nemo.collections.common.losses import NLLLoss
  from nemo.collections.nlp.models.machine_translation.mt_enc_dec_config import MTBottleneckModelConfig
  from nemo.collections.nlp.models.machine_translation.mt_enc_dec_model import MTEncDecModel
  from nemo.core.classes.common import typecheck
  from nemo.utils import timers
label_desc: Use image node_id 10 for calling the MTBottleneckModel obj's underlying member method code with example usage: obj.eval_step(batch, batch_idx, mode, dataloader_idx) and returns: dict