docstr: Calculate loss only on target tokens.
  
  Args:
      batch: A batch of prompt without target answer.
      batch_target: A batch of target answer. Sometimes one question can have multiple target answers.
  
  Returns:
      Loss.
docstr_tok: ["Calculate","loss","only","on","target","tokens",".","Args",":","batch",":","A","batch","of","prompt","without","target","answer",".","batch_target",":","A","batch","of","target","answer",".","Sometimes","one","question","can","have","multiple","target","answers",".","Returns",":","Loss","."]
code: def get_loss(
      self,
      batch_prompt: List[str],
      batch_target: List[List[str]],
      pretrain: bool = False,
  ) -> List[List[float]]:
      """
      Calculate loss only on target tokens.
  
      Args:
          batch: A batch of prompt without target answer.
          batch_target: A batch of target answer. Sometimes one question can have multiple target answers.
  
      Returns:
          Loss.
  
      """
  
      # We set max_new_tokens in self._get_truncated_prompts to 0 because we only need logits to calculate loss.
      # We don't need to generate new tokens.
      # Target answer's length is usually << model_max_length, but we still call it in case.
      # We don't call self._get_truncated_prompts for batch_prompt because we need target answer's length first to reserve some space for target answer's tokens.
      batch_target = [
          self._get_truncated_prompts(prompt_target, 0)
          for prompt_target in batch_target
      ]
  
      # Get the number of target answers for different questions
      batch_target_nums = [
          len(prompt_target) for prompt_target in batch_target
      ]
  
      labels_list = []
      input_ids_list = []
  
      for input, targets in zip(batch_prompt, batch_target):
          for target in targets:
              # Adapted from https://github.com/THUDM/ChatGLM2-6B/blob/main/ptuning/main.py#L180
              prompt = self.tokenizer.build_prompt(input, None)
  
              target_tokenized = self.tokenizer.encode(
                  text=target,
                  add_special_tokens=False,
                  truncation=True,
                  max_length=self.model_max_length,
              )
  
              max_new_tokens = len(target_tokenized)
              prompt_with_correct_length = self._get_truncated_prompts(
                  [prompt], max_new_tokens
              )[0]
              input_tokenized = self.tokenizer.encode(
                  prompt_with_correct_length,
                  add_special_tokens=True,
                  truncation=True,
                  max_length=self.model_max_length,
              )
  
              input_ids = (
                  input_tokenized
                  + target_tokenized
                  + [self.tokenizer.eos_token_id]
              )
              target_ids = [IGNORE_INDEX] * len(input_ids)
  
              # -1 is for "eos"
              target_ids[-max_new_tokens - 1 : -1] = input_ids[
                  -max_new_tokens - 1 : -1
              ]
  
              input_ids_list.append(torch.LongTensor(input_ids))
              labels_list.append(torch.LongTensor(target_ids))
  
      # Because of multiple target answers, the final batch size may be greater than self.batch_size.
      # We will generate new batches.
      losses = []
      target_token_nums = []
  
      batched_input_ids = [
          input_ids_list[i : i + self.batch_size]
          for i in range(0, len(input_ids_list), self.batch_size)
      ]
      batched_labels = [
          labels_list[i : i + self.batch_size]
          for i in range(0, len(labels_list), self.batch_size)
      ]
  
      for batch_input_ids, batch_labels in zip(
          batched_input_ids, batched_labels
      ):
          (
              losses_per_batch,
              target_token_num_per_batch,
          ) = self._calculate_loss(batch_input_ids, batch_labels)
          losses.extend(losses_per_batch)
          target_token_nums.extend(target_token_num_per_batch)
  
      start_indice = 0
      losses_per_sample = []
  
      target_token_nums_per_sample = []
      for length in batch_target_nums:
          losses_per_sample.append(
              losses[start_indice : start_indice + length]
          )
          target_token_nums_per_sample.append(
              target_token_nums[start_indice : start_indice + length]
          )
          start_indice += length
  
      return losses_per_sample, target_token_nums_per_sample, None
  
file_path: ColossalAI/applications/ColossalEval/colossal_eval/models/chatglm.py
imports: import copy
  from typing import List
  import torch
  from .huggingface import HuggingFaceModel
label_desc: Use image node_id 3 for calling the ChatGLM2Model obj's underlying member method code with example usage: obj.get_loss(batch_prompt, batch_target, pretrain) and returns: losses_per_sample,  target_token_nums_per_sample,  None