lichorosario commited on
Commit
6eb9fe9
Β·
verified Β·
1 Parent(s): 10305a5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +203 -89
app.py CHANGED
@@ -1,106 +1,220 @@
1
- import math
2
  import gradio as gr
3
- import spaces
 
 
4
  from PIL import Image
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- from diffsynth_engine import (
7
- fetch_model,
8
- QwenImagePipeline,
9
- QwenImagePipelineConfig,
10
- )
11
-
12
- # ----------------------------
13
- # Pipeline initialization (CPU)
14
- # ----------------------------
15
- config = QwenImagePipelineConfig.basic_config(
16
- model_path=fetch_model(
17
- "Qwen/Qwen-Image-2512",
18
- path="transformer/*.safetensors"
19
- ),
20
- encoder_path=fetch_model(
21
- "Qwen/Qwen-Image-2512",
22
- path="text_encoder/*.safetensors"
23
- ),
24
- vae_path=fetch_model(
25
- "Qwen/Qwen-Image-2512",
26
- path="vae/*.safetensors"
27
- ),
28
- offload_mode="cpu_offload",
29
- )
30
-
31
- pipe = QwenImagePipeline.from_pretrained(config)
32
-
33
- # Load Turbo LoRA
34
- pipe.load_lora(
35
- path=fetch_model(
36
- "Wuli-Art/Qwen-Image-2512-Turbo-LoRA",
37
- path="Wuli-Qwen-Image-2512-Turbo-LoRA-4steps-V1.0-bf16.safetensors"
38
- ),
39
- scale=1.0,
40
- fused=True,
41
- )
42
-
43
- # Scheduler config
44
- pipe.apply_scheduler_config(
45
- {
46
- "exponential_shift_mu": math.log(2.5),
47
- "use_dynamic_shifting": True,
48
- "shift_terminal": None,
49
  }
50
- )
51
-
52
- # ----------------------------
53
- # GPU inference (ZeroGPU)
54
- # ----------------------------
55
- @spaces.GPU
56
- def generate(
57
- prompt: str,
58
- seed: int,
59
- width: int,
60
- height: int,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  ):
62
- result = pipe(
63
- prompt=prompt,
64
- cfg_scale=1,
65
- num_inference_steps=4,
66
- seed=seed,
67
- width=width,
68
- height=height,
69
- )
70
 
71
- # result is PIL.Image
72
- return result
73
 
 
 
 
 
 
 
74
 
75
- # ----------------------------
76
- # Gradio UI
77
- # ----------------------------
78
- with gr.Blocks() as demo:
79
- gr.Markdown("## Qwen Image Β· ZeroGPU demo")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
- with gr.Row():
82
- prompt = gr.Textbox(
83
- label="Prompt",
84
- value="a young girl with flowing long hair, wearing a white halter dress and smiling sweetly. The background features a blue seaside where seagulls fly freely.",
85
- lines=4,
 
 
 
 
 
 
 
 
 
86
  )
 
87
 
88
- with gr.Row():
89
- seed = gr.Number(value=42, label="Seed", precision=0)
90
- width = gr.Number(value=1328, label="Width", precision=0)
91
- height = gr.Number(value=1328, label="Height", precision=0)
 
92
 
93
- generate_btn = gr.Button("Generate")
94
 
95
- output_image = gr.Image(
96
- label="Generated image",
97
- type="pil",
 
98
  )
99
 
