# DiffusionGemma

DiffusionGemma est un modèle de langage encodeur-décodeur à diffusion par blocs. Un encodeur causal lit le prompt propre (ainsi que les blocs générés précédemment) dans un cache KV, et un décodeur bidirectionnel débruite un « canevas » de taille fixe de `canvas_length` jetons en effectuant une attention croisée avec ce cache. La génération alterne une boucle externe autorégressive sur les canevas et une boucle interne de débruitage, où chaque étape échantillonne des jetons candidats, valide les plus confiants via [BlockRefinementScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler) en mode de corruption uniforme, et rebruite le reste. Le modèle lui-même se trouve dans `transformers` sous la forme de `DiffusionGemmaForBlockDiffusion` ; le point de contrôle publié est [`google/diffusiongemma-26B-A4B-it`](https://huggingface.co/google/diffusiongemma-26B-A4B-it).

## Utilisation

```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` est le nombre d’étapes de débruitage par canevas (48 correspond au point de contrôle publié) ; moins d’étapes est plus rapide mais de moindre qualité. `cache_implementation="static"` permet au décodeur d’être compilé avec `torch.compile` et cudagraphs (voir [Cache statique et compilation](#static-cache-and-compilation)) ; supprimez les deux pour une exécution plus simple avec un cache dynamique.

Pour les entrées multi-tours ou multimodales, passez une conversation brute `messages` au lieu de `prompt`. Il s’agit d’une liste de dictionnaires `{"role", "content"}` au format de chat habituel, que le processeur fait passer par son modèle 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)
```

Pour un tour utilisateur unique, vous pouvez omettre `messages` et passer une `image` avec le `prompt` ; le processeur la convertit automatiquement en entrées d'image du modèle.

## Planificateurs

Le planificateur est le module d'échantillonnage qui débruite chaque canevas, et il est interchangeable : remplacez-le pour modifier la stratégie d'échantillonnage sans rien toucher d'autre. Trois planificateurs sont disponibles :

- [BlockRefinementScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler) (par défaut) : engage les jetons les plus sûrs à chaque étape (ceux au-dessus de `threshold`, plus un quota paritaire par étape) et réintroduit du bruit sur le reste. `editing_threshold` permet en outre de rééditer les jetons déjà engagés.
- [DiscreteDDIMScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/discrete_ddim#diffusers.DiscreteDDIMScheduler) : échantillonne chaque position à partir de la postérieure discrète exacte du processus de corruption uniforme (D3PM). Il ne comporte aucun paramètre et l'étape finale engage de manière déterministe les jetons prédits.
- [EntropyBoundScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/entropy_bound#diffusers.EntropyBoundScheduler) : engage les positions à plus faible entropie dont l’entropie conjointe reste sous `entropy_bound`, de sorte que des jetons approximativement indépendants soient acceptés ensemble. Il fait recuire sa température d’échantillonnage depuis `t_max` (`0.8`) à la première étape jusqu’à `t_min` (`0.4`) à la dernière, conformément à l’échantillonneur du point de contrôle publié.

```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])
```

Les paramètres d'échantillonnage spécifiques au planificateur (le `threshold`/`top_k` de raffinement du bloc, la borne d'entropie, ...) sont définis dans la configuration du planificateur :

```py
from diffusers import BlockRefinementScheduler

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

`EntropyBoundScheduler` effectue un recuit de sa température d’échantillonnage (`t_max`/`t_min`) en interne au fil des étapes de débruitage ; `DiscreteDDIMScheduler` et `BlockRefinementScheduler` utilisent la `temperature` plate transmise au pipeline (`0.0` pour un échantillonnage glouton).

### Échantillonnage prédicteur-correcteur

