NEWn1n v2.0.1 is live! Enterprise Unified LLM API Gateway with 500+ AI Models, up to 90% off, Try now

Optimizing Keras 3 on PyTorch: Achieving an 11.6x Speedup via Engine-Level Refactoring

Authors
  • avatar
    Name
    Nino
    Occupation
    Senior Tech Editor

Recent updates in the Keras repository under issue #22561 have transformed how compiled models execute on backend frameworks, particularly PyTorch. Between July and October 2026, a series of 15 pull requests dramatically improved inference throughput. On a standard 2.1M-parameter test language model, compiled Keras[torch] now generates text 11.6 times faster than it did previously.

This performance leap was not achieved by altering hardware or upgrading framework versions—the same NVIDIA RTX PRO 6000 Blackwell GPU, PyTorch build, and JAX versions were maintained across benchmarks. Instead, the gains stem from relentless profiling, eliminating Python-side overhead, and removing graph breaks that previously crippled torch.compile.

Whether you are deploying massive transformer architectures via high-throughput LLM APIs or managing distributed inference clusters using infrastructure aggregators like n1n.ai, understanding these low-level optimizations is crucial for maximizing hardware utilization.


The Performance Transformation: Before and After

In July 2026, compiling a Keras model backed by PyTorch was actually counterproductive. Rather than accelerating execution, torch.compile introduced significant compilation overhead and graph breaks, causing eager execution to outperform the compiled counterpart.

  • July 2026: Compiled Keras[torch] ran at 1,458 tokens/second, whereas eager Keras achieved 2,139 tokens/second.
  • October 2026: The compiled model hits 16,975 tokens/second—delivering a 6.56x speedup over eager Keras and closing in on native, plain compiled PyTorch performance.

Configuration Performance Comparison

The table below illustrates the execution time (in milliseconds per call) across 12 distinct configurations and workloads, tracking progress from the July baseline to the October milestone.

Keras configWorkloadPlain framework (ms)Jul 18 (ms)Oct 15 (ms)Change+ #23336 (ms)A/B check
Keras[torch] · eagerCNN forward0.0640.6680.4771.40x0.4661.39x
Keras[torch] · eagerLLM forward0.1891.881.551.22x1.481.20x
Keras[torch] · eagerLLM generate-325.8559.849.51.21x47.21.20x
Keras[torch] · torch.compileCNN forward0.0761.280.1608.03x0.1618.41x
Keras[torch] · torch.compileLLM forward0.1602.690.3028.93x0.2999.60x
Keras[torch] · torch.compileLLM generate-324.9287.87.5411.6x7.6612.4x
Keras[jax] · eagerCNN forward0.5081.341.231.08x1.181.15x
Keras[jax] · eagerLLM forward2.798.468.381.01x7.901.12x
Keras[jax] · eagerLLM generate-3289.02932671.10x2691.08x
Keras[jax] · jax.jitCNN forward0.0770.0790.0810.97x0.0801.02x
Keras[jax] · jax.jitLLM forward0.1200.1310.1350.97x0.1301.05x
Keras[jax] · jax.jitLLM generate-322.222.302.450.94x2.271.05x

Note: A/B check compares July vs. October timing across three separate back-to-back rounds.


Anatomy of the Optimization: Key Pull Requests

Rather than rewriting the entire codebase, the engineering team targeted shared execution paths (Layer.call, op tracebacks, dtype handling, input validation). Because these modules are shared across backends, the performance dividend extends beyond PyTorch, reducing Python function call overhead across JAX, TensorFlow, and NumPy.

The table below breaks down the impact of individual PRs on call overhead and generation latency:

PRMergedWhat it changedΔ calls/fwd torchJAXTFNumPyΔ eager gen-32 (ms)Δ compiled gen-32 (ms)Graph breaks
#2318307-28Tracebacks built only on op failure−598−586−622−546−2.9−5.2·
#2332708-30Removed graph break in dot_product_attention+6000+0.40−12.3LLM 11 → 0
#2320009-05Stopped re-setting built/_called on every call−1,848−1,098−1,188−1,100−4.9−10.5·
#2320109-11Canonical dict key order for tree code−142+800+0.55−5.2CNN 9 → 0
#2364709-30Tree code stops comparing id()s0−800−0.58−49.4·

For developers building enterprise applications that route prompts across diverse foundational models via n1n.ai, these lower latencies translate directly into reduced compute costs and improved user experience.


Profiling Hot Functions in LLM Forward Passes

A granular look at cProfile data reveals precisely where Python execution time was reclaimed during a single Keras[torch] LLM forward pass:

FunctionJul 18Oct 15Change+ #23336
isinstance2,6001,740−33%1,680
traceback error wrappers7448−35%48
thread-local config lookups624513−18%513
standardize_dtype177244+38%184
tree.flatten9367−28%67
tree.map_structure10262−39%62

By optimizing object checks, caching type promotions, and streamlining tree traversals, the framework successfully stripped out thousands of redundant interpreter operations per forward pass.


Pro Tips for PyTorch & LLM API Integration

  1. Eliminate Dynamic Graph Breaks: Always inspect your compilation boundaries using torch._dynamo.explain(). Unhandled Python constructs or dictionary re-orderings can silently trigger fallbacks to eager mode.
  2. Leverage Aggregated Endpoints: When orchestrating multi-model pipelines or fallback chains, utilize resilient API gateways like n1n.ai to handle rate-limiting and latency routing seamlessly.
  3. Keep Tooling Up to Date: Ensure your execution runtime matches your compilation targets; minor version shifts in PyTorch can sometimes alter graph capture behavior.

Get a free API key at n1n.ai