DEV Community

ONNX Converter
ONNX Converter

Posted on

How to Convert ML Models to ONNX Format: A Complete Guide

Making machine learning model deployment effortless across platforms


TL;DR

Converting ML models to ONNX format enables universal deployment across platforms. This guide covers manual conversion methods and introduces a free tool I built to simplify the process: ONNX Converter.


The Problem: ML Deployment Hell πŸ˜…

Picture this: You've spent weeks building the perfect scikit-learn model. It's accurate, well-tuned, and ready for production. Then comes deployment day...

  • Cloud platform: "We need TensorFlow format"
  • Mobile team: "Can you convert this to Core ML?"
  • Edge device: "ONNX only, please"
  • Backend team: "Just give us a REST API"

Sound familiar? This is where ONNX (Open Neural Network Exchange) becomes your best friend.

What is ONNX and Why Should You Care?

ONNX is an open standard for representing machine learning models. Think of it as the "PDF of machine learning" - a universal format that works everywhere.

Key Benefits:

  • 🌐 Universal compatibility - Deploy anywhere
  • ⚑ Optimized performance - Faster inference
  • πŸ”„ Framework flexibility - Switch between tools easily
  • πŸ“± Multi-platform - Cloud, edge, mobile, web

Supported Platforms:

  • Cloud: Azure ML, AWS SageMaker, Google Cloud AI
  • Edge: NVIDIA Jetson, Intel OpenVINO
  • Mobile: iOS Core ML, Android NNAPI
  • Web: ONNX.js for browser deployment

Manual Conversion Methods

1. Scikit-learn to ONNX

# Install required packages
pip install scikit-learn skl2onnx onnx

# Convert sklearn model
from sklearn.ensemble import RandomForestClassifier
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import pickle

# Load your trained model
with open('model.pkl', 'rb') as f:
    model = pickle.load(f)

# Define input shape (adjust for your model)
initial_types = [('input', FloatTensorType([None, 4]))]

# Convert to ONNX
onnx_model = convert_sklearn(
    model, 
    initial_types=initial_types,
    target_opset=11
)

# Save ONNX model
with open('model.onnx', 'wb') as f:
    f.write(onnx_model.SerializeToString())
Enter fullscreen mode Exit fullscreen mode

2. LightGBM to ONNX

# Install additional package
pip install onnxmltools

import lightgbm as lgb
import onnxmltools
from onnxmltools.convert.common.data_types import FloatTensorType

# Load LightGBM model
model = lgb.Booster(model_file='lightgbm_model.txt')

# Convert to ONNX
initial_types = [('input', FloatTensorType([None, 10]))]
onnx_model = onnxmltools.convert_lightgbm(
    model,
    initial_types=initial_types,
    target_opset=11
)

# Save model
onnxmltools.utils.save_model(onnx_model, 'lightgbm_model.onnx')
Enter fullscreen mode Exit fullscreen mode

3. XGBoost to ONNX

import xgboost as xgb
import onnxmltools
from onnxmltools.convert.common.data_types import FloatTensorType

# Load XGBoost model
model = xgb.Booster()
model.load_model('xgboost_model.json')

# Convert to ONNX
initial_types = [('input', FloatTensorType([None, 8]))]
onnx_model = onnxmltools.convert_xgboost(
    model,
    initial_types=initial_types,
    target_opset=11
)

# Save model
onnxmltools.utils.save_model(onnx_model, 'xgboost_model.onnx')
Enter fullscreen mode Exit fullscreen mode

Common Conversion Challenges

1. Input Shape Issues

Problem: "Cannot determine input shape"

Solution: Always specify the correct input dimensions in FloatTensorType

2. Opset Version Conflicts

Problem: "Unsupported opset version"

Solution: Use target_opset=11 for broad compatibility

3. Custom Preprocessors

Problem: sklearn pipelines with custom transformers

Solution: Convert preprocessing and model separately, or use supported transformers only

4. Large Model Files

Problem: Memory issues with large models

Solution: Use model quantization or chunked processing


The Easy Way: Automated Conversion

While manual conversion gives you full control, it can be time-consuming and error-prone. That's why I built ONNX Converter - a free web tool that handles the complexity for you.

Features:

  • πŸš€ Instant conversion - Upload and download in seconds
  • πŸ”§ Multiple formats - Supports scikit-learn, LightGBM, XGBoost
  • πŸ’° Free tier - 5 conversions per month, no signup required
  • πŸ”’ Secure - Files processed safely and deleted immediately
  • πŸ“± Easy to use - No coding required

How it works:

  1. Visit onnxconverter.com
  2. Select your model type
  3. Upload your model file (.pkl, .txt, .json)
  4. Download the converted ONNX file

Perfect for:

  • Quick prototyping - Test deployment compatibility
  • Learning ONNX - See what converted models look like
  • Production use - Reliable conversion for real projects
  • Team collaboration - Share converted models easily

Validating Your ONNX Model

After conversion, always validate your model:

import onnx
import onnxruntime as ort
import numpy as np

# Load and check ONNX model
onnx_model = onnx.load('model.onnx')
onnx.checker.check_model(onnx_model)

# Test inference
session = ort.InferenceSession('model.onnx')
input_name = session.get_inputs()[0].name

# Create sample input (adjust shape for your model)
sample_input = np.random.random((1, 4)).astype(np.float32)

# Run inference
result = session.run(None, {input_name: sample_input})
print("ONNX model prediction:", result)
Enter fullscreen mode Exit fullscreen mode

Deployment Examples

Web Deployment with ONNX.js

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/onnxjs/dist/onnx.min.js"></script>
</head>
<body>
    <script>
        async function runModel() {
            const session = new onnx.InferenceSession();
            await session.loadModel('./model.onnx');

            const inputTensor = new onnx.Tensor([1, 2, 3, 4], 'float32', [1, 4]);
            const outputMap = await session.run([inputTensor]);
            console.log('Prediction:', outputMap.values().next().value.data);
        }
        runModel();
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Python Inference

import onnxruntime as ort
import numpy as np

# Load model
session = ort.InferenceSession('model.onnx')

# Prepare input
input_data = np.array([[1, 2, 3, 4]], dtype=np.float32)
input_name = session.get_inputs()[0].name

# Run inference
result = session.run(None, {input_name: input_data})
print("Prediction:", result[0])
Enter fullscreen mode Exit fullscreen mode

Best Practices

1. Model Optimization

  • Use quantization for smaller file sizes
  • Remove unnecessary operations
  • Optimize for target hardware

2. Version Management

  • Tag ONNX models with version numbers
  • Document input/output schemas
  • Test across different ONNX runtime versions

3. Performance Testing

  • Benchmark against original model
  • Test on target deployment platform
  • Monitor inference latency

4. Security Considerations

  • Validate model files before deployment
  • Use secure model serving infrastructure
  • Regular security updates

Conclusion

ONNX format is becoming the standard for ML model deployment, and for good reason. It solves the "deployment hell" problem and makes your models truly portable.

Whether you choose manual conversion for full control or automated tools for speed, the key is to start experimenting with ONNX in your workflow.

Quick Start Options:


Resources


What's your experience with ONNX? Share your deployment stories in the comments below! πŸ‘‡

If you found this helpful, you might also like my other posts about ML deployment and web development.

Top comments (0)