Skip to content

Commit a2b7de3

Browse files
committed
Merge branch 'main' into qwen-pipeline-mixin
2 parents 5b3295a + 1448b03 commit a2b7de3

File tree

12 files changed

+530
-270
lines changed

12 files changed

+530
-270
lines changed

docs/source/en/api/pipelines/qwenimage.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Qwen-Image comes in the following variants:
2626
|:----------:|:--------:|
2727
| Qwen-Image | [`Qwen/Qwen-Image`](https://huggingface.co/Qwen/Qwen-Image) |
2828
| Qwen-Image-Edit | [`Qwen/Qwen-Image-Edit`](https://huggingface.co/Qwen/Qwen-Image-Edit) |
29+
| Qwen-Image-Edit Plus | [Qwen/Qwen-Image-Edit-2509](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) |
2930

3031
<Tip>
3132

@@ -96,6 +97,29 @@ The `guidance_scale` parameter in the pipeline is there to support future guidan
9697

9798
</Tip>
9899

100+
## Multi-image reference with QwenImageEditPlusPipeline
101+
102+
With [`QwenImageEditPlusPipeline`], one can provide multiple images as input reference.
103+
104+
```
105+
import torch
106+
from PIL import Image
107+
from diffusers import QwenImageEditPlusPipeline
108+
from diffusers.utils import load_image
109+
110+
pipe = QwenImageEditPlusPipeline.from_pretrained(
111+
"Qwen/Qwen-Image-Edit-2509", torch_dtype=torch.bfloat16
112+
).to("cuda")
113+
114+
image_1 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/grumpy.jpg")
115+
image_2 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/peng.png")
116+
image = pipe(
117+
image=[image_1, image_2],
118+
prompt="put the penguin and the cat at a game show called "Qwen Edit Plus Games"",
119+
num_inference_steps=50
120+
).images[0]
121+
```
122+
99123
## QwenImagePipeline
100124

101125
[[autodoc]] QwenImagePipeline
@@ -126,7 +150,15 @@ The `guidance_scale` parameter in the pipeline is there to support future guidan
126150
- all
127151
- __call__
128152

129-
## QwenImaggeControlNetPipeline
153+
## QwenImageControlNetPipeline
154+
155+
[[autodoc]] QwenImageControlNetPipeline
156+
- all
157+
- __call__
158+
159+
## QwenImageEditPlusPipeline
160+
161+
[[autodoc]] QwenImageEditPlusPipeline
130162
- all
131163
- __call__
132164

src/diffusers/loaders/lora_base.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,41 @@ def save_function(weights, filename):
10641064
save_function(state_dict, save_path)
10651065
logger.info(f"Model weights saved in {save_path}")
10661066

1067+
@classmethod
1068+
def _save_lora_weights(
1069+
cls,
1070+
save_directory: Union[str, os.PathLike],
1071+
lora_layers: Dict[str, Dict[str, Union[torch.nn.Module, torch.Tensor]]],
1072+
lora_metadata: Dict[str, Optional[dict]],
1073+
is_main_process: bool = True,
1074+
weight_name: str = None,
1075+
save_function: Callable = None,
1076+
safe_serialization: bool = True,
1077+
):
1078+
"""
1079+
Helper method to pack and save LoRA weights and metadata. This method centralizes the saving logic for all
1080+
pipeline types.
1081+
"""
1082+
state_dict = {}
1083+
final_lora_adapter_metadata = {}
1084+
1085+
for prefix, layers in lora_layers.items():
1086+
state_dict.update(cls.pack_weights(layers, prefix))
1087+
1088+
for prefix, metadata in lora_metadata.items():
1089+
if metadata:
1090+
final_lora_adapter_metadata.update(_pack_dict_with_prefix(metadata, prefix))
1091+
1092+
cls.write_lora_layers(
1093+
state_dict=state_dict,
1094+
save_directory=save_directory,
1095+
is_main_process=is_main_process,
1096+
weight_name=weight_name,
1097+
save_function=save_function,
1098+
safe_serialization=safe_serialization,
1099+
lora_adapter_metadata=final_lora_adapter_metadata if final_lora_adapter_metadata else None,
1100+
)
1101+
10671102
@classmethod
10681103
def _optionally_disable_offloading(cls, _pipeline):
10691104
return _func_optionally_disable_offloading(_pipeline=_pipeline)

0 commit comments

Comments
 (0)