You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

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.keras
  • sparse_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
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support