generative_continuous / 06 · FM sampling lesson 6 / 15

Flow matching — Euler sampling

A trained vθ gives you an ODE. Solve it. The step count is the whole story.

The ODE

A trained velocity field defines an ordinary differential equation: the trajectory of a particle that starts at x0 ∼ N(0, I) and rides the field. The IVP is

dx/dt = vθ(x, t),   x(0) = x0 ∼ N(0, I),   t ∈ [0, 1].

By construction (lesson 5), the resulting x(1) is a sample from pdata. To produce a batch of samples, integrate one ODE per sample — in batched matrix form, that’s one tensor of shape (N, D) updated in lockstep.

Forward Euler — the simplest integrator

Forward Euler turns the ODE into one update line:

xt + dt = xt + dt · vθ(xt, t),   dt = 1 / K.

For K steps total, that’s K evaluations of vθ. FlowMatching.sample:

x = randn(n, *shape)
dt = 1.0 / steps
for k in range(steps):
    t = full((n,), k * dt)
    x = x + dt * self.model(x, t)
return x

Three lines. This is the payoff for the design effort — the sampler is trivial because the path is straight.

Forward Euler error, in one line
Per-step error is O(dt2) (Taylor expansion: x(t+dt) = x(t) + dt · ẋ + dt2/2 · ẍ + …). Global error is O(dt) = O(1/K). So halving K doubles the error.

Why few steps suffice (for FM specifically)

Forward Euler hops off the true trajectory if the trajectory is curved. The size of that off-path drift depends on the second derivative ẍ = ∂tv + v · ∇xv — the curvature of the integral curves.

For the linear path, each conditional trajectory is exactly a line, so the conditional curvature is zero. The marginal trajectories (the curves you actually integrate at test time) have small curvature inherited from this. Empirically:

SolverSteps (typical)FID on CIFAR-10 (Lipman 2023)
FM Euler20–50< 5
FM RK410< 5
DDPM ancestral1000< 5
DDIM50–100< 5 with caveats

Roughly: same quality, ~20× fewer network calls.

Interactive · Euler on a learnable toy velocity field

The widget below trains a tiny MLP vθ on the two moons (50 seconds in JS), then integrates with Euler at K steps. Watch what happens at K = 2, 5, 50. With a straight path you see usable two moons even at K = 5.

Train v_θ in your browser, then integrate
Tiny MLP, trained on the two moons via the CFM loss. Hit train once; then explore K. Compare with the DDPM ancestral widget in lesson 4 — both reach the same destination, FM with far fewer net calls.
training step
0
loss (EMA)
samples drawn
0
solver order
1

3D · trajectories of your trained model

The widget above renders only the final samples. Here’s what the integrator is actually doing: 30 particles followed step by step through (x, y, t) space, with t as the third axis. Train the model in the widget above, then come here and hit render — straight-ish lines from a Gaussian cloud at t = 0 to the two moons at t = 1. The straighter the lines, the fewer integration steps needed.

FM trajectories in (x, y, t) with the trained v_θ
Compare to lesson 4’s DDPM bundle: those curves bow toward the origin then spread (variance-preserving curvature); these go essentially straight (linear path).

RK4 in one line

If you want lower error per step at the cost of more network calls, use a higher-order Runge-Kutta. RK4 evaluates vθ four times per step:

k1 = v(x,            t)
k2 = v(x + dt/2 * k1, t + dt/2)
k3 = v(x + dt/2 * k2, t + dt/2)
k4 = v(x + dt   * k3, t + dt)
x  = x + dt/6 * (k1 + 2*k2 + 2*k3 + k4)

Global error: O(dt4). Quality gain isn’t free — 4× the compute — but for the same total budget you often want fewer-but-better steps. The widget above lets you switch.

The bigger picture: when to pick what

Solver heuristics
SituationRecommended solverWhy
Straight linear-path FM, tight compute budgetEuler with K=20-50cheap, paths are mostly straight
Curved path (VP-like), few-step budgetRK4 or DPM-Solver++amortize the per-step error
Reproducibility / deterministic latentsRK4 (any FM solver is deterministic)same x₀ ⇒ same x₁; useful for latent editing
Want stochasticity in samplesDDPM ancestral or SDE-flavored solverdiversity from the inner Gaussian, not from the integrator

Common gotchas

Punchline
Sampling is one for-loop. The cost (K forward passes) scales linearly with desired quality. Linear-path FM gives you the best constant on that scaling. Higher-order solvers buy you more per step at the cost of more per step — the right trade depends on the network cost vs. desired quality.