You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/en/modular_diffusers/developer_guide.md
+39-20Lines changed: 39 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -169,16 +169,26 @@ and you would get the same result as the original img2img pipeline.
169
169
170
170
Let's modify the pipeline so that we can get expected result with this example script.
171
171
172
-
We'll start with the `prepare_latents` step, as it is the first step that gets called right after the `input` step. The main changes are:
173
-
- new input `diffdiff_map`: It will become a new input to the pipeline after we built it.
174
-
-`num_inference_steps` and `timestesp` as intermediates inputs: Both variables are created in `set_timesteps` block, we need to list them as intermediates inputs so that we can now use them in `__call__`.
175
-
- A new component `mask_processor`: A default one will be created when we build the pipeline, but user can update it.
176
-
- Inside `__call__`, we created 2 new variables: the change map `diffdiff_mask` and the pre-computed noised latents for all timesteps `original_latents`. We also need to list them as intermediates outputs so the we can use them in the `denoise` step later.
177
-
178
-
I have two tips I want to share for this process:
179
-
1. use `print(dd_pipeline.doc)` to check compiled inputs and outputs of the built piepline.
172
+
We'll start with the `prepare_latents` step, as it is the first step that gets called right after the `input` step. Let's first apply changes in inputs/outputs/components. The main changes are:
173
+
- new input `diffdiff_map`
174
+
- new intermediates inputs `num_inference_steps` and `timestesp`. Both variables are already created in `set_timesteps` block, we can now need to use them in `prepare_latents` step.
175
+
- A new component `mask_processor` to process the `diffdiff_map`
176
+
177
+
<Tip>
178
+
179
+
💡 use `print(dd_pipeline.doc)` to check compiled inputs and outputs of the built piepline.
180
+
180
181
e.g. after we added `diffdiff_map` as an input in this step, we can run `print(dd_pipeline.doc)` to verify that it shows up in the docstring as a user input.
181
-
2. insert `print(state)` and `print(block_state)` everywhere inside the `__call__` method to inspect the intermediate results.
182
+
183
+
</Tip>
184
+
185
+
Once we make sure all the variables we need are available in the block state, we can implement the diff-diff logic inside `__call__`. We created 2 new variables: the change map `diffdiff_mask` and the pre-computed noised latents for all timesteps `original_latents`. We also need to list them as intermediates outputs so the we can use them in the `denoise` step later.
186
+
187
+
<Tip>
188
+
189
+
💡 Implement incrementally! Run the example script as you go, and insert `print(state)` and `print(block_state)` everywhere inside the `__call__` method to inspect the intermediate results. This helps you understand what's going on and what each line you just added does.
190
+
191
+
</Tip>
182
192
183
193
This is the modified `StableDiffusionXLImg2ImgPrepareLatentsStep` we ended up with :
184
194
```diff
@@ -265,7 +275,7 @@ This is the modified `StableDiffusionXLImg2ImgPrepareLatentsStep` we ended up wi
265
275
self.add_block_state(state, block_state)
266
276
```
267
277
268
-
This is the modified`before_denoiser` step, we use diff-diff map to freeze certain regions in the latents before each denoising step.
278
+
Now let's modify`before_denoiser` step, we use diff-diff map to freeze certain regions in the latents before each denoising step.
269
279
270
280
```diff
271
281
class SDXLDiffDiffLoopBeforeDenoiser(PipelineBlock):
@@ -324,10 +334,15 @@ class SDXLDiffDiffLoopBeforeDenoiser(PipelineBlock):
324
334
return components, block_state
325
335
```
326
336
327
-
That's all there is to it! Now your script should run as expected and get a result like this one.
337
+
That's all there is to it! We've just created a simple sequential pipeline by mix-and-match some existing and new pipeline blocks.
338
+
339
+
340
+
<Tip>
341
+
342
+
💡 You can inspect the pipeline you built with `print()`
343
+
344
+
</Tip>
328
345
329
-
Here is the pipeline we created ( hint, `print(dd_blocks)`)
330
-
It is a simple sequential pipeline.
331
346
332
347
```out
333
348
SequentialPipelineBlocks(
@@ -515,7 +530,7 @@ SequentialPipelineBlocks(
515
530
)
516
531
```
517
532
518
-
Let's test it out. I used an orange image to condition the generation via ip-addapter and we can see a slight orange color and texture in the final output.
533
+
Let's test it out. We used an orange image to condition the generation via ip-addapter and we can see a slight orange color and texture in the final output.
519
534
520
535
521
536
```py
@@ -551,8 +566,8 @@ Let's test it out. I used an orange image to condition the generation via ip-add
551
566
## Working with ControlNets
552
567
553
568
What about controlnet? Can differential diffusion work with controlnet? The key differences between a regular pipeline and a ControlNet pipeline are:
554
-
* A ControlNet input step that prepares the control condition
555
-
* Inside the denoising loop, a modified denoiser step where the control image is first processed through ControlNet, then control information is injected into the UNet
569
+
1. A ControlNet input step that prepares the control condition
570
+
2. Inside the denoising loop, a modified denoiser step where the control image is first processed through ControlNet, then control information is injected into the UNet
556
571
557
572
From looking at the code workflow: differential diffusion only modifies the "before denoiser" step, while ControlNet operates within the "denoiser" itself. Since they intervene at different points in the pipeline, they should work together without conflicts.
558
573
@@ -569,7 +584,7 @@ With this understanding, let's assemble the `SDXLDiffDiffControlNetDenoiseLoop`:
569
584
>>># print(controlnet_denoise)
570
585
```
571
586
572
-
We provide a auto controlnet input block that you can directly put into your workflow: similar to auto ip-adapter block, this step will only run if `control_image` input is passed from user. It work with both controlnet and controlnet union.
587
+
We provide a auto controlnet input block that you can directly put into your workflow to proceess the `control_image`: similar to auto ip-adapter block, this step will only run if `control_image` input is passed from user. It work with both controlnet and controlnet union.
Let's assemble the blocks and run an example using controlnet + differential diffusion. I used a canny of a tomato as `control_image`, so you can see in the output, the right half that transformed into a pear had a tomato-like shape.
627
+
Let's assemble the blocks and run an example using controlnet + differential diffusion. We used a tomato as `control_image`, so you can see that in the output, the right half that transformed into a pear had a tomato-like shape.
@@ -652,9 +667,13 @@ Optionally, We can combine `SDXLDiffDiffControlNetDenoiseLoop` and `SDXLDiffDiff
652
667
653
668
`SDXLDiffDiffAutoDenoiseStep` will run the ControlNet denoise step if `control_image` input is provided, otherwise it will run the regular denoise step.
654
669
655
-
We won't go into too much detail about `AutoPipelineBlocks` in this section, but you can read more about it [here](TODO). Note that it's perfectly fine not to use `AutoPipelineBlocks`. In fact, we recommend only using `AutoPipelineBlocks` to package your workflow at the end once you've verified all your pipelines work as expected.
670
+
<Tip>
671
+
672
+
Note that it's perfectly fine not to use `AutoPipelineBlocks`. In fact, we recommend only using `AutoPipelineBlocks` to package your workflow at the end once you've verified all your pipelines work as expected. We won't go into too much detail about `AutoPipelineBlocks` in this section, but you can read more about it [here](TODO).
673
+
674
+
</Tip>
656
675
657
-
now you can create the differential diffusion preset that works with ip-adapter & controlnet.
676
+
Now you can create the differential diffusion preset that works with ip-adapter & controlnet.
0 commit comments