modrec-workflow/convert_to_onnx.py

84 lines
2.3 KiB
Python
Raw Normal View History

import os
import numpy as np
import torch
from data.training.mobilenetv3 import mobilenetv3, RFClassifier
from onnx_files import ONNX_DIR
from helpers.app_settings import get_app_settings
def convert_to_onnx(ckpt_path, fp16=False):
"""
Convert a PyTorch model to ONNX format.
Parameters:
model (torch.nn.Module): The PyTorch model to convert.
input_shape (tuple): The shape of the input tensor.
output_path (str): The path to save the converted ONNX model.
"""
settings = get_app_settings()
2025-05-22 14:12:36 -04:00
inference_cfg = settings.inference
dataset_cfg = settings.dataset
2025-05-22 14:12:36 -04:00
in_channels = 2
batch_size = 1
2025-05-22 14:12:36 -04:00
slice_length = int(1024 / dataset_cfg.num_slices)
num_classes = inference_cfg.num_classes
2025-05-22 14:12:36 -04:00
model = RFClassifier(
model=mobilenetv3(
model_size="mobilenetv3_small_050",
num_classes=num_classes,
in_chans=in_channels,
)
)
2025-05-22 14:12:36 -04:00
checkpoint = torch.load(
2025-05-22 14:12:36 -04:00
ckpt_path, weights_only=True, map_location=torch.device("cpu")
)
model.load_state_dict(checkpoint["state_dict"])
2025-05-22 14:12:36 -04:00
if fp16:
model.half()
2025-05-22 14:12:36 -04:00
model.eval()
2025-05-22 14:12:36 -04:00
# Generate random sample data
base, ext = os.path.splitext(os.path.basename(ckpt_path))
if fp16:
output_path = os.path.join(ONNX_DIR, f"{base}_fp16.onnx")
sample_input = torch.from_numpy(
np.random.rand(batch_size, in_channels, slice_length).astype(np.float16)
)
else:
output_path = os.path.join(ONNX_DIR, f"{base}_fp32.onnx")
sample_input = torch.rand(batch_size, in_channels, slice_length)
2025-05-22 14:12:36 -04:00
torch.onnx.export(
model=model,
args=sample_input,
f=output_path,
export_params=True,
opset_version=20, # Last compatible with ORT v1.15.1 is 18, 21 not supported by torch export
do_constant_folding=True,
input_names=["input"],
output_names=["output"],
dynamo=False, # Requires onnxscript
)
2025-05-22 14:12:36 -04:00
if __name__ == "__main__":
from checkpoint_files import CHECKPOINTS_DIR
2025-05-22 15:04:19 -04:00
model_checkpoint = "inference_recognition_model.ckpt"
2025-05-22 14:12:36 -04:00
print("Converting to ONNX...")
2025-05-22 14:12:36 -04:00
convert_to_onnx(
ckpt_path=os.path.join(CHECKPOINTS_DIR, model_checkpoint), fp16=False
)
print("Conversion complete stored at: ", os.path.join(ONNX_DIR, model_checkpoint))