Flow-Based Generative Models · UFRJ · 2026.2
\[ \frac{\mathrm{d}x}{\mathrm{d}t} \;=\; u_t(x) , \qquad x(0) = x_0 \sim \mathcal{N}(0, I_d) \]
Draw noise at \(t=0\). Follow the field. Whatever you reach at \(t=1\) is your sample.
The network is the right-hand side. Today is about everything to the left of the equals sign.
NFE = number of function evaluations: how many times a solver calls \(f\) while integrating.
\[ \text{cost of one sample} \;=\; \text{NFE} \times (\text{one forward pass}) \]
Every evaluation of \(u_t^\theta\) is a forward pass through a neural network.
By December you will discuss papers whose entire contribution is reducing NFE.
\[ \frac{\mathrm{d}x}{\mathrm{d}t} = f(t, x(t)) , \qquad x(t_0) = x_0 \]
Right-hand sides are f(t, x) — time first. Every solver returns its NFE.
Existence and uniqueness need \(f\) Lipschitz in \(x\) — that is Picard–Lindelöf, stated properly in U2.T1.
At \(x_n\) the equation gives you the velocity. Pretend it holds for a time \(h\).
\[ x_{n+1} = x_n + h \, f(t_n, x_n) \qquad \textbf{1 NFE per step} \]
A polygon inscribed in a curve.
The error of one step, started from the exact point: \[ \tau_{n+1} = x(t_{n+1}) - \bigl[\, x(t_n) + h f(t_n, x(t_n)) \,\bigr] \]
The error that actually reaches you, after all \(N\) steps: \[ e_N = x(t_N) - x_N \]
Order \(p\): local \(O(h^{p+1})\), global \(O(h^{p})\). One power is lost to accumulation.
Taylor-expand the exact solution about \(t_n\):
\[ x(t_{n+1}) = x(t_n) + h \, \dot{x}(t_n) + \frac{h^2}{2}\ddot{x}(\xi) \]
The ODE says \(\dot{x}(t_n) = f(t_n, x(t_n))\) — the first two terms are the Euler step.
\[ \Longrightarrow \quad \tau_{n+1} = \frac{h^2}{2}\,\ddot{x}(\xi) \;=\; O(h^2) \]
Let \(e_n = x(t_n) - x_n\). Subtract the two updates and take norms:
\[ \|e_{n+1}\| \;\le\; (1 + hL)\,\|e_n\| \;+\; \tfrac{1}{2} M h^2 \]
\(L\) = Lipschitz constant of \(f\) in \(x\). Unroll from \(e_0 = 0\):
\[ \|e_N\| \;\le\; \frac{Mh}{2L}\Bigl[\, e^{L(t_1 - t_0)} - 1 \,\Bigr] \;=\; O(h) \]
Read the constant: it grows like \(e^{L(t_1-t_0)}\). Order 1 is a statement about a slope, not a promise of a small number.
Explicit Euler on the harmonic oscillator, \(h = 2\pi/40\). Left: three periods in the phase plane — the exact orbit is the unit circle; Euler ends at radius \(4.32\). Right: energy against time.
\[ E_{n+1} = \tfrac12\bigl[(x_n + hv_n)^2 + (v_n - hx_n)^2\bigr] = (1 + h^2)\,E_n \quad \textbf{exactly} \]
Euler uses the velocity at the start for the whole step. Average the two ends instead — and guess the far end with Euler.
\[ \begin{aligned} k_1 &= f(t_n, x_n) , \qquad k_2 = f(t_n + h, \; x_n + h k_1) \\ x_{n+1} &= x_n + \tfrac{h}{2}(k_1 + k_2) \qquad \textbf{2 NFE per step, order 2} \end{aligned} \]
The first NFE-vs-accuracy trade of the course: one extra evaluation, one extra order.
\[ \begin{aligned} k_1 &= f(t_n, \, x_n) , &\quad k_2 &= f(t_n + \tfrac{h}{2}, \; x_n + \tfrac{h}{2}k_1) , \\ k_3 &= f(t_n + \tfrac{h}{2}, \; x_n + \tfrac{h}{2}k_2) , &\quad k_4 &= f(t_n + h, \; x_n + h k_3) , \\ x_{n+1} &= x_n + \tfrac{h}{6}\bigl(k_1 + 2k_2 + 2k_3 + k_4\bigr) . & &\textbf{4 NFE, order 4} \end{aligned} \]
The weights \(\tfrac16, \tfrac26, \tfrac26, \tfrac16\) are Simpson’s rule — and for an \(f\) that does not depend on \(x\), RK4 is Simpson’s rule.
The idea, in one sentence: sample the field at trial points inside the step, then combine the samples with fixed weights so the Taylor terms cancel.
The coefficients live in a Butcher tableau. The theory of which tableaux reach which order is deep, well developed, and explicitly declined here.
We are consumers of tableaux, not designers of them.
You need three methods and three words: stage, order, embedded pair.
| Method | NFE / step | Order \(p\) | Global error |
|---|---|---|---|
| Euler | 1 | 1 | \(O(h)\) |
| Heun | 2 | 2 | \(O(h^2)\) |
| RK4 | 4 | 4 | \(O(h^4)\) |
Order alone settles nothing: an RK4 step costs four Euler steps.
The honest axis is NFE, not step count.
Global error at \(t = 2\pi\). Left: against step size, log-log — fitted slopes \(1.01\), \(2.00\), \(4.00\). Right: the same errors against NFE, the honest cost axis.
NFE to reach a global error of \(10^{-6}\): Euler \(1.9\times10^{7}\) · Heun \(1.3\times10^{4}\) · RK4 \(3.8\times10^{2}\)
The names on this slide come back as the names of samplers.
“Euler sampling” in a diffusion or Flow Matching paper means exactly \(x_{n+1} = x_n + h\,u_{t_n}^\theta(x_n)\). The EDM sampler is a Heun variant.
When U3.T3 discusses them, you will recognise old friends — and you will already know their NFE per step.
A trajectory can be almost straight for most of its length and turn sharply in one short window.
So let the solver choose \(h\) as it goes — which means it must estimate its own error, without knowing the answer.
Heun already computes \(k_1\) and \(k_2\). But \(k_1\) alone is the Euler step:
\[ \hat{x}_{n+1} = x_n + h k_1 \;\; (\text{order }1) , \qquad x_{n+1} = x_n + \tfrac{h}{2}(k_1 + k_2) \;\; (\text{order }2) \]
\[ \varepsilon_{n+1} = \bigl\| x_{n+1} - \hat{x}_{n+1} \bigr\| \;=\; \text{local error estimate} \]
Written Heun(2)/Euler(1). Propagate the higher order — you paid for it.
rtol and atol actually mean\[ \mathrm{sc}_i = \texttt{atol} + \texttt{rtol}\cdot\max\bigl(|x_{n,i}|,\,|x_{n+1,i}|\bigr) , \qquad \mathrm{err} = \sqrt{\frac{1}{d}\sum_i \Bigl(\frac{\varepsilon_{n+1,i}}{\mathrm{sc}_i}\Bigr)^{\!2}} \] Accept the step when \(\mathrm{err} \le 1\). Otherwise throw it away and retry smaller.
rtol dominates where \(x\) is large — it asks for significant digits.atol dominates where \(x\) is near zero — it says how small is “don’t care”.\[ h_{\text{new}} \;=\; h \cdot \min\Bigl( f_{\max} , \; \max\bigl( f_{\min} , \; \eta \cdot \mathrm{err}^{-1/(p+1)} \bigr) \Bigr) \]
A rejected step is the controller working, not failing. It still costs NFE.
Embedded Heun(2)/Euler(1), rtol \(=10^{-6}\), atol \(=10^{-8}\). Top: solution with every 27th accepted step endpoint marked. Bottom: step size against time, log scale, rejected attempts marked.
\(2513\) accepted, \(12\) rejected, NFE \(= 5050\); step size varies by a factor of \(46\) along one trajectory.
Fast, small NFE, a smooth plausible trajectory that is wrong. Nothing complains.
Test: halve both tolerances and re-run. If the answer moves, it was never converged.
NFE explodes; the extra digits are below the noise of everything else. You notice immediately.
RK45, also called Dormand–Prince: an embedded pair of orders 5 and 4, seven stages.
scipy.integrate.solve_ivpdopri5 in torchdiffeq and in diffraxYou now know what every one of its arguments means.
With an adaptive solver, NFE becomes data-dependent. In U2 you will watch it grow during training, and it will hurt. In U3 it stops hurting. Understanding why is the course.
Block B asked: how accurate is this as \(h \to 0\)?
Block E asks the question that decides whether a method is usable at all:
For a given \(h\), does the numerical solution stay bounded?
Test equation — a scalar problem, because a linear system diagonalises into copies of it:
\[ \frac{\mathrm{d}x}{\mathrm{d}t} = \lambda x , \quad \lambda \in \mathbb{C} , \qquad x(t) = x_0 e^{\lambda t} \]
Euler on the test equation:
\[ x_{n+1} = (1 + h\lambda)\,x_n \quad \Longrightarrow \quad x_n = (1+h\lambda)^n x_0 \]
\[ S = \bigl\{\, z = h\lambda \in \mathbb{C} \;:\; |R(z)| \le 1 \,\bigr\} \] Euler \(R(z) = 1+z\); Heun \(R(z) = 1 + z + \tfrac{z^2}{2}\); RK4 through \(\tfrac{z^4}{24}\).
\(S\) constrains the product \(h\lambda\) — so it is a ceiling on your step size.
Shaded = stable. Left: the explicit methods, all bounded; real-axis limits \(2.000\), \(2.000\), \(2.785\), located by bisection. Right: implicit Euler — everything outside a disk.
RK4 is \(10^3\times\) more accurate than Euler at a given \(h\), and its step ceiling is only \(39\%\) higher. Order and stability are different currencies.
The harmonic oscillator has eigenvalues \(\lambda = \pm i\) — purely imaginary.
The Euler region touches the imaginary axis only at the origin. So:
\[ |1 + ih| = \sqrt{1 + h^2} \; > \; 1 \quad \text{for every } h > 0 \]
No positive step size is stable for that problem. The energy law and the stability region are the same statement twice.
\[ x_{n+1} = x_n + h\,f(t_{n+1},\, x_{n+1}) \qquad \text{(unknown on both sides)} \]
\(R(z) = 1/(1-z)\) — the whole left half-plane is stable, at any step size.
That is bought, not given: each step solves an equation in \(x_{n+1}\), which for a nonlinear \(f\) means an iterative solve with Jacobians.
Our fields are expensive neural networks. The course world is explicit + adaptive; implicit solvers are named here and never implemented.
A problem is stiff when the step size is limited by stability rather than by accuracy — the solver is forced far below the step the answer needs.
Usual cause: a fast decaying mode that dies quickly, stops affecting the answer, and keeps dictating \(h\) long afterwards.
Not a property you read off an equation. A symptom you observe in a solver.
NFE to integrate a 2D linear system to \(t=1\) at rtol \(=10^{-4}\); slow mode fixed at \(-1\), fast mode swept to \(-10^{4}\). Each bar is annotated with the achieved error.
NFE grows \(58\times\). The error does not improve — it sits near \(10^{-5}\) throughout.
Are learned velocity fields stiff? It depends on the design, and this course answers it empirically, not by assertion:
A large part of recent progress in fast sampling is not better solvers. It is fields that are easier to integrate.
One cloud of initial conditions, transported by a single velocity field, at three times. Every point obeys the same ODE. Nobody moves the cloud as a whole — and yet the density changes shape.
The ODE moves a point. What moves the density?
\[ \partial_t \, p_t + \nabla\cdot\bigl(p_t \, u_t\bigr) = 0 \]
The continuity equation. Stated properly and derived in U2.T2. It becomes the foundation of everything in U3.T1.
Generative modelling in this course = choosing the density movie, and learning the field that plays it.
| From today | Reappears in |
|---|---|
f(t, x) time first; NFE returned |
every solver, from U0.L5 on |
| Euler, Heun, RK4 | U0.L5 (by hand); U3.T3 (as samplers) |
| Adaptive stepping, rtol/atol | U2.L1 (assumed); U2.L2 |
| Stability and stiffness | U2.L2; U3.T4 (straightness) |
| The continuity equation | U2.T2 (derived); U3.T1 |
The lecture notes for this session are written standalone-first: complete prose, self-explanatory figures, exercises with answers, everything runs on CPU.
They are the core of the self-study packet PESC students receive at enrollment — which makes them your best review document too.
Next session (U0.L5): implement all four solvers from scratch, each returning its NFE; make the log-log plot yourself; then the same toy ODE in JAX.