class_docstr: [`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 (`int`):
          Batch Size of `input_ids` for which standard beam search decoding is run in parallel.
      num_beams (`int`):
          Number of beams for beam search.
      device (`torch.device`):
          Defines the device type (*e.g.*, `"cpu"` or `"cuda"`) on which this instance of `BeamSearchScorer` will be
          allocated.
      length_penalty (`float`, *optional*, defaults to 1.0):
          Exponential penalty to the length that is used with beam-based generation. It is applied as an exponent to
          the sequence length, which in turn is used to divide the score of the sequence. Since the score is the log
          likelihood of the sequence (i.e. negative), `length_penalty` > 0.0 promotes longer sequences, while
          `length_penalty` < 0.0 encourages shorter sequences.
      do_early_stopping (`bool` or `str`, *optional*, defaults to `False`):
          Controls the stopping condition for beam-based methods, like beam-search. It accepts the following values:
          `True`, where the generation stops as soon as there are `num_beams` complete candidates; `False`, where an
          heuristic is applied and the generation stops when is it very unlikely to find better candidates;
          `"never"`, where the beam search procedure only stops when there cannot be better candidates (canonical
          beam search algorithm).
      num_beam_hyps_to_keep (`int`, *optional*, defaults to 1):
          The number of beam hypotheses that shall be returned upon calling
          [`~transformers.BeamSearchScorer.finalize`].
      num_beam_groups (`int`, *optional*, defaults to 1):
          Number of groups to divide `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.
      max_length (`int`, *optional*):
          The maximum length of the sequence to be generated.
class_docstr_tok: ["[","`","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","(","`","int","`",")",":","Batch","Size","of","`","input_ids","`","for","which","standard","beam","search","decoding","is","run","in","parallel",".","num_beams","(","`","int","`",")",":","Number","of","beams","for","beam","search",".","device","(","`","torch.device","`",")",":","Defines","the","device","type","(","*","e.g",".","*",",","`","``","cpu","''","`","or","`","``","cuda","''","`",")","on","which","this","instance","of","`","BeamSearchScorer","`","will","be","allocated",".","length_penalty","(","`","float","`",",","*","optional","*",",","defaults","to","1.0",")",":","Exponential","penalty","to","the","length","that","is","used","with","beam-based","generation",".","It","is","applied","as","an","exponent","to","the","sequence","length",",","which","in","turn","is","used","to","divide","the","score","of","the","sequence",".","Since","the","score","is","the","log","likelihood","of","the","sequence","(","i.e",".","negative",")",",","`","length_penalty","`",">","0.0","promotes","longer","sequences",",","while","`","length_penalty","`","<","0.0","encourages","shorter","sequences",".","do_early_stopping","(","`","bool","`","or","`","str","`",",","*","optional","*",",","defaults","to","`","False","`",")",":","Controls","the","stopping","condition","for","beam-based","methods",",","like","beam-search",".","It","accepts","the","following","values",":","`","True","`",",","where","the","generation","stops","as","soon","as","there","are","`","num_beams","`","complete","candidates",";","`","False","`",",","where","an","heuristic","is","applied","and","the","generation","stops","when","is","it","very","unlikely","to","find","better","candidates",";","`","``","never","''","`",",","where","the","beam","search","procedure","only","stops","when","there","can","not","be","better","candidates","(","canonical","beam","search","algorithm",")",".","num_beam_hyps_to_keep","(","`","int","`",",","*","optional","*",",","defaults","to","1",")",":","The","number","of","beam","hypotheses","that","shall","be","returned","upon","calling","[","`","~transformers.BeamSearchScorer.finalize","`","]",".","num_beam_groups","(","`","int","`",",","*","optional","*",",","defaults","to","1",")",":","Number","of","groups","to","divide","`","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",".","max_length","(","`","int","`",",","*","optional","*",")",":","The","maximum","length","of","the","sequence","to","be","generated","."]
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[Union[int, List[int]]] = None,
      beam_indices: Optional[torch.LongTensor] = None,
      group_index: Optional[int] = 0,
      decoder_prompt_len: Optional[int] = 0,
  ) -> Dict[str, torch.Tensor]:
      # add up to the length which the next_scores is calculated on (including decoder prompt)
      cur_len = input_ids.shape[-1] + 1
      batch_size = len(self._beam_hyps) // self.num_beam_groups
  
      if not (batch_size == (input_ids.shape[0] // self.group_size)):
          if self.num_beam_groups > 1:
              raise ValueError(
                  f"A group beam size of {input_ids.shape[0]} is used as the input, but a group beam "
                  f"size of {self.group_size} is expected by the beam scorer."
              )
          else:
              raise ValueError(
                  f"A beam size of {input_ids.shape[0]} is used as the input, but a beam size of "
                  f"{self.group_size} is expected by the beam scorer."
              )
  
      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,
      )
  
      if isinstance(eos_token_id, int):
          eos_token_id = [eos_token_id]
  
      for batch_idx in range(batch_size):
          batch_group_idx = (
              batch_idx * self.num_beam_groups + group_index
          )
          if self._done[batch_group_idx]:
              if self.num_beams < len(self._beam_hyps[batch_group_idx]):
                  raise ValueError(
                      f"Batch can only be done if at least {self.num_beams} beams have been generated"
                  )
              if eos_token_id is None or pad_token_id is None:
                  raise ValueError(
                      "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() in 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
                  if beam_indices is not None:
                      beam_index = beam_indices[batch_beam_idx]
                      beam_index = beam_index + (batch_beam_idx,)
                  else:
                      beam_index = None
  
                  self._beam_hyps[batch_group_idx].add(
                      input_ids[batch_beam_idx].clone(),
                      next_score.item(),
                      beam_indices=beam_index,
                      generated_len=cur_len - decoder_prompt_len,
                  )
              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:"
                  f" {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_group_idx] = self._done[
              batch_group_idx
          ] or self._beam_hyps[batch_group_idx].is_done(
              next_scores[batch_idx].max().item(),
              cur_len,
              decoder_prompt_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 Dict, List, Optional, Tuple, Union
  import numpy
  import torch
  from ..utils import add_start_docstrings
  from .beam_constraints import Constraint, ConstraintListState
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, beam_indices, group_index, decoder_prompt_len) and returns: UserDict