class_docstr: Trainer for GAN-based UASR training.
  
  If you'd like to use this trainer, the model must inherit
  espnet.train.abs_gan_espnet_model.AbsGANESPnetModel.
class_docstr_tok: ["Trainer","for","GAN-based","UASR","training",".","If","you","'d","like","to","use","this","trainer",",","the","model","must","inherit","espnet.train.abs_gan_espnet_model.AbsGANESPnetModel","."]
docstr: Validate one epoch.
docstr_tok: ["Validate","one","epoch","."]
code: def validate_one_epoch(
      cls,
      model: torch.nn.Module,
      iterator: Iterable[Dict[str, torch.Tensor]],
      reporter: SubReporter,
      options: UASRTrainerOptions,
      distributed_option: DistributedOption,
  ) -> None:
      """Validate one epoch."""
      assert check_argument_types()
      ngpu = options.ngpu
      no_forward_run = options.no_forward_run
      distributed = distributed_option.distributed
  
      vocab_seen_list = []
  
      model.eval()
  
      logging.info("Doing validation")
      # [For distributed] Because iteration counts are not always equals between
      # processes, send stop-flag to the other processes if iterator is finished
      iterator_stop = torch.tensor(0).to("cuda" if ngpu > 0 else "cpu")
      print_hyp = True
      for _, batch in iterator:
          assert isinstance(batch, dict), type(batch)
          if distributed:
              torch.distributed.all_reduce(iterator_stop, ReduceOp.SUM)
              if iterator_stop > 0:
                  break
  
          batch = to_device(batch, "cuda" if ngpu > 0 else "cpu")
          if no_forward_run:
              continue
  
          retval = model(
              **batch, do_validation=True, print_hyp=print_hyp
          )
          print_hyp = False
          if not (
              isinstance(retval, list) or isinstance(retval, tuple)
          ):
              raise RuntimeError("model output must be tuple or list.")
          else:
              loss, stats, weight, vocab_seen = retval
              vocab_seen_list.append(vocab_seen)
  
          stats = {k: v for k, v in stats.items() if v is not None}
  
          if ngpu > 1 or distributed:
              # Apply weighted averaging for stats.
              # if distributed, this method can also apply all_reduce()
              stats, weight = recursive_average(
                  stats, weight, distributed
              )
  
          reporter.register(stats)
          reporter.next()
  
      else:
          if distributed:
              iterator_stop.fill_(1)
              torch.distributed.all_reduce(iterator_stop, ReduceOp.SUM)
  
      # compute phone error rate
      total_num_errors = 0
      total_num_ref_tokens = 0
      assert (
          "batch_num_errors" in reporter.stats
          and "batch_num_ref_tokens" in reporter.stats
      )
      for batch_num_errors, batch_num_ref_tokens in zip(
          reporter.stats["batch_num_errors"],
          reporter.stats["batch_num_ref_tokens"],
      ):
          total_num_errors += batch_num_errors.value
          total_num_ref_tokens += batch_num_ref_tokens.value
      phone_error_rate = total_num_errors / total_num_ref_tokens
      reporter.register({"phone_error_rate": phone_error_rate})
  
      # compute lm_ppl
      if model.kenlm:
          assert (
              "batch_lm_log_prob" in reporter.stats
              and "batch_num_hyp_tokens" in reporter.stats
              and "batch_size" in reporter.stats
          )
          assert (
              len(reporter.stats["batch_lm_log_prob"])
              == len(reporter.stats["batch_num_hyp_tokens"])
              == len(reporter.stats["batch_size"])
          )
  
          total_lm_log_prob = 0
          total_num_tokens = 0
          total_num_sentences = 0
          for log_prob, num_tokens, batch_size in zip(
              reporter.stats["batch_lm_log_prob"],
              reporter.stats["batch_num_hyp_tokens"],
              reporter.stats["batch_size"],
          ):
              total_lm_log_prob += log_prob.value
              total_num_tokens += num_tokens.value
              total_num_sentences += batch_size.value
          lm_ppl = math.pow(
              10,
              -total_lm_log_prob
              / (total_num_tokens + total_num_sentences),
          )
  
          vocab_seen = (
              torch.stack(vocab_seen_list).sum(dim=0).bool().sum()
          )
          vocab_seen_rate = vocab_seen / model.vocab_size
          assert vocab_seen_rate <= 1.0
          weighted_lm_ppl = lm_ppl / vocab_seen_rate**2
  
          reporter.register({"lm_ppl": lm_ppl})
          reporter.register({"weighted_lm_ppl": weighted_lm_ppl})
  
      reporter.next()
  
imports: import argparse
  import dataclasses
  import logging
  import math
  import time
  from contextlib import contextmanager
  from typing import Dict, Iterable, List, Optional, Sequence, Tuple
  import torch
  from packaging.version import parse
  from typeguard import check_argument_types
  from espnet2.schedulers.abs_scheduler import AbsBatchStepScheduler, AbsScheduler
  from espnet2.torch_utils.device_funcs import to_device
  from espnet2.torch_utils.recursive_op import recursive_average
  from espnet2.train.distributed_utils import DistributedOption
  from espnet2.train.reporter import SubReporter
  from espnet2.train.trainer import Trainer, TrainerOptions
  from espnet2.utils.build_dataclass import build_dataclass
  from espnet2.utils.types import str2bool
label_desc: Use image node_id 4 for calling the UASRTrainer obj's underlying member method code with example usage: obj.validate_one_epoch(cls, model, iterator, reporter, options, distributed_option) without return types