ginipick commited on
Commit
8c89a89
โ€ข
1 Parent(s): 27e8bc2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -178
app.py CHANGED
@@ -13,35 +13,54 @@ torch.backends.cuda.matmul.allow_tf32 = True
13
  # ๋ฒˆ์—ญ ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
14
  translator = pipeline("translation", model="Helsinki-NLP/opus-mt-ko-en")
15
 
 
16
  base_model = "black-forest-labs/FLUX.1-dev"
17
- pipe = DiffusionPipeline.from_pretrained(base_model, torch_dtype=torch.bfloat16)
18
-
19
- lora_repo = "prithivMLmods/Canopus-Clothing-Flux-LoRA"
20
- trigger_word = ""
21
- pipe.load_lora_weights(lora_repo)
22
 
 
23
  pipe.to("cuda")
24
 
25
  MAX_SEED = 2**32-1
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  @spaces.GPU()
28
- def translate_and_generate(prompt, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale, progress=gr.Progress(track_tqdm=True)):
29
  # ํ•œ๊ธ€ ๊ฐ์ง€ ๋ฐ ๋ฒˆ์—ญ
30
  def contains_korean(text):
31
  return any(ord('๊ฐ€') <= ord(char) <= ord('ํžฃ') for char in text)
32
 
33
  if contains_korean(prompt):
34
- # ํ•œ๊ธ€์„ ์˜์–ด๋กœ ๋ฒˆ์—ญ
35
  translated = translator(prompt)[0]['translation_text']
36
  actual_prompt = translated
37
  else:
38
  actual_prompt = prompt
39
 
 
 
 
 
 
 
 
 
40
  if randomize_seed:
41
  seed = random.randint(0, MAX_SEED)
42
  generator = torch.Generator(device="cuda").manual_seed(seed)
43
 
44
- progress(0, "Starting image generation...")
45
 
46
  for i in range(1, steps + 1):
