Releases: keras-team/keras
v3.14.0
Highlights
- Orbax Checkpoint Integration: Full support for Orbax checkpoints, including sharding, remote paths, and step recovery.
- Quantization Upgrades: Added support for Activation-aware Weight Quantization (AWQ) and Asymmetric INT4 Sub-Channel Quantization.
- Batch Renormalization in BatchNorm: Added batch renormalization feature to the
BatchRenormalizationlayer. - New Optimizer: Added
ScheduleFreeAdamWoptimizer. - Gated Attention: Introduced optional Gated Attention support in
MultiHeadAttentionandGroupedQueryAttentionlayers.
New Features and Operations
Multi-Backend Operations
- NaN-aware NumPy Operations: Added support for
nanmin,nanmax,nanmean,nanmedian,nanvar,nanstd,nanprod,nanargmin,nanargmax, andnanquantileinkeras.ops.numpy. - New Math & Linear Algebra Operators: Added
nextafter,ptp,view,sinc,fmod,i0,fliplr,flipud,rad2deg,geomspace,depth_to_space,space_to_depth, andfold.
Preprocessing and Layers
- CLAHE Layer: Added Contrast Limited Adaptive Histogram Equalization preprocessing layer.
- Adapt Support for Iterables: Preprocessing layers now support Python iterables in the
adapt()method, which allows the direct use of Grain datasets.
OpenVINO Backend Support
The OpenVINO backend received a massive update, implementing a wide array of NumPy and Neural Network operations to achieve feature parity with other backends:
- NumPy Operations:
vander,trapezoid,corrcoef,correlate,flip,diagonal,cbrt,hypot,trace,kron,argpartition,logaddexp2,ldexp,select,round,vstack,hsplit,vsplit,tile,nansum,tensordot,exp2,trunc,gcd,unravel_index,inner,cumprod,searchsorted,hanning,diagflat,norm,histogram,lcm,allclose,real,imag,isreal,kaiser,shuffle,einsum,quantile,conj,randint,in_top_k,signbit,gamma,heaviside,var,std,inv,solve,cholesky_inverse,fft,fft2,ifft2,rfft,irfft,stft,istft,scatter,binomial,unfold,QR decomposition,view, and more. - Neural Network Operations: Added support for
separable_conv,conv_transpose,adaptive_average_pool,adaptive_max_pool,RNN,LSTM, andGRU. - Control Flow Operations: Implemented
cond,scan,associative_scan,map,switch,fori_loop, andvectorized_map.
Bug Fixes and Improvements
Backend Specific Improvements
- PyTorch: Dynamic shapes support in export, device selection improvements, and bug fixes to the CuDNN based LSTM and GRU implementation.
- JAX: Improved RNG handling in
FlaxLayerandJaxLayer, variable jitting improvements, and direct JAX-to-ONNX export. - NumPy: Enabled masking support for the NumPy backend.
Other Improvements
- Fixed multiple symbolic shape bugs across layers like
Conv1DTranspose,IndexLookup, andTextVectorization. - Fixed activity regularizer normalization by batch size.
- Improved
Sequentialerror messages for incompatible layers. - Minimized memory usage issues in
sparse_categorical_crossentropy.
New Contributors
We would like to thank our new contributors for making their first contribution to the Keras project:
- @vaidik-gupta made their first contribution in #21939
- @HyperPS made their first contribution in #21880
- @calad0i made their first contribution in #21959
- @KarSri7694 made their first contribution in #21963
- @MarcosAsh made their first contribution in #21961
- @orbin123 made their first contribution in #21935
- @ayulockedin made their first contribution in #21985
- @Shi-pra-19 made their first contribution in #21987
- @mahi21tha made their first contribution in #21989
- @PES2UG23CS205 made their first contribution in #21984
- @samudraneel05 made their first contribution in #22017
- @Junead04 made their first contribution in #21784
- @nexeora made their first contribution in #22051
- @bittoby made their first contribution in #22048
- @0xManan made their first contribution in #22035
- @sharpenteeth made their first contribution in #22079
- @maitry63 made their first contribution in #22068
- @Kh9705 made their first contribution in #22110
- @timon0305 made their first contribution in #22112
- @goyaladitya05 made their first contribution in #22131
- @Sikandar1310291 made their first contribution in #22014
- @haroon10725 made their first contribution in #22159
- @andersendsa made their first contribution in #22155
- @Rahuldrabit made their first contribution in #22146
- @jerryxyj made their first contribution in #22178
- @aaishwarymishra made their first contribution in #22173
- @Sujanian1304 made their first contribution in #22236
- @CityBoy-Claude made their first contribution in #22243
- @rstar327 made their first contribution in #22252
- @daehyun99 made their first contribution in #22289
- @kysolvik made their first contribution in #22290
- @ItzCobaltboy made their first contribution in #22158
- @cpuguy96 made their first contribution in #22284
- @0xRozier made their first contribution in #22218
- @tanguyguyot made their first contribution in #22327
- @AlanPonnachan made their first contribution in #21953
- @shriramThakare3 made their first contribution in #22306
- @Eruis2579 made their first contribution in #22350
- @satheeshbhukya made their first contribution in #22388
- @sam-shubham made their first contribution in #22265
- @Passavee-Losripat made their first contribution in #22404
- @ChiragSW made their first contribution in #22439
- @rishi-sangare made their first contribution in #22407
- @Caslyn made their first contribution in #22488
- @Abineshabee made their first contribution in #22469
- @dagecko made their first contribution in #22555
Full Changelog: v3.13.2...v3.14.0
v3.13.2
Security Fixes & Hardening
This release introduces critical security hardening for model loading and saving, alongside improvements to the JAX backend metadata handling.
-
Disallow
TFSMLayerdeserialization insafe_mode(#22035)- Previously,
TFSMLayercould load external TensorFlow SavedModels during deserialization without respecting Kerassafe_mode. This could allow the execution of attacker-controlled graphs during model invocation. TFSMLayernow enforcessafe_modeby default. Deserialization viafrom_config()will raise aValueErrorunlesssafe_mode=Falseis explicitly passed orkeras.config.enable_unsafe_deserialization()is called.
- Previously,
-
Fix Denial of Service (DoS) in
KerasFileEditor(#21880)- Introduces validation for HDF5 dataset metadata to prevent "shape bomb" attacks.
- Hardens the
.kerasfile editor against malicious metadata that could cause dimension overflows or unbounded memory allocation (unbounded numpy allocation of multi-gigabyte tensors).
-
Block External Links in HDF5 files (#22057)
- Keras now explicitly disallows external links within HDF5 files during loading. This prevents potential security risks where a weight file could point to external system datasets.
- Includes improved verification for H5 Groups and Datasets to ensure they are local and valid.
Backend-specific Improvements (JAX)
- Set
mutable=Trueby default innnx_metadata(#22074)- Updated the JAX backend logic to ensure that variables are treated as mutable by default in
nnx_metadata. - This makes Keras 3.13.2 compatible with Flax 0.12.3 when the Keras NNX integration is enabled.
- Updated the JAX backend logic to ensure that variables are treated as mutable by default in
Saving & Serialization
- Improved H5IOStore Integrity (#22057)
- Refactored
H5IOStoreandShardedH5IOStoreto remove unused, unverified methods. - Fixed key-ordering logic in sharded HDF5 stores to ensure consistent state loading across different environments.
- Refactored
Contributors
We would like to thank the following contributors for their security reports and code improvements:
@0xManan, @HyperPS, @hertschuh, and @divyashreepathihalli.
Full Changelog: v3.13.1...v3.13.2
v3.12.1
Security Fixes & Hardening
This release introduces critical security hardening for model loading and saving, alongside improvements to the JAX backend metadata handling.
-
Disallow
TFSMLayerdeserialization insafe_mode(#22035)- Previously,
TFSMLayercould load external TensorFlow SavedModels during deserialization without respecting Kerassafe_mode. This could allow the execution of attacker-controlled graphs during model invocation. TFSMLayernow enforcessafe_modeby default. Deserialization viafrom_config()will raise aValueErrorunlesssafe_mode=Falseis explicitly passed orkeras.config.enable_unsafe_deserialization()is called.
- Previously,
-
Fix Denial of Service (DoS) in
KerasFileEditor(#21880)- Introduces validation for HDF5 dataset metadata to prevent "shape bomb" attacks.
- Hardens the
.kerasfile editor against malicious metadata that could cause dimension overflows or unbounded memory allocation (unbounded numpy allocation of multi-gigabyte tensors).
-
Block External Links in HDF5 files (#22057)
- Keras now explicitly disallows external links within HDF5 files during loading. This prevents potential security risks where a weight file could point to external system datasets.
- Includes improved verification for H5 Groups and Datasets to ensure they are local and valid.
Saving & Serialization
- Improved H5IOStore Integrity (#22057)
- Refactored
H5IOStoreandShardedH5IOStoreto remove unused, unverified methods. - Fixed key-ordering logic in sharded HDF5 stores to ensure consistent state loading across different environments.
- Refactored
Acknowledgments
Special thanks to the security researchers and contributors who reported these vulnerabilities and helped implement the fixes: @0xManan, @HyperPS, and @hertschuh.
Full Changelog: v3.12.0...v3.12.1
v3.13.1
Bug Fixes & Improvements
- General
- Removed a persistent warning triggered during
import keraswhen using NumPy 2.0 or higher. (#21949)
- Removed a persistent warning triggered during
- Backends
- JAX: Fixed an issue where CUDNN flash attention was broken when using JAX versions greater than 0.6.2. (#21970)
- Export & Serialization
- Resolved a regression in the export pipeline that incorrectly forced batch sizes to be dynamic. The export process now correctly respects static batch sizes when defined. (#21944)
Full Changelog: v3.13.0...v3.13.1
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