Diffusers documentation
Mulai Cepat
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 yang dapat dikombinasikan dengan blok lain untuk beradaptasi dengan alur kerja baru. Blok-blok ini dikonversi menjadi 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, baca Beralih dari DiffusionPipeline terlebih dahulu untuk mengetahui apa yang berbeda.
Jalankan pipeline
ModularPipeline adalah antarmuka utama untuk memuat, menjalankan, dan mengelola pipeline modular.
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]
imagefrom_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(). Ini memberi Anda kendali atas kapan dan bagaimana komponen dimuat.
ComponentsManagerdenganenable_auto_cpu_offloadsecara 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.Jika Anda tidak memerlukan offloading, hapus argumen
components_managerdan pindahkan pipeline ke perangkat Anda secara manual denganto("cuda").
Pelajari lebih lanjut tentang pembuatan dan pemuatan pipeline di panduan Membuat pipeline dan Memuat komponen.
Memahami struktur
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.
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 yang mendefinisikan alur kerja, input, output, dan logika komputasi pipeline.
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.
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.
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.
Anda dapat mengaksesnya melalui properti sub_blocks. Properti doc berguna untuk melihat dokumentasi lengkap dari blok mana pun, termasuk input, output, dan komponennya.
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().
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.
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 untuk membuat blok Anda sendiri).
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 imageGunakan get_workflow untuk mengekstrak workflow ControlNet dari QwenImageAutoBlocks.
# 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 dan saat ini membutuhkan control_image sebagai input. Sisipkan blok canny di awal agar pipeline menerima gambar biasa.
# 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().
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.
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]
outputLangkah selanjutnya
Pahami blok bangunan inti dari Modular Diffusers:
- ModularPipelineBlocks: Unit dasar untuk mendefinisikan langkah dalam pipeline.
- SequentialPipelineBlocks: Rangkai blok untuk dijalankan secara berurutan.
- AutoPipelineBlocks: Buat pipeline yang mendukung beberapa alur kerja.
- States: Bagaimana data dibagikan antar blok.
Pelajari cara membuat blok Anda sendiri dengan logika kustom di panduan Membangun Blok Kustom.
Gunakan ComponentsManager untuk berbagi model di antara beberapa pipeline dan mengelola memori secara efisien.
Hubungkan pipeline modular ke 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.