class_docstr: This class calculates Viterbi alignments in the forward method.
  
  It also records alignments and creates batches of them for use
  in Viterbi training.
  
  Arguments
  ---------
  states_per_phoneme : int
      Number of hidden states to use per phoneme.
  output_folder : str
      It is the folder that the alignments will be stored in when
      saved to disk. Not yet implemented.
  neg_inf : float
      The float used to represent a negative infinite log probability.
      Using `-float("Inf")` tends to give numerical instability.
      A number more negative than -1e5 also sometimes gave errors when
      the `genbmm` library was used (currently not in use). (default: -1e5)
  batch_reduction : string
      One of "none", "sum" or "mean".
      What kind of batch-level reduction to apply to the loss calculated
      in the forward method.
  input_len_norm : bool
      Whether to normalize the loss in the forward method by the length of
      the inputs.
  target_len_norm : bool
      Whether to normalize the loss in the forward method by the length of
      the targets.
  lexicon_path : string
      The location of the lexicon.
  
  Example
  -------
  >>> log_posteriors = torch.tensor([[[ -1., -10., -10.],
  ...                                 [-10.,  -1., -10.],
  ...                                 [-10., -10.,  -1.]],
  ...
  ...                                [[ -1., -10., -10.],
  ...                                 [-10.,  -1., -10.],
  ...                                 [-10., -10., -10.]]])
  >>> lens = torch.tensor([1., 0.66])
  >>> phns = torch.tensor([[0, 1, 2],
  ...                      [0, 1, 0]])
  >>> phn_lens = torch.tensor([1., 0.66])
  >>> aligner = HMMAligner()
  >>> forward_scores = aligner(
  ...        log_posteriors, lens, phns, phn_lens, 'forward'
  ... )
  >>> forward_scores.shape
  torch.Size([2])
  >>> viterbi_scores, alignments = aligner(
  ...        log_posteriors, lens, phns, phn_lens, 'viterbi'
  ... )
  >>> alignments
  [[0, 1, 2], [0, 1]]
  >>> viterbi_scores.shape
  torch.Size([2])
docstr: Creates a 'useful' form of the posterior probabilities, rearranged
  into the order of phoneme appearance in phns.
  
  Arguments
  ---------
  emission_pred : torch.Tensor (batch, time, phoneme in vocabulary)
      posterior probabilities from our acoustic model
  lens_abs : torch.Tensor (batch)
      The absolute length of each input to the acoustic model,
      i.e., the number of frames.
  phn_lens_abs : torch.Tensor (batch)
      The absolute length of each phoneme sequence in the batch.
  phns : torch.Tensor (batch, phoneme in phn sequence)
      The phonemes that are known/thought to be in each utterance.
  
  Returns
  -------
  emiss_pred_useful : torch.Tensor
      Tensor shape (batch, phoneme in phn sequence, time).
docstr_tok: ["Creates","a","'useful","'","form","of","the","posterior","probabilities",",","rearranged","into","the","order","of","phoneme","appearance","in","phns",".","Arguments","--","--","--","--","-","emission_pred",":","torch.Tensor","(","batch",",","time",",","phoneme","in","vocabulary",")","posterior","probabilities","from","our","acoustic","model","lens_abs",":","torch.Tensor","(","batch",")","The","absolute","length","of","each","input","to","the","acoustic","model",",","i.e.",",","the","number","of","frames",".","phn_lens_abs",":","torch.Tensor","(","batch",")","The","absolute","length","of","each","phoneme","sequence","in","the","batch",".","phns",":","torch.Tensor","(","batch",",","phoneme","in","phn","sequence",")","The","phonemes","that","are","known\/thought","to","be","in","each","utterance",".","Returns","--","--","--","-","emiss_pred_useful",":","torch.Tensor","Tensor","shape","(","batch",",","phoneme","in","phn","sequence",",","time",")","."]
code: def _make_emiss_pred_useful(
      self, emission_pred, lens_abs, phn_lens_abs, phns
  ):
      """Creates a 'useful' form of the posterior probabilities, rearranged
      into the order of phoneme appearance in phns.
  
      Arguments
      ---------
      emission_pred : torch.Tensor (batch, time, phoneme in vocabulary)
          posterior probabilities from our acoustic model
      lens_abs : torch.Tensor (batch)
          The absolute length of each input to the acoustic model,
          i.e., the number of frames.
      phn_lens_abs : torch.Tensor (batch)
          The absolute length of each phoneme sequence in the batch.
      phns : torch.Tensor (batch, phoneme in phn sequence)
          The phonemes that are known/thought to be in each utterance.
  
      Returns
      -------
      emiss_pred_useful : torch.Tensor
          Tensor shape (batch, phoneme in phn sequence, time).
      """
      # Extract useful values for later
      U_max = int(phn_lens_abs.max().item())
      fb_max_length = int(lens_abs.max().item())
      device = emission_pred.device
  
      # apply mask based on lens_abs
      mask_lens = (
          torch.arange(fb_max_length).to(device)[None, :]
          < lens_abs[:, None]
      )
  
      emiss_pred_acc_lens = torch.where(
          mask_lens[:, :, None],
          emission_pred,
          torch.tensor([0.0], device=device),
      )
  
      # manipulate phn tensor, and then 'torch.gather'
      phns = phns.to(device)
      phns_copied = phns.unsqueeze(1).expand(-1, fb_max_length, -1)
      emiss_pred_useful = torch.gather(
          emiss_pred_acc_lens, 2, phns_copied
      )
  
      # apply mask based on phn_lens_abs
      mask_phn_lens = (
          torch.arange(U_max).to(device)[None, :]
          < phn_lens_abs[:, None]
      )
      emiss_pred_useful = torch.where(
          mask_phn_lens[:, None, :],
          emiss_pred_useful,
          torch.tensor([self.neg_inf], device=device),
      )
  
      emiss_pred_useful = emiss_pred_useful.permute(0, 2, 1)
  
      return emiss_pred_useful
  
imports: import torch
  import random
  from speechbrain.utils.checkpoints import register_checkpoint_hooks
  from speechbrain.utils.checkpoints import mark_as_saver
  from speechbrain.utils.checkpoints import mark_as_loader
  from speechbrain.utils.data_utils import undo_padding
label_desc: Use image node_id 6 for calling the HMMAligner obj's underlying member method code with example usage: obj._make_emiss_pred_useful(emission_pred, lens_abs, phn_lens_abs, phns) and returns: emiss_pred_useful