keras-3deep-learningjaxpytorchtensorflowxlatutorial

Keras 3 Guide: Multi-Backend Architecture for JAX & PyTorch

Keras 3 Architecture: Multi-Backend Execution on JAX, PyTorch, and TensorFlow with Unified Keras Ops and XLA Compilation

The Problem: The Fragmentation, Rewriting Tax, and Framework Lock-In of Modern Deep Learning

In modern enterprise machine learning, automated web extraction engines, multimodal classification systems, and intelligent data pipelines powered by AiFetchly, machine learning teams must develop, optimize, and deploy neural networks across diverse computing infrastructures. Organizations train transformer backbones on high-performance cloud clusters, fine-tune domain-specific scrapers on on-premise NVIDIA GPUs, and deploy edge extractors across diverse environments ranging from Google Cloud TPUs to mobile and web runtimes.

However, for nearly a decade, the deep learning software ecosystem has been plagued by a crippling structural fracture: framework lock-in and ecosystem fragmentation.

The Deep Learning Framework Fragmentation Crisis: ┌────────────────────────────────────────────────────────┐ │ Silo 1: The PyTorch Ecosystem │ │ • Ubiquitous in research, dynamic eager mode debugging │ │ ❌ Fragmented TPU support; complex production exports │ ├────────────────────────────────────────────────────────┤ │ Silo 2: The JAX Ecosystem │ │ • Blazing XLA compilation speed; native TPU scaling │ │ ❌ Pure functional programming clashes with stateful OOP│ ├────────────────────────────────────────────────────────┤ │ Silo 3: The TensorFlow / TFLite Ecosystem │ │ • Mature production serving, mobile and web runtimes │ │ ❌ Deprecated legacy abstractions; slow research R&D │ └────────────────────────────────────────────────────────┘ Result: Machine learning teams wasted months rewriting models across frameworks!

1. The Cost of Framework Migration and Code Rewrites

In production engineering, a model’s lifecycle frequently spans multiple disparate frameworks:

  • A research scientist prototypes a novel attention layer or document parser using PyTorch due to its vast library of open-source weights.
  • When moving to large-scale distributed pre-training, the infrastructure team discovers that renting Google Cloud TPU v5e pods is significantly more cost-effective than competing GPU clusters. However, running efficiently on TPUs requires JAX and XLA, forcing engineers to completely rewrite the PyTorch code into functional JAX primitives.
  • Finally, when deploying the trained weights to mobile or edge devices, the deployment team demands TensorFlow Lite (TFLite) or ONNX, requiring yet another conversion cycle fraught with numerical discrepancies.

2. The Clash Between Stateful OOP and Functional Paradigms

Bridging PyTorch and JAX is mathematically and architecturally non-trivial:

  • PyTorch’s Object-Oriented State: PyTorch organizes layers around stateful classes (torch.nn.Module) where weights are stored as mutable object attributes (self.weight), updated in-place by optimizers.
  • JAX’s Purely Functional World: JAX strictly adheres to functional programming. Functions must be pure and stateless: transformations like jax.jit, jax.grad, and jax.vmap require passing explicit parameter dictionaries as inputs and receiving updated parameter dictionaries as outputs.
  • Reconciling these two opposing design philosophies in a single readable codebase was previously considered impossible without cumbersome wrapper abstractions.

3. Training vs. Deployment Infrastructure Divergence

Tying an entire machine learning codebase to a single framework creates immense operational risk:

  • If NVIDIA GPU prices surge or supply chains tighten, a team locked into CUDA-dependent PyTorch cannot pivot to alternative hardware (such as Google Cloud TPUs or AWS Trainium).
  • Conversely, a team locked strictly into JAX cannot easily tap into the vast ecosystem of PyTorch-only open-weights libraries (such as Hugging Face PEFT or BitsAndBytes).

To dismantle these artificial barriers, François Chollet and the Keras engineering team introduced Keras 3: a complete ground-up rewrite that establishes a universal multi-backend deep learning architecture across JAX, PyTorch, and TensorFlow.

The Solution: Keras 3 Architecture, Unified Keras Ops & Stateless State Engine

Keras 3 redefines deep learning abstractions by decoupling high-level model definitions from the underlying tensor execution engine. A model written once in Keras 3 can be executed seamlessly in JAX, PyTorch, or TensorFlow simply by setting an environment variable (KERAS_BACKEND=jax).

Keras 3 Comprehensive Multi-Backend Topology: ┌─────────────────────────────────────────────────────────────────┐ │ User Model Definition: Sequential, Functional API, or Subclass │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Keras 3 Core Layer & Model Architecture │ │ • Stateful OOP Layer API (self.add_weight, build, call) │ │ • Functional Stateless State Engine (stateless_call) │ │ • Unified Keras Ops Engine: keras.ops.* │ └─────────────────────────────────────────────────────────────────┘ │ ┌──────────────────────┼──────────────────────┐ ▼ ▼ ▼ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ JAX Backend │ │ PyTorch Back. │ │ TF Backend │ │ • jax.numpy │ │ • torch.Tensor│ │ • tf.Tensor │ │ • jax.jit/vmap│ │ • autograd │ │ • tf.function │ │ • XLA Compile │ │ • Inductor │ │ • XLA Compile │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Hardware Silicon: NVIDIA GPUs / Google TPUs / AMD ROCm / CPUs │ └─────────────────────────────────────────────────────────────────┘

