Skip to content

21. Flow Matching

Diffusion works, and it is a strange way to have arrived at something that works. There is a stochastic differential equation, a variational bound, a noise schedule with a name, a discrete chain of a thousand steps, and three interchangeable parameterizations. The method is not complicated β€” the derivation is.

Flow matching1 arrives at the same place from the other direction and the setup fits in three lines. Draw a noise sample and a data sample. Draw the straight line between them. Train a network to predict the direction of travel at a random point on that line. That is the whole method.

\[ \mathcal{L}_{\text{CFM}} = \mathbb{E}_{t,\,x_0,\,x_1}\Big[\big\|v_\theta(x_t, t) - (x_1 - x_0)\big\|^2\Big], \qquad x_t = (1-t)\,x_0 + t\,x_1 \]

Here \(x_0 \sim \mathcal{N}(0, I)\) is the noise, \(x_1\) a sample of the data, \(t\) a time drawn uniformly in \([0, 1]\) and \(v_\theta\) the network, with weights \(\theta\). CFM stands for conditional flow matching, because the target \(x_1 - x_0\) is that of one drawn pair. Time runs from noise (\(t = 0\)) to data (\(t = 1\)), the opposite of chapter 20.

No schedule, no bound, no chain. And β€” this is the part worth being clear about β€” it is not a different family of model. Diffusion is flow matching with a curved interpolant. Once you see that, chapter 20 and this one collapse into one idea.

It is also not a historical curiosity. Since 2024 almost every open image and video generator whose training objective is published β€” Stable Diffusion 3, FLUX, Wan, HunyuanVideo, Qwen-Image β€” trains with exactly this loss, and so do speech models and the action heads of robot policies. Where it is used has the list, with dates.

Slides

Click the slides and use ← β†’ to move through them; F goes full screen and P opens the presenter view, with the notes. The three simulators of this page and three of its diagrams run inside the slides. Open the slides in a new tab


Moving particles

You have particles distributed as \(p_0 = \mathcal{N}(0, I)\). You want them distributed like your data, \(p_1\), by time \(t = 1\). Learn a velocity field \(v_\theta(x, t)\) that says which way each particle should move at each instant, and integrate.

\[ \frac{dx}{dt} = v_\theta(x, t), \qquad x_0 \sim p_0 \;\Longrightarrow\; x_1 \sim p_1 \]

The panel has the two pictures this chapter keeps comparing. Training pairs is what the loss above sees: each noise sample joined to an independently drawn data point by a straight line. The learned flow is what a network trained on those lines converges to, computed exactly here (the data are a mixture of small Gaussians, so nothing needs training). Animate both.

t = 0.00

There is an obvious problem with training this, and it is the one the whole field was stuck on. The velocity field you need is a marginal: at position \(x\) and time \(t\), it must average over every data point that could plausibly have produced \(x\),

\[ u_t(x) = \mathbb{E}\big[\,x_1 - x_0 \;\big|\; x_t = x\,\big]. \]

You cannot compute that for real data. You cannot even write it down.

The theorem that makes it work

You do not have to. Regressing the conditional velocity β€” the one for a single sampled pair \((x_0, x_1)\), which is just \(x_1 - x_0\) β€” has the same gradient as regressing the intractable marginal one1. So you train on a target you can write down in one line, and the network converges to the field you actually wanted.

This is exactly the move DDPM makes when it regresses \(\epsilon\) instead of the score \(\nabla_x \log p_t(x)\), the direction in which the density of \(x_t\) grows fastest. Same trick, stated once and in general instead of once per noise schedule.

The theorem is easiest to see at a single point. With two data points, exactly two training lines pass through each \((x, t)\), and everything can be computed by hand:

