# LoopSequentialPipelineBlocks

[LoopSequentialPipelineBlocks](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.LoopSequentialPipelineBlocks) — это многоблочный тип, который объединяет другие [ModularPipelineBlocks](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) в цикле. Данные циркулируют, используя `inputs` и `intermediate_outputs`, при этом каждый блок выполняется итеративно. Обычно это используется для создания цикла шумоподавления, который по умолчанию является итеративным.

В этом руководстве показано, как создавать [LoopSequentialPipelineBlocks](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.LoopSequentialPipelineBlocks).

## Обёртка цикла

[LoopSequentialPipelineBlocks](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.LoopSequentialPipelineBlocks), также известный как *обёртка цикла*, поскольку он определяет структуру цикла, переменные итерации и конфигурацию. Внутри обёртки цикла вам потребуются следующие переменные.

- `loop_inputs` — это значения, предоставленные пользователем, и они эквивалентны `inputs`.
- `loop_intermediate_outputs` — это новые промежуточные переменные, создаваемые блоком и добавляемые в [PipelineState](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.PipelineState). Это эквивалентно `intermediate_outputs`.
- Метод `__call__` определяет структуру цикла и логику итераций.

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

class LoopWrapper(LoopSequentialPipelineBlocks):
    model_name = "test"
    @property
    def description(self):
        return "I'm a loop!!"
    @property
    def loop_inputs(self):
        return [InputParam(name="num_steps")]
    @torch.no_grad()
    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        # Loop structure - can be customized to your needs
        for i in range(block_state.num_steps):
            # loop_step executes all registered blocks in sequence
            components, block_state = self.loop_step(components, block_state, i=i)
        self.set_block_state(state, block_state)
        return components, state
```

Обёртка цикла может передавать дополнительные аргументы, такие как индекс текущей итерации, в блоки цикла.

## Блоки циклов

Блок цикла представляет собой [ModularPipelineBlocks](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks), но метод `__call__` работает иначе.

- Он получает переменную итерации от обёртки цикла.
- Работает непосредственно с [BlockState](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.BlockState), а не с [PipelineState](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.PipelineState).
- Для этого не требуется получать или обновлять [BlockState](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.BlockState).

Блоки цикла разделяют один и тот же [BlockState](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.BlockState), что позволяет значениям накапливаться и изменяться на каждой итерации цикла.

```py
class LoopBlock(ModularPipelineBlocks):
    model_name = "test"
    @property
    def inputs(self):
        return [InputParam(name="x")]
    @property
    def intermediate_outputs(self):
        # outputs produced by this block
        return [OutputParam(name="x")]
    @property
    def description(self):
        return "I'm a block used inside the `LoopWrapper` class"
    def __call__(self, components, block_state, i: int):
        block_state.x += 1
        return components, block_state
```

## LoopSequentialPipelineBlocks

Используйте метод [from_blocks_dict()](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.LoopSequentialPipelineBlocks.from_blocks_dict), чтобы добавить блок цикла в обёртку цикла и создать [LoopSequentialPipelineBlocks](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.LoopSequentialPipelineBlocks).

```py
loop = LoopWrapper.from_blocks_dict({"block1": LoopBlock})
```

Добавляйте дополнительные блоки цикла для выполнения в каждой итерации с помощью [from_blocks_dict()](/docs/diffusers/v0.43.0/ru/api/modular_diffusers/pipeline_blocks#diffusers.LoopSequentialPipelineBlocks.from_blocks_dict). Это позволяет изменять блоки, не меняя саму логику цикла.

```py
loop = LoopWrapper.from_blocks_dict({"block1": LoopBlock(), "block2": LoopBlock})
```

Чтобы добавить блок цикла в существующий цикл денойзинга конвейера, например, для выполнения функции `callback_on_step_end` на каждом шаге, см. раздел [Модульные конвейеры](../using-diffusers/callback#modular-pipelines) в руководстве по колбэкам.

