Flow Matching

Turning random noise into real things β€” explained without scary math.

↓ scroll to learn ↓

The Big Idea, In One Sentence

Flow Matching teaches a computer to gently flow a cloud of random noise into something meaningful β€” like a photo, a sound, or a 3D shape β€” by learning, step by step, which direction each point should move.

🌫️

Start: Pure Noise

Imagine a puff of smoke β€” totally random, no shape at all.

🌊

The Flow

A gentle "current" nudges every speck of smoke in a useful direction.

πŸ–ΌοΈ

End: Real Data

After following the current, the smoke has arranged itself into something real.

That "current" is called a vector field β€” just a fancy way of saying "an arrow at every point in space, telling you which way to go and how fast." Flow Matching is simply a recipe for teaching a neural network to draw those arrows correctly.

Why Do We Even Need This?

Modern AI models like image generators (e.g. Stable Diffusion) start from random noise and need a reliable way to turn that noise into a coherent picture, sound, or video. The question is:

"Given a point of pure randomness, where should it go to become something real β€” and how do we get there efficiently?"

Flow Matching is one of the simplest, most direct answers to that question.

Watch It Happen

Below, ~180 random points start as scattered "noise." Drag the slider (or hit Play) to move time t from 0 β†’ 1, and watch every point flow along its own straight little path until the noise rearranges itself into a heart shape.

Each little arrow is the point's velocity: the fixed direction and speed it needs to travel in a straight line to reach its target. Flow Matching trains a network to predict exactly this arrow, for any point, at any time t.

The Training Pipeline, Step by Step

It's easy to blur two very different things together: the process that teaches the network, and the process that uses it to create something new. They happen at completely different times, need different ingredients, and look different. Here's both, side by side.

Phase 1

πŸ‹οΈ Training β€” happens once, offline, needs real data

1🌫️ Sample a random noise point
2πŸ–ΌοΈ Sample one real example from the dataset
3🎲 Pick a random time t between 0 and 1
4πŸ“ Mix them: get the blurry in-between point at time t
5🧠 Ask the network to guess the velocity there
6βš–οΈ Compare its guess to the true straight-line velocity
7πŸ”§ Nudge the network's weights to reduce that error
β†Ί repeat this β€” millions of times, over the whole dataset
Phase 2

✨ Generating β€” happens every time, no data needed

🌫️
random noise
β†’
ask network
take small step
β†’
ask network
take small step
β†’
β‹―
β†’
πŸ–ΌοΈ
new sample!

Notice what's missing here: no real photo is used at all. Only random noise and the network's learned instincts, applied one small step at a time.

Why split it like this? During training, the network never gets to see the final answer directly during generation β€” it only ever practiced on straight lines between noise and real examples. At generation time, it has to rely purely on what it internalized from that practice to find its own way from fresh noise to something realistic.

Why Are the Equations Designed This Way?

The formulas from the "optional peek" further down aren't arbitrary β€” every choice exists to make the network's job as easy as possible. Here's the reasoning behind each one, in plain terms.

🧡 Why a straight line, specifically?

A straight line is the simplest possible path between two points β€” no curving, no speeding up or slowing down, no surprises along the way. If the "noise β†’ data" path were allowed to wander, the network would have to learn a different direction at every instant. By forcing a straight line, it only ever has to learn one fixed direction per pair β€” a dramatically easier problem to solve well.

🚢 Why is the velocity just "data βˆ’ noise", with no time in it?

Picture walking from your house to a cafΓ© in a perfectly straight line at a constant pace. Your direction and speed never change β€” not at the start, not halfway, not near the end. That's exactly what data βˆ’ noise represents: one fixed arrow that stays valid for the entire trip. The network never has to chase a "moving target" β€” just one direction per pair β€” which makes training far more stable than something with a constantly shifting goal.

🌐 Why does it still work when many different pairs overlap?

At almost any blurry in-between point, many different noise→data pairs could plausibly have passed through it. The network can never know exactly which pair produced this particular point — so instead it learns something like the average direction of every pair that could plausibly be there. Remarkably, just following this "average of everyone passing through here" field is enough to reliably carry brand-new noise all the way to realistic data, even though no single training path is being followed exactly.

🎯 Why does this generalize instead of just memorizing?

The network never memorizes specific noise→data pairs — it only ever sees the direction implied by one pair, blended in with millions of directions from other pairs during training. What it ends up learning is the general shape of "where data tends to be," not any individual example. That's why, starting from noise it has never seen before, it can still flow toward something new and realistic.

What the Network Actually Learns

Once trained, the network has effectively learned a full "map of currents" β€” an arrow at every point in space. Below is a simplified visualization: arrows show the learned direction of flow, and glowing particles ride the current toward the target shape, forever looping.

This is the vector field β€” the AI's internal compass for turning noise into data.

Flow Matching vs. Diffusion (Simplified)

Diffusion models (the technique behind the first wave of AI image generators) solve a similar problem, but historically needed many small, noisy correction steps. Flow Matching favors straighter, smoother paths β€” often needing far fewer steps. The animations below are simplified analogies, not literal diffusion math.

🌊 Flow Matching

A straight, direct path. Few steps needed.

πŸŒ€ Diffusion (typical)

A noisy, winding path. Many small steps needed.

Flow MatchingTypical Diffusion
Path shapeMostly straightWinding / stochastic
Steps to generateCan be very fewOften many
Core ideaLearn a direct velocity fieldLearn to gradually denoise
Used inStable Diffusion 3, many video/audio modelsDDPM, early Stable Diffusion

