Diffusers documentation

빠른 시작

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

빠른 시작

Modular Diffusers는 유연하고 사용자 정의 가능한 파이프라인을 빠르게 구축하기 위한 프레임워크입니다. 이러한 파이프라인은 표준 DiffusionPipeline의 범위를 넘어설 수 있습니다. Modular Diffusers의 핵심은 새로운 워크플로우에 맞게 다른 블록과 결합할 수 있는 ModularPipelineBlocks입니다. 이 블록들은 생성 작업을 실행하기 위한 사용자 친화적인 인터페이스인 ModularPipeline으로 변환됩니다.

이 가이드에서는 모듈형 파이프라인을 실행하는 방법, 그 구조를 이해하는 방법, 그리고 구성 블록을 수정하여 파이프라인을 커스터마이징하는 방법을 보여줍니다. DiffusionPipeline에 익숙하시다면, 무엇이 다른지 확인하기 위해 먼저 Coming from DiffusionPipeline을 읽어보세요.

파이프라인 실행

ModularPipeline는 모듈형 파이프라인을 로드하고 실행하며 관리하기 위한 주요 인터페이스입니다.

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()는 지연 로딩을 사용합니다. 구성을 읽어 각 구성 요소를从哪里 로드할지 파악하지만, load_components()를 호출할 때까지 실제 모델 가중치를 로드하지 않습니다. 이를 통해 구성 요소의 로드 시점과 방식을 제어할 수 있습니다.

ComponentsManager에 enable_auto_cpu_offload를 사용하면 필요에 따라 모델이 CPU와 GPU 사이로 자동으로 이동하여 Qwen-Image와 같은 대규모 모델의 메모리 사용량을 줄입니다. 자세한 내용은 ComponentsManager 가이드를 참고하세요.

오프로딩이 필요하지 않다면 components_manager 인수를 제거하고 to("cuda")를 사용하여 파이프라인을 수동으로 원하는 장치로 이동하세요.

파이프라인 만들기 및 컴포넌트 로드 가이드에서 파이프라인 생성 및 로드에 대해 자세히 알아보세요.

구조 이해하기

ModularPipeline는 두 부분으로 구성됩니다: 정의(블록)와 상태(로드된 컴포넌트와 설정).

print을 사용하여 파이프라인의 상태를 확인합니다. 구성 요소, 로딩 상태 및 구성이 표시됩니다.

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입니다.

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 가이드에서 확인하세요.

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를 확인하여 사용 가능한 모든 워크플로를 볼 수 있습니다.

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

서브 블록

Blocks는 다른 Blocks를 포함할 수 있습니다. pipe.blocks는 최상위 블록 정의(여기서는 QwenImageAutoBlocks)를 제공하며, sub_blocks를 사용하면 그 안의 더 작은 블록에 접근할 수 있습니다.

QwenImageAutoBlocks는 text_encoder, vae_encoder, controlnet_vae_encoder, denoise, decode로 구성됩니다.

이러한 서브 블록은 순차적으로 실행되며 데이터는 하나의 블록에서 다음 블록으로 선형적으로 흐릅니다. 각 블록의 intermediate_outputs은 다음 블록의 inputs으로 사용 가능합니다. SequentialPipelineBlocks가 작동하는 방식입니다.

sub_blocks 속성을 통해 액세스할 수 있습니다. doc 속성은 입력, 출력 및 구성 요소를 포함한 블록의 전체 문서를 확인하는 데 유용합니다.

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

이 블록은 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)

새로 로드하는 대신 원래 파이프라인의 VAE를 재사용하여 메모리 사용량을 효율적으로 유지합니다. 컴포넌트 로드 가이드에서 자세히 알아보세요.

블록은 구성 가능(composable)하므로, 블록을 추가하거나 제거하거나 교체하여 파이프라인의 정의를 수정하고 새로운 워크플로를 만들 수 있습니다. 다음 섹션에서는 ControlNet 파이프라인에 canny edge detection 블록을 추가하여, 사전 처리된 canny edge map 대신 일반 이미지를 전달할 수 있도록 합니다.

새 워크플로우 구성

ControlNet 파이프라인에 canny edge detection 블록을 추가해 보겠습니다. 먼저 Hub에서 미리 만들어진 canny 블록을 로드합니다(직접 만들려면 Building Custom Blocks를 참고하세요).

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 워크플로를 추출합니다.

# 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이며 현재 control_image를 입력으로 요구합니다. 파이프라인이 일반 이미지를 대신 받아들이도록 canny 블록을 맨 앞에 삽입하세요.

# 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()로 추가합니다.

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을 위해 이미지를 전처리합니다.

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의 핵심 구성 요소를 이해해 보세요:

Update on GitHub