Buckets:

mishig's picture
|
download
raw
13.2 kB
# 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.

Xet Storage Details

Size:
13.2 kB
·
Xet hash:
563d5a055d219550351d2dee36a204fbecc9e2223fb098f5baf2dce94f46485f

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.