keras-tinygrad
A tinygrad backend for stock Keras 3.
No fork, no vendored Keras — pip install next to the PyPI wheel and train.
Community project — not affiliated with the Keras team or the tiny corp.
Also runs plugin-style on Keras' in-development
pluggable-backend branch
with zero patches (see docs/upstream/pluggable-branch-pilot.md).
import keras_tinygrad # must come first: installs the import hook
import keras # KERAS_BACKEND=tinygrad
import numpy as np
x = np.random.normal(size=(256, 8)).astype("float32")
y = x @ np.random.normal(size=(8, 1)).astype("float32")
model = keras.Sequential(
[
keras.layers.Input(shape=(8,)),
keras.layers.Dense(16, activation="relu"),
keras.layers.Dense(1),
]
)
model.compile(optimizer=keras.optimizers.Adam(0.01), loss="mse")
model.fit(x, y, epochs=5, batch_size=32)
That is the whole API. Everything after the first line is literally just Keras.
Install
pip install keras-tinygrad
New here? Start with TUTORIAL.md — every code block on that page is executed by CI, so it cannot rot.
Works against the stock PyPI keras wheel (3.15.x — 3.15.0 verified by the
full test tally below; 3.15.1 verified by the loader test suite and the
executable tutorial, training included) and tinygrad 0.13; the dependency
pin says the same thing (keras>=3.15,<3.16). On any other Keras version
the import fails loudly at the anchor check — see below.
The only rule: import keras_tinygrad before import keras (importing it
also defaults KERAS_BACKEND=tinygrad; an explicit setting always wins). If
Keras was already imported, you get a RuntimeError — never a half-patched
install.
How it can be a backend without a fork
Keras 3 has no backend plugin hook. This package installs a
sys.meta_path finder that serves keras.src.backend.tinygrad from its own
sources and surgically patches the six Keras modules that hardcode backend
dispatch. Each patch is an exact-string anchor that must match exactly
once — on an unsupported Keras version the import fails loudly with a
version-mismatch error instead of guessing. Details in
docs/how-it-works.md.
Status
Keras' own full layers test tree (preprocessing included): 1,989 passed /
5 failed / 215 skipped (99.7%). (Single run, python 3.12 + tensorflow
installed for collection, 2026-08-03.) All 5 failures are individually
documented: 2× upstream test_quantize_float8 (test-side train_one_step
only defined for tf/jax/torch — fix drafted in docs/upstream/keras-pr/),
2× RandomCrop (tinygrad __getitem__ lacks Tensor slice bounds — upstream
tinygrad item), 1× AutoContrast (FMA-contraction residual 1.9e-06 vs atol
1e-06). Cross-backend parity fuzz vs the numpy reference (make fuzz;
finite-difference gradient checks via make fuzz-grad): green; the one
former flag was the documented keras 64→32 promotion policy
(docs/float64-promotion.md).
Verified against Keras' own test suite, per-op:
- Core layer families green: conv/pooling 100%, activations 100%, losses 166/166, RNN layers (incl. default Orthogonal init) via the generic scan, attention (flash accepted as a hint), CTC with beam search, image ops (all five resize interpolations, antialias included).
- Training uses tinygrad 0.13's explicit
loss.gradient()— gradients are pure outputs, no tape bookkeeping;custom_gradienthonored via the trainer's tape (quantized training works). - int8 / int4 / float8 quantization working.
- No silent fallbacks. An unimplemented op raises
NotImplementedError. You get an error, never a wrong answer or a silently detached gradient.
| Suite | ✅ passed | ❌ failed | skipped | coverage |
|---|---|---|---|---|
| activations | 51 | 0 | 0 | 100.0% |
| Dense | 70 | 1 | 1 | 98.6% |
| EinsumDense | 98 | 1 | 0 | 99.0% |
| Embedding | 48 | 0 | 3 | 100.0% |
| BatchNormalization | 33 | 0 | 0 | 100.0% |
| Dropout | 14 | 0 | 0 | 100.0% |
| Conv | 41 | 0 | 0 | 100.0% |
| pooling | 135 | 0 | 0 | 100.0% |
| SimpleRNN | 5 | 0 | 0 | 100.0% |
| MultiHeadAttention | 49 | 0 | 1 | 100.0% |
| losses | 166 | 0 | 1 | 100.0% |
| Adam | 8 | 0 | 1 | 100.0% |
| SGD | 7 | 0 | 0 | 100.0% |
| accuracy metrics | 35 | 0 | 0 | 100.0% |
| ops/core | 165 | 0 | 9 | 100.0% |
| ops/image | 331 | 0 | 5 | 100.0% |
| ops/math | 208 | 0 | 4 | 100.0% |
| ops/numpy | 5502 | 3 | 708 | 99.9% |
| preprocessing layers (tree) | 689 | 4 | 29 | 99.4% |
| TOTAL | 7655 | 9 | 762 | 99.9% |
The Dense/EinsumDense failures are the upstream float8 test-side gap.
view_as_complex / view_as_real work via complex-lite interop (a
real/imag wrapper value); complex ARITHMETIC remains out of scope — any
complex op beyond that interop set raises NotImplementedError loudly,
never silently. The 4 remaining preprocessing failures: RandomCrop ×2
(needs tinygrad Tensor slice bounds — upstream conversation), one
FMA-precision residual (1.9e-06 vs atol 1e-06), one grain-thread ×
tinygrad-sqlite-cache clash. Preprocessing/ops-image runs need tensorflow
installed for test collection only.
Known gaps
Honest list:
keras.ops.unique/keras.ops.vectorize(data-dependent output shapes — loud stubs pending a design decision; the rest of the numpy tail landed, see docs/ops-numpy-triage.md).- Fused RNN kernels (recurrent layers take the generic scan path — correct, not fast; the TinyJit train step recovers most of the gap).
- Sparse and ragged tensors.
- TF-string preprocessing layers.
- Complex arithmetic (interop works; see docs/complex-support.md).
No clang? Use zig
tinygrad's CPU jit shells out to clang. On boxes without it, the
ziglang PyPI wheel works as a drop-in: a small shim script translates the
target triple to zig's spelling, adds -g0, and execs zig cc. Point
tinygrad's CC at the shim and CPU jit works with zero system packages.
Contributing
The method is fixed: the numpy backend is the semantic reference, Keras' own
tests are the referee, stubs stay loud. Dev loop: uv sync, then
make verify (lint + format + loader tests) before review; make tutorial,
make smoke, and make fuzz for the heavier checks. See
CONTRIBUTING.md.
License
Backend sources subclass and patch Keras (Apache-2.0) and drive tinygrad (MIT). This package's own code: see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file keras_tinygrad-0.1.0.tar.gz.
File metadata
- Download URL: keras_tinygrad-0.1.0.tar.gz
- Upload date:
- Size: 100.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e73a26e1472dd342378b10e0b42d63d30a45f2ff971b2edd5f3eb5088c43e943
|
|
| MD5 |
a14d27680d1a68d66acf2e270a8c0368
|
|
| BLAKE2b-256 |
1ef514f86ee6c2f5e14acd242cdb604079ae453ce53f2decb55d38057214be6f
|
Provenance
The following attestation bundles were made for keras_tinygrad-0.1.0.tar.gz:
Publisher:
publish.yml on c4ffein/keras-tinygrad
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keras_tinygrad-0.1.0.tar.gz -
Subject digest:
e73a26e1472dd342378b10e0b42d63d30a45f2ff971b2edd5f3eb5088c43e943 - Sigstore transparency entry: 2620084473
- Sigstore integration time:
-
Permalink:
c4ffein/keras-tinygrad@033d77aebea3a0d6143b30cc3c5ed8f3adac0f43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/c4ffein
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@033d77aebea3a0d6143b30cc3c5ed8f3adac0f43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file keras_tinygrad-0.1.0-py3-none-any.whl.
File metadata
- Download URL: keras_tinygrad-0.1.0-py3-none-any.whl
- Upload date:
- Size: 101.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a18279b4fc2c0017c2688f485c872a2931b85893b122ea064f7b65b79db9a78
|
|
| MD5 |
62f0e54adf3a9fdef3f8033497c8fbae
|
|
| BLAKE2b-256 |
f574c19486c811ce9d05a87f62651df39615c35b313f2dbc05c9b722f25bb3bd
|
Provenance
The following attestation bundles were made for keras_tinygrad-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on c4ffein/keras-tinygrad
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keras_tinygrad-0.1.0-py3-none-any.whl -
Subject digest:
4a18279b4fc2c0017c2688f485c872a2931b85893b122ea064f7b65b79db9a78 - Sigstore transparency entry: 2620084703
- Sigstore integration time:
-
Permalink:
c4ffein/keras-tinygrad@033d77aebea3a0d6143b30cc3c5ed8f3adac0f43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/c4ffein
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@033d77aebea3a0d6143b30cc3c5ed8f3adac0f43 -
Trigger Event:
push
-
Statement type: