HAL1993 commited on
Commit
7829c6a
·
verified ·
1 Parent(s): 9a8f5a7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +271 -273
app.py CHANGED
@@ -1,167 +1,40 @@
 
1
  import gradio as gr
2
  import numpy as np
3
  import random
4
  import torch
5
  import spaces
6
-
7
  from PIL import Image
8
  from diffusers import FlowMatchEulerDiscreteScheduler
9
  from optimization import optimize_pipeline_
10
  from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
11
  from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel
12
  from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
13
-
14
- from huggingface_hub import InferenceClient
15
- import math
16
-
17
- import os
18
- import base64
19
- import json
20
-
21
- SYSTEM_PROMPT = '''
22
- # Edit Instruction Rewriter
23
- You are a professional edit instruction rewriter. Your task is to generate a precise, concise, and visually achievable professional-level edit instruction based on the user-provided instruction and the image to be edited.
24
-
25
- Please strictly follow the rewriting rules below:
26
-
27
- ## 1. General Principles
28
- - Keep the rewritten prompt **concise and comprehensive**. Avoid overly long sentences and unnecessary descriptive language.
29
- - If the instruction is contradictory, vague, or unachievable, prioritize reasonable inference and correction, and supplement details when necessary.
30
- - Keep the main part of the original instruction unchanged, only enhancing its clarity, rationality, and visual feasibility.
31
- - All added objects or modifications must align with the logic and style of the scene in the input images.
32
- - If multiple sub-images are to be generated, describe the content of each sub-image individually.
33
-
34
- ## 2. Task-Type Handling Rules
35
-
36
- ### 1. Add, Delete, Replace Tasks
37
- - If the instruction is clear (already includes task type, target entity, position, quantity, attributes), preserve the original intent and only refine the grammar.
38
- - If the description is vague, supplement with minimal but sufficient details (category, color, size, orientation, position, etc.). For example:
39
- > Original: "Add an animal"
40
- > Rewritten: "Add a light-gray cat in the bottom-right corner, sitting and facing the camera"
41
- - Remove meaningless instructions: e.g., "Add 0 objects" should be ignored or flagged as invalid.
42
- - For replacement tasks, specify "Replace Y with X" and briefly describe the key visual features of X.
43
-
44
- ### 2. Text Editing Tasks
45
- - All text content must be enclosed in English double quotes `" "`. Keep the original language of the text, and keep the capitalization.
46
- - Both adding new text and replacing existing text are text replacement tasks, For example:
47
- - Replace "xx" to "yy"
48
- - Replace the mask / bounding box to "yy"
49
- - Replace the visual object to "yy"
50
- - Specify text position, color, and layout only if user has required.
51
- - If font is specified, keep the original language of the font.
52
-
53
- ### 3. Human Editing Tasks
54
- - Make the smallest changes to the given user's prompt.
55
- - If changes to background, action, expression, camera shot, or ambient lighting are required, please list each modification individually.
56
- - **Edits to makeup or facial features / expression must be subtle, not exaggerated, and must preserve the subject’s identity consistency.**
57
- > Original: "Add eyebrows to the face"
58
- > Rewritten: "Slightly thicken the person’s eyebrows with little change, look natural."
59
-
60
- ### 4. Style Conversion or Enhancement Tasks
61
- - If a style is specified, describe it concisely using key visual features. For example:
62
- > Original: "Disco style"
63
- > Rewritten: "1970s disco style: flashing lights, disco ball, mirrored walls, vibrant colors"
64
- - For style reference, analyze the original image and extract key characteristics (color, composition, texture, lighting, artistic style, etc.), integrating them into the instruction.
65
- - **Colorization tasks (including old photo restoration) must use the fixed template:**
66
- "Restore and colorize the old photo."
67
- - Clearly specify the object to be modified. For example:
68
- > Original: Modify the subject in Picture 1 to match the style of Picture 2.
69
- > Rewritten: Change the girl in Picture 1 to the ink-wash style of Picture 2 — rendered in black-and-white watercolor with soft color transitions.
70
-
71
- ### 5. Material Replacement
72
- - Clearly specify the object and the material. For example: "Change the material of the apple to papercut style."
73
- - For text material replacement, use the fixed template:
74
- "Change the material of text "xxxx" to laser style"
75
-
76
- ### 6. Logo/Pattern Editing
77
- - Material replacement should preserve the original shape and structure as much as possible. For example:
78
- > Original: "Convert to sapphire material"
79
- > Rewritten: "Convert the main subject in the image to sapphire material, preserving similar shape and structure"
80
- - When migrating logos/patterns to new scenes, ensure shape and structure consistency. For example:
81
- > Original: "Migrate the logo in the image to a new scene"
82
- > Rewritten: "Migrate the logo in the image to a new scene, preserving similar shape and structure"
83
-
84
- ### 7. Multi-Image Tasks
85
- - Rewritten prompts must clearly point out which image’s element is being modified. For example:
86
- > Original: "Replace the subject of picture 1 with the subject of picture 2"
87
- > Rewritten: "Replace the girl of picture 1 with the boy of picture 2, keeping picture 2’s background unchanged"
88
- - For stylization tasks, describe the reference image’s style in the rewritten prompt, while preserving the visual content of the source image.
89
-
90
- ## 3. Rationale and Logic Check
91
- - Resolve contradictory instructions: e.g., “Remove all trees but keep all trees” requires logical correction.
92
- - Supplement missing critical information: e.g., if position is unspecified, choose a reasonable area based on composition (near subject, blank space, center/edge, etc.).
93
-
94
- # Output Format Example
95
- ```json
96
- {
97
- "Rewritten": "..."
98
- }
99
- '''
100
- # --- Prompt Enhancement using Hugging Face InferenceClient ---
101
- def polish_prompt_hf(prompt, img_list):
102
- """
103
- Rewrites the prompt using a Hugging Face InferenceClient.
104
- """
105
- # Ensure HF_TOKEN is set
106
- api_key = os.environ.get("HF_TOKEN")
107
- if not api_key:
108
- print("Warning: HF_TOKEN not set. Falling back to original prompt.")
109
- return prompt
110
-
111
- try:
112
- # Initialize the client
113
- prompt = f"{SYSTEM_PROMPT}\n\nUser Input: {prompt}\n\nRewritten Prompt:"
114
- # Initialize the client
115
- client = InferenceClient(
116
- provider="novita",
117
- api_key=api_key,
118
- )
119
-
120
- # Format the messages for the chat completions API
121
- sys_promot = "you are a helpful assistant, you should provide useful answers to users."
122
- messages = [
123
- {"role": "system", "content": sys_promot},
124
- {"role": "user", "content": []}]
125
- for img in img_list:
126
- messages[1]["content"].append(
127
- {"image": f"data:image/png;base64,{encode_image(img)}"})
128
- messages[1]["content"].append({"text": f"{prompt}"})
129
-
130
- completion = client.chat.completions.create(
131
- model="Qwen/Qwen3-Next-80B-A3B-Instruct",
132
- messages=messages,
133
- )
134
-
135
- # Parse the response
136
- result = completion.choices[0].message.content
137
-
138
- # Try to extract JSON if present
139
- if '{"Rewritten"' in result:
140
- try:
141
- # Clean up the response
142
- result = result.replace('```json', '').replace('```', '')
143
- result_json = json.loads(result)
144
- polished_prompt = result_json.get('Rewritten', result)
145
- except:
146
- polished_prompt = result
147
- else:
148
- polished_prompt = result
149
-
150
- polished_prompt = polished_prompt.strip().replace("\n", " ")
151
- return polished_prompt
152
-
153
- except Exception as e:
154
- print(f"Error during API call to Hugging Face: {e}")
155
- # Fallback to original prompt if enhancement fails
156
- return prompt
157
-
158
-
159
-
160
- def encode_image(pil_image):
161
- import io
162
- buffered = io.BytesIO()
163
- pil_image.save(buffered, format="PNG")
164
- return base64.b64encode(buffered.getvalue()).decode("utf-8")
165
 
