docstr: Prepares a single training sample
  
  Args:
      sentence: input sentence in grapheme form
      start_end: start and end indices of the heteronym spans, start_end indices should be in increasing order
      heteronyms: heteronyms present in the sentence
      word_ids: [Optional] target word_ids, use None for inference, e.g. ['diffuse_adj']
docstr_tok: ["Prepares","a","single","training","sample","Args",":","sentence",":","input","sentence","in","grapheme","form","start_end",":","start","and","end","indices","of","the","heteronym","spans",",","start_end","indices","should","be","in","increasing","order","heteronyms",":","heteronyms","present","in","the","sentence","word_ids",":","[","Optional","]","target","word_ids",",","use","None","for","inference",",","e.g",".","[","'diffuse_adj","'","]"]
code: def _prepare_sample(
      self,
      sentence: str,
      start_end: List[Tuple[int, int]],
      heteronyms: List[str],
      word_ids: Optional[List[str]] = None,
  ):
      """
      Prepares a single training sample
  
      Args:
          sentence: input sentence in grapheme form
          start_end: start and end indices of the heteronym spans, start_end indices should be in increasing order
          heteronyms: heteronyms present in the sentence
          word_ids: [Optional] target word_ids, use None for inference, e.g. ['diffuse_adj']
      """
      # drop example where sequence length exceeds max sequence length, +2 for special tokens
      length = len(self.tokenizer.text_to_tokens(sentence)) + 2
      if length > self.max_seq_len:
          logging.debug(
              f"Sequence length exceeds max sequence length ({self.max_seq_len}): {sentence}."
          )
          return None
  
      # check the correctness on start-end indices
      for heteronym_, start_end_ in zip(heteronyms, start_end):
          if (
              heteronym_.lower()
              != sentence[start_end_[0] : start_end_[1]].lower()
          ):
              logging.debug(
                  f"Span for {heteronym_} is incorrect. Skipping example."
              )
              return None
  
      input_ids, subtokens_mask, target_word_ids = [], [], []
      # add bos token
      if hasattr(self.tokenizer, "bos_id"):
          input_ids.append(self.tokenizer.bos_id)
          subtokens_mask.append(
              self.PAD_TOKEN
          )  # the first tokens of heteronym spans are 1s, the rest of the tokens are 0s
  
          if self.with_labels:
              target_word_ids.append(
                  self.LOSS_PAD_TOKEN
              )  # -100 to pad plain tokens
          else:
              target_word_ids = (
                  None  # for inference when labels are not available
              )
  
      heteronym_span_idx = 0
      # split sentence by space and keep track of word boundaries
      # we assume heteronym is a standalone word
      matches = [
          (m.group(0), (m.start(), m.end() - 1))
          for m in re.finditer(r"\S+", sentence)
      ]
      for match in matches:
          word, word_start_end = match
          # check if the start of the next heteronym span is within the word indices
          if (
              heteronym_span_idx < len(start_end)
              and word_start_end[0]
              <= start_end[heteronym_span_idx][0]
              < word_start_end[1]
          ):
              heteronym_start_end = start_end[heteronym_span_idx]
              prefix = ""
              prefix_ids = []
              # for cases when word also includes punctuation marks at the beginning or a prefix,
              # e.g. "diffuse" vs. diffuse vs. pre-diffuse for heteronym {diffuse}
              if word_start_end[0] < heteronym_start_end[0]:
                  prefix = sentence[
                      word_start_end[0] : heteronym_start_end[0]
                  ]
                  prefix_ids = self.tokenizer.text_to_ids(prefix)
                  subtokens_mask.extend(
                      [self.PAD_TOKEN] * len(prefix_ids)
                  )
  
              word = word[word.index(prefix) + len(prefix) :]
              word_input_ids = self.tokenizer.text_to_ids(word)
              input_ids.extend(prefix_ids + word_input_ids)
  
              subtokens_mask.extend(
                  [1] + [self.PAD_TOKEN] * (len(word_input_ids) - 1)
              )
  
              if self.with_labels:
                  cur_target_word_id = self.wordid_to_idx[
                      word_ids[heteronym_span_idx]
                  ]
                  target_word_ids.extend(
                      [self.LOSS_PAD_TOKEN] * len(prefix_ids)
                      + [cur_target_word_id]
                      + [self.LOSS_PAD_TOKEN]
                      * (len(word_input_ids) - 1)
                  )
  
              heteronym = sentence.lower()[
                  heteronym_start_end[0] : heteronym_start_end[1]
              ]
              if heteronym not in self.heteronym_dict:
                  logging.debug(
                      f"{heteronym} is not supported. Skipping example."
                  )
                  return None
  
              heteronym_span_idx += 1
          else:
              ids = self.tokenizer.text_to_ids(word)
              input_ids.extend(ids)
              subtokens_mask.extend([self.PAD_TOKEN] * len(ids))
              if self.with_labels:
                  target_word_ids.extend(
                      [self.LOSS_PAD_TOKEN] * len(ids)
                  )
  
      if heteronym_span_idx < len(start_end):
          logging.info(
              "Not all heteronym spans were processed. Skipping example."
          )
          return None
  
      # add eos token
      if hasattr(self.tokenizer, "eos_id"):
          input_ids.append(self.tokenizer.eos_id)
          subtokens_mask.append(self.PAD_TOKEN)
          if self.with_labels:
              target_word_ids.append(self.LOSS_PAD_TOKEN)
  
      # target_word_ids are None for inference when labels are not available
      return input_ids, subtokens_mask, target_word_ids
  
file_path: NeMo/nemo/collections/tts/g2p/data/heteronym_classification.py
imports: import json
  import os
  import re
  from typing import Dict, List, Optional, Tuple
  import numpy
  import torch
  from nemo.collections.common.tokenizers.tokenizer_spec import TokenizerSpec
  from nemo.core.classes import Dataset
  from nemo.utils import logging
label_desc: Use image node_id 2 for calling the HeteronymClassificationDataset obj's underlying member method code with example usage: obj._prepare_sample(sentence, start_end, heteronyms, word_ids) and returns: input_ids,  subtokens_mask,  target_word_ids, None, None, None, None