class_docstr: :class:`transformers.BeamScorer` implementing standard beam search decoding.
  
  Adapted in part from `Facebook's XLM beam search code
  <https://github.com/facebookresearch/XLM/blob/9e6f6814d17be4fe5b15f2e6c43eb2b2d76daeb4/src/model/transformer.py#L529>`__.
  
  Reference for the diverse beam search algorithm and implementation `Ashwin Kalyan's DBS implementation
  <https://github.com/ashwinkalyan/dbs/blob/master/dbs/beam_utils.lua>`__
  
  Args:
      batch_size (:obj:`int`):
          Batch Size of :obj:`input_ids` for which standard beam search decoding is run in parallel.
      max_length (:obj:`int`):
          The maximum length of the sequence to be generated.
      num_beams (:obj:`int`):
          Number of beams for beam search.
      device (:obj:`torch.device`):
          Defines the device type (*e.g.*, :obj:`"cpu"` or :obj:`"cuda"`) on which this instance of
          :obj:`BeamSearchScorer` will be allocated.
      length_penalty (:obj:`float`, `optional`, defaults to 1.0):
          Exponential penalty to the length. 1.0 means no penalty. Set to values < 1.0 in order to encourage the
          model to generate shorter sequences, to a value > 1.0 in order to encourage the model to produce longer
          sequences.
      do_early_stopping (:obj:`bool`, `optional`, defaults to :obj:`False`):
          Whether to stop the beam search when at least ``num_beams`` sentences are finished per batch or not.
      num_beam_hyps_to_keep (:obj:`int`, `optional`, defaults to 1):
          The number of beam hypotheses that shall be returned upon calling
          :meth:`~transformer.BeamSearchScorer.finalize`.
      num_beam_groups (:obj:`int`):
          Number of groups to divide :obj:`num_beams` into in order to ensure diversity among different groups of
          beams. See `this paper <https://arxiv.org/pdf/1610.02424.pdf>`__ for more details.
