code: def forward(self, logits, labels):
      shift_logits = logits[..., :-1, :].contiguous()
      shift_labels = labels[..., 1:].contiguous()
  
      perplexity = []
      for i in range(labels.shape[0]):
          perplexity.append(
              self.loss_fn(shift_logits[i], shift_labels[i])
          )
      perplexity = torch.stack(perplexity, dim=0)
      perplexity = torch.exp(perplexity)
      if self.reduce:
          perplexity = torch.mean(perplexity)
      return perplexity
  
imports: import logging
  import os
  from functools import partial
  from typing import Any, Dict, List, Tuple, Union
  import numpy
  import openai
  import pandas
  import torch
  from joblib import Parallel, delayed
  from numpy.typing import NDArray
  from sacrebleu import BLEU
  from sacrebleu.metrics.base import Metric
  from tenacity import retry, stop_after_attempt, wait_random_exponential
  from torch import nn
  from tqdm import tqdm
  from llm_studio.src.datasets.text_utils import get_texts
  from llm_studio.src.utils.logging_utils import TqdmToLogger
label_desc: Use image node_id 2 for calling the Perplexity obj's underlying member method code with example usage: obj.forward(logits, labels) and returns: perplexity