tori29umai commited on
Commit
218b488
·
verified ·
1 Parent(s): b36bbcf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -277
app.py CHANGED
@@ -3,165 +3,14 @@ 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
- client = InferenceClient(
115
- provider="cerebras",
116
- api_key=api_key,
117
- )
118
-
119
- # Format the messages for the chat completions API
120
- sys_promot = "you are a helpful assistant, you should provide useful answers to users."
121
- messages = [
122
- {"role": "system", "content": sys_promot},
123
- {"role": "user", "content": []}]
124
- for img in img_list:
125
- messages[1]["content"].append(
126
- {"image": f"data:image/png;base64,{encode_image(img)}"})
127
- messages[1]["content"].append({"text": f"{prompt}"})
128
-
129
- # Call the API
130
- completion = client.chat.completions.create(
131
- model="Qwen/Qwen3-235B-A22B-Instruct-2507",
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
@@ -193,8 +42,8 @@ pipe = QwenImageEditPlusPipeline.from_pretrained("Qwen/Qwen-Image-Edit-2509",
193
  scheduler=scheduler,
194
  torch_dtype=dtype).to(device)
195
  pipe.load_lora_weights(
196
- "lightx2v/Qwen-Image-Lightning",
197
- weight_name="Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-8steps-V1.0-bf16.safetensors"
198
  )
199
  pipe.fuse_lora()
200
 
@@ -208,40 +57,54 @@ optimize_pipeline_(pipe, image=[Image.new("RGB", (1024, 1024)), Image.new("RGB",
208
  # --- UI Constants and Helpers ---
209
  MAX_SEED = np.iinfo(np.int32).max
210
 
211
- def use_output_as_input(output_images):
212
- """Convert output images to input format for the gallery"""
213
- if output_images is None or len(output_images) == 0:
214
- return []
215
- return output_images
 
 
216
 
217
- # --- Main Inference Function (with hardcoded negative prompt) ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  @spaces.GPU(duration=300)
219
- def infer(
220
  images,
221
- prompt,
222
  seed=42,
223
  randomize_seed=False,
224
  true_guidance_scale=1.0,
225
- num_inference_steps=8,
226
- height=None,
227
- width=None,
228
- rewrite_prompt=True,
229
- num_images_per_prompt=1,
230
  progress=gr.Progress(track_tqdm=True),
231
  ):
232
  """
233
- Generates an image using the local Qwen-Image diffusers pipeline.
234
  """
235
- # Hardcode the negative prompt as requested
236
- negative_prompt = " "
237
-
238
  if randomize_seed:
239
  seed = random.randint(0, MAX_SEED)
240
-
241
- # Set up the generator for reproducibility
242
- generator = torch.Generator(device=device).manual_seed(seed)
243
 
244
- # Load input images into PIL Images
245
  pil_images = []
246
  if images is not None:
247
  for item in images:
@@ -254,87 +117,78 @@ def infer(
254
  pil_images.append(Image.open(item.name).convert("RGB"))
255
  except Exception:
256
  continue
257
-
258
- if height==256 and width==256:
259
- height, width = None, None
260
- print(f"Calling pipeline with prompt: '{prompt}'")
261
- print(f"Negative Prompt: '{negative_prompt}'")
262
- print(f"Seed: {seed}, Steps: {num_inference_steps}, Guidance: {true_guidance_scale}, Size: {width}x{height}")
263
- if rewrite_prompt and len(pil_images) > 0:
264
- prompt = polish_prompt_hf(prompt, pil_images)
265
- print(f"Rewritten Prompt: {prompt}")
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
- # Generate the image
269
- image = pipe(
270
- image=pil_images if len(pil_images) > 0 else None,
271
- prompt=prompt,
272
- height=height,
273
- width=width,
274
- negative_prompt=negative_prompt,
275
- num_inference_steps=num_inference_steps,
276
- generator=generator,
277
- true_cfg_scale=true_guidance_scale,
278
- num_images_per_prompt=num_images_per_prompt,
279
- ).images
280
-
281
- # Return images, seed, and make button visible
282
- return image, seed, gr.update(visible=True)
283
-
284
- # --- Examples and UI Layout ---
285
- examples = []
286
-
287
  css = """
288
  #col-container {
289
  margin: 0 auto;
290
- max-width: 1024px;
291
  }
292
- #logo-title {
293
  text-align: center;
 
 
294
  }
295
- #logo-title img {
296
- width: 400px;
297
- }
298
- #edit_text{margin-top: -62px !important}
299
  """
300
 
301
  with gr.Blocks(css=css) as demo:
 
 
 
302
  with gr.Column(elem_id="col-container"):
303
- gr.HTML("""
304
- <div id="logo-title">
305
- <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;">
306
- <h2 style="font-style: italic;color: #5b47d1;margin-top: -27px !important;margin-left: 96px">[Plus] Fast, 8-steps with Lightning LoRA</h2>
307
- </div>
308
- """)
309
- gr.Markdown("""
310
- [Learn more](https://github.com/QwenLM/Qwen-Image) about the Qwen-Image series.
311
- 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.
312
- 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.
313
- """)
 
 
314
  with gr.Row():
315
  with gr.Column():
316
- input_images = gr.Gallery(label="Input Images",
317
- show_label=False,
318
- type="pil",
319
- interactive=True)
320
-
321
  with gr.Column():
322
- result = gr.Gallery(label="Result", show_label=False, type="pil")
323
- # Add this button right after the result gallery - initially hidden
324
- use_output_btn = gr.Button("↗️ Use as input", variant="secondary", size="sm", visible=False)
325
-
326
  with gr.Row():
327
- prompt = gr.Text(
328
- label="Prompt",
329
- show_label=False,
330
- placeholder="describe the edit instruction",
331
- container=False,
332
- )
333
- run_button = gr.Button("Edit!", variant="primary")
334
-
335
- with gr.Accordion("Advanced Settings", open=False):
336
- # Negative prompt UI element is removed here
337
 
 
338
  seed = gr.Slider(
339
  label="Seed",
340
  minimum=0,
@@ -343,10 +197,9 @@ with gr.Blocks(css=css) as demo:
343
  value=0,
344
  )
345
 
346
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
347
 
348
  with gr.Row():
349
-
350
  true_guidance_scale = gr.Slider(
351
  label="True guidance scale",
352
  minimum=1.0,
@@ -356,56 +209,31 @@ with gr.Blocks(css=css) as demo:
356
  )
357
 
358
  num_inference_steps = gr.Slider(
359
- label="Number of inference steps",
360
  minimum=1,
361
  maximum=40,
362
  step=1,
363
- value=8,
364
- )
365
-
366
- height = gr.Slider(
367
- label="Height",
368
- minimum=256,
369
- maximum=2048,
370
- step=8,
371
- value=None,
372
- )
373
-
374
- width = gr.Slider(
375
- label="Width",
376
- minimum=256,
377
- maximum=2048,
378
- step=8,
379
- value=None,
380
  )
381
-
382
-
383
- rewrite_prompt = gr.Checkbox(label="Rewrite prompt", value=False)
384
 
385
- # gr.Examples(examples=examples, inputs=[prompt], outputs=[result, seed], fn=infer, cache_examples=False)
 
 
386
 
387
- gr.on(
388
- triggers=[run_button.click, prompt.submit],
389
- fn=infer,
390
  inputs=[
391
  input_images,
392
- prompt,
393
  seed,
394
  randomize_seed,
395
  true_guidance_scale,
396
  num_inference_steps,
397
- height,
398
- width,
399
- rewrite_prompt,
400
  ],
401
- outputs=[result, seed, use_output_btn], # Added use_output_btn to outputs
402
- )
403
-
404
- # Add the new event handler for the "Use Output as Input" button
405
- use_output_btn.click(
406
- fn=use_output_as_input,
407
- inputs=[result],
408
- outputs=[input_images]
409
  )
410
 
411
  if __name__ == "__main__":
 
3
  import random
4
  import torch
5
  import spaces
 
6
  from PIL import Image
7
  from diffusers import FlowMatchEulerDiscreteScheduler
8
  from optimization import optimize_pipeline_
9
  from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
10
  from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel
11
  from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
 
 
12
  import math
 
13
  import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  # --- Model Loading ---
16
  dtype = torch.bfloat16
 
42
  scheduler=scheduler,
43
  torch_dtype=dtype).to(device)
44
  pipe.load_lora_weights(
45
+ "2vXpSwA7/iroiro-lora",
46
+ weight_name="qwen_lora/Qwen-Image-Edit-2509-Lightning-4steps-V1.0-bf16_dim1.safetensors"
47
  )
48
  pipe.fuse_lora()
49
 
 
57
  # --- UI Constants and Helpers ---
58
  MAX_SEED = np.iinfo(np.int32).max
59
 
60
+ # 固定プロンプト定義
61
+ PROMPTS = {
62
+ "front": "Move the camera to a front-facing position so the full body of the character is visible. The character stands with both arms extended slightly downward and close to the thighs, keeping the body evenly balanced on both sides. Background is plain white.",
63
+ "back": "Move the camera to a back-facing position so the full body of the character is visible. The character stands with both arms extended slightly downward and close to the thighs, keeping the body evenly balanced on both sides. Background is plain white.",
64
+ "left": "Move the camera to a side view (profile) from the left so the full body of the character is visible. The character stands with both arms extended slightly downward and close to the thighs, keeping the body evenly balanced. Background is plain white.",
65
+ "right": "Move the camera to a side view (profile) from the right so the full body of the character is visible. The character stands with both arms extended slightly downward and close to the thighs, keeping the body evenly balanced. Background is plain white."
66
+ }
67
 
68
+ def generate_single_view(input_images, prompt, seed, num_inference_steps, true_guidance_scale):
69
+ """単一の視点の画像を生成"""
70
+ negative_prompt = " "
71
+ generator = torch.Generator(device=device).manual_seed(seed)
72
+
73
+ print(f"Generating with prompt: '{prompt}'")
74
+ print(f"Seed: {seed}, Steps: {num_inference_steps}, Guidance: {true_guidance_scale}")
75
+
76
+ # Generate the image
77
+ result = pipe(
78
+ image=input_images if input_images else None,
79
+ prompt=prompt,
80
+ height=None,
81
+ width=None,
82
+ negative_prompt=negative_prompt,
83
+ num_inference_steps=num_inference_steps,
84
+ generator=generator,
85
+ true_cfg_scale=true_guidance_scale,
86
+ num_images_per_prompt=1,
87
+ ).images
88
+
89
+ return result[0]
90
+
91
+ # --- Main Inference Function ---
92
  @spaces.GPU(duration=300)
93
+ def generate_turnaround(
94
  images,
 
95
  seed=42,
96
  randomize_seed=False,
97
  true_guidance_scale=1.0,
98
+ num_inference_steps=4,
 
 
 
 
99
  progress=gr.Progress(track_tqdm=True),
100
  ):
101
  """
102
+ 入力画像から4つの視点(正面、背面、左側面、右側面)の立ち絵を生成
103
  """
 
 
 
104
  if randomize_seed:
105
  seed = random.randint(0, MAX_SEED)
 
 
 
106
 
107
+ # 入力画像の読み込み
108
  pil_images = []
109
  if images is not None:
110
  for item in images:
 
117
  pil_images.append(Image.open(item.name).convert("RGB"))
118
  except Exception:
119
  continue
 
 
 
 
 
 
 
 
 
120
 
121
+ if not pil_images:
122
+ return [None, None, None, None], seed, "エラー: 入力画像をアップロードしてください"
123
+
124
+ results = []
125
+
126
+ # 1. 正面立ち絵を生成
127
+ progress(0.25, desc="正面立ち絵を生成中...")
128
+ front_image = generate_single_view(pil_images, PROMPTS["front"], seed, num_inference_steps, true_guidance_scale)
129
+ results.append(front_image)
130
+
131
+ # 2. 正面立ち絵を入力として背面を生成
132
+ progress(0.50, desc="背面立ち絵を生成中...")
133
+ back_image = generate_single_view([front_image], PROMPTS["back"], seed+1, num_inference_steps, true_guidance_scale)
134
+ results.append(back_image)
135
+
136
+ # 3. 正面立ち絵を入力として左側面を生成
137
+ progress(0.75, desc="左側面立ち絵を生成中...")
138
+ left_image = generate_single_view([front_image], PROMPTS["left"], seed+2, num_inference_steps, true_guidance_scale)
139
+ results.append(left_image)
140
+
141
+ # 4. 正面立ち絵を入力として右側面を生成
142
+ progress(1.0, desc="右側面立ち絵を生成中...")
143
+ right_image = generate_single_view([front_image], PROMPTS["right"], seed+3, num_inference_steps, true_guidance_scale)
144
+ results.append(right_image)
145
+
146
+ return results, seed, "✅ 4視点の立ち絵生成が完了しました"
147
 
148
+ # --- UI Layout ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  css = """
150
  #col-container {
151
  margin: 0 auto;
152
+ max-width: 1200px;
153
  }
154
+ .view-label {
155
  text-align: center;
156
+ font-weight: bold;
157
+ margin-top: 10px;
158
  }
 
 
 
 
159
  """
160
 
161
  with gr.Blocks(css=css) as demo:
162
+ gr.Markdown("# キャラクター4視点立ち絵自動生成")
163
+ gr.Markdown("キャラクター画像をアップロードすると、正面・背面・左側面・右側面の4つの立ち絵を自動生成します")
164
+
165
  with gr.Column(elem_id="col-container"):
166
+ with gr.Row():
167
+ input_images = gr.Gallery(
168
+ label="入力画像(キャラクター画像をアップロード)",
169
+ show_label=True,
170
+ type="pil",
171
+ interactive=True,
172
+ height=400
173
+ )
174
+
175
+ run_button = gr.Button("🎨 4視点立ち絵を生成", variant="primary", size="lg")
176
+
177
+ status_text = gr.Textbox(label="ステータス", interactive=False)
178
+
179
  with gr.Row():
180
  with gr.Column():
181
+ result_front = gr.Image(label="正面", type="pil", height=400)
 
 
 
 
182
  with gr.Column():
183
+ result_back = gr.Image(label="背面", type="pil", height=400)
184
+
 
 
185
  with gr.Row():
186
+ with gr.Column():
187
+ result_left = gr.Image(label="左側面", type="pil", height=400)
188
+ with gr.Column():
189
+ result_right = gr.Image(label="右側面", type="pil", height=400)
 
 
 
 
 
 
190
 
191
+ with gr.Accordion("⚙️ 詳細設定", open=False):
192
  seed = gr.Slider(
193
  label="Seed",
194
  minimum=0,
 
197
  value=0,
198
  )
199
 
200
+ randomize_seed = gr.Checkbox(label="ランダムシード", value=True)
201
 
202
  with gr.Row():
 
203
  true_guidance_scale = gr.Slider(
204
  label="True guidance scale",
205
  minimum=1.0,
 
209
  )
210
 
211
  num_inference_steps = gr.Slider(
212
+ label="生成ステップ数",
213
  minimum=1,
214
  maximum=40,
215
  step=1,
216
+ value=4,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  )
 
 
 
218
 
219
+ def update_results(results, seed, status):
220
+ """結果を個別の画像コンポーネントに分配"""
221
+ return results[0], results[1], results[2], results[3], seed, status
222
 
223
+ run_button.click(
224
+ fn=generate_turnaround,
 
225
  inputs=[
226
  input_images,
 
227
  seed,
228
  randomize_seed,
229
  true_guidance_scale,
230
  num_inference_steps,
 
 
 
231
  ],
232
+ outputs=[gr.State(), seed, status_text],
233
+ ).then(
234
+ fn=update_results,
235
+ inputs=[gr.State(), seed, status_text],
236
+ outputs=[result_front, result_back, result_left, result_right, seed, status_text]
 
 
 
237
  )
238
 
239
  if __name__ == "__main__":