Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
837506d
Add LiteRT (TFLite) export support to Keras
pctablet505 Aug 28, 2025
631850e
Update lite_rt_exporter.py
pctablet505 Aug 28, 2025
f5aa72e
Update export_utils.py
pctablet505 Aug 28, 2025
2b952d6
Refactor LiteRTExporter to simplify TFLite conversion
pctablet505 Aug 28, 2025
8f81dd5
Refactor import structure to avoid circular dependencies
pctablet505 Aug 28, 2025
011f1d8
trying kerashub
pctablet505 Aug 28, 2025
9a99a32
Enhance LiteRT export for sequence models and large models
pctablet505 Aug 28, 2025
d0070c6
Update lite_rt_exporter.py
pctablet505 Aug 28, 2025
761793f
Update lite_rt_exporter.py
pctablet505 Aug 28, 2025
7bb0506
Prevent tensor overflow for large vocabulary models
pctablet505 Sep 1, 2025
c219eb1
Update export_utils.py
pctablet505 Sep 1, 2025
e26ff6b
Update lite_rt_exporter.py
pctablet505 Sep 1, 2025
4a32e04
Simplify TFLite export and sequence length safety checks
pctablet505 Sep 1, 2025
3aca2f6
Merge branch 'keras-team:master' into export
pctablet505 Sep 2, 2025
926b0a8
Refactor TFLite export logic and add simple exporter
pctablet505 Sep 2, 2025
441a778
Merge branch 'export' of https://github.com/pctablet505/keras into ex…
pctablet505 Sep 2, 2025
4a8a9d5
Improve export robustness for large vocab and Keras-Hub models
pctablet505 Sep 2, 2025
f4b43b4
Update lite_rt_exporter.py
pctablet505 Sep 2, 2025
0fe4bd5
Update lite_rt_exporter.py
pctablet505 Sep 2, 2025
8c3faa3
Update lite_rt_exporter.py
pctablet505 Sep 2, 2025
88b6a6f
Update lite_rt_exporter.py
pctablet505 Sep 2, 2025
da13d04
Update lite_rt_exporter.py
pctablet505 Sep 3, 2025
f1f700c
Update lite_rt_exporter.py
pctablet505 Sep 8, 2025
5944780
Update lite_rt_exporter.py
pctablet505 Sep 9, 2025
4404c39
Update lite_rt_exporter.py
pctablet505 Sep 9, 2025
6a119fb
Update lite_rt_exporter.py
pctablet505 Sep 15, 2025
4cec7cd
Merge branch 'keras-team:master' into export
pctablet505 Sep 16, 2025
3a7fcc4
Merge branch 'keras-team:master' into export
pctablet505 Sep 17, 2025
51a1c7f
Remove sequence length bounding from export utils
pctablet505 Sep 17, 2025
e1fca24
Delete test_keras_hub_export.py
pctablet505 Sep 17, 2025
214558a
Merge branch 'keras-team:master' into export
pctablet505 Sep 22, 2025
73f00f1
Rename LiteRT exporter to Litert and update references
pctablet505 Sep 29, 2025
ebf11e2
Enhance LiteRT exporter and expand export tests
pctablet505 Sep 29, 2025
c6f0c70
Refactor LiteRT exporter to use module_utils.litert
pctablet505 Sep 30, 2025
3c1d90a
Simplify export_litert return value and messaging
pctablet505 Oct 1, 2025
657a271
Merge branch 'keras-team:master' into export
pctablet505 Oct 1, 2025
8ce8bfa
Merge branch 'export' of https://github.com/pctablet505/keras into ex…
pctablet505 Oct 1, 2025
cd9d063
Update export_utils.py
pctablet505 Oct 1, 2025
fa3d3ed
Refactor input signature inference for export
pctablet505 Oct 3, 2025
e775ff2
simplified code
pctablet505 Oct 3, 2025
34b662d
Refactor LiteRT exporter and update import paths
pctablet505 Oct 6, 2025
33b0550
Merge branch 'keras-team:master' into export
pctablet505 Oct 6, 2025
cbe0229
Refactor import statements for export_utils functions
pctablet505 Oct 6, 2025
e52de85
Update saved_model.py
pctablet505 Oct 6, 2025
87af9ed
Update litert.py
pctablet505 Oct 6, 2025
c643772
Add conditional TensorFlow import for LiteRT export
pctablet505 Oct 6, 2025
f243a6e
reformat
pctablet505 Oct 6, 2025
d8236fa
Update litert_test.py
pctablet505 Oct 6, 2025
83577be
Update litert_test.py
pctablet505 Oct 6, 2025
c53b264
Update litert_test.py
pctablet505 Oct 6, 2025
487184d
Update litert_test.py
pctablet505 Oct 7, 2025
374d90b
Update requirements-tensorflow-cuda.txt
pctablet505 Oct 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions keras/src/export/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@
from keras.src.export.saved_model import ExportArchive
from keras.src.export.saved_model import export_saved_model
from keras.src.export.tfsm_layer import TFSMLayer

