skl2onnx converts scikit-learn pipelines into ONNX graphs
Convert scikit-learn models and pipelines to ONNX
At a glance
- What is it?
- sklearn-onnx is the Apache 2.0 licensed converter that turns scikit-learn models and pipelines into the ONNX format so they can be scored with ONNX Runtime, and every converter in the project is tested against that runtime. Its boundaries are explicit, with the last supported opset at 21 and a documented path for registering converters for models that come from other libraries.
- Who is it for?
- Data science teams that train in scikit-learn and serve somewhere else, in a C++ service, a mobile runtime or an edge device, will find this the standard path to getting a model out of Python, and the fact that every converter is tested against ONNX Runtime is what makes the output trustworthy rather than merely plausible.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The point is scoring the same model outside Python
sklearn-onnx converts scikit-learn models to ONNX, and once a model is in the ONNX format you can use tools like ONNX Runtime for high performance scoring. That is the whole pitch, and it is aimed at a specific situation: the model was trained in Python, and the thing that needs to run it is not Python. A C++ service, a Java application, an edge device or a web assembly runtime can all consume ONNX, and the model that was fitted with a scikit-learn pipeline becomes a graph of operators rather than a pickled estimator. The repository is the Python package `skl2onnx`, published on PyPI under the older name `skl2onnx`, with the source under the `skl2onnx/` directory, the tests in `tests/`, a separate `tests_onnxmltools/` directory for the external converter tests, a `benchmarks/` directory and a `docs/` tree. The runtime requirements are modest, with onnx 1.2.1 or later and scikit-learn 1.1 or later, and the package supports Python 3.8 through 3.13.
to_onnx needs a sample of the input data
The conversion call takes the fitted estimator and a sample of the input, and the documentation's example is short enough to work through. The model is trained first, the data is cast to float32, and the estimator is converted with `to_onnx`, after which the graph is serialised to a file and loaded into an ONNX Runtime session:
from skl2onnx import to_onnx
onx = to_onnx(clr, X[:1])
with open("rf_iris.onnx", "wb") as f:
f.write(onx.SerializeToString())
import onnxruntime as rt
sess = rt.InferenceSession("rf_iris.onnx", providers=["CPUExecutionProvider"])
input_name = sess.get_inputs()[0].name
label_name = sess.get_outputs()[0].name
pred_onx = sess.run([label_name], {input_name: X_test.astype(np.float32)})[0]The sample argument, here `X[:1]`, is what tells the converter about the input types and shapes, which is why the data is cast to float32 before the split. A single row is enough, because the converter needs the schema rather than the volume. The rest of the example is the part worth copying: names of inputs and outputs are read from the session rather than hard coded, and the runtime session is created with an explicit provider list, so the same file can later be served on a different execution provider.
Converters are tested against ONNX Runtime
The verification story is what separates this from a format translator that merely emits plausible looking graphs. The documentation states that all converters are tested with onnxruntime, which means the test suite for each estimator trains a model, converts it, runs it through the runtime and compares the results against the scikit-learn output. That is a much stronger claim than producing a file that loads, because a graph can be structurally valid and still compute the wrong thing. The runtime itself is not a dependency of the package, which is worth noting, since the requirements are only onnx and scikit-learn. The full documentation, including tutorials, is published at onnx.ai/sklearn-onnx, and there is a separate supported models page listing which scikit-learn estimators are covered, which is the page to consult before promising a pipeline will convert.
External models are handled by registering a converter
Real pipelines rarely contain only scikit-learn estimators. The answer the project gives is a registration mechanism: any external converter can be registered to convert a scikit-learn pipeline that includes models or transformers coming from external libraries. The `tests_onnxmltools/` directory in the repository is where those external converters are exercised, which tells you the extension point is meant to be used rather than merely possible. The practical sequence for a team is therefore: check the supported models list, and when an estimator is missing, either write a converter and register it or replace that step. That is more work than clicking export, but it is the difference between a model that runs correctly in the runtime and one that quietly returns different answers, which is why the runtime-based test coverage matters more here than in a typical wrapper library.
Opset 21 is the current ceiling
The documentation gives a single number for the version boundary: the last supported opset is 21. Opsets are the versioning mechanism of the ONNX format itself, and they are what determines whether a runtime in the field can execute the graph you produced. A converter that emits operators from a newer opset than the runtime supports will fail to load, so the number is a hard ceiling on what you can ship rather than a footnote. It also means the ONNX runtime and the scikit-learn version you train with are both part of the compatibility surface, and the package's own version line moves with them. The documentation points at existing issues and invites a new one for questions, which is the right place to look for known gaps before you convert a large model.
Install from PyPI, or from a git checkout
Two install paths are documented, and the choice is between stability and freshness:
pip install skl2onnxpip install git+https://github.com/onnx/sklearn-onnx.gitThe second form installs from the source with the latest changes, which is what you want when a specific estimator has just gained a converter upstream. The package is built with setuptools, and the project metadata takes the version from the `__version__` attribute of the `skl2onnx` package rather than hard coding it, and it takes its dependencies from the requirements file. The licence is Apache 2.0, and the repository carries both a `LICENSE` file and a `NOTICE`, which is the combination an organisation's legal review will expect when the code ends up inside a commercial product.
Style is enforced before a pull request lands
The contribution rules are short and specific. The project welcomes feedback, ideas and code, and the pull request instructions ask that two commands are run first to fix style issues:
black .
ruff check .Black is the formatter and Ruff is the linter, and the Ruff configuration in the project metadata is explicit about the rule set, selecting the bugbear, comprehensions, pycodestyle, Pyflakes, logging format, implicit concat, logging, PIE, flake8-pyi, Ruff-specific, simplify and slot rules while leaving several families commented out, including pydocstyle, isort, pep8-naming and Perflint. The line length is set to 93, which is slightly wider than the default and matches the wider lines this codebase uses for converter definitions. The release history shows a 1.19 line in May 2025 and 1.20.0 in January 2026, and the last push to the repository was on 2026-10-13 with the repository not archived, so the project is still receiving work, and the changelogs in `CHANGELOGS.md` are where to check what a given version changed.
Editorial conclusion
Data science teams that train in scikit-learn and serve somewhere else, in a C++ service, a mobile runtime or an edge device, will find this the standard path to getting a model out of Python, and the fact that every converter is tested against ONNX Runtime is what makes the output trustworthy rather than merely plausible. It is the wrong tool if your model contains an estimator that has no converter, since the fix there is to write and register one rather than to expect the tool to guess, and it is the wrong tool if you need features newer than opset 21. Before you commit to it, convert one real pipeline, compare its predictions with the scikit-learn original on your own data, and check the supported models page for the estimators you actually use.
Frequently asked questions
How do I convert a scikit-learn model to ONNX?
Fit the model, then call `to_onnx(model, sample_data)` and write the result with `SerializeToString`. The sample data tells the converter the input types and shapes, and the resulting file can be loaded into an ONNX Runtime session for scoring.
Which scikit-learn estimators can be converted?
The project publishes a supported models page listing the covered estimators, and the documentation says all converters are tested with onnxruntime. External models and transformers can also be handled by registering an external converter for the pipeline.
What ONNX opset does skl2onnx support?
The documentation states that the last supported opset is 21, which sets the ceiling on the operators the converter will emit and therefore on which runtimes can execute the resulting graph.
How do I install skl2onnx?
Install the released package from PyPI with `pip install skl2onnx`, or install the latest source with `pip install git+https://github.com/onnx/sklearn-onnx.git`. The package requires onnx 1.2.1 or later and scikit-learn 1.1 or later, and supports Python 3.8 through 3.13.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/onnx-sklearn-onnx)Was this useful?