class_docstr: A dataset class that converts from raw data to
  a dataset that can be used by DataLayerNM.
  Args:
      input_file: file to sequence + label.
          the first line is header (sentence [tab] label)
          each line should be [sentence][tab][label]
      tokenizer: tokenizer object such as AutoTokenizer
      max_seq_length: max sequence length minus 2 for [CLS] and [SEP]
      num_samples: number of samples you want to use for the dataset.
          If -1, use all dataset. Useful for testing.
      shuffle: Shuffles the dataset after loading.
      use_cache: Enables caching to use pickle format to store and read data from
docstr: Encode a list of sentences into a list of tuples of (input_ids, segment_ids, input_mask, label).
docstr_tok: ["Encode","a","list","of","sentences","into","a","list","of","tuples","of","(","input_ids",",","segment_ids",",","input_mask",",","label",")","."]
code: def get_features(
      all_sents, tokenizer, max_seq_length, labels=None, verbose=True
  ):
      """Encode a list of sentences into a list of tuples of (input_ids, segment_ids, input_mask, label)."""
      features = []
      sent_lengths = []
      too_long_count = 0
      for sent_id, sent in enumerate(all_sents):
          if sent_id % 1000 == 0:
              logging.debug(
                  f"Encoding sentence {sent_id}/{len(all_sents)}"
              )
          sent_subtokens = [tokenizer.cls_token]
          for word in sent:
              word_tokens = tokenizer.text_to_tokens(word)
              sent_subtokens.extend(word_tokens)
  
          if (
              max_seq_length > 0
              and len(sent_subtokens) + 1 > max_seq_length
          ):
              sent_subtokens = sent_subtokens[: max_seq_length - 1]
              too_long_count += 1
  
          sent_subtokens.append(tokenizer.sep_token)
          sent_lengths.append(len(sent_subtokens))
  
          input_ids = [
              tokenizer.tokens_to_ids(t) for t in sent_subtokens
          ]
  
          # The mask has 1 for real tokens and 0 for padding tokens.
          # Only real tokens are attended to.
          input_mask = [1] * len(input_ids)
          segment_ids = [0] * len(input_ids)
  
          if verbose and sent_id < 2:
              logging.info("*** Example ***")
              logging.info(f"example {sent_id}: {sent}")
              logging.info("subtokens: %s" % " ".join(sent_subtokens))
              logging.info("input_ids: %s" % list2str(input_ids))
              logging.info("segment_ids: %s" % list2str(segment_ids))
              logging.info("input_mask: %s" % list2str(input_mask))
              logging.info(
                  "label: %s" % labels[sent_id]
                  if labels
                  else "**Not Provided**"
              )
  
          label = labels[sent_id] if labels else -1
          features.append(
              [
                  np.asarray(input_ids),
                  np.asarray(segment_ids),
                  np.asarray(input_mask),
                  label,
              ]
          )
  
      if max_seq_length > -1 and too_long_count > 0:
          logging.warning(
              f"Found {too_long_count} out of {len(all_sents)} sentences with more than {max_seq_length} subtokens. "
              f"Truncated long sentences from the end."
          )
      if verbose:
          get_stats(sent_lengths)
      return features
  
imports: import os
  import pickle
  import random
  from typing import Dict, List, Optional
  import numpy
  import torch
  from nemo.collections.common.tokenizers.tokenizer_spec import TokenizerSpec
  from nemo.collections.nlp.data.data_utils.data_preprocessing import fill_class_weights, get_freq_weights, get_label_stats, get_stats
  from nemo.collections.nlp.parts.utils_funcs import list2str
  from nemo.core.classes import Dataset
  from nemo.core.neural_types import ChannelType, LabelsType, MaskType, NeuralType
  from nemo.utils import logging
  from nemo.utils.env_var_parsing import get_envint
label_desc: Use image node_id 6 for calling the TextClassificationDataset obj's underlying member method code with example usage: obj.get_features(all_sents, tokenizer, max_seq_length, labels, verbose) and returns: features