Kapre puts the spectrogram inside the Keras model graph
kapre: Keras Audio Preprocessors
At a glance
- What is it?
- Kapre is a small set of TensorFlow Keras layers that compute STFT, magnitude, mel-spectrogram and inverse transforms on GPU as part of the model, so a training run takes raw waveforms and a deployment needs nothing but a sampling rate. The cost is a hard dependency ceiling on Keras, pinned below 3.14 because of a TFLite conversion break.
- Who is it for?
- Adopt Kapre when you train audio models in TensorFlow Keras and want the DSP parameters inside the graph so a hyperparameter sweep can vary n_fft and a deployed model needs only the sampling rate. Do not adopt it if you need TFLite inference on the same graph, since the standard STFT layer does not convert and the TFLite variants cannot train beyond batch size 1.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 158 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The spectrogram becomes a layer instead of a cached file
Most audio pipelines convert waveforms to spectrograms once, write the results to disk, and train on the cached arrays. Kapre takes the opposite position. Its layers sit inside the Keras model, so the transform is computed on GPU in real time during training and inference.
The README frames this as a choice between two workflows, pre-computation against your own implementation. Against pre-computation, the argument is that DSP parameters become optimizable, deployment gets simpler and more consistent, and the code and model carry fewer dependencies. Against writing the transform yourself, the argument is speed, consistency with 1D and 2D TensorFlow batch shapes, freedom from the data format question since both channels_first and channels_last work, and fewer errors, because the layers are tested against Librosa.
That last claim is the one to hold onto. The README is blunt that STFT and decibel conversion are trickier than they look, and a library whose numbers are checked against a reference implementation is worth more than one that is merely convenient. Two extended capabilities are called out beyond what the default tf.signals implementation offers: a perfectly invertible STFT and InverseSTFT pair, and a mel-spectrogram with more options.
Five steps end with the deployment needing only a sampling rate
The workflow the README describes is worth reading because it shows where responsibility moves. You preprocess the audio dataset yourself, resampling to the right sampling rate and storing the waveforms. In the model, you add a Kapre layer such as kapre.time_frequency.STFT() as the first layer. The data loader then simply loads waveforms and feeds them in.
In a hyperparameter search you include DSP parameters like n_fft, which is where the payoff appears: the transform is part of the model, so the search can vary it alongside the learning rate and the layer sizes. When the final model is deployed, the README states that all you need to remember is the sampling rate of the signal. No dependency or preprocessing.
The shift is worth naming precisely. Pre-computation moves the DSP out of the training loop, where it runs once and gets cached; Kapre moves it into the loop, where it runs on every batch. What you gain in flexibility, you pay for in compute, and the repository does not publish a benchmark, so the size of that trade is something you would have to measure on your own data rather than read off a page.
Installing is one command, and the first model is one import block
Installation is the usual pip install of the package name:
pip install kapreThe quick start then builds a Sequential model whose first layer is the transform. The excerpt below is the part that matters for anyone wiring Kapre into an existing pipeline, the STFT layer configuration and the two layers that follow it:
from kapre import STFT, Magnitude, MagnitudeToDecibel
from kapre.composed import get_melspectrogram_layer, get_log_frequency_spectrogram_layer
model = Sequential()
model.add(Input(shape=input_shape))
model.add(STFT(n_fft=2048, win_length=2048, hop_length=1024,
window_name=None, pad_end=False,
input_data_format='channels_last', output_data_format='channels_last'))
model.add(Magnitude())
model.add(MagnitudeToDecibel())Two details are easy to miss. The first is that window_name is set to None in the example, so the window function is not fixed by that call, and the second is that the composed helpers exist for the common cases, so a mel-spectrogram or log-frequency spectrogram can be dropped in instead of the three layer sequence. The example input is a 44100 sample, 6 channel signal, which is a shape convention rather than a requirement, and the same file also demonstrates a SpecAugment data augmentation notebook under the examples folder.
TFLite conversion needs a different layer set and a different model
This is where the project draws its clearest line, and it is a real constraint rather than a caveat. The README states that the STFT layer is not TFLite compatible, because of tf.signal.stft. To make a TFLite compatible model you train with the normal Kapre layers first, then build a second model that replaces STFT and Magnitude with STFTTflite and MagnitudeTflite:
from kapre import STFTTflite, MagnitudeTflite
model_tflite = Sequential()
model_tflite.add(Input(shape=input_shape))
model_tflite.add(STFTTflite(n_fft=2048, win_length=2048, hop_length=1024,
window_name=None, pad_end=False,
input_data_format='channels_last', output_data_format='channels_last'))
model_tflite.add(MagnitudeTflite())
model_tflite.add(MagnitudeToDecibel())The weights are then transferred with set_weights, so the training work is not repeated. But the TFLite compatible layers are restricted to a batch size of 1, which prevents using them during training. That restriction is why the two-model dance is necessary, and it also means the deployed graph is not the graph you trained. A team that needs a single artefact for both training and on-device inference has to accept that this library does not provide it.
Keras is pinned below 3.14 for a specific TFLite reason
The dependency bounds in setup.py are worth reading closely, because they are not the usual floating ranges. The install requirements ask for numpy between 1.26.0 and 3.0.0, librosa between 0.11.0 and 1.0.0, keras between 3.0.0 and 3.14.0, and tensorflow between 2.16.0 and 2.21.0. The keras ceiling carries a comment explaining that Keras 3.14.x currently breaks TensorFlow 2.20 TFLite conversion on Python 3.12 and later.
So the upper bound on Keras is a workaround for a specific conversion bug, and it is documented in the file itself. The cost of that workaround is that a project already on a newer Keras cannot install this release without pinning backwards, and the pin is only justified if you care about TFLite. If your deployment target is a server GPU or CPU, the constraint is inheritance rather than need.
The package also declares python_requires of 3.9 or newer, and the README describes the project as tested on Python 3.9 and later with TensorFlow 2.16 through 2.20. The version number itself is not written in setup.py. It is read out of kapre/__init__.py with a regular expression, and the build fails loudly with a RuntimeError if that string is missing, which is a small but sensible piece of build hygiene.
Type hints, two type checkers, and black with a 100 character line
Kapre carries type hints throughout, and the repository is set up for checking them with either of the two usual tools. The bundled script is the shortest path:
python scripts/check_types.pyOr you can point your own checker at the package directory, with mypy or with pyright, after installing it. For contributors, the development setup is a single editable install with the dev extra, followed by the test suite, the type check, black and flake8:
pip install -e ".[dev]"
pytest tests/
python scripts/check_types.py
black kapre/ tests/
flake8 kapre/ tests/The dev extra pins black 24.0 or newer, flake8 7.0 or newer, mypy 1.8 or newer, pyright 1.1 or newer and pytest 8.0 or newer, and a separate docs extra carries Sphinx and the read the docs theme. The formatting configuration in pyproject.toml sets a line length of 100, targets py39 and skips string normalization, with a long exclude list for build and cache directories. A mypy.ini and a pyrightconfig.json at the root keep the two checkers in agreement, which is the kind of detail that shows the project treats typing as part of the public contract rather than an afterthought.
Releases came in a burst, and the licence is plain MIT
The version history is uneven. Kapre 0.3.7 was published on 2022-01-21, then nothing for nearly four years, then Kapre 0.4.0 on 2025-10-13 and Kapre 0.4.1 on 2026-05-17. The repository is not archived and the last push was on 2026-05-17, the same day as the newest release, so the current line is being worked on rather than abandoned.
The licence is MIT, declared in setup.py and matched by a LICENSE.txt file in the repository root, which is about as permissive as a dependency gets and about as little as you need to read. MIT is not copyleft, though redistributing the library still means keeping its copyright and permission notice.
Two administrative details are worth noticing in the tree. A tox.ini sits alongside the per-tool configuration, and a srcs/ directory exists next to the kapre package, which suggests build files or extra sources kept separately from the importable package. A LLM-TODO.md file at the root also stands out: it is the project's own list of tasks, and its presence tells you the maintainer is thinking about how tooling such as language models fits into the work.
Editorial conclusion
Adopt Kapre when you train audio models in TensorFlow Keras and want the DSP parameters inside the graph so a hyperparameter sweep can vary n_fft and a deployed model needs only the sampling rate. Do not adopt it if you need TFLite inference on the same graph, since the standard STFT layer does not convert and the TFLite variants cannot train beyond batch size 1. Verify first that your environment satisfies the setup.py bounds, keras below 3.14 and tensorflow below 2.21, and that the librosa comparison tests in tests/ pass against your NumPy version.
Frequently asked questions
How do I install Kapre for a Keras audio model?
The documented install is pip install kapre, and setup.py requires Python 3.9 or newer. The declared dependencies are numpy 1.26.0 or newer below 3.0.0, librosa 0.11.0 or newer below 1.0.0, keras 3.0.0 or newer below 3.14.0, and tensorflow 2.16.0 or newer below 2.21.0.
Is the Kapre STFT layer compatible with TFLite?
No, the README states the STFT layer is not TFLite compatible because of tf.signal.stft. You train with the normal layers and then build a second model using STFTTflite and MagnitudeTflite, and those layers are limited to a batch size of 1.
Why is the keras version capped below 3.14 in Kapre?
The comment in setup.py states that Keras 3.14.x currently breaks TensorFlow 2.20 TFLite conversion on Python 3.12 and later, so the upper bound on the keras requirement is a workaround for that conversion issue.
What is the advantage of Kapre over pre-computing spectrograms?
Because the transform runs inside the model, DSP parameters such as n_fft can be included in a hyperparameter search, and a deployed model only needs the sampling rate of the signal rather than a separate preprocessing step.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/keunwoochoi-kapre)Was this useful?