2025-05-22 14:12:10 -04:00
|
|
|
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
|
|
|
|
2025-05-22 14:12:10 -04:00
|
|
|
inference_cfg = settings.inference
|
|
|
|
dataset_cfg = settings.dataset
|
2025-05-22 14:12:36 -04:00
|
|
|
|
2025-05-22 14:12:10 -04:00
|
|
|
in_channels = 2
|
|
|
|
batch_size = 1
|
2025-05-22 14:12:36 -04:00
|
|
|
slice_length = int(1024 / dataset_cfg.num_slices)
|
2025-05-22 14:12:10 -04:00
|
|
|
num_classes = inference_cfg.num_classes
|
2025-05-22 14:12:36 -04:00
|
|
|
|
2025-05-22 14:12:10 -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
|
|
|
|
2025-05-22 14:12:10 -04:00
|
|
|
checkpoint = torch.load(
|
2025-05-22 14:12:36 -04:00
|
|
|
ckpt_path, weights_only=True, map_location=torch.device("cpu")
|
2025-05-22 14:12:10 -04:00
|
|
|
)
|
|
|
|
model.load_state_dict(checkpoint["state_dict"])
|
2025-05-22 14:12:36 -04:00
|
|
|
|
2025-05-22 14:12:10 -04:00
|
|
|
if fp16:
|
|
|
|
model.half()
|
2025-05-22 14:12:36 -04:00
|
|
|
|
2025-05-22 14:12:10 -04:00
|
|
|
model.eval()
|
2025-05-22 14:12:36 -04:00
|
|
|
|
2025-05-22 14:12:10 -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
|
|
|
|
2025-05-22 14:12:10 -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
|
|
|
|
|
|
|
|
2025-05-22 14:12:10 -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
|
|
|
|
2025-05-22 14:12:10 -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))
|