class_docstr_tok: [":","class",":","`","transformers.BeamScorer","`","implementing","standard","beam","search","decoding",".","Adapted","in","part","from","`","Facebook","'s","XLM","beam","search","code","<","https",":","\/\/github.com\/facebookresearch\/XLM\/blob\/9e6f6814d17be4fe5b15f2e6c43eb2b2d76daeb4\/src\/model\/transformer.py","#","L529",">","`","__",".","Reference","for","the","diverse","beam","search","algorithm","and","implementation","`","Ashwin","Kalyan","'s","DBS","implementation","<","https",":","\/\/github.com\/ashwinkalyan\/dbs\/blob\/master\/dbs\/beam_utils.lua",">","`","__","Args",":","batch_size","(",":","obj",":","`","int","`",")",":","Batch","Size","of",":","obj",":","`","input_ids","`","for","which","standard","beam","search","decoding","is","run","in","parallel",".","max_length","(",":","obj",":","`","int","`",")",":","The","maximum","length","of","the","sequence","to","be","generated",".","num_beams","(",":","obj",":","`","int","`",")",":","Number","of","beams","for","beam","search",".","device","(",":","obj",":","`","torch.device","`",")",":","Defines","the","device","type","(","*","e.g",".","*",",",":","obj",":","`","``","cpu","''","`","or",":","obj",":","`","``","cuda","''","`",")","on","which","this","instance","of",":","obj",":","`","BeamSearchScorer","`","will","be","allocated",".","length_penalty","(",":","obj",":","`","float","`",",","`","optional","`",",","defaults","to","1.0",")",":","Exponential","penalty","to","the","length",".","1.0","means","no","penalty",".","Set","to","values","<","1.0","in","order","to","encourage","the","model","to","generate","shorter","sequences",",","to","a","value",">","1.0","in","order","to","encourage","the","model","to","produce","longer","sequences",".","do_early_stopping","(",":","obj",":","`","bool","`",",","`","optional","`",",","defaults","to",":","obj",":","`","False","`",")",":","Whether","to","stop","the","beam","search","when","at","least","``","num_beams","``","sentences","are","finished","per","batch","or","not",".","num_beam_hyps_to_keep","(",":","obj",":","`","int","`",",","`","optional","`",",","defaults","to","1",")",":","The","number","of","beam","hypotheses","that","shall","be","returned","upon","calling",":","meth",":","`","~transformer.BeamSearchScorer.finalize","`",".","num_beam_groups","(",":","obj",":","`","int","`",")",":","Number","of","groups","to","divide",":","obj",":","`","num_beams","`","into","in","order","to","ensure","diversity","among","different","groups","of","beams",".","See","`","this","paper","<","https",":","\/\/arxiv.org\/pdf\/1610.02424.pdf",">","`","__","for","more","details","."]
code: def process(
      self,
      input_ids: "torch.LongTensor",
      next_scores: "torch.FloatTensor",
      next_tokens: "torch.LongTensor",
      next_indices: "torch.LongTensor",
      pad_token_id: Optional[int] = None,
      eos_token_id: Optional[int] = None,
  ) -> Tuple["torch.Tensor"]:
      cur_len = input_ids.shape[-1]
      batch_size = len(self._beam_hyps)
      assert batch_size == (input_ids.shape[0] // self.group_size)
  
      device = input_ids.device
      next_beam_scores = torch.zeros(
          (batch_size, self.group_size),
          dtype=next_scores.dtype,
          device=device,
      )
      next_beam_tokens = torch.zeros(
          (batch_size, self.group_size),
          dtype=next_tokens.dtype,
          device=device,
      )
      next_beam_indices = torch.zeros(
          (batch_size, self.group_size),
          dtype=next_indices.dtype,
          device=device,
      )
  
      for batch_idx, beam_hyp in enumerate(self._beam_hyps):
          if self._done[batch_idx]:
              assert (
                  len(beam_hyp) >= self.num_beams
              ), f"Batch can only be done if at least {self.num_beams} beams have been generated"
              assert (
                  eos_token_id is not None and pad_token_id is not None
              ), "generated beams >= num_beams -> eos_token_id and pad_token have to be defined"
              # pad the batch
              next_beam_scores[batch_idx, :] = 0
              next_beam_tokens[batch_idx, :] = pad_token_id
              next_beam_indices[batch_idx, :] = 0
              continue
  
          # next tokens for this sentence
          beam_idx = 0
          for beam_token_rank, (
              next_token,
              next_score,
              next_index,
          ) in enumerate(
              zip(
                  next_tokens[batch_idx],
                  next_scores[batch_idx],
                  next_indices[batch_idx],
              )
          ):
              batch_beam_idx = batch_idx * self.group_size + next_index
              # add to generated hypotheses if end of sentence
              if (eos_token_id is not None) and (
                  next_token.item() == eos_token_id
              ):
                  # if beam_token does not belong to top num_beams tokens, it should not be added
                  is_beam_token_worse_than_top_num_beams = (
                      beam_token_rank >= self.group_size
                  )
                  if is_beam_token_worse_than_top_num_beams:
                      continue
                  beam_hyp.add(
                      input_ids[batch_beam_idx].clone(),
                      next_score.item(),
                  )
              else:
                  # add next predicted token since it is not eos_token
                  next_beam_scores[batch_idx, beam_idx] = next_score
                  next_beam_tokens[batch_idx, beam_idx] = next_token
                  next_beam_indices[
                      batch_idx, beam_idx
                  ] = batch_beam_idx
                  beam_idx += 1
  
              # once the beam for next step is full, don't add more tokens to it.
              if beam_idx == self.group_size:
                  break
  
          if beam_idx < self.group_size:
              raise ValueError(
                  f"At most {self.group_size} tokens in {next_tokens[batch_idx]} can be equal to `eos_token_id: {eos_token_id}`. Make sure {next_tokens[batch_idx]} are corrected."
              )
  
          # Check if we are done so that we can save a pad step if all(done)
          self._done[batch_idx] = self._done[
              batch_idx
          ] or beam_hyp.is_done(
              next_scores[batch_idx].max().item(), cur_len
          )
  
      return UserDict(
          {
              "next_beam_scores": next_beam_scores.view(-1),
              "next_beam_tokens": next_beam_tokens.view(-1),
              "next_beam_indices": next_beam_indices.view(-1),
          }
      )
  
imports: from abc import ABC, abstractmethod
  from collections import UserDict
  from typing import Optional, Tuple
  from .file_utils import add_start_docstrings
  from fastNLP.envs.imports import _NEED_IMPORT_TORCH
  from fastNLP.core.log import logger
label_desc: Use image node_id 3 for calling the BeamSearchScorer obj's underlying member method code with example usage: obj.process(input_ids, next_scores, next_tokens, next_indices, pad_token_id, eos_token_id) and returns: UserDict