FLUX.1, Stable Diffusion 3, and Stable Video Diffusion all secretly run on flow matching — a continuous normalizing flow trained with a new objective. Understand classical normalizing flows and you've already solved half the math behind 2025's best image and video models.
Learning Objectives
After this lesson, you will be able to:
Apply the change-of-variables formula to compute exact likelihoods through any invertible transformation, and understand why generative modeling can be reframed as 'find a bijection from noise to data'
Build coupling layers (NICE/RealNVP) that are simultaneously invertible AND have a triangular Jacobian whose determinant is a single multiplication — the trick that makes flows tractable
Compare normalizing flows against VAEs, GANs, and diffusion: when exact likelihood matters, flows win; when sample quality matters at the same parameter count, diffusion wins
Recognize Continuous Normalizing Flows (Neural ODEs) as the bridge from discrete-step flows to Flow Matching — the same ODE framing, different training objective
Don't worry if "invertible neural network" sounds like an oxymoron -- once you see the coupling-layer trick, the whole field clicks. NFs are the most mathematically clean of the generative families, and they reward the effort to understand them.
A normalizing flow defines a bijection f: ℝ^d → ℝ^d between a simple base distribution z ~ p_Z (typically Gaussian) and the data distribution x = f(z). The whole machinery hangs on one piece of math from undergraduate probability: the change of variables formula.
If x = f(z) and f is invertible with differentiable inverse, then:
pX(x)=pZ(f−1(x))⋅det∂x∂f−1
Take logs to make it computable in practice and to compose multiple layers cleanly:
logpX(x)=logpZ(f−1(x))+logdet∂x∂f−1
The whole training objective is one line: maximize log-likelihood. No discriminator, no KL term to balance, no noise schedule to tune. The catch: that determinant.
Watch an invertible map bend a Gaussian into the data distribution while the change-of-variables formula tracks the density.
For a generic neural network with L layers and dimension d, computing det(J) is O(d³) per layer — cubic in the data dimension. For a 32×32 RGB image, d = 3072 → ~3 billion operations per layer per sample per training step. Computationally hopeless.
The entire art of designing normalizing flows comes down to: how do we build neural networks that are simultaneously invertible AND have a tractable Jacobian determinant?
The breakthrough came from Dinh et al. 2014 (NICE) and 2017 (RealNVP): split the input vector into two halves and only transform one of them.
The specific transform RealNVP uses on the moving half is affine coupling:
yAyB=xA=xB⊙exp(s(xA))+t(xA)
The functions s and t can be arbitrary neural networks of arbitrary depth — they don't have to be invertible themselves, because we only ever use them to compute parameters for the coupling, never to invert anything.
Stack L coupling layers (alternating which half is the "passive" one each time): x = z_0 → z_1 → ... → z_L = y. By the chain rule of determinants, the total log-determinant is just the sum of the per-layer log-determinants:
Glow (Kingma & Dhariwal 2018) added two key tricks that pushed flows to photorealistic faces:
Invertible 1×1 convolutions — replace the fixed half-split with a learned linear shuffle. The 1×1 conv weight matrix W is ~h×h (small, e.g. 64×64), so its determinant is computable in O(h³) but h³ is tiny per channel. This lets the model learn which dimensions to entangle in each layer rather than relying on a hardcoded split.
Multi-scale architecture — periodically halve the spatial resolution by factoring out half the dimensions and routing them straight to the output. This dramatically reduces compute per layer at high resolutions and matches the way images carry information across scales.
What Do You Think?
You stack 8 affine coupling layers but use the SAME mask pattern (top-half passive, bottom-half active) on every layer. What goes wrong?
The top half of the input passes through unchanged in every single layer, so the network can never modify it. RealNVP and Glow alternate the mask pattern (e.g., top-passive on odd layers, bottom-passive on even layers), or — in Glow — replace the fixed split with a learned 1×1 conv shuffle so every dimension gets its turn in motion.
The discrete-step flow z_0 → z_1 → ... → z_L can be taken to a continuous limit. Imagine infinitely many infinitesimal layers, each making a tiny change. The whole flow becomes the solution of an ordinary differential equation:
z(T)=z(0)+∫0Tfθ(z(t),t)dt
This is the Neural ODE framework (Chen et al. 2018). It became the foundation for Flow Matching (next track lesson 8): instead of training the flow by maximizing likelihood (which requires expensive Jacobian estimation), Flow Matching trains the vector field f_θ via a regression loss against a known target velocity field — O(1) cost per training step.
Each conditional is a learned transform of a Gaussian. The Jacobian is triangular by construction (later dimensions depend only on earlier ones), so the determinant is again the product of diagonal entries.
The tradeoff: autoregressive flows are fast in one direction and slow (O(d) sequential steps) in the other. MAF (Masked Autoregressive Flow, Papamakarios 2017) is fast for density estimation but slow for sampling. IAF (Inverse Autoregressive Flow, Kingma 2016) is fast for sampling but slow for density estimation. You pick which direction matters.
Coupling flows are the compromise: O(L) cost in both directions.
Tests · Verify samples lie roughly on the two-moons distribution. Verify the exact reconstruction error is at floating-point noise level (~1e-7), proving the bijection is mathematically tight.
Actnorm — a per-channel affine transform initialized so the first batch has zero mean and unit variance. Replaces BatchNorm (which isn't invertible across batches).
Invertible 1x1 conv — a learned channel-mixing matrix. The determinant is computable in O(c³) where c is the channel count (small).
Affine coupling — same RealNVP coupling, but the s and t networks are convolutional.
Three of these stacked = one "step of flow." Stack 32 steps per scale, halve resolution between scales (multi-scale architecture), and you have Glow's 60M-parameter flow that produces 256x256 face samples with exact log-likelihoods.
By 2022, flows had been overtaken on image quality by diffusion models. The reason isn't fundamental — it's that:
Diffusion scales gracefully: bigger models, more compute, more steps → linearly better samples. Flows hit a quality ceiling per parameter because the architecture must remain invertible.
Diffusion trains on a simple regression loss (predict noise). Flows train on direct log-likelihood, which is theoretically the right objective but harder to optimize at scale.
But flows still dominate where exact likelihood matters:
Physics simulation (lattice QCD, statistical mechanics) — you need exact ratios of probabilities for Markov-chain Monte Carlo
Anomaly detection. Exact log-likelihood gives a meaningful "weirdness" score
Variational inference for Bayesian models. Flows parameterize approximate posteriors that you can score and sample from
And the conceptual descendant of flows — Continuous Normalizing Flows — became the architectural foundation for Flow Matching, which by 2024 was beating pure diffusion on speed and quality in models like FLUX, SD3, and Stable Video Diffusion.
The change-of-variables formula reduces generative modeling to designing invertible neural networks — log p(x) = log p(z) + log|det J|, where J is the Jacobian of the transform; if you can build invertible networks with tractable Jacobians, you have a generative model with exact likelihood and exact sampling
Coupling layers solve the determinant problem. Split the input, freeze one half, transform the other half conditioned on the frozen half; the resulting Jacobian is triangular, so the determinant is just the product of the scale factors — O(d) instead of O(d³)
Stack many alternating coupling layers, then add 1x1 convs and multi-scale routing for production quality — RealNVP, Glow, and the autoregressive variants are all variations on this theme; the trick is making the architecture rich enough to model real data while keeping every layer invertible
Continuous Normalizing Flows reframe stacked layers as an ODE. Z(T) = z(0) + integral of f_theta from 0 to T; this is the conceptual ancestor of Flow Matching and the modern image/video models built on it
Flows lost the image-generation race to diffusion at large scale, but stayed crucial for exact-likelihood applications — physics, chemistry, Bayesian inference, lossless compression, and as a foundation for Flow Matching, which is now state-of-the-art in 2026
Why do affine coupling layers (RealNVP) have a tractable Jacobian determinant?
Normalizing flows are the most mathematically pristine of the generative families — exact likelihood, exact sampling, exact inversion, all from one network. Next up: Score-Based Models, which take the ODE viewpoint of CNFs and lift it to a stochastic differential equation, unifying everything we've seen so far with diffusion.