code: def eval_model(args):
      # Model
      disable_torch_init()
      model_path = os.path.expanduser(args.model_path)
      model_name = get_model_name_from_path(model_path)
      (
          tokenizer,
          model,
          image_processor,
          context_len,
      ) = load_pretrained_model(model_path, args.model_base, model_name)
  
      questions = json.load(
          open(os.path.expanduser(args.question_file), "r")
      )
      questions = get_chunk(questions, args.num_chunks, args.chunk_idx)
      answers_file = os.path.expanduser(args.answers_file)
      os.makedirs(os.path.dirname(answers_file), exist_ok=True)
      ans_file = open(answers_file, "w")
      for i, line in enumerate(tqdm(questions)):
          idx = line["id"]
          question = line["conversations"][0]
          qs = question["value"].replace("<image>", "").strip()
          cur_prompt = qs
  
          if "image" in line:
              image_file = line["image"]
              image = Image.open(
                  os.path.join(args.image_folder, image_file)
              )
              image_tensor = image_processor.preprocess(
                  image, return_tensors="pt"
              )["pixel_values"][0]
              images = image_tensor.unsqueeze(0).half().cuda()
              if getattr(model.config, "mm_use_im_start_end", False):
                  qs = (
                      DEFAULT_IM_START_TOKEN
                      + DEFAULT_IMAGE_TOKEN
                      + DEFAULT_IM_END_TOKEN
                      + "\n"
                      + qs
                  )
              else:
                  qs = DEFAULT_IMAGE_TOKEN + "\n" + qs
              cur_prompt = "<image>" + "\n" + cur_prompt
          else:
              images = None
  
          if args.single_pred_prompt:
              qs = (
                  qs
                  + "\n"
                  + "Answer with the option's letter from the given choices directly."
              )
              cur_prompt = (
                  cur_prompt
                  + "\n"
                  + "Answer with the option's letter from the given choices directly."
              )
  
          conv = conv_templates[args.conv_mode].copy()
          conv.append_message(conv.roles[0], qs)
          conv.append_message(conv.roles[1], None)
          prompt = conv.get_prompt()
  
          input_ids = (
              tokenizer_image_token(
                  prompt,
                  tokenizer,
                  IMAGE_TOKEN_INDEX,
                  return_tensors="pt",
              )
              .unsqueeze(0)
              .cuda()
          )
  
          stop_str = (
              conv.sep
              if conv.sep_style != SeparatorStyle.TWO
              else conv.sep2
          )
          keywords = [stop_str]
          stopping_criteria = (
              [KeywordsStoppingCriteria(keywords, tokenizer, input_ids)]
              if conv.version == "v0"
              else None
          )
  
          model.update_prompt(
              [[cur_prompt.replace("<image>", "").strip("\n")]]
          )
  
          with torch.inference_mode():
              output_ids = model.generate(
                  input_ids,
                  images=images,
                  do_sample=True if args.temperature > 0 else False,
                  temperature=args.temperature,
                  max_new_tokens=1024,
                  use_cache=True,
                  stopping_criteria=stopping_criteria,
              )
  
          input_token_len = input_ids.shape[1]
          n_diff_input_output = (
              (input_ids != output_ids[:, :input_token_len])
              .sum()
              .item()
          )
          if n_diff_input_output > 0:
              print(
                  f"[Warning] {n_diff_input_output} output_ids are not the same as the input_ids"
              )
          outputs = tokenizer.batch_decode(
              output_ids[:, input_token_len:], skip_special_tokens=True
          )[0]
          outputs = outputs.strip()
          if outputs.endswith(stop_str):
              outputs = outputs[: -len(stop_str)]
          outputs = outputs.strip()
  
          # prompt for answer
          if args.answer_prompter:
              outputs_reasoning = outputs
              input_ids = (
                  tokenizer_image_token(
                      prompt + outputs_reasoning + " ###\nANSWER:",
                      tokenizer,
                      IMAGE_TOKEN_INDEX,
                      return_tensors="pt",
                  )
                  .unsqueeze(0)
                  .cuda()
              )
  
              with torch.inference_mode():
                  output_ids = model.generate(
                      input_ids,
                      images=images,
                      do_sample=True if args.temperature > 0 else False,
                      temperature=args.temperature,
                      max_new_tokens=64,
                      use_cache=True,
                      stopping_criteria=[stopping_criteria],
                  )
  
              input_token_len = input_ids.shape[1]
              n_diff_input_output = (
                  (input_ids != output_ids[:, :input_token_len])
                  .sum()
                  .item()
              )
              if n_diff_input_output > 0:
                  print(
                      f"[Warning] {n_diff_input_output} output_ids are not the same as the input_ids"
                  )
              outputs = tokenizer.batch_decode(
                  output_ids[:, input_token_len:],
                  skip_special_tokens=True,
              )[0]
              outputs = outputs.strip()
              if outputs.endswith(stop_str):
                  outputs = outputs[: -len(stop_str)]
              outputs = outputs.strip()
              outputs = (
                  outputs_reasoning + "\n The answer is " + outputs
              )
  
          ans_id = shortuuid.uuid()
          ans_file.write(
              json.dumps(
                  {
                      "question_id": idx,
                      "prompt": cur_prompt,
                      "text": outputs,
                      "answer_id": ans_id,
                      "model_id": model_name,
                      "metadata": {},
                  }
              )
              + "\n"
          )
          ans_file.flush()
      ans_file.close()
  
file_path: llama-vid/llamavid/eval/model_vqa_science.py
imports: import argparse
  import torch
  import os
  import json
  from tqdm import tqdm
  import shortuuid
  from llamavid.constants import IMAGE_TOKEN_INDEX, DEFAULT_IMAGE_TOKEN, DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN
  from llamavid.conversation import conv_templates, SeparatorStyle
  from llamavid.model.builder import load_pretrained_model
  from llava.utils import disable_torch_init
  from llava.mm_utils import tokenizer_image_token, get_model_name_from_path, KeywordsStoppingCriteria
  from PIL import Image
  import math
label_desc: Use image node_id 3 for calling a global function with example usage: eval_model(args) without return types