Two training lines pass through the same point x t at t = 0.25: one from the noise x0 = (1, 1) to B = (βˆ’2, 0), one from x0β€² = (βˆ’0.33, 1) to A = (2, 0). Their targets are (βˆ’3, βˆ’1) and (2.33, βˆ’1). Weighted by how likely each noise sample is, 0.39 and 0.61, they average to the marginal velocity (0.25, βˆ’1.00); the spread around it, 6.77, is the floor of the loss at this point. noise 𝒩(0, I) ut​ A = (2, 0)B = (βˆ’2, 0) x0​ x0​′ xt​ LINE TO B x0​ = (1, 1) target (βˆ’3, βˆ’1) weight 0.39 errorΒ² 10.56 LINE TO A x0​′ = (βˆ’0.33, 1) target (2.33, βˆ’1) weight 0.61 errorΒ² 4.34 t = 0.25xt​ = (0.25, 0.75) ut​(xt​) = 0.61Β·(2.33, βˆ’1) + 0.39Β·(βˆ’3, βˆ’1) = (0.25, βˆ’1) floor = 0.61 Β· 4.34 + 0.39 Β· 10.56 = 6.77 arrows: 0.5 Γ— velocity

Two consequences are visible in the particle panel and are worth stating, because both surprise people the first time:

  • The training loss does not go to zero. Many pairs pass near the same \((x, t)\) with different directions; the network can only output their average, and the spread around it is a floor. On the eight-Gaussian target of the lab the floor is 3.73 (computed exactly), and the trained network ends at 3.76, a few hundredths above it. A loss of 3.76 here is a model that has converged, not one that failed.
  • The learned paths cannot cross. An ODE has one velocity per point and time, so two particles never meet. The flow therefore re-pairs noise and data: each particle lands on the data, but not on the point it was paired with in training. In the panel the training pairs travel 1.23 on average and the flow 0.51.

The same two facts in the lab's code: one step of train_2d on three pairs in 2-D, then Euler sampling from the noise of pair 1. The network is replaced by the field it converges to, exact here because the data are two points, \(A = (2, 0)\) and \(B = (-2, 0)\). Pair 1 joins the noise \((1, 1)\) to \(B\): with the network already ideal it carries the whole loss, and the flow then takes that noise to \(A\). Change \(t\), the number of Euler steps or the case:

x0 Β· noise
x1 Β· data
t

● data A, B Β· ● x0 Β· ● xt Β· β†’ target Β· β†’ v Β· β€” Euler (arrows: 0.25 Γ— velocity)

Diffusion is a special case

Take any pair of functions \(a(t)\), \(b(t)\) and define the interpolant8

\[ x_t = a(t)\, x_1 + b(t)\, x_0 \]

Every method in this module is a choice of \(a\) and \(b\):

Method \(a(t)\) \(b(t)\) Path shape
DDPM / diffusion \(\sqrt{\bar\alpha_t}\) \(\sqrt{1 - \bar\alpha_t}\) Curved: \((b, a)\) on a quarter circle
Flow matching (OT path) \(t\) \(1 - t\) Straight, per pair
Rectified flow3 \(t\) \(1 - t\) Straight, and re-coupled

Here \(\bar\alpha_t\) is the noise schedule of chapter 20 read backwards, growing from 0 at the noise to 1 at the data. With the cosine schedule it is \(\bar\alpha_t = \sin^2(\pi t/2)\), so \(a = \sin(\pi t/2)\) and \(b = \cos(\pi t/2)\). OT stands for optimal transport, the name Lipman et al. give the straight path. One pair under both interpolants (pick \(t\)):

t =
The same noise–data pair under two interpolants. Left, the weights (b, a): flow matching moves along the straight line a + b = 1, diffusion along the quarter circle aΒ² + bΒ² = 1. Right, the pair in the plane: flow matching goes from x0 to x1 in a straight line at constant velocity x1 βˆ’ x0; diffusion follows a curve and its velocity aβ€²x1 + bβ€²x0 changes along the way. Buttons choose t. THE WEIGHTS: (b, a) 011 b: weight of the noise a: weight of the data a + b = 1 aΒ² + bΒ² = 1 ONE PAIR: xt​ = aΒ·x1​ + bΒ·x0​ 0 x0​ (noise) x1​ (data) arrows: 0.25 Γ— velocity flow matching: a = t, b = 1 βˆ’ t diffusion: a = sin(Ο€t/2), b = cos(Ο€t/2)

The conditional velocity is \(a'(t)x_1 + b'(t)x_0\) in every case, and the marginal is its conditional expectation. One framework, one loss, one code path. With a Gaussian \(p_0\) the two views are exactly interchangeable: a model trained one way can be sampled the other, and on the linear path the deterministic DDIM sampler is the Euler step of the flow9 (on other schedules it is an Euler step in rescaled variables). The remaining differences are the weighting of the loss across \(t\) and the shape of the trajectory β€” which is what the next panel measures.