100
- generate_btn.click(
101
- fn=generate,
102
- inputs=[prompt, seed, width, height],
103
- outputs=output_image,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
- demo.queue().launch()
 
 
1
+ import os
2
  import gradio as gr
3
+ import json
4
+ import logging
5
+ import torch
6
  from PIL import Image
7
+ import spaces
8
+ from diffusers import DiffusionPipeline, FlowMatchEulerDiscreteScheduler
9
+ from huggingface_hub import hf_hub_download, HfFileSystem, ModelCard, snapshot_download
10
+ import copy
11
+ import random
12
+ import time
13
+ import re
14
+ import math
15
+ import numpy as np
16
+ import traceback
17
+
18
+ #from diffsynth_engine import fetch_model, QwenImagePipeline, QwenImagePipelineConfig
19
 
20
+ from huggingface_hub import login, InferenceClient
21
+
22
+ login(token=os.environ.get('hf'))
23
+
24
+ def apply_aspect_ratio(ratio):
25
+ sizes = {
26
+ "1:1": (1024, 1024),
27
+ "16:9": (1365, 768),
28
+ "9:16": (768, 1365),
29
+ "3:2": (1254, 836),
30
+ "2:3": (836, 1254),
31
+ "3:1": (1774, 591),
32
+ "2:1": (1448, 724),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
+ return sizes.get(ratio, (1024, 1024))
35
+
36
+
37
+ # Initialize the base model
38
+ dtype = torch.bfloat16
39
+ device = "cuda" if torch.cuda.is_available() else "cpu"
40
+ base_model = "Qwen/Qwen-Image-2512"
41
+
42
+ # Scheduler configuration from the Qwen-Image-Lightning repository
43
+ scheduler_config = {
44
+ "base_image_seq_len": 256,
45
+ "base_shift": math.log(3),
46
+ "invert_sigmas": False,
47
+ "max_image_seq_len": 8192,
48
+ "max_shift": math.log(3),
49
+ "num_train_timesteps": 1000,
50
+ "shift": 1.0,
51
+ "shift_terminal": None,
52
+ "stochastic_sampling": False,
53
+ "time_shift_type": "exponential",
54
+ "use_beta_sigmas": False,
55
+ "use_dynamic_shifting": True,
56
+ "use_exponential_sigmas": False,
57
+ "use_karras_sigmas": False,
58
+ }
59
+
60
+ scheduler = FlowMatchEulerDiscreteScheduler.from_config(scheduler_config)
61
+ pipe = DiffusionPipeline.from_pretrained(
62
+ base_model, scheduler=scheduler, torch_dtype=dtype
63
+ ).to(device)
64
+
65
+
66
+
67
+ # Lightning LoRA info (no global state)
68
+ LIGHTNING_LORA_REPO = "lightx2v/Qwen-Image-2512-Lightning"
69
+ LIGHTNING_LORA_WEIGHT = "Qwen-Image-2512-Lightning-4steps-V1.0-bf16.safetensors"
70
+ LIGHTNING8_LORA_WEIGHT = "Qwen-Image-Lightning-8steps-V2.0-bf16.safetensors"
71
+ LIGHTNING_FP8_4STEPS_LORA_WEIGHT = "Qwen-Image-fp8-e4m3fn-Lightning-4steps-V1.0-bf16.safetensors"
72
+
73
+ #LIGHTNING_LORA_REPO = "Wuli-art/Qwen-Image-2512-Turbo-LoRA"
74
+ #LIGHTNING_LORA_WEIGHT = "Wuli-Qwen-Image-2512-Turbo-LoRA-4steps-V1.0-bf16.safetensors"
75
+ #LIGHTNING8_LORA_WEIGHT = "Wuli-Qwen-Image-2512-Turbo-LoRA-4steps-V1.0-bf16.safetensors"
76
+
77
+ MAX_SEED = np.iinfo(np.int32).max
78
+
79
+
80
+ class calculateDuration:
81
+ def __init__(self, activity_name=""):
82
+ self.activity_name = activity_name
83
+
84
+
85
+ def __enter__(self):
86
+ self.start_time = time.time()
87
+ return self
88
+
89
+ def __exit__(self, exc_type, exc_value, traceback):
90
+ self.end_time = time.time()
91
+ self.elapsed_time = self.end_time - self.start_time
92
+ if self.activity_name:
93
+ print(f"Elapsed time for {self.activity_name}: {self.elapsed_time:.6f} seconds")
94
+ else:
95
+ print(f"Elapsed time: {self.elapsed_time:.6f} seconds")
96
+
97
+
98
+ @spaces.GPU(duration=70)
99
+ def generate_image(
100
+ prompt_mash,
101
+ width,
102
+ height,
103
  ):
104
+ pipe.to("cuda")
105
+ if negative_prompt == '':
106
+ negative_prompt = "δ½Žεˆ†θΎ¨ηŽ‡οΌŒδ½Žη”»θ΄¨οΌŒθ‚’δ½“η•Έε½’οΌŒζ‰‹ζŒ‡η•Έε½’οΌŒη”»ι’θΏ‡ι₯±ε’ŒοΌŒθœ‘εƒζ„ŸοΌŒδΊΊθ„Έζ— η»†θŠ‚οΌŒθΏ‡εΊ¦ε…‰ζ»‘οΌŒη”»ι’ε…·ζœ‰AIζ„Ÿγ€‚ζž„ε›Ύζ··δΉ±γ€‚ζ–‡ε­—ζ¨‘η³ŠοΌŒζ‰­ζ›²γ€‚"
 
 
 
 
 
107
 
 
 
108
 
109
+ seed = 235234
110
+ num_images = 1
111
+ seeds = [seed + (i * 100) for i in range(num_images)]
112
+ generators = [torch.Generator(device="cuda").manual_seed(s) for s in seeds]
113
+
114
+ images = []
115
 
116
+ with calculateDuration("Generating images (sequential)"):
117
+ for i in range(num_images):
118
+ current_seed = seed + (i * 100)
119
+ generator = torch.Generator(device="cuda").manual_seed(current_seed)
120
+
121
+ result = pipe(
122
+ prompt=prompt_mash,
123
+ negative_prompt=negative_prompt,
124
+ num_inference_steps=4,
125
+ true_cfg_scale=1,
126
+ width=width,
127
+ height=height,
128
+ num_images_per_prompt=1,
129
+ generator=generator,
130
+ )
131
+
132
+ images.append((result.images[0], current_seed))
133
+ return images
134
+
135
 
136
+
137
+ @spaces.GPU(duration=70)
138
+ def run_lora(
139
+ prompt,
140
+ width,
141
+ height,
142
+ progress=gr.Progress(track_tqdm=True)
143
+ ):
144
+
145
+ with calculateDuration("Loading Lightning LoRA and style LoRA"):
146
+ pipe.load_lora_weights(
147
+ 'Wuli-Art/Qwen-Image-2512-Turbo-LoRA',
148
+ weight_name='Wuli-Qwen-Image-2512-Turbo-LoRA-4steps-V1.0-bf16.safetensors',
149
+ adapter_name="lightning"
150
  )
151
+ pipe.set_adapters(["lightning"], adapter_weights=[1.0])
152
 
153
+
154
+ multiplier = float(quality_multiplier.replace('x', ''))
155
+ width = int(width * multiplier)
156
+ height = int(height * multiplier)
157
+ num_images = int(quantity) + 1
158
 
 
159
 
160
+ pairs = generate_image(
161
+ prompt,
162
+ width,
163
+ height
164
  )
165
 
166
+ images_for_gallery = [
167
+ (img, str(s))
168
+ for (img, s) in pairs
169
+ ]
170
+
171
+ return images_for_gallery
172
+
173
+
174
+
175
+ css = '''
176
+ #gen_btn{height: 100%}
177
+ #gen_column{align-self: stretch}
178
+ #title{text-align: center}
179
+ #title h1{font-size: 3em; display:inline-flex; align-items:center}
180
+ #title img{width: 100px; margin-right: 0.5em}
181
+ #gallery .grid-wrap{height: 10vh}
182
+ #lora_list{background: var(--block-background-fill);padding: 0 1em .3em; font-size: 90%}
183
+ .card_internal{display: flex;height: 100px;margin-top: .5em}
184
+ .card_internal img{margin-right: 1em}
185
+ .styler{--form-gap-width: 0px !important}
186
+ #speed_status{padding: .5em; border-radius: 5px; margin: 1em 0}
187
+ '''
188
+
189
+
190
+ with gr.Blocks(theme=gr.themes.Soft(), css=css, delete_cache=(60, 60)) as app:
191
+ title = gr.HTML(
192
+ """<img src=\"https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/qwen_image_logo.png\" alt=\"Qwen-Image\" style=\"width: 280px; margin: 0 auto\">
193
+ <h3 style=\"margin-top: -10px\">Wuli-art/Qwen-Image-2512-Turbo-LoRA</h3>""",
194
+ elem_id="title",
195
  )
196
+
197
+ selected_index = gr.State(None)
198
+
199
+ with gr.Row():
200
+ with gr.Column(scale=3):
201
+ prompt = gr.Textbox(label="Prompt", lines=1, placeholder="Type a prompt after selecting a LoRA")
202
+ generate_button = gr.Button("Generate", variant="primary", elem_id="gen_btn", interactive=False)
203
+ with gr.Column(scale=1, elem_id="gen_column"):
204
+ result = gr.Gallery(label="Generated Images", show_label=True, elem_id="result_gallery")
205
+
206
+
207
+ generate_event = gr.on(
208
+ triggers=[generate_button.click, prompt.submit],
209
+ fn=run_lora,
210
+ inputs=[
211
+ prompt,
212
+ width,
213
+ height
214
+ ],
215
+ outputs=[result]
216
+ )
217
+
218
 
219
+ app.queue()
220
+ app.launch()