Skip to content

Commit f2ac074

Browse files
authored
Merge branch 'main' into feature/flux2-klein-inpaint
2 parents eac2a72 + 6a339ce commit f2ac074

323 files changed

Lines changed: 20230 additions & 5155 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ai/AGENTS.md

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,68 +10,34 @@ Strive to write code as simple and explicit as possible.
1010

1111
---
1212

13-
### Dependencies
14-
- No new mandatory dependency without discussion (e.g. `einops`)
15-
- Optional deps guarded with `is_X_available()` and a dummy in `utils/dummy_*.py`
16-
1713
## Code formatting
14+
1815
- `make style` and `make fix-copies` should be run as the final step before opening a PR
1916

2017
### Copied Code
18+
2119
- Many classes are kept in sync with a source via a `# Copied from ...` header comment
2220
- Do not edit a `# Copied from` block directly — run `make fix-copies` to propagate changes from the source
2321
- Remove the header to intentionally break the link
2422

2523
### Models
26-
- All layer calls should be visible directly in `forward` — avoid helper functions that hide `nn.Module` calls.
27-
- Try to not introduce graph breaks as much as possible for better compatibility with `torch.compile`. For example, DO NOT arbitrarily insert operations from NumPy in the forward implementations.
28-
- Attention must follow the diffusers pattern: both the `Attention` class and its processor are defined in the model file. The processor's `__call__` handles the actual compute and must use `dispatch_attention_fn` rather than calling `F.scaled_dot_product_attention` directly. The attention class inherits `AttentionModuleMixin` and declares `_default_processor_cls` and `_available_processors`.
29-
30-
```python
31-
# transformer_mymodel.py
32-
33-
class MyModelAttnProcessor:
34-
_attention_backend = None
35-
_parallel_config = None
36-
37-
def __call__(self, attn, hidden_states, attention_mask=None, ...):
38-
query = attn.to_q(hidden_states)
39-
key = attn.to_k(hidden_states)
40-
value = attn.to_v(hidden_states)
41-
# reshape, apply rope, etc.
42-
hidden_states = dispatch_attention_fn(
43-
query, key, value,
44-
attn_mask=attention_mask,
45-
backend=self._attention_backend,
46-
parallel_config=self._parallel_config,
47-
)
48-
hidden_states = hidden_states.flatten(2, 3)
49-
return attn.to_out[0](hidden_states)
50-
51-
52-
class MyModelAttention(nn.Module, AttentionModuleMixin):
53-
_default_processor_cls = MyModelAttnProcessor
54-
_available_processors = [MyModelAttnProcessor]
5524

56-
def __init__(self, query_dim, heads=8, dim_head=64, ...):
57-
super().__init__()
58-
self.to_q = nn.Linear(query_dim, heads * dim_head, bias=False)
59-
self.to_k = nn.Linear(query_dim, heads * dim_head, bias=False)
60-
self.to_v = nn.Linear(query_dim, heads * dim_head, bias=False)
61-
self.to_out = nn.ModuleList([nn.Linear(heads * dim_head, query_dim), nn.Dropout(0.0)])
62-
self.set_processor(MyModelAttnProcessor())
25+
- See [models.md](models.md) for model conventions, attention pattern, implementation rules, dependencies, and gotchas.
26+
- See the [model-integration](./skills/model-integration/SKILL.md) skill for the full integration workflow, file structure, test setup, and other details.
6327

64-
def forward(self, hidden_states, attention_mask=None, **kwargs):
65-
return self.processor(self, hidden_states, attention_mask, **kwargs)
66-
```
28+
### Pipelines & Schedulers
6729

68-
Consult the implementations in `src/diffusers/models/transformers/` if you need further references.
30+
- Pipelines inherit from `DiffusionPipeline`
31+
- Schedulers use `SchedulerMixin` with `ConfigMixin`
32+
- Use `@torch.no_grad()` on pipeline `__call__`
33+
- Support `output_type="latent"` for skipping VAE decode
34+
- Support `generator` parameter for reproducibility
35+
- Use `self.progress_bar(timesteps)` for progress tracking
36+
- Don't subclass an existing pipeline for a variant — DO NOT use an existing pipeline class (e.g., `FluxPipeline`) to override another pipeline (e.g., `FluxImg2ImgPipeline`) which will be a part of the core codebase (`src`)
6937