What "straighter paths" actually means

The standard claim is that flow matching gives straight trajectories and therefore needs fewer integration steps. It is half true, and the half that is false is worth knowing.

Everything in that panel is exact β€” the target is a Gaussian mixture, so both interpolants' marginal velocities have closed forms and nothing is trained. Compare the two and:

  • The conditional path β€” the line between one noise sample and one data sample β€” is straight by construction with the linear interpolant.
  • The marginal path, which is what the model actually learns, is not. It has to average over every data point compatible with the current position, and independently paired noise and data cross each other constantly. On this target the linear-interpolant paths come out more curved than the diffusion ones: 111% longer than the straight line against 58%.
  • Neither interpolant wins at every step count (at 2 steps diffusion's endpoint error is lower, at 8 the linear one's), and past about 32 steps both are below anything you would see. The entire argument is about the few-step regime.

On real images the measurements are mixed, and the weighting of the loss across \(t\) matters as much as the path. Lipman et al. counted the evaluations an adaptive solver needs: 122–142 with the linear path against 183–193 with the diffusion path with the same architecture, on CIFAR-10 and ImageNet 32 and 641 β€” 22 to 37% fewer, not an order of magnitude. Esser et al. trained 61 formulations for Stable Diffusion 3: the rectified-flow variants were the best when sampling with few steps, but with a uniform \(t\) rectified flow ranked below the classic \(\epsilon\)-prediction overall, and only with logit-normal timestep sampling (below) did it come out first7. The lab trains both paths on MNIST with a uniform \(t\) and the same budget, and the cosine diffusion path wins at every step count (FD 94.0 against 133 at 8 Euler steps). FD is the recipe of FID, the FrΓ©chet distance between the features a network extracts from generated and from real images, with a digit classifier in place of the Inception network; lower is better.

Flow matching's real advantage is not the trajectory

It is the objective: a single regression with no schedule to tune and no choice between predicting \(\epsilon\) and \(\mathbf{v}\) (chapter 20) to get wrong at high noise. The Movie Gen team, who trained both, report flow matching as more robust to the choice of noise schedule and better than the diffusion losses they tried10. That, more than the step count, is why SD3, FLUX and the video models adopted it. The interpolant alone saves tens of percent of the steps; going from fifty steps to four or one takes reflow or distillation, which is the next section.

Rectified flow: straightening on purpose

If the paths are not straight, straighten them3. Reflow is two steps:

  1. Sample noise \(z\), integrate the trained ODE accurately, get \(x = \text{ODE}(z)\).
  2. Retrain the model on the pairs \((z, x)\) that it produced itself, on the straight line between them.

The marginal distribution of \(x\) is unchanged β€” you are not altering what the model generates, only which noise is paired with which output. And the new pairing is one the model can nearly realize with straight lines: the flow's paths do not meet, so the lines between their endpoints rarely cross, and a straight line is integrated exactly by one Euler step. The same steps with six noise samples and the two data points from before:

Six noise samples and two data points, A and B. Step 1: training joins each noise sample to a data point drawn at random by a straight line, and the lines cross. Step 2: the learned flow bends the paths so that they never meet; four of the six land on the other data point. Step 3: one Euler step on this flow sends every sample to the mean of the data, (0, 0). Step 4: reflow pairs each sample with where its own path ends, by a straight line. Step 5: after reflow, one Euler step lands on the data. noise 𝒩(0, I) mean of the data A = (2, 0)B = (βˆ’2, 0) hover a noise sample noise sample zdata point

Tick after an ideal reflow in the paths panel above: the curvature (how much longer the paths are than the straight line between their ends) and the error go to zero at every step count. That is the limit, a model that learned the new lines exactly. A trained reflow gets close: on the lab's eight Gaussians it drops the curvature from 88% to 0.1% and makes one step better than 8 of the original model; on MNIST one step goes from FD 2255 to 201. It is not free, though: each round needs a large set of pairs generated with the full ODE, the errors of the first model are baked into them, and on images one reflow left a visible gap until the training recipe was reworked (2-rectified flow on CIFAR-10 went from a one-step FID of 12.21 to 3.07 with a better initialization, timestep sampling and loss)11. InstaFlow ran reflow plus distillation on Stable Diffusion for one-step text-to-image in 202312.

