# Mulai Cepat

Modular Diffusers adalah kerangka kerja untuk membangun pipeline yang fleksibel dan dapat disesuaikan dengan cepat. Pipeline-pipeline ini dapat melampaui kemampuan standar `DiffusionPipeline`. Inti dari Modular Diffusers adalah [ModularPipelineBlocks](/docs/diffusers/main/id/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) yang dapat dikombinasikan dengan blok lain untuk beradaptasi dengan alur kerja baru. Blok-blok ini dikonversi menjadi [ModularPipeline](/docs/diffusers/main/id/api/modular_diffusers/pipeline#diffusers.ModularPipeline), yaitu antarmuka yang ramah pengguna untuk menjalankan tugas generasi.

Panduan ini menunjukkan cara menjalankan pipeline modular, memahami strukturnya, dan menyesuaikannya dengan memodifikasi blok-blok yang menyusunnya. Jika Anda sudah familiar dengan [DiffusionPipeline](/docs/diffusers/main/id/api/pipelines/overview#diffusers.DiffusionPipeline), baca [Beralih dari DiffusionPipeline](./coming_from_diffusion_pipeline) terlebih dahulu untuk mengetahui apa yang berbeda.

## Jalankan pipeline

[ModularPipeline](/docs/diffusers/main/id/api/modular_diffusers/pipeline#diffusers.ModularPipeline) adalah antarmuka utama untuk memuat, menjalankan, dan mengelola pipeline modular.
```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/id/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) menggunakan lazy loading - ia membaca konfigurasi untuk mengetahui dari mana setiap komponen dimuat, tetapi tidak benar-benar memuat bobot model hingga Anda memanggil [load_components()](/docs/diffusers/main/id/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components). Ini memberi Anda kendali atas kapan dan bagaimana komponen dimuat.

> [!TIP]
> `ComponentsManager` dengan `enable_auto_cpu_offload` secara otomatis memindahkan model antara CPU dan GPU sesuai kebutuhan, sehingga mengurangi penggunaan memori untuk model besar seperti Qwen-Image. Pelajari lebih lanjut di panduan [ComponentsManager](./components_manager).
>
> Jika Anda tidak memerlukan offloading, hapus argumen `components_manager` dan pindahkan pipeline ke perangkat Anda secara manual dengan `to("cuda")`.

Pelajari lebih lanjut tentang pembuatan dan pemuatan pipeline di panduan [Membuat pipeline](https://huggingface.co/docs/diffusers/modular_diffusers/modular_pipeline#creating-a-pipeline) dan [Memuat komponen](https://huggingface.co/docs/diffusers/modular_diffusers/modular_pipeline#loading-components).

## Memahami struktur

[ModularPipeline](/docs/diffusers/main/id/api/modular_diffusers/pipeline#diffusers.ModularPipeline) memiliki dua bagian: **definisi** (blok-blok) dan **state** (komponen dan konfigurasi yang dimuat).

Cetak pipeline untuk melihat statusnya — komponen dan status pemuatan serta konfigurasinya.
```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
    }
  ],
  ...
}
```

Akses definisi melalui `pipe.blocks` — ini adalah [ModularPipelineBlocks](/docs/diffusers/main/id/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) yang mendefinisikan alur kerja, input, output, dan logika komputasi pipeline.
```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)
)
```

Output yang dikembalikan:
- Workflow yang didukung (text2image, image2image, inpainting, dll.)
- Sub-Block yang membentuknya (text_encoder, vae_encoder, denoise, decode)

### Alur Kerja

Pipeline ini mendukung beberapa alur kerja dan menyesuaikan perilakunya berdasarkan input yang Anda berikan. Misalnya, jika Anda meneruskan `image` ke pipeline, ia akan menjalankan alur kerja image-to-image alih-alih text-to-image. Pelajari lebih lanjut tentang cara kerjanya di balik layar pada panduan [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]
```

Gunakan `get_workflow()` untuk mengekstrak blok untuk workflow tertentu. Masukkan nama workflow (misalnya, `"image2image"`, `"inpainting"`, `"controlnet_text2image"`) untuk mendapatkan hanya blok yang relevan dengan workflow tersebut. Ini berguna ketika Anda ingin menyesuaikan atau men-debug workflow tertentu. Anda dapat memeriksa `pipe.blocks.available_workflows` untuk melihat semua workflow yang tersedia.
```py
img2img_blocks = pipe.blocks.get_workflow("image2image")
```

### Sub-blok