1. The Unified Low-Level Tensor Engine: Keras Ops

At the core of Keras 3 is keras.ops: a comprehensive, low-level tensor manipulation library comprising hundreds of mathematical operations (such as ops.matmul, ops.conv, ops.einsum, ops.scatter, and ops.qr):

  • Zero Overhead Dispatch: Each operation in keras.ops is implemented directly using the native backend primitives: when using the JAX backend, ops.matmul calls jax.numpy.matmul; on PyTorch, it invokes torch.matmul.
  • Framework-Agnostic Custom Layers: Developers can write custom layers, loss functions, and activation kernels using keras.ops without importing torch or jax directly. The resulting layer functions natively in all three backends with zero performance penalty.

2. Bridging Object-Oriented State with Functional JAX

Keras 3 resolves the classic clash between PyTorch’s stateful OOP and JAX’s functional programming via an innovative dual-execution model:

  • Stateful OOP Interface: Developers define layers naturally using familiar object-oriented conventions:
    class CustomLinear(keras.layers.Layer): def build(self, input_shape): self.w = self.add_weight(shape=(input_shape[-1], self.units)) def call(self, inputs): return keras.ops.matmul(inputs, self.w)
  • Stateless Functional Bridge: Internally, Keras 3 equips every layer with a stateless_call() method. When executing under the JAX backend, Keras extracts weights as an immutable dictionary of variables, evaluates the pure function inside jax.jit or jax.vmap, and maps the updated states back.
  • This gives engineers the best of both worlds: intuitive object-oriented model definition with the extreme execution speed of pure functional JAX compilation.

3. Ahead-of-Time Graph Compilation via XLA and TorchInductor

By targeting multiple backends, Keras 3 unlocks the premier optimizing compilers of the modern deep learning era:

  • JAX XLA Acceleration: Compiling a Keras 3 model via JAX leverages the Accelerated Linear Algebra (XLA) compiler. XLA performs aggressive horizontal and vertical kernel fusion, keeping intermediate activations inside fast on-chip SRAM and boosting training throughput by 20% to 50% compared to eager PyTorch.
  • TorchInductor Integration: When executing on the PyTorch backend, Keras 3 models integrate seamlessly with torch.compile, emitting optimized OpenAI Triton kernels on GPUs and vectorized OpenMP C++ code on CPUs.

4. Universal Cross-Framework Weight Serialization

Keras 3 introduces universal weight serialization format (.weights.h5):

  • A model trained using PyTorch autograd can be saved to disk and loaded immediately into a JAX instance without writing custom tensor renaming scripts or converting PyTorch state_dict structures.
  • Teams can train a large vision transformer in JAX on TPU pods, export the weights, and serve them locally inside a lightweight PyTorch or C++ inference engine.

Architectural Comparison: Keras 3 vs. Raw PyTorch vs. Native JAX vs. Keras 2 (TF-Only)

To understand how Keras 3 reshapes the deep learning development lifecycle, consider the following technical comparison:

Metric / CapabilityRaw PyTorchNative JAXKeras 2 (Legacy)Keras 3
Backend PortabilityPyTorch OnlyJAX OnlyTensorFlow OnlyJAX, PyTorch & TensorFlow
Programming ParadigmStateful OOP (nn.Module)Pure Functional (stateless)Stateful OOPHybrid OOP + Stateless Functional
TPU PerformanceModerate (Torch-XLA)Exceptional (Native XLA)Strong (TF XLA)Exceptional (via JAX XLA)
Compiler OptimizationTorchInductor / TritonXLA Ahead-of-TimeXLA (TF Graph)Native XLA + TorchInductor
Low-Level Math APItorch.*jax.numpy.*tf.*Unified keras.ops.*
Cross-Backend WeightsRequires custom scriptsRequires custom picklingTF SavedModel onlyUniversal .weights.h5 Loading
Mobile & Edge ExportExecuTorch (Emerging)Complex ExportTFLiteInstant TFLite, ONNX & TFJS
Learning CurveModerateHigh (Functional learning)ModerateGentle / Pythonic Standard

Hands-On Implementation: Building a Multi-Backend Neural Network with Keras 3

Below is a complete, production-grade guide demonstrating how to install Keras 3, author a custom layer using unified keras.ops, and dynamically switch execution backends between PyTorch and JAX with zero code modifications.

Step 1: Install Dependencies

Install Keras 3 alongside JAX and PyTorch:

# Create and activate environment conda create -n keras3 python=3.10 -y conda activate keras3 # Install PyTorch with CUDA 12.4 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124 # Install JAX with CUDA acceleration pip install "jax[cuda12]" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html # Install Keras 3 pip install keras>=3.6.0

