class_docstr: VITS module (generator + discriminator).
  
  This is a module of VITS described in `Conditional Variational Autoencoder
  with Adversarial Learning for End-to-End Text-to-Speech`_.
  
  .. _`Conditional Variational Autoencoder with Adversarial Learning for End-to-End
      Text-to-Speech`: https://arxiv.org/abs/2006.04558
docstr: Perform generator forward.
  
  Args:
      text (Tensor): Text index tensor (B, T_text).
      text_lengths (Tensor): Text length tensor (B,).
      feats (Tensor): Feature tensor (B, T_feats, aux_channels).
      feats_lengths (Tensor): Feature length tensor (B,).
      singing (Tensor): Singing waveform tensor (B, T_wav).
      singing_lengths (Tensor): Singing length tensor (B,).
      label (Tensor): Label index tensor (B, T_text).
      label_lengths (Tensor): Label length tensor (B,).
      melody (Tensor): Melody index tensor (B, T_text).
      gt_dur (Tensor): Groundtruth duration tensor (B, T_text).
      score_dur (Tensor): Score duration tensor (B, T_text).
      slur (Tensor): Slur index tensor (B, T_text).
      pitch (FloatTensor): Batch of padded f0 (B, T_feats).
      ying (Optional[Tensor]): Yin pitch tensor (B, T_feats).
      sids (Optional[Tensor]): Speaker index tensor (B,) or (B, 1).
      spembs (Optional[Tensor]): Speaker embedding tensor (B, spk_embed_dim).
      lids (Optional[Tensor]): Language index tensor (B,) or (B, 1).
  
  Returns:
      Dict[str, Any]:
          * loss (Tensor): Loss scalar tensor.
          * stats (Dict[str, float]): Statistics to be monitored.
          * weight (Tensor): Weight tensor to summarize losses.
          * optim_idx (int): Optimizer index (0 for G and 1 for D).
