# DiffusionGemma

DiffusionGemma es un modelo de lenguaje encoder-decoder de difusión por bloques. Un encoder causal lee el prompt limpio (y cualquier bloque generado previamente) en una caché KV, y un decoder bidireccional desruidiza un "lienzo" de tamaño fijo de `canvas_length` tokens mediante atención cruzada con esa caché. La generación alterna un bucle externo autoregresivo sobre lienzos con un bucle interno de desruidizado, donde cada paso muestrea tokens candidatos, confirma los de mayor confianza mediante [BlockRefinementScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler) en modo de corrupción uniforme y vuelve a añadir ruido al resto. El modelo en sí se encuentra en `transformers` como `DiffusionGemmaForBlockDiffusion`; el punto de control publicado es [`google/diffusiongemma-26B-A4B-it`](https://huggingface.co/google/diffusiongemma-26B-A4B-it).

## Uso

```py
import torch
from transformers import AutoProcessor, DiffusionGemmaForBlockDiffusion

from diffusers import BlockRefinementScheduler, DiffusionGemmaPipeline

model_id = "google/diffusiongemma-26B-A4B-it"
model = DiffusionGemmaForBlockDiffusion.from_pretrained(model_id, dtype=torch.bfloat16, device_map="auto")
processor = AutoProcessor.from_pretrained(model_id)
scheduler = BlockRefinementScheduler()

pipe = DiffusionGemmaPipeline(model=model, scheduler=scheduler, processor=processor)
pipe.model.model.decoder = torch.compile(pipe.model.model.decoder, mode="reduce-overhead", fullgraph=True)
output = pipe(
    prompt="Why is the sky blue?",
    gen_length=256,
    num_inference_steps=48,
    cache_implementation="static",
)
print(output.texts[0])
```

`num_inference_steps` es el número de pasos de desruido por lienzo (48 coincide con el punto de control publicado); menos pasos son más rápidos pero de menor calidad. `cache_implementation="static"` permite que el decodificador se compile con `torch.compile` y cudagraphs (ver [Caché estática y compilación](#static-cache-and-compilation)); omita ambos para una ejecución más simple con caché dinámica.

Para entradas de varios turnos o multimodales, pase una conversación cruda de `messages` en lugar de `prompt`. Es una lista de diccionarios `{"role", "content"}` en el formato de chat habitual, que el procesador ejecuta a través de su plantilla de chat:

```py
messages = [
    {"role": "user", "content": "Why is the sky blue?"},
]
# or with an image:
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "image": image},
            {"type": "text", "text": "Describe this image."},
        ],
    },
]
output = pipe(messages=messages, gen_length=256)
```

Para un turno de un solo usuario, puedes omitir `messages` y pasar una `image` junto con el `prompt`; el procesador la convierte automáticamente en las entradas de imagen del modelo.

## Planificadores

El scheduler es el sampler que desruidifica cada lienzo y es intercambiable: cámbialo para modificar la estrategia de muestreo sin tocar nada más. Hay tres schedulers disponibles:

- [BlockRefinementScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler) (predeterminado): confirma en cada paso los tokens más seguros (por encima de `threshold`, más una cuota uniforme por paso) y re-ruidos el resto. `editing_threshold` permite además reeditar tokens ya confirmados.
- [DiscreteDDIMScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/discrete_ddim#diffusers.DiscreteDDIMScheduler): muestrea cada posición de la posterior discreta exacta del proceso de corrupción uniforme (D3PM). No tiene parámetros y el paso final compromete de forma determinista los tokens predichos.
- [EntropyBoundScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/entropy_bound#diffusers.EntropyBoundScheduler): confirma las posiciones de menor entropía cuya entropía conjunta se mantiene por debajo de `entropy_bound`, de modo que los tokens aproximadamente independientes se acepten juntos. Anela su temperatura de muestreo desde `t_max` (`0.8`) en el primer paso hasta `t_min` (`0.4`) en el último, coincidiendo con el muestreador del punto de control publicado.

```py
from diffusers import DiscreteDDIMScheduler, EntropyBoundScheduler

pipe.scheduler = DiscreteDDIMScheduler()
# or: pipe.scheduler = EntropyBoundScheduler(entropy_bound=0.1)
output = pipe(prompt="Why is the sky blue?", gen_length=256, num_inference_steps=48)
print(output.texts[0])
```

Los parámetros de muestreo específicos del programador (el `threshold`/`top_k` de refinamiento de bloques, el límite de entropía, ...) se configuran en la configuración del programador:

```py
from diffusers import BlockRefinementScheduler

pipe.scheduler = BlockRefinementScheduler.from_config(pipe.scheduler.config, threshold=0.9)
```

`EntropyBoundScheduler` reduce internamente su temperatura de muestreo (`t_max`/`t_min`) a lo largo de los pasos de desruido; `DiscreteDDIMScheduler` y `BlockRefinementScheduler` utilizan la `temperature` plana que se pasa a la pipeline (`0.0` para greedy).

### Muestreo predictor-corrección

`DiscreteDDIMScheduler` admite el predictor-corrección leave-one-out de [Uniform Diffusion Models Revisited: Leave-One-Out Denoiser and Absorbing State Reformulation](https://huggingface.co/papers/2605.22765). Refina el lienzo con `corrector_steps` barridos de Gibbs que muestrean de nuevo las posiciones de menor confianza a partir de la condicional de una coordenada de la marginal ruidosa, lo que deja esa marginal invariante y mejora la generación sin coste adicional de entrenamiento. Funciona directamente sobre el checkpoint publicado: para la difusión uniforme, el desruidador y la posterior leave-one-out son intercambiables en forma cerrada, por lo que el corrector recupera las cantidades leave-one-out que necesita sin necesidad de ningún reentrenamiento.

Los barridos del corrector se integran en el presupuesto de `num_inference_steps` en lugar de sumarse a él: la tubería ejecuta menos pasos del predictor y destina las pasadas liberadas a los correctores, de modo que el número total de pasadas del modelo se mantiene en `num_inference_steps` y el costo del predictor-corrector es el mismo que el de la muestreo ancestral simple.

```py
from diffusers import DiscreteDDIMScheduler

pipe.scheduler = DiscreteDDIMScheduler(corrector_steps=2, corrector_k=12)
output = pipe(prompt="Why is the sky blue?", gen_length=256, num_inference_steps=48)
print(output.texts[0])
```

## Adaptadores PEFT

El denoiser es un modelo de 🤗 Transformers, por lo que los adaptadores se cargan a través de su integración nativa de [PEFT](https://huggingface.co/docs/peft) en lugar de la API `load_lora_weights` de diffusers. Dado que esa integración no depende del tipo de adaptador, las mismas llamadas cargan adaptadores LoRA, DoRA o cualquier otro adaptador PEFT (p. ej., la salida de `SFTTrainer` de TRL). Gestione los adaptadores directamente en el componente del modelo:

```py
pipe.model.load_adapter("path/to/adapter", adapter_name="sft")  # LoRA, DoRA, ...
pipe.model.set_adapter("sft")
output = pipe(prompt="Why is the sky blue?", gen_length=256)

pipe.model.disable_adapters()  # run the base model
pipe.model.delete_adapter("sft")
```

Los adaptadores permanecen activos y sin fusionar: DiffusionGemma vincula los pesos base del codificador y del decodificador, por lo que fusionar un adaptador en ellos corruptaría ambas ramas.

## Caché estática y compilación

El pipeline precarga el codificador una vez por bloque en una caché reutilizable (una `DynamicCache` por defecto). Pasar `cache_implementation="static"` utiliza en su lugar una `StaticCache` de forma fija, cuyas formas permiten `torch.compile` el decodificador con cudagraphs para una mayor aceleración (el pipeline marca cada paso y clona los logits para que la memoria de cudagraph no se sobrescriba); esta es la configuración mostrada en [Uso](#usage). Elimina tanto la llamada a `torch.compile` como `cache_implementation="static"` para una ejecución más simple con caché dinámica.

## Detención adaptativa

Un bloque suele converger antes de agotar todos los `num_inference_steps`, por lo que, de forma predeterminada, el pipeline congela cada ejemplo del lote una vez que su predicción de argmax es estable durante `stability_threshold` pasos y su entropía media por token cae por debajo de `confidence_threshold` (`0.005`, el valor utilizado por el checkpoint publicado). El bucle de desruido finaliza una vez que todos los ejemplos están congelados. Esto reduce aproximadamente a la mitad el número de pases del decodificador a una calidad equivalente y es el mayor factor individual de rendimiento. Pasa `confidence_threshold=None` para ejecutar siempre los `num_inference_steps` completos:

```py
output = pipe(prompt="Why is the sky blue?", gen_length=256, confidence_threshold=None)  # disable adaptive stopping
```

## Callbacks

Los callbacks se ejecutan después de cada paso de desruido. Pasa `callback_on_step_end_tensor_inputs` para seleccionar qué tensores se incluyen en `callback_kwargs`; `canvas` (los tokens del bloque actual) y `logits` están disponibles. Devuelve `{"canvas": ...}` desde el callback para reemplazar el canvas.

```py
def on_step_end(pipe, step, timestep, callback_kwargs):
    canvas = callback_kwargs["canvas"]
    # Inspect or modify `canvas` here.
    return {"canvas": canvas}

out = pipe(
    prompt="Why is the sky blue?",
    callback_on_step_end=on_step_end,
    callback_on_step_end_tensor_inputs=["canvas"],
)
```

## DiffusionGemmaPipeline[[diffusers.DiffusionGemmaPipeline]]

#### diffusers.DiffusionGemmaPipeline[[diffusers.DiffusionGemmaPipeline]]

```python
diffusers.DiffusionGemmaPipeline(model: Any, scheduler: BlockRefinementScheduler | DiscreteDDIMScheduler | EntropyBoundScheduler, processor: Any)
```

[Fuente](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/diffusion_gemma/pipeline_diffusion_gemma.py#L53)

**Parámetros:**

model ([DiffusionGemmaForBlockDiffusion](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/diffusion_gemma#transformers.DiffusionGemmaForBlockDiffusion)) : El desruidador de difusión por bloques (codificador causal + decodificador bidireccional con pesos compartidos).

scheduler ([BlockRefinementScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler), [DiscreteDDIMScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/discrete_ddim#diffusers.DiscreteDDIMScheduler) o [EntropyBoundScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/entropy_bound#diffusers.EntropyBoundScheduler)) : El muestreador que confirma y re-ruidifica los tokens del lienzo en cada paso de desruido.

processor ([ProcessorMixin](https://huggingface.co/docs/transformers/v5.22.2/en/main_classes/processors#transformers.ProcessorMixin)) : el procesador utilizado para aplicar la plantilla de chat y decodificar los tokens generados.

Pipeline para la generación de texto con difusión por bloques de DiffusionGemma.

DiffusionGemma es un modelo encoder-decoder de difusión por bloques: un encoder causal lee el prompt limpio (y cualquier bloque generado previamente) en una caché KV, y un decoder bidireccional desruidiza un lienzo de tamaño fijo de `canvas_length` tokens mediante atención cruzada con esa caché. La generación alterna un bucle externo autoregresivo sobre los lienzos con un bucle interno de desruidizado, donde cada paso muestrea tokens candidatos, confirma los de mayor confianza mediante [BlockRefinementScheduler](/docs/diffusers/v0.43.0/es/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler) (modo de corrupción uniforme, `mask_token_id=None`) y vuelve a añadir ruido al resto.

Se espera que el modelo sea una instancia de `DiffusionGemmaForBlockDiffusion` que exponga `forward(input_ids, decoder_input_ids=..., self_conditioning_logits=..., ...)` y devuelva logits de forma `[batch, canvas_length, vocab_size]` sobre el lienzo. Consulte la tarjeta del modelo en https://huggingface.co/google/diffusiongemma-26B-A4B-it.

#### __call__[[diffusers.DiffusionGemmaPipeline.__call__]]

```python
__call__(prompt: str | list[str] | None = None, messages: list[dict] | None = None, image: Any | list[Any] | None = None, add_generation_prompt: bool = True, gen_length: int = 256, num_inference_steps: int = 48, temperature: float = 0.0, cache_implementation: str | None = None, eos_early_stop: bool = True, eos_token_id: int | None = None, stability_threshold: int = 1, confidence_threshold: float | None = 0.005, generator: torch.Generator | None = None, output_type: str = 'text', return_dict: bool = True, callback_on_step_end: Callable[[Any, int, int, dict], dict] | PipelineCallback | MultiPipelineCallbacks | None = None, callback_on_step_end_tensor_inputs: list[str] | None = None)
```

[Fuente](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/diffusion_gemma/pipeline_diffusion_gemma.py#L163)

**Parámetros:**

prompt (`str` o `List[str]`, *opcional*) : Texto del prompt, envuelto en una plantilla de chat y tokenizado por el procesador. Proporcione esto o `messages`.

messages (`List[Dict]`, *opcional*) : Una conversación de chat sin procesar para codificar, por ejemplo, `[{"role": "user", "content": "Hello"}]` o una conversación de varios turnos / multimodal. Utilice esto en lugar de `prompt` para cualquier cosa que vaya más allá de un solo turno de usuario.

image (`PIL.Image.Image` o `List`, *opcional*) : Imagen(es) para asociar con `prompt` para la generación multimodal; el procesador las convierte en las entradas de imagen del modelo. Para diseños más ricos, coloque el contenido de la imagen directamente en `messages`.

add_generation_prompt (`bool`, por defecto `True`) : Si se debe añadir el prompt de generación al aplicar la plantilla de chat.

gen_length (`int`, por defecto `256`) : Número de tokens a generar, redondeado hacia arriba a un múltiplo de la `canvas_length` del modelo.

num_inference_steps (`int`, por defecto `48`) : Número de pasos de desruido por lienzo.

temperature (`float`, por defecto `0.0`) : Temperatura de muestreo para `DiscreteDDIMScheduler`/`BlockRefinementScheduler` (`0.0` es codicioso); `EntropyBoundScheduler` la ignora y ajusta su propia temperatura. Otros parámetros de muestreo (p. ej. `top_k`, `threshold`, `t_min`/`t_max`) son configuración del programador; establécelos en el programador, p. ej. `pipe.scheduler = BlockRefinementScheduler.from_config(pipe.scheduler.config, top_k=...)`.

cache_implementation (`str`, *opcional*) : Establezca `"static"` para prellenar el codificador una vez por bloque en una `StaticCache` persistente y ejecutar el decodificador contra ella con formas fijas, en lugar de recodificar la secuencia completa en cada paso. Las formas fijas también le permiten compilar el decodificador, por ejemplo, `pipe.model.model.decoder = torch.compile(pipe.model.model.decoder, fullgraph=True)`.

eos_early_stop (`bool`, por defecto `True`) : Si se debe dejar de generar más lienzos una vez que cada secuencia ha emitido EOS.

eos_token_id (`int`, *opcional*) : ID del token EOS para la detención anticipada. Si no se especifica, se utiliza el tokenizador del procesador.

stability_threshold (`int`, por defecto `1`) : Número de pasos consecutivos durante los cuales la predicción argmax de un ejemplo debe permanecer sin cambios para que ese ejemplo se considere estable. Solo se utiliza cuando se establece `confidence_threshold`.

confidence_threshold (`float`, *opcional*, valor predeterminado `0.005`) : Congela cada ejemplo una vez que es estable (ver `stability_threshold`) y la entropía media por token de sus logits de predicción con forma de programador es inferior a este valor. El bucle de desruido del bloque termina una vez que todos los ejemplos están congelados. Acelera la generación con la misma calidad; el valor predeterminado coincide con el punto de control publicado. Establece `None` para ejecutar siempre todos los `num_inference_steps`.

generator (`torch.Generator`, *opcional*) : Generador de números aleatorios para el muestreo.

output_type (`str`, por defecto `"text"`) : `"text"` decodifica las secuencias en cadenas de texto (requiere un procesador); `"seq"` devuelve solo los IDs de tokens.

return_dict (`bool`, por defecto `True`) : Si se debe devolver un [DiffusionGemmaPipelineOutput](/docs/diffusers/v0.43.0/es/api/pipelines/diffusion_gemma#diffusers.DiffusionGemmaPipelineOutput) en lugar de una tupla.

callback_on_step_end (`Callable` o `PipelineCallback`, *opcional*) : Callback que se ejecuta después de cada paso de desruido con la firma `callback_on_step_end(self, step, timestep, callback_kwargs)`. Claves de tensor permitidas: `canvas`, `logits`.

callback_on_step_end_tensor_inputs (`List[str]`, *opcional*) : Claves de tensor para pasar al callback.

**Devuelve:** [DiffusionGemmaPipelineOutput](/docs/diffusers/v0.43.0/es/api/pipelines/diffusion_gemma#diffusers.DiffusionGemmaPipelineOutput) o `tuple`

Los IDs de tokens generados (`sequences`) y, para `output_type="text"`, los `texts` decodificados.

Generar texto con difusión por bloques.

Ejemplos:
```python
>>> import torch
>>> from transformers import AutoProcessor, DiffusionGemmaForBlockDiffusion
>>> from diffusers import BlockRefinementScheduler, DiffusionGemmaPipeline

>>> model_id = "google/diffusiongemma-26B-A4B-it"
>>> model = DiffusionGemmaForBlockDiffusion.from_pretrained(model_id, dtype=torch.bfloat16, device_map="auto")
>>> processor = AutoProcessor.from_pretrained(model_id)
>>> scheduler = BlockRefinementScheduler()

>>> pipe = DiffusionGemmaPipeline(model=model, scheduler=scheduler, processor=processor)
>>> output = pipe(prompt="Why is the sky blue?", gen_length=256)
>>> print(output.texts[0])
```

## DiffusionGemmaPipelineOutput[[diffusers.DiffusionGemmaPipelineOutput]]

#### diffusers.DiffusionGemmaPipelineOutput[[diffusers.DiffusionGemmaPipelineOutput]]

```python
diffusers.DiffusionGemmaPipelineOutput(sequences: torch.LongTensor, texts: list[str] | None = None)
```

[Fuente](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/diffusion_gemma/pipeline_output.py#L25)

**Parámetros:**

sequences (`torch.LongTensor` de forma `(batch_size, gen_length)`) : Los IDs de los tokens generados (el prompt se elimina).

texts (`list[str]`, *opcional*) : El texto decodificado, una cadena por secuencia. Solo se establece para `output_type="text"`.

Clase de salida para la generación de difusión por bloques de DiffusionGemma.

