class_docstr: Solver for MusicGen training task.
  
  Used in: https://arxiv.org/abs/2306.05284
docstr: Evaluate audio generation with off-the-shelf metrics.
docstr_tok: ["Evaluate","audio","generation","with","off-the-shelf","metrics","."]
code: def evaluate_audio_generation(self) -> dict:
      """Evaluate audio generation with off-the-shelf metrics."""
      evaluate_stage_name = f"{self.current_stage}_generation"
      # instantiate evaluation metrics, if at least one metric is defined, run audio generation evaluation
      fad: tp.Optional[eval_metrics.FrechetAudioDistanceMetric] = None
      kldiv: tp.Optional[eval_metrics.KLDivergenceMetric] = None
      text_consistency: tp.Optional[
          eval_metrics.TextConsistencyMetric
      ] = None
      chroma_cosine: tp.Optional[
          eval_metrics.ChromaCosineSimilarityMetric
      ] = None
      should_run_eval = False
      eval_chroma_wavs: tp.Optional[torch.Tensor] = None
      if self.cfg.evaluate.metrics.fad:
          fad = builders.get_fad(self.cfg.metrics.fad).to(self.device)
          should_run_eval = True
      if self.cfg.evaluate.metrics.kld:
          kldiv = builders.get_kldiv(self.cfg.metrics.kld).to(
              self.device
          )
          should_run_eval = True
      if self.cfg.evaluate.metrics.text_consistency:
          text_consistency = builders.get_text_consistency(
              self.cfg.metrics.text_consistency
          ).to(self.device)
          should_run_eval = True
      if self.cfg.evaluate.metrics.chroma_cosine:
          chroma_cosine = builders.get_chroma_cosine_similarity(
              self.cfg.metrics.chroma_cosine
          ).to(self.device)
          # if we have predefind wavs for chroma we should purge them for computing the cosine metric
          has_predefined_eval_chromas = (
              "self_wav" in self.model.condition_provider.conditioners
              and self.model.condition_provider.conditioners[
                  "self_wav"
              ].has_eval_wavs()
          )
          if has_predefined_eval_chromas:
              warn_once(
                  self.logger,
                  "Attempting to run cosine eval for config with pre-defined eval chromas! "
                  "Resetting eval chromas to None for evaluation.",
              )
              eval_chroma_wavs = self.model.condition_provider.conditioners.self_wav.eval_wavs  # type: ignore
              self.model.condition_provider.conditioners.self_wav.reset_eval_wavs(None)  # type: ignore
          should_run_eval = True
  
      def get_compressed_audio(audio: torch.Tensor) -> torch.Tensor:
          audio_tokens, scale = self.compression_model.encode(
              audio.to(self.device)
          )
          compressed_audio = self.compression_model.decode(
              audio_tokens, scale
          )
          return compressed_audio[..., : audio.shape[-1]]
  
      metrics: dict = {}
      if should_run_eval:
          loader = self.dataloaders["evaluate"]
          updates = len(loader)
          lp = self.log_progress(
              f"{evaluate_stage_name} inference",
              loader,
              total=updates,
              updates=self.log_updates,
          )
          average = flashy.averager()
          dataset = get_dataset_from_loader(loader)
          assert isinstance(dataset, AudioDataset)
          self.logger.info(
              f"Computing evaluation metrics on {len(dataset)} samples"
          )
  
          for idx, batch in enumerate(lp):
              audio, meta = batch
              assert all(
                  [self.cfg.sample_rate == m.sample_rate for m in meta]
              )
  
              target_duration = audio.shape[-1] / self.cfg.sample_rate
              if self.cfg.evaluate.fixed_generation_duration:
                  target_duration = (
                      self.cfg.evaluate.fixed_generation_duration
                  )
  
              gen_outputs = self.run_generate_step(
                  batch,
                  gen_duration=target_duration,
                  **self.generation_params,
              )
              y_pred = gen_outputs["gen_audio"].detach()
              y_pred = y_pred[..., : audio.shape[-1]]
  
              normalize_kwargs = dict(self.cfg.generate.audio)
              normalize_kwargs.pop("format", None)
              y_pred = torch.stack(
                  [
                      normalize_audio(w, **normalize_kwargs)
                      for w in y_pred
                  ],
                  dim=0,
              ).cpu()
              y = (
                  audio.cpu()
              )  # should already be on CPU but just in case
              sizes = torch.tensor(
                  [m.n_frames for m in meta]
              )  # actual sizes without padding
              sample_rates = torch.tensor(
                  [m.sample_rate for m in meta]
              )  # sample rates for audio samples
              audio_stems = [
                  Path(m.meta.path).stem + f"_{m.seek_time}"
                  for m in meta
              ]
  
              if fad is not None:
                  if self.cfg.metrics.fad.use_gt:
                      y_pred = get_compressed_audio(y).cpu()
                  fad.update(
                      y_pred, y, sizes, sample_rates, audio_stems
                  )
              if kldiv is not None:
                  if self.cfg.metrics.kld.use_gt:
                      y_pred = get_compressed_audio(y).cpu()
                  kldiv.update(y_pred, y, sizes, sample_rates)
              if text_consistency is not None:
                  texts = [m.description for m in meta]
                  if self.cfg.metrics.text_consistency.use_gt:
                      y_pred = y
                  text_consistency.update(
                      y_pred, texts, sizes, sample_rates
                  )
              if chroma_cosine is not None:
                  if self.cfg.metrics.chroma_cosine.use_gt:
                      y_pred = get_compressed_audio(y).cpu()
                  chroma_cosine.update(y_pred, y, sizes, sample_rates)
                  # restore chroma conditioner's eval chroma wavs
                  if eval_chroma_wavs is not None:
                      self.model.condition_provider.conditioners[
                          "self_wav"
                      ].reset_eval_wavs(eval_chroma_wavs)
  
          flashy.distrib.barrier()
          if fad is not None:
              metrics["fad"] = fad.compute()
          if kldiv is not None:
              kld_metrics = kldiv.compute()
              metrics.update(kld_metrics)
          if text_consistency is not None:
              metrics["text_consistency"] = text_consistency.compute()
          if chroma_cosine is not None:
              metrics["chroma_cosine"] = chroma_cosine.compute()
          metrics = average(metrics)
          metrics = flashy.distrib.average_metrics(metrics, len(loader))
  
      return metrics
  
imports: from pathlib import Path
  import time
  import typing
  import warnings
  import flashy
  import math
  import omegaconf
  import torch
  from torch.nn import functional
  from .None import base, builders
  from .compression import CompressionSolver
  from ..None import metrics
  from ..None import models
  from ..data.audio_dataset import AudioDataset
  from ..data.music_dataset import MusicDataset, MusicInfo, AudioInfo
  from ..data.audio_utils import normalize_audio
  from ..modules.conditioners import JointEmbedCondition, SegmentWithAttributes, WavCondition
  from ..utils.cache import CachedBatchWriter, CachedBatchLoader
  from ..utils.samples.manager import SampleManager
  from ..utils.utils import get_dataset_from_loader, is_jsonable, warn_once, model_hash
label_desc: Use image node_id 18 for calling the MusicGenSolver obj's underlying member method code with example usage: obj.evaluate_audio_generation() and returns: metrics, compressed_audio