A trained model sitting in a notebook is not production-ready. Model packaging wraps your model, its dependencies, and inference code into a self-contained artifact — a Docker image, an ONNX file, or an MLflow model directory — that can be deployed anywhere identically.
| Format | Pros | Best for |
|---|---|---|
| Docker Image | Full environment isolation | Microservice deployments |
| ONNX | Framework-agnostic, optimized runtime | Cross-platform inference |
| MLflow Model | Versioned, metadata-rich | MLflow ecosystem |
| BentoML Bundle | Built-in API server | Quick API endpoints |
| Pickle / Joblib | Simple, native Python | Prototyping only |
The same six weights packaged with two requirement files that differ in a single pin — NumPy 1.26.4 against 2.0.0 — get different artifact IDs: e93e1a2e4504 and c538e448aba7. That is the point of packaging: a model is not its weights, it is its weights plus everything they need to run, and a change to either is a new version.
- A container is only reproducible if its inputs are pinned. A base image tagged
latestor an unpinnedpip installbuilds a different artifact next month. - Converting to ONNX or another format can change numerics or drop unsupported operations; compare outputs before and after on real inputs.
- Loading a pickle runs code. Never load one from a source you do not control.
import hashlib
weights = np.arange(6, dtype=np.float32).reshape(2, 3) # the trained model, tiny here
def artifact_id(weights, requirements): # identity = model bytes + the environment it needs
h = hashlib.sha256(weights.tobytes())
h.update(requirements.encode())
return h.hexdigest()[:12]
a = artifact_id(weights, 'numpy==1.26.4\nscikit-learn==1.4.2')
b = artifact_id(weights, 'numpy==2.0.0\nscikit-learn==1.4.2') # same weights, one pin changedAssumes import numpy as np and import pandas as pd. Each snippet carries its own example numbers; the comments say which are made up or simulated.
The same idea with a library
# Python — export model as ONNX + Docker import onnx, torch # Export PyTorch model to ONNX dummy = torch.randn(1, 10) torch.onnx.export(model, dummy, "model.onnx", input_names=["features"], output_names=["prediction"]) # Dockerfile # FROM python:3.11-slim # COPY model.onnx requirements.txt serve.py . # RUN pip install -r requirements.txt # CMD ["python", "serve.py"]
- D. Sculley et al., “Hidden Technical Debt in Machine Learning Systems”, Advances in Neural Information Processing Systems 28, 2015
- M. Zaharia et al., “Accelerating the Machine Learning Lifecycle with MLflow”, IEEE Data Engineering Bulletin 41(4), 2018
- Open Neural Network Exchange (ONNX) specification, onnx.ai — the portable model format
Last reviewed October 2026 · How this site checks its content · Report a mistake