class_docstr: The dataset class for prompt-tuning or p-tuning pretrained GPT models.
  
  Args:
      data (list[strings], list[dicts]): (1) paths to .jsonl or .json files, (2) dict objects corresponding to each input example
      tokenizer (tokenizer): Tokenizer from frozen language model
      virtual_prompt_source (Enum): Either VirtualPromptSource.NO_PROMPTS or VirtualPromptSource.PROMPT_ENCODER
      task_templates (dict): Dictionary containing all task template information needed to format prompts. Created in the GPTPromptLearningModel class.
      pseudo_tokens (list[strings]): A list of virtual prompt token placeholders e.g [<prompt_1>, <prompt_2>, ...] up to max num virtual tokens
      pad_token_id (int): ID of pad token from tokenizer
      max_seq_length (int): maximum sequence length for each dataset examples. Examples will either be truncated to fit this length or dropped if they cannot be truncated.
      min_seq_length (int): min length of each data example in the dataset. Data examples will be dropped if they do not meet the min length requirements. 
      add_bos (bool): Whether to add a beginning of sentence token to each data example
      add_eos (bool): Whether to add an end of sentence token to each data example
      for_train (bool): Whether you're creating a dataset for training or inference
      tokens_to_generate (int): (inference only) Number of tokens to generate during inference
docstr: Pad input_ids in batch to max batch length while building loss mask 
docstr_tok: ["Pad","input_ids","in","batch","to","max","batch","length","while","building","loss","mask"]
code: def pad_batch_and_build_loss_mask(
      self, input_ids, batch_max, answer_starts
  ):
      """Pad input_ids in batch to max batch length while building loss mask"""
      batch_loss_masks = []
      padded_input_ids = []
      for ids, answer_start_idx in zip(input_ids, answer_starts):
          if answer_start_idx is not None:
              # Loss mask where answer tokens are 1.0 and all other tokens are 0.0
              loss_mask = [
                  float(idx >= answer_start_idx)
                  for idx in range(len(ids))
              ]
          else:
              # Loss mask where virtual tokens are 0.0 and all other tokens are 1.0
              loss_mask = [
                  float(token_id not in self.pseudo_token_ids)
                  for token_id in ids
              ]
  
          # Pad to max length
          input_length = len(ids)
          padding_length = batch_max - input_length
          pad_extend = [self.pad_token_id] * padding_length
          ids = ids + pad_extend
          padded_input_ids.append(ids)
  
          # Account for padding in loss mask
          loss_mask.extend([0.0] * padding_length)
          batch_loss_masks.append(
              torch.tensor(loss_mask, dtype=torch.float)
          )
  
      # Make into torch tensors
      padded_input_ids = torch.tensor(
          padded_input_ids, dtype=torch.long
      )
      batch_loss_masks = torch.stack(batch_loss_masks)
  
      return padded_input_ids, batch_loss_masks
  
imports: import json
  import os
  import pickle
  import torch
  from tqdm.auto import tqdm
  from nemo.collections.nlp.modules.common import VirtualPromptSource
  from nemo.collections.nlp.modules.common.megatron.utils import build_position_ids
  from nemo.core import Dataset
  from nemo.utils import AppState, logging
label_desc: Use image node_id 13 for calling the GPTPromptLearningDataset obj's underlying member method code with example usage: obj.pad_batch_and_build_loss_mask(input_ids, batch_max, answer_starts) and returns: padded_input_ids,  batch_loss_masks