Mccscs2 commited on
Commit
a41840b
Β·
verified Β·
1 Parent(s): 5cccc30

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -40
app.py CHANGED
@@ -1,9 +1,11 @@
1
  import torch
2
  import spaces
3
  import gradio as gr
4
- from diffusers import DiffusionPipeline, FluxImg2ImgPipeline
 
5
 
6
  print("Loading pipelines...")
 
7
  # Text to image pipeline
8
  pipe_t2i = DiffusionPipeline.from_pretrained(
9
  "Tongyi-MAI/Z-Image-Turbo",
@@ -12,15 +14,34 @@ pipe_t2i = DiffusionPipeline.from_pretrained(
12
  )
13
  pipe_t2i.to("cuda")
14
 
15
- # Image to image pipeline
16
- pipe_i2i = FluxImg2ImgPipeline.from_pretrained(
17
  "black-forest-labs/FLUX.1-schnell",
18
  torch_dtype=torch.bfloat16,
19
  )
20
- pipe_i2i.to("cuda")
 
 
 
 
 
 
 
 
21
 
22
  print("Pipelines loaded!")
23
 
 
 
 
 
 
 
 
 
 
 
 
24
  @spaces.GPU
25
  def generate_t2i(prompt, height, width, num_inference_steps, seed, randomize_seed, progress=gr.Progress(track_tqdm=True)):
26
  if randomize_seed:
@@ -37,32 +58,35 @@ def generate_t2i(prompt, height, width, num_inference_steps, seed, randomize_see
37
  return image, seed
38
 
39
  @spaces.GPU
40
- def generate_i2i(input_image, prompt, strength, num_inference_steps, seed, randomize_seed, progress=gr.Progress(track_tqdm=True)):
 
 
41
  if randomize_seed:
42
  seed = torch.randint(0, 2**32 - 1, (1,)).item()
43
  generator = torch.Generator("cuda").manual_seed(int(seed))
44
-
45
- # Preserve original aspect ratio
46
- orig_w, orig_h = input_image.size
47
- # Round to nearest multiple of 64
48
- new_w = round(orig_w / 64) * 64
49
- new_h = round(orig_h / 64) * 64
50
- # Cap at 1024 on longest side
51
- scale = min(1024 / new_w, 1024 / new_h)
52
- if scale < 1:
53
- new_w = round(new_w * scale / 64) * 64
54
- new_h = round(new_h * scale / 64) * 64
55
- input_image = input_image.resize((new_w, new_h))
56
-
57
- image = pipe_i2i(
58
- prompt=prompt,
59
- image=input_image,
60
- strength=float(strength),
61
- num_inference_steps=int(num_inference_steps),
62
- generator=generator,
63
- width=new_w,
64
- height=new_h,
65
- ).images[0]
 
66
  return image, seed
67
 
68
  examples_t2i = [
@@ -98,16 +122,14 @@ with gr.Blocks(fill_height=True) as demo:
98
 
99
  with gr.Tabs():
100
 
101
- # ── Tab 1: Text to Image ──────────────────────────────────────
102
  with gr.Tab("✨ Text to Image"):
103
  with gr.Row(equal_height=False):
104
  with gr.Column(scale=1, min_width=320):
105
  t2i_prompt = gr.Textbox(
106
  label="✨ Your Prompt",
107
  placeholder="Describe the image you want to create...",
108
- lines=5,
109
- max_lines=10,
110
- autofocus=True,
111
  )
112
  with gr.Accordion("βš™οΈ Advanced Settings", open=False):
113
  with gr.Row():
@@ -131,19 +153,33 @@ with gr.Blocks(fill_height=True) as demo:
131
  t2i_btn.click(generate_t2i, [t2i_prompt, t2i_height, t2i_width, t2i_steps, t2i_seed, t2i_randomize], [t2i_output, t2i_used_seed])
132
  t2i_prompt.submit(generate_t2i, [t2i_prompt, t2i_height, t2i_width, t2i_steps, t2i_seed, t2i_randomize], [t2i_output, t2i_used_seed])
133
 
134
- # ── Tab 2: Image to Image ─────────────────────────────────────
135
  with gr.Tab("πŸ–ΌοΈ Image to Image"):
136
  with gr.Row(equal_height=False):
137
  with gr.Column(scale=1, min_width=320):
 
 
 
 
 
 
 
 
 
 
 
138
  i2i_input = gr.Image(label="Upload Image", type="pil")
139
  i2i_prompt = gr.Textbox(
140
  label="✨ Edit Instruction",
141
- placeholder="Describe how you want to edit the image...",
142
  lines=4,
143
  )
 
144
  with gr.Accordion("βš™οΈ Advanced Settings", open=False):
145
- i2i_strength = gr.Slider(0.1, 1.0, value=0.85, step=0.05, label="Strength", info="Higher = more change")
146
- i2i_steps = gr.Slider(1, 8, value=4, step=1, label="Inference Steps")
 
 
147
  with gr.Row():
148
  i2i_randomize = gr.Checkbox(label="🎲 Random Seed", value=True)
149
  i2i_seed = gr.Number(label="Seed", value=42, precision=0, visible=False)
@@ -151,22 +187,27 @@ with gr.Blocks(fill_height=True) as demo:
151
  lambda r: gr.Number(visible=not r),
152
  inputs=[i2i_randomize], outputs=[i2i_seed]
153
  )
 
154
  i2i_btn = gr.Button("πŸš€ Edit Image", variant="primary", size="lg")
155
 
156
  with gr.Column(scale=1, min_width=320):
157
  i2i_output = gr.Image(label="Result", type="pil", format="png", show_label=False, height=600)
158
  i2i_used_seed = gr.Number(label="🎲 Seed Used", interactive=False)
159
 
160
- i2i_btn.click(generate_i2i, [i2i_input, i2i_prompt, i2i_strength, i2i_steps, i2i_seed, i2i_randomize], [i2i_output, i2i_used_seed])
 
 
 
 
161
 
162
  gr.Markdown(
163
  """
164
  ---
165
  <div style="text-align: center; opacity: 0.7; font-size: 0.9em;">
166
- <strong>T2I Model:</strong> Tongyi-MAI/Z-Image-Turbo β€’
167
- <strong>I2I Model:</strong> FLUX.1-schnell
168
  </div>
169
- """,
170
  )
171
 
172
  if __name__ == "__main__":
@@ -183,7 +224,7 @@ if __name__ == "__main__":
183
  }
184
  .header-text p { font-size: 1.1rem !important; color: #64748b !important; }
185
  .gradio-container { max-width: 1400px !important; margin: 0 auto !important; }
186
- button, .gr-button { transition: all 0.2s ease !important; }
187
  button:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.15) !important; }
