# ModularPipelineBlocks

[ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)은 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)을 구축하는 기본 블록입니다. 이 블록은 파이프라인의 특정 단계에서 수행해야 할 구성 요소, 입력/출력 및 계산을 정의합니다. [ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)는 [state](./modular_diffusers_states)를 사용하여 다른 블록과 연결되어 워크플로의 모듈형 구축을 가능하게 합니다.

[ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)만으로는 실행할 수 없습니다. 이는 파이프라인에서 각 단계가 수행해야 할 작업에 대한 설계도입니다. 파이프라인을 실제로 실행하려면 [ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)를 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)으로 변환해야 합니다.

이 가이드에서는 [ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)를 만드는 방법을 보여줍니다.

## 입력과 출력

> [!TIP]
> Modular Diffusers에서 상태가 작동하는 방식에 익숙하지 않다면 [States](./modular_diffusers_states) 가이드를 참조하세요.

[ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)에는 `inputs`와 `intermediate_outputs`가 필요합니다.

- `inputs`는 블록이 계산을 수행하기 위해 [PipelineState](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.PipelineState)에서 읽는 값입니다. 이는 사용자가 제공하는 값(프롬프트나 이미지 등)이거나 이전 블록이 생성한 값(인코딩된 `image_latents` 등)일 수 있습니다.

    `InputParam`을 사용하여 `inputs`를 정의합니다.

```py
class ImageEncodeStep(ModularPipelineBlocks):
    ...

    @property
    def inputs(self):
        return [
            InputParam(name="image", type_hint="PIL.Image", required=True, description="raw input image to process"),
        ]
    ...
```

- `intermediate_outputs`는 블록이 생성하여 [PipelineState](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.PipelineState)에 추가하는 새로운 값입니다. `intermediate_outputs`는 후속 블록의 `inputs`로 사용되거나 파이프라인 실행의 최종 출력으로 사용할 수 있습니다.

    `OutputParam`을 사용하여 `intermediate_outputs`를 정의합니다.

```py
class ImageEncodeStep(ModularPipelineBlocks):
    ...

    @property
    def intermediate_outputs(self):
        return [
            OutputParam(name="image_latents", description="latents representing the image"),
        ]

    ...
```

중간 입력과 출력은 블록을 연결하기 위해 데이터를 공유합니다. 모든 시점에서 접근할 수 있어 워크플로우의 진행 상황을 추적할 수 있습니다.

## 컴포넌트 및 구성

블록에 필요한 구성 요소와 파이프라인 수준의 설정은 [ComponentSpec](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec)과 [ConfigSpec](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ConfigSpec)에 지정됩니다.

- [ComponentSpec](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec)는 블록이 사용하는 예상 구성 요소를 포함합니다. 구성 요소의 `name`이 필요하며, 구성 요소가 정확히 무엇인지 명시하는 `type_hint`가 있으면 좋습니다.
- [ConfigSpec](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ConfigSpec)에는 모든 블록에 걸친 동작을 제어하는 파이프라인 수준의 설정이 포함되어 있습니다.

```py
class ImageEncodeStep(ModularPipelineBlocks):
    ...

    @property
    def expected_components(self):
        return [
            ComponentSpec(name="vae", type_hint=AutoencoderKL),
        ]

    @property
    def expected_configs(self):
        return [
            ConfigSpec("force_zeros_for_empty_prompt", True),
        ]

    ...
```

블록이 파이프라인으로 변환되면, 구성 요소는 `__call__`의 첫 번째 인수로 블록에 사용 가능해집니다.

## 계산 로직

블록이 수행하는 계산은 `__call__` 메서드에서 정의되며, 특정 구조를 따릅니다.

1. `inputs`의 로컬 뷰를 가져오려면 [BlockState](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.BlockState)를 가져옵니다.
2. `inputs`에 대해 계산 로직을 구현합니다.
3. 로컬 [BlockState](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.BlockState)의 변경 사항을 전역 [PipelineState](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.PipelineState)에 반영하도록 [PipelineState](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.PipelineState)를 업데이트합니다.
4. 다음 블록에서 사용할 수 있는 구성 요소와 상태를 반환합니다.

```py
class ImageEncodeStep(ModularPipelineBlocks):

    def __call__(self, components, state):
        # Get a local view of the state variables this block needs
        block_state = self.get_block_state(state)

        # Your computation logic here
        # block_state contains all your inputs
        # Access them like: block_state.image, block_state.processed_image

        # Update the pipeline state with your updated block_states
        self.set_block_state(state, block_state)
        return components, state
```

## 모든 것을 하나로

…

```py
from diffusers import ComponentSpec, AutoencoderKL
from diffusers.modular_pipelines import InputParam, ModularPipelineBlocks, OutputParam

class ImageEncodeStep(ModularPipelineBlocks):

    @property
    def description(self):
        return "Encode an image into latent space."

    @property
    def expected_components(self):
        return [
            ComponentSpec(name="vae", type_hint=AutoencoderKL),
        ]

    @property
    def inputs(self):
        return [
            InputParam(name="image", type_hint="PIL.Image", required=True, description="raw input image to process"),
        ]

    @property
    def intermediate_outputs(self):
        return [
            OutputParam(name="image_latents", type_hint="torch.Tensor", description="latents representing the image"),
        ]

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        block_state.image_latents = components.vae.encode(block_state.image)
        self.set_block_state(state, block_state)
        return components, state
```

모든 블록에는 위에서 정의한 속성으로부터 자동으로 생성되는 `doc` 속성이 있습니다. 이 속성은 블록의 설명, 구성 요소, 입력 및 출력을 요약하여 제공합니다.

```py
block = ImageEncoderStep()
print(block.doc)
class ImageEncodeStep

  Encode an image into latent space.

  Components:
      vae (`AutoencoderKL`)

  Inputs:
      image (`PIL.Image`):
          raw input image to process

  Outputs:
      image_latents (`torch.Tensor`):
          latents representing the image
```

