Skip to content

Commit d958b77

Browse files
authored
feat: support 🔥Qwen-Image-Layered (#615)
* feat: support Qwen-Image-Layered * feat: support Qwen-Image-Layered * feat: support Qwen-Image-Layered * feat: support Qwen-Image-Layered * feat: support Qwen-Image-Layered * feat: support Qwen-Image-Layered
1 parent 442ac7c commit d958b77

File tree

6 files changed

+53
-4
lines changed

6 files changed

+53
-4
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ You can install the stable release of cache-dit from PyPI, or the latest develop
8080
8181
<div align="center">
8282

83-
| 📚Supported DiTs: `🤗60+` | Cache | C-P | T-P | TE-P | CN-P | VAE-P |
83+
| 📚Supported DiTs: `🤗65+` | Cache | C-P | T-P | TE-P | CN-P | VAE-P |
8484
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
85+
| Qwen-Image-Layered ||||| ✖️ | ✖️ |
8586
| Qwen-Image-Edit-2511-Lightning ||||| ✖️ | ✖️ |
8687
| Qwen-Image-Edit-2511 ||||| ✖️ | ✖️ |
8788
| LongCat-Image ||||| ✖️ | ✖️ |

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ python3 generate.py list # list all available examples
4949
[generate.py:53] - ✅ qwen_image_edit_lightning - Defalut: lightx2v/Qwen-Image-Lightning
5050
[generate.py:53] - ✅ qwen_image_edit - Defalut: Qwen/Qwen-Image-Edit-2509
5151
[generate.py:53] - ✅ qwen_image_controlnet - Defalut: InstantX/Qwen-Image-ControlNet-Inpainting
52+
[generate.py:53] - ✅ qwen_image_layered - Defalut: Qwen/Qwen-Image-Layered
5253
[generate.py:53] - ✅ skyreels_v2 - Defalut: Skywork/SkyReels-V2-T2V-14B-720P-Diffusers
5354
[generate.py:53] - ✅ wan2.2_t2v - Defalut: Wan-AI/Wan2.2-T2V-A14B-Diffusers
5455
[generate.py:53] - ✅ wan2.1_t2v - Defalut: Wan-AI/Wan2.1-T2V-1.3B-Diffusers

examples/base.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ class ExampleInputData:
6464
control_image: Optional[Union[List[Image.Image], Image.Image]] = None
6565
control_mask: Optional[Union[List[Image.Image], Image.Image]] = None
6666
controlnet_conditioning_scale: Optional[float] = None
67+
# Specific inputs for Qwen Image Layered
68+
layers: Optional[int] = None
69+
resolution: Optional[int] = None
70+
cfg_normalize: Optional[bool] = None
71+
use_en_prompt: Optional[bool] = None
6772
# Other inputs
6873
seed: Optional[int] = None
6974
generator: torch.Generator = torch.Generator("cpu").manual_seed(0)
@@ -203,7 +208,9 @@ class ExampleOutputData:
203208
model_tag: Optional[str] = None
204209
strify_tag: Optional[str] = None
205210
# Generated image or video
206-
image: Optional[Image.Image] = None # Single PIL Images
211+
image: Optional[Image.Image | List[Image.Image]] = (
212+
None # Single PIL Images or list of PIL Images
213+
)
207214
video: Optional[List[Image.Image]] = None # List of PIL Images or video frames
208215
# Performance metrics
209216
load_time: Optional[float] = None
@@ -223,8 +230,16 @@ def save(self, args: argparse.Namespace) -> None:
223230
return
224231

225232
if self.image is not None:
226-
self.image.save(save_path)
227-
logger.info(f"Image saved to {save_path}")
233+
if isinstance(self.image, Image.Image):
234+
self.image.save(save_path)
235+
logger.info(f"Image saved to {save_path}")
236+
elif isinstance(self.image, list):
237+
save_pre = ".".join(save_path.split(".")[:-1])
238+
save_ext = save_path.split(".")[-1]
239+
for i, img in enumerate(self.image):
240+
img_save_path = f"{save_pre}_{i}.{save_ext}"
241+
img.save(img_save_path)
242+
logger.info(f"Image {i} saved to {img_save_path}")
228243

229244
if self.video is not None:
230245
export_to_video(self.video, save_path, fps=8)

examples/data/yarn-art-pikachu.png

1.61 MB
Loading

examples/helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ def activate_all_examples():
44
from registers import qwen_image_example # noqa: F403, F401
55
from registers import qwen_image_controlnet_example # noqa: F403, F401
66
from registers import qwen_image_edit_example # noqa: F403, F401
7+
from registers import qwen_image_layered_example # noqa: F403, F401
78
from registers import skyreels_v2_example # noqa: F403, F401
89
from registers import wan_example # noqa: F403, F401
910
from registers import wan_i2v_example # noqa: F403, F401

examples/registers.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"qwen_image_example",
2929
"qwen_image_controlnet_example",
3030
"qwen_image_edit_example",
31+
"qwen_image_layered_example",
3132
"skyreels_v2_example",
3233
"wan_example",
3334
"wan_i2v_example",
@@ -54,6 +55,7 @@
5455
"QWEN_IMAGE_EDIT_2511_DIR": "Qwen/Qwen-Image-Edit-2511",
5556
"QWEN_IMAGE_EDIT_2511_LIGHT_DIR": "lightx2v/Qwen-Image-Edit-2511-Lightning",
5657
"QWEN_IMAGE_CONTROLNET_DIR": "InstantX/Qwen-Image-ControlNet-Inpainting",
58+
"QWEN_IMAGE_LAYERED_DIR": "Qwen/Qwen-Image-Layered",
5759
"SKYREELS_V2_DIR": "Skywork/SkyReels-V2-T2V-14B-720P-Diffusers",
5860
"WAN_DIR": "Wan2.1-T2V-1.3B-Diffusers",
5961
"WAN_2_2_DIR": "Wan-AI/Wan2.2-T2V-A14B-Diffusers",
@@ -408,6 +410,35 @@ def qwen_image_controlnet_example(args: argparse.Namespace, **kwargs) -> Example
408410
)
409411

