Skip to content

feat(export): add TFLite export support with FP32/FP16/INT8#920

Open
mfazrinizar wants to merge 3 commits intoroboflow:developfrom
mfazrinizar:feat/tflite-export
Open

feat(export): add TFLite export support with FP32/FP16/INT8#920
mfazrinizar wants to merge 3 commits intoroboflow:developfrom
mfazrinizar:feat/tflite-export

Conversation

@mfazrinizar
Copy link
Copy Markdown

What does this PR do?

Adds an ONNX → TFLite conversion pipeline for RF-DETR detection and segmentation models via onnx2tf.

Users can now export any RF-DETR model to TFLite format with a single call:

from rfdetr import RFDETRNano

model = RFDETRNano()

# FP32 (recommended — also produces FP16 automatically)
model.export(format="tflite")

# INT8 with calibration images
model.export(format="tflite", quantization="int8", calibration_data="path/to/images/")

Key changes

New module: src/rfdetr/export/_tflite/

  • converter.py: Core export_tflite() function — converts ONNX to TFLite via onnx2tf Python API
  • Supports quantization="int8" with calibration from an image directory, .npy file, or NumPy array
  • max_images parameter controls calibration sample count (default: 100)
  • Applies output_signaturedefs=True fix for segmentation models (onnx2tf node naming issue with leading / characters violating TF saved_model naming pattern)
  • Monkey-patches onnx2tf's download_test_image_data() to use local calibration data instead of downloading from GitHub (which fails in CI, firewalls, air-gapped systems)
  • NumPy allow_pickle compatibility shim for onnx2tf 1.x releases

Modified files

  • src/rfdetr/detr.py: Added format="tflite" routing in export() with quantization, calibration_data, max_images, output_dir parameters
  • src/rfdetr/export/main.py / __init__.py: Wired up export_tflite import
  • pyproject.toml: Added onnx2tf>=1.26.0 and tf-keras>=2.16.0 to [onnx] optional dependencies
  • docs/learn/export.md: TFLite usage guide, calibration explanation, parameter reference, FP32/FP16 always-produced behavior note

Related Issue(s): Related to #173 and this PR

Type of Change

  • New feature (non-breaking change that adds functionality)

Testing

  • I have tested this change locally
  • I have added/updated tests for this change

Test details:

56 unit tests in tests/export/test_tflite_export.py (all CPU, no GPU required):

  • Format routing: export(format="tflite") correctly dispatches to export_tflite
  • Quantization options: Validates None, "fp32", "fp16", "int8" modes; rejects invalid values
  • Calibration data preparation: Tests random noise generation, .npy file loading, NumPy array input, and directory-based image loading with resize
  • max_images parameter forwarding: Verifies max_images flows through detr.pyexport_tflite()_prepare_calibration_data()_load_calibration_images()
  • Error handling: Missing ONNX file, missing calibration directory, empty image directory
  • INT8 warning: Emits warning when no calibration data provided for INT8

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code where necessary, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors
  • I have updated the documentation accordingly (if applicable)

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 3, 2026

CLA assistant check
All committers have signed the CLA.

- Use getattr/setattr for dynamic module attribute access instead of
  direct attribute assignment (attr-defined)
- Add unused-ignore to type: ignore comments for numpy.load
  monkey-patch to handle both mypy versions (unused-ignore)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants