# AutoPipelineBlocks

[AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) là một kiểu đa khối chứa các khối hỗ trợ các luồng công việc khác nhau. Nó tự động chọn các khối con cần chạy dựa trên đầu vào được cung cấp khi chạy. Điều này thường được dùng để đóng gói nhiều luồng công việc - text-to-image, image-to-image, inpaint - vào một pipeline duy nhất cho tiện lợi.

Hướng dẫn này cho thấy cách tạo [AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks).

Tạo ba [ModularPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) cho text-to-image, image-to-image và inpainting. Chúng đại diện cho các luồng công việc khác nhau có sẵn trong pipeline.

```py
import torch
from diffusers.modular_pipelines import ModularPipelineBlocks, InputParam, OutputParam

class TextToImageBlock(ModularPipelineBlocks):
    model_name = "text2img"

    @property
    def inputs(self):
        return [InputParam(name="prompt")]

    @property
    def intermediate_outputs(self):
        return []

    @property
    def description(self):
        return "I'm a text-to-image workflow!"

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        print("running the text-to-image workflow")
        # Add your text-to-image logic here
        # For example: generate image from prompt
        self.set_block_state(state, block_state)
        return components, state
```

```py
class ImageToImageBlock(ModularPipelineBlocks):
    model_name = "img2img"

    @property
    def inputs(self):
        return [InputParam(name="prompt"), InputParam(name="image")]

    @property
    def intermediate_outputs(self):
        return []

    @property
    def description(self):
        return "I'm an image-to-image workflow!"

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        print("running the image-to-image workflow")
        # Add your image-to-image logic here
        # For example: transform input image based on prompt
        self.set_block_state(state, block_state)
        return components, state
```

```py
class InpaintBlock(ModularPipelineBlocks):
    model_name = "inpaint"

    @property
    def inputs(self):
        return [InputParam(name="prompt"), InputParam(name="image"), InputParam(name="mask")]

    @property
    def intermediate_outputs(self):
        return []

    @property
    def description(self):
        return "I'm an inpaint workflow!"

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        print("running the inpaint workflow")
        # Add your inpainting logic here
        # For example: fill masked areas based on prompt
        self.set_block_state(state, block_state)
        return components, state
```

Tạo một lớp [AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) bao gồm một danh sách các lớp con-block và tên block tương ứng của chúng.

Bạn cũng cần bao gồm `block_trigger_inputs`, một danh sách các tên đầu vào kích hoạt khối tương ứng. Nếu một đầu vào kích hoạt được cung cấp khi chạy, thì khối đó sẽ được chọn để thực thi. Sử dụng `None` để chỉ định khối mặc định cần chạy nếu không phát hiện đầu vào kích hoạt nào.

Cuối cùng, việc bao gồm một `description` giải thích rõ ràng các đầu vào nào kích hoạt quy trình làm việc nào là rất quan trọng. Điều này giúp người dùng hiểu cách chạy các quy trình làm việc cụ thể.

```py
from diffusers.modular_pipelines import AutoPipelineBlocks

class AutoImageBlocks(AutoPipelineBlocks):
    # List of sub-block classes to choose from
    block_classes = [InpaintBlock, ImageToImageBlock, TextToImageBlock]
    # Names for each block in the same order
    block_names = ["inpaint", "img2img", "text2img"]
    # Trigger inputs that determine which block to run
    # - "mask" triggers inpaint workflow
    # - "image" triggers img2img workflow (but only if mask is not provided)
    # - if none of above, runs the text2img workflow (default)
    block_trigger_inputs = ["mask", "image", None]

    @property
    def description(self):
        return (
            "Pipeline generates images given different types of conditions!\n"
            + "This is an auto pipeline block that works for text2img, img2img and inpainting tasks.\n"
            + " - inpaint workflow is run when `mask` is provided.\n"
            + " - img2img workflow is run when `image` is provided (but only when `mask` is not provided).\n"
            + " - text2img workflow is run when neither `image` nor `mask` is provided.\n"
        )
```

Việc bao gồm `description` là **rất** quan trọng để tránh mọi sự nhầm lẫn về cách chạy một block và các đầu vào nào là bắt buộc. Mặc dù [AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) rất tiện lợi, nhưng logic điều kiện của nó có thể khó nắm bắt nếu không được giải thích rõ ràng.

Tạo một instance của `AutoImageBlocks`.

```py
auto_blocks = AutoImageBlocks()
```