410412

413+
@ExampleRegister.register("qwen_image_layered", default="Qwen/Qwen-Image-Layered")
414+
def qwen_image_layered_example(args: argparse.Namespace, **kwargs) -> Example:
415+
from diffusers import QwenImageLayeredPipeline
416+
417+
model_name_or_path = _path("Qwen/Qwen-Image-Layered", args=args)
418+
return Example(
419+
args=args,
420+
init_config=ExampleInitConfig(
421+
task_type=ExampleType.T2I, # Text to Image
422+
model_name_or_path=model_name_or_path,
423+
pipeline_class=QwenImageLayeredPipeline,
424+
bnb_4bit_components=["text_encoder", "transformer"],
425+
extra_optimize_kwargs={
426+
"enable_separate_cfg": False, # negative prompt is not used in example
427+
},
428+
),
429+
input_data=ExampleInputData(
430+
image=load_image("./data/yarn-art-pikachu.png").convert("RGBA"),
431+
prompt="",
432+
num_inference_steps=50,
433+
true_cfg_scale=4.0,
434+
layers=4,
435+
resolution=640,
436+
cfg_normalize=False,
437+
use_en_prompt=True,
438+
),
439+
)
440+
441+
411442
@ExampleRegister.register("skyreels_v2", default="Skywork/SkyReels-V2-T2V-14B-720P-Diffusers")
412443
def skyreels_v2_example(args: argparse.Namespace, **kwargs) -> Example:
413444
from diffusers import AutoModel, SkyReelsV2Pipeline, UniPCMultistepScheduler

0 commit comments

Comments
 (0)