code: def eval_model(args):
      # Data
      dataset = LVISData_V1(
          data_path=args.data_path,
          image_path=args.image_path,
          args=args,
      )
      data_ids = dataset.ids
  
      # 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)
  
      chunk_data_ids = get_chunk(
          data_ids, args.num_chunks, args.chunk_idx
      )
      answers_file = os.path.expanduser(args.answers_file)
      os.makedirs(answers_file, exist_ok=True)
      answers_file = os.path.join(
          answers_file, f"{args.chunk_idx}_of_{args.num_chunks}.jsonl"
      )
      ans_file = open(answers_file, "w")
  
      for i, id in enumerate(tqdm(chunk_data_ids)):
          ann = dataset.fetch_data(id)
          image_path = ann["image_path"]
  
          qs = ann["question"]
          cur_prompt = qs
          # pdb.set_trace()
          if model.config.mm_use_im_start_end:
              qs = (
                  DEFAULT_IM_START_TOKEN
                  + DEFAULT_IMAGE_TOKEN
                  + DEFAULT_IM_END_TOKEN
                  + "\n"
                  + qs
              )
          else:
              qs = DEFAULT_IMAGE_TOKEN + "\n" + qs
  
          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()
          )
          image = Image.open(image_path).convert("RGB")
          image_tensor = image_processor.preprocess(
              image,
              return_tensors="pt",
              do_resize=True,
              do_center_crop=False,
              size=[args.image_h, args.image_w],
          )["pixel_values"][0]
  
          stop_str = (
              conv.sep
              if conv.sep_style != SeparatorStyle.TWO
              else conv.sep2
          )
          keywords = [stop_str]
          stopping_criteria = KeywordsStoppingCriteria(
              keywords, tokenizer, input_ids
          )
  
          region_masks = ann["region_masks"]
          if region_masks is not None:
              region_masks = [
                  [
                      region_mask_i.cuda().half()
                      for region_mask_i in region_masks
                  ]
              ]
          else:
              region_masks = None
  
          # pdb.set_trace()
          with torch.inference_mode():
              model.orig_forward = model.forward
              model.forward = partial(
                  model.orig_forward, region_masks=region_masks
              )
              output_ids = model.generate(
                  input_ids,
                  images=image_tensor.unsqueeze(0).half().cuda(),
                  do_sample=True,
                  temperature=args.temperature,
                  top_p=args.top_p,
                  num_beams=args.num_beams,
                  # no_repeat_ngram_size=3,
                  max_new_tokens=1024,
                  use_cache=True,
                  stopping_criteria=[stopping_criteria],
              )
              model.forward = model.orig_forward
  
          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] Sample {i}: {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()
  
          # pdb.set_trace()
          ans_file.write(
              json.dumps(
                  {
                      "id": ann["id"],  # +1 offset
                      "image_path": image_path,
                      "prompt": cur_prompt,
                      "text": outputs,
                      "name": ann["name"],
                      "synonyms": ann["synonyms"],
                      "bbox": ann["bbox"],
                      "bbox_norm": ann["bbox_norm"],
                      "width": ann["width"],
                      "height": ann["height"],
                  }
              )
              + "\n"
          )
          ans_file.flush()
      ans_file.close()
  
imports: import argparse
  import torch
  import os
  import json
  from tqdm import tqdm
  from ferret.mm_utils import tokenizer_image_token, get_model_name_from_path, KeywordsStoppingCriteria
  from ferret.model.builder import load_pretrained_model
  from ferret.constants import IMAGE_TOKEN_INDEX, DEFAULT_IMAGE_TOKEN, DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN
  from ferret.conversation import conv_templates, SeparatorStyle
  from ferret.utils import disable_torch_init
  from PIL import Image
  import math
  import pdb
  import numpy
  from copy import deepcopy
  from functools import partial
label_desc: Use image node_id 4 for calling a global function with example usage: eval_model(args) without return types