TonalIQ-Backend / src /models /onnx_export.py
rohan21005's picture
Upload 34 files
2486f9d verified
Raw
History Blame Contribute Delete
2.68 kB
"""
backend/src/models/onnx_export.py
Converts the trained PyTorch Wav2Vec2 model to an optimized ONNX format,
and performs dynamic INT8 quantization for low-latency production execution.
"""
import torch
import logging
from pathlib import Path
from transformers import Wav2Vec2ForSequenceClassification
from onnxruntime.quantization import quantize_dynamic, QuantType
from src.models.config import CHECKPOINT_DIR, OPTIMIZED_DIR, MODEL_NAME, NUM_LABELS
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
def export_and_quantize():
hf_model_path = CHECKPOINT_DIR / "hf_model"
if not hf_model_path.exists():
logger.error(f"Fine-tuned HuggingFace model missing at {hf_model_path}. Train the model first!")
return
logger.info(f"Loading fine-tuned model from {hf_model_path} for ONNX export...")
model = Wav2Vec2ForSequenceClassification.from_pretrained(hf_model_path)
model.eval()
# Define paths
onnx_path = OPTIMIZED_DIR / "model.onnx"
quant_path = OPTIMIZED_DIR / "model_quantized.onnx"
# 1. Export to ONNX
logger.info("Exporting model to ONNX...")
# Dummy input: batch_size=1, audio_length = 3 seconds (3 * 16000 = 48000 samples)
dummy_input = torch.randn(1, 48000)
# Export with dynamic axes for input sequence length and batch size
torch.onnx.export(
model,
dummy_input,
str(onnx_path),
input_names=["input_values"],
output_names=["logits"],
dynamic_axes={
"input_values": {0: "batch_size", 1: "sequence_length"},
"logits": {0: "batch_size"}
},
opset_version=14,
do_constant_folding=True
)
logger.info(f"Base ONNX model successfully saved to {onnx_path}")
# 2. INT8 Dynamic Quantization
logger.info("Quantizing ONNX model to INT8...")
try:
quantize_dynamic(
model_input=str(onnx_path),
model_output=str(quant_path),
weight_type=QuantType.QUInt8
)
logger.info(f"Quantized INT8 ONNX model successfully saved to {quant_path}")
except Exception as e:
logger.warning(f"ONNX Quantization failed due to shape inference constraints: {str(e)}")
logger.info("Falling back to unquantized base ONNX model for production execution...")
import shutil
shutil.copy(onnx_path, quant_path)
logger.info(f"Base ONNX model copied to {quant_path} successfully.")
if __name__ == "__main__":
export_and_quantize()