ginipick commited on
Commit
e4ed2d7
Β·
verified Β·
1 Parent(s): 6b80e3c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +217 -128
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import os
2
  import gc
 
3
  import gradio as gr
4
  import numpy as np
5
  import torch
@@ -8,10 +9,14 @@ import spaces
8
  import config
9
  import utils
10
  import logging
11
- from PIL import Image, PngImagePlugin
12
  from datetime import datetime
 
 
13
  from diffusers.models import AutoencoderKL
14
  from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
 
 
15
  from config import (
16
  MODEL,
17
  MIN_IMAGE_SIZE,
@@ -26,8 +31,6 @@ from config import (
26
  aspect_ratios,
27
  style_list,
28
  )
29
- import time
30
- from typing import List, Dict, Tuple, Optional
31
 
32
  # Enhanced logging configuration
33
  logging.basicConfig(
@@ -50,10 +53,27 @@ torch.backends.cuda.matmul.allow_tf32 = True
50
  device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
51
  logger.info(f"Using device: {device}")
52
 
 
 
 
53
  class GenerationError(Exception):
54
  """Custom exception for generation errors"""
55
  pass
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  def validate_prompt(prompt: str) -> str:
58
  """Validate and clean up the input prompt."""
59
  if not isinstance(prompt, str):
@@ -69,6 +89,9 @@ def validate_prompt(prompt: str) -> str:
69
  # Only check if the prompt is completely empty or only whitespace
70
  if not prompt or prompt.isspace():
71
  raise GenerationError("Prompt cannot be empty")
 
 
 
72
  return prompt.strip()
73
 
74
  def validate_dimensions(width: int, height: int) -> None:
@@ -124,7 +147,7 @@ def generate(
124
 
125
  # Process prompts
126
  if add_quality_tags:
127
- prompt = "masterpiece, high score, great score, absurdres, {prompt}".format(prompt=prompt)
128
 
129
  prompt, negative_prompt = utils.preprocess_prompt(
130
  styles, style_selector, prompt, negative_prompt
@@ -257,121 +280,151 @@ else:
257
  # Process styles
258
  styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list}
259
 
260
- with gr.Blocks(css="style.css", theme="Nymbo/Nymbo_Theme_5") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  gr.HTML(
262
  """
263
  <div class="header">
264
  <div class="title">ANIM4GINE</div>
265
- <div class="subtitle">Gradio demo for <a href="https://huggingface.co/CagliostroLab/Animagine-XL-4.0" target="_blank">Animagine XL 4.0</a></div>
266
  </div>
267
- """,
268
  )
269
 
 
270
  with gr.Row():
271
- with gr.Column(scale=2):
272
- with gr.Group():
273
- prompt = gr.Text(
274
- label="Prompt",
275
- max_lines=5,
276
- placeholder="Describe what you want to generate",
277
- info="Enter your image generation prompt here. Be specific and descriptive for better results.",
278
- )
279
- negative_prompt = gr.Text(
280
- label="Negative Prompt",
281
- max_lines=5,
282
- placeholder="Describe what you want to avoid",
283
- value=DEFAULT_NEGATIVE_PROMPT,
284
- info="Specify elements you don't want in the image.",
285
- )
286
- add_quality_tags = gr.Checkbox(
287
- label="Quality Tags",
288
- value=True,
289
- info="Add quality-enhancing tags to your prompt automatically.",
290
- )
291
- with gr.Accordion(label="More Settings", open=False):
292
- with gr.Group():
293
- aspect_ratio_selector = gr.Radio(
294
- label="Aspect Ratio",
295
- choices=aspect_ratios,
296
- value=DEFAULT_ASPECT_RATIO,
297
- container=True,
298
- info="Choose the dimensions of your image.",
299
- )
300
- with gr.Group(visible=False) as custom_resolution:
301
- with gr.Row():
302
- custom_width = gr.Slider(
303
- label="Width",
304
- minimum=MIN_IMAGE_SIZE,
305
- maximum=MAX_IMAGE_SIZE,
306
- step=8,
307
- value=1024,
308
- info=f"Image width (must be between {MIN_IMAGE_SIZE} and {MAX_IMAGE_SIZE})",
309
- )
310
- custom_height = gr.Slider(
311
- label="Height",
312
- minimum=MIN_IMAGE_SIZE,
313
- maximum=MAX_IMAGE_SIZE,
314
- step=8,
315
- value=1024,
316
- info=f"Image height (must be between {MIN_IMAGE_SIZE} and {MAX_IMAGE_SIZE})",
317
- )
318
- with gr.Group():
319
- use_upscaler = gr.Checkbox(
320
- label="Use Upscaler",
321
- value=False,
322
- info="Enable high-resolution upscaling.",
323
- )
324
- with gr.Row() as upscaler_row:
325
- upscaler_strength = gr.Slider(
326
- label="Strength",
327
- minimum=0,
328
- maximum=1,
329
- step=0.05,
330
- value=0.55,
331
- visible=False,
332
- info="Control how much the upscaler affects the final image.",
333
- )
334
- upscale_by = gr.Slider(
335
- label="Upscale by",
336
- minimum=1,
337
- maximum=1.5,
338
- step=0.1,
339
- value=1.5,
340
- visible=False,
341
- info="Multiplier for the final image resolution.",
342
- )
343
- with gr.Accordion(label="Advanced Parameters", open=False):
344
- with gr.Group():
345
- style_selector = gr.Dropdown(
346
- label="Style Preset",
347
- interactive=True,
348
- choices=list(styles.keys()),
349
- value="(None)",
350
- info="Apply a predefined style to your generation.",
351
- )
352
  with gr.Group():
353
- sampler = gr.Dropdown(
354
- label="Sampler",
355
- choices=sampler_list,
356
- interactive=True,
357
- value="Euler a",
358
- info="Different samplers can produce varying results.",
359
  )
360
- with gr.Group():
361
- seed = gr.Slider(
362
- label="Seed",
363
- minimum=0,
364
- maximum=utils.MAX_SEED,
365
- step=1,
366
- value=0,
367
- info="Set a specific seed for reproducible results.",
368
  )
369
- randomize_seed = gr.Checkbox(
370
- label="Randomize seed",
371
  value=True,
372
- info="Generate a new random seed for each image.",
373
  )
374
- with gr.Group():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  with gr.Row():
376
  guidance_scale = gr.Slider(
377
  label="Guidance scale",
@@ -382,48 +435,84 @@ with gr.Blocks(css="style.css", theme="Nymbo/Nymbo_Theme_5") as demo:
382
  info="Higher values make the image more closely match your prompt.",
383
  )
384
  num_inference_steps = gr.Slider(
385
- label="Number of inference steps",
386
  minimum=1,
387
  maximum=50,
388
  step=1,
389
  value=25,
390
- info="More steps generally mean higher quality but slower generation.",
391
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
 
393
- with gr.Column(scale=3):
394
- with gr.Blocks():
395
- run_button = gr.Button("Generate", variant="primary", elem_id="generate-button")
396
  result = gr.Gallery(
397
  label="Generated Images",
398
- columns=1,
399
- height='768px',
400
- preview=True,
401
  show_label=True,
 
402
  )
403
  with gr.Accordion(label="Generation Parameters", open=False):
404
  gr_metadata = gr.JSON(
405
  label="Image Metadata",
406
  show_label=True,
407
  )
408
- gr.Examples(
409
- examples=examples,
410
- inputs=prompt,
411
- outputs=[result, gr_metadata],
412
- fn=lambda *args, **kwargs: generate(*args, use_upscaler=True, **kwargs),
413
- cache_examples=CACHE_EXAMPLES,
414
- )
415
 
416
- # Discord button in a new full row
417
  with gr.Row():
418
  gr.HTML(
419
  """
420
- <a href="https://discord.com/invite/cqh9tZgbGc" target="_blank" class="discord-btn">
421
- <svg class="discord-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><path fill="currentColor" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></svg>
422
- <span class="discord-text">Join our Discord Server</span>
423
- </a>
 
 
 
 
424
  """
425
  )
426
-
 
427
  use_upscaler.change(
428
  fn=lambda x: [gr.update(visible=x), gr.update(visible=x)],
429
  inputs=use_upscaler,
@@ -439,7 +528,7 @@ with gr.Blocks(css="style.css", theme="Nymbo/Nymbo_Theme_5") as demo:
439
  api_name=False,
440
  )
441
 
442
- # Combine all triggers including keyboard shortcuts
443
  gr.on(
444
  triggers=[
445
  prompt.submit,
 
1
  import os
2
  import gc
3
+ import re
4
  import gradio as gr
5
  import numpy as np
6
  import torch
 
9
  import config
10
  import utils
11
  import logging
12
+ import time
13
  from datetime import datetime
14
+ from typing import List, Dict, Tuple, Optional
15
+ from PIL import Image, PngImagePlugin
16
  from diffusers.models import AutoencoderKL
17
  from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
18
+ from transformers import pipeline as translation_pipeline
19
+
20
  from config import (
21
  MODEL,
22
  MIN_IMAGE_SIZE,
 
31
  aspect_ratios,
32
  style_list,
33
  )
 
 
34
 
35
  # Enhanced logging configuration
36
  logging.basicConfig(
 
53
  device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
54
  logger.info(f"Using device: {device}")
55
 
56
+ # λ²ˆμ—­ νŒŒμ΄ν”„λΌμΈ μ΄ˆκΈ°ν™” (ν•œκΈ€ β†’ μ˜μ–΄)
57
+ translator = translation_pipeline("translation", model="Helsinki-NLP/opus-mt-ko-en")
58
+
59
  class GenerationError(Exception):
60
  """Custom exception for generation errors"""
61
  pass
62
 
63
+ def translate_if_korean(prompt: str) -> str:
64
+ """ν”„λ‘¬ν”„νŠΈμ— ν•œκΈ€μ΄ ν¬ν•¨λ˜μ–΄ 있으면 μ˜μ–΄λ‘œ λ²ˆμ—­"""
65
+ if re.search(r'[γ„±-γ…Žγ…-γ…£κ°€-힣]', prompt):
66
+ logger.info("Korean detected in prompt. Translating to English...")
67
+ try:
68
+ translation = translator(prompt)[0]['translation_text']
69
+ logger.info(f"Translation result: {translation}")
70
+ return translation
71
+ except Exception as e:
72
+ logger.error(f"Translation error: {e}")
73
+ # λ²ˆμ—­ μ‹€νŒ¨ μ‹œ 원본 ν”„λ‘¬ν”„νŠΈ μ‚¬μš©
74
+ return prompt
75
+ return prompt
76
+
77
  def validate_prompt(prompt: str) -> str:
78
  """Validate and clean up the input prompt."""
79
  if not isinstance(prompt, str):
 
89
  # Only check if the prompt is completely empty or only whitespace
90
  if not prompt or prompt.isspace():
91
  raise GenerationError("Prompt cannot be empty")
92
+
93
+ # λ²ˆμ—­ 적용: ν•œκΈ€μ΄ κ°μ§€λ˜λ©΄ μ˜μ–΄λ‘œ λ³€ν™˜
94
+ prompt = translate_if_korean(prompt)
95
  return prompt.strip()
96
 
97
  def validate_dimensions(width: int, height: int) -> None:
 
147
 
148
  # Process prompts
149
  if add_quality_tags:
150
+ prompt = f"masterpiece, high score, great score, absurdres, {prompt}"
151
 
152
  prompt, negative_prompt = utils.preprocess_prompt(
153
  styles, style_selector, prompt, negative_prompt
 
280
  # Process styles
281
  styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list}
282
 
283
+ # μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€ (UI) κ°œμ„ : CSS μŠ€νƒ€μΌ 및 λ ˆμ΄μ•„μ›ƒ μˆ˜μ •
284
+ custom_css = """
285
+ /* λ°°κ²½ 및 κΈ€μž 색상 λ³€κ²½ */
286
+ body {
287
+ background-color: #f7f9fc;
288
+ color: #333;
289
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
290
+ }
291
+
292
+ /* 헀더 μŠ€νƒ€μΌ */
293
+ .header {
294
+ text-align: center;
295
+ padding: 20px;
296
+ }
297
+ .header .title {
298
+ font-size: 3em;
299
+ font-weight: bold;
300
+ color: #2c3e50;
301
+ }
302
+ .header .subtitle {
303
+ font-size: 1.2em;
304
+ color: #7f8c8d;
305
+ }
306
+ a {
307
+ text-decoration: none;
308
+ color: #3498db;
309
+ }
310
+
311
+ /* Discord λ²„νŠΌ μŠ€νƒ€μΌ */
312
+ .discord-btn {
313
+ display: flex;
314
+ align-items: center;
315
+ justify-content: center;
316
+ padding: 10px 20px;
317
+ background: #7289da;
318
+ color: white;
319
+ border-radius: 8px;
320
+ font-weight: bold;
321
+ margin-top: 20px;
322
+ }
323
+ .discord-btn:hover {
324
+ background: #5b6eae;
325
+ }
326
+ .discord-icon {
327
+ width: 24px;
328
+ height: 24px;
329
+ margin-right: 8px;
330
+ }
331
+
332
+ /* Gradio 가러리 μŠ€νƒ€μΌ κ°œμ„  */
333
+ .gradio-gallery {
334
+ border: none;
335
+ box-shadow: none;
336
+ }
337
+ """
338
+
339
+ with gr.Blocks(css=custom_css, theme="default") as demo:
340
+ # 상단 헀더
341
  gr.HTML(
342
  """
343
  <div class="header">
344
  <div class="title">ANIM4GINE</div>
345
+ <div class="subtitle">A sleek and intuitive demo for <a href="https://huggingface.co/CagliostroLab/Animagine-XL-4.0" target="_blank">Animagine XL 4.0</a></div>
346
  </div>
347
+ """
348
  )
349
 
350
+ # μ’ŒμΈ‘μ— μž…λ ₯ 및 μ„€μ •, μš°μΈ‘μ— κ²°κ³Ό 좜λ ₯ 배치
351
  with gr.Row():
352
+ with gr.Column(scale=3):
353
+ with gr.Tabs():
354
+ with gr.TabItem("Generate"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  with gr.Group():
356
+ prompt = gr.Textbox(
357
+ label="Prompt",
358
+ lines=4,
359
+ placeholder="Describe what you want to generate...",
360
+ info="Enter your image generation prompt here. ν•œκΈ€ μž…λ ₯ μ‹œ μžλ™μœΌλ‘œ μ˜μ–΄λ‘œ λ²ˆμ—­λ©λ‹ˆλ‹€.",
 
361
  )
362
+ negative_prompt = gr.Textbox(
363
+ label="Negative Prompt",
364
+ lines=4,
365
+ placeholder="Describe what you want to avoid",
366
+ value=DEFAULT_NEGATIVE_PROMPT,
367
+ info="Specify elements you don't want in the image.",
 
 
368
  )
369
+ add_quality_tags = gr.Checkbox(
370
+ label="Quality Tags",
371
  value=True,
372
+ info="Automatically add quality-enhancing tags to your prompt.",
373
  )
374
+ with gr.Accordion(label="More Settings", open=False):
375
+ with gr.Column():
376
+ aspect_ratio_selector = gr.Radio(
377
+ label="Aspect Ratio",
378
+ choices=aspect_ratios,
379
+ value=DEFAULT_ASPECT_RATIO,
380
+ container=True,
381
+ info="Choose the dimensions of your image.",
382
+ )
383
+ with gr.Row(visible=False) as custom_resolution:
384
+ custom_width = gr.Slider(
385
+ label="Width",
386
+ minimum=MIN_IMAGE_SIZE,
387
+ maximum=MAX_IMAGE_SIZE,
388
+ step=8,
389
+ value=1024,
390
+ info=f"Image width (between {MIN_IMAGE_SIZE} and {MAX_IMAGE_SIZE})",
391
+ )
392
+ custom_height = gr.Slider(
393
+ label="Height",
394
+ minimum=MIN_IMAGE_SIZE,
395
+ maximum=MAX_IMAGE_SIZE,
396
+ step=8,
397
+ value=1024,
398
+ info=f"Image height (between {MIN_IMAGE_SIZE} and {MAX_IMAGE_SIZE})",
399
+ )
400
+ with gr.Accordion(label="Advanced Parameters", open=False):
401
+ with gr.Row():
402
+ style_selector = gr.Dropdown(
403
+ label="Style Preset",
404
+ choices=list(styles.keys()),
405
+ value="(None)",
406
+ info="Apply a predefined style to your generation.",
407
+ )
408
+ sampler = gr.Dropdown(
409
+ label="Sampler",
410
+ choices=sampler_list,
411
+ value="Euler a",
412
+ info="Different samplers can produce varying results.",
413
+ )
414
+ with gr.Row():
415
+ seed = gr.Slider(
416
+ label="Seed",
417
+ minimum=0,
418
+ maximum=utils.MAX_SEED,
419
+ step=1,
420
+ value=0,
421
+ info="Set a specific seed for reproducible results.",
422
+ )
423
+ randomize_seed = gr.Checkbox(
424
+ label="Randomize seed",
425
+ value=True,
426
+ info="Generate a new random seed for each image.",
427
+ )
428
  with gr.Row():
429
  guidance_scale = gr.Slider(
430
  label="Guidance scale",
 
435
  info="Higher values make the image more closely match your prompt.",
436
  )
437
  num_inference_steps = gr.Slider(
438
+ label="Inference steps",
439
  minimum=1,
440
  maximum=50,
441
  step=1,
442
  value=25,
443
+ info="More steps generally yield higher quality images.",
444
  )
445
+ with gr.Row():
446
+ use_upscaler = gr.Checkbox(
447
+ label="Use Upscaler",
448
+ value=False,
449
+ info="Enable high-resolution upscaling.",
450
+ )
451
+ upscaler_strength = gr.Slider(
452
+ label="Upscaler Strength",
453
+ minimum=0,
454
+ maximum=1,
455
+ step=0.05,
456
+ value=0.55,
457
+ visible=False,
458
+ info="Control how strongly the upscaler affects the image.",
459
+ )
460
+ upscale_by = gr.Slider(
461
+ label="Upscale By",
462
+ minimum=1,
463
+ maximum=1.5,
464
+ step=0.1,
465
+ value=1.5,
466
+ visible=False,
467
+ info="Multiplier for the final image resolution.",
468
+ )
469
+ with gr.TabItem("Examples"):
470
+ gr.Markdown(
471
+ """
472
+ ### Example Prompts
473
+ - **Scenic Landscape:** A breathtaking view of a mountain landscape during sunrise.
474
+ - **Cyberpunk City:** A futuristic cyberpunk city with neon lights and towering skyscrapers.
475
+ - **Fantasy Character:** A majestic wizard with a long beard and glowing magical staff.
476
+ """
477
+ )
478
+ gr.Examples(
479
+ examples=examples,
480
+ inputs=prompt,
481
+ outputs=[],
482
+ cache_examples=CACHE_EXAMPLES,
483
+ )
484
+ run_button = gr.Button("Generate", variant="primary", elem_id="generate-button")
485
 
486
+ with gr.Column(scale=4):
 
 
487
  result = gr.Gallery(
488
  label="Generated Images",
489
+ columns=2,
490
+ height="600px",
 
491
  show_label=True,
492
+ elem_classes="gradio-gallery",
493
  )
494
  with gr.Accordion(label="Generation Parameters", open=False):
495
  gr_metadata = gr.JSON(
496
  label="Image Metadata",
497
  show_label=True,
498
  )
 
 
 
 
 
 
 
499
 
500
+ # Discord λ²„νŠΌμ„ ν•˜λ‹¨ 쀑앙에 배치
501
  with gr.Row():
502
  gr.HTML(
503
  """
504
+ <div style="width:100%; display:flex; justify-content:center;">
505
+ <a href="https://discord.com/invite/cqh9tZgbGc" target="_blank" class="discord-btn">
506
+ <svg class="discord-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36">
507
+ <path fill="currentColor" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/>
508
+ </svg>
509
+ <span class="discord-text">Join our Discord Server</span>
510
+ </a>
511
+ </div>
512
  """
513
  )
514
+
515
+ # UI 동적 μ—…λ°μ΄νŠΈ: μ—…μŠ€μΌ€μΌλŸ¬ μ˜΅μ…˜ 및 μ»€μŠ€ν…€ 해상도 μŠ¬λΌμ΄λ” ν‘œμ‹œ μ œμ–΄
516
  use_upscaler.change(
517
  fn=lambda x: [gr.update(visible=x), gr.update(visible=x)],
518
  inputs=use_upscaler,
 
528
  api_name=False,
529
  )
530
 
531
+ # 트리거 μ„€μ •: ν”„λ‘¬ν”„νŠΈ μž…λ ₯, λ²„νŠΌ 클릭 μ‹œ μ‹œλ“œ λžœλ€ν™” ν›„ 이미지 생성 μ‹€ν–‰
532
  gr.on(
533
  triggers=[
534
  prompt.submit,