# AutoPipelineBlocks

[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) は、異なるワークフローをサポートするブロックを含むマルチブロック型です。実行時に提供される入力に基づいて、実行するサブブロックを自動的に選択します。通常、テキストから画像への変換、画像から画像への変換、インペイントといった複数のワークフローを、利便性のため単一のパイプラインにパッケージ化する際に使用されます。

このガイドでは、[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks)の作成方法を示します。

テキストから画像への変換、画像から画像への変換、インペインティングの3つの[ModularPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)を作成します。これらは、パイプラインで利用可能な異なるワークフローを表しています。

```py
import torch
from diffusers.modular_pipelines import ModularPipelineBlocks, InputParam, OutputParam

class TextToImageBlock(ModularPipelineBlocks):
    model_name = "text2img"

    @property
    def inputs(self):
        return [InputParam(name="prompt")]

    @property
    def intermediate_outputs(self):
        return []

    @property
    def description(self):
        return "I'm a text-to-image workflow!"

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        print("running the text-to-image workflow")
        # Add your text-to-image logic here
        # For example: generate image from prompt
        self.set_block_state(state, block_state)
        return components, state
```

```py
class ImageToImageBlock(ModularPipelineBlocks):
    model_name = "img2img"

    @property
    def inputs(self):
        return [InputParam(name="prompt"), InputParam(name="image")]

    @property
    def intermediate_outputs(self):
        return []

    @property
    def description(self):
        return "I'm an image-to-image workflow!"

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        print("running the image-to-image workflow")
        # Add your image-to-image logic here
        # For example: transform input image based on prompt
        self.set_block_state(state, block_state)
        return components, state
```

```py
class InpaintBlock(ModularPipelineBlocks):
    model_name = "inpaint"

    @property
    def inputs(self):
        return [InputParam(name="prompt"), InputParam(name="image"), InputParam(name="mask")]

    @property
    def intermediate_outputs(self):
        return []

    @property
    def description(self):
        return "I'm an inpaint workflow!"

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        print("running the inpaint workflow")
        # Add your inpainting logic here
        # For example: fill masked areas based on prompt
        self.set_block_state(state, block_state)
        return components, state
```

サブブロックのクラスとその対応するブロック名のリストを含む[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks)クラスを作成します。

また、対応するブロックをトリガーする入力名のリストである`block_trigger_inputs`を含める必要があります。実行時にトリガー入力が提供された場合、そのブロックが実行対象として選択されます。トリガー入力が検出されない場合に実行するデフォルトのブロックを指定するには、`None`を使用します。

最後に、どの入力がどのワークフローをトリガーするかを明確に説明する`description`を含めることが重要です。これにより、ユーザーは特定のワークフローの実行方法を理解しやすくなります。

```py
from diffusers.modular_pipelines import AutoPipelineBlocks

class AutoImageBlocks(AutoPipelineBlocks):
    # List of sub-block classes to choose from
    block_classes = [InpaintBlock, ImageToImageBlock, TextToImageBlock]
    # Names for each block in the same order
    block_names = ["inpaint", "img2img", "text2img"]
    # Trigger inputs that determine which block to run
    # - "mask" triggers inpaint workflow
    # - "image" triggers img2img workflow (but only if mask is not provided)
    # - if none of above, runs the text2img workflow (default)
    block_trigger_inputs = ["mask", "image", None]

    @property
    def description(self):
        return (
            "Pipeline generates images given different types of conditions!\n"
            + "This is an auto pipeline block that works for text2img, img2img and inpainting tasks.\n"
            + " - inpaint workflow is run when `mask` is provided.\n"
            + " - img2img workflow is run when `image` is provided (but only when `mask` is not provided).\n"
            + " - text2img workflow is run when neither `image` nor `mask` is provided.\n"
        )
```

ブロックの実行方法や必要な入力について混乱を避けるため、`description`を含めることは**非常に**重要です。[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks)は便利ですが、適切に説明されていない場合、その条件分岐ロジックを理解するのが困難になる可能性があります。

