code: def main_eval(
      model_path,
      backbone,
      config,
      evaluator,
      result_dir,
      buffer,
      model,
      mode,
  ):
      if not os.path.exists(result_dir):
          os.makedirs(result_dir, exist_ok=True)
  
      total_imgs_bboxes_gt, total_imgs_path = load_test_dataset_iou(
          "custom_data", config
      )
  
      if mode == "weak_supervision" and torch.cuda.device_count() != 1:
          gpu_count = torch.cuda.device_count() // 2
      else:
          gpu_count = torch.cuda.device_count()
      gpu_idx = torch.cuda.current_device()
      torch.cuda.set_device(gpu_idx)
  
      # Only evaluation time
      if model is None:
          piece_imgs_path = total_imgs_path
  
          if backbone == "vgg":
              model = CRAFT()
          else:
              raise Exception("Undefined architecture")
  
          print("Loading weights from checkpoint (" + model_path + ")")
          net_param = torch.load(
              model_path, map_location=f"cuda:{gpu_idx}"
          )
          model.load_state_dict(copyStateDict(net_param["craft"]))
  
          if config.cuda:
              model = model.cuda()
              cudnn.benchmark = False
  
      # Distributed evaluation in the middle of training time
      else:
          if buffer is not None:
              # check all buffer value is None for distributed evaluation
              assert all(
                  v is None for v in buffer
              ), "Buffer already filled with another value."
          slice_idx = len(total_imgs_bboxes_gt) // gpu_count
  
          # last gpu
          if gpu_idx == gpu_count - 1:
              piece_imgs_path = total_imgs_path[gpu_idx * slice_idx :]
              # piece_imgs_bboxes_gt = total_imgs_bboxes_gt[gpu_idx * slice_idx:]
          else:
              piece_imgs_path = total_imgs_path[
                  gpu_idx * slice_idx : (gpu_idx + 1) * slice_idx
              ]
              # piece_imgs_bboxes_gt = total_imgs_bboxes_gt[gpu_idx * slice_idx: (gpu_idx + 1) * slice_idx]
  
      model.eval()
  
      # -----------------------------------------------------------------------------------------------------------------#
      total_imgs_bboxes_pre = []
      for k, img_path in enumerate(tqdm(piece_imgs_path)):
          image = cv2.imread(img_path)
          image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
          single_img_bbox = []
          bboxes, polys, score_text = test_net(
              model,
              image,
              config.text_threshold,
              config.link_threshold,
              config.low_text,
              config.cuda,
              config.poly,
              config.canvas_size,
              config.mag_ratio,
          )
  
          for box in bboxes:
              box_info = {"points": box, "text": "###", "ignore": False}
              single_img_bbox.append(box_info)
          total_imgs_bboxes_pre.append(single_img_bbox)
          # Distributed evaluation -------------------------------------------------------------------------------------#
          if buffer is not None:
              buffer[gpu_idx * slice_idx + k] = single_img_bbox
          # print(sum([element is not None for element in buffer]))
          # -------------------------------------------------------------------------------------------------------------#
  
          if config.vis_opt:
              viz_test(
                  image,
                  score_text,
                  pre_box=polys,
                  gt_box=total_imgs_bboxes_gt[k],
                  img_name=img_path,
                  result_dir=result_dir,
                  test_folder_name="custom_data",
              )
  
      # When distributed evaluation mode, wait until buffer is full filled
      if buffer is not None:
          while None in buffer:
              continue
          assert all(v is not None for v in buffer), "Buffer not filled"
          total_imgs_bboxes_pre = buffer
  
      results = []
      for i, (gt, pred) in enumerate(
          zip(total_imgs_bboxes_gt, total_imgs_bboxes_pre)
      ):
          perSampleMetrics_dict = evaluator.evaluate_image(gt, pred)
          results.append(perSampleMetrics_dict)
  
      metrics = evaluator.combine_results(results)
      print(metrics)
      return metrics
  
imports: import argparse
  import os
  import cv2
  import numpy
  import torch
  import torch.backends.cudnn
  from tqdm import tqdm
  import wandb
  from config.load_config import load_yaml, DotDict
  from model.craft import CRAFT
  from metrics.eval_det_iou import DetectionIoUEvaluator
  from utils.inference_boxes import test_net, load_icdar2015_gt, load_icdar2013_gt, load_synthtext_gt
  from utils.util import copyStateDict
label_desc: Use image node_id 7 for calling a global function with example usage: main_eval(model_path, backbone, config, evaluator, result_dir, buffer, model, mode) and returns: metrics