The name means less than it seems

SD3 and FLUX are called rectified flow models, and neither paper describes a reflow stage. In the SD3 paper the name refers to the straight interpolant \((1-t)\,x + t\,\epsilon\) of Liu et al. (data \(x\) at \(t = 0\)), which is the flow-matching path of this chapter7. The few-step versions that shipped were made by distillation: FLUX.1 [schnell] by latent adversarial diffusion distillation (1–4 steps), SD3.5 Large Turbo by adversarial diffusion distillation (4 steps)13.

Fewer steps: from velocities to jumps

Reflow straightens the field so that a short integration is accurate. The other line of work stops integrating: it trains the network to predict where the trajectory ends up after a jump of any size, a flow map \(X_{s \to t}(x)\): the point at time \(t\) of the trajectory that passes through \(x\) at time \(s\)14. The instantaneous velocity is the limit of a jump of zero length, and a one-step sampler is the jump from 0 to 1.

Method What the network learns Result
Consistency models4 The map from any point of a trajectory to its endpoint; self-consistency along the trajectory is the loss. sCM (2025) made the continuous-time version train stably at scale15 2-step FID 1.88 on ImageNet 512
Shortcut models5 The velocity and the step size: a jump of \(2d\) must equal two jumps of \(d\) One model for 1, 4 or 128 steps
MeanFlow6 The average velocity over an interval, through an identity that links it to the instantaneous one 1-step FID 3.43 on ImageNet 256, from scratch; 1.72 in the improved version (Dec 2025)16
Adversarial distillation (ADD, LADD) A few-step student of a trained model, with a discriminator β€” the GAN of chapter 18 β€” keeping single steps sharp What FLUX.1 [schnell] and SD3.5 Turbo shipped

The research methods (the first three) train one-step models from scratch on ImageNet; what ships in products in 2026 is still mostly distillation of a many-step flow-matching model, adversarial or distribution-matching. Both start from the field this chapter trains.

Training choices that matter

The loss is one line, but three choices around it changed between the first papers and the current models, and you will meet all three in any recent codebase:

  • Where in \(t\) to train. Uniform \(t\) wastes effort near the ends, where the target is easy. SD3 samples \(t\) from a logit-normal, concentrated on the middle7, and HunyuanVideo does the same; the robot policies Ο€0 and GR00T use a Beta distribution that favours the noisy end17.
  • Shift with the resolution. More pixels or tokens make a given noise level easier to see through, so large images and videos move the timesteps toward the noise end, by a factor that grows with the number of tokens (SD3, LTX-Video). This is the timestep shift of the SNR panel in chapter 20.
  • What the network outputs. Velocity is the default, but the network may also predict \(x_1\) (the clean data) or the noise, all convertible given \(t\). Li and He argue that predicting the clean data directly is what lets a plain Transformer generate in pixel space with large patches18 β€” a 2025 result that reopened a choice everyone thought settled.

Where it is used

Flow matching is not a niche alternative any more. Where a training objective is published, the current generation of generative models uses it β€” but not everywhere, and some of the best-known systems do not say.

Domain Models (first release) What flows
Image Stable Diffusion 3 (2024)7, FLUX.1 (Aug 2024)2, FLUX.1 Kontext (May 2025), Qwen-Image (Aug 2025), Z-Image (Nov 2025), FLUX.2 (Nov 2025)19 A VAE latent, through an MMDiT or single-stream DiT
Video Movie Gen (Oct 2024)10, HunyuanVideo (Dec 2024), LTX-Video, Wan 2.1 (Feb 2025)20, Open-Sora 2.0 A spatio-temporal latent, patchified in space and time
Speech, audio, music Voicebox (2023)21, Matcha-TTS, CosyVoice, F5-TTS (2024), Movie Gen Audio, ACE-Step (2025) Mel spectrograms or audio latents, conditioned on text and a voice prompt
Robot policies Ο€0 (Oct 2024)17, Ο€0.5, GR00T N1 (Mar 2025), SmolVLA A chunk of future actions (50 steps for Ο€0), conditioned on a vision-language model
Proteins FrameFlow, FoldFlow (2023), Proteina (2025) Backbone coordinates or frames; on frames, flow matching on a manifold22
Inside multimodal LLMs JanusFlow (2024), BAGEL (2025) An image head trained with rectified flow next to the next-token loss

