prithivMLmods commited on
Commit
3bf0e48
·
verified ·
1 Parent(s): fbd8b21
Files changed (1) hide show
  1. app.py +58 -70
app.py CHANGED
@@ -7,6 +7,7 @@ import random
7
  from PIL import Image
8
  from typing import Iterable
9
 
 
10
  from gradio.themes import Soft
11
  from gradio.themes.utils import colors, fonts, sizes
12
 
@@ -57,29 +58,18 @@ class SteelBlueTheme(Soft):
57
  button_primary_text_color_hover="white",
58
  button_primary_background_fill="linear-gradient(90deg, *secondary_500, *secondary_600)",
59
  button_primary_background_fill_hover="linear-gradient(90deg, *secondary_600, *secondary_700)",
60
- button_primary_background_fill_dark="linear-gradient(90deg, *secondary_600, *secondary_800)",
61
- button_primary_background_fill_hover_dark="linear-gradient(90deg, *secondary_500, *secondary_500)",
62
- button_secondary_text_color="black",
63
- button_secondary_text_color_hover="white",
64
- button_secondary_background_fill="linear-gradient(90deg, *primary_300, *primary_300)",
65
- button_secondary_background_fill_hover="linear-gradient(90deg, *primary_400, *primary_400)",
66
- button_secondary_background_fill_dark="linear-gradient(90deg, *primary_500, *primary_600)",
67
- button_secondary_background_fill_hover_dark="linear-gradient(90deg, *primary_500, *primary_500)",
68
  slider_color="*secondary_500",
69
  slider_color_dark="*secondary_600",
70
  block_title_text_weight="600",
71
  block_border_width="3px",
72
  block_shadow="*shadow_drop_lg",
73
- button_primary_shadow="*shadow_drop_lg",
74
- button_large_padding="11px",
75
- color_accent_soft="*primary_100",
76
- block_label_background_fill="*primary_200",
77
  )
78
 
79
  steel_blue_theme = SteelBlueTheme()
80
 
 
81
  from diffusers import FlowMatchEulerDiscreteScheduler
82
- from optimization import optimize_pipeline_
83
  from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
84
  from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel
85
  from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
@@ -112,14 +102,30 @@ pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Relight",
112
  weight_name="Qwen-Edit-Relight.safetensors",
113
  adapter_name="relight")
114
 
115
-
116
- pipe.transformer.__class__ = QwenImageTransformer2DModel
117
  pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
118
-
119
- optimize_pipeline_(pipe, image=[Image.new("RGB", (1024, 1024)), Image.new("RGB", (1024, 1024))], prompt="prompt")
120
-
121
  MAX_SEED = np.iinfo(np.int32).max
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  # --- Main Inference Function ---
124
  @spaces.GPU