166
  # --- Model Loading ---
167
  dtype = torch.bfloat16
@@ -207,8 +80,9 @@ optimize_pipeline_(pipe, image=[Image.new("RGB", (1024, 1024)), Image.new("RGB",
207
 
208
  # --- UI Constants and Helpers ---
209
  MAX_SEED = np.iinfo(np.int32).max
 
210
 
211
- # --- Main Inference Function (with hardcoded negative prompt) ---
212
  @spaces.GPU(duration=40)
213
  def infer(
214
  images,
@@ -219,19 +93,21 @@ def infer(
219
  num_inference_steps=4,
220
  height=None,
221
  width=None,
222
- rewrite_prompt=True,
223
  num_images_per_prompt=1,
224
  progress=gr.Progress(track_tqdm=True),
225
  ):
226
  """
227
  Generates an image using the local Qwen-Image diffusers pipeline.
228
  """
229
- # Hardcode the negative prompt as requested
230
- negative_prompt = " "
231
 
232
  if randomize_seed:
233
  seed = random.randint(0, MAX_SEED)
234
 
 
 
 
235
  # Set up the generator for reproducibility
236
  generator = torch.Generator(device=device).manual_seed(seed)
237
 
@@ -249,20 +125,16 @@ def infer(
249
  except Exception:
250
  continue
251
 
252
- if height==256 and width==256:
253
  height, width = None, None
254
- print(f"Calling pipeline with prompt: '{prompt}'")
255
  print(f"Negative Prompt: '{negative_prompt}'")
256
  print(f"Seed: {seed}, Steps: {num_inference_steps}, Guidance: {true_guidance_scale}, Size: {width}x{height}")
257
- if rewrite_prompt and len(pil_images) > 0:
258
- prompt = polish_prompt_hf(prompt, pil_images)
259
- print(f"Rewritten Prompt: {prompt}")
260
-
261
 
262
  # Generate the image
263
  image = pipe(
264
  image=pil_images if len(pil_images) > 0 else None,
265
- prompt=prompt,
266
  height=height,
267
  width=width,
268
  negative_prompt=negative_prompt,
@@ -274,122 +146,248 @@ def infer(
274
 
275
  return image, seed
276
 
277
- # --- Examples and UI Layout ---
278
- examples = []
279
-
280
- css = """
281
- #col-container {
282
- margin: 0 auto;
283
- max-width: 1024px;
284
- }
285
- #logo-title {
286
- text-align: center;
287
- }
288
- #logo-title img {
289
- width: 400px;
290
- }
291
- #edit_text{margin-top: -62px !important}
292
- """
293
-
294
- with gr.Blocks(css=css) as demo:
295
- with gr.Column(elem_id="col-container"):
296
  gr.HTML("""
297
- <div id="logo-title">
298
- <img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Image/qwen_image_edit_logo.png" alt="Qwen-Image Edit Logo" width="400" style="display: block; margin: 0 auto;">
299
- <h2 style="font-style: italic;color: #5b47d1;margin-top: -27px !important;margin-left: 96px">[Plus] Fast, 8-steps with Lightning LoRA</h2>
300
- </div>
301
- """)
302
- gr.Markdown("""
303
- [Learn more](https://github.com/QwenLM/Qwen-Image) about the Qwen-Image series.
304
- This demo uses the new [Qwen-Image-Edit-2509](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) with the [Qwen-Image-Lightning v2](https://huggingface.co/lightx2v/Qwen-Image-Lightning) LoRA + [AoT compilation & FA3](https://huggingface.co/blog/zerogpu-aoti) for accelerated inference.
305
- Try on [Qwen Chat](https://chat.qwen.ai/), or [download model](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) to run locally with ComfyUI or diffusers.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  """)
307
- with gr.Row():
308
- with gr.Column():
309
- input_images = gr.Gallery(label="Input Images",
310
- show_label=False,
311
- type="pil",
312
- interactive=True)
313
 
314
- # result = gr.Image(label="Result", show_label=False, type="pil")
315
- result = gr.Gallery(label="Result", show_label=False, type="pil")
316
- with gr.Row():
317
- prompt = gr.Text(
318
- label="Prompt",
319
- show_label=False,
320
- placeholder="describe the edit instruction",
321
- container=False,
322
- )
323
- run_button = gr.Button("Edit!", variant="primary")
324
-
325
- with gr.Accordion("Advanced Settings", open=False):
326
- # Negative prompt UI element is removed here
327
-
328
- seed = gr.Slider(
329
- label="Seed",
330
- minimum=0,
331
- maximum=MAX_SEED,
332
- step=1,
333
- value=0,
334
- )
335
-
336
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
337
-
338
- with gr.Row():
339
-
340
- true_guidance_scale = gr.Slider(
341
- label="True guidance scale",
342
- minimum=1.0,
343
- maximum=10.0,
344
- step=0.1,
345
- value=1.0
346
  )
347
-
348
- num_inference_steps = gr.Slider(
349
- label="Number of inference steps",
350
- minimum=1,
351
- maximum=40,
352
- step=1,
353
- value=4,
354
  )
355
-
356
- height = gr.Slider(
357
- label="Height",
358
- minimum=256,
359
- maximum=2048,
360
- step=8,
361
- value=None,
362
  )
363
-
364
- width = gr.Slider(
365
- label="Width",
366
- minimum=256,
367
- maximum=2048,
368
- step=8,
369
- value=None,
370
  )
371
-
372
-
373
- rewrite_prompt = gr.Checkbox(label="Rewrite prompt (being fixed)", value=False)
374
-
375
- # gr.Examples(examples=examples, inputs=[prompt], outputs=[result, seed], fn=infer, cache_examples=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
 
377
- gr.on(
378
- triggers=[run_button.click, prompt.submit],
379
- fn=infer,
380
- inputs=[
381
- input_images,
382
- prompt,
383
- seed,
384
- randomize_seed,
385
- true_guidance_scale,
386
- num_inference_steps,
387
- height,
388
- width,
389
- rewrite_prompt,
390
- ],
391
- outputs=[result, seed],
392
- )
393
 
394
  if __name__ == "__main__":
395
- demo.launch()
 
 
 
1
+ import os
2
  import gradio as gr
3
  import numpy as np
4
  import random
5
  import torch
6
  import spaces
 
7
  from PIL import Image
8
  from diffusers import FlowMatchEulerDiscreteScheduler
9
  from optimization import optimize_pipeline_
10
  from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
11
  from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel
12
  from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
13
+ import requests # For translation API
14
+
15
+ # --- Translation Function ---
16
+ @spaces.GPU
17
+ def translate_albanian_to_english(text):
18
+ """Translate from Albanian to English using the sepioo-facebook-translation API."""
19
+ if not text.strip():
20
+ raise gr.Error("Please enter a description.")
21
+ for attempt in range(2):
22
+ try:
23
+ response = requests.post(
24
+ "https://hal1993-mdftranslation1234567890abcdef1234567890-fc073a6.hf.space/v1/translate",
25
+ json={"from_language": "sq", "to_language": "en", "input_text": text},
26
+ headers={"accept": "application/json", "Content-Type": "application/json"},
27
+ timeout=5
28
+ )
29
+ response.raise_for_status()
30
+ translated = response.json().get("translate", "")
31
+ print(f"Translation response: {translated}")
32
+ return translated
33
+ except Exception as e:
34
+ print(f"Translation error (attempt {attempt + 1}): {e}")
35
+ if attempt == 1:
36
+ raise gr.Error("Translation failed. Please try again.")
37
+ raise gr.Error("Translation failed. Please try again.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  # --- Model Loading ---
40
  dtype = torch.bfloat16
 
80
 
81
  # --- UI Constants and Helpers ---
82
  MAX_SEED = np.iinfo(np.int32).max
83
+ QUALITY_PROMPT = ", high quality, detailed, vibrant, professional lighting"
84
 
85
+ # --- Main Inference Function ---
86
  @spaces.GPU(duration=40)
87
  def infer(
88
  images,
 
93
  num_inference_steps=4,
94
  height=None,
95
  width=None,
96
+ rewrite_prompt=False,
97
  num_images_per_prompt=1,
98
  progress=gr.Progress(track_tqdm=True),
99
  ):
100
  """
101
  Generates an image using the local Qwen-Image diffusers pipeline.
102
  """
103
+ negative_prompt = "" # Empty as in original
 
104
 
105
  if randomize_seed:
106
  seed = random.randint(0, MAX_SEED)
107
 
108
+ # Translate prompt from Albanian to English
109
+ prompt_final = translate_albanian_to_english(prompt.strip()) + QUALITY_PROMPT
110
+
111
  # Set up the generator for reproducibility
112
  generator = torch.Generator(device=device).manual_seed(seed)
113
 
 
125
  except Exception:
126
  continue
127
 
128
+ if height == 256 and width == 256:
129
  height, width = None, None
130
+ print(f"Calling pipeline with prompt: '{prompt_final}'")
131
  print(f"Negative Prompt: '{negative_prompt}'")
132
  print(f"Seed: {seed}, Steps: {num_inference_steps}, Guidance: {true_guidance_scale}, Size: {width}x{height}")
 
 
 
 
133
 
134
  # Generate the image
135
  image = pipe(
136
  image=pil_images if len(pil_images) > 0 else None,
137
+ prompt=prompt_final,
138
  height=height,
139
  width=width,
140
  negative_prompt=negative_prompt,
 
146
 
147
  return image, seed
148
 
149
+ # --- Gradio User Interface ---
150
+ def create_demo():
151
+ with gr.Blocks(css="", title="Qwen Image Editor") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  gr.HTML("""
153
+ <style>
154
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;700&display=swap');
155
+ body {
156
+ background: #000000;
157
+ color: #FFFFFF;
158
+ font-family: 'Orbitron', sans-serif;
159
+ min-height: 100vh;
160
+ margin: 0;
161
+ padding: 0;
162
+ display: flex;
163
+ justify-content: center;
164
+ align-items: center;
165
+ flex-direction: column;
166
+ }
167
+ body::before {
168
+ content: "";
169
+ display: block;
170
+ height: 600px;
171
+ background: #000000;
172
+ }
173
+ #general_items {
174
+ width: 100%;
175
+ margin: 2rem 0;
176
+ display: flex;
177
+ flex-direction: column;
178
+ align-items: center;
179
+ }
180
+ #input_column {
181
+ background: rgba(0, 0, 0, 0.5);
182
+ border: 1px solid #FFFFFF;
183
+ border-radius: 8px;
184
+ padding: 1rem;
185
+ box-shadow: 0 0 8px rgba(255, 255, 255, 0.2);
186
+ width: 100%;
187
+ }
188
+ h1 {
189
+ font-size: 5rem;
190
+ font-weight: 700;
191
+ text-align: center;
192
+ color: #FFFFFF;
193
+ text-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
194
+ margin-bottom: 0.5rem;
195
+ }
196
+ #subtitle {
197
+ font-size: 1rem;
198
+ text-align: center;
199
+ color: #FFFFFF;
200
+ opacity: 0.8;
201
+ margin-bottom: 1rem;
202
+ }
203
+ .gradio-component {
204
+ background: transparent;
205
+ border: none;
206
+ margin: 0.75rem 0;
207
+ width: 100%;
208
+ }
209
+ .gr-gallery {
210
+ width: 100%;
211
+ border: 1px solid #FFFFFF;
212
+ border-radius: 4px;
213
+ }
214
+ input, textarea, .gr-slider {
215
+ background: #000000;
216
+ color: #FFFFFF;
217
+ border: 1px solid #FFFFFF;
218
+ border-radius: 4px;
219
+ padding: 0.5rem;
220
+ width: 100%;
221
+ box-sizing: border-box;
222
+ }
223
+ input:hover, textarea:hover, .gr-slider:hover {
224
+ box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
225
+ transition: box-shadow 0.3s;
226
+ }
227
+ .gr-button-primary {
228
+ background: #000000 !important;
229
+ color: #FFFFFF !important;
230
+ border: 1px solid #FFFFFF !important;
231
+ border-radius: 6px;
232
+ padding: 0.75rem 1.5rem;
233
+ font-size: 1.1rem;
234
+ font-weight: 600;
235
+ box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
236
+ transition: box-shadow 0.3s, transform 0.3s;
237
+ width: 100%;
238
+ min-height: 48px;
239
+ cursor: pointer;
240
+ }
241
+ .gr-button-primary:hover {
242
+ box-shadow: 0 0 12px rgba(255, 255, 255, 0.5);
243
+ transform: scale(1.05);
244
+ }
245
+ button[aria-label="Download"] {
246
+ transform: scale(3);
247
+ transform-origin: top right;
248
+ background: #000000 !important;
249
+ color: #FFFFFF !important;
250
+ border: 1px solid #FFFFFF !important;
251
+ border-radius: 4px;
252
+ padding: 0.4rem !important;
253
+ margin: 0.5rem !important;
254
+ box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
255
+ transition: box-shadow 0.3s;
256
+ }
257
+ button[aria-label="Download"]:hover {
258
+ box-shadow: 0 0 12px rgba(255, 255, 255, 0.5);
259
+ }
260
+ button[aria-label="Fullscreen"], button[aria-label="Fullscreen"]:hover,
261
+ button[aria-label="Share"], button[aria-label="Share"]:hover {
262
+ display: none !important;
263
+ }
264
+ .progress-text {
265
+ color: #FFFFFF !important;
266
+ }
267
+ footer, .gr-button-secondary {
268
+ display: none;
269
+ }
270
+ .gr-accordion {
271
+ background: rgba(0, 0, 0, 0.5);
272
+ border: 1px solid #FFFFFF;
273
+ border-radius: 4px;
274
+ width: 100%;
275
+ }
276
+ @media (max-width: 768px) {
277
+ h1 {
278
+ font-size: 4rem;
279
+ }
280
+ #subtitle {
281
+ font-size: 0.9rem;
282
+ }
283
+ .gr-button-primary {
284
+ padding: 0.6rem 1rem;
285
+ font-size: 1rem;
286
+ }
287
+ }
288
+ </style>
289
  """)
 
 
 
 
 
 
290
 
291
+ with gr.Row(elem_id="general_items"):
292
+ gr.Markdown("# Qwen Image Editor")
293
+ gr.Markdown("Edit your images with precise instructions", elem_id="subtitle")
294
+ with gr.Column(elem_id="input_column"):
295
+ input_images = gr.Gallery(
296
+ label="Input Images",
297
+ show_label=True,
298
+ type="pil",
299
+ interactive=True,
300
+ elem_classes=["gradio-component", "gr-gallery"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  )
302
+ result = gr.Gallery(
303
+ label="Result",
304
+ show_label=True,
305
+ type="pil",
306
+ elem_classes=["gradio-component", "gr-gallery"]
 
 
307
  )
308
+ prompt = gr.Textbox(
309
+ label="Prompt",
310
+ placeholder="Describe the edit instruction",
311
+ lines=3,
312
+ elem_classes="gradio-component"
 
 
313
  )
314
+ run_button = gr.Button(
315
+ "Edit!",
316
+ variant="primary",
317
+ elem_classes="gradio-component"
 
 
 
318
  )
319
+ with gr.Accordion("Advanced Settings", open=False):
320
+ seed = gr.Slider(
321
+ label="Seed",
322
+ minimum=0,
323
+ maximum=MAX_SEED,
324
+ step=1,
325
+ value=0,
326
+ elem_classes="gradio-component"
327
+ )
328
+ randomize_seed = gr.Checkbox(
329
+ label="Randomize seed",
330
+ value=True,
331
+ elem_classes="gradio-component"
332
+ )
333
+ true_guidance_scale = gr.Slider(
334
+ label="True guidance scale",
335
+ minimum=1.0,
336
+ maximum=10.0,
337
+ step=0.1,
338
+ value=1.0,
339
+ elem_classes="gradio-component"
340
+ )
341
+ num_inference_steps = gr.Slider(
342
+ label="Number of inference steps",
343
+ minimum=1,
344
+ maximum=40,
345
+ step=1,
346
+ value=4,
347
+ elem_classes="gradio-component"
348
+ )
349
+ height = gr.Slider(
350
+ label="Height",
351
+ minimum=256,
352
+ maximum=2048,
353
+ step=8,
354
+ value=None,
355
+ elem_classes="gradio-component"
356
+ )
357
+ width = gr.Slider(
358
+ label="Width",
359
+ minimum=256,
360
+ maximum=2048,
361
+ step=8,
362
+ value=None,
363
+ elem_classes="gradio-component"
364
+ )
365
+ rewrite_prompt = gr.Checkbox(
366
+ label="Rewrite prompt (being fixed)",
367
+ value=False,
368
+ elem_classes="gradio-component"
369
+ )
370
+
371
+ gr.on(
372
+ triggers=[run_button.click, prompt.submit],
373
+ fn=infer,
374
+ inputs=[
375
+ input_images,
376
+ prompt,
377
+ seed,
378
+ randomize_seed,
379
+ true_guidance_scale,
380
+ num_inference_steps,
381
+ height,
382
+ width,
383
+ rewrite_prompt,
384
+ ],
385
+ outputs=[result, seed],
386
+ )
387
 
388
+ return demo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
 
390
  if __name__ == "__main__":
391
+ print(f"Gradio version: {gr.__version__}")
392
+ demo = create_demo()
393
+ demo.queue().launch(share=True)