code: def evaluate(
      answers: List[Dict],
      prompt: Dict[str, Any],
      metrics: List[str],
      category: str,
      save_path: str,
      model_name: str,
      model: str,
      language: str,
      references: List[Dict] = None,
  ) -> List[Dict]:
      """
      Use GPT models to evaluate model answers and save evaluation results.
  
      Args:
          answers: model answers.
          prompt: prompt for GPT evaluation.
          metrics: metrics for GPT evaluation.
          category: the category of the model answers for evaluation.
          model: the specific GPT model used to evaluate answers.
          language: language used in GPT evaluation
          references: references for GPT evaluation
  
      Returns:
          Evaluations of the given answers.
      """
  
      print(
          f"The number of instances of category {category}'s is {len(answers)}."
      )
  
      evaluations = []
  
      metrics_str = ", ".join(x for x in metrics)
      print(f"Category {category}'s metrics are {metrics_str}.")
  
      gpt_base_save_path = os.path.join(
          save_path, "gpt_evaluate", "gpt_evaluate_results"
      )
      gpt_evaluation_results_save_path = os.path.join(
          gpt_base_save_path, "evaluation_results"
      )
      category_file = os.path.join(
          gpt_evaluation_results_save_path,
          model_name,
          f"{category}_evaluation_results.json",
      )
  
      if os.path.exists(category_file):
          print(
              f"Evaluation results for category {category}, model {model_name} already exists."
          )
          print("Skip evaluating.")
  
          evaluations = jload(category_file)
  
          retry = []
          evaluations_copy = deepcopy(evaluations)
  
          success = []
          for idx, e in enumerate(evaluations_copy):
              keys = list(e["evaluation"].keys())
              for key in keys:
                  if e["evaluation"][key] == {}:
                      retry.append(e["id"])
                      print(f"Re-evaluate id {e['id']} now.")
                      break
              if e["id"] not in retry:
                  success.append(e)
  
          if len(retry) == 0:
              evaluations.sort(key=lambda x: x["id"])
              print(f"{category} done.")
              return evaluations
  
          with concurrent.futures.ThreadPoolExecutor(
              max_workers=4
          ) as executor:
              futures = []
              for idx, inst in enumerate(answers):
                  if not inst["id"] in retry:
                      continue
                  # Completion models can return log probabilities.
                  if model == "text-davinci-003":
                      future = executor.submit(
                          get_gpt_evaluation_with_logprobs,
                          prompt,
                          inst,
                          metrics,
                          1,
                      )
                  else:
                      future = executor.submit(
                          get_gpt_evaluation_without_logprobs,
                          prompt,
                          inst,
                          metrics,
                          language,
                          reference=None
                          if references is None
                          else references[idx],
                          model=model,
                          max_tokens=1,
                      )
  
                  futures.append(future)
  
              for future in tqdm.tqdm(
                  concurrent.futures.as_completed(futures),
                  desc=f"{category}: ",
                  total=len(futures),
              ):
                  success.append(future.result())
  
          success.sort(key=lambda x: x["id"])
  
          print(
              f"Saving evaluation results for category {category}, model {model_name}."
          )
  
          jdump(success, category_file)
  
          return success
  
      with concurrent.futures.ThreadPoolExecutor(
          max_workers=4
      ) as executor:
          futures = []
          for idx, inst in enumerate(answers):
              # Completion models can return log probabilities.
              if model == "text-davinci-003":
                  future = executor.submit(
                      get_gpt_evaluation_with_logprobs,
                      prompt,
                      inst,
                      metrics,
                      1,
                  )
              else:
                  future = executor.submit(
                      get_gpt_evaluation_without_logprobs,
                      prompt,
                      inst,
                      metrics,
                      language,
                      reference=None
                      if references is None
                      else references[idx],
                      model=model,
                      max_tokens=1,
                  )
  
              futures.append(future)
  
          for future in tqdm.tqdm(
              concurrent.futures.as_completed(futures),
              desc=f"{category}: ",
              total=len(futures),
          ):
              evaluations.append(future.result())
  
      evaluations.sort(key=lambda x: x["id"])
  
      print(f"{category} done.")
  
      print(
          f"Saving evaluation results for category {category}, model {model_name}."
      )
  
      jdump(evaluations, category_file)
  
      return evaluations
  
imports: import concurrent.futures
  import os
  import re
  import time
  from copy import deepcopy
  from typing import Any, Dict, List
  import matplotlib.pyplot
  import numpy
  import openai
  import pandas
  import seaborn
  import tqdm
  from colossal_eval.utils import jdump, jload
label_desc: Use image node_id 10 for calling a global function with example usage: evaluate(answers, prompt, metrics, category, save_path, model_name, model, language, references) and returns: evaluations, success, evaluations