47
  if i % (steps // 10) == 0:
@@ -60,59 +79,44 @@ def translate_and_generate(prompt, cfg_scale, steps, randomize_seed, seed, width
60
  progress(100, "Completed!")
61
  return image, seed
62
 
63
- example_image_path = "example0.webp"
64
- example_prompt = """Cozy winter scene with a Christmas atmosphere: a snow-covered cabin in the forest, warm light glowing from the windows, surrounded by sparkling Christmas decorations and a beautifully adorned Christmas tree. The sky is filled with stars, and soft snowflakes are gently falling, creating a serene and warm ambiance"""
65
- example_cfg_scale = 3.2
66
- example_steps = 32
67
- example_width = 1152
68
- example_height = 896
69
- example_seed = 3981632454
70
- example_lora_scale = 0.85
71
-
72
- def load_example():
73
- example_image = Image.open(example_image_path)
74
- return example_prompt, example_cfg_scale, example_steps, True, example_seed, example_width, example_height, example_lora_scale, example_image
75
-
76
-
77
  # CSS ์ •์˜
78
  custom_css = """
79
- /* ๊ธฐ๋ณธ ์Šคํƒ€์ผ */
80
  body {
81
- margin: 0;
82
- padding: 0;
83
- background: url('file/example0.webp') no-repeat center center fixed;
84
- background-size: cover;
85
- min-height: 100vh;
86
  }
87
 
88
- /* ์ปจํ…Œ์ด๋„ˆ */
89
  .container {
90
  max-width: 1200px;
91
  margin: 0 auto;
92
  padding: 20px;
93
- box-sizing: border-box;
94
  }
95
 
96
- /* ํ—ค๋” */
97
  .header {
98
  text-align: center;
99
- color: white;
100
- text-shadow: 2px 2px 4px rgba(0,0,0,0.7);
101
  margin-bottom: 30px;
102
  font-size: 2.5em;
 
 
103
  }
104
 
105
- /* ๋ฐ•์Šค ๊ณตํ†ต ์Šคํƒ€์ผ */
106
  .box-common {
107
- background-color: rgba(255, 255, 255, 0.85);
108
- backdrop-filter: blur(10px);
109
  border-radius: 15px;
110
- padding: 20px;
111
  margin: 20px 0;
112
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
113
  }
114
 
115
- /* ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€ ๋ฐ•์Šค */
 
 
 
 
 
 
 
116
  .result-box {
117
  width: 90%;
118
  max-width: 1000px;
@@ -126,162 +130,99 @@ body {
126
  display: block;
127
  }
128
 
129
- /* ํ”„๋กฌํ”„ํŠธ ์ž…๋ ฅ ๋ฐ•์Šค */
130
  .prompt-box {
131
  width: 90%;
132
  max-width: 1000px;
133
  margin: 20px auto;
134
  }
135
 
136
- /* ๋ฒ„ํŠผ ์Šคํƒ€์ผ */
137
  .generate-btn {
138
- background-color: #2ecc71 !important;
139
  color: white !important;
140
- padding: 12px 30px !important;
141
  border-radius: 8px !important;
142
  border: none !important;
143
  font-size: 1.1em !important;
144
  cursor: pointer !important;
145
- transition: background-color 0.3s ease !important;
146
- width: 200px !important;
147
  margin: 20px auto !important;
148
  display: block !important;
 
 
149
  }
150
 
151
  .generate-btn:hover {
152
- background-color: #27ae60 !important;
 
 
153
  }
154
 
155
- /* ์•„์ฝ”๋””์–ธ ์Šคํƒ€์ผ */
156
  .accordion {
157
  width: 90%;
158
  max-width: 1000px;
159
  margin: 20px auto;
160
  }
161
 
162
- /* ์˜ค๋””์˜ค ์ปจํŠธ๋กค */
163
- .audio-controls {
164
- position: fixed;
165
- bottom: 20px;
166
- right: 20px;
167
- z-index: 1000;
168
- display: flex;
169
- gap: 10px;
170
- background-color: rgba(255, 255, 255, 0.9);
171
  padding: 15px;
172
- border-radius: 10px;
173
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
174
- }
175
-
176
- .audio-btn {
177
- background-color: #3498db;
178
- color: white;
179
- border: none;
180
- padding: 8px 15px;
181
- border-radius: 5px;
182
- cursor: pointer;
183
- transition: background-color 0.3s ease;
184
- }
185
-
186
- .audio-btn:hover {
187
- background-color: #2980b9;
188
- }
189
-
190
- /* ๋ˆˆ ๋‚ด๋ฆฌ๋Š” ํšจ๊ณผ */
191
- @keyframes snowfall {
192
- 0% {
193
- transform: translateY(-10vh) translateX(0);
194
- opacity: 1;
195
- }
196
- 100% {
197
- transform: translateY(100vh) translateX(100px);
198
- opacity: 0.3;
199
- }
200
  }
201
 
202
- .snowflake {
203
- position: fixed;
204
- color: white;
205
- font-size: 1.5em;
206
- user-select: none;
207
- z-index: 1000;
208
- pointer-events: none;
209
- animation: snowfall linear infinite;
210
- }
211
- """
212
-
213
- # JavaScript ์ฝ”๋“œ
214
- snow_js = """
215
- function createSnowflake() {
216
- const snowflake = document.createElement('div');
217
- snowflake.innerHTML = 'โ„';
218
- snowflake.className = 'snowflake';
219
- snowflake.style.left = Math.random() * 100 + 'vw';
220
- snowflake.style.animationDuration = Math.random() * 3 + 2 + 's';
221
- snowflake.style.opacity = Math.random();
222
- document.body.appendChild(snowflake);
223
-
224
- setTimeout(() => {
225
- snowflake.remove();
226
- }, 5000);
227
- }
228
-
229
- setInterval(createSnowflake, 200);
230
- """
231
-
232
- audio_js = """
233
- let currentlyPlaying = null;
234
-
235
- function toggleAudio(num) {
236
- const audio = document.getElementById('bgMusic' + num);
237
- const otherAudio = document.getElementById('bgMusic' + (num === 1 ? 2 : 1));
238
-
239
- if (currentlyPlaying === audio) {
240
- audio.pause();
241
- currentlyPlaying = null;
242
- } else {
243
- if (currentlyPlaying) {
244
- currentlyPlaying.pause();
245
- }
246
- otherAudio.pause();
247
- audio.play();
248
- currentlyPlaying = audio;
249
- }
250
- }
251
-
252
- function stopAllAudio() {
253
- const audios = document.querySelectorAll('audio');
254
- audios.forEach(audio => audio.pause());
255
- currentlyPlaying = null;
256
  }
257
  """
258
 
259
  # Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
260
- app = gr.Blocks(css=custom_css,theme="Yntec/HaleyCH_Theme_Orange")
261
-
262
- with app:
263
- # JavaScript ์ดˆ๊ธฐํ™”
264
- gr.HTML(f"<script>{snow_js}</script>")
265
-
266
  with gr.Column(elem_classes="container"):
267
- gr.Markdown("# ๐ŸŽ„ X-MAS LoRA", elem_classes="header")
 
 
 
 
 
 
 
 
268
 
269
  # ์ด๋ฏธ์ง€ ์ถœ๋ ฅ ์˜์—ญ
270
  with gr.Group(elem_classes="result-box box-common"):
271
- gr.Markdown("### ๐Ÿ–ผ๏ธ Generated Image")
272
  result = gr.Image(label="Result", elem_classes="image-output")
273
 
274
  # ํ”„๋กฌํ”„ํŠธ ์ž…๋ ฅ ์˜์—ญ
275
  with gr.Group(elem_classes="prompt-box box-common"):
276
  prompt = gr.TextArea(
277
- label="โœ๏ธ Your Prompt (ํ•œ๊ธ€ ๋˜๋Š” ์˜์–ด)",
278
- placeholder="์ด๋ฏธ์ง€๋ฅผ ์„ค๋ช…ํ•˜์„ธ์š”...",
279
  lines=5
280
  )
281
  generate_button = gr.Button(
282
- "๐Ÿš€ Generate Image",
283
  elem_classes="generate-btn"
284
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
 
286
  # ๊ณ ๊ธ‰ ์˜ต์…˜
287
  with gr.Accordion("๐ŸŽจ Advanced Options", open=False, elem_classes="accordion box-common"):
@@ -294,21 +235,21 @@ with app:
294
  minimum=1,
295
  maximum=20,
296
  step=0.5,
297
- value=example_cfg_scale
298
  )
299
  steps = gr.Slider(
300
  label="Steps",
301
  minimum=1,
302
  maximum=100,
303
  step=1,
304
- value=example_steps
305
  )
306
  lora_scale = gr.Slider(
307
  label="LoRA Scale",
308
  minimum=0,
309
  maximum=1,
310
  step=0.01,
311
- value=example_lora_scale
312
  )
313
 
314
  with gr.Group(elem_classes="parameter-box"):
@@ -319,14 +260,14 @@ with app:
319
  minimum=256,
320
  maximum=1536,
321
  step=64,
322
- value=example_width
323
  )
324
  height = gr.Slider(
325
  label="Height",
326
  minimum=256,
327
  maximum=1536,
328
  step=64,
329
- value=example_height
330
  )
331
 
332
  with gr.Group(elem_classes="parameter-box"):
@@ -341,35 +282,13 @@ with app:
341
  minimum=0,
342
  maximum=MAX_SEED,
343
  step=1,
344
- value=example_seed
345
  )
