class_docstr: SSLDisentangler is a Conformer based model for extracting disentangled content and speaker embeddings
  from an audio waveform. This model uses a pre-trained Conformer SSL model. To extract the linguistic content 
  and speaker representations using a pre-trained Conformer, two randomly initialized downstream 
  heads are added and the entire setup is finetuned in multi-task manner for speech recognition and speaker verification. 
  These representations can be used by FastPitchModel_SSL for voice conversion by swapping the speaker embedding 
  of a given source utterance, with the speaker embedding of a target speaker.
class_docstr_tok: ["SSLDisentangler","is","a","Conformer","based","model","for","extracting","disentangled","content","and","speaker","embeddings","from","an","audio","waveform",".","This","model","uses","a","pre-trained","Conformer","SSL","model",".","To","extract","the","linguistic","content","and","speaker","representations","using","a","pre-trained","Conformer",",","two","randomly","initialized","downstream","heads","are","added","and","the","entire","setup","is","finetuned","in","multi-task","manner","for","speech","recognition","and","speaker","verification",".","These","representations","can","be","used","by","FastPitchModel_SSL","for","voice","conversion","by","swapping","the","speaker","embedding","of","a","given","source","utterance",",","with","the","speaker","embedding","of","a","target","speaker","."]
code: def validation_step(self, batch, batch_idx):
      loss_total = 0
      for key in batch.keys():
          if key == "sv":
              signal = batch[key]["audio"]
              signal_len = batch[key]["audio_lens"]
              speaker_id = batch[key]["speaker_id"]
              sv_logits, sv_emb, _, _, _ = self.forward(
                  input_signal=signal, input_signal_length=signal_len
              )
  
              pred_speaker = torch.argmax(sv_logits, dim=1)
              sv_loss = self.sv_loss(
                  logits=sv_logits, labels=speaker_id
              )
              loss_total += sv_loss
  
              correct = (
                  pred_speaker.eq(speaker_id.data.view_as(pred_speaker))
                  .sum()
                  .item()
              )
              acc = (correct / len(speaker_id)) * 100
              acc_val = torch.as_tensor(acc)
  
          if key == "content":
              content_loss = 0
              signal = batch[key]["audio"]
              signal_len = batch[key]["audio_lens"]
              target = batch[key]["text"]  # (B, T)
              target_len = batch[key]["text_lens"]
  
              (
                  _,
                  _,
                  content_embedding,
                  content_log_probs,
                  encoded_len,
              ) = self.forward(
                  input_signal=signal, input_signal_length=signal_len
              )
  
              ctc_loss = self.ctc_loss(
                  content_log_probs, target, encoded_len, target_len
              )
  
              # check if ctc loss is nan
              if torch.isfinite(ctc_loss):
                  content_loss += ctc_loss
              else:
                  logging.warning(
                      f"ctc_loss is not finite. Add min duration to avoid getting here."
                  )
  
              if self.pitch_augment:
                  augmented_signal = batch[key]["audio_shifted"]
                  (
                      _,
                      _,
                      content_embedding_aug,
                      content_log_probs_aug,
                      _,
                  ) = self.forward(
                      input_signal=augmented_signal,
                      input_signal_length=signal_len,
                  )
                  if self.aug_loss_type == "mse":
                      sim_loss = self.mse_loss(
                          content_embedding, content_embedding_aug
                      )
                  elif self.aug_loss_type == "cosine":
                      cosine_similarity = (
                          torch.nn.functional.cosine_similarity(
                              content_embedding,
                              content_embedding_aug,
                              dim=-1,
                          ).mean()
                      )
                      sim_loss = 1.0 - cosine_similarity
  
                  content_loss += self._cfg.augment_sim_alpha * sim_loss
  
              loss_total += content_loss
              cers = []
              for _idx in range(target.shape[0]):
                  item_log_prob = content_log_probs[:, _idx, :][
                      : encoded_len[_idx]
                  ].cpu()
                  item_target = target[_idx][: target_len[_idx]].cpu()
                  _, predicted_str = self.ctc_decoder(item_log_prob)
                  tokenizer = self._text_tokenizer
                  target_str = tokenizer.sep.join(
                      tokenizer._id2token[t]
                      for t in item_target.tolist()
                  )
                  ed = editdistance.eval(predicted_str, target_str)
                  if max(len(predicted_str), len(target_str)) > 0:
                      normalized_ed = (1.0 * ed) / max(
                          len(predicted_str), len(target_str)
                      )
                  else:
                      normalized_ed = 1.0
                  cers.append(normalized_ed)
  
      return {
          "val_loss": loss_total.cpu(),
          "sv_loss": sv_loss.cpu(),
          "ctc_loss": ctc_loss.cpu(),
          "content_loss": content_loss.cpu(),
          "accuracy_sv": acc_val.cpu(),
          "cer": torch.tensor(cers).mean().cpu(),
      }
  
imports: import itertools
  from typing import Iterable, Optional
  import editdistance
  import librosa
  import torch
  from hydra.utils import instantiate
  from omegaconf import DictConfig, OmegaConf
  from pytorch_lightning import Trainer
  from pytorch_lightning.loggers import TensorBoardLogger
  from pytorch_lightning.utilities.combined_loader import CombinedLoader
  from nemo.collections.asr.losses.angularloss import AngularSoftmaxLoss
  from nemo.collections.tts.data.dataset import TTSDataset
  from nemo.collections.tts.modules.ssl_tts import GreedyCTCDecoder
  from nemo.collections.tts.torch.tts_tokenizers import BaseTokenizer, EnglishCharsTokenizer
  from nemo.core.classes import ModelPT
  from nemo.core.classes.common import PretrainedModelInfo
  from nemo.core.optim.lr_scheduler import WarmupPolicy
  from nemo.utils import logging
  from nemo.utils.decorators import experimental
label_desc: Use image node_id 11 for calling the SSLDisentangler obj's underlying member method code with example usage: obj.validation_step(batch, batch_idx) and returns: dict