Instructions to use MediumIQ/keras-hdf5-sparse-dos-poc with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use MediumIQ/keras-hdf5-sparse-dos-poc with Keras:
# Available backend options are: "jax", "torch", "tensorflow". import os os.environ["KERAS_BACKEND"] = "jax" import keras model = keras.saving.load_model("hf://MediumIQ/keras-hdf5-sparse-dos-poc") - Notebooks
- Google Colab
- Kaggle
YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
# Keras .keras sparse HDF5 weight DoS PoC
This repo is a small proof of concept for a Keras native .keras loading issue.
The short version: Keras reads a weight dataset from model.weights.h5 into memory before it checks that the dataset shape matches the variable it is being assigned to. HDF5 lets a dataset have a large logical shape while taking almost no physical space on disk. Putting those two facts together gives a very small .keras file that can cause a large memory spike during keras.saving.load_model().
This is a load-time memory amplification / denial-of-service issue.
Files
sparse_kernel_8192x8192.keras- bounded PoC model file.build_poc.py- rebuilds the PoC from a clean Keras model.verify_poc.py- inspects the HDF5 metadata and can run the Keras load path in a child process.verification_summary.json- short summary from the packaged verifier run.requirements.txt- versions used while testing.
Warning
The included 8192x8192 PoC is intentionally bounded for review safety. On my Windows test box this bounded sample caused about 800 MB of peak RSS growth before Keras rejected the model with a shape error. This is not a maximum: larger HDF5 logical shapes can keep the file small while requesting much larger materializations, until the loader hits the process/container/host memory limit.
Run the --load check in a disposable shell or a memory-limited container/VM if possible.
Tested environment
- Python 3.12.3
- Keras 3.14.1
- h5py 3.14.0
- ModelScan 0.8.8
- TensorFlow backend
- Windows 64-bit
Rebuild the PoC
python build_poc.py
By default this creates:
dense_clean_reference.kerassparse_kernel_8192x8192.keras
The sparse model keeps the inner HDF5 member tiny, but changes the Dense kernel dataset to:
{
"path": "layers/dense/vars/0",
"shape": [8192, 8192],
"dtype": "float32",
"storage_size": 0,
"chunks": null
}
Inspect without loading
This is the safe check. It does not call load_model().
python verify_poc.py
You should see the large logical shape and storage_size: 0 for layers/dense/vars/0.
Trigger the load path
This is the actual reproduction. It starts a child process, imports Keras, then measures memory while the child calls load_model().
python verify_poc.py --load --timeout 30
Expected result: Keras eventually raises a shape mismatch similar to:
variable.shape=(4, 3), Received: value.shape=(8192, 8192)
The important part is that the error comes after Keras has already materialized the large logical dataset.
Local result
My bounded run produced this summary:
.keras size: 13,470 bytes
model.weights.h5 size: 11,604 bytes
logical kernel: 8192 x 8192 float32 = 268,435,456 bytes
peak RSS delta during load: 795,549,696 bytes in the earlier run, and 817,274,880 bytes in the packaged verifier run
load result: ValueError after materialization
That is roughly 59k:1 amplification from the .keras file size to peak RSS growth, or about 68k:1 if measured from the inner HDF5 member.
ModelScan note
ModelScan 0.8.8 did not flag this native .keras PoC in my test run. The inner model.weights.h5 member was skipped by the HDF5 scanner because it is not a legacy HDF5 model file with a model_config attribute. So the file can look clean to ModelScan while still causing the memory spike when Keras loads the weights.
Observed summary:
{
"issues": [],
"errors": [],
"skipped": [
"...model.weights.h5 was skipped during a hdf5 scan: Model Config not found"
]
}
Why I think this matters
A service that only stores uploaded .keras files is not affected by storage alone. The issue is triggered when a backend loads the file, for example during validation, scanning, conversion, or deployment.
That is a common pattern for model hubs and internal ML platforms. A tiny upload can put hundreds of megabytes of pressure on the worker that tries to load it. Bigger logical shapes should push this further until the process hits its memory limit or gets killed by the container/OS.
The fix should be simple in principle: check the HDF5 dataset shape against the expected variable shape before converting the dataset into a NumPy array.
- Downloads last month
- 13