code: def pytorch2onnx(
      config_path,
      checkpoint_path,
      input_img,
      input_shape,
      opset_version=11,
      show=False,
      output_file="tmp.onnx",
      verify=False,
      simplify=True,
      dynamic=True,
      normalize_cfg=None,
      dataset="coco",
      test_img=None,
  ):
      input_config = {
          "input_shape": input_shape,
          "input_path": input_img,
          "normalize_cfg": normalize_cfg,
      }
      checkpoint = torch.load(checkpoint_path, map_location="cpu")
      tmp_ckpt_file = None
      # remove optimizer for smaller file size
      if "optimizer" in checkpoint:
          del checkpoint["optimizer"]
          tmp_ckpt_file = checkpoint_path + "_slim.pth"
          torch.save(checkpoint, tmp_ckpt_file)
          print("remove optimizer params and save to", tmp_ckpt_file)
          checkpoint_path = tmp_ckpt_file
  
      model, tensor_data = generate_inputs_and_wrap_model(
          config_path, checkpoint_path, input_config
      )
  
      if tmp_ckpt_file is not None:
          os.remove(tmp_ckpt_file)
  
      if simplify or dynamic:
          ori_output_file = output_file.split(".")[0] + "_ori.onnx"
      else:
          ori_output_file = output_file
  
      # Define input and outputs names, which are required to properly define
      # dynamic axes
      input_names = ["input.1"]
      output_names = [
          "score_8",
          "score_16",
          "score_32",
          "bbox_8",
          "bbox_16",
          "bbox_32",
      ]
  
      # If model graph contains keypoints strides add keypoints to outputs
      if "stride_kps" in str(model):
          output_names += ["kps_8", "kps_16", "kps_32"]
  
      # Define dynamic axes for export
      dynamic_axes = None
      if dynamic:
          dynamic_axes = {out: {0: "?", 1: "?"} for out in output_names}
          dynamic_axes[input_names[0]] = {0: "?", 2: "?", 3: "?"}
  
      torch.onnx.export(
          model,
          tensor_data,
          ori_output_file,
          keep_initializers_as_inputs=False,
          verbose=False,
          input_names=input_names,
          output_names=output_names,
          dynamic_axes=dynamic_axes,
          opset_version=opset_version,
      )
  
      if simplify or dynamic:
          model = onnx.load(ori_output_file)
          if simplify:
              from onnxsim import simplify
  
              # print(model.graph.input[0])
              if dynamic:
                  input_shapes = {
                      model.graph.input[0].name: list(input_shape)
                  }
                  model, check = simplify(
                      model,
                      input_shapes=input_shapes,
                      dynamic_input_shape=True,
                  )
              else:
                  model, check = simplify(model)
              assert (
                  check
              ), "Simplified ONNX model could not be validated"
          onnx.save(model, output_file)
          os.remove(ori_output_file)
  
      print(f"Successfully exported ONNX model: {output_file}")
  
file_path: insightface/detection/scrfd/tools/scrfd2onnx.py
imports: import argparse
  import os.path
  import numpy
  import onnx
  import os
  import torch
  from mmdet.core import build_model_from_cfg, generate_inputs_and_wrap_model, preprocess_example_input
label_desc: Use image node_id 1 for calling a global function with example usage: pytorch2onnx(config_path, checkpoint_path, input_img, input_shape, opset_version, show, output_file, verify, simplify, dynamic, normalize_cfg, dataset, test_img) without return types