Latents & Logs
Generative ModelsSeed

DiT Control Is a Few Decisions About Tokens

A working skeleton: what a diffusion transformer actually is, why every control method decomposes into a handful of token-level decisions, and a starter table mapping papers onto those axes.

On this page ›
  1. The floor: what a DiT actually is
  2. The claim
  3. Refinement one: the exception is modulation
  4. Refinement two: two axes hide inside “add tokens”
  5. The coordinate system, as a table
  6. First test case: SIGMA-GEN

The floor: what a DiT actually is

Four facts carry almost everything else:

  1. Latent patches are the tokens. A VAE encodes the image into a latent (say 64×64×4), which is chopped into patches (say 2×2), each linearly projected into an embedding. A “token” in a DiT is a spatial patch of the latent, not a word.
  2. The transformer predicts noise (or velocity). The denoising objective is unchanged from U-Net diffusion — only the backbone swapped. Nothing in the diffusion math cares that it’s attention now.
  3. Conditioning enters two ways. The timestep (and class label or pooled text vector) usually enters via adaLN: an MLP maps the condition vector to per-block scale/shift/gate values that modulate every token’s LayerNorm. Rich text conditioning enters via cross-attention (classic DiT / PixArt) or by concatenating text tokens into one joint sequence (MM-DiT, as in SD3 and FLUX).
  4. Why DiT won. Transformers scale predictably with compute (the DiT paper’s Gflops-vs-FID plot), and a token sequence is a universal interface: text, image latents, reference latents, and video frames all concatenate into the same attention.

The claim

Inside a DiT there is no such thing as “the image” versus “the condition.” There is only the token sequence. So every form of control decomposes into three actions:

  1. Add tokens — what enters the sequence
  2. Assign coordinates — what position/role each token claims
  3. Decide who is allowed to look at whom — the attention pattern

Cross-attention stops being a separate mechanism under this view: it’s just a joint attention where the text tokens are visible but never updated. Action 3 covers it.

Refinement one: the exception is modulation

One thing never enters as a token: the global condition. The timestep, the pooled text vector, the guidance embedding — they bypass the sequence entirely and act through adaLN modulation on every token at once. So the honest version of the list has a fourth action:

  1. Set the global knobs — conditions that skip the sequence and arrive via modulation

Refinement two: two axes hide inside “add tokens”

Recent papers mostly differentiate on two questions that “add tokens” quietly contains:

  • Which weights process the tokens? Shared weights for all modalities (FLUX single-stream blocks; OminiControl’s LoRA on shared weights) versus separate per-modality parameters (SD3’s MM-DiT; FLUX double-stream blocks; IP-Adapter’s decoupled K/V projections).
  • When do the tokens exist? Condition tokens don’t change across denoising steps, so their features can be computed once and cached — exactly OminiControl2’s feature reuse — or injected only into some blocks.

The coordinate system, as a table

Six columns: tokens added · coordinates · attention · weights · non-token (adaLN) · lifecycle. Each paper is one row.

PaperTokens addedCoordinatesWho sees whomWeightsNon-token (adaLN)Lifecycle
DiT ‘22nonestandard 2Dfull self-attn—class + timestep—
PixArt-αtext (side sequence)none for textone-way (cross-attn)separate K/Vtimestep (adaLN-single)recomputed
SD3 (MM-DiT)text joined in-sequenceno spatial position for textfull jointseparate per modalitypooled text + timesteprecomputed
FLUXtext + image, 3D RoPE(t, h, w) ids; text at id 0full jointdouble→single streamtimestep, guidancerecomputed
OminiControlVAE-encoded condition imagessame coords if spatially aligned (depth/Canny); offset coords if subject referencefull joint, biasableshared + LoRAtimesteprecomputed
OminiControl2compact condition tokenssame schemefull jointshared + LoRAtimestepcached across steps
ControlNetnone — features added directlyn/an/acopied branchtimesteprecomputed

Two things the table exposes. The coordinates column is where OminiControl earns its keep: position assignment is literally how it distinguishes “control map” from “subject reference.” And ControlNet sits outside the frame entirely — it operates in feature space, not token space — which is useful because it marks the frame’s boundary.

First test case: SIGMA-GEN

I’m currently reading SIGMA-GEN — single-pass multi-subject identity-preserving generation, with structure guidance anywhere from coarse 2D/3D boxes to pixel-level segmentation and depth, in one model. My bet before finishing the method section: its contribution lives mostly in the tokens added and coordinates columns.

Open question: where does SIGMA-GEN place each subject’s identity tokens in coordinate space so that multiple identities don’t blend?