class_docstr: Base class for TextGeneration Strategy
class_docstr_tok: ["Base","class","for","TextGeneration","Strategy"]
docstr: return whether the generation should stop based on the previous token
  Args:
      tokens (torch.Tensor): the generated tokens so far
      prev  (torch.Tensor): the previous token
      eod_id (int): the end of document token id
      end_strings (List[str]): the list of end of generation strings
  returns:
      a boolean tensor indicating whether the generation should stop
code: def end_of_generation_condition(
      self,
      tokens: torch.Tensor,
      prev: torch.Tensor,
      eod_id: int,
      end_strings: List[str],
  ) -> torch.Tensor:
      """
      return whether the generation should stop based on the previous token
      Args:
          tokens (torch.Tensor): the generated tokens so far
          prev  (torch.Tensor): the previous token
          eod_id (int): the end of document token id
          end_strings (List[str]): the list of end of generation strings
      returns:
          a boolean tensor indicating whether the generation should stop
      """
      if (
          len(end_strings) == 1 and end_strings[0] == END_OF_SEQ
      ) or not end_strings:
          # Simple scenario: only finish on end of document token.
          return prev == eod_id
  
      (
          end_tokens,
          end_strings_to_check,
      ) = self._get_end_of_generation_tokens_and_strings(
          eod_id, end_strings
      )
      assert end_tokens
  
      is_end = torch.isin(
          prev,
          torch.tensor(
              list(end_tokens), dtype=prev.dtype, device=prev.device
          ),
      )
  
      if end_strings_to_check:
          # The loop below is inefficient (see warning in `_get_end_of_generation_tokens_and_strings()`)
          # TODO In addition, we will not stop if the model generates an end string followed by extra characters,
          # e.g., if `end_string` is "Done" and there exists a "Done!" token it could generate tokens
          #       [..., ".", "Done!"]
          # which would fail the `endswith("Done")` check. However, stopping when "Done!" is generated would not
          # work either, since we would need to post-process the generated string to truncate the extra "!".
          # ==> this is left for future work if there is a compelling use case requiring this feature.
          for idx, token_seq in enumerate(tokens):
              text = self.model.tokenizer.ids_to_text(
                  token_seq.tolist()
              )
              is_end[idx] |= any(
                  text.endswith(end_string)
                  for end_string in end_strings_to_check
              )
  
      return is_end
  
imports: import abc
  import copy
  import os
  import re
  import warnings
  from typing import List, Set, Tuple
  import torch
  from transformers import CLIPImageProcessor
  from nemo.collections.nlp.modules.common.lm_utils import pad_batch
  from nemo.collections.nlp.modules.common.megatron.utils import get_ltor_masks_and_position_ids
label_desc: Use image node_id 8 for calling the TextGenerationStrategy obj's underlying member method code with example usage: obj.end_of_generation_condition(tokens, prev, eod_id, end_strings) and returns: is_end, unknown