`DiscreteDDIMScheduler` prend en charge le prédicteur-correcteur leave-one-out de [Uniform Diffusion Models Revisited: Leave-One-Out Denoiser and Absorbing State Reformulation](https://huggingface.co/papers/2605.22765). Il affine le canevas à l’aide de `corrector_steps` balayages de Gibbs qui rééchantillonnent les positions les moins confiantes à partir de la conditionnelle à une coordonnée de la marginale bruitée, ce qui laisse cette marginale invariante et améliore la génération sans coût d’entraînement supplémentaire. Il fonctionne directement sur le point de contrôle publié : pour la diffusion uniforme, le débruiteur et la postérieure leave-one-out sont interchangeables sous forme fermée, de sorte que le correcteur récupère les quantités leave-one-out dont il a besoin sans aucun réentraînement.

Les balayages du correcteur sont intégrés au budget de `num_inference_steps` plutôt qu’ajoutés en sus : le pipeline exécute moins d’étapes de prédicteur et consacre les passages avant libérés aux correcteurs, de sorte que le nombre total de passages avant du modèle reste `num_inference_steps` et que le coût prédicteur-correcteur est identique à celui de l’échantillonnage 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])
```

## Adaptateurs PEFT

Le débruiteur est un modèle 🤗 Transformers, les adaptateurs sont donc chargés via son intégration native [PEFT](https://huggingface.co/docs/peft) plutôt que via l’API `load_lora_weights` de diffusers. Comme cette intégration est indépendante du type d’adaptateur, les mêmes appels chargent des adaptateurs LoRA, DoRA ou tout autre adaptateur PEFT (par exemple la sortie de `SFTTrainer` de TRL). Gérez les adaptateurs directement sur le composant modèle :

```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")
```

Les adaptateurs restent actifs et non fusionnés : DiffusionGemma lie les poids de base de l’encodeur et du décodeur, de sorte que la fusion d’un adaptateur dans ceux-ci corromprait les deux branches.

## Cache statique et compilation

Le pipeline préremplit l'encodeur une fois par bloc dans un cache réutilisable (un `DynamicCache` par défaut). Passer `cache_implementation="static"` utilise à la place un `StaticCache` de forme fixe, dont les formes permettent de `torch.compile` le décodeur avec cudagraphs pour un gain de vitesse supplémentaire (le pipeline marque chaque étape et clone les logits afin que la mémoire cudagraph ne soit pas écrasée) ; c'est la configuration présentée dans [Utilisation](#usage). Supprimez à la fois l'appel `torch.compile` et `cache_implementation="static"` pour une exécution plus simple avec un cache dynamique.

## Arrêt adaptatif

Un bloc converge généralement avant que toutes les `num_inference_steps` ne soient consommées. Par défaut, le pipeline fige chaque exemple du lot dès que sa prédiction argmax est stable pendant `stability_threshold` étapes et que son entropie moyenne par jeton passe sous `confidence_threshold` (`0.005`, la valeur utilisée par le point de contrôle publié). La boucle de débruitage se termine dès que tous les exemples sont figés. Cela divise par deux, à qualité égale, le nombre de passages en avant du décodeur et constitue le levier de débit le plus important. Passez `confidence_threshold=None` pour toujours exécuter les `num_inference_steps` complètes :

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

## Callbacks

Les callbacks s'exécutent après chaque étape de débruitage. Passez `callback_on_step_end_tensor_inputs` pour sélectionner les tenseurs inclus dans `callback_kwargs` ; `canvas` (les jetons du bloc actuel) et `logits` sont disponibles. Retournez `{"canvas": ...}` depuis le callback pour remplacer le 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)
```

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

**Paramètres :**

