# JoyAI-Image-Edit-Plus

[JoyAI-Image](https://github.com/jd-opensource/JoyAI-Image)は、画像理解、テキストからの画像生成、指示に基づく画像編集のための統合型マルチモーダル基盤モデルです。8Bのマルチモーダル大規模言語モデル（MLLM）と16Bのマルチモーダル拡散トランスフォーマー（MMDiT）を組み合わせています。

JoyAI-Image-Edit-Plus は、**複数の参照画像**とテキスト指示を受け取り、その指示に従って参照画像の要素を組み合わせることで新しい画像を生成する、マルチ画像の指示ガイド型編集モデルです。1 サンプルあたり 1〜5 枚の参照画像に対応しています。

| モデル | 説明 | ダウンロード |
|:-----:|:-----------:|:--------:|
| JoyAI-Image-Edit-Plus | 複数の参照からの要素合成を用いた、複数画像の指示ガイド付き編集 | [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)
```

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

**パラメータ:**

scheduler ([FlowMatchEulerDiscreteScheduler](/docs/diffusers/v0.43.0/ja/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)) : `transformer` と組み合わせて、エンコードされた画像の潜在変数をデノイズするために使用するスケジューラー。

vae ([AutoencoderKLWan](/docs/diffusers/v0.43.0/ja/api/models/autoencoder_kl_wan#diffusers.AutoencoderKLWan)) : 画像を潜在表現にエンコードし、潜在表現からデコードするための変分オートエンコーダ（VAE）モデル。

text_encoder (`Qwen3VLForConditionalGeneration`) : インライン画像理解を伴うプロンプトエンコーディング用のマルチモーダルテキストエンコーダー。

tokenizer (`Qwen2Tokenizer`) : テキスト処理用のトークナイザー。

transformer ([JoyImageEditPlusTransformer3DModel](/docs/diffusers/v0.43.0/ja/api/models/transformer_joyimage_edit_plus#diffusers.JoyImageEditPlusTransformer3DModel)) : エンコードされた画像潜在変数をデノイズするための条件付き Transformer (MMDiT) アーキテクチャ。

processor (`Qwen3VLProcessor`) : マルチモーダル入力（テキスト + 画像）用のプロセッサ。

text_token_max_length (`int`、デフォルトは`2048`) : テキストエンコードにおける最大トークン長。

JoyImage Edit Plus を使用した、複数画像の指示ガイド付き編集のための Diffusion パイプライン。

異なる解像度を有する複数の参照画像をサポートします。各参照画像は独立してVAEエンコードおよびパッチ化され、その後、ターゲットノイズパッチと連結されて共同デノイジングが行われます。

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

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

**パラメータ:**

images (`list[Image.Image]` または `list[list[Image.Image]]`、*任意*) : 編集用の参照画像。各画像の解像度は異なっていても構いません。フラットなリストが指定された場合、複数の参照を持つ1つのサンプルとして扱われます。

prompt (`str` または `list[str]`、*省略可*) : 画像生成をガイドするためのプロンプトです。未定義の場合、代わりに `prompt_embeds` を渡す必要があります。

height (`int`, *任意*) : 生成される画像のピクセル単位の縦幅。`None`の場合、最後の参照画像から決定されます。

width (`int`, *optional*) : 生成される画像の幅（ピクセル単位）。`None` の場合、最後の参照画像から決定されます。

num_inference_steps (`int`、*任意*、デフォルトは`30`) : デノイジングのステップ数です。デノイジングのステップ数を増やすと、推論速度が遅くなる代わりに、通常はより高品質な画像が得られます。

timesteps (`list[int]`, *任意*) : 去噪プロセスで使用するためのカスタムタイムステップ。未定義の場合、等間隔が使用されます。

sigmas (`list[float]`, *任意*) : 去噪プロセスに使用するカスタムシグマ。

guidance_scale (`float`、*任意*、デフォルトは `4.0`) : Classifier-free guidance のスケールです。値を大きくすると、`prompt` に沿った画像を生成する傾向が強まりますが、画像の品質が低下する可能性があります。

negative_prompt (`str` または `list[str]`、*省略可*) : 画像生成をガイドしないプロンプトです。定義されていない場合、classifier-free guidance に空のプロンプトが使用されます。

generator (`torch.Generator` または `list[torch.Generator]`、*任意*) : 生成を決定論的にするための [torch ジェネレーター](https://pytorch.org/docs/stable/generated/torch.Generator.html) 1 つまたはそのリスト。

latents (`torch.Tensor`, *任意*) : 画像生成の入力として使用する、事前生成されたノイズ付き潜在変数。

prompt_embeds (`torch.Tensor`, *任意*) : 事前に生成されたテキスト埋め込み。テキスト入力の調整を簡単に実行できます。

prompt_embeds_mask (`torch.Tensor`, *任意*) : 事前に生成されたテキスト埋め込み用のアテンションマスク。

negative_prompt_embeds (`torch.Tensor`, *任意*) : 事前生成されたネガティブテキスト埋め込み。

negative_prompt_embeds_mask (`torch.Tensor`, *任意*) : 事前生成されたネガティブテキスト埋め込み用のアテンションマスク。

output_type (`str`、*任意*、デフォルトは`"pil"`) : 生成画像の出力形式。`"pil"` (`PIL.Image.Image`)、`"np"` (`np.ndarray`)、`"pt"` (`torch.Tensor`)、または生の潜在出力の`"latent"`から選択します。

return_dict (`bool`、*任意*、デフォルトは `True`) : プレーンなタプルではなく [JoyImageEditPlusPipelineOutput](/docs/diffusers/v0.43.0/ja/api/pipelines/joyimage_edit_plus#diffusers.JoyImageEditPlusPipelineOutput) を返すかどうか。

callback_on_step_end (`Callable`、*任意*) : 各デノイジングステップの終了時に呼び出される関数です。引数として、パイプライン、ステップインデックス、タイムステップ、およびコールバックのテンソル入力を含む辞書を受け取ります。

callback_on_step_end_tensor_inputs (`list[str]`、*任意*、デフォルトは`["latents"]`) : `callback_on_step_end`関数へのテンソル入力のリスト。

max_sequence_length (`int`、*任意*、デフォルトは`4096`) : テキストエンコーダーの最大シーケンス長。

**戻り値:** [JoyImageEditPlusPipelineOutput](/docs/diffusers/v0.43.0/ja/api/pipelines/joyimage_edit_plus#diffusers.JoyImageEditPlusPipelineOutput) または `tuple`

`return_dict` が `True` の場合、[JoyImageEditPlusPipelineOutput](/docs/diffusers/v0.43.0/ja/api/pipelines/joyimage_edit_plus#diffusers.JoyImageEditPlusPipelineOutput) が返され、それ以外の場合は、最初の要素が生成された画像のリストである `tuple` が返されます。

生成用のパイプラインを呼び出したときに実行される関数。

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

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

Qwen3-VL プロセッサーを使用して、インラインの tokens を含むプロンプトをエンコードします。

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

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

**パラメータ:**

latents : ターゲットスロット用の事前計算済みノイズ。形状は`(B, C, 1, H', W')`で、`H'`と`W'`は潜在空間の次元です。`None`の場合、ランダムなノイズがサンプリングされます。

**戻り値:** `padded_latents`

[B, max_patches, C, pt, ph, pw] target_mask: [B, max_patches] (ターゲットパッチが True) shape_list: 各コンポーネントの (t, h, w) タプルのサンプルごとのリスト

ターゲットノイズと参照画像の潜在変数を含む、6次元のパディング済み潜在テンソルを準備します。

## JoyImageEditPlusPipelineOutput[[diffusers.JoyImageEditPlusPipelineOutput]]

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

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

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

JoyImage Edit Plus マルチ画像編集パイプライン用の出力クラスです。