Step 2: Build a Custom Multi-Backend Layer with Keras Ops

The following script defines a complete, custom Multi-Layer Perceptron with GELU activation using pure keras.ops:

import os # Set backend dynamically: 'jax', 'torch', or 'tensorflow' os.environ["KERAS_BACKEND"] = "torch" import keras from keras import ops print(f"Active Keras Backend: {keras.backend.backend()}") class MultiBackendDense(keras.layers.Layer): """Custom dense layer using unified Keras Ops compatible with JAX and PyTorch.""" def __init__(self, units: int, activation=None, **kwargs): super().__init__(**kwargs) self.units = units self.activation = keras.activations.get(activation) def build(self, input_shape): input_dim = input_shape[-1] self.kernel = self.add_weight( shape=(input_dim, self.units), initializer="glorot_uniform", trainable=True, name="kernel" ) self.bias = self.add_weight( shape=(self.units,), initializer="zeros", trainable=True, name="bias" ) def call(self, inputs): # Low-level ops automatically dispatched to active backend! output = ops.matmul(inputs, self.kernel) output = ops.add(output, self.bias) if self.activation is not None: output = self.activation(output) return output # Instantiate and verify layer layer = MultiBackendDense(units=64, activation="gelu") dummy_input = ops.ones((8, 32)) output = layer(dummy_input) print(f"Layer output tensor shape: {output.shape} (Type: {type(output)})")

Step 3: Train and Switch Backends Dynamically between PyTorch and JAX

Now, observe how the exact same model definition compiles and trains on both PyTorch and JAX backends:

import os import numpy as np # Select JAX backend for blazing XLA compilation os.environ["KERAS_BACKEND"] = "jax" import keras print(f"\n--- Running Training on Backend: {keras.backend.backend()} ---") # 1. Build Model using Functional API inputs = keras.Input(shape=(32,)) x = keras.layers.Dense(64, activation="relu")(inputs) x = keras.layers.Dropout(0.2)(x) outputs = keras.layers.Dense(1, activation="sigmoid")(x) model = keras.Model(inputs=inputs, outputs=outputs) # 2. Compile with XLA JIT optimization model.compile( optimizer=keras.optimizers.Adam(learning_rate=1e-3), loss="binary_crossentropy", metrics=["accuracy"], jit_compile=True # Triggers JAX XLA JIT compilation ) # 3. Generate synthetic classification dataset X_train = np.random.randn(1000, 32).astype("float32") y_train = (np.sum(X_train[:, :5], axis=1) > 0).astype("float32") # 4. Fit model history = model.fit(X_train, y_train, epochs=3, batch_size=32, verbose=1) # 5. Save universal weights model.save_weights("universal_model.weights.h5") print("\nUniversal weights successfully saved to 'universal_model.weights.h5'!") print("These weights can be loaded directly into PyTorch or TensorFlow instances without conversion.")

Production Deployment with aiFetchly

In autonomous data collection, real-time web scraping, and document classification pipelines engineered by AiFetchly, machine learning systems must adapt continuously to evolving data structures and multi-cloud server topologies.

Here is how Keras 3 empowers high-velocity data harvesting:

aiFetchly Enterprise Deep Learning Pipeline with Keras 3: ┌─────────────────────────────────────────────────────────────────┐ │ 1. Rapid PyTorch Prototyping │ │ • Researchers develop novel DOM parsers & text taggers in Torch │ │ • Interactive line-by-line debugging with eager autograd │ ├─────────────────────────────────────────────────────────────────┤ │ 2. Cost-Effective TPU Training via JAX │ │ • Swap KERAS_BACKEND=jax; deploy to Google Cloud TPU pods │ │ • XLA graph compilation accelerates pre-training by 35% │ ├─────────────────────────────────────────────────────────────────┤ │ 3. Universal Weight Portability (.weights.h5) │ │ • Zero conversion scripts between research and production │ │ • Instant loading into on-premise NVIDIA inference servers │ ├─────────────────────────────────────────────────────────────────┤ │ 4. Lightweight Edge Export for Desktop Agents │ │ • Direct export to TFLite and ONNX for client-side scrapers │ │ • Runs locally on office laptops without PyTorch dependencies │ └─────────────────────────────────────────────────────────────────┘
  1. Multi-Cloud Cost Arbitrage: With Keras 3, aiFetchly avoids vendor lock-in. When GPU pricing spikes on commercial cloud providers, data extraction models can be trained immediately on Google Cloud TPUs via JAX with zero code rewrites.
  2. Accelerated Ingestion Throughput: By utilizing JAX XLA compilation inside production feature extractors, aiFetchly processes incoming web documents 35% faster than legacy eager PyTorch pipelines.
  3. Streamlined Edge Distribution: Models trained in cloud clusters can be exported directly into lightweight TFLite and ONNX runtimes for deployment inside aiFetchly’s private desktop scraping copilots.

To discover how aiFetchly combines modern deep learning architectures with high-throughput automated web harvesting, explore our AiFetchly Documentation or review our AiFetchly Pricing.