# LiteRT export requires TensorFlow, so we import conditionally
try:
from keras.src.export.litert import LitertExporter
from keras.src.export.litert import export_litert
except ImportError:
# TensorFlow not available, LiteRT export will not be available
LitertExporter = None
export_litert = None
38 changes: 32 additions & 6 deletions keras/src/export/export_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@


def get_input_signature(model):
"""Get input signature for model export.

Args:
model: A Keras Model instance.

Returns:
Input signature suitable for model export (always a tuple or list).
"""
if not isinstance(model, models.Model):
raise TypeError(
"The model must be a `keras.Model`. "
Expand All @@ -17,18 +25,25 @@ def get_input_signature(model):
"The model provided has not yet been built. It must be built "
"before export."
)

if isinstance(model, models.Functional):
# Functional models expect a single positional argument `inputs`
# containing the full nested input structure. We keep the
# original behavior of returning a single-element list that
# wraps the mapped structure so that downstream exporters
# build a tf.function with one positional argument.
input_signature = [
tree.map_structure(make_input_spec, model._inputs_struct)
]
elif isinstance(model, models.Sequential):
input_signature = tree.map_structure(make_input_spec, model.inputs)
else:
# Subclassed models: rely on recorded shapes from the first call.
input_signature = _infer_input_signature_from_model(model)
if not input_signature or not model._called:
raise ValueError(
"The model provided has never called. "
"It must be called at least once before export."
"The model provided has never called. It must be called "
"at least once before export."
)
return input_signature

Expand All @@ -41,25 +56,36 @@ def _infer_input_signature_from_model(model):
def _make_input_spec(structure):
# We need to turn wrapper structures like TrackingDict or _DictWrapper
# into plain Python structures because they don't work with jax2tf/JAX.
if structure is None:
return None
if isinstance(structure, dict):
return {k: _make_input_spec(v) for k, v in structure.items()}
elif isinstance(structure, tuple):
if all(isinstance(d, (int, type(None))) for d in structure):
return layers.InputSpec(
shape=(None,) + structure[1:], dtype=model.input_dtype
# For export, force batch dimension to None for flexible
# batching
shape = (
(None,) + structure[1:] if len(structure) > 0 else structure
)
return layers.InputSpec(shape=shape, dtype=model.input_dtype)
return tuple(_make_input_spec(v) for v in structure)
elif isinstance(structure, list):
if all(isinstance(d, (int, type(None))) for d in structure):
return layers.InputSpec(
shape=[None] + structure[1:], dtype=model.input_dtype
# For export, force batch dimension to None for flexible
# batching
shape = (
(None,) + tuple(structure[1:])
if len(structure) > 0
else tuple(structure)
)
return layers.InputSpec(shape=shape, dtype=model.input_dtype)
return [_make_input_spec(v) for v in structure]
else:
raise ValueError(
f"Unsupported type {type(structure)} for {structure}"
)

# Always return a flat list preserving the order of shapes_dict values
return [_make_input_spec(value) for value in shapes_dict.values()]


Expand Down
Loading