Block dapat berisi block lain. `pipe.blocks` memberikan definisi block tingkat atas (di sini, `QwenImageAutoBlocks`), sedangkan `sub_blocks` memungkinkan Anda mengakses block yang lebih kecil di dalamnya.

`QwenImageAutoBlocks` terdiri dari: `text_encoder`, `vae_encoder`, `controlnet_vae_encoder`, `denoise`, dan `decode`.

Sub-blok ini berjalan satu per satu secara berurutan dan data mengalir secara linear dari satu blok ke blok berikutnya — `intermediate_outputs` dari setiap blok menjadi tersedia sebagai `inputs` untuk blok berikutnya. Inilah cara kerja [`SequentialPipelineBlocks`](./sequential_pipeline_blocks).

Anda dapat mengaksesnya melalui properti `sub_blocks`. Properti `doc` berguna untuk melihat dokumentasi lengkap dari blok mana pun, termasuk input, output, dan komponennya.
```py
vae_encoder_block = pipe.blocks.sub_blocks["vae_encoder"]
print(vae_encoder_block.doc)
```

Blok ini dapat dikonversi menjadi pipeline sehingga dapat berjalan secara mandiri dengan [init_pipeline()](/docs/diffusers/main/id/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)
```

Komponen ini menggunakan ulang VAE dari pipeline asli kami alih-alih memuat ulang, sehingga penggunaan memori tetap efisien. Pelajari lebih lanjut di panduan [Memuat komponen](https://huggingface.co/docs/diffusers/modular_diffusers/modular_pipeline#loading-components).

Karena blok bersifat komposabel, Anda dapat memodifikasi definisi pipeline dengan menambahkan, menghapus, atau mengganti blok untuk membuat alur kerja baru. Pada bagian berikutnya, kami akan menambahkan blok deteksi tepi canny ke pipeline ControlNet, sehingga Anda dapat meneruskan gambar biasa alih-alih peta tepi canny yang sudah diproses sebelumnya.

## Susun alur kerja baru

Mari kita tambahkan blok deteksi tepi canny ke pipeline ControlNet. Pertama, muat blok canny yang sudah dibuat dari Hub (lihat [Membangun Blok Kustom](https://huggingface.co/docs/diffusers/modular_diffusers/custom_blocks) untuk membuat blok Anda sendiri).
```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
```

Gunakan `get_workflow` untuk mengekstrak workflow ControlNet dari `QwenImageAutoBlocks`.
```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.
      ...
```

Workflow yang diekstrak adalah [`SequentialPipelineBlocks`](./sequential_pipeline_blocks) dan saat ini membutuhkan `control_image` sebagai input. Sisipkan blok canny di awal agar pipeline menerima gambar biasa.
```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.
      ...
```

Sekarang pipeline mengambil `image` sebagai input alih-alih `control_image`. Karena blok dalam sebuah urutan berbagi data secara otomatis, output dari blok canny (`control_image`) mengalir ke blok denoise yang membutuhkannya, dan input dari blok canny (`image`) menjadi input pipeline karena tidak ada blok sebelumnya yang menyediakannya.

Buat pipeline dari blok yang dimodifikasi dan muat model ControlNet. ControlNet bukan bagian dari repositori model asli, jadi muat secara terpisah dan tambahkan dengan [update_components()](/docs/diffusers/main/id/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)
```

Sekarang jalankan pipeline - blok canny memproses praproses gambar untuk 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
```

## Langkah selanjutnya

Pahami blok bangunan inti dari Modular Diffusers:

- [ModularPipelineBlocks](./pipeline_block): Unit dasar untuk mendefinisikan langkah dalam pipeline.
- [SequentialPipelineBlocks](./sequential_pipeline_blocks): Rangkai blok untuk dijalankan secara berurutan.
- [AutoPipelineBlocks](./auto_pipeline_blocks): Buat pipeline yang mendukung beberapa alur kerja.
- [States](./modular_diffusers_states): Bagaimana data dibagikan antar blok.

Pelajari cara membuat blok Anda sendiri dengan logika kustom di panduan [Membangun Blok Kustom](./custom_blocks).

Gunakan [`ComponentsManager`](./components_manager) untuk berbagi model di antara beberapa pipeline dan mengelola memori secara efisien.

Hubungkan pipeline modular ke [Mellon](https://github.com/cubiq/Mellon), antarmuka berbasis node visual untuk membangun alur kerja. Blok kustom yang dibangun dengan Modular Diffusers langsung berfungsi dengan Mellon - tidak diperlukan kode UI. Baca selengkapnya di panduan Mellon.

