Based on an article by Apple ML at the original source

Before anything else, understand the two fundamental approaches to generating text:
"The" → "The cat" → "The cat sat" → "The cat sat down"
↑ each step waits for the previous
The key tension: Text is discrete (words, tokens), but diffusion/flow models work in continuous space. How do you bridge this gap?
Flow matching is a framework that learns to transport one probability distribution to another via a smooth, continuous path.
Start: Gaussian Noise →→→→→→→→→→ End: Data Distribution
N(0, I) (flow path) p(text)
| Step | What Happens |
|---|---|
| 1 | Sample random Gaussian noise z₀ |
| 2 | A neural network learns a velocity field v(z, t) |
| 3 | Follow the velocity field from t=0 to t=1 |
| 4 | Arrive at a sample z₁ that looks like real data |
The model learns to predict the direction to move at each point in time:
Loss = E[ || v_θ(z_t, t) - (z₁ - z₀) ||² ]
↑ predicted ↑ true direction
velocity from noise to data
Key insight: You're teaching the model "if you're at this point in space at this time, move in this direction."
Tokens are discrete: ["cat", "dog", "bird"] → [0, 1, 2]
Flow matching needs continuous vectors to work.
Convert each token into a binary vector:
Vocabulary: [cat, dog, bird, fish]
"cat" → [1, 0, 0, 0]
"dog" → [0, 1, 0, 0]
"bird" → [0, 0, 1, 0]
Now each token lives in continuous space (as a corner of a hypercube).
Gaussian Noise → One-Hot Encoded Token
[0.3, -0.1, 0.8, 0.2] → [0, 0, 1, 0] ("bird")
↑ continuous ↑ discrete corner
The flow model learns to push noisy continuous vectors toward these discrete corners.
Semi-discrete setting = the source (Gaussian) is continuous, the target (one-hot) is discrete. This is a key technical term in the paper.
Standard flow matching requires many small steps to travel from noise to data:
z₀ → z₀.₁ → z₀.₂ → ... → z₀.₉ → z₁
(100+ steps, slow!)
A flow map is a function that skips directly from one time point to another:
Standard: z₀ → z₀.₂₅ → z₀.₅ → z₀.₇₅ → z₁ (4 steps)
Flow Map: z₀ ─────────────────────────────→ z₁ (1 step!)
Mathematically:
Φ(z, s, t) = "where does z at time s end up at time t?"
CFMs apply this idea to categorical/text data:
Base Model: 100 steps → good text
CFM: 4 steps → nearly as good text ✓
Distillation = using a large, slow model (teacher) to train a faster model (student).
Here, the same model plays both roles:
Phase 1: Train base flow model (1.7B parameters, 2.1T tokens)
↓
Phase 2: Use base model to generate "multi-step trajectories"
↓
Phase 3: Train CFM to replicate those trajectories in fewer steps
↓
Result: CFM generates text in 4 steps with near-identical quality
| Property | Benefit |
|---|---|
| No separate teacher model needed | Saves compute |
| Teacher and student share architecture | Easier training |
| Teacher trajectories are high quality | Student learns good shortcuts |
Language model benchmarks require the model to assign probabilities to text:
P("The cat sat on the mat") = ?
P("The cat sat on the quantum") = ?
A good model should assign higher probability to natural text.
Flow models don't directly output probabilities — they output directions (velocity fields). Computing exact likelihoods is expensive.
The paper introduces a lower bound on the log-likelihood:
log P(x) ≥ BOUND(x)
↑
computable from the flow model
This bound is:
Analogy: You can't easily measure the exact height of a mountain, but you can establish "it's at least 8,000 meters" — useful for comparison even if not exact.
Previous CFM work was tested at < 1 Billion parameters. This paper scales to 1.7B parameters on 2.1 Trillion tokens — a massive jump.
Different time steps contribute differently to the loss:
t ≈ 0 (near noise): easy, model learns quickly
t ≈ 1 (near data): hard, model needs more attention
Fix: Weight the loss to emphasize harder time steps:
Loss = Σ w(t) × ||v_θ(z_t, t) - target||²
↑
learned/tuned weights
How you sample time steps during training matters enormously:
Uniform sampling: t ~ Uniform(0, 1) ← naive, suboptimal
Logit-normal: t ~ LogitNormal(μ, σ) ← better for text
The paper provides prescriptive insights (concrete recommendations) on which schedules work at scale.
Entropy measures diversity/uncertainty in generated text:
High entropy: Model generates varied, diverse text
Low entropy: Model generates repetitive, boring text
Mathematically:
H(p) = -Σ p(token) × log p(token)
The paper's CFM achieves entropy close to real data:
Real text entropy: H_data ≈ X bits
CFM (4 steps): H_CFM ≈ X - ε bits ✓ (very close!)
Autoregressive: H_AR ≈ X bits
This means the model isn't collapsing to repetitive outputs — a common failure mode in fast generation.
Here's the complete pipeline:
┌─────────────────────────────────────────────────────────┐
│ TRAINING PHASE │
│ │
│ Text Tokens → One-Hot Encode → [0,0,1,0,...] │
│ ↓ │
│ Gaussian Noise → Flow Matching → Learn velocity field │
│ (1.7B params, 2.1T tokens, careful loss/time tuning) │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ DISTILLATION PHASE │
│ │
│ Base Model (slow) → Self-Distill → CFM (fast) │
│ 100+ steps needed ────────→ 4 steps needed │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ INFERENCE PHASE │
│ │
│ Gaussian Noise → [4 CFM steps] → One-Hot Vectors │
│ ↓ │
│ argmax → Text Tokens │
│ │
│ Scoring: Use likelihood bound for benchmarks │
└─────────────────────────────────────────────────────────┘
| Concept | Core Idea |
|---|---|
| Flow Matching | Learn to transport noise → data continuously |
| One-Hot Encoding | Make discrete tokens continuous |
| CFMs | Skip multiple flow steps at once |
| Self-Distillation | Use slow model to train fast model |
| Likelihood Bound | Approximate scoring for benchmarks |
| Scaling Insights | Loss weighting + time scheduling matter enormously |
The big picture: This paper proves that continuous flow models can compete with autoregressive models for text generation at scale, while offering unique advantages like few-step sampling — a potentially transformative result for language modeling.