Curious About the Formula? (Totally Optional)

Peek under the hood β€” full step-by-step derivation β†’

Nothing here is memorized from a textbook β€” every line below is built from the previous one. Let's construct both equations from scratch, exactly the way you'd build them yourself.

Step 1

Name the two points

Call a random noise point xβ‚€ (this is where a particle starts β€” same x0 in the interactive demo above) and a real data example x₁ (where it needs to end up). Both are just lists of numbers β€” pixel values for an image, for instance β€” so all the "arithmetic" below is really just vector addition, done per-number.

Step 2

Connect them with the standard "line between two points" formula

From basic geometry (the same formula used to draw any line in computer graphics): to move a fraction t of the way from a point A to a point B, you take A and add t times the direction (B βˆ’ A):

point(t)  =  A + tΒ·(B βˆ’ A)

Now just substitute A = xβ‚€ (start) and B = x₁ (end):

x(t)  =  xβ‚€ + tΒ·(x₁ βˆ’ xβ‚€)
     =  xβ‚€ βˆ’ tΒ·xβ‚€ + tΒ·x₁
     =  (1 βˆ’ t)Β·xβ‚€ + tΒ·x₁

That last line is just regrouping terms β€” it's the exact same equation, only rearranged. It's usually written this way because it makes one thing obvious at a glance: plug in t = 0 and you get pure noise; plug in t = 1 and you get the pure data point.

x(t) = (1 βˆ’ t) Β· xβ‚€ + t Β· x₁

"Mix noise and data together β€” how much of each depends on t." This is exactly the lerp driving the slider in the heart demo above.

Step 3

Read off the velocity β€” differentiate with respect to time

"Velocity" just means how fast x(t) changes as t ticks forward β€” in calculus terms, its derivative dx/dt. Since xβ‚€ and x₁ are fixed numbers for this particular pair (they don't change as t moves), differentiating is simple: the constant term xβ‚€ vanishes, and tΒ·(x₁ βˆ’ xβ‚€) differentiates to just its coefficient, (x₁ βˆ’ xβ‚€):

dx/dt  =  d/dt [ xβ‚€ + tΒ·(x₁ βˆ’ xβ‚€) ]
      =  0 + (x₁ βˆ’ xβ‚€)
      =  x₁ βˆ’ xβ‚€

This is exactly why the arrows in the demo above never change length or direction as you drag the slider β€” a straight line has one constant slope, the same way y = mx + b always has slope m, no matter which x you plug in.

velocity = x₁ βˆ’ xβ‚€

"The straight-line direction and speed β€” the same at every point along the path."

Step 4

Turn it into something a network can be trained on

Every time we randomly sample a noise point, a data point, and a time t, Steps 2 and 3 hand us a matched pair for free: an input (x(t), t) and the correct answer (x₁ βˆ’ xβ‚€). Training just means: show the network many, many such inputs, and push its guess closer to the correct answer each time. Written as a loss function (a single number measuring "how wrong" the network currently is):

L(ΞΈ) = average over many (xβ‚€, x₁, t) of  β€– v_ΞΈ(x(t), t) βˆ’ (x₁ βˆ’ xβ‚€) β€–Β²

v_ΞΈ is the network (ΞΈ = its adjustable weights); the double bars mean "distance between the two arrows, squared" β€” the standard way to measure numeric error. Smaller L means the network's guessed arrow is closer to the true one. This one formula is steps 5–7 of the training loop from the section above: guess, compare, and β€” via gradient descent β€” nudge ΞΈ to shrink L.

Step 5

Use it to actually generate something (solving the ODE)

After training, swap the true velocity for the network's learned approximation and treat it as a rule for motion:

dx/dt = v_ΞΈ(x, t) ,  starting from x(0) = fresh random noise

This is an "ODE" (ordinary differential equation) β€” a fancy name for "a rule telling you your rate of motion, given where you currently are." Computers solve it the same simple way you'd approximate any motion: take a small time step Ξ”t, nudge your position by velocity Γ— Ξ”t, then ask again:

x(t + Ξ”t)  =  x(t) + Ξ”t Β· v_ΞΈ(x(t), t)

Repeat that update from t = 0 to t = 1 and you've just reconstructed, in one formula, the entire "ask network β†’ small step β†’ ask network β†’ small step" Generation phase from the pipeline section above.

One last thread to pull: at generation time you start from noise that was never paired with any specific data point during training, so no single straight line applies anymore. That's the "why does it still work" question answered in the Why section above β€” the network was really learning the average direction across every pair that could plausibly pass through each point, and following that averaged field turns out to be enough.

Where This Shows Up In Real Life

πŸ–ΌοΈ

Image Generation

Stable Diffusion 3 and other modern image models use Flow Matching to turn noise into pictures.

🎬

Video Generation

Text-to-video models use it to generate smooth, coherent frames.

πŸ”Š

Audio & Speech

Speech and music generators flow noise into waveforms.

🧬

Science

Used to generate plausible molecules and protein structures.

Quick Recap β€” Flip the Cards

Click any card to reveal a plain-English definition.

Noise
Pure randomness β€” the messy starting point, like TV static.
Data
A real example the model wants to learn to recreate β€” a real photo, sound, etc.
Vector Field
An arrow at every point in space telling you which way to move and how fast.
Velocity
The direction + speed a specific point should travel right now.
Sampling
Generating something new: start at noise, follow the arrows, arrive at data.
Training
Teaching the network to correctly predict the velocity arrows, using many noise→data pairs.