# Início rápido

Modular Diffusers é um framework para construir rapidamente pipelines flexíveis e personalizáveis. Esses pipelines podem ir além do que os `DiffusionPipeline` padrão conseguem fazer. No núcleo do Modular Diffusers estão os [ModularPipelineBlocks](/docs/diffusers/main/pt/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks), que podem ser combinados com outros blocos para se adaptar a novos fluxos de trabalho. Os blocos são convertidos em um [ModularPipeline](/docs/diffusers/main/pt/api/modular_diffusers/pipeline#diffusers.ModularPipeline), uma interface amigável voltada para o usuário para executar tarefas de geração.

Este guia mostra como executar um pipeline modular, entender sua estrutura e personalizá-lo modificando os blocos que o compõem. Se você está familiarizado com [DiffusionPipeline](/docs/diffusers/main/pt/api/pipelines/overview#diffusers.DiffusionPipeline), leia [Vindo do DiffusionPipeline](./coming_from_diffusion_pipeline) primeiro para saber o que funciona de forma diferente.

## Executar um pipeline

[ModularPipeline](/docs/diffusers/main/pt/api/modular_diffusers/pipeline#diffusers.ModularPipeline) é a interface principal para carregar, executar e gerenciar pipelines modulares.
```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/pt/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) usa carregamento preguiçoso - ele lê a configuração para saber de onde carregar cada componente, mas não carrega os pesos do modelo de fato até você chamar [load_components()](/docs/diffusers/main/pt/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components). Isso dá a você controle sobre quando e como os componentes são carregados.

> [!TIP]
> `ComponentsManager` com `enable_auto_cpu_offload` move automaticamente os modelos entre a CPU e a GPU conforme necessário, reduzindo o uso de memória para modelos grandes como Qwen-Image. Saiba mais no guia [ComponentsManager](./components_manager).
>
> Se você não precisar de offloading, remova o argumento `components_manager` e mova o pipeline para o seu dispositivo manualmente com `to("cuda")`.

Saiba mais sobre a criação e o carregamento de pipelines nos guias [Criando um pipeline](./modular_pipeline#creating-a-pipeline) e [Carregando componentes](./modular_pipeline#loading-components).

## Entender a estrutura

A [ModularPipeline](/docs/diffusers/main/pt/api/modular_diffusers/pipeline#diffusers.ModularPipeline) tem duas partes: uma **definição** (os blocos) e um **estado** (os componentes e configurações carregados).

Imprima o pipeline para ver seu estado — os componentes e seu status de carregamento e configuração.
```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
    }
  ],
  ...
}
```

Acesse a definição por meio de `pipe.blocks` — este é o [ModularPipelineBlocks](/docs/diffusers/main/pt/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) que define os fluxos de trabalho, entradas, saídas e a lógica de computação do 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)
)
```

A saída retorna:
- Os fluxos de trabalho suportados (text2image, image2image, inpainting, etc.)
- Os Sub-Blocks dos quais é composto (text_encoder, vae_encoder, denoise, decode)

### Fluxos de trabalho