70-
### Pipeline
71-
- All pipelines must inherit from `DiffusionPipeline`. Consult implementations in `src/diffusers/pipelines` in case you need references.
72-
- DO NOT use an existing pipeline class (e.g., `FluxPipeline`) to override another pipeline (e.g., `FluxImg2ImgPipeline` which will be a part of the core codebase (`src`).
38+
## Skills
7339

40+
Task-specific guides live in `.ai/skills/` and are loaded on demand by AI agents. Available skills include:
7441

75-
### Tests
76-
- Slow tests gated with `@slow` and `RUN_SLOW=1`
77-
- All model-level tests must use the `BaseModelTesterConfig`, `ModelTesterMixin`, `MemoryTesterMixin`, `AttentionTesterMixin`, `LoraTesterMixin`, and `TrainingTesterMixin` classes initially to write the tests. Any additional tests should be added after discussions with the maintainers. Use `tests/models/transformers/test_models_transformer_flux.py` as a reference.
42+
- [model-integration](./skills/model-integration/SKILL.md) (adding/converting pipelines)
43+
- [parity-testing](./skills/parity-testing/SKILL.md) (debugging numerical parity).

.ai/models.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Model conventions and rules
2+
3+
Shared reference for model-related conventions, patterns, and gotchas.
4+
Linked from `AGENTS.md`, `skills/model-integration/SKILL.md`, and `review-rules.md`.
5+
6+
## Coding style
7+
8+
- All layer calls should be visible directly in `forward` — avoid helper functions that hide `nn.Module` calls.
9+
- Avoid graph breaks for `torch.compile` compatibility — do not insert NumPy operations in forward implementations and any other patterns that can break `torch.compile` compatibility with `fullgraph=True`.
10+
- No new mandatory dependency without discussion (e.g. `einops`). Optional deps guarded with `is_X_available()` and a dummy in `utils/dummy_*.py`.
11+
12+
## Common model conventions
13+
14+
- Models use `ModelMixin` with `register_to_config` for config serialization
15+
16+
## Attention pattern
17+
18+
Attention must follow the diffusers pattern: both the `Attention` class and its processor are defined in the model file. The processor's `__call__` handles the actual compute and must use `dispatch_attention_fn` rather than calling `F.scaled_dot_product_attention` directly. The attention class inherits `AttentionModuleMixin` and declares `_default_processor_cls` and `_available_processors`.
19+
20+
```python
21+
# transformer_mymodel.py
22+
23+
class MyModelAttnProcessor:
24+
_attention_backend = None
25+
_parallel_config = None
26+
27+
def __call__(self, attn, hidden_states, attention_mask=None, ...):
28+
query = attn.to_q(hidden_states)
29+
key = attn.to_k(hidden_states)
30+
value = attn.to_v(hidden_states)
31+
# reshape, apply rope, etc.
32+
hidden_states = dispatch_attention_fn(
33+
query, key, value,
34+
attn_mask=attention_mask,
35+
backend=self._attention_backend,
36+
parallel_config=self._parallel_config,
37+
)
38+
hidden_states = hidden_states.flatten(2, 3)
39+
return attn.to_out[0](hidden_states)
40+
41+
42+
class MyModelAttention(nn.Module, AttentionModuleMixin):
43+
_default_processor_cls = MyModelAttnProcessor
44+
_available_processors = [MyModelAttnProcessor]
45+
46+
def __init__(self, query_dim, heads=8, dim_head=64, ...):
47+
super().__init__()
48+
self.to_q = nn.Linear(query_dim, heads * dim_head, bias=False)
49+
self.to_k = nn.Linear(query_dim, heads * dim_head, bias=False)
50+
self.to_v = nn.Linear(query_dim, heads * dim_head, bias=False)
51+
self.to_out = nn.ModuleList([nn.Linear(heads * dim_head, query_dim), nn.Dropout(0.0)])
52+
self.set_processor(MyModelAttnProcessor())
53+
54+
def forward(self, hidden_states, attention_mask=None, **kwargs):
55+
return self.processor(self, hidden_states, attention_mask, **kwargs)
56+
```
57+
58+
Consult the implementations in `src/diffusers/models/transformers/` if you need further references.
59+
60+
## Gotchas
61+
62+
1. **Forgetting `__init__.py` lazy imports.** Every new class must be registered in the appropriate `__init__.py` with lazy imports. Missing this causes `ImportError` that only shows up when users try `from diffusers import YourNewClass`.
63+
64+
2. **Using `einops` or other non-PyTorch deps.** Reference implementations often use `einops.rearrange`. Always rewrite with native PyTorch (`reshape`, `permute`, `unflatten`). Don't add the dependency. If a dependency is truly unavoidable, guard its import: `if is_my_dependency_available(): import my_dependency`.
65+
66+
3. **Missing `make fix-copies` after `# Copied from`.** If you add `# Copied from` annotations, you must run `make fix-copies` to propagate them. CI will fail otherwise.
67+
68+
4. **Wrong `_supports_cache_class` / `_no_split_modules`.** These class attributes control KV cache and device placement. Copy from a similar model and verify -- wrong values cause silent correctness bugs or OOM errors.
69+
70+
5. **Missing `@torch.no_grad()` on pipeline `__call__`.** Forgetting this causes GPU OOM from gradient accumulation during inference.
71+
72+
6. **Config serialization gaps.** Every `__init__` parameter in a `ModelMixin` subclass must be captured by `register_to_config`. If you add a new param but forget to register it, `from_pretrained` will silently use the default instead of the saved value.
73+
74+
7. **Forgetting to update `_import_structure` and `_lazy_modules`.** The top-level `src/diffusers/__init__.py` has both -- missing either one causes partial import failures.
75+
76+
8. **Hardcoded dtype in model forward.** Don't hardcode `torch.float32` or `torch.bfloat16` in the model's forward pass. Use the dtype of the input tensors or `self.dtype` so the model works with any precision.

.ai/review-rules.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# PR Review Rules
2+
3+
Review-specific rules for Claude. Focus on correctness — style is handled by ruff.
4+
5+
Before reviewing, read and apply the guidelines in:
6+
- [AGENTS.md](AGENTS.md) — coding style, copied code
7+
- [models.md](models.md) — model conventions, attention pattern, implementation rules, dependencies, gotchas
8+
- [skills/model-integration/modular-conversion.md](skills/model-integration/modular-conversion.md) — modular pipeline patterns, block structure, key conventions
9+
- [skills/parity-testing/SKILL.md](skills/parity-testing/SKILL.md) — testing rules, comparison utilities
10+
- [skills/parity-testing/pitfalls.md](skills/parity-testing/pitfalls.md) — known pitfalls (dtype mismatches, config assumptions, etc.)
11+
12+
## Common mistakes (add new rules below this line)
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
name: integrating-models
3+
description: >
4+
Use when adding a new model or pipeline to diffusers, setting up file
5+
structure for a new model, converting a pipeline to modular format, or
6+
converting weights for a new version of an already-supported model.
7+
---
8+
9+
## Goal
10+
11+
Integrate a new model into diffusers end-to-end. The overall flow:
12+
13+
1. **Gather info** — ask the user for the reference repo, setup guide, a runnable inference script, and other objectives such as standard vs modular.
14+
2. **Confirm the plan** — once you have everything, tell the user exactly what you'll do: e.g. "I'll integrate model X with pipeline Y into diffusers based on your script. I'll run parity tests (model-level and pipeline-level) using the `parity-testing` skill to verify numerical correctness against the reference."
15+
3. **Implement** — write the diffusers code (model, pipeline, scheduler if needed), convert weights, register in `__init__.py`.
16+
4. **Parity test** — use the `parity-testing` skill to verify component and e2e parity against the reference implementation.
17+
5. **Deliver a unit test** — provide a self-contained test script that runs the diffusers implementation, checks numerical output (np allclose), and saves an image/video for visual verification. This is what the user runs to confirm everything works.
18+
19+
Work one workflow at a time — get it to full parity before moving on.
20+
21+
## Setup — gather before starting
22+
23+
Before writing any code, gather info in this order:
24+
25+
1. **Reference repo** — ask for the github link. If they've already set it up locally, ask for the path. Otherwise, ask what setup steps are needed (install deps, download checkpoints, set env vars, etc.) and run through them before proceeding.
26+
2. **Inference script** — ask for a runnable end-to-end script for a basic workflow first (e.g. T2V). Then ask what other workflows they want to support (I2V, V2V, etc.) and agree on the full implementation order together.
27+
3. **Standard vs modular** — standard pipelines, modular, or both?
28+
29+
Use `AskUserQuestion` with structured choices for step 3 when the options are known.
30+
31+
## Standard Pipeline Integration
32+
33+
### File structure for a new model
34+
35+
```
36+
src/diffusers/
37+
models/transformers/transformer_<model>.py # The core model
38+
schedulers/scheduling_<model>.py # If model needs a custom scheduler
39+
pipelines/<model>/
40+
__init__.py
41+
pipeline_<model>.py # Main pipeline
42+
pipeline_<model>_<variant>.py # Variant pipelines (e.g. pyramid, distilled)
43+
pipeline_output.py # Output dataclass
44+
loaders/lora_pipeline.py # LoRA mixin (add to existing file)
45+
46+
tests/
47+
models/transformers/test_models_transformer_<model>.py
48+
pipelines/<model>/test_<model>.py
49+
lora/test_lora_layers_<model>.py
50+
51+
docs/source/en/api/
52+
pipelines/<model>.md
53+
models/<model>_transformer3d.md # or appropriate name
54+
```
55+
56+
### Integration checklist
57+
58+
- [ ] Implement transformer model with `from_pretrained` support
59+
- [ ] Implement or reuse scheduler
60+
- [ ] Implement pipeline(s) with `__call__` method
61+
- [ ] Add LoRA support if applicable
62+
- [ ] Register all classes in `__init__.py` files (lazy imports)
63+
- [ ] Write unit tests (model, pipeline, LoRA)
64+
- [ ] Write docs
65+
- [ ] Run `make style` and `make quality`
66+
- [ ] Test parity with reference implementation (see `parity-testing` skill)
67+
68+
### Model conventions, attention pattern, and implementation rules
69+
70+
See [../../models.md](../../models.md) for the attention pattern, implementation rules, common conventions, dependencies, and gotchas. These apply to all model work.
71+
72+
### Model integration specific rules
73+
74+
**Don't combine structural changes with behavioral changes.** Restructuring code to fit diffusers APIs (ModelMixin, ConfigMixin, etc.) is unavoidable. But don't also "improve" the algorithm, refactor computation order, or rename internal variables for aesthetics. Keep numerical logic as close to the reference as possible, even if it looks unclean. For standard → modular, this is stricter: copy loop logic verbatim and only restructure into blocks. Clean up in a separate commit after parity is confirmed.
75+
76+
### Test setup
77+
78+
- Slow tests gated with `@slow` and `RUN_SLOW=1`
79+
- All model-level tests must use the `BaseModelTesterConfig`, `ModelTesterMixin`, `MemoryTesterMixin`, `AttentionTesterMixin`, `LoraTesterMixin`, and `TrainingTesterMixin` classes initially to write the tests. Any additional tests should be added after discussions with the maintainers. Use `tests/models/transformers/test_models_transformer_flux.py` as a reference.
80+
81+
---
82+
83+
## Modular Pipeline Conversion
84+
85+
See [modular-conversion.md](modular-conversion.md) for the full guide on converting standard pipelines to modular format, including block types, build order, guider abstraction, and conversion checklist.
86+
87+
---
88+
89+
## Weight Conversion Tips
90+
91+
<!-- TODO: Add concrete examples as we encounter them. Common patterns to watch for:
92+
- Fused QKV weights that need splitting into separate Q, K, V
93+
- Scale/shift ordering differences (reference stores [shift, scale], diffusers expects [scale, shift])
94+
- Weight transpositions (linear stored as transposed conv, or vice versa)
95+
- Interleaved head dimensions that need reshaping
96+
- Bias terms absorbed into different layers
97+
Add each with a before/after code snippet showing the conversion. -->

0 commit comments

Comments
 (0)