Skip to content

Commit e9c092d

Browse files
yiyixuxuyiyi@huggingface.co
andauthored
[agent] add modular doc (#13410)
* merge * update based on feedback --------- Co-authored-by: yiyi@huggingface.co <yiyi@ip-26-0-160-103.ec2.internal>
1 parent f65f135 commit e9c092d

4 files changed

Lines changed: 46 additions & 15 deletions

File tree

.ai/AGENTS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Strive to write code as simple and explicit as possible.
3535
- Use `self.progress_bar(timesteps)` for progress tracking
3636
- 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`)
3737

38+
### Modular Pipelines
39+
40+
- See [modular.md](modular.md) for modular pipeline conventions, patterns, and gotchas.
41+
3842
## Skills
3943

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

.ai/skills/model-integration/modular-conversion.md renamed to .ai/modular.md

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
# Modular Pipeline Conversion Reference
1+
# Modular pipeline conventions and rules
22

3-
## When to use
4-
5-
Modular pipelines break a monolithic `__call__` into composable blocks. Convert when:
6-
- The model supports multiple workflows (T2V, I2V, V2V, etc.)
7-
- Users need to swap guidance strategies (CFG, CFG-Zero*, PAG)
8-
- You want to share blocks across pipeline variants
3+
Shared reference for modular pipeline conventions, patterns, and gotchas.
94

105
## File structure
116

@@ -14,7 +9,7 @@ src/diffusers/modular_pipelines/<model>/
149
__init__.py # Lazy imports
1510
modular_pipeline.py # Pipeline class (tiny, mostly config)
1611
encoders.py # Text encoder + image/video VAE encoder blocks
17-
before_denoise.py # Pre-denoise setup blocks
12+
before_denoise.py # Pre-denoise setup blocks (timesteps, latent prep, noise)
1813
denoise.py # The denoising loop blocks
1914
decoders.py # VAE decode block
2015
modular_blocks_<model>.py # Block assembly (AutoBlocks)
@@ -81,15 +76,27 @@ for i, t in enumerate(timesteps):
8176
latents = components.scheduler.step(noise_pred, t, latents, generator=generator)[0]
8277
```
8378

84-
## Key pattern: Chunk loops for video models
79+
## Key pattern: Denoising loop
80+
81+
All models use `LoopSequentialPipelineBlocks` for the denoising loop (iterating over timesteps):
82+
```python
83+
class MyModelDenoiseLoopWrapper(LoopSequentialPipelineBlocks):
84+
block_classes = [LoopBeforeDenoiser, LoopDenoiser, LoopAfterDenoiser]
85+
```
8586

86-
Use `LoopSequentialPipelineBlocks` for outer loop:
87+
Autoregressive video models (e.g. Helios) also use it for an outer chunk loop:
8788
```python
88-
class ChunkDenoiseStep(LoopSequentialPipelineBlocks):
89-
block_classes = [PrepareChunkStep, NoiseGenStep, DenoiseInnerStep, UpdateStep]
89+
class HeliosChunkDenoiseStep(HeliosChunkLoopWrapper):
90+
block_classes = [
91+
HeliosChunkHistorySliceStep,
92+
HeliosChunkNoiseGenStep,
93+
HeliosChunkSchedulerResetStep,
94+
HeliosChunkDenoiseInner,
95+
HeliosChunkUpdateStep,
96+
]
9097
```
9198

92-
Note: blocks inside `LoopSequentialPipelineBlocks` receive `(components, block_state, k)` where `k` is the loop iteration index.
99+
Note: sub-blocks inside `LoopSequentialPipelineBlocks` receive `(components, block_state, i, t)` for denoise loops or `(components, block_state, k)` for chunk loops.
93100

94101
## Key pattern: Workflow selection
95102

@@ -136,6 +143,26 @@ ComponentSpec(
136143
)
137144
```
138145

146+
## Gotchas
147+
148+
1. **Importing from standard pipelines.** The modular and standard pipeline systems are parallel — modular blocks must not import from `diffusers.pipelines.*`. For shared utility methods (e.g. `_pack_latents`, `retrieve_timesteps`), either redefine as standalone functions or use `# Copied from diffusers.pipelines.<model>...` headers. See `wan/before_denoise.py` and `helios/before_denoise.py` for examples.
149+
150+
2. **Cross-importing between modular pipelines.** Don't import utilities from another model's modular pipeline (e.g. SD3 importing from `qwenimage.inputs`). If a utility is shared, move it to `modular_pipeline_utils.py` or copy it with a `# Copied from` header.
151+
152+
3. **Accepting `guidance_scale` as a pipeline input.** Users configure the guider separately (see [guider docs](https://huggingface.co/docs/diffusers/main/en/api/guiders)). Different guider types have different parameters; forwarding them through the pipeline doesn't scale. Don't manually set `components.guider.guidance_scale = ...` inside blocks. Same applies to computing `do_classifier_free_guidance` — that logic belongs in the guider.
153+
154+
4. **Accepting pre-computed outputs as inputs to skip encoding.** In standard pipelines we accept `prompt_embeds`, `negative_prompt_embeds`, `image_latents`, etc. so users can skip encoding steps. In modular pipelines this is unnecessary — users just pop out the encoder block and run it separately. Encoder blocks should only accept raw inputs (`prompt`, `image`, etc.).
155+
156+
5. **VAE encoding inside prepare-latents.** Image encoding should be its own block in `encoders.py` (e.g. `MyModelVaeEncoderStep`). The prepare-latents block should accept `image_latents`, not raw images. This lets users run encoding standalone. See `WanVaeEncoderStep` for reference.
157+
158+
6. **Instantiating components inline.** If a class like `VideoProcessor` is needed, register it as a `ComponentSpec` and access via `components.video_processor`. Don't create new instances inside block `__call__`.
159+
160+
7. **Deeply nested block structure.** Prefer flat sequences over nesting Auto blocks inside Sequential blocks inside Auto blocks. Put the `Auto` selection at the top level and make each workflow variant a flat `InsertableDict` of leaf blocks. See `flux2/modular_blocks_flux2_klein.py` for the pattern.
161+
162+
8. **Using `InputParam.template()` / `OutputParam.template()` when semantics don't match.** Templates carry predefined descriptions — e.g. the `"latents"` output template means "Denoised latents". Don't use it for initial noisy latents from a prepare-latents step. Use a plain `InputParam(...)` / `OutputParam(...)` with an accurate description instead.
163+
164+
9. **Test model paths pointing to contributor repos.** Tiny test models must live under `hf-internal-testing/`, not personal repos like `username/tiny-model`. Move the model before merge.
165+
139166
## Conversion checklist
140167

141168
- [ ] Read original pipeline's `__call__` end-to-end, map stages

.ai/review-rules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Review-specific rules for Claude. Focus on correctness — style is handled by r
55
Before reviewing, read and apply the guidelines in:
66
- [AGENTS.md](AGENTS.md) — coding style, copied code
77
- [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
8+
- [modular.md](modular.md) — modular pipeline conventions, patterns, common mistakes
99
- [skills/parity-testing/SKILL.md](skills/parity-testing/SKILL.md) — testing rules, comparison utilities
1010
- [skills/parity-testing/pitfalls.md](skills/parity-testing/pitfalls.md) — known pitfalls (dtype mismatches, config assumptions, etc.)
1111

.ai/skills/model-integration/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ See [../../models.md](../../models.md) for the attention pattern, implementation
8282

8383
## Modular Pipeline Conversion
8484

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.
85+
See [modular.md](../../modular.md) for the full guide on modular pipeline conventions, block types, build order, guider abstraction, gotchas, and conversion checklist.
8686

8787
---
8888

0 commit comments

Comments
 (0)