# SequentialPipelineBlocks

[SequentialPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks) est un type multi-blocs qui compose d'autres [ModularPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) en séquence. Les données circulent linéairement d'un bloc à l'autre à l'aide de `inputs` et `intermediate_outputs`. Chaque bloc de [SequentialPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks) représente généralement une étape du pipeline, et en les combinant, vous construisez progressivement un pipeline.

Ce guide vous montre comment connecter deux blocs dans un [SequentialPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks).

Créez deux [ModularPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks). Le premier bloc, `InputBlock`, renvoie une valeur `batch_size` et le second bloc, `ImageEncoderBlock`, utilise `batch_size` comme `inputs`.

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

class InputBlock(ModularPipelineBlocks):

    @property
    def inputs(self):
        return [
            InputParam(name="prompt", type_hint=list, description="list of text prompts"),
            InputParam(name="num_images_per_prompt", type_hint=int, description="number of images per prompt"),
        ]

    @property
    def intermediate_outputs(self):
        return [
            OutputParam(name="batch_size", description="calculated batch size"),
        ]

    @property
    def description(self):
        return "A block that determines batch_size based on the number of prompts and num_images_per_prompt argument."

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        batch_size = len(block_state.prompt)
        block_state.batch_size = batch_size * block_state.num_images_per_prompt
        self.set_block_state(state, block_state)
        return components, state
```

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

class ImageEncoderBlock(ModularPipelineBlocks):

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

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

    @property
    def description(self):
        return "Encode raw image into its latent presentation"

    def __call__(self, components, state):
        block_state = self.get_block_state(state)
        # Simulate processing the image
        # This will change the state of the image from a PIL image to a tensor for all blocks
        block_state.image = torch.randn(1, 3, 512, 512)
        block_state.batch_size = block_state.batch_size * 2
        block_state.image_latents = torch.randn(1, 4, 64, 64)
        self.set_block_state(state, block_state)
        return components, state
```

Connectez les deux blocs en définissant un [SequentialPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks). Listez les instances de blocs dans `block_classes` et leurs noms correspondants dans `block_names`. Les blocs sont exécutés dans l'ordre où ils apparaissent dans `block_classes`, et les données circulent d'un bloc à l'autre via [PipelineState](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_states#diffusers.modular_pipelines.PipelineState).

```py
class ImageProcessingStep(SequentialPipelineBlocks):
    """
    # auto_docstring
    """
    model_name = "my_model"
    block_classes = [InputBlock(), ImageEncoderBlock()]
    block_names = ["input", "image_encoder"]

    @property
    def description(self):
        return (
            "Process text prompts and images for the pipeline. It:\n"
            " - Determines the batch size from the prompts.\n"
            " - Encodes the image into latent space."
        )
```

Lors de la création d'un [SequentialPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.SequentialPipelineBlocks), les propriétés telles que `inputs`, `intermediate_outputs` et `expected_components` sont automatiquement agrégées à partir des sous-blocs, il n'est donc pas nécessaire de les redéfinir.

Voici quelques propriétés que vous devez définir :

- `description` : Nous recommandons d'ajouter une description pour le bloc assemblé afin d'expliquer ce que fait l'étape combinée.
- `model_name` : Cette valeur est dérivée automatiquement des sous-blocs, mais elle n'est pas toujours correcte, il peut donc être nécessaire de la remplacer.
- `outputs` : par défaut, c'est la même chose que `intermediate_outputs`, mais vous pouvez le définir manuellement pour contrôler les valeurs affichées dans la documentation. C'est utile pour n'afficher que les sorties finales plutôt que toutes les valeurs intermédiaires.

Ces propriétés, ainsi que les `inputs`, `intermediate_outputs` et `expected_components` agrégés, sont utilisées pour générer automatiquement la propriété `doc`.

Affichez le bloc `ImageProcessingStep` pour inspecter ses sous-blocs, et utilisez `doc` pour un résumé complet des entrées, des sorties et des composants du bloc.

```py
blocks = ImageProcessingStep()
print(blocks)
print(blocks.doc)
```

