INT8 全量化需自备预处理好的 .npy 校准数据,多输入模型每个输入一个文件且顺序需与 ONNX 一致;不提供校准数据时用随机校准,精度会很低;Direct IR 后端尚不支持部分算子(如 Erf),需回退到默认 Keras 后端
onnx2tflite
MPolarisApache-2.0更新放缓把 ONNX 模型转成 Keras 或 TFLite 的转换工具,方便将 PyTorch 训练好的模型部署到移动端和嵌入式设备,还支持量化。
Tool for onnx->keras or onnx->tflite. Hope this tool can help you.
git clone https://github.com/MPolaris/onnx2tflite.git
cd onnx2tflite
python setup.py installREADME 未说明
把 ONNX 模型转成 Keras 或 TFLite 的转换工具,方便部署到移动端和嵌入式
把 ONNX 模型转成 Keras 或 TFLite 的转换工具,方便将 PyTorch 训练好的模型部署到移动端和嵌入式设备,还支持量化。
核心能力
- 支持输出 TFLite 和 Keras 两种格式
- 自动把 PyTorch 的 NCHW 布局转换为 TF 的 NHWC
- 提供 FP16、仅权重 INT8、全 INT8 三种量化
- 可用 .npy 校准数据支持多输入模型的 INT8 量化
- Direct IR 后端绕过 Keras 直接生成 TFLite,转换更快
容易踩的坑
暂无 release 数据(可能没有发版,或尚未同步)。
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
ONNX->Keras and ONNX->TFLite tools
Welcome
If you have some good ideas, welcome to discuss or give project PRs.
Install
git clone https://github.com/MPolaris/onnx2tflite.git
cd onnx2tflite
python setup.py install
from onnx2tflite import onnx_converter
res = onnx_converter(
onnx_model_path = "./model.onnx",
need_simplify = True,
output_path = "./models/",
target_formats = ['tflite'],
)
CLI Usage
# basic conversion
python -m onnx2tflite --weights "./your_model.onnx"
# save to specific path
python -m onnx2tflite --weights "./your_model.onnx" --outpath "./save_path"
# output formats
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite"
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite" "keras"
# subgraph extraction (cutoff model by layer names)
python -m onnx2tflite --weights "./your_model.onnx" --input-node-names "layer_in" --output-node-names "layer_out1" "layer_out2"
# quantization
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite" --weigthquant # weight-only int8
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite" --fp16 # fp16
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite" --int8 # int8 (random calib, low accuracy)
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite" --int8 # int8 with calibration
--calibration-data "./calib_input.npy"
# multi-input model with int8
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite" --int8
--calibration-data "./input0.npy" "./input1.npy"
# direct IR conversion (bypass Keras, faster)
python -m onnx2tflite --weights "./your_model.onnx" --formats "tflite" --direct-ir
Features
- High Consistency. Compare to ONNX outputs, average error less than 1e-5 per elements.
- More Faster. Output tensorflow-lite model 30% faster than onnx_tf.
- Auto Channel Align. Auto convert pytorch format(NCHW) to tensorflow format(NHWC).
- Deployment Support. FP16, INT8 (weight-only, full integer) quantization.
- Two Backends: Keras (stable) and Direct IR (fast, bypasses Keras).
- Multi-Input INT8: calibration data via .npy files, supports models with multiple inputs.
INT8 Calibration Data Format
INT8 quantization requires a representative dataset for calibration.
Calibration data is provided as .npy files — one file per model input.
Data format:
- Shape:
(N, ...)where N is the number of calibration samples (recommended: 50-200) - The remaining dimensions must match the model input shape
- Data should be preprocessed (normalized, resized, channel-ordered) before saving
Multi-input models: provide one .npy file per input in the same order as the ONNX model inputs.
import numpy as np
# Single-input model: shape (1, 3, 224, 224)
calib = np.random.randn(100, 3, 224, 224).astype(np.float32)
np.save("./calib_input.npy", calib)
# Multi-input model: two inputs with shapes (1, 3, 224, 224) and (1, 1000)
np.save("./calib_img.npy", np.random.randn(100, 3, 224, 224).astype(np.float32))
np.save("./calib_vec.npy", np.random.randn(100, 1000).astype(np.float32))
onnx_converter(
onnx_model_path = "./model.onnx",
int8_model = True,
calibration_data = ["./calib_img.npy", "./calib_vec.npy"],
)
Direct IR Backend
The use_direct_ir=True flag enables a new conversion path that builds TFLite
FlatBuffer models directly from the ONNX graph, bypassing Keras entirely.
- Faster conversion (no Keras model building or saving)
- More control over the generated TFLite ops
- Supports most common operators
from onnx2tflite import onnx_converter
onnx_converter("model.onnx", use_direct_ir=True)
The Keras backend (use_direct_ir=False, default) remains available for operators
not yet supported by the direct IR path (e.g. Erf).
Python API
from onnx2tflite import onnx_converter
# Basic conversion
onnx_converter("model.onnx", output_path="./out", target_formats=['tflite'])
# INT8 quantization with calibration data
onnx_converter(
"model.onnx",
int8_model=True,
calibration_data=["./calib_input.npy"],
)
# Direct IR backend (bypass Keras)
onnx_converter("model.onnx", use_direct_ir=True)
onnx_converter parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| onnx_model_path | str | required | Path to ONNX model file |
| output_path | str | None | Output directory (default: same as input) |
| input_node_names | list | None | Subgraph input names (None = all) |
| output_node_names | list | None | Subgraph output names (None = all) |
| need_simplify | bool | True | Run onnx-simplifier before conversion |
| target_formats | list | ['tflite'] | Output formats: 'tflite', 'keras' |
| use_direct_ir | bool | False | Use direct IR backend (bypass Keras) |
| native_groupconv | bool | False | Use native grouped conv (tflite >= 2.9) |
| weight_quant | bool | False | Weight-only INT8 quantization |
| fp16_model | bool | False | FP16 quantization |
| int8_model | bool | False | Full INT8 quantization |
| calibration_data | list | None | List of .npy file paths for INT8 calibration |
Validated models
- SSD
- HRNet
- YOLOX
- YOLOV3
- YOLOV4
- YOLOV5
- YOLOV6
- YOLOV7
- YOLOV10
- MoveNet
- UNet\FPN
- ViT(torchvision)
- SwinTransformerV1
- MLP(custom)
- DCGAN(custom)
- AutoEncoder/VAE
- all torchvision classification models
- some segmation models in torchvision
- 1D or 2D CNN without special operators(custom)
Add operator by yourself
When you counter unspported operator, you can choose to add it by yourself or make an issue.
Keras backend
Register a handler class in keras_backend/ops/ (e.g. activation.py):
@OPERATOR.register_operator("HardSigmoid")
class TFHardSigmoid():
def __init__(self, tensor_graph, node_weights, node_inputs,
node_attribute, node_outputs, layout_dict, *args, **kwargs):
super().__init__()
self.alpha = node_attribute.get("alpha", 0.2)
self.beta = node_attribute.get("beta", 0.5)
def __call__(self, inputs):
return tf.clip_by_value(self.alpha*inputs+self.beta, 0, 1)
TFLite direct IR backend
Add a handler function in tflite_backend/ops/:
@_register("HardSigmoid")
def _hard_sigmoid(builder, node):
inp = builder._tensor_map[node.input[0]]
...
License
This software is covered by Apache-2.0 license.