Skip to content

Commit c67dda4

Browse files
committed
update
1 parent e3f111a commit c67dda4

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

docs/source/en/_toctree.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@
126126
title: ComponentsManager
127127
- local: modular_diffusers/guiders
128128
title: Guiders
129+
- local: modular_diffusers/custom_blocks
130+
title: Building Custom Blocks
129131

130132
- title: Training
131133
isExpanded: false

docs/source/en/modular_diffusers/custom_blocks.md

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,19 @@ specific language governing permissions and limitations under the License.
1313

1414
# Building Custom Blocks
1515

16-
Modular Diffusers allows you to create custom blocks that can be used in a pipeline. This guide will show you how to create a custom block, define its inputs and outputs, and implement the computation logic.
16+
Modular Diffusers allows you to create custom blocks that can be plugged into Modular Pipelines. This guide will show you how to create and use a custom block.
1717

18-
Let's create a custom block that uses the Florence2 model to process an input image and generate a mask for inpainting
18+
First let's take a look at the structure of our custom block project:
1919

20-
First let's define a custom block in a file called `block.py`:
20+
```shell
21+
.
22+
├── block.py
23+
└── modular_config.json
24+
```
25+
26+
The code to define the custom block lives in a file called `block.py`. The `modular_config.json` file contains metadata for loading the block with Modular Diffusers.
27+
28+
In this example, we will create a custom block that uses the Florence 2 model to process an input image and generate a mask for inpainting
2129

2230
```py
2331
from typing import List, Union
@@ -32,7 +40,7 @@ from diffusers.modular_pipelines import (
3240
ComponentSpec,
3341
OutputParam,
3442
)
35-
from transformers import AutoProcessor, AutoModelForCausalLM
43+
from transformers import AutoProcessor, Florence2ForConditionalGeneration
3644

3745

3846
class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
@@ -41,13 +49,13 @@ class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
4149
return [
4250
ComponentSpec(
4351
name="image_annotator",
44-
type_hint=AutoModelForCausalLM,
45-
repo="mrhendrey/Florence-2-large-ft-safetensors",
52+
type_hint=Florence2ForConditionalGeneration,
53+
repo="florence-community/Florence-2-base-ft",
4654
),
4755
ComponentSpec(
4856
name="image_annotator_processor",
4957
type_hint=AutoProcessor,
50-
repo="mrhendrey/Florence-2-large-ft-safetensors",
58+
repo="florence-community/Florence-2-base-ft",
5159
),
5260
]
5361

@@ -93,12 +101,10 @@ class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
93101
required=True,
94102
default="mask_image",
95103
description="""Output type from annotation predictions. Availabe options are
96-
annotation:
97-
- raw annotation predictions from the model based on task type.
98104
mask_image:
99105
-black and white mask image for the given image based on the task type
100106
mask_overlay:
101-
- white mask overlayed on the original image
107+
- mask overlayed on the original image
102108
bounding_box:
103109
- bounding boxes drawn on the original image
104110
""",
@@ -159,7 +165,7 @@ class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
159165
)
160166
return outputs
161167

162-
def prepare_mask(self, images, annotations, overlay=False):
168+
def prepare_mask(self, images, annotations, overlay=False, fill="white"):
163169
masks = []
164170
for image, annotation in zip(images, annotations):
165171
mask_image = image.copy() if overlay else Image.new("L", image.size, 0)
@@ -172,7 +178,7 @@ class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
172178
if len(polygon) < 3:
173179
continue
174180
polygon = polygon.reshape(-1).tolist()
175-
draw.polygon(polygon, fill="white")
181+
draw.polygon(polygon, fill=fill)
176182

177183
elif "bbox" in _annotation:
178184
bbox = _annotation["bbox"]
@@ -218,6 +224,7 @@ class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
218224
block_state.image, block_state.annotation_prompt
219225
)
220226
task = block_state.annotation_task
227+
fill = block_state.fill
221228

222229
annotations = self.get_annotations(
223230
components, images, annotation_task_prompt, task
@@ -229,7 +236,7 @@ class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
229236
block_state.mask_image = None
230237

231238
if block_state.annotation_output_type == "mask_overlay":
232-
block_state.image = self.prepare_mask(images, annotations, overlay=True)
239+
block_state.image = self.prepare_mask(images, annotations, overlay=True, fill=fill)
233240

234241
elif block_state.annotation_output_type == "bounding_box":
235242
block_state.image = self.prepare_bounding_boxes(images, annotations)
@@ -239,7 +246,7 @@ class Florence2ImageAnnotatorBlock(ModularPipelineBlocks):
239246
return components, state
240247
```
241248

242-
Once we have defined our custom block, we can save it as a model repo so that we can easily reuse it.
249+
Now that we have defined our custom block, we can save it as a model repository on the Huggingface Hub so that it is easy to share and reuse.
243250

244251
There are two ways to save the block:
245252

@@ -275,7 +282,7 @@ from diffusers.modular_pipelines.stable_diffusion_xl import INPAINT_BLOCKS
275282
from diffusers.utils import load_image
276283

277284
# Fetch the Florence2 image annotator block that will create our mask
278-
image_annotator_block = ModularPipelineBlocks.from_pretrained("diffusers/florence2-image-annotator", trust_remote_code=True)
285+
image_annotator_block = ModularPipelineBlocks.from_pretrained("diffusers/florence-2-custom-block", trust_remote_code=True)
279286

280287
my_blocks = INPAINT_BLOCKS.copy()
281288
# insert the annotation block before the image encoding step
@@ -284,7 +291,7 @@ my_blocks.insert("image_annotator", image_annotator_block, 1)
284291
# Create our initial set of inpainting blocks
285292
blocks = SequentialPipelineBlocks.from_blocks_dict(my_blocks)
286293

287-
repo_id = "diffusers-internal-dev/modular-sdxl-inpainting"
294+
repo_id = "diffusers/modular-stable-diffusion-xl-base-1.0"
288295
pipe = blocks.init_pipeline(repo_id)
289296
pipe.load_components(torch_dtype=torch.float16, device_map="cuda", trust_remote_code=True)
290297

0 commit comments

Comments
 (0)