Two things in that table are worth a second look. In robotics, flow matching won for a reason that is not image quality: Ο€0 needs about 10 Euler steps for a chunk of 50 actions, fast enough for control at up to 50 Hz, and it can represent an action distribution with several modes, where a regression head would average them into an action that matches none17. In video, the pipeline is the same as for images β€” only the latent gains a time axis.

What is not flow matching is just as instructive: AlphaFold 3 uses a standard diffusion module; CogVideoX trains with \(\mathbf{v}\)-prediction diffusion; Stable Audio Open with the \(\mathbf{v}\) objective; Sora and Veo 3 are described by their makers as diffusion models, without the objective being disclosed. Given the equivalence above the boundary is thin, and the label matters less than the interpolant, the target and the timestep weighting.

FLUX.1-dev at 1024 Γ— 1024, with the shape of what passes between the parts. The velocity field of this chapter is the box in the middle, now also conditioned on the text, \(c\); everything around it is the latent-diffusion plumbing of chapter 20, and the Transformer itself is chapter 22. FLUX.2 keeps the scheme with a 32B Transformer and replaces the two text encoders with a 24B vision-language model19.

FLUX.1-dev generating a 1024 Γ— 1024 image. The prompt goes to two frozen text encoders: CLIP-L gives one pooled vector of 768, which with the time t modulates every block (adaLN), and T5-XXL gives 512 tokens of 4096, which join the image tokens in attention. The noise z0, 16 Γ— 128 Γ— 128, is cut into 2 Γ— 2 patches, 4096 tokens of 64. The 12B Diffusion Transformer predicts a velocity and an ODE solver takes 20 to 50 steps from t = 0 (noise) to t = 1 (data); the latent z1, 16 Γ— 128 Γ— 128, goes once through the VAE decoder to a 3 Γ— 1024 Γ— 1024 image. prompt text noise z0​ 16 Γ— 128 Γ— 128 CLIP-L pooled vector Β· 768 T5-XXL 512 tokens Γ— 4096 patchify 2 Γ— 2 4096 tokens Γ— 64 Diffusion Transformer Β· 12B rectified flow adaLN: CLIP + t joint attention text + image tokens image tokens predicts vθ​(x, t, c) x ← x + Ξ”t Β· vθ​(x, t, c) 20–50 steps, t from 0 (noise) to 1 (data) latent z1​ 16 Γ— 128 Γ— 128 VAE decoder Γ—8 per side, 16 β†’ 3 ch image 3 Γ— 1024 Γ— 1024

Sampling

The training gives you a velocity field. Turning it into a sample is ODE integration, and you may pick the solver β€” the same separation as in chapter 20.

import torch

@torch.no_grad()
def sample_euler(model, shape, n_steps=25, device='cuda'):
    """First order. One model evaluation per step."""
    x = torch.randn(shape, device=device)             # x at t = 0 is pure noise
    dt = 1.0 / n_steps
    for i in range(n_steps):
        t = torch.full((shape[0],), i * dt, device=device)
        x = x + dt * model(x, t)
    return x

@torch.no_grad()
def sample_heun(model, shape, n_steps=15, device='cuda'):
    """Second order: two evaluations per step, but far less error per step."""
    x = torch.randn(shape, device=device)
    dt = 1.0 / n_steps
    for i in range(n_steps):
        t  = torch.full((shape[0],), i * dt, device=device)
        t2 = torch.full((shape[0],), (i + 1) * dt, device=device)
        v1 = model(x, t)
        v2 = model(x + dt * v1, t2)                   # predictor, then correct
        x = x + dt * (v1 + v2) / 2
    return x

Count model evaluations, not steps: Heun with 8 steps costs what Euler with 16 does. On the lab's MNIST model Heun loses with few evaluations (FD 550 against Euler's 226 at 4) and wins from 16 on (89.7 against 99.3): a second-order step needs steps small enough for its correction to be right.

Reading a flow-matching codebase

