bep40 commited on
Commit
8601190
·
verified ·
1 Parent(s): 4da7422

Replace pipeline file with full version

Browse files
qwenimage/pipeline_qwenimage_edit_plus.py CHANGED
@@ -1,171 +1,3 @@
1
- # Copyright 2025 Qwen-Image Team and The HuggingFace Team. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- import inspect
16
- import math
17
- from typing import Any, Callable, Dict, List, Optional, Union
18
-
19
- import numpy as np
20
- import torch
21
- from transformers import Qwen2_5_VLForConditionalGeneration, Qwen2Tokenizer, Qwen2VLProcessor
22
-
23
- from diffusers.image_processor import PipelineImageInput, VaeImageProcessor
24
- from diffusers.loaders import QwenImageLoraLoaderMixin
25
- from diffusers.models import AutoencoderKLQwenImage, QwenImageTransformer2DModel
26
- from diffusers.schedulers import FlowMatchEulerDiscreteScheduler
27
- from diffusers.utils import is_torch_xla_available, logging, replace_example_docstring
28
- from diffusers.utils.torch_utils import randn_tensor
29
- from diffusers.pipelines.pipeline_utils import DiffusionPipeline
30
- from diffusers.pipelines.qwenimage.pipeline_output import QwenImagePipelineOutput
31
-
32
-
33
- if is_torch_xla_available():
34
- import torch_xla.core.xla_model as xm
35
-
36
- XLA_AVAILABLE = True
37
- else:
38
- XLA_AVAILABLE = False
39
-
40
-
41
- logger = logging.get_logger(__name__) # pylint: disable=invalid-name
42
-
43
- EXAMPLE_DOC_STRING = """
44
- Examples:
45
- ```py
46
- >>> import torch
47
- >>> from PIL import Image
48
- >>> from diffusers import QwenImageEditPlusPipeline
49
- >>> from diffusers.utils import load_image
50
-
51
- >>> pipe = QwenImageEditPlusPipeline.from_pretrained("Qwen/Qwen-Image-Edit-2509", torch_dtype=torch.bfloat16)
52
- >>> pipe.to("cuda")
53
- >>> image = load_image(
54
- ... "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/yarn-art-pikachu.png"
55
- ... ).convert("RGB")
56
- >>> prompt = (
57
- ... "Make Pikachu hold a sign that says 'Qwen Edit is awesome', yarn art style, detailed, vibrant colors"
58
- ... )
59
- >>> # Depending on the variant being used, the pipeline call will slightly vary.
60
- >>> # Refer to the pipeline documentation for more details.
61
- >>> image = pipe(image, prompt, num_inference_steps=50).images[0]
62
- >>> image.save("qwenimage_edit_plus.png")
63
- ```
64
- """
65
-
66
- CONDITION_IMAGE_SIZE = 384 * 384
67
- VAE_IMAGE_SIZE = 1024 * 1024
68
-
69
-
70
- # Copied from diffusers.pipelines.qwenimage.pipeline_qwenimage.calculate_shift
71
- def calculate_shift(
72
- image_seq_len,
73
- base_seq_len: int = 256,
74
- max_seq_len: int = 4096,
75
- base_shift: float = 0.5,
76
- max_shift: float = 1.15,
77
- ):
78
- m = (max_shift - base_shift) / (max_seq_len - base_seq_len)
79
- b = base_shift - m * base_seq_len
80
- mu = image_seq_len * m + b
81
- return mu
82
-
83
-
84
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps
85
- def retrieve_timesteps(
86
- scheduler,
87
- num_inference_steps: Optional[int] = None,
88
- device: Optional[Union[str, torch.device]] = None,
89
- timesteps: Optional[List[int]] = None,
90
- sigmas: Optional[List[float]] = None,
91
- **kwargs,
92
- ):
93
- r"""
94
- Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles
95
- custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`.
96
-
97
- Args:
98
- scheduler (`SchedulerMixin`):
99
- The scheduler to get timesteps from.
100
- num_inference_steps (`int`):
101
- The number of denoising steps used when generating samples with a pre-trained model. If used, `timesteps`
102
- must be `None`.
103
- device (`str` or `torch.device`, *optional*):
104
- The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
105
- timesteps (`List[int]`, *optional*):
106
- Custom timesteps used to override the timestep spacing strategy of the scheduler. If `timesteps` is passed,
107
- `num_inference_steps` and `sigmas` must be `None`.
108
- sigmas (`List[float]`, *optional*):
109
- Custom sigmas used to override the timestep spacing strategy of the scheduler. If `sigmas` is passed,
110
- `num_inference_steps` and `timesteps` must be `None`.
111
-
112
- Returns:
113
- `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the
114
- second element is the number of inference steps.
115
- """
116
- if timesteps is not None and sigmas is not None:
117
- raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values")
118
- if timesteps is not None:
119
- accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
120
- if not accepts_timesteps:
121
- raise ValueError(
122
- f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
123
- f" timestep schedules. Please check whether you are using the correct scheduler."
124
- )
125
- scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
126
- timesteps = scheduler.timesteps
127
- num_inference_steps = len(timesteps)
128
- elif sigmas is not None:
129
- accept_sigmas = "sigmas" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
130
- if not accept_sigmas:
131
- raise ValueError(
132
- f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
133
- f" sigmas schedules. Please check whether you are using the correct scheduler."
134
- )
135
- scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs)
136
- timesteps = scheduler.timesteps
137
- num_inference_steps = len(timesteps)
138
- else:
139
- scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
140
- timesteps = scheduler.timesteps
141
- return timesteps, num_inference_steps
142
-
143
-
144
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stablediffusion_img2img.retrieve_latents
145
- def retrieve_latents(
146
- encoder_output: torch.Tensor, generator: Optional[torch.Generator] = None, sample_mode: str = "sample"
147
- ):
148
- if hasattr(encoder_output, "latent_dist") and sample_mode == "sample":
149
- return encoder_output.latent_dist.sample(generator)
150
- elif hasattr(encoder_output, "latent_dist") and sample_mode == "argmax":
151
- return encoder_output.latent_dist.mode()
152
- elif hasattr(encoder_output, "latents"):
153
- return encoder_output.latents
154
- else:
155
- raise AttributeError("Could not access latents of provided encoder_output")
156
-
157
-
158
- def calculate_dimensions(target_area, ratio):
159
- width = math.sqrt(target_area * ratio)
160
- height = width / ratio
161
-
162
- width = round(width / 32) * 32
163
- height = round(height / 32) * 32
164
-
165
- return width, height
166
-
167
-
168
- class QwenImageEditPlusPipeline(DiffusionPipeline, QwenImageLoraLoaderMixin):
169
- r"""
170
- The Qwen-Image-Edit pipeline for image editing.
171
- """
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e4e2c398dd8af84cc8bec13c55ef11d8548dfc2632d68cc0fd9c972730b5613f
3
+ size 7249