346
 
347
- # ์˜ค๋””์˜ค ์ปจํŠธ๋กค
348
- gr.HTML(f"""
349
- <div class="audio-controls">
350
- <button class="audio-btn" onclick="toggleAudio(1)">๐ŸŽต Music 1</button>
351
- <button class="audio-btn" onclick="toggleAudio(2)">๐ŸŽต Music 2</button>
352
- <button class="audio-btn" onclick="stopAllAudio()">โน Stop</button>
353
- </div>
354
- <audio id="bgMusic1" loop>
355
- <source src="file/1.mp3" type="audio/mp3">
356
- </audio>
357
- <audio id="bgMusic2" loop>
358
- <source src="file/2.mp3" type="audio/mp3">
359
- </audio>
360
- <script>{audio_js}</script>
361
- """)
362
-
363
  # ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
364
- app.load(
365
- load_example,
366
- inputs=[],
367
- outputs=[prompt, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale, result]
368
- )
369
-
370
  generate_button.click(
371
- translate_and_generate,
372
- inputs=[prompt, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale],
373
  outputs=[result, seed]
374
  )
375
 
 
13
  # ๋ฒˆ์—ญ ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
14
  translator = pipeline("translation", model="Helsinki-NLP/opus-mt-ko-en")
15
 
16
+ # ๊ธฐ๋ณธ ๋ชจ๋ธ ๋ฐ LoRA ์„ค์ •
17
  base_model = "black-forest-labs/FLUX.1-dev"
18
+ model_lora_repo = "Motas/Flux_Fashion_Photography_Style" # ํŒจ์…˜ ๋ชจ๋ธ LoRA
19
+ clothes_lora_repo = "prithivMLmods/Canopus-Clothing-Flux-LoRA" # ์˜๋ฅ˜ LoRA
 
 
 
20
 