Three conventions differ between papers and will cost you an afternoon if you assume: whether \(t = 0\) is noise or data (this chapter uses noise; the SD3 paper and many codebases put the data at \(t = 0\)), whether the model predicts velocity, \(x_1\) or \(\epsilon\) (all interconvertible, given \(t\) and the interpolant), and whether \(t\) is passed as a number in \([0,1]\) or an integer timestep index. Check all three before debugging anything else. Meta's Flow Matching Guide and Code states them in one notation and ships a reference PyTorch library23.

Lab: flow matching from scratch

The chapter's claims are measured in a Colab notebook that trains flow-matching models end to end, first on two dimensions, where the exact field is known, then on MNIST. It runs on the free tier: CPU is enough for sections 1–5, and the MNIST sections want a T4 GPU (Runtime β†’ Change runtime type β†’ T4 GPU); the reference run of every cell took 15 to 25 minutes on an Apple laptop GPU shared with other jobs, slower than a T4. Eight sections, each ending in a checkpoint with a check value:

  1. the exact marginal field of a 2-D mixture, and the floor of the loss, computed;
  2. a velocity MLP trained to that floor, and its distance to the exact field;
  3. sampling: endpoint error and distance to the data against the number of steps, Euler against Heun at equal cost, and the curvature of the learned paths;
  4. the diffusion interpolant with the same code, and which one is straighter;
  5. one round of reflow, and what it does to the curvature and to one-step samples;
  6. MNIST: a small U-Net trained with the same loss, scored by a FrΓ©chet distance;
  7. one step lands on the mean digit; Heun, and the diffusion interpolant, on images;
  8. reflow on MNIST, and an open task: logit-normal timesteps, with a table to fill in.

Open the lab in Colab β€” save a copy to your Drive (File β†’ Save a copy in Drive) to run and edit it.

