code: def viterbi_decode(log_p_attn, text_lengths, feats_lengths):
      """Extract duration from an attention probability matrix
  
      Args:
          log_p_attn (Tensor): Batched log probability of attention
              matrix (B, T_feats, T_text).
          text_lengths (Tensor): Text length tensor (B,).
          feats_legnths (Tensor): Feature length tensor (B,).
  
      Returns:
          Tensor: Batched token duration extracted from `log_p_attn` (B, T_text).
          Tensor: Binarization loss tensor ().
  
      """
      B = log_p_attn.size(0)
      T_text = log_p_attn.size(2)
      device = log_p_attn.device
  
      bin_loss = 0
      ds = torch.zeros((B, T_text), device=device)
      for b in range(B):
          cur_log_p_attn = log_p_attn[
              b, : feats_lengths[b], : text_lengths[b]
          ]
          viterbi = _monotonic_alignment_search(
              cur_log_p_attn.detach().cpu().numpy()
          )
          _ds = np.bincount(viterbi)
          ds[b, : len(_ds)] = torch.from_numpy(_ds).to(device)
  
          t_idx = torch.arange(feats_lengths[b])
          bin_loss = bin_loss - cur_log_p_attn[t_idx, viterbi].mean()
      bin_loss = bin_loss / B
      return ds, bin_loss
  
file_path: espnet/espnet2/gan_tts/jets/alignments.py
imports: import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from numba import jit
  from scipy.stats import betabinom
label_desc: Use image node_id 2 for calling a global function with example usage: viterbi_decode(log_p_attn, text_lengths, feats_lengths) and returns: ds,  bin_loss