Skip to content

Commit bb40443

Browse files
committed
up
1 parent 1ae591e commit bb40443

1 file changed

Lines changed: 39 additions & 20 deletions

File tree

docs/source/en/modular_diffusers/developer_guide.md

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,26 @@ and you would get the same result as the original img2img pipeline.
169169

170170
Let's modify the pipeline so that we can get expected result with this example script.
171171

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+
180181
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>
182192

183193
This is the modified `StableDiffusionXLImg2ImgPrepareLatentsStep` we ended up with :
184194
```diff
@@ -265,7 +275,7 @@ This is the modified `StableDiffusionXLImg2ImgPrepareLatentsStep` we ended up wi
265275
self.add_block_state(state, block_state)
266276
```
267277

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.
269279

270280
```diff
271281
class SDXLDiffDiffLoopBeforeDenoiser(PipelineBlock):
@@ -324,10 +334,15 @@ class SDXLDiffDiffLoopBeforeDenoiser(PipelineBlock):
324334
return components, block_state
325335
```
326336

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>
328345

329-
Here is the pipeline we created ( hint, `print(dd_blocks)`)
330-
It is a simple sequential pipeline.
331346

332347
```out
333348
SequentialPipelineBlocks(
@@ -515,7 +530,7 @@ SequentialPipelineBlocks(
515530
)
516531
```
517532

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.
519534

520535

521536
```py
@@ -551,8 +566,8 @@ Let's test it out. I used an orange image to condition the generation via ip-add
551566
## Working with ControlNets
552567

553568
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
556571

557572
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.
558573

@@ -569,7 +584,7 @@ With this understanding, let's assemble the `SDXLDiffDiffControlNetDenoiseLoop`:
569584
>>> # print(controlnet_denoise)
570585
```
571586

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.
573588

574589

575590
```py
@@ -609,7 +624,7 @@ StableDiffusionXLControlNetAutoInput(
609624
)
610625
```
611626

612-
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.
613628

614629
```py
615630
>>> dd_blocks.blocks.insert("controlnet_input", control_input_block, 7)
@@ -652,9 +667,13 @@ Optionally, We can combine `SDXLDiffDiffControlNetDenoiseLoop` and `SDXLDiffDiff
652667

653668
`SDXLDiffDiffAutoDenoiseStep` will run the ControlNet denoise step if `control_image` input is provided, otherwise it will run the regular denoise step.
654669

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>
656675

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.
658677

659678
```py
660679
>>> DIFFDIFF_AUTO_BLOCKS = IMAGE2IMAGE_BLOCKS.copy()

0 commit comments

Comments
 (0)