docstr_tok: ["Perform","generator","forward",".","Args",":","text","(","Tensor",")",":","Text","index","tensor","(","B",",","T_text",")",".","text_lengths","(","Tensor",")",":","Text","length","tensor","(","B",",",")",".","feats","(","Tensor",")",":","Feature","tensor","(","B",",","T_feats",",","aux_channels",")",".","feats_lengths","(","Tensor",")",":","Feature","length","tensor","(","B",",",")",".","singing","(","Tensor",")",":","Singing","waveform","tensor","(","B",",","T_wav",")",".","singing_lengths","(","Tensor",")",":","Singing","length","tensor","(","B",",",")",".","label","(","Tensor",")",":","Label","index","tensor","(","B",",","T_text",")",".","label_lengths","(","Tensor",")",":","Label","length","tensor","(","B",",",")",".","melody","(","Tensor",")",":","Melody","index","tensor","(","B",",","T_text",")",".","gt_dur","(","Tensor",")",":","Groundtruth","duration","tensor","(","B",",","T_text",")",".","score_dur","(","Tensor",")",":","Score","duration","tensor","(","B",",","T_text",")",".","slur","(","Tensor",")",":","Slur","index","tensor","(","B",",","T_text",")",".","pitch","(","FloatTensor",")",":","Batch","of","padded","f0","(","B",",","T_feats",")",".","ying","(","Optional","[","Tensor","]",")",":","Yin","pitch","tensor","(","B",",","T_feats",")",".","sids","(","Optional","[","Tensor","]",")",":","Speaker","index","tensor","(","B",",",")","or","(","B",",","1",")",".","spembs","(","Optional","[","Tensor","]",")",":","Speaker","embedding","tensor","(","B",",","spk_embed_dim",")",".","lids","(","Optional","[","Tensor","]",")",":","Language","index","tensor","(","B",",",")","or","(","B",",","1",")",".","Returns",":","Dict","[","str",",","Any","]",":","*","loss","(","Tensor",")",":","Loss","scalar","tensor",".","*","stats","(","Dict","[","str",",","float","]",")",":","Statistics","to","be","monitored",".","*","weight","(","Tensor",")",":","Weight","tensor","to","summarize","losses",".","*","optim_idx","(","int",")",":","Optimizer","index","(","0","for","G","and","1","for","D",")","."]
code: def _forward_generator(
      self,
      text: torch.Tensor,
      text_lengths: torch.Tensor,
      feats: torch.Tensor,
      feats_lengths: torch.Tensor,
      singing: torch.Tensor,
      singing_lengths: torch.Tensor,
      label: torch.Tensor = None,
      label_lengths: torch.Tensor = None,
      melody: torch.Tensor = None,
      gt_dur: torch.Tensor = None,
      score_dur: torch.Tensor = None,
      slur: torch.Tensor = None,
      pitch: torch.Tensor = None,
      ying: Optional[torch.Tensor] = None,
      sids: Optional[torch.Tensor] = None,
      spembs: Optional[torch.Tensor] = None,
      lids: Optional[torch.Tensor] = None,
  ) -> Dict[str, Any]:
      """Perform generator forward.
  
      Args:
          text (Tensor): Text index tensor (B, T_text).
          text_lengths (Tensor): Text length tensor (B,).
          feats (Tensor): Feature tensor (B, T_feats, aux_channels).
          feats_lengths (Tensor): Feature length tensor (B,).
          singing (Tensor): Singing waveform tensor (B, T_wav).
          singing_lengths (Tensor): Singing length tensor (B,).
          label (Tensor): Label index tensor (B, T_text).
          label_lengths (Tensor): Label length tensor (B,).
          melody (Tensor): Melody index tensor (B, T_text).
          gt_dur (Tensor): Groundtruth duration tensor (B, T_text).
          score_dur (Tensor): Score duration tensor (B, T_text).
          slur (Tensor): Slur index tensor (B, T_text).
          pitch (FloatTensor): Batch of padded f0 (B, T_feats).
          ying (Optional[Tensor]): Yin pitch tensor (B, T_feats).
          sids (Optional[Tensor]): Speaker index tensor (B,) or (B, 1).
          spembs (Optional[Tensor]): Speaker embedding tensor (B, spk_embed_dim).
          lids (Optional[Tensor]): Language index tensor (B,) or (B, 1).
  
      Returns:
          Dict[str, Any]:
              * loss (Tensor): Loss scalar tensor.
              * stats (Dict[str, float]): Statistics to be monitored.
              * weight (Tensor): Weight tensor to summarize losses.
              * optim_idx (int): Optimizer index (0 for G and 1 for D).
  
      """
      # setup
      batch_size = text.size(0)
      feats = feats.transpose(1, 2)
      singing = singing.unsqueeze(1)
  
      # calculate generator outputs
      reuse_cache = True
      if not self.cache_generator_outputs or self._cache is None:
          reuse_cache = False
          outs = self.generator(
              text=text,
              text_lengths=text_lengths,
              feats=feats,
              feats_lengths=feats_lengths,
              label=label,
              label_lengths=label_lengths,
              melody=melody,
              gt_dur=gt_dur,
              score_dur=score_dur,
              slur=slur,
              pitch=pitch,
              ying=ying,
              sids=sids,
              spembs=spembs,
              lids=lids,
          )
      else:
          outs = self._cache
  
      # store cache
      if (
          self.training
          and self.cache_generator_outputs
          and not reuse_cache
      ):
          self._cache = outs
  
      # parse outputs
      if "visinger" in self.generator_type:
          singing_hat_, start_idxs, _, z_mask, outs_, *extra_outs = outs
  
          if (
              self.vocoder_generator_type == "visinger2"
              and self.generator_type == "visinger2"
          ):
              singing_hat_ddsp_, predict_mel = extra_outs
          elif self.vocoder_generator_type == "visinger2":
              singing_hat_ddsp_ = extra_outs[0]
          elif self.generator_type == "visinger2":
              predict_mel = extra_outs[0]
      elif "pisinger" in self.generator_type:
          if self.vocoder_generator_type == "visinger2":
              (
                  singing_hat_,
                  start_idxs,
                  _,
                  z_mask,
                  outs_,
                  singing_hat_ddsp_,
                  outs2_,
              ) = outs
          else:
              singing_hat_, start_idxs, _, z_mask, outs_, outs2_ = outs
          (
              yin_gt_crop,
              yin_gt_shifted_crop,
              yin_dec_crop,
              z_yin_crop_shifted,
              scope_shift,
          ) = outs2_
  
      (
          _,
          z_p,
          m_p,
          logs_p,
          m_q,
          logs_q,
          pred_pitch,
          gt_pitch,
          pred_dur,
          gt_dur,
          log_probs,
      ) = outs_
  
      singing_ = get_segments(
          x=singing,
          start_idxs=start_idxs * self.generator.upsample_factor,
          segment_size=self.generator.segment_size
          * self.generator.upsample_factor,
      )
  
      # calculate discriminator outputs
      if "avocodo" in self.discriminator_type:
          p, p_hat, fmaps_real, fmaps_fake = self.discriminator(
              singing_, singing_hat_
          )
      else:
          p_hat = self.discriminator(singing_hat_)
          with torch.no_grad():
              # do not store discriminator gradient in generator turn
              p = self.discriminator(singing_)
  
      # calculate losses
      with autocast(enabled=False):
          if "pisinger" in self.generator_type:
              yin_dec_loss = (
                  F.l1_loss(yin_gt_shifted_crop, yin_dec_crop)
                  * self.lambda_c_yin
              )
              # TODO(yifeng): add yin shift loss later
              # loss_yin_shift = (
              #     F.l1_loss(torch.exp(-yin_gt_crop), torch.exp(-yin_hat_crop))
              #     * self.lambda_c_yin
              #     + F.l1_loss(
              #         torch.exp(-yin_hat_shifted),
              #         torch.exp(-(torch.chunk(yin_hat_crop, 2, dim=0)[1])),
              #     )
              #     * self.lambda_c_yin
              # )
          if self.use_avocodo:
              mel_loss = self.mel_loss(singing_hat_[-1], singing_)
          elif self.vocoder_generator_type == "visinger2":
              mel_loss = self.mel_loss(singing_hat_, singing_)
              ddsp_mel_loss = self.mel_loss(singing_hat_ddsp_, singing_)
          else:
              mel_loss = self.mel_loss(singing_hat_, singing_)
          if self.use_flow:
              kl_loss = self.kl_loss(z_p, logs_q, m_p, logs_p, z_mask)
          else:
              kl_loss = self.kl_loss(m_q, logs_q, m_p, logs_p)
  
          if "avocodo" in self.discriminator_type:
              adv_loss = self.generator_adv_loss(p_hat)
              feat_match_loss = self.feat_match_loss(
                  fmaps_fake, fmaps_real
              )
          else:
              adv_loss = self.generator_adv_loss(p_hat)
              feat_match_loss = self.feat_match_loss(p_hat, p)
  
          pitch_loss = self.mse_loss(pred_pitch, gt_pitch)
  
          phoneme_dur_loss = self.mse_loss(
              pred_dur[:, 0, :].squeeze(1), gt_dur.float()
          )
          score_dur_loss = self.mse_loss(
              pred_dur[:, 1, :].squeeze(1), gt_dur.float()
          )
  
          if self.use_phoneme_predictor:
              ctc_loss = self.ctc_loss(
                  log_probs, label, feats_lengths, label_lengths
              )
  
          mel_loss = mel_loss * self.lambda_mel
          kl_loss = kl_loss * self.lambda_kl
  
          adv_loss = adv_loss * self.lambda_adv
          feat_match_loss = feat_match_loss * self.lambda_feat_match
  
          pitch_loss = pitch_loss * self.lambda_pitch
          phoneme_dur_loss = phoneme_dur_loss * self.lambda_dur
          score_dur_loss = score_dur_loss * self.lambda_dur
          if self.use_phoneme_predictor:
              ctc_loss = ctc_loss * self.lambda_phoneme
  
          loss = mel_loss + kl_loss + adv_loss + feat_match_loss
          if self.vocoder_generator_type == "visinger2":
              ddsp_mel_loss = ddsp_mel_loss * self.lambda_mel
              loss = loss + ddsp_mel_loss
          if self.generator_type == "visinger2":
              loss_mel_am = self.mse_loss(
                  feats * z_mask, predict_mel * z_mask
              )
              loss = loss + loss_mel_am
  
          loss = loss + pitch_loss
          loss = loss + phoneme_dur_loss
          loss = loss + score_dur_loss
          if self.use_phoneme_predictor:
              loss = loss + ctc_loss
          if "pisinger" in self.generator_type:
              loss = loss + yin_dec_loss
  
      stats = dict(
          generator_loss=loss.item(),
          generator_mel_loss=mel_loss.item(),
          generator_phn_dur_loss=phoneme_dur_loss.item(),
          generator_score_dur_loss=score_dur_loss.item(),
          generator_adv_loss=adv_loss.item(),
          generator_feat_match_loss=feat_match_loss.item(),
          generator_pitch_loss=pitch_loss.item(),
          generator_kl_loss=kl_loss.item(),
      )
  
      if self.use_phoneme_predictor:
          stats.update(
              dict(
                  generator_phoneme_loss=ctc_loss.item(),
              )
          )
  
      if self.vocoder_generator_type == "visinger2":
          stats.update(
              dict(
                  generator_mel_ddsp_loss=ddsp_mel_loss.item(),
              )
          )
      if self.generator_type == "visinger2":
          stats.update(
              dict(
                  generator_mel_am_loss=loss_mel_am.item(),
              )
          )
      if "pisinger" in self.generator_type:
          stats.update(
              dict(
                  generator_yin_dec_loss=yin_dec_loss.item(),
              )
          )
  
      loss, stats, weight = force_gatherable(
          (loss, stats, batch_size), loss.device
      )
  
      # reset cache
      if reuse_cache or not self.training:
          self._cache = None
  
      return {
          "loss": loss,
          "stats": stats,
          "weight": weight,
          "optim_idx": 0,  # needed for trainer
      }
  