`AutoImageBlocks`のインスタンスを作成します。

```py
auto_blocks = AutoImageBlocks()
```

ネストされた[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks)ブロックがより大きなパイプライン内でサブブロックとして使用される場合など、より複雑な構成については、[get_execution_blocks()](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks.get_execution_blocks)メソッドを使用して、入力に基づいて実際に実行されるブロックを抽出します。

```py
auto_blocks.get_execution_blocks(mask=True)
```

## ConditionalPipelineBlocks

[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) は [ConditionalPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks) の特殊なケースです。[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) はトリガー入力が提供されているかどうかに基づいてブロックを選択するのに対し、[ConditionalPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks) は `select_block` メソッドで提供されるカスタムな選択ロジックに基づいてブロックを選択できます。

[ConditionalPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks) を直接使用して記述した同じ例を以下に示します。

```py
from diffusers.modular_pipelines import ConditionalPipelineBlocks

class AutoImageBlocks(ConditionalPipelineBlocks):
    block_classes = [InpaintBlock, ImageToImageBlock, TextToImageBlock]
    block_names = ["inpaint", "img2img", "text2img"]
    block_trigger_inputs = ["mask", "image"]
    default_block_name = "text2img"

    @property
    def description(self):
        return (
            "Pipeline generates images given different types of conditions!\n"
            + "This is an auto pipeline block that works for text2img, img2img and inpainting tasks.\n"
            + " - inpaint workflow is run when `mask` is provided.\n"
            + " - img2img workflow is run when `image` is provided (but only when `mask` is not provided).\n"
            + " - text2img workflow is run when neither `image` nor `mask` is provided.\n"
        )

    def select_block(self, mask=None, image=None) -> str | None:
        if mask is not None:
            return "inpaint"
        if image is not None:
            return "img2img"
        return None  # falls back to default_block_name ("text2img")
```

`block_trigger_inputs` に列挙された入力は、`select_block()` へのキーワード引数として渡されます。`select_block` が `None` を返す場合、`default_block_name` にフォールバックします。`default_block_name` も `None` の場合、条件付きブロック全体がスキップされます。これは、特定の入力が提供された場合のみ実行されるべき任意の処理ステップに有用です。

## ワークフロー

条件ブロック（[AutoPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks)または[ConditionalPipelineBlocks](/docs/diffusers/v0.43.0/ja/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks)）を含むパイプラインは、複数のワークフローをサポートできます。例えば、当社のSDXLモジュラーパイプラインでは、1つのパイプラインで12ものワークフローをサポートしています。しかし、それゆえに、ユーザーがどのワークフローがサポートされているのか、またそれらをどのように実行するのかを理解するのが難しくなる可能性があります。パイプラインのビルダーにとって、特定のワークフローに関連するブロックのみを抽出できることは有用です。

各ワークフローに名前を付け、必要な入力を明示的に列挙するために、`_workflow_map` を定義することをお勧めします。

```py
from diffusers.modular_pipelines import SequentialPipelineBlocks

class MyPipelineBlocks(SequentialPipelineBlocks):
    block_classes = [TextEncoderBlock, AutoImageBlocks, DecodeBlock]
    block_names = ["text_encoder", "auto_image", "decode"]

    _workflow_map = {
        "text2image": {"prompt": True},
        "image2image": {"image": True, "prompt": True},
        "inpaint": {"mask": True, "image": True, "prompt": True},
    }
```

組み込みのモジュラーパイプラインにはすべて、事前定義されたワークフローが用意されています。`available_workflows`プロパティは、サポートされているすべてのワークフローをリストします。

```py
pipeline_blocks = MyPipelineBlocks()
pipeline_blocks.available_workflows
# ['text2image', 'image2image', 'inpaint']
```

`get_workflow` を使用して特定のワークフローを取得し、そのワークフローを実行する特定のブロックを調査・デバッグします。

```py
pipeline_blocks.get_workflow("inpaint")
```