Đối với các cấu hình phức tạp hơn, chẳng hạn như các khối [AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) lồng nhau khi chúng được dùng làm khối con trong các pipeline lớn hơn, hãy sử dụng phương thức [get_execution_blocks()](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks.get_execution_blocks) để trích xuất khối thực sự được thực thi dựa trên đầu vào của bạn.

```py
auto_blocks.get_execution_blocks(mask=True)
```

## ConditionalPipelineBlocks

[AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) là một trường hợp đặc biệt của [ConditionalPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks). Trong khi [AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) chọn khối dựa trên việc có cung cấp đầu vào kích hoạt hay không, thì [ConditionalPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks) có thể chọn một khối dựa trên logic tùy chỉnh được cung cấp trong phương thức `select_block`.

Dưới đây là cùng một ví dụ được viết bằng cách sử dụng trực tiếp [ConditionalPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks):

```py
from diffusers.modular_pipelines import ConditionalPipelineBlocks

class AutoImageBlocks(ConditionalPipelineBlocks):
    block_classes = [InpaintBlock, ImageToImageBlock, TextToImageBlock]
    block_names = ["inpaint", "img2img", "text2img"]
    block_trigger_inputs = ["mask", "image"]
    default_block_name = "text2img"

    @property
    def description(self):
        return (
            "Pipeline generates images given different types of conditions!\n"
            + "This is an auto pipeline block that works for text2img, img2img and inpainting tasks.\n"
            + " - inpaint workflow is run when `mask` is provided.\n"
            + " - img2img workflow is run when `image` is provided (but only when `mask` is not provided).\n"
            + " - text2img workflow is run when neither `image` nor `mask` is provided.\n"
        )

    def select_block(self, mask=None, image=None) -> str | None:
        if mask is not None:
            return "inpaint"
        if image is not None:
            return "img2img"
        return None  # falls back to default_block_name ("text2img")
```

Các đầu vào được liệt kê trong `block_trigger_inputs` được truyền dưới dạng các tham số keyword cho `select_block()`. Khi `select_block` trả về `None`, hệ thống sẽ chuyển sang `default_block_name`. Nếu `default_block_name` cũng là `None`, toàn bộ khối điều kiện sẽ bị bỏ qua — điều này hữu ích cho các bước xử lý tùy chọn chỉ nên chạy khi các đầu vào cụ thể được cung cấp.

## Quy trình làm việc

Các pipeline chứa các khối điều kiện ([AutoPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.AutoPipelineBlocks) hoặc [ConditionalPipelineBlocks](/docs/diffusers/main/vi/api/modular_diffusers/pipeline_blocks#diffusers.ConditionalPipelineBlocks)) có thể hỗ trợ nhiều luồng công việc — ví dụ, pipeline modular SDXL của chúng tôi hỗ trợ hàng chục luồng công việc trong cùng một pipeline. Nhưng điều này cũng có nghĩa là người dùng có thể cảm thấy bối rối khi muốn biết những luồng công việc nào được hỗ trợ và cách chạy chúng. Đối với những người xây dựng pipeline, việc có thể trích xuất chỉ các khối liên quan đến một luồng công việc cụ thể là rất hữu ích.

Chúng tôi khuyến nghị định nghĩa `_workflow_map` để đặt tên cho từng workflow và liệt kê rõ các đầu vào mà nó yêu cầu.

```py
from diffusers.modular_pipelines import SequentialPipelineBlocks

class MyPipelineBlocks(SequentialPipelineBlocks):
    block_classes = [TextEncoderBlock, AutoImageBlocks, DecodeBlock]
    block_names = ["text_encoder", "auto_image", "decode"]

    _workflow_map = {
        "text2image": {"prompt": True},
        "image2image": {"image": True, "prompt": True},
        "inpaint": {"mask": True, "image": True, "prompt": True},
    }
```

Tất cả các pipeline module tích hợp sẵn của chúng tôi đều đi kèm với các quy trình làm việc được định nghĩa trước. Thuộc tính `available_workflows` liệt kê tất cả các quy trình làm việc được hỗ trợ:

```py
pipeline_blocks = MyPipelineBlocks()
pipeline_blocks.available_workflows
# ['text2image', 'image2image', 'inpaint']
```

Sử dụng `get_workflow` để lấy một workflow cụ thể nhằm kiểm tra và gỡ lỗi một khối cụ thể thực thi workflow đó.

```py
pipeline_blocks.get_workflow("inpaint")
```

