sherwin6180 commited on
Commit
97bbd0f
·
verified ·
1 Parent(s): 544306c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -151
app.py CHANGED
@@ -1,7 +1,6 @@
1
  import os
2
  import gradio as gr
3
  import numpy as np
4
- import spaces
5
  import torch
6
  import random
7
  from PIL import Image
@@ -9,6 +8,14 @@ from typing import Iterable
9
  from gradio.themes import Soft
10
  from gradio.themes.utils import colors, fonts, sizes
11
 
 
 
 
 
 
 
 
 
12
  colors.steel_blue = colors.Color(
13
  name="steel_blue",
14
  c50="#EBF3F8",
@@ -74,21 +81,10 @@ class SteelBlueTheme(Soft):
74
  color_accent_soft="*primary_100",
75
  block_label_background_fill="*primary_200",
76
  )
77
-
78
  steel_blue_theme = SteelBlueTheme()
79
 
80
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
81
-
82
- print("CUDA_VISIBLE_DEVICES=", os.environ.get("CUDA_VISIBLE_DEVICES"))
83
- print("torch.__version__ =", torch.__version__)
84
- print("torch.version.cuda =", torch.version.cuda)
85
- print("cuda available:", torch.cuda.is_available())
86
- print("cuda device count:", torch.cuda.device_count())
87
- if torch.cuda.is_available():
88
- print("current device:", torch.cuda.current_device())
89
- print("device name:", torch.cuda.get_device_name(torch.cuda.current_device()))
90
-
91
- print("Using device:", device)
92
 
93
  from diffusers import FlowMatchEulerDiscreteScheduler
94
  from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
@@ -96,54 +92,45 @@ from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel
96
  from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
97
 
98
  dtype = torch.bfloat16
99
- device = "cuda" if torch.cuda.is_available() else "cpu"
 
 
 
 
 
 
 
 
 
100
 
101
  pipe = QwenImageEditPlusPipeline.from_pretrained(
102
  "Qwen/Qwen-Image-Edit-2509",
103
- transformer=QwenImageTransformer2DModel.from_pretrained(
104
- "linoyts/Qwen-Image-Edit-Rapid-AIO", # [transformer weights extracted from: Phr00t/Qwen-Image-Edit-Rapid-AIO]
105
- subfolder='transformer',
106
- torch_dtype=dtype,
107
- device_map='cuda'
108
- ),
109
- torch_dtype=dtype
110
- ).to(device)
111
 
112
- pipe.load_lora_weights("autoweeb/Qwen-Image-Edit-2509-Photo-to-Anime",
113
- weight_name="Qwen-Image-Edit-2509-Photo-to-Anime_000001000.safetensors",
114
- adapter_name="anime")
115
- pipe.load_lora_weights("dx8152/Qwen-Edit-2509-Multiple-angles",
116
- weight_name="镜头转换.safetensors",
117
- adapter_name="multiple-angles")
118
- pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Light_restoration",
119
- weight_name="移除光影.safetensors",
120
- adapter_name="light-restoration")
121
- pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Relight",
122
- weight_name="Qwen-Edit-Relight.safetensors",
123
- adapter_name="relight")
124
- pipe.load_lora_weights("dx8152/Qwen-Edit-2509-Multi-Angle-Lighting",
125
- weight_name="多角度灯光-251116.safetensors",
126
- adapter_name="multi-angle-lighting")
127
- pipe.load_lora_weights("tlennon-ie/qwen-edit-skin",
128
- weight_name="qwen-edit-skin_1.1_000002750.safetensors",
129
- adapter_name="edit-skin")
130
- pipe.load_lora_weights("lovis93/next-scene-qwen-image-lora-2509",
131
- weight_name="next-scene_lora-v2-3000.safetensors",
132
- adapter_name="next-scene")
133
- pipe.load_lora_weights("vafipas663/Qwen-Edit-2509-Upscale-LoRA",
134
- weight_name="qwen-edit-enhance_64-v3_000001000.safetensors",
135
- adapter_name="upscale-image")
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
- pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
139
  MAX_SEED = np.iinfo(np.int32).max
140
 
141
  def update_dimensions_on_upload(image):
142
  if image is None:
143
  return 1024, 1024
144
-
145
  original_width, original_height = image.size
146
-
147
  if original_width > original_height:
148
  new_width = 1024
149
  aspect_ratio = original_height / original_width
@@ -152,55 +139,38 @@ def update_dimensions_on_upload(image):
152
  new_height = 1024
153
  aspect_ratio = original_width / original_height
154
  new_width = int(new_height * aspect_ratio)