Este pipeline suporta vários fluxos de trabalho e adapta seu comportamento com base nas entradas que você fornece. Por exemplo, se você passar `image` para o pipeline, ele executa um fluxo de trabalho de imagem para imagem em vez de texto para imagem. Saiba mais sobre como isso funciona por baixo dos panos no guia [AutoPipelineBlocks](./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]
```

Use `get_workflow()` para extrair os blocos de um workflow específico. Passe o nome do workflow (por exemplo, `"image2image"`, `"inpainting"`, `"controlnet_text2image"`) para obter apenas os blocos relevantes para aquele workflow. Isso é útil quando você deseja personalizar ou depurar um workflow específico. Você pode verificar `pipe.blocks.available_workflows` para ver todos os workflows disponíveis.
```py
img2img_blocks = pipe.blocks.get_workflow("image2image")
```

### Sub-blocos

Blocos podem conter outros blocos. `pipe.blocks` fornece a definição do bloco de nível superior (aqui, `QwenImageAutoBlocks`), enquanto `sub_blocks` permite acessar os blocos menores dentro dele.

`QwenImageAutoBlocks` é composto por: `text_encoder`, `vae_encoder`, `controlnet_vae_encoder`, `denoise` e `decode`.

Esses sub-blocos são executados um após o outro e os dados fluem linearmente de um bloco para o próximo — os `intermediate_outputs` de cada bloco ficam disponíveis como `inputs` para o bloco seguinte. É assim que o [`SequentialPipelineBlocks`](./sequential_pipeline_blocks) funciona.

Você pode acessá-los por meio da propriedade `sub_blocks`. A propriedade `doc` é útil para ver a documentação completa de qualquer bloco, incluindo suas entradas, saídas e componentes.
```py
vae_encoder_block = pipe.blocks.sub_blocks["vae_encoder"]
print(vae_encoder_block.doc)
```

Este bloco pode ser convertido em um pipeline para que ele possa ser executado de forma independente com [init_pipeline()](/docs/diffusers/main/pt/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)
```

Ele reutiliza o VAE do nosso pipeline original em vez de recarregá-lo, mantendo o uso de memória eficiente. Saiba mais no guia [Carregando componentes](./modular_pipeline#loading-components).

Como os blocos são composíveis, você pode modificar a definição do pipeline adicionando, removendo ou substituindo blocos para criar novos fluxos de trabalho. Na próxima seção, adicionaremos um bloco de detecção de bordas canny a um pipeline ControlNet, para que você possa passar uma imagem comum em vez de um mapa de bordas canny pré-processado.

## Crie novos fluxos de trabalho

Vamos adicionar um bloco de detecção de bordas canny a um pipeline do ControlNet. Primeiro, carregue um bloco canny pré-construído do Hub (veja [Building Custom Blocks](./custom_blocks) para criar o seu próprio).
```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
```

Use `get_workflow` para extrair o workflow do ControlNet de `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.
      ...
```

O workflow extraído é um [`SequentialPipelineBlocks`](./sequential_pipeline_blocks) e atualmente requer `control_image` como entrada. Insira o bloco canny no início para que o pipeline aceite uma imagem comum.
```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.
      ...
```

Agora o pipeline recebe `image` como entrada em vez de `control_image`. Como os blocos em uma sequência compartilham dados automaticamente, a saída do bloco canny (`control_image`) flui para o bloco denoise que precisa dela, e a entrada do bloco canny (`image`) se torna uma entrada do pipeline, já que nenhum bloco anterior a fornece.

Crie um pipeline a partir dos blocos modificados e carregue um modelo ControlNet. O ControlNet não faz parte do repositório original do modelo, portanto, carregue-o separadamente e adicione-o com [update_components()](/docs/diffusers/main/pt/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)
```

Agora execute o pipeline - o bloco canny pré-processa a imagem para o 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
```

## Próximas etapas

Entenda os blocos de construção fundamentais do Modular Diffusers:

- [ModularPipelineBlocks](./pipeline_block): a unidade básica para definir uma etapa em um pipeline.
- [SequentialPipelineBlocks](./sequential_pipeline_blocks): Encadeia blocos para executá-los em sequência.
- [AutoPipelineBlocks](./auto_pipeline_blocks): Crie pipelines que suportam múltiplos fluxos de trabalho.
- [Estados](./modular_diffusers_states): Como os dados são compartilhados entre blocos.

Aprenda a criar seus próprios blocos com lógica personalizada no guia [Building Custom Blocks](./custom_blocks).

Use [`ComponentsManager`](./components_manager) para compartilhar modelos entre vários pipelines e gerenciar a memória de forma eficiente.

Conecte pipelines modulares ao [Mellon](https://github.com/cubiq/Mellon), uma interface visual baseada em nós para a criação de fluxos de trabalho. Blocos personalizados criados com Modular Diffusers funcionam imediatamente com o Mellon - sem necessidade de código de interface. Leia mais no guia do Mellon.