Key takeaways

  1. Flow matching learns a velocity field and samples by integrating an ODE. The loss is one MSE with no schedule and no bound.
  2. The marginal velocity is intractable, but regressing the conditional one has the same gradient. That theorem is the whole method. A consequence: the loss has a floor above zero.
  3. Diffusion is flow matching with a curved interpolant. \(a(t) = \sqrt{\bar\alpha_t}\) instead of \(a(t) = t\). One framework covers both; on the linear path, DDIM is exactly the Euler step of the flow.
  4. "Straight paths" applies to the conditional path. The marginal path β€” the one the model learns β€” is not straight; it re-pairs noise and data so that paths never meet.
  5. On images the linear path saves at most about a third of the solver steps, and only with the right weighting across \(t\); with a uniform \(t\) a good diffusion schedule can beat it, as in the lab. The bigger reasons for adopting it are the objective (simple, robust to the schedule) and the recipe around it: logit-normal timesteps, resolution shift.
  6. Reflow straightens the field by retraining on the model's own pairs. It works, at the cost of generating those pairs. The "rectified flow" of SD3 and FLUX is the straight interpolant, not reflow.
  7. One-step generation comes from learning jumps instead of velocities β€” consistency, shortcut, MeanFlow β€” and, in shipped models, from distillation (FLUX.1 [schnell], SD3.5 Turbo).
  8. Since 2024 the objective is shared by image, video, speech and robot-action models: a different \(p_1\), the same line of code.


  1. Lipman, Y., Chen, R. T. Q., Ben-Hamu, H., Nickel, M., & Le, M. (2023). Flow Matching for Generative Modeling β€” ICLR. The conditional-flow-matching theorem is section 3, and it is short; the solver evaluations are in table 1 (adaptive solver; DDPM needs 262–274 on the same benchmarks). ↩↩↩

  2. Black Forest Labs (2024). Announcing Black Forest Labs and FLUX.1 β€” a 12B model "built on flow matching"; [dev] is guidance-distilled from [pro]. ↩

  3. Liu, X., Gong, C., & Liu, Q. (2023). Flow Straight and Fast: Learning to Generate and Transfer Data with Rectified Flow β€” ICLR. Rectified flow and the reflow procedure. ↩↩

  4. Song, Y., Dhariwal, P., Chen, M., & Sutskever, I. (2023). Consistency Models β€” ICML. ↩

  5. Frans, K., Hafner, D., Levine, S., & Abbeel, P. (2025). One Step Diffusion via Shortcut Models β€” ICLR. Condition on the step size and one model serves every step budget. ↩

  6. Geng, Z., Deng, M., Bai, X., Kolter, J. Z., & He, K. (2025). Mean Flows for One-step Generative Modeling β€” NeurIPS. Average velocity instead of instantaneous, and one-step generation without a distillation stage. ↩

  7. Esser, P., et al. (2024). Scaling Rectified Flow Transformers for High-Resolution Image Synthesis β€” ICML. SD3. Section 5.1 compares 61 formulations (interpolants, targets and timestep samplers); the same paper introduces logit-normal timestep sampling and the resolution-dependent shift. ↩↩↩↩

  8. Albergo, M. S., Boffi, N. M., & Vanden-Eijnden, E. (2023). Stochastic Interpolants: A Unifying Framework for Flows and Diffusions. The general \(a(t), b(t)\) statement used in the table. ↩

  9. Diffusion Meets Flow Matching: Two Sides of the Same Coin (2025), blog post; the authors are not named on the page. "Diffusion models and Gaussian flow matching are the same", worked out sampler by sampler. ↩

  10. Polyak, A., et al. (2024). Movie Gen: A Cast of Media Foundation Models. Flow matching for video (section 3.1.2) and for audio (section 6); the comparison with diffusion losses is in section 3.6.2. ↩↩

  11. Lee, S., Lin, Z., & Fanti, G. (2024). Improving the Training of Rectified Flows β€” NeurIPS. Why one reflow is usually enough, and what it costs. ↩

  12. Liu, X., Zhang, X., Ma, J., Peng, J., & Liu, Q. (2024). InstaFlow: One Step is Enough for High-Quality Diffusion-Based Text-to-Image Generation β€” ICLR. ↩

  13. Model cards: FLUX.1 [schnell] ("trained using latent adversarial diffusion distillation") and Stable Diffusion 3.5 Large Turbo (adversarial diffusion distillation, 4 steps). ↩

  14. Boffi, N. M., Albergo, M. S., & Vanden-Eijnden, E. (2024). Flow Map Matching. Consistency, shortcut and mean-flow models as ways of learning the two-time map. ↩

  15. Lu, C., & Song, Y. (2025). Simplifying, Stabilizing and Scaling Continuous-Time Consistency Models β€” ICLR. ↩

  16. Geng, Z., Lu, Y., Wu, Z., Shechtman, E., Kolter, J. Z., & He, K. (2025). Improved Mean Flows: On the Challenges of Fastforward Generative Models. Preprint. ↩

  17. Black, K., et al. (2024). Ο€0: A Vision-Language-Action Flow Model for General Robot Control. The action expert, chunks of 50 actions, 10 integration steps and a Beta timestep distribution; GR00T N1 (Bjorck et al., 2025) uses 4 steps for chunks of 16. ↩↩↩

  18. Li, T., & He, K. (2025). Back to Basics: Let Denoising Generative Models Denoise. Preprint. ↩

  19. Black Forest Labs (2025). FLUX.2 β€” "a latent flow matching architecture", a Mistral-3 24B vision-language model with a rectified-flow Transformer; 32B parameters according to the FLUX.2 [dev] model card. ↩↩

  20. Wan Team (2025). Wan: Open and Advanced Large-Scale Video Generative Models. The flow-matching objective is section 4.2.2. HunyuanVideo (Kong et al., 2024) and LTX-Video (HaCohen et al., 2024) state the same objective. ↩

  21. Le, M., et al. (2023). Voicebox: Text-Guided Multilingual Universal Speech Generation at Scale β€” NeurIPS. F5-TTS (Chen et al., 2024) is flow matching with a diffusion Transformer. ↩

  22. Chen, R. T. Q., & Lipman, Y. (2024). Flow Matching on General Geometries β€” ICLR. Riemannian flow matching, the basis of the frame-based protein models (FrameFlow, FoldFlow). ↩

  23. Lipman, Y., Havasi, M., Holderrieth, P., Shaul, N., Le, M., Karrer, B., Chen, R. T. Q., Lopez-Paz, D., Ben-Hamu, H., & Gat, I. (2024). Flow Matching Guide and Code. With the flow_matching PyTorch package. ↩