Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions examples/discrete_diffusion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,54 @@ python examples/discrete_diffusion/sample_llada2.py \
--use_chat_template \
--add_generation_prompt
```

## Visualizing the sampling process

`animate_sampling.py` records the intermediate canvas of every denoising step (through each pipeline's
`callback_on_step_end`, without changing the pipelines) and renders it as an animation. It makes the difference
between the two families of discrete diffusion easy to see:

* Masked diffusion (LLaDA2): every slot starts as `[MASK]` and is progressively unmasked, revealing text from blanks.
* Uniform block diffusion (DiffusionGemma): every slot always holds a real token, so a canvas of random tokens is
sharpened into text, one cached block at a time.

The script has two subcommands. `capture` runs a real pipeline and saves one trajectory as JSON. `render` turns one or
more trajectories into a self-contained HTML animation (and, with `--gif`, an animated GIF). Highlighted states use a
color-blind-safe palette that also stays legible in grayscale.

### Capture a trajectory

```bash
# LLaDA2 (masked diffusion)
python examples/discrete_diffusion/animate_sampling.py capture \
--method llada2 --model_id inclusionAI/LLaDA2.1-mini \
--prompt "Why is the sky blue? Explain in detail." --use_chat_template \
--gen_length 512 --block_length 32 --num_inference_steps 32 \
--out traj_llada2.json

# DiffusionGemma (uniform block diffusion); --scheduler picks one of the three supported samplers
python examples/discrete_diffusion/animate_sampling.py capture \
--method diffusion_gemma --model_id google/diffusiongemma-26B-A4B-it \
--prompt "Why is the sky blue?" --gen_length 512 --num_inference_steps 32 \
--scheduler entropy_bound \
--out traj_dg.json
```

`--scheduler` accepts `entropy_bound` (the released checkpoint's sampler), `discrete_ddim` (exact D3PM posterior,
ancestral), or `block_refinement` (confidence-committed refinement). Capture one trajectory per scheduler to compare
them on the same prompt and seed.

### Render an animation

```bash
# One or more trajectories become a single side-by-side animation
python examples/discrete_diffusion/animate_sampling.py render \
traj_llada2.json traj_dg.json \
--out sampling_animation.html --gif sampling_animation.gif
```

Trajectories with different step counts are resampled onto a shared timeline, so every panel starts and finishes
together regardless of how many steps each sampler took. Use `--max_frames` to cap the GIF length and `--cols` to set
the characters per line.

The script is also runnable with [uv](https://docs.astral.sh/uv/): `uv run examples/discrete_diffusion/animate_sampling.py ...`.
Loading
Loading