# JoyAI-Image-Edit-Plus

[JoyAI-Image](https://github.com/jd-opensource/JoyAI-Image) là một mô hình nền tảng đa phương thức thống nhất cho việc hiểu hình ảnh, tạo hình ảnh từ văn bản và chỉnh sửa hình ảnh theo hướng dẫn. Nó kết hợp một Mô hình Ngôn ngữ Lớn Đa phương thức (MLLM) 8B với một Transformer Khuếch tán Đa phương thức (MMDiT) 16B.

JoyAI-Image-Edit-Plus là một mô hình chỉnh sửa hình ảnh theo hướng dẫn bằng văn bản, nhận **nhiều hình ảnh tham chiếu** và một hướng dẫn văn bản để tạo ra một hình ảnh mới kết hợp các yếu tố từ các hình tham chiếu theo hướng dẫn. Nó hỗ trợ từ 1 đến 5 hình ảnh tham chiếu cho mỗi mẫu.

| Mô hình | Mô tả | Tải xuống |
|:-----:|:-----------:|:--------:|
| JoyAI-Image-Edit-Plus | Chỉnh sửa theo hướng dẫn chỉ thị cho nhiều hình ảnh với việc kết hợp các yếu tố từ nhiều tham chiếu | [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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L129)

**Tham số:**

scheduler ([FlowMatchEulerDiscreteScheduler](/docs/diffusers/main/vi/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)) : Một trình lập lịch được sử dụng kết hợp với `transformer` để khử nhiễu các latent ảnh đã mã hóa.

vae ([AutoencoderKLWan](/docs/diffusers/main/vi/api/models/autoencoder_kl_wan#diffusers.AutoencoderKLWan)) : Mô hình Variational Auto-Encoder (VAE) để mã hóa và giải mã hình ảnh sang và từ các biểu diễn ẩn.

text_encoder (`Qwen3VLForConditionalGeneration`) : Bộ mã hóa văn bản đa phương thức để mã hóa prompt với khả năng hiểu hình ảnh inline.

tokenizer (`Qwen2Tokenizer`) : Tokenizer để xử lý văn bản.

transformer ([JoyImageEditPlusTransformer3DModel](/docs/diffusers/main/vi/api/models/transformer_joyimage_edit_plus#diffusers.JoyImageEditPlusTransformer3DModel)) : Kiến trúc Conditional Transformer (MMDiT) để khử nhiễu các latents ảnh đã mã hóa.

processor (`Qwen3VLProcessor`) : Bộ xử lý cho đầu vào đa phương thức (văn bản + hình ảnh).

text_token_max_length (`int`, mặc định là `2048`) : Độ dài token tối đa cho việc mã hóa văn bản.

Pipeline khuếch tán cho chỉnh sửa theo hướng dẫn chỉ thị trên nhiều hình ảnh sử dụng JoyImage Edit Plus.

Hỗ trợ nhiều hình ảnh tham chiếu với độ phân giải khác nhau. Mỗi hình ảnh tham chiếu được mã hóa VAE và chia thành các khối (patch) một cách độc lập, sau đó được nối với các khối nhiễu của hình ảnh đích để khử nhiễu chung.

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

[Nguồn](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L441)

**Tham số:**

images (`list[Image.Image]` hoặc `list[list[Image.Image]]`, *tùy chọn*) : Các hình ảnh tham chiếu để chỉnh sửa. Mỗi hình ảnh có thể có độ phân giải khác nhau. Nếu danh sách phẳng được cung cấp, nó được coi là một mẫu với nhiều tham chiếu.

prompt (`str` hoặc `list[str]`, *tùy chọn*) : Prompt hoặc các prompt để hướng dẫn việc tạo ảnh. Nếu không được định nghĩa, bạn phải truyền `prompt_embeds` thay thế.

height (`int`, *optional*) : Chiều cao của hình ảnh được tạo ra, tính bằng pixel. Nếu là `None`, giá trị này sẽ được xác định từ hình ảnh tham chiếu cuối cùng.

width (`int`, *optional*) : Độ rộng của hình ảnh được tạo ra, tính bằng pixel. Nếu là `None`, giá trị này sẽ được xác định từ hình ảnh tham chiếu cuối cùng.

num_inference_steps (`int`, *tuỳ chọn*, mặc định là `30`) : Số bước khử nhiễu. Số bước khử nhiễu nhiều hơn thường dẫn đến hình ảnh có chất lượng cao hơn, đổi lại là suy luận chậm hơn.

timesteps (`list[int]`, *optional*) : Các bước thời gian tùy chỉnh để sử dụng cho quá trình khử nhiễu. Nếu không được định nghĩa, khoảng cách đều sẽ được sử dụng.

sigmas (`list[float]`, *tùy chọn*) : Các sigma tùy chỉnh để sử dụng cho quá trình khử nhiễu.

guidance_scale (`float`, *optional*, mặc định là `4.0`) : Thang độ hướng dẫn không có điều kiện (classifier-free guidance). Các giá trị cao hơn khuyến khích mô hình tạo ra hình ảnh phù hợp hơn với `prompt` nhưng làm giảm chất lượng hình ảnh.

negative_prompt (`str` hoặc `list[str]`, *tùy chọn*) : Prompt hoặc các prompt không được dùng để hướng dẫn tạo ảnh. Nếu không được định nghĩa, một prompt trống sẽ được sử dụng cho classifier-free guidance.

generator (`torch.Generator` hoặc `list[torch.Generator]`, *tùy chọn*) : Một hoặc một danh sách [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) để đảm bảo quá trình sinh là tất định.

latents (`torch.Tensor`, *tùy chọn*) : Các latents nhiễu đã được tạo trước để sử dụng làm đầu vào cho việc tạo ảnh.

prompt_embeds (`torch.Tensor`, *tùy chọn*) : Các vector nhúng văn bản đã được tạo trước. Có thể được sử dụng để dễ dàng điều chỉnh các đầu vào văn bản.

prompt_embeds_mask (`torch.Tensor`, *tùy chọn*) : Mặt nạ chú ý cho các nhúng văn bản được tạo trước.

negative_prompt_embeds (`torch.Tensor`, *tùy chọn*) : Các vector nhúng văn bản âm đã được tạo trước.

negative_prompt_embeds_mask (`torch.Tensor`, *tùy chọn*) : Mặt nạ chú ý cho các vector nhúng văn bản âm được tạo trước.

output_type (`str`, *tùy chọn*, mặc định là `"pil"`) : Định dạng đầu ra của hình ảnh được tạo. Chọn giữa `"pil"` (`PIL.Image.Image`), `"np"` (`np.ndarray`), `"pt"` (`torch.Tensor`), hoặc `"latent"` cho đầu ra latent thô.

return_dict (`bool`, *tùy chọn*, mặc định là `True`) : Có nên trả về một [JoyImageEditPlusPipelineOutput](/docs/diffusers/main/vi/api/pipelines/joyimage_edit_plus#diffusers.JoyImageEditPlusPipelineOutput) thay vì một tuple thông thường hay không.

callback_on_step_end (`Callable`, *tùy chọn*) : Một hàm được gọi vào cuối mỗi bước khử nhiễu với các đối số: pipeline, chỉ số bước, timestep và một dict chứa các tensor đầu vào của callback.

callback_on_step_end_tensor_inputs (`list[str]`, *tùy chọn*, mặc định là `["latents"]`) : Danh sách các đầu vào tensor cho hàm `callback_on_step_end`.

max_sequence_length (`int`, *tuỳ chọn*, mặc định là `4096`) : Độ dài tối đa của chuỗi cho trình mã hóa văn bản.

**Trả về:** [JoyImageEditPlusPipelineOutput](/docs/diffusers/main/vi/api/pipelines/joyimage_edit_plus#diffusers.JoyImageEditPlusPipelineOutput) hoặc `tuple`

Nếu `return_dict` là `True`, [JoyImageEditPlusPipelineOutput](/docs/diffusers/main/vi/api/pipelines/joyimage_edit_plus#diffusers.JoyImageEditPlusPipelineOutput) sẽ được trả về, ngược lại một `tuple` sẽ được trả về trong đó phần tử đầu tiên là một danh sách các hình ảnh đã tạo.

Hàm được gọi khi gọi pipeline cho việc sinh.

Ví dụ:
```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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L229)

Mã hóa các prompt với các token inline thông qua bộ xử lý 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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/joyimage/pipeline_joyimage_edit_plus.py#L274)

**Tham số:**

latents : Nhiễu đã tính toán trước tùy chọn cho slot đích. Hình dạng `(B, C, 1, H', W')` trong đó `H'` và `W'` là các kích thước trong không gian latent. Khi `None`, nhiễu ngẫu nhiên sẽ được lấy mẫu.

**Trả về:** `padded_latents`

[B, max_patches, C, pt, ph, pw] target_mask: [B, max_patches] (True cho các patch đích) shape_list: danh sách theo mẫu gồm các bộ ba (t, h, w) cho từng thành phần

Chuẩn bị tensor latent có đệm 6D với nhiễu mục tiêu + latents của hình ảnh tham chiếu.

## JoyImageEditPlusPipelineOutput[[diffusers.JoyImageEditPlusPipelineOutput]]

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

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

[Nguồn](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/joyimage/pipeline_output.py#L20)

Lớp đầu ra cho các pipeline chỉnh sửa đa ảnh của JoyImage Edit Plus.