imports: from contextlib import contextmanager
  from distutils.version import LooseVersion
  from typing import Any, Dict, Optional
  import torch
  from torch.nn import functional
  from typeguard import check_argument_types
  from espnet2.gan_svs.abs_gan_svs import AbsGANSVS
  from espnet2.gan_svs.avocodo.avocodo import SBD, AvocodoDiscriminator, AvocodoDiscriminatorPlus, CoMBD
  from espnet2.gan_svs.visinger2.visinger2_vocoder import VISinger2Discriminator
  from espnet2.gan_svs.vits.generator import VISingerGenerator
  from espnet2.gan_tts.hifigan import HiFiGANMultiPeriodDiscriminator, HiFiGANMultiScaleDiscriminator, HiFiGANMultiScaleMultiPeriodDiscriminator, HiFiGANPeriodDiscriminator, HiFiGANScaleDiscriminator
  from espnet2.gan_tts.hifigan.loss import DiscriminatorAdversarialLoss, FeatureMatchLoss, GeneratorAdversarialLoss, MelSpectrogramLoss
  from espnet2.gan_tts.utils import get_segments
  from espnet2.gan_tts.vits.loss import KLDivergenceLoss, KLDivergenceLossWithoutFlow
  from espnet2.torch_utils.device_funcs import force_gatherable
label_desc: Use image node_id 5 for calling the VITS obj's underlying member method code with example usage: obj._forward_generator(text, text_lengths, feats, feats_lengths, singing, singing_lengths, label, label_lengths, melody, gt_dur, score_dur, slur, pitch, ying, sids, spembs, lids) and returns: dict