Releases: keras-team/keras
v3.13.0
BREAKING changes
Starting with version 3.13.0, Keras now requires Python 3.11 or higher. Please ensure your environment is updated to Python 3.11+ to install the latest version.
Highlights
LiteRT Export
You can now export Keras models directly to the LiteRT format (formerly TensorFlow Lite) for on-device inference.
This changes comes with improvements to input signature handling and export utility documentation. The changes ensure that LiteRT export is only available when TensorFlow is installed, update the export API and documentation, and enhance input signature inference for various model types.
Example:
import keras
import numpy as np
# 1. Define a simple model
model = keras.Sequential([
keras.layers.Input(shape=(10,)),
keras.layers.Dense(10, activation="relu"),
keras.layers.Dense(1, activation="sigmoid")
])
# 2. Compile and train (optional, but recommended before export)
model.compile(optimizer="adam", loss="binary_crossentropy")
model.fit(np.random.rand(100, 10), np.random.randint(0, 2, 100), epochs=1)
# 3. Export the model to LiteRT format
model.export("my_model.tflite", format="litert")
print("Model exported successfully to 'my_model.tflite' using LiteRT format.")GPTQ Quantization
-
Introduced
keras.quantizers.QuantizationConfigAPI that allows for customizable weight and activation quantizers, providing greater flexibility in defining quantization schemes. -
Introduced a new
filtersargument to theModel.quantizemethod, allowing users to specify which layers should be quantized using regex strings, lists of regex strings, or a callable function. This provides fine-grained control over the quantization process. -
Refactored the GPTQ quantization process to remove heuristic-based model structure detection. Instead, the model's quantization structure can now be explicitly provided via
GPTQConfigor by overriding a newModel.get_quantization_layer_structuremethod, enhancing flexibility and robustness for diverse model architectures. -
Core layers such as
Dense,EinsumDense,Embedding, andReversibleEmbeddinghave been updated to accept and utilize the newQuantizationConfigobject, enabling fine-grained control over their quantization behavior. -
Added a new method
get_quantization_layer_structureto the Model class, intended for model authors to define the topology required for structure-aware quantization modes like GPTQ. -
Introduced a new utility function
should_quantize_layerto centralize the logic for determining if a layer should be quantized based on the provided filters. -
Enabled the serialization and deserialization of
QuantizationConfigobjects within Keras layers, allowing quantized models to be saved and loaded correctly. -
Modified the
AbsMaxQuantizerto allow specifying the quantization axis dynamically during the__call__method, rather than strictly defining it at initialization.
Example:
- Default Quantization (Int8)
Applies the defaultAbsMaxQuantizerto both weights and activations.
model.quantize("int8")- Weight-Only Quantization (Int8)
Disable activation quantization by setting the activation quantizer toNone.
from keras.quantizers import Int8QuantizationConfig, AbsMaxQuantizer
config = Int8QuantizationConfig(
weight_quantizer=AbsMaxQuantizer(axis=0),
activation_quantizer=None
)
model.quantize(config=config)- Custom Quantization Parameters
Customize the value range or other parameters for specific quantizers.
config = Int8QuantizationConfig(
# Restrict range for symmetric quantization
weight_quantizer=AbsMaxQuantizer(axis=0, value_range=(-127, 127)),
activation_quantizer=AbsMaxQuantizer(axis=-1, value_range=(-127, 127))
)
model.quantize(config=config)Adaptive Pooling layers
Added adaptive pooling operations keras.ops.nn.adaptive_average_pool and keras.ops.nn.adaptive_max_pool for 1D, 2D, and 3D inputs. These operations transform inputs of varying spatial dimensions into a fixed target shape defined by output_size by dynamically inferring the required kernel size and stride. Added corresponding layers:
keras.layers.AdaptiveAveragePooling1Dkeras.layers.AdaptiveAveragePooling2Dkeras.layers.AdaptiveAveragePooling3Dkeras.layers.AdaptiveMaxPooling1Dkeras.layers.AdaptiveMaxPooling2Dkeras.layers.AdaptiveMaxPooling3D
New features
- Add
keras.ops.numpy.array_splitop a fundamental building block for tensor parallelism. - Add
keras.ops.numpy.empty_likeop. - Add
keras.ops.numpy.ldexpop. - Add
keras.ops.numpy.vanderop which constructs a Vandermonde matrix from a 1-D input tensor. - Add
keras.distribution.get_device_countutility function for distribution API. keras.layers.JaxLayerandkeras.layers.FlaxLayernow support the TensorFlow backend in addition to the JAX backed. This allows you to embedflax.linen.Moduleinstances or JAX functions in your model. The TensorFlow support is based onjax2tf.
OpenVINO Backend Support:
- Added
numpy.digitizesupport. - Added
numpy.diagsupport. - Added
numpy.isinsupport. - Added
numpy.vdotsupport. - Added
numpy.floor_dividesupport. - Added
numpy.rollsupport. - Added
numpy.multi_hotsupport. - Added
numpy.psnrsupport. - Added
numpy.empty_likesupport.
Bug fixes and Improvements
- NNX Support: Improved compatibility and fixed tests for the NNX library (JAX), ensuring better stability for NNX-based Keras models.
- MultiHeadAttention: Fixed negative index handling in
attention_axesforMultiHeadAttentionlayers. - Softmax: The update on
Softmaxmask handling, aimed at improving numerical robustness, was based on a deep investigation led by Jaswanth Sreeram, who prototyped the solution with contributions from others. - PyDataset Support: The
Normalizationlayer'sadaptmethod now supportsPyDatasetobjects, allowing for proper adaptation when using this data type.
TPU Test setup
Configured the TPU testing infrastructure to enforce unit test coverage across the entire codebase. This ensures that both existing logic and all future contributions are validated for functionality and correctness within the TPU environment.
New Contributors
- @mattjj made their first contribution in #21776
- @GaetanLepage made their first contribution in #21790
- @MalyalaKarthik66 made their first contribution in #21733
- @Mithil27360 made their first contribution in #21816
- @erahulkulkarni made their first contribution in #21812
- @yashwantbezawada made their first contribution in #21827
- @Abhinavexists made their first contribution in #21819
- @khanhkhanhlele made their first contribution in #21830
- @kharshith-k made their first contribution in #21425
- @SamareshSingh made their first contribution in #21834
- @yangliyl-g made their first contribution in #21850
- @ssam18 made their first contribution in #21855
- @kathyfan made their first contribution in #21805
- @almilosz made their first contribution in #21826
- @RohitYandigeri made their first contribution in #21902
Full Changelog: v3.12.0...v3.13.0
Keras 3.12.0
Highlights
Keras has a new model distillation API!
You now have access to an easy-to-use API for distilling large models into small models while minimizing performance drop on a reference dataset -- compatible with all existing Keras models. You can specify a range of different distillation losses, or create your own losses. The API supports multiple concurrent distillation losses at the same time.
Example:
# Load a model to distill
teacher = ...
# This is the model we want to distill it into
student = ...
# Configure the process
distiller = Distiller(
teacher=teacher,
student=student,
distillation_losses=LogitsDistillation(temperature=3.0),
)
distiller.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Train the distilled model
distiller.fit(x_train, y_train, epochs=10)Keras supports GPTQ quantization!
GPTQ is now built into the Keras API. GPTQ is a post-training, weights-only quantization method that compresses a model to int4 layer by layer. For each layer, it uses a second-order method to update weights while minimizing the error on a calibration dataset.
Learn how to use it in this guide.
Example:
model = keras_hub.models.Gemma3CausalLM.from_preset("gemma3_1b")
gptq_config = keras.quantizers.GPTQConfig(
dataset=calibration_dataset,
tokenizer=model.preprocessor.tokenizer,
weight_bits=4,
group_size=128,
num_samples=256,
sequence_length=256,
hessian_damping=0.01,
symmetric=False,
activation_order=False,
)
model.quantize("gptq", config=gptq_config)
outputs = model.generate(prompt, max_length=30)Better support for Grain datasets!
- Add Grain support to
keras.utils.image_dataset_from_directoryandkeras.utils.text_dataset_from_directory. Specifyformat="grain"to return a Grain dataset instead of a TF dataset. - Make almost all Keras preprocessing layers compatible with Grain datasets.
New features
- Add
keras.layers.ReversibleEmbeddinglayer: an embedding layer that can also also project backwards to the input space. Use it with thereverseargument incall(). - Add argument
opset_versioninmodel.export(). Argument specific toformat="onnx"; specifies the ONNX opset version. - Add
keras.ops.isinop. - Add
keras.ops.isneginf,keras.ops.isposinfops. - Add
keras.ops.isrealop. - Add
keras.ops.cholesky_inverseop and addupperargument inkeras.ops.cholesky. - Add
keras.ops.image.scale_and_translateop. - Add
keras.ops.hypotop. - Add
keras.ops.gcdop. - Add
keras.ops.kronop. - Add
keras.ops.logaddexp2op. - Add
keras.ops.viewop. - Add
keras.ops.unfoldop. - Add
keras.ops.jvpop. - Add
keras.ops.trapezoidop. - Add support for over 20 news ops with the OpenVINO backend.
Breaking changes
- Layers
StringLookup&IntegerLookupnow save vocabulary loaded from file. Previously, when instantiating these layers from a vocabulary filepath, only the filepath would be saved when saving the layer. Now, the entire vocabulary is materialized and saved as part of the.kerasarchive.
Security fixes
- Fix two vulnerabilities related to adversarial saved files loaded with
safe_mode: CVE-2025-12058 and CVE-2025-12060.
New Contributors
- @WIgor made their first contribution in #21432
- @ILCSFNO made their first contribution in #21563
- @samthakur587 made their first contribution in #21524
- @buildwithsuhana made their first contribution in #21554
- @MCCbena made their first contribution in #21569
- @amitsrivastava78 made their first contribution in #21551
- @Ma-gi-cian made their first contribution in #21614
- @arunthakur009 made their first contribution in #21600
- @vpratz made their first contribution in #21615
- @miguelteixeiragomes made their first contribution in #21650
- @Flakes342 made their first contribution in #21646
- @TRNWWZ made their first contribution in #21671
- @danielenricocahall made their first contribution in #21738
- @utsab345 made their first contribution in #21721
- @wenyi-guo made their first contribution in #21763
- @SamKnightGit made their first contribution in #21782
Full Changelog: v3.11.0...v3.12.0
Keras 3.11.3
Keras 3.11.2
What's Changed
- Version bump 3.11.2 and nnx fix #21565 by @laxmareddyp in #21570
New Contributors
- @laxmareddyp made their first contribution in #21570
Full Changelog: v3.11.1...v3.11.2
Keras 3.11.1
Keras 3.11.0
What's Changed
- Add int4 quantization support.
- Support Grain data loaders in
fit()/evaluate()/predict(). - Add
keras.ops.kaiserfunction. - Add
keras.ops.hanningfunction. - Add
keras.ops.cbrtfunction. - Add
keras.ops.deg2radfunction. - Add
keras.ops.layer_normalizationfunction to leverage backend-specific performance optimizations. - Various bug fixes and performance optimizations.
Backend-specific changes
JAX backend
- Support NNX library. It is now possible to use Keras layers and models as NNX modules.
- Support shape -1 for slice op.
TensorFlow backend
- Add support for multiple dynamic dimensions in
Flattenlayer.
OpenVINO backend
- Add support for over 30 new backend ops.
New Contributors
- @adar21a made their first contribution in #21275
- @Phil2852 made their first contribution in #21304
- @dayo09 made their first contribution in #21340
- @iazzi made their first contribution in #21370
- @timovdk made their first contribution in #21385
- @mohiuddin-khan-shiam made their first contribution in #21392
- @p-wysocki made their first contribution in #21317
- @Gayathri-K-Binoy made their first contribution in #21493
Full Changelog: v3.10.0...v3.11.0
Keras 3.10.0
New features
- Add support for weight sharding for saving very large models with
model.save(). It is controlled via themax_shard_sizeargument. Specifying this argument will split your Keras model weight file into chunks of this size at most. Useload_model()to reload the sharded files. - Add optimizer
keras.optimizers.Muon - Add image preprocessing layer
keras.layers.RandomElasticTransform - Add loss function
keras.losses.CategoricalGeneralizedCrossEntropy(with functional versionkeras.losses.categorical_generalized_cross_entropy) - Add
axisargument toSparseCategoricalCrossentropy - Add
lora_alphato all LoRA-enabled layers. If set, this parameter scales the low-rank adaptation delta during the forward pass. - Add activation function
keras.activations.sparse_sigmoid - Add op
keras.ops.image.elastic_transform - Add op
keras.ops.angle - Add op
keras.ops.bartlett - Add op
keras.ops.blackman - Add op
keras.ops.hamming - Add ops
keras.ops.view_as_complex,keras.ops.view_as_real
PyTorch backend
- Add cuDNN support for LSTM with the PyTorch backend
TensorFlow backend
- Add
tf.RaggedTensorsupport toEmbeddinglayer - Add variable-level support for
synchronizationargument
OpenVINO backend
- Add support for over 50 additional Keras ops in the OpenVINO inference backend!
New Contributors
- @JyotinderSingh made their first contribution in #20993
- @SaifMohammed22 made their first contribution in #20982
- @11happy made their first contribution in #20940
- @jpy794 made their first contribution in #21008
- @chiruu12 made their first contribution in #20950
- @arkhamHack made their first contribution in #21010
- @samitshah1 made their first contribution in #21036
- @nathanrooy made their first contribution in #21056
- @rfezzani made their first contribution in #21053
- @drasmuss made their first contribution in #21072
- @pass-lin made their first contribution in #21037
- @wilsbj made their first contribution in #21077
- @timsweeneyfanelli made their first contribution in #21081
- @darshil929 made their first contribution in #21042
- @superbobry made their first contribution in #21106
- @nithin9000 made their first contribution in #21136
- @Huanli-Gong made their first contribution in #21141
- @he7d3r made their first contribution in #21098
- @Kayyuri made their first contribution in #21125
- @b05505027 made their first contribution in #21139
- @Hmm-1224 made their first contribution in #21060
- @hridaya14 made their first contribution in #21138
- @pschuh made their first contribution in #21164
- @cantonios made their first contribution in #21184
- @victorgearhead made their first contribution in #21129
- @srinjoydutta03 made their first contribution in #21168
- @SiddharthV147 made their first contribution in #21231
- @emmanuel-ferdman made their first contribution in #21241
- @pctablet505 made their first contribution in #21254
- @Imokutmfon made their first contribution in #21257
- @sanleo-wq made their first contribution in #21269
Full Changelog: v3.9.0...v3.10.0
Keras 3.9.2
Keras 3.9.1
What's Changed
- Fix flash attention TPU error
- Fix incorrect argument in JAX flash attention.
Full Changelog: v3.9.0...v3.9.1
Keras 3.9.0
New features
- Add new Keras rematerialization API:
keras.RematScopeandkeras.remat. It can be used to turn on rematerizaliation for certain layers in fine-grained manner, e.g. only for layers larger than a certain size, or for a specific set of layers, or only for activations. - Increase op coverage for OpenVINO backend.
- New operations:
keras.ops.rot90keras.ops.rearrange(Einops-style)keras.ops.signbitkeras.ops.polarkeras.ops.image.perspective_transformkeras.ops.image.gaussian_blur
- New layers:
keras.layers.RMSNormalizationkeras.layers.AugMixkeras.layers.CutMixkeras.layers.RandomInvertkeras.layers.RandomErasingkeras.layers.RandomGaussianBlurkeras.layers.RandomPerspective
- Minor additions:
- Add support for
dtypeargument toJaxLayerandFlaxLayerlayers - Add boolean input support to
BinaryAccuracymetric - Add
antialiasargument tokeras.layers.Resizinglayer.
- Add support for
- Security fix: disallow object pickling in saved
npzmodel files (numpy format). Thanks to Peng Zhou for reporting the vulnerability.
New Contributors
- @harshaljanjani made their first contribution in #20745
- @doncarlos999 made their first contribution in #20641
- @sonali-kumari1 made their first contribution in #20775
- @jurca made their first contribution in #20810
- @zskendall made their first contribution in #20805
- @apehex made their first contribution in #20803
- @nikolasavic3 made their first contribution in #20896
- @ibraaaa made their first contribution in #20926
- @AsVoider made their first contribution in #20921
- @abheesht17 made their first contribution in #20932
- @Mohamed-Ashraf273 made their first contribution in #20934
- @kuanxian1 made their first contribution in #20951
- @praveenhosdrug123 made their first contribution in #20916
Full Changelog: v3.8.0...v3.9.0