docstr: Fine-tunes a transformer on the priming data.
  
  Transformer is fine-tuned with weight-decay on training split. 
  
  Train + Dev are concatenated together and a transformer is then fine tuned with weight-decay applied on the transformer parameters. The option to freeze the underlying transformer and only train a linear layer exists if `frozen=True`. This trains faster, with the exception that the performance is often lower than fine-tuning on internal benchmarks.
  
  :param train_priming_data: Text data in the train set
  :param dev_priming_data: Text data in the dev set
  :param encoded_target_values: Encoded target labels in Nrows x N_output_dimension
docstr_tok: ["Fine-tunes","a","transformer","on","the","priming","data",".","Transformer","is","fine-tuned","with","weight-decay","on","training","split",".","Train","+","Dev","are","concatenated","together","and","a","transformer","is","then","fine","tuned","with","weight-decay","applied","on","the","transformer","parameters",".","The","option","to","freeze","the","underlying","transformer","and","only","train","a","linear","layer","exists","if","`","frozen=True","`",".","This","trains","faster",",","with","the","exception","that","the","performance","is","often","lower","than","fine-tuning","on","internal","benchmarks",".",":","param","train_priming_data",":","Text","data","in","the","train","set",":","param","dev_priming_data",":","Text","data","in","the","dev","set",":","param","encoded_target_values",":","Encoded","target","labels","in","Nrows","x","N_output_dimension"]
code: def prepare(
      self,
      train_priming_data: pd.Series,
      dev_priming_data: pd.Series,
      encoded_target_values: torch.Tensor,
  ):
      """
      Fine-tunes a transformer on the priming data.
  
      Transformer is fine-tuned with weight-decay on training split.
  
      Train + Dev are concatenated together and a transformer is then fine tuned with weight-decay applied on the transformer parameters. The option to freeze the underlying transformer and only train a linear layer exists if `frozen=True`. This trains faster, with the exception that the performance is often lower than fine-tuning on internal benchmarks.
  
      :param train_priming_data: Text data in the train set
      :param dev_priming_data: Text data in the dev set
      :param encoded_target_values: Encoded target labels in Nrows x N_output_dimension
      """  # noqa
      if self.is_prepared:
          raise Exception("Encoder is already prepared.")
  
      os.environ["TOKENIZERS_PARALLELISM"] = "true"
  
      # remove empty strings (`None`s for dtype `object`)
      filtered_tr = train_priming_data[~train_priming_data.isna()]
      filtered_dev = dev_priming_data[~dev_priming_data.isna()]
  
      if filtered_dev.shape[0] > 0:
          priming_data = pd.concat([filtered_tr, filtered_dev]).tolist()
          val_size = (len(dev_priming_data)) / len(train_priming_data)
      else:
          priming_data = filtered_tr.tolist()
          val_size = 0.1  # leave out 0.1 for validation
  
      # Label encode the OHE/binary output for classification
      labels = encoded_target_values.argmax(dim=1)
  
      # Split into train and validation sets
      (
          train_texts,
          val_texts,
          train_labels,
          val_labels,
      ) = train_test_split(priming_data, labels, test_size=val_size)
  
      # If classification, then fine-tune
      if self.output_type in (dtype.categorical, dtype.binary):
          log.info("Training model.\n\tOutput trained is categorical")
  
          # Prepare priming data into tokenized form + attention masks
          training_text = self._tokenizer(
              train_texts, truncation=True, padding=True
          )
          validation_text = self._tokenizer(
              val_texts, truncation=True, padding=True
          )
  
          # Construct the model
          self._model = self._classifier_model_class.from_pretrained(
              self._pretrained_model_name,
              num_labels=len(
                  encoded_target_values[0]
              ),  # max classes to test
          ).to(self.device)
  
          # Construct the dataset for training
          xinp = TextEmbed(training_text, train_labels)
          train_dataset = DataLoader(
              xinp, batch_size=self._batch_size, shuffle=True
          )
  
          # Construct the dataset for validation
          xvalinp = TextEmbed(validation_text, val_labels)
          val_dataset = DataLoader(
              xvalinp, batch_size=self._batch_size, shuffle=True
          )
  
          # Set max length of input string; affects input to the model
          if self._max_len is None:
              self._max_len = self._model.config.max_position_embeddings
  
          if self._frozen:
              log.info("\tFrozen Model + Training Classifier Layers")
              """
                  Freeze the base transformer model and train a linear layer on top
                  """
              # Freeze all the transformer parameters
              for param in self._model.base_model.parameters():
                  param.requires_grad = False
  
              optimizer_grouped_parameters = self._model.parameters()
  
          else:
              log.info("\tFine-tuning model")
              """
                  Fine-tuning parameters with weight decay
                  """
              no_decay = [
                  "bias",
                  "LayerNorm.weight",
              ]  # decay on all terms EXCLUDING bias/layernorms
              optimizer_grouped_parameters = [
                  {
                      "params": [
                          p
                          for n, p in self._model.named_parameters()
                          if not any(nd in n for nd in no_decay)
                      ],
                      "weight_decay": 0.01,
                  },
                  {
                      "params": [
                          p
                          for n, p in self._model.named_parameters()
                          if any(nd in n for nd in no_decay)
                      ],
                      "weight_decay": 0.0,
                  },
              ]
  
          optimizer = AdamW(optimizer_grouped_parameters, lr=1e-5)
          scheduler = get_linear_schedule_with_warmup(
              optimizer,
              num_warmup_steps=0,  # default value for GLUE
              num_training_steps=len(train_dataset) * self._epochs,
          )
  
          # Train model; declare optimizer earlier if desired.
          self._tune_model(
              train_dataset,
              val_dataset,
              optim=optimizer,
              scheduler=scheduler,
              n_epochs=self._epochs,
          )
  
      else:
          log.info(
              "Target is not classification; Embeddings Generator only"
          )
  
          self.model_type = "embeddings_generator"
          self._model = self._embeddings_model_class.from_pretrained(
              self._pretrained_model_name
          ).to(self.device)
  
          # TODO: Not a great flag
          # Currently, if the task is not classification, you must have an embedding generator only
          if self.embed_mode is False:
              log.info(
                  "Embedding mode must be ON for non-classification targets."
              )
              self.embed_mode = True
  
      self.is_prepared = True
      encoded = self.encode(priming_data[0:1])
      self.output_size = len(encoded[0])
  
imports: import os
  import time
  from typing import Iterable
  from collections import deque
  import numpy
  import torch
  from torch.utils.data import DataLoader
  import pandas
  from type_infer.dtype import dtype
  from transformers import DistilBertModel, DistilBertForSequenceClassification, DistilBertTokenizerFast, AdamW, get_linear_schedule_with_warmup
  from sklearn.model_selection import train_test_split
  from lightwood.encoder.text.helpers.pretrained_helpers import TextEmbed
  from lightwood.helpers.device import get_device_from_name
  from lightwood.encoder.base import BaseEncoder
  from lightwood.helpers.log import log
  from lightwood.helpers.torch import LightwoodAutocast
  from lightwood.helpers.general import is_none
label_desc: Use image node_id 2 for calling the PretrainedLangEncoder obj's underlying member method code with example usage: obj.prepare(train_priming_data, dev_priming_data, encoded_target_values) without return types