Repository navigation
FLUX.2-klein PR 1: Scaffold for flow matching shared by several models, first of which is flux2-klein #286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
22dbcf4
Add the DiT scaffold package for diffusion models
merceod 44dbe7d
Add flow-matching schedules and the Euler step
merceod 6e00245
Add multi-axis rotary embeddings for FLUX-family DiTs
merceod 1e93597
Add joint attention over packed DiT tokens
merceod e7aa1f1
Add latent packing and PNG helpers for image DiTs
merceod dedf868
Add a native Qwen3 hidden-state text encoder
merceod 6208799
Add the generic denoise-loop submodule
merceod 5de1bfe
Add the KL autoencoder port to the DiT scaffold
merceod 3042cc5
Expose fused-linear shard slices for in-place updates
merceod 4b81515
Add static LoRA merging to the DiT scaffold
merceod 1deecf0
Test the denoise-loop scaffold on CPU
merceod b683390
Add a generic image adapter for diffusion models
merceod 0f6b87f
Add edit_image to the SDK client
merceod 4b41de5
Document edit_image in the SDK client table
merceod 8ff1929
Test static LoRA merging on plain and fused linears
merceod 509a8d2
Add an SDK image edit example
merceod a0246d8
Document the diffusion scaffold in the adding-models guide
merceod 20b9ff1
Let a ragged attention config declare its activation dtype
merceod ce13e60
Build the ragged manager from the config dtype, KV dtype as fallback
merceod a3672d0
Test the ragged attention dtype resolution
merceod f667d12
Declare every attention span of a denoise step with its own label
merceod 031e883
Test multi-span step declarations in the denoise loop
merceod 75b1ced
Match the HF RMSNorm rounding order in the Qwen3 text encoder
merceod b545a10
Quantise pixels in the image processor's dtype order
merceod d2e6e66
Add the Z-Image pipeline's torch.linspace base grid
merceod 3fca8d7
Test the scaffold's norm, quantisation and grid numerics
merceod dbe8557
Document attention spans in the diffusion scaffold guide
merceod 1bb86f8
Hand the compiled DiT one ragged callable per label
merceod 20150e9
Test that ragged callables are stable across steps
merceod 209ca2e
Build the Qwen3 rotary tables exactly as HF does
merceod 3dedc9f
Test the Qwen3 rotary tables against HF
merceod fdce9c9
Mirror HF's mask-free attention path for unpadded batches
merceod 54c1c0a
Encode PNG with parallel deflate and add the OpenAI output-format knobs
merceod c971456
Test the PNG writers, parallel deflate and output formats
merceod 9c2ed2f
Broadcast a per-request Euler dt over latents of any rank
merceod 9b20840
Test the batched Euler step on token and latent layouts
merceod 8931fd0
Address the VAE activations as modules
merceod d0bb6d3
Accept a single filename-bytes pair as one SDK upload
merceod 253217c
Test the SDK's single filename-bytes upload
merceod 1cf1286
Forward the edit size field and answer validation errors with 400
merceod aa46539
Test the edit size passthrough and the 400 on validation errors
merceod cb3962d
Let a graph config declare its static inputs' token axis
merceod 56bcf4f
Intern static buffers along the declared token axis
merceod c11e5de
Declare the denoise loop's static inputs as row-leading
merceod 4a2ee49
Test static buffer interning with a declared token axis
merceod e3f2ebf
Test the denoise loop's static token-axis declaration
merceod f0eb890
Take LoRA scaling from the adapter's sidecar config like PEFT
merceod 523b66f
Test the sidecar-config LoRA scaling
merceod a58c629
Say which engine dtype a cacheless attention inherits
merceod e2697c0
Count a loop's re-injected inputs as ready for its next iteration
merceod 5e3f552
Run speculative loop iterations under their own loop counters
merceod 7dff73e
Test speculation readiness with a loop's re-injected inputs
merceod ac351c5
Test the loop counters a speculative batch runs under
merceod 6d4deb5
Stage persisted outputs for a send only when peer workers exist
merceod e2d0d63
Test when persisted outputs are staged for a send
merceod 4d5bf44
Take the ragged dtype comment wording from #291
merceod 7699dcc
Merge main into engine/dit-scaffold
NSagan271 462c697
Add persist check to the rust runtime
NSagan271 d628695
Add persist check to Python runtime
NSagan271 710d5a5
make LoraAdapter a NamedTuple
NSagan271 bcbf44b
Make the denoise harness more generalizable
NSagan271 95fea94
Merge main into engine/dit-scaffold
NSagan271 5ffb22c
raise on latent failure post step0 denoise rather than reseed
stephen-dwq File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| """Text-to-image, then an edit of the result, via the Python SDK. | ||
|
|
||
| Start a server for an image model that serves edits first, e.g.: mstar serve bagel | ||
| """ | ||
|
|
||
| from mstar import MStarClient | ||
|
|
||
| client = MStarClient("http://localhost:8000") | ||
|
|
||
| png = client.generate_image("a cat holding a sign that says hello world", seed=0) | ||
| with open("out.png", "wb") as f: | ||
| f.write(png) | ||
| print(f"wrote out.png - {len(png)} bytes") | ||
|
|
||
| edited = client.edit_image("make the sign say goodbye, watercolor style", "out.png", seed=1) | ||
| with open("edit.png", "wb") as f: | ||
| f.write(edited) | ||
| print(f"wrote edit.png - {len(edited)} bytes") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """The DiT scaffold: shared pieces of a text -> flow-transformer loop -> VAE model. | ||
|
|
||
| Each module here is model-agnostic and tested against the reference library | ||
| once, so a new image/video diffusion model brings only its config, its exact | ||
| component ports, a weight loader and a thin graph file: | ||
|
|
||
| * ``flow_match`` sigma schedules (linear / dynamic / FLUX.2 empirical shift) + the Euler step | ||
| * ``rope`` multi-axis rotary tables and the interleaved application FLUX-family DiTs use | ||
| * ``attention`` joint attention over packed text+image tokens: SDPA eagerly, the ragged | ||
| FlashInfer resource under CUDA graphs | ||
| * ``text_encoder`` a native Qwen3-family encoder returning tapped hidden states | ||
| * ``denoise_loop`` the Loop-body submodule: seeded noise, equal-shape request batching, per-step | ||
| CUDA graphs, stop at the request's step count | ||
| * ``image_io`` pixel/latent packing helpers and PNG encoding | ||
| * ``lora`` static LoRA merging at load time | ||
| """ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| """Joint attention over a DiT's packed tokens. | ||
|
|
||
| A diffusion transformer attends bidirectionally over all of a request's tokens | ||
| (text + image + reference-image) and keeps nothing between steps, so there is | ||
| no KV cache to page. Two backends serve the same ``[B, S, H, D]`` contract: | ||
|
|
||
| * ``sdpa`` ``torch.nn.functional.scaled_dot_product_attention`` — the reference | ||
| pipelines' own kernel, hence the parity baseline; used eagerly and on CPU. | ||
| * the engine's **ragged attention resource** (``RaggedAttentionSpec``, FlashInfer's | ||
| ragged prefill on FA2/FA3) — one segment per request, planned by the runner | ||
| outside the captured graph, so a per-step CUDA graph can replay it. The | ||
| resource is bound by the submodule and threaded to the layers as a callable. | ||
|
|
||
| Layers call :func:`joint_attention`; the choice is made once per forward by | ||
| whoever owns the resource, not per layer. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from collections.abc import Callable | ||
|
|
||
| import torch | ||
| import torch.nn.functional as F | ||
|
|
||
| # ``(q, k, v) -> out`` over packed ``[total_tokens, H, D]`` tensors, one segment per request. | ||
| RaggedAttentionFn = Callable[[torch.Tensor, torch.Tensor, torch.Tensor], torch.Tensor] | ||
|
|
||
|
|
||
| def sdpa_attention(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor: | ||
| """Bidirectional attention over ``[B, S, H, D]`` tensors via SDPA; returns ``[B, S, H, D]``.""" | ||
| out = F.scaled_dot_product_attention( | ||
| q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2), is_causal=False, | ||
| ) | ||
| return out.transpose(1, 2) | ||
|
|
||
|
|
||
| def joint_attention( | ||
| q: torch.Tensor, k: torch.Tensor, v: torch.Tensor, ragged: RaggedAttentionFn | None = None, | ||
| ) -> torch.Tensor: | ||
| """Attention over ``[B, S, H, D]`` q/k/v (all requests in the batch share | ||
| ``S``) through the ragged resource when one is bound, else SDPA. | ||
|
|
||
| The ragged kernel wants the batch packed to ``[B * S, H, D]`` with one | ||
| segment of ``S`` tokens per request — exactly what the owning submodule | ||
| declared in its step — and hands back the same packing. | ||
| """ | ||
| if ragged is None: | ||
| return sdpa_attention(q, k, v) | ||
| bsz, seq, heads, dim = q.shape | ||
| out = ragged( | ||
| q.reshape(bsz * seq, heads, dim), k.reshape(bsz * seq, heads, dim), v.reshape(bsz * seq, heads, dim), | ||
| ) | ||
| return out.view(bsz, seq, heads, dim).to(q.dtype) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to also move Wan, BAGEL, etc. to the scaffold in this PR, or should that be a separate change (If so, can you put up an issue for it)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(will do this as a different change and put up an issue for it)