188
  """,
189
  mcp_server=True
 
1
  import torch
2
  import spaces
3
  import gradio as gr
4
+ from diffusers import DiffusionPipeline, FluxImg2ImgPipeline, StableDiffusionInstructPix2PixPipeline
5
+ from PIL import Image
6
 
7
  print("Loading pipelines...")
8
+
9
  # Text to image pipeline
10
  pipe_t2i = DiffusionPipeline.from_pretrained(
11
  "Tongyi-MAI/Z-Image-Turbo",
 
14
  )
15
  pipe_t2i.to("cuda")
16
 
17
+ # Image to image - FLUX
18
+ pipe_flux = FluxImg2ImgPipeline.from_pretrained(
19
  "black-forest-labs/FLUX.1-schnell",
20
  torch_dtype=torch.bfloat16,
21
  )
22
+ pipe_flux.to("cuda")
23
+
24
+ # Image to image - InstructPix2Pix
25
+ pipe_ip2p = StableDiffusionInstructPix2PixPipeline.from_pretrained(
26
+ "timbrooks/instruct-pix2pix",
27
+ torch_dtype=torch.float16,
28
+ safety_checker=None,
29
+ )
30
+ pipe_ip2p.to("cuda")
31
 
32
  print("Pipelines loaded!")
33
 
34
+ def resize_image(image, max_size=1024):
35
+ orig_w, orig_h = image.size
36
+ scale = min(max_size / orig_w, max_size / orig_h)
37
+ if scale < 1:
38
+ new_w = round(orig_w * scale / 64) * 64
39
+ new_h = round(orig_h * scale / 64) * 64
40
+ else:
41
+ new_w = round(orig_w / 64) * 64
42
+ new_h = round(orig_h / 64) * 64
43
+ return image.resize((new_w, new_h))
44
+
45
  @spaces.GPU
46
  def generate_t2i(prompt, height, width, num_inference_steps, seed, randomize_seed, progress=gr.Progress(track_tqdm=True)):
47
  if randomize_seed:
 
58
  return image, seed
59
 
60
  @spaces.GPU
61
+ def generate_i2i(model_choice, input_image, prompt, strength, num_inference_steps, seed, randomize_seed, progress=gr.Progress(track_tqdm=True)):
62
+ if input_image is None:
63
+ raise gr.Error("Please upload an image first.")
64
  if randomize_seed:
65
  seed = torch.randint(0, 2**32 - 1, (1,)).item()
66
  generator = torch.Generator("cuda").manual_seed(int(seed))
67
+ input_image = resize_image(input_image)
68
+
69
+ if model_choice == "FLUX.1-schnell (Creative, high change)":
70
+ image = pipe_flux(
71
+ prompt=prompt,
72
+ image=input_image,
73
+ strength=float(strength),
74
+ num_inference_steps=int(num_inference_steps),
75
+ generator=generator,
76
+ width=input_image.width,
77
+ height=input_image.height,
78
+ ).images[0]
79
+
80
+ elif model_choice == "InstructPix2Pix (Precise, preserves identity)":
81
+ image = pipe_ip2p(
82
+ prompt=prompt,
83
+ image=input_image,
84
+ num_inference_steps=int(num_inference_steps),
85
+ image_guidance_scale=1.5,
86
+ guidance_scale=7.5,
87
+ generator=generator,
88
+ ).images[0]
89
+
90
  return image, seed
91
 
92
  examples_t2i = [
 
122
 
123
  with gr.Tabs():
124
 
125
+ # ── Tab 1: Text to Image ──────────────────────────────────
126
  with gr.Tab("✨ Text to Image"):
127
  with gr.Row(equal_height=False):
128
  with gr.Column(scale=1, min_width=320):
129
  t2i_prompt = gr.Textbox(
130
  label="✨ Your Prompt",
131
  placeholder="Describe the image you want to create...",
132
+ lines=5, max_lines=10, autofocus=True,
 
 
133
  )
134
  with gr.Accordion("βš™οΈ Advanced Settings", open=False):
135
  with gr.Row():
 
153
  t2i_btn.click(generate_t2i, [t2i_prompt, t2i_height, t2i_width, t2i_steps, t2i_seed, t2i_randomize], [t2i_output, t2i_used_seed])
154
  t2i_prompt.submit(generate_t2i, [t2i_prompt, t2i_height, t2i_width, t2i_steps, t2i_seed, t2i_randomize], [t2i_output, t2i_used_seed])
155
 
156
+ # ── Tab 2: Image to Image ─────────────────────────────────
157
  with gr.Tab("πŸ–ΌοΈ Image to Image"):
158
  with gr.Row(equal_height=False):
159
  with gr.Column(scale=1, min_width=320):
160
+
161
+ model_choice = gr.Radio(
162
+ choices=[
163
+ "FLUX.1-schnell (Creative, high change)",
164
+ "InstructPix2Pix (Precise, preserves identity)",
165
+ ],
166
+ value="InstructPix2Pix (Precise, preserves identity)",
167
+ label="πŸ€– Model",
168
+ info="InstructPix2Pix is better for targeted edits like changing colours or styles while keeping the person. FLUX is better for creative transformations."
169
+ )
170
+
171
  i2i_input = gr.Image(label="Upload Image", type="pil")
172
  i2i_prompt = gr.Textbox(
173
  label="✨ Edit Instruction",
174
+ placeholder="e.g. 'change the dress to blue' or 'make it a sunset'",
175
  lines=4,
176
  )
177
+
178
  with gr.Accordion("βš™οΈ Advanced Settings", open=False):
179
+ i2i_strength = gr.Slider(0.1, 1.0, value=0.75, step=0.05,
180
+ label="Strength (FLUX only)",
181
+ info="Higher = more change. Not used by InstructPix2Pix.")
182
+ i2i_steps = gr.Slider(1, 50, value=20, step=1, label="Inference Steps")
183
  with gr.Row():
184
  i2i_randomize = gr.Checkbox(label="🎲 Random Seed", value=True)
185
  i2i_seed = gr.Number(label="Seed", value=42, precision=0, visible=False)
 
187
  lambda r: gr.Number(visible=not r),
188
  inputs=[i2i_randomize], outputs=[i2i_seed]
189
  )
190
+
191
  i2i_btn = gr.Button("πŸš€ Edit Image", variant="primary", size="lg")
192
 
193
  with gr.Column(scale=1, min_width=320):
194
  i2i_output = gr.Image(label="Result", type="pil", format="png", show_label=False, height=600)
195
  i2i_used_seed = gr.Number(label="🎲 Seed Used", interactive=False)
196
 
197
+ i2i_btn.click(
198
+ generate_i2i,
199
+ [model_choice, i2i_input, i2i_prompt, i2i_strength, i2i_steps, i2i_seed, i2i_randomize],
200
+ [i2i_output, i2i_used_seed]
201
+ )
202
 
203
  gr.Markdown(
204
  """
205
  ---
206
  <div style="text-align: center; opacity: 0.7; font-size: 0.9em;">
207
+ <strong>T2I:</strong> Tongyi-MAI/Z-Image-Turbo β€’
208
+ <strong>I2I:</strong> FLUX.1-schnell + InstructPix2Pix
209
  </div>
210
+ """
211
  )
212
 
213
  if __name__ == "__main__":
 
224
  }
225
  .header-text p { font-size: 1.1rem !important; color: #64748b !important; }
226
  .gradio-container { max-width: 1400px !important; margin: 0 auto !important; }
227
+ button { transition: all 0.2s ease !important; }
228
  button:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.15) !important; }
229
  """,
230
  mcp_server=True