model ([DiffusionGemmaForBlockDiffusion](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/diffusion_gemma#transformers.DiffusionGemmaForBlockDiffusion)) : le débruiteur de diffusion par blocs (encodeur causal + décodeur bidirectionnel avec poids liés).

scheduler ([BlockRefinementScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler), [DiscreteDDIMScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/discrete_ddim#diffusers.DiscreteDDIMScheduler) ou [EntropyBoundScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/entropy_bound#diffusers.EntropyBoundScheduler)) : l'échantillonneur qui valide et ré-bruitise les jetons de la toile à chaque étape de débruitage.

processor ([ProcessorMixin](https://huggingface.co/docs/transformers/v5.22.2/en/main_classes/processors#transformers.ProcessorMixin)) : le processeur utilisé pour appliquer le modèle de discussion et décoder les jetons générés.

Pipeline pour la génération de texte par diffusion en blocs de DiffusionGemma.

DiffusionGemma est un modèle encodeur-décodeur à diffusion par blocs : un encodeur causal lit le prompt propre (ainsi que les blocs générés précédemment) dans un cache KV, et un décodeur bidirectionnel débruite une « toile » de taille fixe de `canvas_length` jetons en effectuant une attention croisée avec ce cache. La génération alterne une boucle externe autorégressive sur les toiles et une boucle interne de débruitage, où chaque étape échantillonne des jetons candidats, valide les plus confiants via [BlockRefinementScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/block_refinement#diffusers.BlockRefinementScheduler) (mode de corruption uniforme, `mask_token_id=None`) et réintroduit du bruit sur le reste.

Le modèle est censé être une instance de `DiffusionGemmaForBlockDiffusion` exposant `forward(input_ids, decoder_input_ids=..., self_conditioning_logits=..., ...)` et renvoyant des logits de forme `[batch, canvas_length, vocab_size]` sur le canvas. Consultez la carte du modèle à https://huggingface.co/google/diffusiongemma-26B-A4B-it.

#### __appel__[[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)
```

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

**Paramètres :**

prompt (`str` ou `List[str]`, *facultatif*) : Texte du prompt, encapsulé dans un modèle de chat et tokenisé par le processeur. Fournissez soit ceci, soit `messages`.

messages (`List[Dict]`, *facultatif*) : Une conversation de chat brute à encoder, par exemple `[{"role": "user", "content": "Hello"}]` ou une conversation multi-tours / multimodale. Utilisez ceci à la place de `prompt` pour tout ce qui dépasse un simple tour utilisateur.

image (`PIL.Image.Image` ou `List`, *facultatif*) : Image(s) à associer à `prompt` pour la génération multimodale ; le processeur les convertit en entrées d'image du modèle. Pour des mises en page plus riches, placez le contenu de l'image directement dans `messages`.

add_generation_prompt (`bool`, par défaut `True`) : Indique s'il faut ajouter le prompt de génération lors de l'application du modèle de chat.

gen_length (`int`, par défaut `256`) : Nombre de jetons à générer, arrondi au multiple supérieur de la `canvas_length` du modèle.

num_inference_steps (`int`, par défaut `48`) : Nombre d'étapes de débruitage par canevas.

temperature (`float`, par défaut `0.0`) : Température d'échantillonnage pour `DiscreteDDIMScheduler`/`BlockRefinementScheduler` (`0.0` est glouton) ; `EntropyBoundScheduler` l'ignore et recuit sa propre température. Les autres paramètres d'échantillonnage (par ex. `top_k`, `threshold`, `t_min`/`t_max`) sont la configuration du planificateur ; définissez-les sur le planificateur, par ex. `pipe.scheduler = BlockRefinementScheduler.from_config(pipe.scheduler.config, top_k=...)`.

cache_implementation (`str`, *facultatif*) : Définir sur `"static"` pour préremplir l'encodeur une fois par bloc dans un `StaticCache` persistant et exécuter le décodeur à son encontre avec des formes fixes, au lieu de réencoder la séquence complète à chaque étape. Les formes fixes permettent également de compiler le décodeur, par exemple `pipe.model.model.decoder = torch.compile(pipe.model.model.decoder, fullgraph=True)`.

eos_early_stop (`bool`, par défaut `True`) : Indique s'il faut arrêter la génération de nouveaux canevas dès que chaque séquence a émis EOS.

eos_token_id (`int`, *facultatif*) : ID du jeton EOS pour l'arrêt anticipé. Repli sur le tokenizer du processeur.

stability_threshold (`int`, par défaut `1`) : Nombre d'étapes consécutives pendant lesquelles la prédiction argmax d'un exemple doit rester inchangée pour que cet exemple soit considéré comme stable. Utilisé uniquement lorsque `confidence_threshold` est défini.

confidence_threshold (`float`, *facultatif*, valeur par défaut `0.005`) : Gèle chaque exemple une fois qu'il est stable (voir `stability_threshold`) et que l'entropie moyenne par jeton de ses logits de prédiction, façonnés par le planificateur, est inférieure à cette valeur. La boucle de débruitage du bloc se termine une fois que tous les exemples sont gelés. Accélère la génération à qualité égale ; la valeur par défaut correspond au point de contrôle publié. Définir sur `None` pour toujours exécuter les `num_inference_steps` pas.

generator (`torch.Generator`, *facultatif*) : générateur de nombres aléatoires pour l'échantillonnage.

output_type (`str`, par défaut `"text"`) : `"text"` décode les séquences en chaînes de caractères (nécessite un processeur) ; `"seq"` renvoie uniquement les identifiants de jetons.

return_dict (`bool`, par défaut `True`) : Indique s'il faut retourner un [DiffusionGemmaPipelineOutput](/docs/diffusers/v0.43.0/fr/api/pipelines/diffusion_gemma#diffusers.DiffusionGemmaPipelineOutput) plutôt qu'un tuple.

callback_on_step_end (`Callable` ou `PipelineCallback`, *facultatif*) : Callback exécuté après chaque étape de débruitage avec la signature `callback_on_step_end(self, step, timestep, callback_kwargs)`. Clés de tenseurs autorisées : `canvas`, `logits`.

callback_on_step_end_tensor_inputs (`List[str]`, *facultatif*) : Clés de tenseurs à passer au rappel.

**Retourne :** [DiffusionGemmaPipelineOutput](/docs/diffusers/v0.43.0/fr/api/pipelines/diffusion_gemma#diffusers.DiffusionGemmaPipelineOutput) ou `tuple`

Les identifiants de jetons générés (`sequences`) et, pour `output_type="text"`, les `texts` décodés.

Générer du texte avec la diffusion par blocs.

Exemples :
```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)
```

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

**Paramètres :**

sequences (`torch.LongTensor` de forme `(batch_size, gen_length)`) : Les identifiants des jetons générés (le prompt est retiré).

texts (`list[str]`, *facultatif*) : Le texte décodé, une chaîne par séquence. Défini uniquement pour `output_type="text"`.

Classe de sortie pour la génération par diffusion en blocs de DiffusionGemma.