21
+ pipe = DiffusionPipeline.from_pretrained(base_model, torch_dtype=torch.bfloat16)
22
  pipe.to("cuda")
23
 
24
  MAX_SEED = 2**32-1
25
 
26
+ # ์˜ˆ์ œ ์„ค์ •
27
+ example_model_prompts = [
28
+ "professional fashion model, full body shot, standing pose, natural lighting, studio background, high fashion, elegant pose",
29
+ "fashion model portrait, upper body, confident pose, fashion photography, neutral background, professional lighting",
30
+ "stylish fashion model, three-quarter view, editorial pose, high-end fashion magazine style, minimal background"
31
+ ]
32
+
33
+ example_clothes_prompts = [
34
+ "luxury designer sweater, cashmere material, cream color, cable knit pattern, high-end fashion, product photography",
35
+ "elegant business blazer, tailored fit, charcoal grey, premium wool fabric, professional wear",
36
+ "modern streetwear hoodie, oversized fit, minimalist design, premium cotton, urban style"
37
+ ]
38
+
39
  @spaces.GPU()
40
+ def generate_fashion(prompt, mode, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale, progress=gr.Progress(track_tqdm=True)):
41
  # ํ•œ๊ธ€ ๊ฐ์ง€ ๋ฐ ๋ฒˆ์—ญ
42
  def contains_korean(text):
43
  return any(ord('๊ฐ€') <= ord(char) <= ord('ํžฃ') for char in text)
44
 
45
  if contains_korean(prompt):
 
46
  translated = translator(prompt)[0]['translation_text']
47
  actual_prompt = translated
48
  else:
49
  actual_prompt = prompt
50
 
51
+ # ๋ชจ๋“œ์— ๋”ฐ๋ฅธ LoRA ๋ฐ ํŠธ๋ฆฌ๊ฑฐ์›Œ๋“œ ์„ค์ •
52
+ if mode == "Generate Model":
53
+ pipe.load_lora_weights(model_lora_repo)
54
+ trigger_word = "fashion photography, professional model"
55
+ else:
56
+ pipe.load_lora_weights(clothes_lora_repo)
57
+ trigger_word = "upper clothing, fashion item"
58
+
59
  if randomize_seed:
60
  seed = random.randint(0, MAX_SEED)
61
  generator = torch.Generator(device="cuda").manual_seed(seed)
62
 
63
+ progress(0, "Starting fashion generation...")
64
 
65
  for i in range(1, steps + 1):
