Diffusers documentation

Bắt đầu nhanh

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Bắt đầu nhanh

Modular Diffusers là một framework để nhanh chóng xây dựng các pipeline linh hoạt và có thể tùy chỉnh. Các pipeline này có thể vượt ra ngoài những gì các DiffusionPipeline tiêu chuẩn có thể làm. Nền tảng cốt lõi của Modular Diffusers là các ModularPipelineBlocks có thể được kết hợp với các block khác để thích ứng với các quy trình làm việc mới. Các block này được chuyển đổi thành một ModularPipeline, một giao diện thân thiện với người dùng để chạy các tác vụ tạo sinh.

Hướng dẫn này cho bạn cách chạy một pipeline dạng module, hiểu cấu trúc của nó và tùy chỉnh nó bằng cách sửa đổi các khối cấu thành. Nếu bạn đã quen thuộc với DiffusionPipeline, hãy đọc Coming from DiffusionPipeline trước để biết những điểm khác biệt.

Chạy một pipeline

ModularPipeline là giao diện chính để tải, chạy và quản lý các pipeline dạng module.

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() sử dụng nạp chậm - nó đọc cấu hình để biết nơi nạp mỗi thành phần, nhưng không thực sự nạp trọng số mô hình cho đến khi bạn gọi load_components(). Điều này cho bạn quyền kiểm soát thời điểm và cách thức nạp các thành phần.

ComponentsManager với enable_auto_cpu_offload tự động di chuyển mô hình giữa CPU và GPU khi cần, giúp giảm mức sử dụng bộ nhớ cho các mô hình lớn như Qwen-Image. Tìm hiểu thêm trong hướng dẫn ComponentsManager.

Nếu bạn không cần offloading, hãy xóa đối số components_manager và di chuyển pipeline sang thiết bị của bạn một cách thủ công bằng to("cuda").

Tìm hiểu thêm về việc tạo và nạp pipeline trong các hướng dẫn Tạo pipeline và Nạp các thành phần.

Hiểu cấu trúc

Một ModularPipeline có hai phần: một định nghĩa (các khối) và một trạng thái (các thành phần và cấu hình đã được nạp).

In pipeline để xem trạng thái của nó — các thành phần cùng trạng thái tải và cấu hình của chúng.

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
    }
  ],
  ...
}

Truy cập định nghĩa thông qua pipe.blocks — đây là ModularPipelineBlocks xác định các luồng công việc, đầu vào, đầu ra và logic tính toán của 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)
)

Đầu ra trả về:

  • Các quy trình làm việc được hỗ trợ (text2image, image2image, inpainting, v.v.)
  • Các khối con cấu thành nên nó (text_encoder, vae_encoder, denoise, decode)

Quy trình làm việc

Pipeline này hỗ trợ nhiều luồng công việc và điều chỉnh hành vi dựa trên các đầu vào bạn cung cấp. Ví dụ, nếu bạn truyền image vào pipeline, nó sẽ chạy luồng công việc từ ảnh sang ảnh thay vì từ văn bản sang ảnh. Tìm hiểu thêm về cách hoạt động bên trong trong hướng dẫn 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]

Sử dụng get_workflow() để trích xuất các khối cho một workflow cụ thể. Truyền tên workflow (ví dụ: "image2image", "inpainting", "controlnet_text2image") để chỉ lấy các khối liên quan đến workflow đó. Điều này hữu ích khi bạn muốn tùy chỉnh hoặc gỡ lỗi một workflow cụ thể. Bạn có thể kiểm tra pipe.blocks.available_workflows để xem tất cả các workflow khả dụng.

img2img_blocks = pipe.blocks.get_workflow("image2image")

Các khối con

Các block có thể chứa các block khác. pipe.blocks cung cấp cho bạn định nghĩa block cấp cao nhất (ở đây là QwenImageAutoBlocks), trong khi sub_blocks cho phép bạn truy cập các block nhỏ hơn bên trong nó.

QwenImageAutoBlocks bao gồm: text_encoder, vae_encoder, controlnet_vae_encoder, denoise và decode.

Các khối con này chạy lần lượt và dữ liệu chảy tuyến tính từ khối này sang khối tiếp theo — intermediate_outputs của mỗi khối sẽ trở thành inputs cho khối kế tiếp. Đây là cách SequentialPipelineBlocks hoạt động.

Bạn có thể truy cập chúng thông qua thuộc tính sub_blocks. Thuộc tính doc hữu ích để xem tài liệu đầy đủ của bất kỳ khối nào, bao gồm các đầu vào, đầu ra và các thành phần của nó.

vae_encoder_block = pipe.blocks.sub_blocks["vae_encoder"]
print(vae_encoder_block.doc)

Khối này có thể được chuyển đổi thành một pipeline để nó có thể chạy độc lập bằng 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)

Nó tái sử dụng VAE từ pipeline gốc của chúng ta thay vì tải lại, giúp duy trì hiệu quả sử dụng bộ nhớ. Tìm hiểu thêm trong hướng dẫn Tải các thành phần.

Vì các khối có thể kết hợp được, bạn có thể sửa đổi định nghĩa của pipeline bằng cách thêm, xóa hoặc thay thế các khối để tạo ra các quy trình làm việc mới. Trong phần tiếp theo, chúng ta sẽ thêm một khối phát hiện cạnh canny vào pipeline ControlNet, để bạn có thể truyền vào một hình ảnh thông thường thay vì một bản đồ cạnh canny đã được xử lý trước.

Tạo các quy trình làm việc mới

Hãy thêm một khối phát hiện cạnh canny vào pipeline ControlNet. Trước tiên, hãy tải một khối canny có sẵn từ Hub (xem Building Custom Blocks để tự tạo khối của riêng bạn).

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

Sử dụng get_workflow để trích xuất workflow ControlNet từ 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 được trích xuất là SequentialPipelineBlocks và hiện tại yêu cầu control_image làm đầu vào. Chèn khối canny vào đầu để pipeline nhận một hình ảnh thông thường thay thế.

# 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.
      ...

Bây giờ pipeline nhận image làm đầu vào thay vì control_image. Vì các khối trong một chuỗi tự động chia sẻ dữ liệu, đầu ra của khối canny (control_image) sẽ chảy đến khối denoise cần nó, và đầu vào của khối canny (image) trở thành đầu vào của pipeline vì không có khối nào trước đó cung cấp nó.

Tạo một pipeline từ các khối đã chỉnh sửa và tải một mô hình ControlNet. ControlNet không nằm trong kho lưu trữ mô hình gốc, vì vậy hãy tải nó riêng và thêm vào bằng 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)

Bây giờ chạy pipeline - khối canny tiền xử lý ảnh cho 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]
output

Các bước tiếp theo

Học các kiến thức cơ bản
Xây dựng các khối tùy chỉnh
Chia sẻ các thành phần
Giao diện trực quan

Hiểu các khối xây dựng cốt lõi của Modular Diffusers:

Update on GitHub