code: def _forward(
      self,
      src_ids,
      encoder_input_mask,
      decoder_input_ids=None,
      return_beam_scores=False,
  ):
      encoder_hidden_states = [
          self._get_encoder_hidden_states(
              src_ids, encoder_input_mask, i
          )
          for i in range(self.num_models)
      ]
      tgt, batch_size, max_generation_length = self._prepare_for_search(
          decoder_input_ids, encoder_hidden_states[0]
      )
  
      # generate initial buffer of beam_size prefixes-hypotheses
      outputs = [
          self._one_step_forward(
              i,
              tgt,
              encoder_hidden_states[i],
              encoder_input_mask,
              None,
              0,
          )
          for i in range(self.num_models)
      ]
      nmt_log_probs = self._average_probs([x[0] for x in outputs])
      decoder_mems_lists = [x[1] for x in outputs]
  
      if self.language_model is not None:
          lm_log_probs, lm_mems_list = self._one_step_forward_lm(
              tgt, None, 0
          )
          log_probs = nmt_log_probs + self.fusion_coef * lm_log_probs
      else:
          log_probs = nmt_log_probs
      scores, prefixes = torch.topk(
          log_probs.permute(0, 2, 1), self.beam_size, dim=1
      )
      scores, prefixes = scores.view(-1, 1), prefixes.view(-1, 1)
  
      # repeat init target prefixes and cached memory states beam_size times
      prefixes = torch.cat(
          (tgt.repeat(1, self.beam_size).view(-1, 1), prefixes), dim=1
      )
      for i in range(self.num_models):
          for j in range(len(decoder_mems_lists[i])):
              decoder_mems_lists[i][j] = decoder_mems_lists[i][
                  j
              ].repeat(self.beam_size, 1, 1)
  
      if self.language_model is not None:
          for j in range(len(lm_mems_list)):
              lm_mems_list[j] = lm_mems_list[j].repeat(
                  self.beam_size, 1, 1
              )
          lm_hidden_size = lm_mems_list[0].size(2)
  
      encoder_input_mask = encoder_input_mask.repeat(
          1, self.beam_size
      ).view(-1, encoder_input_mask.size(1))
      for i in range(self.num_models):
          _, src_length, hidden_size = encoder_hidden_states[i].size()
          encoder_hidden_states[i] = (
              encoder_hidden_states[i]
              .repeat(1, self.beam_size, 1)
              .view(-1, src_length, hidden_size)
          )
  
      # pad_profile tracks finished hypotheses to generate only <pad> tokens
      # if <eos> or <pad> has been generated
      pad_profile = torch.zeros_like(scores).long()
  
      # prefixes_len tracks lengths of generated hypotheses to perform
      # length penalty correction
      prefixes_len = torch.zeros_like(scores).fill_(
          prefixes.size(1) + 1
      )
  
      for i in range(max_generation_length):
          # mask all finished hypotheses to exclude them from beam
          pad_mask = pad_profile.repeat(1, self.beam_size)
  
          # generate and score candidates for prefixes continuation
          outputs = [
              self._one_step_forward(
                  model_num,
                  prefixes[:, -1:],
                  encoder_hidden_states[model_num],
                  encoder_input_mask,
                  decoder_mems_lists[model_num],
                  i + 1,
              )
              for model_num in range(self.num_models)
          ]
          nmt_log_probs = self._average_probs([x[0] for x in outputs])
          decoder_mems_lists = [x[1] for x in outputs]
  
          if self.language_model is not None:
              lm_log_probs, lm_mems_list = self._one_step_forward_lm(
                  prefixes[:, -1:], lm_mems_list, i + 1
              )
              log_probs = (
                  nmt_log_probs + self.fusion_coef * lm_log_probs
              )
          else:
              log_probs = nmt_log_probs
          scores_i, prefixes_i = torch.topk(
              log_probs[:, -1, :], self.beam_size, dim=-1
          )
  
          # for all prefixes ending with <eos> or <pad> replace generated
          # continuations with <pad>
          prefixes_i = self.pad * pad_mask + prefixes_i * (1 - pad_mask)
  
          # force all hypotheses but one generated from already finished
          # hypotheses to have extremely low score, so they will not be
          # considered during beam re-ranking
          pad_mask[:, 1:] = pad_mask[:, 1:] * NEG_INF
          scores = scores + scores_i * (1 - pad_mask).to(scores.dtype)
  
          # choose top-k hypotheses with length penalty applied
          len_penalties = self.compute_len_penalty(
              prefixes_len, self.len_pen
          )
          scores = scores / len_penalties
          scores, indices_i = torch.topk(
              scores.view(-1, self.beam_size**2),
              self.beam_size,
              dim=1,
          )
          scores = scores.view(-1, 1) * len_penalties
  
          # select prefixes which correspond to the chosen hypotheses
          prefixes = prefixes.unsqueeze(1).repeat(1, self.beam_size, 1)
          prefixes = torch.cat(
              (prefixes, prefixes_i.unsqueeze(2)), dim=2
          )
          prefixes = prefixes.view(batch_size, self.beam_size**2, -1)
          p_len = prefixes.size(2)
          prefixes_ids = indices_i.unsqueeze(2).repeat(1, 1, p_len)
          prefixes = prefixes.gather(1, prefixes_ids).view(-1, p_len)
  
          # reshuffle cached decoder memory states to restore the order
          # of hypotheses broken after top-k selection
          for model_num in range(self.num_models):
              hidden_size = decoder_mems_lists[model_num][0].size(2)
              mems_ids = (
                  indices_i.unsqueeze(2)
                  .unsqueeze(3)
                  .repeat(1, 1, p_len - 1, hidden_size)
                  // self.beam_size
              )
              for j in range(len(decoder_mems_lists[model_num])):
                  decoder_mems_lists[model_num][j] = (
                      decoder_mems_lists[model_num][j]
                      .view(-1, self.beam_size, p_len - 1, hidden_size)
                      .gather(1, mems_ids)
                      .view(-1, p_len - 1, hidden_size)
                  )
          if self.language_model is not None:
              lm_mems_ids = (
                  indices_i.unsqueeze(2)
                  .unsqueeze(3)
                  .repeat(1, 1, p_len - 1, lm_hidden_size)
                  // self.beam_size
              )
              for j in range(len(lm_mems_list)):
                  lm_mems_list[j] = (
                      lm_mems_list[j]
                      .view(
                          -1, self.beam_size, p_len - 1, lm_hidden_size
                      )
                      .gather(1, lm_mems_ids)
                      .view(-1, p_len - 1, lm_hidden_size)
                  )
  
          # update prefixes_len and pad_profile
          not_eos_pad = prefixes.ne(self.eos) & prefixes.ne(self.pad)
          prefixes_len = 1 + not_eos_pad.sum(dim=1, keepdim=True).to(
              scores.dtype
          )
          pad_profile = (~not_eos_pad[:, -1:]).long()
  
          # if all hypotheses end with <eos> or <pad>, interrupt search
          if pad_profile.sum() == batch_size * self.beam_size:
              break
  
      # select best performing hypotheses in each element of the batch
      len_penalties = self.compute_len_penalty(
          prefixes_len, self.len_pen
      )
      scores = scores / len_penalties
      best_guesses = (
          torch.argmax(
              scores.view(-1, self.beam_size), dim=1, keepdim=True
          )
          .repeat(1, prefixes.size(1))
          .unsqueeze(1)
      )
      tgt = (
          prefixes.view(batch_size, self.beam_size, -1)
          .gather(1, best_guesses)
          .squeeze(1)
      )
  
      if return_beam_scores:
          return prefixes, scores * len_penalties, tgt
      else:
          return tgt
  
imports: from contextlib import contextmanager
  import torch
  from nemo.collections.common.parts import NEG_INF, mask_padded_tokens
label_desc: Use image node_id 8 for calling the EnsembleBeamSearchSequenceGenerator obj's underlying member method code with example usage: obj._forward(src_ids, encoder_input_mask, decoder_input_ids, return_beam_scores) and returns: prefixes,  unknown,  tgt, tgt