66
  if i % (steps // 10) == 0:
 
79
  progress(100, "Completed!")
80
  return image, seed
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  # CSS ์ •์˜
83
  custom_css = """
 
84
  body {
85
+ background-color: #f5f5f5;
86
+ font-family: 'Arial', sans-serif;
 
 
 
87
  }
88
 
 
89
  .container {
90
  max-width: 1200px;
91
  margin: 0 auto;
92
  padding: 20px;
 
93
  }
94
 
 
95
  .header {
96
  text-align: center;
97
+ color: #333;
 
98
  margin-bottom: 30px;
99
  font-size: 2.5em;
100
+ text-transform: uppercase;
101
+ letter-spacing: 2px;
102
  }
103
 
 
104
  .box-common {
105
+ background-color: white;
 
106
  border-radius: 15px;
107
+ padding: 25px;
108
  margin: 20px 0;
109
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
110
  }
111
 
112
+ .mode-box {
113
+ background-color: #fff;
114
+ padding: 20px;
115
+ border-radius: 10px;
116
+ margin-bottom: 20px;
117
+ border: 2px solid #eee;
118
+ }
119
+
120
  .result-box {
121
  width: 90%;
122
  max-width: 1000px;
 
130
  display: block;
131
  }
132
 
 
133
  .prompt-box {
134
  width: 90%;
135
  max-width: 1000px;
136
  margin: 20px auto;
137
  }
138
 
 
139
  .generate-btn {
140
+ background: linear-gradient(45deg, #ff6b6b, #ff8e8e) !important;
141
  color: white !important;
142
+ padding: 15px 30px !important;
143
  border-radius: 8px !important;
144
  border: none !important;
145
  font-size: 1.1em !important;
146
  cursor: pointer !important;
147
+ transition: all 0.3s ease !important;
148
+ width: 250px !important;
149
  margin: 20px auto !important;
150
  display: block !important;
151
+ text-transform: uppercase !important;
152
+ letter-spacing: 1px !important;
153
  }
154
 
155
  .generate-btn:hover {
156
+ background: linear-gradient(45deg, #ff8e8e, #ff6b6b) !important;
157
+ transform: translateY(-2px) !important;
158
+ box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4) !important;
159
  }
160
 
 
161
  .accordion {
162
  width: 90%;
163
  max-width: 1000px;
164
  margin: 20px auto;
165
  }
166
 
167
+ .examples-table {
168
+ background-color: rgba(255, 255, 255, 0.95);
169
+ border-radius: 8px;
 
 
 
 
 
 
170
  padding: 15px;
171
+ margin-top: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  }
173
 
174
+ .parameter-box {
175
+ background-color: #f8f9fa;
176
+ padding: 20px;
177
+ border-radius: 8px;
178
+ margin: 10px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
180
  """
181
 
182
  # Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
183
+ with gr.Blocks(css=custom_css, theme="Yntec/HaleyCH_Theme_Orange") as app:
 
 
 
 
 
184
  with gr.Column(elem_classes="container"):
185
+ gr.Markdown("# ๐ŸŽญ Fashion Generation Studio", elem_classes="header")
186
+
187
+ # ๋ชจ๋“œ ์„ ํƒ
188
+ with gr.Group(elem_classes="mode-box box-common"):
189
+ mode = gr.Radio(
190
+ choices=["Generate Model", "Generate Clothes"],
191
+ label="Generation Mode",
192
+ value="Generate Model"
193
+ )
194
 
195
  # ์ด๋ฏธ์ง€ ์ถœ๋ ฅ ์˜์—ญ
196
  with gr.Group(elem_classes="result-box box-common"):
197
+ gr.Markdown("### ๐Ÿ–ผ๏ธ Generated Fashion")
198
  result = gr.Image(label="Result", elem_classes="image-output")
199
 
200
  # ํ”„๋กฌํ”„ํŠธ ์ž…๋ ฅ ์˜์—ญ
201
  with gr.Group(elem_classes="prompt-box box-common"):
202
  prompt = gr.TextArea(
203
+ label="โœ๏ธ Fashion Description (ํ•œ๊ธ€ ๋˜๋Š” ์˜์–ด)",
204
+ placeholder="ํŒจ์…˜ ๋ชจ๋ธ์ด๋‚˜ ์˜๋ฅ˜๋ฅผ ์„ค๋ช…ํ•˜์„ธ์š”...",
205
  lines=5
206
  )
207
  generate_button = gr.Button(
208
+ "๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ Generate Fashion",
209
  elem_classes="generate-btn"
210
  )
211
+
212
+ # ์˜ˆ์ œ ํƒญ
213
+ with gr.Tabs():
214
+ with gr.TabItem("Model Examples"):
215
+ gr.Examples(
216
+ examples=example_model_prompts,
217
+ inputs=prompt,
218
+ label="Model Prompts"
219
+ )
220
+ with gr.TabItem("Clothes Examples"):
221
+ gr.Examples(
222
+ examples=example_clothes_prompts,
223
+ inputs=prompt,
224
+ label="Clothes Prompts"
225
+ )
226
 
227
  # ๊ณ ๊ธ‰ ์˜ต์…˜
228
  with gr.Accordion("๐ŸŽจ Advanced Options", open=False, elem_classes="accordion box-common"):
 
235
  minimum=1,
236
  maximum=20,
237
  step=0.5,
238
+ value=7.0
239
  )
240
  steps = gr.Slider(
241
  label="Steps",
242
  minimum=1,
243
  maximum=100,
244
  step=1,
245
+ value=30
246
  )
247
  lora_scale = gr.Slider(
248
  label="LoRA Scale",
249
  minimum=0,
250
  maximum=1,
251
  step=0.01,
252
+ value=0.85
253
  )
254
 
255
  with gr.Group(elem_classes="parameter-box"):
 
260
  minimum=256,
261
  maximum=1536,
262
  step=64,
263
+ value=512
264
  )
265
  height = gr.Slider(
266
  label="Height",
267
  minimum=256,
268
  maximum=1536,
269
  step=64,
270
+ value=768
271
  )
272
 
273
  with gr.Group(elem_classes="parameter-box"):
 
282
  minimum=0,
283
  maximum=MAX_SEED,
284
  step=1,
285
+ value=42
286
  )
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  # ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
 
 
 
 
 
 
289
  generate_button.click(
290
+ generate_fashion,
291
+ inputs=[prompt, mode, cfg_scale, steps, randomize_seed, seed, width, height, lora_scale],
292
  outputs=[result, seed]
293
  )
294