# ModularPipeline

[ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline) convertit les [ModularPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) en un pipeline exécutable qui charge les modèles et effectue les étapes de calcul définies dans les blocs. C'est l'interface principale pour exécuter un pipeline et l'API est très similaire à celle de [DiffusionPipeline](/docs/diffusers/main/fr/api/pipelines/overview#diffusers.DiffusionPipeline), mais avec quelques différences clés.

- **Le chargement est différé.** Avec [DiffusionPipeline](/docs/diffusers/main/fr/api/pipelines/overview#diffusers.DiffusionPipeline), [from_pretrained()](/docs/diffusers/main/fr/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) crée le pipeline et charge tous les modèles en même temps. Avec [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline), la création et le chargement sont deux étapes distinctes : [from_pretrained()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) lit la configuration et sait où charger chaque composant, mais ne charge pas réellement les poids du modèle. Vous chargez les modèles plus tard avec [load_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components), où vous passez les arguments de chargement tels que `dtype` et `quantization_config`.

- **Deux façons de créer un pipeline.** Vous pouvez utiliser [from_pretrained()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) avec un dépôt de modèle diffusers existant — il mappe automatiquement sur les blocs de pipeline par défaut, puis convertit en [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline) sans configuration supplémentaire. Vous pouvez consulter le [modular_pipelines_directory](https://github.com/huggingface/diffusers/tree/main/src/diffusers/modular_pipelines) pour voir quels modèles sont actuellement pris en charge. Vous pouvez également assembler votre propre pipeline à partir de [ModularPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) et le convertir avec la méthode [init_pipeline()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) (voir [Créer un pipeline](#creating-a-pipeline) pour plus de détails).

- **L’exécution du pipeline est identique.** Une fois chargé, vous appelez le pipeline avec les mêmes arguments que d’habitude. Un seul [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline) peut prendre en charge plusieurs flux de travail (texte-vers-image, image-vers-image, inpainting, etc.) lorsque les blocs du pipeline utilisent [`AutoPipelineBlocks`](./auto_pipeline_blocks) pour sélectionner automatiquement le flux de travail en fonction de vos entrées.

Voici des exemples complets pour la génération d'images à partir de texte, la transformation d'image en image et l'inpainting avec SDXL.

```py
import torch
from diffusers import ModularPipeline

pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
pipeline.load_components(dtype=torch.float16)
pipeline.to("cuda")  # or "mps", "xpu", "cpu"

image = pipeline(prompt="Astronaut in a jungle, cold color palette, muted colors, detailed, 8k").images[0]
image.save("modular_t2i_out.png")
```

```py
import torch
from diffusers import ModularPipeline
from diffusers.utils import load_image

pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
pipeline.load_components(dtype=torch.float16)
pipeline.to("cuda")  # or "mps", "xpu", "cpu"

url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
init_image = load_image(url)
prompt = "a dog catching a frisbee in the jungle"
image = pipeline(prompt=prompt, image=init_image, strength=0.8).images[0]
image.save("modular_i2i_out.png")
```

```py
import torch
from diffusers import ModularPipeline
from diffusers.utils import load_image

pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
pipeline.load_components(dtype=torch.float16)
pipeline.to("cuda")  # or "mps", "xpu", "cpu"

img_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
mask_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-inpaint-mask.png"

init_image = load_image(img_url)
mask_image = load_image(mask_url)

prompt = "A deep sea diver floating"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, strength=0.85).images[0]
image.save("modular_inpaint_out.png")
```

Ce guide vous montre comment créer un [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline), gérer ses composants et exécuter le pipeline.

## Créer un pipeline

Il existe deux façons de créer un [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline). Assembler et créer un pipeline à partir de [ModularPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) avec [init_pipeline()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline), ou charger un pipeline existant avec [from_pretrained()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained).

Vous pouvez également initialiser un [`ComponentsManager`](./components_manager) pour gérer le placement sur les périphériques et la gestion de la mémoire. Si vous n'avez pas besoin de déchargement automatique, vous pouvez passer cette étape et déplacer le pipeline vers votre périphérique manuellement avec `pipeline.to("cuda")`.

> [!TIP]
> Consultez la documentation de [ComponentsManager](./components_manager) pour plus de détails sur la manière dont il peut aider à gérer les composants à travers différents flux de travail.

### init_pipeline

[init_pipeline()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) convertit tout [ModularPipelineBlocks](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) en [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline).

Définissons un bloc minimal pour voir comment il fonctionne :

```py
from transformers import CLIPTextModel
from diffusers.modular_pipelines import (
    ComponentSpec,
    ModularPipelineBlocks,
    PipelineState,
)

class MyBlock(ModularPipelineBlocks):
    @property
    def expected_components(self):
        return [
            ComponentSpec(
                name="text_encoder",
                type_hint=CLIPTextModel,
                pretrained_model_name_or_path="openai/clip-vit-large-patch14",
            ),
        ]

    def __call__(self, components, state: PipelineState) -> PipelineState:
        return components, state
```

Appel [init_pipeline()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) pour le convertir en pipeline. L'attribut `blocks` du pipeline correspond aux blocs à partir desquels il a été créé — il détermine les entrées, les sorties et la logique de calcul attendues.

```py
block = MyBlock()
pipe = block.init_pipeline()
pipe.blocks
```

```
MyBlock {
  "_class_name": "MyBlock",
  "_diffusers_version": "0.37.0.dev0"
}
```

> [!WARNING]
> Les blocs sont mutables — vous pouvez librement ajouter, supprimer ou remplacer des blocs avant de créer un pipeline. Cependant, une fois un pipeline créé, modifier `pipeline.blocks` n'affectera pas le pipeline, car il renvoie une copie. Si vous souhaitez une structure de blocs différente, créez un nouveau pipeline après avoir modifié les blocs.

Lorsque vous appelez [init_pipeline()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) sans dépôt, il utilise le `pretrained_model_name_or_path` défini dans le [ComponentSpec](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec) du bloc pour déterminer d'où charger chaque composant. L'affichage du pipeline montre la configuration de chargement des composants.

```py
pipe
ModularPipeline {
  "_blocks_class_name": "MyBlock",
  "_class_name": "ModularPipeline",
  "_diffusers_version": "0.37.0.dev0",
  "text_encoder": [
    null,
    null,
    {
      "pretrained_model_name_or_path": "openai/clip-vit-large-patch14",
      "revision": null,
      "subfolder": "",
      "type_hint": [
        "transformers",
        "CLIPTextModel"
      ],
      "variant": null
    }
  ]
}
```

Si vous passez un dépôt à [init_pipeline()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline), il remplace le chemin de chargement en comparant les composants de votre bloc avec la configuration du pipeline dans ce dépôt (`model_index.json` ou `modular_model_index.json`). Consultez [Modular repository](#modular-repository) pour savoir comment les spécifications de chargement sont enregistrées et sauvegardées.

Dans l'exemple ci-dessous, le `pretrained_model_name_or_path` sera mis à jour vers `"stabilityai/stable-diffusion-xl-base-1.0"`.

```py
pipe = block.init_pipeline("stabilityai/stable-diffusion-xl-base-1.0")
pipe
ModularPipeline {
  "_blocks_class_name": "MyBlock",
  "_class_name": "ModularPipeline",
  "_diffusers_version": "0.37.0.dev0",
  "text_encoder": [
    null,
    null,
    {
      "pretrained_model_name_or_path": "stabilityai/stable-diffusion-xl-base-1.0",
      "revision": null,
      "subfolder": "text_encoder",
      "type_hint": [
        "transformers",
        "CLIPTextModel"
      ],
      "variant": null
    }
  ]
}
```

Si un composant de votre bloc n'existe pas dans le dépôt, il reste `null` et est ignoré lors de l'appel à [load_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components).

### from_pretrained

[from_pretrained()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) est une méthode pratique pour créer un [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline) sans avoir à définir les blocs vous-même.

Il fonctionne avec trois types de dépôts.

**Un dépôt diffusers standard.** Passez n'importe quel dépôt de modèle pris en charge et il sera automatiquement mappé sur les blocs de pipeline par défaut. Les modèles actuellement pris en charge incluent SDXL, Wan, Qwen, Z-Image, Flux et Flux2.

```py
from diffusers import ModularPipeline, ComponentsManager

components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", components_manager=components
)
```

**Un dépôt modulaire.** Ces dépôts contiennent un `modular_model_index.json` qui spécifie la classe de chaque composant et l’endroit où le charger, les composants étant stockés à ses côtés. Consultez [Dépôt modulaire](#modular-repository) pour savoir comment en créer un.

```py
from diffusers import ModularPipeline, ComponentsManager

components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
    "MiniMaxAI/MiniMax-H3", components_manager=components
)
```

**Un dépôt modulaire avec du code personnalisé.** Certains dépôts incluent des blocs de pipeline personnalisés en plus de la configuration de chargement. Ajoutez `trust_remote_code=True` pour les charger. Consultez [Blocs personnalisés](./custom_blocks) pour savoir comment créer les vôtres.

```py
from diffusers import ModularPipeline, ComponentsManager

components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
    "diffusers/Florence2-image-Annotator", trust_remote_code=True, components_manager=components
)
```

Lorsque les blocs du pipeline définissent des workflows (consultez `pipeline.blocks.available_workflows`), passez `workflow=` pour ne conserver que les blocs de ce workflow — la même élagage que [get_workflow()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.get_workflow). Le pipeline ne déclare alors que les composants utilisés par ce workflow, et sa docstring décrit précisément les entrées de ce workflow.

```py
pipeline = ModularPipeline.from_pretrained("Qwen/Qwen-Image", workflow="inpainting")
```

## Chargement des composants

Un [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline) n'est pas instancié automatiquement avec des composants. Il charge uniquement la configuration et les spécifications des composants. Vous pouvez charger les composants avec [load_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components).

Cela chargera tous les composants qui disposent d'une spécification de chargement valide.

```py
import torch

pipeline.load_components(dtype=torch.float16)
```

Vous pouvez également charger des composants spécifiques par leur nom. L'exemple ci-dessous ne charge que le `text_encoder`.

```py
pipeline.load_components(names=["text_encoder"], dtype=torch.float16)
```

Sur un pipeline dont les blocs définissent des workflows, `workflow=` ne charge que les composants utilisés par ce workflow. Le pipeline conserve tous ses blocs, ce qui en fait la méthode pratique pour exécuter un même pipeline à travers plusieurs workflows : chaque appel n’ajoute que ce qui manque encore au nouveau workflow.

```py
pipeline.load_components(workflow="inpainting", dtype=torch.float16)
```

Après le chargement, l’affichage du pipeline indique les composants chargés — les deux premiers champs passent de `null` à la bibliothèque et à la classe du composant.

```py
pipeline
```

```
# text_encoder is loaded - shows library and class
"text_encoder": [
  "transformers",
  "CLIPTextModel",
  { ... }
]

# unet is not loaded yet - still null
"unet": [
  null,
  null,
  { ... }
]
```

Les arguments de mots-clés tels que `dtype`, `variant`, `revision` et `quantization_config` sont transmis à `from_pretrained()` pour chaque composant. Vous pouvez passer une valeur unique à appliquer à tous les composants, ou un dictionnaire pour définir des valeurs par composant.

```py
# apply bfloat16 to all components
pipeline.load_components(dtype=torch.bfloat16)

# different dtypes per component
pipeline.load_components(dtype={"transformer": torch.bfloat16, "default": torch.float32})
```

[load_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) ne charge que les composants qui n’ont pas encore été chargés et qui disposent d’une spécification de chargement valide. Cela signifie que si vous avez déjà défini un composant sur le pipeline, un nouvel appel à [load_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) ne le rechargera pas.

## Mise à jour des composants

[update_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.update_components) remplace un composant du pipeline par un nouveau. Lorsqu’un composant est mis à jour, les spécifications de chargement sont également mises à jour dans la configuration du pipeline et [load_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) l’ignora lors des appels suivants.

### Depuis AutoModel

Vous pouvez passer un objet de modèle chargé avec `AutoModel.from_pretrained()`. Les modèles chargés de cette manière sont automatiquement étiquetés avec leurs informations de chargement.

```py
from diffusers import AutoModel

unet = AutoModel.from_pretrained(
    "RunDiffusion/Juggernaut-XL-v9", subfolder="unet", variant="fp16", dtype=torch.float16
)
pipeline.update_components(unet=unet)
```

### Depuis ComponentSpec

Utilisez [get_component_spec()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.get_component_spec) pour obtenir une copie de la spécification actuelle du composant, la modifier, puis charger un nouveau composant.

```py
unet_spec = pipeline.get_component_spec("unet")

# modify to load from a different repository
unet_spec.pretrained_model_name_or_path = "RunDiffusion/Juggernaut-XL-v9"

# load and update
unet = unet_spec.load(dtype=torch.float16)
pipeline.update_components(unet=unet)
```

Vous pouvez également créer un [ComponentSpec](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec) à partir de zéro.

Tous les composants ne sont pas chargés à partir de poids pré-entraînés — certains sont créés à partir d'une configuration (listée sous `pipeline.config_component_names`). Pour ceux-ci, utilisez [create()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec.create) au lieu de [load()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec.load).

```py
guider_spec = pipeline.get_component_spec("guider")
guider_spec.config = {"guidance_scale": 5.0}
guider = guider_spec.create()
pipeline.update_components(guider=guider)
```

Ou passez simplement l'objet directement.

```py
from diffusers.guiders import ClassifierFreeGuidance

guider = ClassifierFreeGuidance(guidance_scale=5.0)
pipeline.update_components(guider=guider)
```

Consultez le guide [Guiders](../using-diffusers/guiders) pour plus de détails sur les guiders disponibles et sur leur configuration.

## Découper un pipeline en étapes

Les blocs étant composables, vous pouvez décomposer un pipeline et le reconstruire en pipelines distincts pour chaque étape. L'exemple ci-dessous montre comment séparer le bloc d'encodeur de texte du reste du pipeline, afin que vous puissiez encoder le prompt indépendamment et transmettre les embeddings au pipeline principal.

```py
from diffusers import ModularPipeline, ComponentsManager
import torch

device = "cuda"  # or "mps", "xpu", "cpu"
dtype = torch.bfloat16
repo_id = "black-forest-labs/FLUX.2-klein-4B"

# get the blocks and separate out the text encoder
blocks = ModularPipeline.from_pretrained(repo_id).blocks
text_block = blocks.sub_blocks.pop("text_encoder")

# use ComponentsManager to handle offloading across multiple pipelines
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device=device)

# create separate pipelines for each stage
text_encoder_pipeline = text_block.init_pipeline(repo_id, components_manager=manager)
pipeline = blocks.init_pipeline(repo_id, components_manager=manager)

# encode text
text_encoder_pipeline.load_components(dtype=dtype)
text_embeddings = text_encoder_pipeline(prompt="a cat").get_by_kwargs("denoiser_input_fields")

# denoise and decode
pipeline.load_components(dtype=dtype)
output = pipeline(
    **text_embeddings,
    num_inference_steps=4,
).images[0]
```

[ComponentsManager](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager) gère la mémoire sur plusieurs pipelines. Contrairement aux stratégies de déchargement de [DiffusionPipeline](/docs/diffusers/main/fr/api/pipelines/overview#diffusers.DiffusionPipeline) qui suivent un ordre fixe, [ComponentsManager](/docs/diffusers/main/fr/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager) prend des décisions de déchargement dynamiquement à chaque passage avant d’un modèle, en fonction de la situation mémoire actuelle. Cela signifie qu’il fonctionne quel que soit le nombre de pipelines créés ou l’ordre dans lequel ils sont exécutés. Consultez le guide [ComponentsManager](./components_manager) pour plus de détails.

Si les étapes du pipeline partagent des composants (par exemple, le même VAE utilisé pour l’encodage et le décodage), vous pouvez utiliser [update_components()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.update_components) pour passer un composant déjà chargé à un autre pipeline au lieu de le recharger.

## Dépôt modulaire

Un dépôt est requis si les blocs de pipeline utilisent des *composants pré-entraînés*. Le dépôt fournit les spécifications de chargement et les métadonnées.

[ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline) fonctionne avec les dépôts diffusers classiques sans configuration supplémentaire. Vous pouvez toutefois créer un *dépôt modulaire* pour plus de flexibilité. Un dépôt modulaire contient un fichier `modular_model_index.json` qui comprend les 3 éléments suivants.

- `library` et `class` indiquent la bibliothèque d’origine du composant et sa classe. Si la valeur est `null`, le composant n’a pas encore été chargé.
- `loading_specs_dict` contient les informations nécessaires pour charger le composant, telles que le dépôt et le sous-dossier d’origine.

```py
from diffusers import ModularPipeline

# load from a regular repo
pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
pipeline.load_components()

# push as a modular repository
pipeline.save_pretrained("local/path", repo_id="my-username/sdxl-modular", push_to_hub=True)
```

Par défaut, [save_pretrained()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.save_pretrained) écrit chaque composant actuellement chargé que Diffusers peut sérialiser. Les composants non chargés, ou qui ne peuvent pas être sérialisés, ne sont pas écrits et conservent leurs spécifications de chargement existantes.

### Enregistrer une copie autonome

Chargez tous les composants, puis enregistrez-les. Chaque spécification pointe vers le résultat, de sorte qu'il se recharge entièrement depuis un seul endroit, y compris hors ligne.

```py
pipe = ModularPipeline.from_pretrained("MiniMaxAI/MiniMax-H3")
pipe.load_components()
pipe.save_pretrained("path/to/local-copy")
```

La destination enregistrée dans `modular_model_index.json` est l’endroit où [save_pretrained()](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline.save_pretrained) écrit : le `save_directory` pour une sauvegarde locale, ou le `repo_id` lorsque vous passez `push_to_hub=True`.

Déplacer les fichiers de toute autre manière ne réécrit pas l’index. Une copie téléchargée avec `hf download --local-dir` fonctionne toujours : lorsqu’un pipeline est chargé depuis un répertoire local, chaque composant dont les fichiers sont présents dans ce répertoire est chargé depuis celui-ci plutôt que depuis le dépôt enregistré. Une copie téléversée avec `hf upload` continue de pointer vers l’emplacement d’origine, il faut donc mettre à jour l’index manuellement dans ce cas.

À partir de `huggingface_hub>=1.32.0`, les fichiers identiques basés sur Xet peuvent partager une même charge utile mise en cache entre différents dépôts du Hub. Cela inclut les fichiers individuels d'un point de contrôle fragmenté : un fragment ayant le même hachage Xet peut être réutilisé, même si les autres fragments diffèrent. Les deux téléchargements doivent utiliser le même répertoire de cache du Hub avec prise en charge des liens symboliques. Modifier le type de données, la sérialisation ou les limites des fragments peut changer les hachages des fichiers et empêcher la réutilisation. Cela permet d'économiser le trafic de téléchargement et l'espace disque, mais pas la mémoire utilisée par les composants chargés.

La mise en cache partagée est effectuée sur une base de meilleur effort. La définition de `HF_HUB_DISABLE_SHARED_BLOBS=1` prend toujours en charge le chargement, mais met en cache des copies séparées. Les références aux composants existantes dans `modular_model_index.json` restent inchangées ; conservez les références externes pour les composants qui ne sont pas stockés dans le dépôt modulaire.

### Référence de composants dans d'autres dépôts

La spécification de chargement d'un composant dans `modular_model_index.json` peut pointer vers un dépôt différent. Par exemple, [diffusers/flux2-bnb-4bit-modular](https://huggingface.co/diffusers/flux2-bnb-4bit-modular) charge son transformeur quantisé depuis `diffusers/FLUX.2-dev-bnb-4bit` et les composants restants depuis `black-forest-labs/FLUX.2-dev`.

Nous préférons vivement les dépôts autonomes : regrouper tous les composants facilite le téléchargement, le partage et l'utilisation hors ligne d'un pipeline, sans dépendre d'autres dépôts. N'utilisez des références inter-dépôts que si vous souhaitez intentionnellement qu'un composant soit hébergé ailleurs.

Passez `overwrite_modular_index=False` pour conserver les spécifications de chargement de `modular_model_index.json` en l’état. Un composant enregistré dont la spécification de chargement est vide est toujours complété avec la destination, car il n’y a rien à préserver.

À partir de `huggingface_hub>=1.32.0`, les fichiers identiques basés sur Xet peuvent partager une même charge utile mise en cache entre les dépôts via des liens symboliques, évitant ainsi les téléchargements et l'occupation disque en double. Les références inter-dépôts ne sont pas nécessaires pour cela. Consultez [Enregistrer une copie autonome](#save-a-self-contained-copy) pour connaître les exigences et les limites de la cache partagée.

#### Mettre à jour un index modulaire existant

Les références existantes au dépôt d’origine continuent de fonctionner. Si une référence n’était utilisée que pour éviter les téléchargements en double, il est préférable de la mettre à jour afin de charger depuis le dépôt modulaire dès que les fichiers de composant y sont disponibles.

Vérifiez d'abord que le dépôt modulaire contient la même configuration de composants ainsi que tous les fichiers de poids requis, y compris l'index des poids et chaque fragment pour un point de contrôle fragmenté. Les hachages Xet correspondants déterminent quels fichiers de poids peuvent réutiliser le cache partagé. Conservez les références aux composants absents ou chargés intentionnellement depuis un autre point de contrôle.

Modifiez uniquement la spécification de chargement pertinente dans une copie locale de `modular_model_index.json`. Par exemple, pour utiliser un VAE stocké sous `vae/` dans le dépôt modulaire avec la même variante de poids :

```py
import json
from pathlib import Path

index_path = Path("path/to/local-copy/modular_model_index.json")
index = json.loads(index_path.read_text())
spec = index["vae"][2]
spec["pretrained_model_name_or_path"] = "my-username/my-modular-repo"
spec.pop("repo", None)
spec["subfolder"] = "vae"
spec["revision"] = None
index_path.write_text(json.dumps(index, indent=2) + "\n")
```

Cela supprime également le champ `repo` obsolète. Une révision du dépôt d’origine n’identifie pas une révision dans la destination : utilisez `None` pour la branche par défaut de la destination, ou fixez une révision de destination contenant le composant. Ajustez `subfolder` et `variant` si les noms de fichiers diffèrent.

Avant de publier l’index mis à jour, chargez-le avec `ModularPipeline.from_pretrained("path/to/local-copy")`, appelez `load_components(names="vae")` et vérifiez que le composant se charge avec les paramètres attendus. Téléchargez uniquement l’index modifié ; la réenregistrement des poids peut modifier leurs hachages et empêcher la réutilisation du cache.

### Code personnalisé

Un dépôt modulaire peut également inclure des blocs de pipeline personnalisés sous forme de code Python. Cela vous permet de partager des blocs spécialisés qui ne sont pas natifs à Diffusers. Par exemple, [diffusers/Florence2-image-Annotator](https://huggingface.co/diffusers/Florence2-image-Annotator) contient des blocs personnalisés aux côtés de la configuration de chargement :

```
Florence2-image-Annotator/
├── block.py                    # Custom pipeline blocks implementation
├── config.json                 # Pipeline configuration and auto_map
├── mellon_config.json          # UI configuration for Mellon
└── modular_model_index.json    # Component loading specifications
```

Le fichier `config.json` contient une clé `auto_map` qui indique à [ModularPipeline](/docs/diffusers/main/fr/api/modular_diffusers/pipeline#diffusers.ModularPipeline) où trouver les blocs personnalisés :

```json
{
  "_class_name": "Florence2AnnotatorBlocks",
  "auto_map": {
    "ModularPipelineBlocks": "block.Florence2AnnotatorBlocks"
  }
}
```

Chargez des dépôts de code personnalisés avec `trust_remote_code=True` comme indiqué dans [from_pretrained](#frompretrained). Consultez [Blocs personnalisés](./custom_blocks) pour savoir comment créer et partager les vôtres.

