# JoyAI-Image-Edit-Plus

[JoyAI-Image](https://github.com/jd-opensource/JoyAI-Image) est un modèle de fondation multimodal unifié pour la compréhension d'images, la génération d'images à partir de texte et l'édition d'images guidée par des instructions. Il combine un grand modèle de langage multimodal (MLLM) de 8B avec un transformeur de diffusion multimodal (MMDiT) de 16B.

JoyAI-Image-Edit-Plus est un modèle d'édition guidé par des instructions multi-images qui accepte **plusieurs images de référence** et une instruction textuelle pour générer une nouvelle image combinant des éléments des images de référence conformément à l'instruction. Il prend en charge de 1 à 5 images de référence par échantillon.

| Modèle | Description | Télécharger |
|:-----:|:-----------:|:--------:|
| JoyAI-Image-Edit-Plus | Édition guidée par des instructions sur plusieurs images avec composition d'éléments à partir de plusieurs références | [Hugging Face](https://huggingface.co/jdopensource/JoyAI-Image-Edit-Plus-Diffusers) |

```python
import torch
from PIL import Image
from diffusers import JoyImageEditPlusPipeline

pipeline = JoyImageEditPlusPipeline.from_pretrained(
    "jdopensource/JoyAI-Image-Edit-Plus-Diffusers", dtype=torch.bfloat16
)
pipeline.to("cuda")  # or "mps", "xpu", "cpu"

images = [
    Image.open("reference_0.png").convert("RGB"),
    Image.open("reference_1.png").convert("RGB"),
]

target_h, target_w = pipeline.image_processor.get_default_height_width(images[-1])

output = pipeline(
    images=images,
    prompt="Combine the person from the second image with the scene from the first image.",
    negative_prompt="low quality, blurry, deformed",
    height=target_h,
    width=target_w,
    num_inference_steps=30,
    guidance_scale=4.0,
    generator=torch.Generator("cuda").manual_seed(42),
).images[0]
output.save("joyimage_edit_plus_output.png")
```

## JoyImageEditPlusPipeline[[diffusers.JoyImageEditPlusPipeline]]

#### diffusers.JoyImageEditPlusPipeline[[diffusers.JoyImageEditPlusPipeline]]

```python
diffusers.JoyImageEditPlusPipeline(scheduler: FlowMatchEulerDiscreteScheduler, vae: AutoencoderKLWan, text_encoder: Qwen3VLForConditionalGeneration, tokenizer: Qwen2Tokenizer, transformer: JoyImageEditPlusTransformer3DModel, processor: Qwen3VLProcessor, text_token_max_length: int = 2048)
```

[Source](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L129)

**Paramètres :**

scheduler ([FlowMatchEulerDiscreteScheduler](/docs/diffusers/v0.43.0/fr/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)) : un planificateur à utiliser en combinaison avec `transformer` pour débruyer les latents d'image encodés.

vae ([AutoencoderKLWan](/docs/diffusers/v0.43.0/fr/api/models/autoencoder_kl_wan#diffusers.AutoencoderKLWan)) : modèle de Variational Auto-Encoder (VAE) permettant d’encoder et de décoder des images vers et depuis des représentations latentes.

text_encoder (`Qwen3VLForConditionalGeneration`) : encodeur de texte multimodal pour l'encodage des prompts avec compréhension d'images intégrées.

tokenizer (`Qwen2Tokenizer`) : Tokenizer pour le traitement du texte.

transformer ([JoyImageEditPlusTransformer3DModel](/docs/diffusers/v0.43.0/fr/api/models/transformer_joyimage_edit_plus#diffusers.JoyImageEditPlusTransformer3DModel)) : architecture Transformer conditionnelle (MMDiT) pour le débruitage des latents d'image encodés.

processor (`Qwen3VLProcessor`) : Processeur pour les entrées multimodales (texte + images).

text_token_max_length (`int`, par défaut `2048`) : Longueur maximale des jetons pour l'encodage du texte.

Pipeline de diffusion pour l'édition guidée par des instructions sur plusieurs images à l'aide de JoyImage Edit Plus.

Prend en charge plusieurs images de référence avec des résolutions différentes. Chaque image de référence est encodée de manière indépendante par le VAE et patchifiée, puis concaténée avec les patches de bruit de la cible pour un débruitage conjoint.

#### __appel__[[diffusers.JoyImageEditPlusPipeline.__call__]]

```python
__call__(images: list[PIL.Image.Image] | list[list[PIL.Image.Image]] | None = None, prompt: str | list[str] = None, height: int | None = None, width: int | None = None, num_inference_steps: int = 30, timesteps: list[int] = None, sigmas: list[float] = None, guidance_scale: float = 4.0, negative_prompt: str | list[str] | None = None, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, prompt_embeds: typing.Optional[torch.Tensor] = None, prompt_embeds_mask: typing.Optional[torch.Tensor] = None, negative_prompt_embeds: typing.Optional[torch.Tensor] = None, negative_prompt_embeds_mask: typing.Optional[torch.Tensor] = None, output_type: str | None = 'pil', return_dict: bool = True, callback_on_step_end: typing.Union[typing.Callable[[int, int, dict], NoneType], diffusers.callbacks.PipelineCallback, diffusers.callbacks.MultiPipelineCallbacks, NoneType] = None, callback_on_step_end_tensor_inputs: list[str] = ['latents'], max_sequence_length: int = 4096)
```

[Source](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L441)

**Paramètres :**

images (`list[Image.Image]` ou `list[list[Image.Image]]`, *facultatif*) : Images de référence pour l'édition. Chaque image peut avoir une résolution différente. Si une liste plate est fournie, elle est traitée comme un seul échantillon avec plusieurs références.

prompt (`str` ou `list[str]`, *facultatif*) : Le prompt ou les prompts pour guider la génération d’image. S’il n’est pas défini, il faut passer `prompt_embeds` à la place.

height (`int`, *facultatif*) : La hauteur en pixels de l'image générée. Si `None`, elle est déterminée à partir de la dernière image de référence.

width (`int`, *facultatif*) : La largeur en pixels de l'image générée. Si `None`, elle est déterminée à partir de la dernière image de référence.

num_inference_steps (`int`, *facultatif*, valeur par défaut `30`) : Le nombre d'étapes de débruitage. Un plus grand nombre d'étapes de débruitage conduit généralement à une image de meilleure qualité, au prix d'une inférence plus lente.

timesteps (`list[int]`, *facultatif*) : Étapes de temps personnalisées à utiliser pour le processus de débruitage. Si non définies, un espacement égal est utilisé.

sigmas (`list[float]`, *facultatif*) : Sigmas personnalisés à utiliser pour le processus de débruitage.

guidance_scale (`float`, *facultatif*, valeur par défaut `4.0`) : Échelle de guidage sans classifieur. Des valeurs plus élevées encouragent le modèle à générer des images plus alignées avec le `prompt` au détriment de la qualité de l'image.

negative_prompt (`str` ou `list[str]`, *facultatif*) : Le prompt ou les prompts à ne pas utiliser pour guider la génération d’image. S’il n’est pas défini, un prompt vide est utilisé pour le guidage sans classifieur.

generator (`torch.Generator` ou `list[torch.Generator]`, *facultatif*) : Un ou une liste de [générateurs torch](https://pytorch.org/docs/stable/generated/torch.Generator.html) pour rendre la génération déterministe.

latents (`torch.Tensor`, *facultatif*) : Latents bruités pré-générés à utiliser comme entrées pour la génération d'images.

prompt_embeds (`torch.Tensor`, *facultatif*) : Incrustations de texte pré-générées. Peut être utilisé pour ajuster facilement les entrées de texte.

prompt_embeds_mask (`torch.Tensor`, *facultatif*) : Masque d'attention pour les embeddings de texte pré-générés.

negative_prompt_embeds (`torch.Tensor`, *facultatif*) : Incrustations de texte négatif pré-générées.

negative_prompt_embeds_mask (`torch.Tensor`, *facultatif*) : Masque d'attention pour les embeddings de texte négatif pré-générés.

output_type (`str`, *facultatif*, par défaut `"pil"`) : Le format de sortie de l'image générée. Choisissez entre `"pil"` (`PIL.Image.Image`), `"np"` (`np.ndarray`), `"pt"` (`torch.Tensor`) ou `"latent"` pour une sortie latente brute.

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

callback_on_step_end (`Callable`, *facultatif*) : une fonction appelée à la fin de chaque étape de débruitage avec les arguments suivants : le pipeline, l'indice de l'étape, le timestep et un dictionnaire des entrées tensorielles du callback.

callback_on_step_end_tensor_inputs (`list[str]`, *facultatif*, par défaut `["latents"]`) : La liste des entrées de tenseurs pour la fonction `callback_on_step_end`.

max_sequence_length (`int`, *facultatif*, par défaut `4096`) : Longueur de séquence maximale pour l'encodeur de texte.

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

Si `return_dict` est `True`, [JoyImageEditPlusPipelineOutput](/docs/diffusers/v0.43.0/fr/api/pipelines/joyimage_edit_plus#diffusers.JoyImageEditPlusPipelineOutput) est retourné, sinon un `tuple` est retourné dont le premier élément est une liste d’images générées.

Fonction appelée lors de l'appel du pipeline pour la génération.

Exemples :
```python
>>> import torch
>>> from diffusers import JoyImageEditPlusPipeline
>>> from diffusers.utils import load_image

>>> model_id = "jdopensource/JoyAI-Image-Edit-Plus-Diffusers"
>>> pipe = JoyImageEditPlusPipeline.from_pretrained(model_id, torch_dtype=torch.bfloat16)
>>> pipe.to("cuda")

>>> images = [
...     load_image("dog.png"),
...     load_image("person.png"),
... ]
>>> output = pipe(
...     images=images,
...     prompt="Let the person lovingly play with the dog.",
...     height=1024,
...     width=1024,
...     num_inference_steps=30,
...     guidance_scale=4.0,
...     generator=torch.manual_seed(42),
... )
>>> output.images[0].save("output.png")
```

#### encode_prompt_multiple_images[[diffusers.JoyImageEditPlusPipeline.encode_prompt_multiple_images]]

```python
encode_prompt_multiple_images(prompt: str | list[str], device: typing.Optional[torch.device] = None, images: list[PIL.Image.Image] | None = None, max_sequence_length: int | None = None)
```

[Source](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L229)

Encodez les prompts avec des jetons en ligne via le processeur Qwen3-VL.

#### prepare_latents[[diffusers.JoyImageEditPlusPipeline.prepare_latents]]

```python
prepare_latents(batch_size: int, num_channels_latents: int, height: int, width: int, dtype: dtype, device: device, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType], reference_images: list[list[PIL.Image.Image]] | None = None, latents: typing.Optional[torch.Tensor] = None)
```

[Source](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L274)

**Paramètres :**

latents : Bruit précalculé facultatif pour le slot cible. Forme `(B, C, 1, H', W')` où `H'` et `W'` sont les dimensions de l'espace latent. Si `None`, un bruit aléatoire est échantillonné.

**Retourne :** `padded_latents`

[B, max_patches, C, pt, ph, pw] target_mask : [B, max_patches] (True pour les patches cibles) shape_list : liste par échantillon de tuples (t, h, w) pour chaque composant

Préparez un tenseur latent 6D avec bourrage, contenant le bruit cible et les latents de l'image de référence.

## JoyImageEditPlusPipelineOutput[[diffusers.JoyImageEditPlusPipelineOutput]]

#### diffusers.JoyImageEditPlusPipelineOutput[[diffusers.JoyImageEditPlusPipelineOutput]]

```python
diffusers.JoyImageEditPlusPipelineOutput(images: typing.Union[typing.List[PIL.Image.Image], numpy.ndarray])
```

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

Classe de sortie pour les pipelines d'édition multi-images JoyImage Edit Plus.

