Buckets:

mishig's picture
|
download
raw
28.7 kB
# ModularPipeline
[ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline) convierte [ModularPipelineBlocks](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) en un pipeline ejecutable que carga modelos y realiza las etapas de cálculo definidas en los bloques. Es la interfaz principal para ejecutar un pipeline y su API es muy similar a la de [DiffusionPipeline](/docs/diffusers/v0.43.0/es/api/pipelines/overview#diffusers.DiffusionPipeline), pero con algunas diferencias clave.
- **La carga es perezosa.** Con [DiffusionPipeline](/docs/diffusers/v0.43.0/es/api/pipelines/overview#diffusers.DiffusionPipeline), [from_pretrained()](/docs/diffusers/v0.43.0/es/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) crea el pipeline y carga todos los modelos al mismo tiempo. Con [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline), la creación y la carga son dos pasos separados: [from_pretrained()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) lee la configuración y sabe desde dónde cargar cada componente, pero no carga realmente los pesos del modelo. Cargas los modelos más adelante con [load_components()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components), donde pasas argumentos de carga como `dtype` y `quantization_config`.
- **Dos formas de crear un pipeline.** Puedes usar [from_pretrained()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) con un repositorio de modelos de diffusers existente: se mapea automáticamente a los bloques de pipeline predeterminados y luego se convierte en un [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline) sin configuración adicional. Puedes consultar el [modular_pipelines_directory](https://github.com/huggingface/diffusers/tree/main/src/diffusers/modular_pipelines) para ver qué modelos se admiten actualmente. También puedes ensamblar tu propio pipeline a partir de [ModularPipelineBlocks](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) y convertirlo con el método [init_pipeline()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) (consulta [Creación de un pipeline](#creating-a-pipeline) para más detalles).
- **La ejecución del pipeline es la misma.** Una vez cargado, se llama al pipeline con los mismos argumentos a los que está acostumbrado. Un único [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline) puede soportar múltiples flujos de trabajo (texto a imagen, imagen a imagen, inpainting, etc.) cuando los bloques del pipeline usan [`AutoPipelineBlocks`](./auto_pipeline_blocks) para seleccionar automáticamente el flujo de trabajo en función de sus entradas.
A continuación se muestran ejemplos completos para texto a imagen, imagen a imagen e inpainting con 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")
```
Esta guía le mostrará cómo crear un [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline), gestionar sus componentes y ejecutar la pipeline.
## Creación de un pipeline
Hay dos formas de crear un [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline). Ensamblar y crear un pipeline a partir de [ModularPipelineBlocks](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) con [init_pipeline()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline), o cargar un pipeline existente con [from_pretrained()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained).
También puedes inicializar un [`ComponentsManager`](./components_manager) para gestionar la colocación de dispositivos y la memoria. Si no necesitas el descargado automático, puedes omitir esto y mover el pipeline a tu dispositivo manualmente con `pipeline.to("cuda")`.
> [!TIP]
> Consulte la documentación de [ComponentsManager](./components_manager) para obtener más detalles sobre cómo puede ayudar a gestionar componentes en diferentes flujos de trabajo.
### init_pipeline
[init_pipeline()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) convierte cualquier [ModularPipelineBlocks](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) en un [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline).
Definamos un bloque mínimo para ver cómo funciona:
```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
```
Llama a [init_pipeline()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) para convertirlo en un pipeline. El atributo `blocks` del pipeline son los bloques con los que se creó: determina las entradas, salidas y la lógica de cálculo esperadas.
```py
block = MyBlock()
pipe = block.init_pipeline()
pipe.blocks
```
```
MyBlock {
"_class_name": "MyBlock",
"_diffusers_version": "0.37.0.dev0"
}
```
> [!WARNING]
> Los bloques son mutables: puedes agregar, eliminar o intercambiar bloques libremente antes de crear una pipeline. Sin embargo, una vez que se crea una pipeline, modificar `pipeline.blocks` no afectará a la pipeline, ya que devuelve una copia. Si deseas una estructura de bloques diferente, crea una nueva pipeline después de modificar los bloques.
Cuando se llama a [init_pipeline()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) sin un repositorio, utiliza el `pretrained_model_name_or_path` definido en el [ComponentSpec](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec) del bloque para determinar desde dónde cargar cada componente. Imprimir el pipeline muestra la configuración de carga de los componentes.
```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 pasas un repositorio a [init_pipeline()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline), este anula la ruta de carga al hacer coincidir los componentes de tu bloque con la configuración de la pipeline en ese repositorio (`model_index.json` o `modular_model_index.json`). Consulta [Modular repository](#modular-repository) para ver cómo se registran y guardan las especificaciones de carga.
En el ejemplo siguiente, `pretrained_model_name_or_path` se actualizará a `"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 componente de tu bloque no existe en el repositorio, permanece como `null` y se omite durante [load_components()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components).
### from_pretrained
[from_pretrained()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) es una forma conveniente de crear un [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline) sin tener que definir los bloques usted mismo.
Funciona con tres tipos de repositorios.
**Un repositorio de diffusers estándar.** Pasa cualquier repositorio de modelo compatible y se mapea automáticamente a los bloques de pipeline predeterminados. Los modelos compatibles actualmente incluyen SDXL, Wan, Qwen, Z-Image, Flux y Flux2.
```py
from diffusers import ModularPipeline, ComponentsManager
components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0", components_manager=components
)
```
**Un repositorio modular.** Estos repositorios contienen un `modular_model_index.json` que especifica la clase de cada componente y desde dónde cargarlo, con los componentes almacenados junto a él. Consulte [Repositorio modular](#modular-repository) para saber cómo crear uno.
```py
from diffusers import ModularPipeline, ComponentsManager
components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
"MiniMaxAI/MiniMax-H3", components_manager=components
)
```
**Un repositorio modular con código personalizado.** Algunos repositorios incluyen bloques de pipeline personalizados junto con la configuración de carga. Añade `trust_remote_code=True` para cargarlos. Consulta [Bloques personalizados](./custom_blocks) para saber cómo crear los tuyos.
```py
from diffusers import ModularPipeline, ComponentsManager
components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
"diffusers/Florence2-image-Annotator", trust_remote_code=True, components_manager=components
)
```
Cuando los bloques de la pipeline definen flujos de trabajo (consulte `pipeline.blocks.available_workflows`), pase `workflow=` para conservar solo los bloques de ese flujo de trabajo, la misma poda que realiza [get_workflow()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.get_workflow). La pipeline entonces solo declara los componentes que utiliza ese flujo de trabajo, y su docstring describe exactamente las entradas de ese flujo de trabajo.
```py
pipeline = ModularPipeline.from_pretrained("Qwen/Qwen-Image", workflow="inpainting")
```
## Cargando componentes
Un [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline) no se instancia automáticamente con componentes. Solo carga la configuración y las especificaciones de los componentes. Puedes cargar los componentes con [load_components()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components).
Esto cargará todos los componentes que tienen una especificación de carga válida.
```py
import torch
pipeline.load_components(dtype=torch.float16)
```
También puede cargar componentes específicos por nombre. El siguiente ejemplo solo carga el `text_encoder`.
```py
pipeline.load_components(names=["text_encoder"], dtype=torch.float16)
```
En un pipeline cuyos bloques definen flujos de trabajo, `workflow=` carga solo los componentes que utiliza ese flujo de trabajo. El pipeline conserva todos sus bloques, por lo que esta es la forma conveniente de ejecutar un mismo pipeline a través de varios flujos de trabajo: cada llamada añade solo lo que el nuevo flujo de trabajo aún no tiene.
```py
pipeline.load_components(workflow="inpainting", dtype=torch.float16)
```
Tras la carga, al imprimir el pipeline se muestran los componentes cargados: los dos primeros campos cambian de `null` a la biblioteca y la clase del componente.
```py
pipeline
```
```
# text_encoder is loaded - shows library and class
"text_encoder": [
"transformers",
"CLIPTextModel",
{ ... }
]
# unet is not loaded yet - still null
"unet": [
null,
null,
{ ... }
]
```
Los argumentos de palabra clave como `dtype`, `variant`, `revision` y `quantization_config` se transmiten a `from_pretrained()` para cada componente. Puede pasar un único valor para aplicarlo a todos los componentes, o un diccionario para establecer valores por componente.
```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/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) solo carga los componentes que aún no se han cargado y que tienen una especificación de carga válida. Esto significa que si ya has establecido un componente en el pipeline, llamar a [load_components()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) de nuevo no lo recargará.
## Actualización de componentes
[update_components()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.update_components) reemplaza un componente del pipeline por uno nuevo. Cuando se actualiza un componente, las especificaciones de carga también se actualizan en la configuración del pipeline y [load_components()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) lo omitirá en las llamadas posteriores.
### Desde AutoModel
Puede pasar un objeto de modelo cargado con `AutoModel.from_pretrained()`. Los modelos cargados de esta manera se etiquetan automáticamente con su información de carga.
```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)
```
### Desde ComponentSpec
Use [get_component_spec()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.get_component_spec) para obtener una copia de la especificación actual del componente, modificarla y cargar un nuevo componente.
```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)
```
También puedes crear un [ComponentSpec](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec) desde cero.
No todos los componentes se cargan desde pesos preentrenados: algunos se crean a partir de una configuración (enumerados en `pipeline.config_component_names`). Para estos, use [create()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec.create) en lugar de [load()](/docs/diffusers/v0.43.0/es/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)
```
O simplemente pase el objeto directamente.
```py
from diffusers.guiders import ClassifierFreeGuidance
guider = ClassifierFreeGuidance(guidance_scale=5.0)
pipeline.update_components(guider=guider)
```
Consulte la guía de [Guiders](../using-diffusers/guiders) para obtener más detalles sobre los guiders disponibles y cómo configurarlos.
## Dividir un pipeline en etapas
Dado que los bloques son componibles, puedes desmontar un pipeline y reconstruirlo en pipelines separados para cada etapa. El siguiente ejemplo muestra cómo podemos separar el bloque del codificador de texto del resto del pipeline, de modo que puedas codificar el prompt de forma independiente y pasar los embeddings al 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/v0.43.0/es/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager) gestiona la memoria entre varios pipelines. A diferencia de las estrategias de offloading en [DiffusionPipeline](/docs/diffusers/v0.43.0/es/api/pipelines/overview#diffusers.DiffusionPipeline) que siguen un orden fijo, [ComponentsManager](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager) toma decisiones de offloading dinámicamente cada vez que se ejecuta una pasada hacia adelante de un modelo, basándose en la situación de memoria actual. Esto significa que funciona sin importar cuántos pipelines crees ni en qué orden los ejecutes. Consulta la guía de [ComponentsManager](./components_manager) para más detalles.
Si las etapas de la pipeline comparten componentes (por ejemplo, el mismo VAE utilizado para codificar y decodificar), puede usar [update_components()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.update_components) para pasar un componente ya cargado a otra pipeline en lugar de volver a cargarlo.
## Repositorio modular
Se requiere un repositorio si los bloques de pipeline usan *componentes preentrenados*. El repositorio proporciona las especificaciones de carga y los metadatos.
[ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline) funciona con repositorios de diffusers estándar sin configuración adicional. Sin embargo, también puedes crear un *repositorio modular* para mayor flexibilidad. Un repositorio modular contiene un archivo `modular_model_index.json` con los siguientes 3 elementos.
- `library` y `class` indican desde qué biblioteca se cargó el componente y su clase. Si es `null`, el componente aún no se ha cargado.
- `loading_specs_dict` contiene la información necesaria para cargar el componente, como el repositorio y el subdirectorio desde el que se carga.
```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)
```
Por defecto, [save_pretrained()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.save_pretrained) escribe cada componente actualmente cargado que Diffusers puede serializar. Los componentes que no están cargados, o que no se pueden serializar, no se escriben y conservan sus especificaciones de carga existentes.
### Guardar una copia autocontenida
Cargue todos los componentes y luego guarde. Cada especificación apunta al resultado, por lo que se recarga por completo desde un solo lugar, incluso sin conexión.
```py
pipe = ModularPipeline.from_pretrained("MiniMaxAI/MiniMax-H3")
pipe.load_components()
pipe.save_pretrained("path/to/local-copy")
```
El destino registrado en `modular_model_index.json` es donde [save_pretrained()](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline.save_pretrained) escribe: el `save_directory` para un guardado local, o el `repo_id` cuando pasas `push_to_hub=True`.
Mover los archivos de cualquier otra forma no reescribe el índice. Una copia descargada con `hf download --local-dir` sigue funcionando: cuando se carga un pipeline desde un directorio local, cada componente cuyos archivos están presentes en ese directorio se carga desde él en lugar del repositorio registrado. Una copia subida con `hf upload` sigue apuntando a la ubicación anterior, por lo que en ese caso hay que actualizar el índice manualmente.
Con `huggingface_hub>=1.32.0`, los archivos idénticos respaldados por Xet pueden compartir un mismo payload en caché entre cualquier repositorio de Hub. Esto incluye archivos individuales en un checkpoint fragmentado: un fragmento con el mismo hash de Xet puede reutilizarse incluso cuando otros fragmentos difieren. Ambas descargas deben utilizar el mismo directorio de caché de Hub con soporte para enlaces simbólicos. Cambiar el dtype, la serialización o los límites de los fragmentos puede alterar los hashes de los archivos y evitar la reutilización. Esto ahorra tráfico de descarga y espacio en disco, no la memoria utilizada por los componentes cargados.
La caché compartida es de mejor esfuerzo. Establecer `HF_HUB_DISABLE_SHARED_BLOBS=1` sigue admitiendo la carga, pero almacena copias separadas en la caché. Las referencias de componentes existentes en `modular_model_index.json` permanecen sin cambios; mantenga las referencias externas para los componentes que no se almacenan en el repositorio modular.
### Referenciar componentes en otros repositorios
La especificación de carga de un componente en `modular_model_index.json` puede apuntar a un repositorio diferente. Por ejemplo, [diffusers/flux2-bnb-4bit-modular](https://huggingface.co/diffusers/flux2-bnb-4bit-modular) carga su transformer cuantizado desde `diffusers/FLUX.2-dev-bnb-4bit` y los componentes restantes desde `black-forest-labs/FLUX.2-dev`.
Preferimos fuertemente los repositorios autocontenidos: mantener todos los componentes juntos facilita la descarga, el intercambio y el uso sin conexión de un pipeline, sin depender de otros repositorios. Utilice referencias entre repositorios solo cuando desee intencionalmente que un componente esté alojado en otro lugar.
Pase `overwrite_modular_index=False` para mantener las especificaciones de carga en `modular_model_index.json` tal como están. Un componente guardado cuya especificación de carga esté vacía se completará igualmente con el destino, ya que no hay nada que preservar.
Con `huggingface_hub>=1.32.0`, los archivos idénticos respaldados por Xet pueden compartir una sola carga en caché entre repositorios mediante enlaces simbólicos, evitando descargas y uso de disco duplicados. No se necesitan referencias entre repositorios para esto. Consulte [Guardar una copia autocontenida](#save-a-self-contained-copy) para conocer los requisitos y limitaciones de la caché compartida.
#### Actualizar un índice modular existente
Las referencias existentes al repositorio original siguen funcionando. Si una referencia solo se usaba para evitar descargas duplicadas, es preferible actualizarla para que cargue desde el repositorio modular una vez que los archivos de componentes estén disponibles allí.
Primero, compruebe que el repositorio modular contiene la misma configuración de componentes y todos los archivos de pesos requeridos, incluido el índice de pesos y cada fragmento para un punto de control fragmentado. Los hashes Xet coincidentes determinan qué archivos de pesos pueden reutilizar la caché compartida. Mantenga las referencias a los componentes que están ausentes o que se cargan intencionalmente desde otro punto de control.
Edite solo la especificación de carga relevante en una copia local de `modular_model_index.json`. Por ejemplo, para usar un VAE almacenado en `vae/` en el repositorio modular con la misma variante de pesos:
```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")
```
Esto también elimina el campo `repo` heredado. Una revisión del repositorio original no identifica una revisión en el destino: use `None` para la rama predeterminada del destino, o fije una revisión de destino que contenga el componente. Ajuste `subfolder` y `variant` si sus nombres de archivo difieren.
Antes de publicar el índice actualizado, cárgalo con `ModularPipeline.from_pretrained("path/to/local-copy")`, llama a `load_components(names="vae")` y verifica que el componente se cargue con los parámetros esperados. Sube solo el índice editado; volver a guardar los pesos puede cambiar sus hashes y evitar la reutilización de la caché.
### Código personalizado
Un repositorio modular también puede incluir bloques de pipeline personalizados como código de Python. Esto le permite compartir bloques especializados que no son nativos de Diffusers. Por ejemplo, [diffusers/Florence2-image-Annotator](https://huggingface.co/diffusers/Florence2-image-Annotator) contiene bloques personalizados junto con la configuración de carga:
```
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
```
El archivo `config.json` contiene una clave `auto_map` que indica a [ModularPipeline](/docs/diffusers/v0.43.0/es/api/modular_diffusers/pipeline#diffusers.ModularPipeline) dónde encontrar los bloques personalizados:
```json
{
"_class_name": "Florence2AnnotatorBlocks",
"auto_map": {
"ModularPipelineBlocks": "block.Florence2AnnotatorBlocks"
}
}
```
Carga repositorios de código personalizados con `trust_remote_code=True` como se muestra en [from_pretrained](#frompretrained). Consulta [Bloques personalizados](./custom_blocks) para saber cómo crear y compartir los tuyos.

Xet Storage Details

Size:
28.7 kB
·
Xet hash:
596cc57fa55e12b119b35596082b78f01c0cabddbee0152ef660a88ec135ea6f

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.