# クイックスタート

Modular Diffusersは、柔軟でカスタマイズ可能なパイプラインを迅速に構築するためのフレームワークです。これらのパイプラインは、標準的な`DiffusionPipeline`の機能を超えた処理を行うことができます。Modular Diffusersの中核をなすのは[ModularPipelineBlocks](/docs/diffusers/main/ja/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)であり、他のブロックと組み合わせることで新しいワークフローに対応できます。これらのブロックは、生成タスクを実行するためのユーザーフレンドリーなインターフェースである[ModularPipeline](/docs/diffusers/main/ja/api/modular_diffusers/pipeline#diffusers.ModularPipeline)に変換されます。

このガイドでは、モジュラーパイプラインの実行方法、その構造の理解、そしてそれを構成するブロックを変更することによるカスタマイズ方法について説明します。[DiffusionPipeline](/docs/diffusers/main/ja/api/pipelines/overview#diffusers.DiffusionPipeline)に精通している場合は、動作の違いについて理解するために、まず[DiffusionPipelineからの移行](./coming_from_diffusion_pipeline)をお読みください。

## パイプラインの実行

[ModularPipeline](/docs/diffusers/main/ja/api/modular_diffusers/pipeline#diffusers.ModularPipeline)は、モジュラーパイプラインの読み込み、実行、および管理を行うためのメインインターフェースです。
```py
import torch
from diffusers import ModularPipeline, ComponentsManager

# Use ComponentsManager to enable auto CPU offloading for memory efficiency
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda:0")

pipe = ModularPipeline.from_pretrained("Qwen/Qwen-Image", components_manager=manager)
pipe.load_components(dtype=torch.bfloat16)

image = pipe(
    prompt="cat wizard with red hat, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney",
).images[0]
image
```

[from_pretrained()](/docs/diffusers/main/ja/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) は遅延読み込みを使用します。設定を読み取って各コンポーネントの読み込み先を把握しますが、[load_components()](/docs/diffusers/main/ja/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) を呼び出すまで実際のモデルの重みは読み込まれません。これにより、コンポーネントの読み込みタイミングと方法を制御できます。

> [!TIP]
> `ComponentsManager`に`enable_auto_cpu_offload`を指定すると、必要に応じてモデルをCPUとGPUの間で自動的に移動し、Qwen-Imageのような大規模モデルのメモリ使用量を削減します。詳細は[ComponentsManager](./components_manager)ガイドを参照してください。
>
> オフローディングが不要な場合は、`components_manager` 引数を削除し、`to("cuda")` を使用してパイプラインを手動でデバイスに移動してください。

[パイプラインの作成](https://huggingface.co/docs/diffusers/modular_diffusers/modular_pipeline#creating-a-pipeline)および[コンポーネントの読み込み](https://huggingface.co/docs/diffusers/modular_diffusers/modular_pipeline#loading-components)のガイドで、パイプラインの作成と読み込みについて詳しく学んでください。

## 構造を理解する

[ModularPipeline](/docs/diffusers/main/ja/api/modular_diffusers/pipeline#diffusers.ModularPipeline) は2つの部分から構成されています。**定義**（ブロック）と、**状態**（読み込まれたコンポーネントと設定）です。

パイプラインを出力して、その状態を確認します。コンポーネントとその読み込みステータス、設定が表示されます。
```py
print(pipe)
```
```
QwenImageModularPipeline {
  "_blocks_class_name": "QwenImageAutoBlocks",
  "_class_name": "QwenImageModularPipeline",
  "_diffusers_version": "0.37.0.dev0",
  "transformer": [
    "diffusers",
    "QwenImageTransformer2DModel",
    {
      "pretrained_model_name_or_path": "Qwen/Qwen-Image",
      "revision": null,
      "subfolder": "transformer",
      "type_hint": [
        "diffusers",
        "QwenImageTransformer2DModel"
      ],
      "variant": null
    }
  ],
  ...
}
```

`pipe.blocks` を介して定義にアクセスします。これは、パイプラインのワークフロー、入力、出力、および計算ロジックを定義する [ModularPipelineBlocks](/docs/diffusers/main/ja/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) です。
```py
print(pipe.blocks)
```
```
QwenImageAutoBlocks(
  Class: SequentialPipelineBlocks

  Description: Auto Modular pipeline for text-to-image, image-to-image, inpainting, and controlnet tasks using QwenImage.
      
      Supported workflows:
        - `text2image`: requires `prompt`
        - `image2image`: requires `prompt`, `image`
        - `inpainting`: requires `prompt`, `mask_image`, `image`
        - `controlnet_text2image`: requires `prompt`, `control_image`
        ...

  Components:
      text_encoder (`Qwen2_5_VLForConditionalGeneration`)
      vae (`AutoencoderKLQwenImage`)
      transformer (`QwenImageTransformer2DModel`)
      ...

  Sub-Blocks:
    [0] text_encoder (QwenImageAutoTextEncoderStep)
    [1] vae_encoder (QwenImageAutoVaeEncoderStep)
    [2] controlnet_vae_encoder (QwenImageOptionalControlNetVaeEncoderStep)
    [3] denoise (QwenImageAutoCoreDenoiseStep)
    [4] decode (QwenImageAutoDecodeStep)
)
```

出力は以下を返します:
- サポートされているワークフロー（text2image、image2image、inpainting など）
- 構成されるサブブロック（text_encoder、vae_encoder、denoise、decode）

### ワークフロー

このパイプラインは複数のワークフローをサポートし、提供される入力に基づいて動作を適応させます。例えば、パイプラインに`image`を渡すと、テキストから画像への生成ではなく、画像から画像へのワークフローが実行されます。内部でどのように動作しているかについては、[AutoPipelineBlocks](https://huggingface.co/docs/diffusers/modular_diffusers/auto_pipeline_blocks)ガイドを参照してください。

```py
from diffusers.utils import load_image

input_image = load_image("https://github.com/Trgtuan10/Image_storage/blob/main/cute_cat.png?raw=true")

image = pipe(
    prompt="cat wizard with red hat, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney",
    image=input_image,
).images[0]
```

`get_workflow()` を使用して、特定のワークフローのブロックを抽出します。ワークフロー名（例: `"image2image"`、`"inpainting"`、`"controlnet_text2image"`）を渡すことで、そのワークフローに関連するブロックのみを取得できます。これは、特定のワークフローをカスタマイズしたりデバッグしたりする場合に便利です。`pipe.blocks.available_workflows` を確認すると、利用可能なすべてのワークフローを表示できます。
```py
img2img_blocks = pipe.blocks.get_workflow("image2image")
```

### サブブロック

ブロックは他のブロックを含むことができます。`pipe.blocks` はトップレベルのブロック定義（ここでは `QwenImageAutoBlocks`）を返し、`sub_blocks` を使用すると、その内部にあるより小さなブロックにアクセスできます。

`QwenImageAutoBlocks` は、`text_encoder`、`vae_encoder`、`controlnet_vae_encoder`、`denoise`、`decode` で構成されています。

これらのサブブロックは順次実行され、データはブロックから次のブロックへ直線的に流れます。各ブロックの`intermediate_outputs`は、次のブロックの`inputs`として利用可能になります。[`SequentialPipelineBlocks`](./sequential_pipeline_blocks)は、この仕組みで動作します。

`sub_blocks` プロパティを介してアクセスできます。`doc` プロパティは、ブロックの完全なドキュメント、つまり入力、出力、コンポーネントを確認するのに便利です。
```py
vae_encoder_block = pipe.blocks.sub_blocks["vae_encoder"]
print(vae_encoder_block.doc)
```

このブロックは、[init_pipeline()](/docs/diffusers/main/ja/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) を使用してパイプラインに変換することで、単独で実行できるようになります。
```py
vae_encoder_pipe = vae_encoder_block.init_pipeline()

# Reuse the VAE we already loaded, we can reuse it with update_components() method
vae_encoder_pipe.update_components(vae=pipe.vae)

# Run just this block
image_latents = vae_encoder_pipe(image=input_image).image_latents
print(image_latents.shape)
```

元のパイプラインのVAEを再読み込みせずに再利用することで、メモリ使用量を効率的に保ちます。詳細は[コンポーネントの読み込み](https://huggingface.co/docs/diffusers/modular_diffusers/modular_pipeline#loading-components)ガイドを参照してください。

ブロックは合成可能であるため、ブロックの追加、削除、または交換によってパイプラインの定義を変更し、新しいワークフローを作成できます。次のセクションでは、ControlNet パイプラインに canny エッジ検出ブロックを追加します。これにより、事前処理済みの canny エッジマップの代わりに、通常の画像を渡すことができます。

## 新しいワークフローを構築

ControlNet パイプラインに canny エッジ検出ブロックを追加しましょう。まず、Hub から事前構築済みの canny ブロックを読み込みます（独自のブロックを作成するには、[カスタムブロックの構築](https://huggingface.co/docs/diffusers/modular_diffusers/custom_blocks)を参照してください）。
```py
from diffusers.modular_pipelines import ModularPipelineBlocks

# Load a canny block from the Hub
canny_block = ModularPipelineBlocks.from_pretrained(
    "diffusers-internal-dev/canny-filtering",
    trust_remote_code=True,
)

print(canny_block.doc)
```
```
class CannyBlock

  Inputs:
      image (`Union[Image, ndarray]`):
          Image to compute canny filter on
      low_threshold (`int`, *optional*, defaults to 50):
          Low threshold for the canny filter.
      high_threshold (`int`, *optional*, defaults to 200):
          High threshold for the canny filter.
      ...

  Outputs:
      control_image (`PIL.Image`):
          Canny map for input image
```

`get_workflow` を使用して、`QwenImageAutoBlocks` から ControlNet ワークフローを抽出します。
```py
# Get the controlnet workflow that we want to work with
blocks = pipe.blocks.get_workflow("controlnet_text2image")
print(blocks.doc)
```
```
class SequentialPipelineBlocks

  Inputs:
      prompt (`str`):
          The prompt or prompts to guide image generation.
      control_image (`Image`):
          Control image for ControlNet conditioning.
      ...
```

抽出されたワークフローは[`SequentialPipelineBlocks`](./sequential_pipeline_blocks)であり、現在`control_image`を入力として必要としています。パイプラインが通常の画像を受け入れられるように、canny ブロックを先頭に挿入してください。
```py
# Insert canny at the beginning
blocks.sub_blocks.insert("canny", canny_block, 0)

# Check the updated structure: CannyBlock is now listed as first sub-block
print(blocks)
# Check the updated doc
print(blocks.doc)
```
```
class SequentialPipelineBlocks

  Inputs:
      image (`Union[Image, ndarray]`):
          Image to compute canny filter on
      low_threshold (`int`, *optional*, defaults to 50):
          Low threshold for the canny filter.
      high_threshold (`int`, *optional*, defaults to 200):
          High threshold for the canny filter.
      prompt (`str`):
          The prompt or prompts to guide image generation.
      ...
```

これにより、パイプラインは`control_image`ではなく`image`を入力として受け取るようになります。シーケンス内のブロックは自動的にデータを共有するため、cannyブロックの出力（`control_image`）はそれを必要とするdenoiseブロックに流れます。また、cannyブロックの入力（`image`）は、それより前のブロックがそれを提供しないため、パイプラインの入力となります。

修正されたブロックからパイプラインを作成し、ControlNet モデルを読み込みます。ControlNet は元のモデルリポジトリの一部ではないため、個別に読み込み、[update_components()](/docs/diffusers/main/ja/api/modular_diffusers/pipeline#diffusers.ModularPipeline.update_components) を使用して追加します。
```py
pipeline = blocks.init_pipeline("Qwen/Qwen-Image", components_manager=manager)

pipeline.load_components(dtype=torch.bfloat16)

# Load the ControlNet model
controlnet_spec = pipeline.get_component_spec("controlnet")
controlnet_spec.pretrained_model_name_or_path = "InstantX/Qwen-Image-ControlNet-Union"
controlnet = controlnet_spec.load(dtype=torch.bfloat16)
pipeline.update_components(controlnet=controlnet)
```

次にパイプラインを実行します。cannyブロックは、ControlNet用に画像を前処理します。
```py
from diffusers.utils import load_image

prompt = "cat wizard with red hat, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney"
image = load_image("https://github.com/Trgtuan10/Image_storage/blob/main/cute_cat.png?raw=true")

output = pipeline(
    prompt=prompt,
    image=image,
).images[0]
output
```

## 次のステップ

Modular Diffusersのコアとなる構成要素を理解します:

- [ModularPipelineBlocks](./pipeline_block): パイプラインのステップを定義するための基本単位です。
- [SequentialPipelineBlocks](./sequential_pipeline_blocks): ブロックを連鎖させて、順番に実行します。
- [AutoPipelineBlocks](./auto_pipeline_blocks): 複数のワークフローをサポートするパイプラインを作成します。
- [状態](./modular_diffusers_states): ブロック間でデータがどのように共有されるか。

[Building Custom Blocks](./custom_blocks) ガイドで、カスタムロジックを含む独自のブロックを作成する方法を学びましょう。

[`ComponentsManager`](./components_manager) を使用して、複数のパイプライン間でモデルを共有し、メモリを効率的に管理します。

モジュラーパイプラインを、ワークフローを構築するためのビジュアルなノードベースインターフェースである[Mellon](https://github.com/cubiq/Mellon)に接続できます。Modular Diffusersで構築したカスタムブロックは、Mellonでそのまま動作します。UIコードは不要です。詳細はMellonのガイドを参照してください。

