docstr: For a batch of input and its prediction, return a list of batch predict
  alignment src indice Tensor in size ``(batch, n_best,)``.
docstr_tok: ["For","a","batch","of","input","and","its","prediction",",","return","a","list","of","batch","predict","alignment","src","indice","Tensor","in","size","``","(","batch",",","n_best",",",")","``","."]
code: def _align_forward(self, batch, predictions):
      """
      For a batch of input and its prediction, return a list of batch predict
      alignment src indice Tensor in size ``(batch, n_best,)``.
      """
  
      # (0) add BOS and padding to tgt prediction
      if "tgt" in batch.keys() and self.gold_align:
          self._log("Computing alignments with gold target")
          batch_tgt_idxs = batch["tgt"].transpose(1, 2)
      else:
          batch_tgt_idxs = self._align_pad_prediction(
              predictions, bos=self._tgt_bos_idx, pad=self._tgt_pad_idx
          )
      tgt_mask = (
          batch_tgt_idxs.eq(self._tgt_pad_idx)
          | batch_tgt_idxs.eq(self._tgt_eos_idx)
          | batch_tgt_idxs.eq(self._tgt_bos_idx)
      )
  
      n_best = batch_tgt_idxs.size(1)
      # (1) Encoder forward.
      src, enc_states, enc_out, src_len = self._run_encoder(batch)
  
      # (2) Repeat src objects `n_best` times.
      # We use batch_size x n_best, get ``(batch * n_best, src_len, nfeat)``
      src = tile(src, n_best, dim=0)
      if enc_states is not None:
          # Quick fix. Transformers return None as enc_states.
          # enc_states are only used later on to init decoder's state
          # but are never used in Transformer decoder, so we can skip
          enc_states = tile(enc_states, n_best, dim=0)
      if isinstance(enc_out, tuple):
          enc_out = tuple(tile(x, n_best, dim=0) for x in enc_out)
      else:
          enc_out = tile(enc_out, n_best, dim=0)
      src_len = tile(src_len, n_best)  # ``(batch * n_best,)``
  
      # (3) Init decoder with n_best src,
      self.model.decoder.init_state(src, enc_out, enc_states)
      # reshape tgt to ``(len, batch * n_best, nfeat)``
      # it should be done in a better way
      tgt = batch_tgt_idxs.view(
          -1, batch_tgt_idxs.size(-1)
      ).T.unsqueeze(-1)
      dec_in = tgt[:-1].transpose(
          0, 1
      )  # exclude last target from inputs
      # here dec_in is batch first
      _, attns = self.model.decoder(
          dec_in, enc_out, src_len=src_len, with_align=True
      )
  
      alignment_attn = attns["align"]  # ``(B, tgt_len-1, src_len)``
      # masked_select
      align_tgt_mask = tgt_mask.view(-1, tgt_mask.size(-1))
      prediction_mask = align_tgt_mask[
          :, 1:
      ]  # exclude bos to match pred
      # get aligned src id for each prediction's valid tgt tokens
      alignement = extract_alignment(
          alignment_attn, prediction_mask, src_len, n_best
      )
      return alignement
  
imports: import torch
  from torch.nn.functional import log_softmax
  from torch.nn.utils.rnn import pad_sequence
  import codecs
  from time import time
  from math import exp
  from itertools import count, zip_longest
  from copy import deepcopy
  import onmt.model_builder
  import onmt.decoders.ensemble
  from onmt.constants import DefaultTokens
  from onmt.translate.beam_search import BeamSearch, BeamSearchLM
  from onmt.translate.greedy_search import GreedySearch, GreedySearchLM
  from onmt.utils.misc import tile, set_random_seed, report_matrix
  from onmt.utils.alignment import extract_alignment, build_align_pharaoh
  from onmt.modules.copy_generator import collapse_copy_scores
  from onmt.constants import ModelTask
  from onmt.transforms import TransformPipe
label_desc: Use image node_id 2 for calling the Translator obj's underlying member method code with example usage: obj._align_forward(batch, predictions) and returns: alignement