deepjazz: a two-layer LSTM that turns one MIDI file into jazz, with a hackathon-sized scope
Deep learning driven jazz generation using Keras & Theano!
At a glance
- What is it?
- deepjazz is a Python project that trains a two-layer LSTM on a single MIDI file and writes out new jazz. It is small, archived in spirit if not in name, and pinned to a Keras and Theano stack that most teams no longer run.
- Who is it for?
- Adopt deepjazz if you want a readable, small-scale example of sequence modelling over symbolic music and you accept that you will be editing preprocess.py by hand for any MIDI file other than the bundled one, on a Keras and Theano stack the project itself no longer develops. Do not adopt it as a production music service or as a general MIDI-to-jazz tool: the README states the melody part must be selected manually and that native handling is only a planned feature.
- Can I use it commercially?
- Yes. Apache-2.0 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?
- Activity is slowing. The repository last received commits 6 months 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 September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What deepjazz actually does, and the one input it expects
deepjazz generates jazz music from a MIDI file. The README describes it as a two-layer LSTM that learns from a given MIDI file, and the author states it was built in 36 hours at a hackathon. That origin explains the shape of the tool: one input file, one model definition, one output. It is not a library you import into a larger pipeline, and it is not a service. It is a script that reads a MIDI file, trains a network on it, and produces music.
The audience is narrow in a useful way. If you want to see how a recurrent network handles symbolic music, where the input is note events rather than audio samples, deepjazz is small enough to read end to end. If you want a tool that accepts arbitrary MIDI uploads and returns jazz, it is not that, and the README says so indirectly: preprocess.py must be modified to work with other MIDI files, because the relevant melody part has to be selected. The bundled workflow is tuned to one file. Everything else is manual work.
That constraint is the single most important fact about the project. It determines who can use it without touching code (almost nobody) and who will spend their first hour reading preprocess.py rather than running the generator.
The architecture: two LSTM layers, one MIDI file, a Theano backend
The README states the model is a two-layer LSTM built with Keras on Theano. The data flow implied by the repository layout is preprocessing, training, generation. preprocess.py reads a MIDI file and extracts the note sequences the network will learn from. generator.py builds the model, trains it for the number of epochs you pass on the command line, and produces output. The README points to the DeepLearning.net LSTM tutorial as the reference for the architecture, which suggests a standard sequence model rather than a custom cell design.
The dependency list is short and specific: Keras, Theano, and music21. music21 is the piece that handles symbolic music, which is why the melody part selection lives in preprocessing rather than in the model. The network never sees audio. It sees whatever representation preprocess.py extracts, and that representation is the real design decision in the project. The README does not document the encoding in detail, so if you need to know exactly how notes map to vectors, you will be reading the source.
The Theano requirement is the part that has aged worst. The README asks for the bleeding-edge version from GitHub, not a released package. That instruction was written when Theano was the default Keras backend. Keras has since moved on, and Theano's own maintenance status has changed. The README does not address any of this, and the project's opening note says it is no longer actively developed. Anyone running deepjazz today is running it against a dependency graph the author stopped updating.
Running it: two commands and one file you will have to edit
The README gives two commands. On CPU:
python generator.py [# of epochs]
On GPU:
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python generator.py [# of epochs]
The GPU path is a Theano configuration string rather than a project flag, which tells you where the hardware abstraction lives. The README notes that GPU use is formally supported only for NVIDIA cards through the CUDA backend. There is no config file, no environment file, and no CLI beyond the epoch count. If you want to change the model or the input, you edit Python.
The edit you will almost certainly make is in preprocess.py. The README is explicit: it must be modified to work with other MIDI files because the relevant melody part needs to be selected, and native handling of that selection is described as a planned feature. That planned feature does not exist in the material provided, and the project is no longer actively developed, so treat the manual edit as permanent rather than temporary.
There is no installation section beyond the three dependency links. No requirements.txt is mentioned in the README, no pinned versions, no virtual environment instructions. Reproducing the original environment means reconstructing it from three links, one of which asks for a bleeding-edge build.
Where deepjazz breaks: one file, one melody, no native MIDI handling
The failure mode is stated plainly in the README rather than discovered in an issue tracker. Feed deepjazz a MIDI file with multiple parts and it will not know which one is the melody. You have to open preprocess.py and select it yourself. For a solo piano MIDI, that is trivial. For an ensemble arrangement, a multi-track file, or anything where the melodic line moves between instruments, it is a real piece of work, and the project gives you no tooling for it.
A second limitation follows from the first. Because the model learns from one MIDI file, the output is shaped by that file's vocabulary. The README frames the project as learning from the given MIDI file, singular. There is no documented path for training across a corpus, and no pretrained weights mentioned. If you want a model that has absorbed a broad jazz idiom, this is the wrong starting point.
The dependency stack is the third constraint. Theano's bleeding-edge install is not a stable target, and the README's own note says the project is no longer actively developed and may be refactored at some point in the future. That sentence is a maintenance warning, not a roadmap. Combined with the manual preprocessing, it means deepjazz is best treated as a fixed artifact: get it working once, read it, and expect the installation to be the hardest part.
jazzml and the difference between a notebook and a pipeline
The README credits Evan Chow's jazzml for much of the preprocessing code, used with permission. That is the closest thing to a sibling project in the material, and the relationship is worth understanding because it clarifies what deepjazz is. deepjazz borrows the music parsing and then wraps a Keras LSTM around it. jazzml is the source of the preprocessing approach, not a competing generator in this description.
The practical difference is scope. deepjazz is a single script with a hardcoded target: one MIDI file, one melody part, one training run. The preprocessing it inherits is general enough to be reused, which is why the author could build the project in 36 hours. But the reuse stops at the model boundary. If you need to handle many MIDI files, the preprocessing layer is the part you would extend, and the README's note that native multi-file handling is only planned tells you deepjazz never made that extension.
For a team choosing between the two approaches, the question is whether you want a runnable example or a preprocessing foundation. deepjazz gives you the former and inherits the latter. Neither is documented here as a maintained product, so the decision is about reading code, not about support contracts.
Licence, media rights and the cost of keeping it alive
The code is Apache-2.0. That is a permissive licence with a patent grant and a requirement to preserve notices and state changes, which matters if you modify preprocess.py and redistribute. The README draws a line that is easy to miss: images and other media are copyrighted by Ji-Sung Kim and are not covered by the code licence. If you fork deepjazz and reuse the logo or any media assets, the Apache-2.0 grant does not apply to them. This is a description of the licence text and the README's own statement, not legal advice; check the terms yourself if you plan to redistribute.
Maintenance cost is the harder number. There are no releases retrieved for this repository, and the README opens by saying the project is no longer actively developed. That means no upgrade path, no compatibility work for newer Keras or Theano, and no fixes for the dependency install. The cost of adopting deepjazz is not a subscription or a support contract. It is the hours you spend reconstructing a 2016-era Python environment and the ongoing risk that the bleeding-edge Theano build you install today is not the one the code was written against.
If you pin your environment once and treat the project as frozen, that cost is bounded. If you expect it to track upstream Keras, it will not, and the README says as much.
Who should run deepjazz, and what to check before you do
Run it if you are studying sequence models over symbolic music and you want a codebase small enough to read in an afternoon. The two-layer LSTM, the music21 preprocessing, and the two-command interface make the whole pipeline visible. The README's citation of the DeepLearning.net LSTM tutorial gives you the architectural reference, and the preprocessing is credited to jazzml, so you can trace where each piece came from.
Do not run it if you need multi-file MIDI ingestion, a maintained dependency stack, or a model trained on a broad corpus. The README states that preprocess.py must be edited per file and that native handling is only planned. The project is not actively developed. Those two sentences together rule out production use.
Before you invest time, verify the environment in this order. First, confirm you can install the Theano bleeding-edge build the README points to on your Python version; if that fails, nothing else matters. Second, install music21 and confirm it parses your target MIDI file. Third, open preprocess.py and locate the part-selection logic, then check whether your file's melody part is identifiable without rewriting that logic. If all three pass, the CPU command python generator.py [# of epochs] is your entry point. If the third one fails, you are not running deepjazz, you are extending it, and the README gives you no guidance for that.
Editorial conclusion
Adopt deepjazz if you want a readable, small-scale example of sequence modelling over symbolic music and you accept that you will be editing preprocess.py by hand for any MIDI file other than the bundled one, on a Keras and Theano stack the project itself no longer develops. Do not adopt it as a production music service or as a general MIDI-to-jazz tool: the README states the melody part must be selected manually and that native handling is only a planned feature. Before you commit, verify three things in your own checkout: that you can install the Theano bleeding-edge build on your Python version, that you can install music21, and that preprocess.py parses your specific MIDI file without hand-editing the part selection. If any of those three fails, the project stops at the first step.
Community notes