jmtomczak/intro_dgm: Reading Deep Generative Models One Notebook at a Time
"Deep Generative Modeling": Introductory Examples
At a glance
- What is it?
- The intro_dgm repository is a set of small PyTorch notebooks that accompany Jakub M. Tomczak's Deep Generative Modeling book. It is a teaching companion, not a library, and its value depends on whether you want to read model code line by line rather than call a trainer.
- Who is it for?
- Adopt intro_dgm if you are learning generative modelling and want to type through every line, or if you teach a course and need short runnable assignments. Do not adopt it if you need a maintained library with an API, tests or GPU-scale training.
- 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 140 days ago.
- What is it written in?
- Mainly Jupyter Notebook, 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 intro_dgm is, and what it deliberately is not
The repository is the code companion to the book Deep Generative Modeling by Jakub M. Tomczak, published by Springer Cham in 2024. The README states the intent plainly: the examples "might look oversimplistic but that's the point", and the goal is that a reader can follow every line and run the experiments "within a couple of minutes on almost any laptop or computer". That sentence sets the scope. There is no package to install, no model zoo, no training script that scales to a dataset you would actually ship. Each folder under the repository root holds a Jupyter notebook for one model family, and the model is small on purpose. The audience named in the README is students, engineers and researchers with undergraduate calculus, linear algebra, probability and some Python and PyTorch. If you already run diffusion training jobs and want a faster sampler, this is not the repository for you. If you have read about score matching three times and still cannot picture the loss, it is.
The eleven folders and the model families they cover
The README lists eleven example directories. mog covers a mixture of Gaussians with equiprobable components or trainable component probabilities. arms covers autoregressive models with a causal convolution layer in 1D and with transformers. flows covers RealNVP with coupling and permutation layers, plus Integer Discrete Flows. vaes contains three notebooks: a fully connected VAE with a standard Gaussian prior, a notebook on various priors, and a hierarchical VAE. ddgms has a diffusion model with Gaussian forward diffusion at fixed variance and an MLP-parameterized reverse process. sbgms has three: score matching with an MLP score model, an SDE-based diffusion model, and conditional flow matching. hybrid_modeling combines fully connected layers with IDFs. ebms is an energy-based model with an MLP. gans is a GAN with MLPs. neural_compression applies generative modelling to image compression. llms contains a decoder-only transformer the README calls teenyGPT. The spread matters more than the depth. You can read the same training loop shape eleven times and see where the objective changes, which is the comparison the book is built around.
How a notebook is put together
The material is Jupyter Notebook, so the architecture is visible in the cell order rather than hidden behind an abstraction. A typical notebook defines a small PyTorch module for the model, a sampling or decoding function, a loss computed from the model's own outputs, and a training loop that prints or plots progress. Because the MLPs are small and the data is low dimensional, the forward and reverse passes fit in memory on a laptop. The README's dependency list confirms the scale: pytorch 1.7.0, numpy 1.17.2, matplotlib 3.1.1, scikit-learn 0.21.3, pytorch-model-summary 0.1.1 and jupyter 1.0.0. pytorch-model-summary appears in that list because the notebooks print layer shapes, which is a teaching choice: you are meant to see the tensor dimensions change as data moves through the model. If you want a diagram of the architecture before reading code, the teaching/figures folder is where the README points teachers, and it is also the quickest way to decide whether a given notebook matches the model you have in mind.
Running one: clone, environment, open the notebook
The README does not give an installation command, and the repository has no setup.py or pyproject.toml in the material provided, so the workflow is manual. Clone the repository, create an environment, and install the pinned versions from the Requirements section. The keys to match are pytorch 1.7.0, numpy 1.17.2, matplotlib 3.1.1, scikit-learn 0.21.3, pytorch-model-summary 0.1.1 and jupyter 1.0.0. Then start Jupyter and open the notebook in the folder you want, for example the notebook under flows for RealNVP. There is no configuration file, no CLI, no environment variable to set. Everything is in the notebook cells, which means the run command is whatever you use to launch Jupyter, and the parameters you would otherwise pass as flags are variables you edit in a cell. That is convenient for a reader and inconvenient for anyone who wants reproducible sweeps. If you need to run the same model twenty times with different seeds, you are writing that loop yourself.
The pinned dependencies are the main practical obstacle
pytorch 1.7.0 and numpy 1.17.2 were current in 2020. Installing them today is possible but it is the part of this repository most likely to cost you an afternoon. NumPy 1.17 predates the removal of several aliases that later releases dropped, and PyTorch 1.7 predates API changes in optimizers, distributions and device handling. The README gives no compatibility statement beyond the version list, so I cannot tell you which notebooks still run unmodified on a current stack; that is something you have to check per notebook. Two options exist. Build an environment with the pinned versions and accept an old toolchain, or install a current PyTorch and fix the cells that break. The second path is arguably educational, since the failures are usually small and local, but it turns a five-minute experiment into a debugging session. Either way, do not expect the repository to track upstream releases: the last push to main is dated 2026-04-28, and there are no tagged releases in the material provided.
What it does not give you, and where a framework wins
The clearest alternative is a modelling framework such as PyTorch's own distributions and training utilities, or a dedicated generative library that exposes a trainer and a sampler. The difference in approach is structural. A framework gives you a stable interface, batching, checkpointing and device management, and you trade away the ability to see the loss written out in full. intro_dgm does the opposite: it shows the loss and nothing else. That trade is the whole product. If your task is to train a VAE on a real image dataset, use a framework, because you will need data loaders, augmentation, mixed precision and checkpointing, none of which the README mentions. If your task is to understand why the hierarchical VAE in the vaes folder differs from the fully connected one, the notebook is faster than reading a library's source. A second, softer alternative is the book itself, which the README asks you to cite if you use the code, with the BibTeX entry for Tomczak (2024). The notebooks are the code snippets referenced from the chapters, so reading them without the book loses the derivation that explains each loss term.
Teaching material, citation and the MIT licence
Two folders exist for instructors. teaching/assignments_examples holds three assignment examples, one for ARMs, one for VAEs, and one group assignment. teaching/figures holds lecture figures. The README asks that anyone reusing this material cite the book, and gives both an APA entry and a BibTeX entry for Tomczak, J. M. (2024), Deep Generative Modeling, Springer Cham. The repository itself is MIT licensed, which permits reuse and modification with the licence and copyright notice retained. The citation request is separate from the licence: MIT does not oblige you to cite the book, but the author asks for it, and for teaching material that is a reasonable ask to honour. I am not a lawyer and this is not legal advice; if you plan to ship the code inside a product, read the MIT text yourself and confirm how you want to handle the citation request. Note also that the notebooks are the companion to a commercial book, so the code being permissive does not make the book's text reusable.
Maintenance cost and who this is actually for
There is no release history, no continuous integration described in the README, and no dependency update policy. The maintenance cost therefore falls on you: you own the environment, and you own any cell that a newer PyTorch breaks. For a course, that cost is bounded, because you prepare the environment once per term and the students run the same notebooks. For an individual, the cost is one evening of setup and then near zero, since the models are small and there is nothing to keep patched. The judgement is straightforward. Use intro_dgm if you are learning, teaching, or refreshing a specific model family and want to read the objective function rather than call it. Skip it if you need a supported library, GPU-scale training, or an API with version guarantees. The first thing to verify is whether the notebook you plan to run still executes against your PyTorch version, and the second is whether the book chapter that explains it is on your desk, because the code alone shows the what and not the why.
Editorial conclusion
Adopt intro_dgm if you are learning generative modelling and want to type through every line, or if you teach a course and need short runnable assignments. Do not adopt it if you need a maintained library with an API, tests or GPU-scale training. Before using it, check the notebook you care about against the pinned versions in the README, because pytorch 1.7.0 and numpy 1.17.2 predate several changes in those libraries.
Community notes