155
-
156
- # Ensure dimensions are multiples of 8
157
  new_width = (new_width // 8) * 8
158
  new_height = (new_height // 8) * 8
159
-
160
  return new_width, new_height
161
 
162
  @spaces.GPU(duration=30)
163
- def infer(
164
- input_image,
165
- prompt,
166
- lora_adapter,
167
- seed,
168
- randomize_seed,
169
- guidance_scale,
170
- steps,
171
- progress=gr.Progress(track_tqdm=True)
172
- ):
173
  if input_image is None:
174
  raise gr.Error("Please upload an image to edit.")
175
-
176
- if lora_adapter == "Photo-to-Anime":
177
- pipe.set_adapters(["anime"], adapter_weights=[1.0])
178
- elif lora_adapter == "Multiple-Angles":
179
- pipe.set_adapters(["multiple-angles"], adapter_weights=[1.0])
180
- elif lora_adapter == "Light-Restoration":
181
- pipe.set_adapters(["light-restoration"], adapter_weights=[1.0])
182
- elif lora_adapter == "Relight":
183
- pipe.set_adapters(["relight"], adapter_weights=[1.0])
184
- elif lora_adapter == "Multi-Angle-Lighting":
185
- pipe.set_adapters(["multi-angle-lighting"], adapter_weights=[1.0])
186
- elif lora_adapter == "Edit-Skin":
187
- pipe.set_adapters(["edit-skin"], adapter_weights=[1.0])
188
- elif lora_adapter == "Next-Scene":
189
- pipe.set_adapters(["next-scene"], adapter_weights=[1.0])
190
- elif lora_adapter == "Upscale-Image":
191
- pipe.set_adapters(["upscale-image"], adapter_weights=[1.0])
192
-
193
  if randomize_seed:
194
  seed = random.randint(0, MAX_SEED)
195
-
196
- generator = torch.Generator(device=device).manual_seed(seed)
 
197
  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"
198
-
199
  original_image = input_image.convert("RGB")
200
-
201
- # Use the new function to update dimensions
202
  width, height = update_dimensions_on_upload(original_image)
203
-
204
  result = pipe(
205
  image=original_image,
206
  prompt=prompt,
@@ -211,88 +181,46 @@ def infer(
211
  generator=generator,
212
  true_cfg_scale=guidance_scale,
213
  ).images[0]
214
-
215
  return result, seed
216
 
217
  @spaces.GPU(duration=30)
218
  def infer_example(input_image, prompt, lora_adapter):
219
  input_pil = input_image.convert("RGB")
220
- guidance_scale = 1.0
221
- steps = 4
222
- result, seed = infer(input_pil, prompt, lora_adapter, 0, True, guidance_scale, steps)
223
  return result, seed
224
 
225
-
226
  css="""
227
- #col-container {
228
- margin: 0 auto;
229
- max-width: 960px;
230
- }
231
- #main-title h1 {font-size: 2.1em !important;}
232
  """
233
 
234
  with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
235
  with gr.Column(elem_id="col-container"):
236
- gr.Markdown("# **Qwen-Image-Edit-2509-LoRAs-Fast**", elem_id="main-title")
237
- gr.Markdown("Perform diverse image edits using specialized [LoRA](https://huggingface.co/models?other=base_model:adapter:Qwen/Qwen-Image-Edit-2509) adapters for the [Qwen-Image-Edit](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) model.")
238
-
239
  with gr.Row(equal_height=True):
240
  with gr.Column():
241
  input_image = gr.Image(label="Upload Image", type="pil", height=290)
242
-
243
- prompt = gr.Text(
244
- label="Edit Prompt",
245
- show_label=True,
246
- placeholder="e.g., transform into anime..",
247
- )
248
-
249
  run_button = gr.Button("Edit Image", variant="primary")
250
-
251
  with gr.Column():
252
  output_image = gr.Image(label="Output Image", interactive=False, format="png", height=350)
253
-
254
- with gr.Row():
255
- lora_adapter = gr.Dropdown(
256
- label="Choose Editing Style",
257
- choices=["Photo-to-Anime", "Multiple-Angles", "Light-Restoration", "Multi-Angle-Lighting", "Upscale-Image", "Relight", "Next-Scene", "Edit-Skin"],
258
- value="Photo-to-Anime"
259
- )
260
- with gr.Accordion("Advanced Settings", open=False, visible=False):
261
- seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
262
- randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
263
- guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=1.0)
264
- steps = gr.Slider(label="Inference Steps", minimum=1, maximum=50, step=1, value=4)
265
 
266
- gr.Examples(
267
- examples=[
268
- ["examples/1.jpg", "Transform into anime.", "Photo-to-Anime"],
269
- ["examples/5.jpg", "Remove shadows and relight the image using soft lighting.", "Light-Restoration"],
270
- ["examples/4.jpg", "Use a subtle golden-hour filter with smooth light diffusion.", "Relight"],
271
- ["examples/2.jpeg", "Rotate the camera 45 degrees to the left.", "Multiple-Angles"],
272
- ["examples/7.jpg", "Light source from the Right Rear", "Multi-Angle-Lighting"],
273
- ["examples/10.jpeg", "Upscale the image.", "Upscale-Image"],
274
- ["examples/7.jpg", "Light source from the Below", "Multi-Angle-Lighting"],
275
- ["examples/2.jpeg", "Switch the camera to a top-down right corner view.", "Multiple-Angles"],
276
- ["examples/9.jpg", "The camera moves slightly forward as sunlight breaks through the clouds, casting a soft glow around the character's silhouette in the mist. Realistic cinematic style, atmospheric depth.", "Next-Scene"],
277
- ["examples/8.jpg", "Make the subjects skin details more prominent and natural.", "Edit-Skin"],
278
- ["examples/6.jpg", "Switch the camera to a bottom-up view.", "Multiple-Angles"],
279
- ["examples/6.jpg", "Rotate the camera 180 degrees upside down.", "Multiple-Angles"],
280
- ["examples/4.jpg", "Rotate the camera 45 degrees to the right.", "Multiple-Angles"],
281
- ["examples/4.jpg", "Switch the camera to a top-down view.", "Multiple-Angles"],
282
- ["examples/4.jpg", "Switch the camera to a wide-angle lens.", "Multiple-Angles"],
283
- ],
284
- inputs=[input_image, prompt, lora_adapter],
285
- outputs=[output_image, seed],
286
- fn=infer_example,
287
- cache_examples=False,
288
- label="Examples"
289
- )
290
-
291
- run_button.click(
292
- fn=infer,
293
- inputs=[input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps],
294
- outputs=[output_image, seed]
295
- )
296
 
297
  if __name__ == "__main__":
298
- demo.queue(max_size=30).launch(mcp_server=True, ssr_mode=False, show_error=True)
 
1
  import os
2
  import gradio as gr
3
  import numpy as np
 
4
  import torch
5
  import random
6
  from PIL import Image
 
8
  from gradio.themes import Soft
9
  from gradio.themes.utils import colors, fonts, sizes
10
 
11
+
12
+ class MockSpaces:
13
+ def GPU(self, duration=0):
14
+ def decorator(func):
15
+ return func
16
+ return decorator
17
+ spaces = MockSpaces()
18
+
19
  colors.steel_blue = colors.Color(
20
  name="steel_blue",
21
  c50="#EBF3F8",
 
81
  color_accent_soft="*primary_100",
82
  block_label_background_fill="*primary_200",
83
  )
 
84
  steel_blue_theme = SteelBlueTheme()
85
 
86
+ print("CUDA_VISIBLE_DEVICES:", os.environ.get("CUDA_VISIBLE_DEVICES"))
87
+ print("GPU Count:", torch.cuda.device_count())
 
 
 
 
 
 
 
 
 
 
88
 
89
  from diffusers import FlowMatchEulerDiscreteScheduler
90
  from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
 
92
  from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
93
 
94
  dtype = torch.bfloat16
95
+
96
+ print("Loading Transformer with split config...")
97
+ transformer_model = QwenImageTransformer2DModel.from_pretrained(
98
+ "linoyts/Qwen-Image-Edit-Rapid-AIO",
99
+ subfolder='transformer',
100
+ torch_dtype=dtype,
101
+ device_map="auto"
102
+ )
103
+
104
+ print("Loading Pipeline...")
105
 
106
  pipe = QwenImageEditPlusPipeline.from_pretrained(
107
  "Qwen/Qwen-Image-Edit-2509",
108
+ transformer=transformer_model,
109
+ torch_dtype=dtype,
110
+ device_map="auto"
111
+ )
 
 
 
 
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
+ pipe.load_lora_weights("autoweeb/Qwen-Image-Edit-2509-Photo-to-Anime", weight_name="Qwen-Image-Edit-2509-Photo-to-Anime_000001000.safetensors", adapter_name="anime")
115
+ pipe.load_lora_weights("dx8152/Qwen-Edit-2509-Multiple-angles", weight_name="镜头转换.safetensors", adapter_name="multiple-angles")
116
+ pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Light_restoration", weight_name="移除光影.safetensors", adapter_name="light-restoration")
117
+ pipe.load_lora_weights("dx8152/Qwen-Image-Edit-2509-Relight", weight_name="Qwen-Edit-Relight.safetensors", adapter_name="relight")
118
+ pipe.load_lora_weights("dx8152/Qwen-Edit-2509-Multi-Angle-Lighting", weight_name="多角度灯光-251116.safetensors", adapter_name="multi-angle-lighting")
119
+ pipe.load_lora_weights("tlennon-ie/qwen-edit-skin", weight_name="qwen-edit-skin_1.1_000002750.safetensors", adapter_name="edit-skin")
120
+ pipe.load_lora_weights("lovis93/next-scene-qwen-image-lora-2509", weight_name="next-scene_lora-v2-3000.safetensors", adapter_name="next-scene")
121
+ pipe.load_lora_weights("vafipas663/Qwen-Edit-2509-Upscale-LoRA", weight_name="qwen-edit-enhance_64-v3_000001000.safetensors", adapter_name="upscale-image")
122
+
123
+ try:
124
+ pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
125
+ except Exception as e:
126
+ print(f"Warning: FA3 set skipped: {e}")
127
 
 
128
  MAX_SEED = np.iinfo(np.int32).max
129
 
130
  def update_dimensions_on_upload(image):
131
  if image is None:
132
  return 1024, 1024
 
133
  original_width, original_height = image.size
 
134
  if original_width > original_height:
135
  new_width = 1024
136
  aspect_ratio = original_height / original_width
 
139
  new_height = 1024
140
  aspect_ratio = original_width / original_height
141
  new_width = int(new_height * aspect_ratio)
 
 
142
  new_width = (new_width // 8) * 8
143
  new_height = (new_height // 8) * 8
 
144
  return new_width, new_height
145
 
146
  @spaces.GPU(duration=30)
147
+ def infer(input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps, progress=gr.Progress(track_tqdm=True)):
 
 
 
 
 
 
 
 
 
148
  if input_image is None:
149
  raise gr.Error("Please upload an image to edit.")
150
+
151
+ adapters_map = {
152
+ "Photo-to-Anime": "anime",
153
+ "Multiple-Angles": "multiple-angles",
154
+ "Light-Restoration": "light-restoration",
155
+ "Relight": "relight",
156
+ "Multi-Angle-Lighting": "multi-angle-lighting",
157
+ "Edit-Skin": "edit-skin",
158
+ "Next-Scene": "next-scene",
159
+ "Upscale-Image": "upscale-image"
160
+ }
161
+
162
+ if lora_adapter in adapters_map:
163
+ pipe.set_adapters([adapters_map[lora_adapter]], adapter_weights=[1.0])
164
+
 
 
 
165
  if randomize_seed:
166
  seed = random.randint(0, MAX_SEED)
167
+
168
+ generator = torch.Generator(device=pipe.device).manual_seed(seed)
169
+
170
  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"
 
171
  original_image = input_image.convert("RGB")
 
 
172
  width, height = update_dimensions_on_upload(original_image)
173
+
174
  result = pipe(
175
  image=original_image,
176
  prompt=prompt,
 
181
  generator=generator,
182
  true_cfg_scale=guidance_scale,
183
  ).images[0]
 
184
  return result, seed
185
 
186
  @spaces.GPU(duration=30)
187
  def infer_example(input_image, prompt, lora_adapter):
188
  input_pil = input_image.convert("RGB")
189
+ result, seed = infer(input_pil, prompt, lora_adapter, 0, True, 1.0, 4)
 
 
190
  return result, seed
191
 
 
192
  css="""
193
+ #col-container { margin: 0 auto; max-width: 960px; }
194
+ #main-title h1 { font-size: 2.1em !important; }
 
 
 
195
  """
196
 
197
  with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
198
  with gr.Column(elem_id="col-container"):
199
+ gr.Markdown("# **Qwen-Image-Edit-2509-LoRAs-Fast (2xA40 Fixed)**", elem_id="main-title")
200
+ gr.Markdown("Forked & Optimized for RunPod 2xGPU Split.")
201
+
202
  with gr.Row(equal_height=True):
203
  with gr.Column():
204
  input_image = gr.Image(label="Upload Image", type="pil", height=290)
205
+ prompt = gr.Text(label="Edit Prompt", show_label=True, placeholder="e.g., transform into anime..")
 
 
 
 
 
 
206
  run_button = gr.Button("Edit Image", variant="primary")
 
207
  with gr.Column():
208
  output_image = gr.Image(label="Output Image", interactive=False, format="png", height=350)
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
+ with gr.Row():
211
+ lora_adapter = gr.Dropdown(
212
+ label="Choose Editing Style",
213
+ choices=["Photo-to-Anime", "Multiple-Angles", "Light-Restoration", "Multi-Angle-Lighting", "Upscale-Image", "Relight", "Next-Scene", "Edit-Skin"],
214
+ value="Photo-to-Anime"
215
+ )
216
+
217
+ with gr.Accordion("Advanced Settings", open=False, visible=False):
218
+ seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
219
+ randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
220
+ guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=1.0)
221
+ steps = gr.Slider(label="Inference Steps", minimum=1, maximum=50, step=1, value=4)
222
+
223
+ run_button.click(fn=infer, inputs=[input_image, prompt, lora_adapter, seed, randomize_seed, guidance_scale, steps], outputs=[output_image, seed])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
  if __name__ == "__main__":
226
+ demo.queue(max_size=30).launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)