code: def _mask_targets(
      target,
      tokenized_lens,
      speakers,
      header_len,
      s_ids,
      tokenizer,
      mask_role,
      gtype,
      name_end_token_ids,
      special_tokens,
      label_start_ids,
      num_turn_start_tokens,
  ):
      """This function masks the tokens so the loss is computed only on the non-masked role's responses.
      For 'TEXT_TO_VALUE' type, the loss is computed on the value attributes.
  
      Args:
          target (Tensor): input ids
          tokenized_lens (List[int]): array of lengths of each turns
          speakers (List[str]): array of speakers of each turns
          header_len (int): the system prompt length
          s_ids (List[Tensor]): array of tokenized ids of each turns
          tokenizer (TokenizerSpec): tokenizer object
          mask_role (str): the speaker id to be masked from loss computation
          gtype (str): either 'TEXT_TO_VALUE' or 'VALUE_TO_TEXT'
          name_end_token_ids (int): end of name token ids
          special_tokens (dict): special tokens used for the chat prompt. It has the keys: system_turn_start, turn_start, label_start, end_of_turn
          label_start_ids (list): list of label start token ids,
          num_turn_start_tokens (int): number of tokens of the turn_start str
      """
      TURN_TOKEN = special_tokens["turn_start"]
      END_NAME_SIGNAL = special_tokens["end_of_name"]
      label_start_ids = torch.tensor(label_start_ids)
      name_end_token_ids = torch.tensor(name_end_token_ids)
  
      cur_idx = header_len
      tgt_len = target.shape[0]
      for i, (tokenized_len, speaker, s_id) in enumerate(
          zip(tokenized_lens, speakers, s_ids)
      ):
          # note, sentence piece will add extra empty token in front. has to compute the diff
          id1 = tokenizer.text_to_ids(PREFIX_STR)
          id2 = tokenizer.text_to_ids(
              PREFIX_STR + TURN_TOKEN + speaker + END_NAME_SIGNAL
          )
          skip_name_len = len(id2) - len(
              id1
          )  # s_ids[:skip_name_len] is the name part of the prompt 'TURN_TOKEN + speaker + END_NAME_SIGNAL'
          # get the position of the label start string in this turn
          location = identify_start_index_of_subsequence(
              label_start_ids, s_id
          )
  
          if location >= 0:
              # if it contains the label start tokens
              if gtype == "VALUE_TO_TEXT":
                  # handles the case that condition on labels to generate respone
                  # the next token after the name part of the prompt is the beginning of the label start tokens
                  assert skip_name_len == location
                  # find the first new line token after the label part, which indicates the end of the whole label string
                  # newline_loc = torch.where((s_id[skip_name_len:] == name_end_token_ids))[0]
                  newline_loc = identify_start_index_of_subsequence(
                      name_end_token_ids, s_id[skip_name_len:]
                  )
                  if newline_loc < 0:
                      # cannot find new line token, which means the the whole turn is just a partial label string. Mask the whole turn
                      target[
                          cur_idx : cur_idx + tokenized_len
                      ] = IGNORE_INDEX
                      continue
                  # skip the label part and the new line token
                  more_skip_len = newline_loc + len(name_end_token_ids)
                  # skip the name part and the label part
                  skip_name_len += more_skip_len
              elif gtype == "TEXT_TO_VALUE":
                  # handles the case that condition on response to generate label
                  # skip the name part, response and the label start tokens part, the remainder is the label string without label start, e.g. 'quality:9,toxicity:8...'
                  skip_name_len = location + len(label_start_ids)
          if cur_idx >= tgt_len:
              break
          elif cur_idx + tokenized_len < tgt_len:
              # Check whether the mask is applied to the correct position, the first token is turn start tokens
              if not torch.equal(
                  target[cur_idx + 1 : cur_idx + tokenized_len],
                  s_id[1:],
              ):
                  logging.warning(
                      "a sentence mismatches the corresponding piece "
                      "in the conversation"
                  )
          if i == 0 and (gtype == "VALUE_TO_TEXT" or gtype is None):
              # mask the first turn completely to provide at least one turn as context for the rest
              target[cur_idx : cur_idx + tokenized_len] = IGNORE_INDEX
          elif (
              speaker == mask_role
              and i == 1
              and gtype == "TEXT_TO_VALUE"
          ):
              # leave the first turn start tag unmasked, servers severs as the end of turn signal
              target[
                  cur_idx
                  + num_turn_start_tokens : cur_idx
                  + tokenized_len
              ] = IGNORE_INDEX
          elif speaker == mask_role and (i > 1):
              # leave the first turn start tag unmasked, which severs as the end of turn signal
              target[
                  cur_idx
                  + num_turn_start_tokens : cur_idx
                  + tokenized_len
              ] = IGNORE_INDEX
          elif speaker == mask_role and (i <= 1):
              # mask out everything in the second turn
              target[cur_idx : cur_idx + tokenized_len] = IGNORE_INDEX
          else:
              # mask up to name part, label part for VALUE_TO_TEXT, or name part, response and label start tokens for TEXT_TO_VALUE, or just the name part if gtype is None
              target[cur_idx : cur_idx + skip_name_len] = IGNORE_INDEX
          cur_idx += tokenized_len
  
file_path: NeMo/nemo/collections/nlp/data/language_modeling/megatron/gpt_sft_chat_dataset.py
imports: import copy
  import torch
  from nemo.collections.common.tokenizers.tokenizer_spec import TokenizerSpec
  from nemo.collections.nlp.data.language_modeling.megatron.gpt_sft_dataset import GPTSFTDataset
  from nemo.utils import logging
label_desc: Use image node_id 4 for calling a global function with example usage: _mask_targets(target, tokenized_lens, speakers, header_len, s_ids, tokenizer, mask_role, gtype, name_end_token_ids, special_tokens, label_start_ids, num_turn_start_tokens) without return types