125
  def infer(
@@ -152,13 +158,12 @@ def infer(
152
 
153
  generator = torch.Generator(device=device).manual_seed(seed)
154
 
155
- # *** FIX: Added a negative prompt to enable classifier-free guidance ***
156
  negative_prompt = "worst quality, low quality, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, jpeg artifacts, signature, watermark, username, blurry"
157
 
158
  result = pipe(
159
  image=input_image.convert("RGB"),
160
  prompt=prompt,
161
- negative_prompt=negative_prompt, # This line enables CFG
162
  height=height,
163
  width=width,
164
  num_inference_steps=steps,
@@ -167,39 +172,22 @@ def infer(
167
  num_images_per_prompt=1,
168
  ).images[0]
169
 
170
- return result, seed, gr.Button(visible=True)
 
171
 
172
- # --- Helper Functions ---
173
- def update_dimensions_on_upload(image):
174
- if image is None:
175
- return 1024, 1024
176
-
177
- original_width, original_height = image.size
178
-
179
- # Cap max dimension to 1024 while preserving aspect ratio
180
- if original_width > original_height:
181
- new_width = 1024
182
- aspect_ratio = original_height / original_width
183
- new_height = int(new_width * aspect_ratio)
184
- else:
185
- new_height = 1024
186
- aspect_ratio = original_width / original_height
187
- new_width = int(new_height * aspect_ratio)
188
-
189
- # Ensure dimensions are multiples of 8 for model compatibility
190
- new_width = (new_width // 8) * 8
191
- new_height = (new_height // 8) * 8
192
-
193
- return new_width, new_height
194
-
195
- # Wrapper for examples to handle file paths
196
- #@spaces.GPU
197
- #def infer_example(input_image_path, prompt, lora_adapter):
198
- #input_pil = Image.open(input_image_path).convert("RGB")
199
- #width, height = update_dimensions_on_upload(input_pil)
200
- # Set default values for example inference
201
- #result, seed, _ = infer(input_pil, prompt, lora_adapter, 0, True, 1.0, 4, width, height)
202
- #return result, seed
203
 
204
  # --- UI Layout ---
205
  css="""
@@ -215,10 +203,16 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
215
  gr.Markdown("# **Qwen-Image-Edit-2509-LoRAs-Fast**", elem_id="main-title")
216
  gr.Markdown("Perform diverse image edits using specialized LoRA adapters for the Qwen-Image-Edit model.")
217
 
218
- with gr.Row():
219
  with gr.Column():
220
- input_image = gr.Image(label="Upload Image", type="pil")
221
-
 
 
 
 
 
 
222
  prompt = gr.Text(
223
  label="Edit Prompt",
224
  show_label=True,
@@ -227,25 +221,18 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
227
 
228
  run_button = gr.Button("Run", variant="primary")
229
 
230
- with gr.Column():
231
- output_image = gr.Image(label="Output Image", interactive=False, format="png", height=290)
232
-
233
- with gr.Row():
234
- lora_adapter = gr.Dropdown(
235
- label="Choose Editing Style",
236
- choices=["Photo-to-Anime", "Multiple-Angles", "Light-Restoration", "Relight"],
237
- value="Photo-to-Anime"
238
- )
239
-
240
  with gr.Accordion("⚙️ Advanced Settings", open=False):
241
  seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
242
  randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
243
- guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=1.0)
244
- steps = gr.Slider(label="Inference Steps", minimum=1, maximum=50, step=1, value=4)
245
  # Hidden sliders to hold image dimensions
246
  height = gr.Slider(label="Height", minimum=256, maximum=1024, step=8, value=1024, visible=False)
247
  width = gr.Slider(label="Width", minimum=256, maximum=1024, step=8, value=1024, visible=False)
248
 
 
 
 
249
  gr.Examples(
250
  examples=[
251
  ["examples/1.jpg", "Transform into anime.", "Photo-to-Anime"],
@@ -262,11 +249,12 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
262
  ],
263
  inputs=[input_image, prompt, lora_adapter],
264
  outputs=[output_image, seed],
265
- #fn=infer_example,
266
- cache_examples=False,
267
  label="Examples"
268
  )
269
 
 
270
  run_button.click(
271
  fn=infer,
272
  inputs=[input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps, width, height],
@@ -279,4 +267,4 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
279
  outputs=[width, height]
280
  )
281
 
282
- demo.launch(ssr_mode=False)
 
7
  from PIL import Image
8
  from typing import Iterable
9
 
10
+ # --- Gradio Theme ---
11
  from gradio.themes import Soft
12
  from gradio.themes.utils import colors, fonts, sizes
13
 
 
58
  button_primary_text_color_hover="white",
59
  button_primary_background_fill="linear-gradient(90deg, *secondary_500, *secondary_600)",
60
  button_primary_background_fill_hover="linear-gradient(90deg, *secondary_600, *secondary_700)",
 
 
 
 
 
 
 
 
61
  slider_color="*secondary_500",
62
  slider_color_dark="*secondary_600",
63
  block_title_text_weight="600",
64
  block_border_width="3px",
65
  block_shadow="*shadow_drop_lg",
 
 
 
 
66
  )
67
 
68
  steel_blue_theme = SteelBlueTheme()
69
 
70
+ # --- Model Loading ---
71
  from diffusers import FlowMatchEulerDiscreteScheduler
72
+ # from optimization import optimize_pipeline_ # Assuming this is a custom file
73
  from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
74
  from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel
75
  from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
 
102
  weight_name="Qwen-Edit-Relight.safetensors",
103
  adapter_name="relight")
104
 
 
 
105
  pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
 
 
 
106
  MAX_SEED = np.iinfo(np.int32).max
107
 
108
+ # --- Helper Function for Aspect Ratio ---
109
+ def update_dimensions_on_upload(image):
110
+ if image is None:
111
+ return 1024, 1024
112
+
113
+ original_width, original_height = image.size
114
+
115
+ # Cap max dimension to 1024 while preserving aspect ratio
116
+ if original_width > original_height:
117
+ new_width = 1024
118
+ new_height = int(1024 * original_height / original_width)
119
+ else:
120
+ new_height = 1024
121
+ new_width = int(1024 * original_width / original_height)
122
+
123
+ # Ensure dimensions are multiples of 8 for model compatibility
124
+ new_width = (new_width // 8) * 8
125
+ new_height = (new_height // 8) * 8
126
+
127
+ return new_width, new_height
128
+
129
  # --- Main Inference Function ---
130
  @spaces.GPU
131
  def infer(
 
158
 
159
  generator = torch.Generator(device=device).manual_seed(seed)
160
 
 
161
  negative_prompt = "worst quality, low quality, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, jpeg artifacts, signature, watermark, username, blurry"
162
 
163
  result = pipe(
164
  image=input_image.convert("RGB"),
165
  prompt=prompt,
166
+ negative_prompt=negative_prompt,
167
  height=height,
168
  width=width,
169
  num_inference_steps=steps,
 
172
  num_images_per_prompt=1,
173
  ).images[0]
174
 
175
+ # *** FIX: Changed function to return only 2 values to match the button's expectation ***
176
+ return result, seed
177
 
178
+ # --- Wrapper for Examples ---
179
+ @spaces.GPU
180
+ def infer_example(input_image_path, prompt, lora_adapter):
181
+ # *** FIX: Fully implemented this function to handle examples correctly ***
182
+ input_pil = Image.open(input_image_path).convert("RGB")
183
+ # Calculate aspect ratio for the example image
184
+ width, height = update_dimensions_on_upload(input_pil)
185
+ # Set reasonable default values for example inference
186
+ guidance_scale = 4.0
187
+ steps = 25
188
+ # Call the main infer function
189
+ result, seed = infer(input_pil, prompt, lora_adapter, 0, True, guidance_scale, steps, width, height)
190
+ return result, seed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
  # --- UI Layout ---
193
  css="""
 
203
  gr.Markdown("# **Qwen-Image-Edit-2509-LoRAs-Fast**", elem_id="main-title")
204
  gr.Markdown("Perform diverse image edits using specialized LoRA adapters for the Qwen-Image-Edit model.")
205
 
206
+ with gr.Row(equal_height=True):
207
  with gr.Column():
208
+ input_image = gr.Image(label="Upload Image", type="pil", height=400)
209
+
210
+ lora_adapter = gr.Dropdown(
211
+ label="Choose Editing Style",
212
+ choices=["Photo-to-Anime", "Multiple-Angles", "Light-Restoration", "Relight"],
213
+ value="Photo-to-Anime"
214
+ )
215
+
216
  prompt = gr.Text(
217
  label="Edit Prompt",
218
  show_label=True,
 
221
 
222
  run_button = gr.Button("Run", variant="primary")
223
 
 
 
 
 
 
 
 
 
 
 
224
  with gr.Accordion("⚙️ Advanced Settings", open=False):
225
  seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
226
  randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
227
+ guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=4.0)
228
+ steps = gr.Slider(label="Inference Steps", minimum=1, maximum=50, step=1, value=25)
229
  # Hidden sliders to hold image dimensions
230
  height = gr.Slider(label="Height", minimum=256, maximum=1024, step=8, value=1024, visible=False)
231
  width = gr.Slider(label="Width", minimum=256, maximum=1024, step=8, value=1024, visible=False)
232
 
233
+ with gr.Column():
234
+ output_image = gr.Image(label="Output Image", interactive=False, format="png", height=400)
235
+
236
  gr.Examples(
237
  examples=[
238
  ["examples/1.jpg", "Transform into anime.", "Photo-to-Anime"],
 
249
  ],
250
  inputs=[input_image, prompt, lora_adapter],
251
  outputs=[output_image, seed],
252
+ fn=infer_example,
253
+ cache_examples="lazy", # Changed to lazy for better performance
254
  label="Examples"
255
  )
256
 
257
+ # --- Event Handlers ---
258
  run_button.click(
259
  fn=infer,
260
  inputs=[input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps, width, height],
 
267
  outputs=[width, height]
268
  )
269
 
270
+ demo.launch()