tf2onnx: converting TensorFlow, Keras, TFLite and TF.js models to ONNX
Convert TensorFlow, Keras, Tensorflow.js and Tflite models to ONNX
At a glance
- What is it?
- tf2onnx is the ONNX project's converter for TensorFlow-family models. It handles SavedModel, checkpoint, GraphDef, TFLite and experimental TF.js input, but the README asks for a new maintainer and TensorFlow has more ops than ONNX can express.
- Who is it for?
- Adopt tf2onnx if you have a TensorFlow-family model in SavedModel, checkpoint, GraphDef or TFLite form and you need an ONNX artifact for a runtime that is not TensorFlow. Do not adopt it if you are starting from PyTorch, since torch.onnx is the shorter path, or if your graph leans on ops that the support_status.md table does not list.
- 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 2 days ago.
- What is it written in?
- Mainly Jupyter Notebook, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What tf2onnx is for, and who actually needs it
A TensorFlow model is not portable by default. SavedModel, checkpoint and GraphDef are TensorFlow's own formats, and TFLite is a separate runtime format again. If the target device or service runs ONNX Runtime, TensorRT, OpenVINO or another ONNX-consuming stack, something has to translate the graph first. tf2onnx is that translator, published under the onnx organisation rather than by an individual.
The audience is narrow but real. You have a trained model in one of the TensorFlow formats, you cannot or do not want to retrain it in another framework, and the deployment target does not speak TensorFlow. The README covers SavedModel, checkpoint, GraphDef, TFLite and tensorflow.js input, so the converter is aimed at people who already have weights on disk rather than at people choosing a training framework. If you are training in PyTorch, this is the wrong tool entirely.
How the conversion works: graph rewriting, not execution
The converter reads the TensorFlow graph and rewrites it into ONNX operators. It does not run your model to produce the output. That distinction matters when a conversion fails: the error is usually a missing operator mapping, not a numerical problem.
The README is direct about the core constraint. TensorFlow has many more ops than ONNX, and occasionally mapping a model to ONNX creates issues. The repository ships support_status.md as the list of supported TensorFlow ops and their ONNX mapping, and Troubleshooting.md collects the common failures. Those two files are the real specification of what will convert and what will not.
For SavedModel input, inputs and outputs do not need to be specified, because the converter reads them from the signatures. For checkpoint and GraphDef input they do, which is why the CLI takes --inputs and --outputs in the form input0:0,input1:0. When a placeholder has unknown rank or dims that cannot be mapped to ONNX, the README says you can append a shape in brackets after the input name, such as X:0[1,28,28,3], using -1 for an unknown dimension. The README also recommends getting a SavedModel from your model provider instead of working from checkpoint or GraphDef, since that avoids the input-naming step altogether.
Installing tf2onnx and converting a SavedModel
Install TensorFlow first if it is not already present, then install the converter from PyPI. The README gives both commands.
pip install tensorflow
pip install -U tf2onnxThe package requires Python 3.10 to 3.12, and the pyproject.toml declares numpy>=1.23.5, onnx>=1.14.0, requests and flatbuffers>=1.12 as dependencies. tf2onnx uses whatever ONNX version is on your system and installs the latest if none is found.
A SavedModel conversion is a single command. Point --saved-model at the directory and --output at the target file.
python -m tf2onnx.convert --saved-model tensorflow-model-path --output model.onnxThe default output opset is 15. To pin a different one, pass --opset explicitly, as in the README's opset 18 example.
python -m tf2onnx.convert --saved-model tensorflow-model-path --opset 18 --output model.onnxFor TFLite the flag changes and inputs and outputs are not needed. The README uses opset 16 in this example.
python -m tf2onnx.convert --opset 16 --tflite tflite-file --output model.onnxIf you want to check the result, install a runtime and load the file. The README suggests onnxruntime for that purpose.
pip install onnxruntimeA successful run leaves an ONNX file at the path you gave. The README does not document a rollback procedure, so keep the original TensorFlow artifacts until you have validated the converted graph yourself.
The opset choice is yours to get wrong
tf2onnx supports and tests ONNX opset 14 through 18. Opsets 6 through 13 are described as likely to work but untested, and the default is 15. That default is a compromise, not a recommendation for your deployment.
The opset you pick constrains the runtime you can use. A newer opset may carry operators an older ONNX Runtime build does not implement; an older opset may lack the operator a particular TensorFlow op maps onto. The README points at the ONNX operator documentation when you are unsure, which is the honest answer, because the right value depends on the consumer rather than on the converter. If your serving stack pins an ONNX Runtime version, pick the opset that version supports and pass it with --opset rather than accepting 15.
The CLI also exposes --dequantize, --target, --custom-ops, --extra_opset, --large_model and --continue_on_error. The README lists these flags without explaining each one in the parameter section, so their exact behaviour has to be read from the source or the troubleshooting guide.
Where conversion breaks, and the maintainer question
Two limitations sit at the top of the README rather than buried in a footnote. First, tensorflow.js support is experimental: the project states it tested many tfjs models from tfhub but not all models may convert correctly. Treat --tfjs as a best-effort path, not a supported one.
Second, the operator gap. TensorFlow's op set is larger than ONNX's, so any model using an op without a mapping will fail or need a custom op registered through --custom-ops. The repository carries examples/tf_custom_op/ for that case. Before converting a model you care about, check its ops against support_status.md; that is faster than converting and reading the error.
The maintenance signal is the part a procurement or platform team should weigh. The README carries a Maintainer Wanted notice asking for someone to help support and evolve tf2onnx, with interested parties directed to open an issue or comment on the thread. The repository is not archived and the last push was on 2026-09-02, so work is happening, but the project is publicly asking for a new maintainer. A converter that sits on the critical path between training and deployment deserves a plan for that.
tf2onnx versus torch.onnx and versus staying in TensorFlow
The obvious alternative is not a different converter but a different starting point. If your model is in PyTorch, torch.onnx exports it directly and tf2onnx has nothing to do. The two tools occupy the same slot in the pipeline, an export step to ONNX, but they are bound to different source frameworks, so the choice is made by where your weights live, not by feature comparison.
The second alternative is not converting at all. If your serving stack runs TensorFlow or TFLite natively, adding an ONNX hop introduces a second runtime, a second set of operator semantics to validate, and a conversion step that can fail on an unmapped op. The conversion earns its place when the target runtime is ONNX-only, or when you are consolidating several framework-specific models behind one runtime. If you are consolidating, note that tf2onnx is only half of that story: PyTorch models come through torch.onnx, and the two paths produce graphs that still need to be validated against the same runtime version.
Editorial conclusion
Adopt tf2onnx if you have a TensorFlow-family model in SavedModel, checkpoint, GraphDef or TFLite form and you need an ONNX artifact for a runtime that is not TensorFlow. Do not adopt it if you are starting from PyTorch, since torch.onnx is the shorter path, or if your graph leans on ops that the support_status.md table does not list. Before committing, convert your own model with --opset 18, check the ops that the converter reports as unsupported, and read the Maintainer Wanted note at the top of the README, because the project is openly asking for someone to take over support.
Frequently asked questions
What is the purpose of ONNX?
ONNX is the interchange format tf2onnx targets, and the README's framing is that TensorFlow has many more ops than ONNX, so conversion is a mapping exercise between two operator sets. The practical purpose in this project is to let a TensorFlow-family model run on an ONNX-consuming runtime instead of TensorFlow.
Which is faster, ONNX or TorchScript?
The README does not compare ONNX and TorchScript performance. It only states which ONNX opsets tf2onnx supports and tests, and the repository includes examples/benchmark_tfmodel_ort.py for benchmarking a converted TensorFlow model under ONNX Runtime, which is where a speed comparison would have to be measured.
How do I convert a Keras model to ONNX with tf2onnx?
The README's getting-started path is the SavedModel route, since a Keras model saved in SavedModel format converts with --saved-model and needs no input or output names. The repository also ships examples/end2end_tfkeras.py, which the README does not describe in the text.
Does tf2onnx support TFLite models?
Yes. The README shows converting a .tflite file with --tflite, and notes that inputs and outputs do not need to be specified for that format. The example uses --opset 16.
What Python and TensorFlow versions does tf2onnx require?
Python 3.10 to 3.12, and TensorFlow 2.x, with the test matrix running on tf-2.13 or better. The build table lists TensorFlow 2.13 to 2.15 against ONNX opset 14 to 18.
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-tensorflow-onnx)