openfree commited on
Commit
bbe13b0
Β·
verified Β·
1 Parent(s): fd8eb54

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -67
app.py CHANGED
@@ -10,10 +10,17 @@ import numpy as np
10
  from diffusers import DiffusionPipeline
11
  from transformers import pipeline as hf_pipeline
12
 
13
- # ---------------------- 이미지 생성 κ΄€λ ¨ μ„€μ • ----------------------
14
- device = "cuda" if torch.cuda.is_available() else "cpu"
15
- dtype = torch.bfloat16 if device=="cuda" else torch.float32
 
 
 
 
 
 
16
 
 
17
  # ν•œκ΅­μ–΄-μ˜μ–΄ λ²ˆμ—­ λͺ¨λΈ λ‘œλ“œ (μž₯μΉ˜μ— 따라 CPU λ˜λŠ” GPU μ‚¬μš©)
18
  translator = hf_pipeline("translation", model="Helsinki-NLP/opus-mt-ko-en", device=0 if device=="cuda" else -1)
19
 
@@ -79,7 +86,6 @@ logger = logging.getLogger("idea_generator")
79
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
80
  genai.configure(api_key=GEMINI_API_KEY)
81
 
82
- # μŠ¬λž˜μ‹œ("/")κ°€ ν¬ν•¨λœ λ³€ν™˜ λ¬Έμžμ—΄μ—μ„œ 두 μ˜΅μ…˜ 쀑 ν•˜λ‚˜λ§Œ μ„ νƒν•˜λŠ” 헬퍼 ν•¨μˆ˜
83
  def choose_alternative(transformation):
84
  if "/" not in transformation:
85
  return transformation
@@ -101,7 +107,7 @@ def choose_alternative(transformation):
101
  else:
102
  return random.choice([left, right])
103
 
104
- # 창의적인 λͺ¨λΈ/컨셉/ν˜•μƒ λ³€ν™” 아이디어λ₯Ό μœ„ν•œ μΉ΄ν…Œκ³ λ¦¬
105
  physical_transformation_categories = {
106
  "곡간 이동": [
107
  "μ•ž/λ’€ 이동", "쒌/우 이동", "μœ„/μ•„λž˜ 이동", "μ„Έλ‘œμΆ• νšŒμ „(고개 λ„λ•μž„)",
@@ -209,7 +215,7 @@ physical_transformation_categories = {
209
  "음ν–₯ λ°˜μ‚¬/흑수", "음ν–₯ λ„ν”ŒλŸ¬ 효과", "음파 κ°„μ„­", "음ν–₯ 곡진",
210
  "진동 νŒ¨ν„΄ λ³€ν™”", "타악 효과", "음ν–₯ ν”Όλ“œλ°±", "음ν–₯ 차폐/증폭",
211
  "μ†Œλ¦¬ μ§€ν–₯μ„±", "음ν–₯ μ™œκ³‘", "λΉ„νŠΈ 생성", "ν•˜λͺ¨λ‹‰μŠ€ 생성", "주파수 λ³€μ‘°",
212
- "음ν–₯ 좩격파", "음ν–₯ 필터링", "음파 μ „νŒŒ νŒ¨ν„΄", "진동 λŒν•‘"
213
  ],
214
 
215
  "생물학적 λ³€ν™”": [
@@ -244,7 +250,7 @@ physical_transformation_categories = {
244
  }
245
 
246
  ##############################################################################
247
- # Gemini API 호좜 ν•¨μˆ˜ (예: gemini-2.0-flash-thinking-exp-01-21 -> λ‹€λ₯Έ λͺ¨λΈ μ‚¬μš© μ‹œ μˆ˜μ •)
248
  ##############################################################################
249
  def query_gemini_api(prompt):
250
  try:
@@ -253,15 +259,13 @@ def query_gemini_api(prompt):
253
  try:
254
  if hasattr(response, 'text'):
255
  return response.text
256
-
257
  if hasattr(response, 'candidates') and response.candidates:
258
- if len(response.candidates) > 0:
259
- candidate = response.candidates[0]
260
- if hasattr(candidate, 'content'):
261
- content = candidate.content
262
- if hasattr(content, 'parts') and content.parts:
263
- if len(content.parts) > 0:
264
- return content.parts[0].text
265
  if hasattr(response, 'parts') and response.parts:
266
  if len(response.parts) > 0:
267
  return response.parts[0].text
@@ -290,48 +294,42 @@ def enhance_with_llm(base_description, obj_name, category):
290
  return query_gemini_api(prompt)
291
 
292
  ##############################################################################
293
- # 단일 ν‚€μ›Œλ“œμ— λŒ€ν•œ "창의적 λ³€ν™” 아이디어" 생성
294
  ##############################################################################
295
- def generate_single_object_transformations(obj):
296
- results = {}
297
- for category, transformations in physical_transformation_categories.items():
298
- transformation = choose_alternative(random.choice(transformations))
299
- base_description = f"{obj}이(κ°€) {transformation} ν˜„μƒμ„ 보인닀"
300
- results[category] = {"base": base_description, "enhanced": None}
301
- return results
302
 
303
- ##############################################################################
304
- # 두 ν‚€μ›Œλ“œμ— λŒ€ν•œ "창의적 λ³€ν™” 아이디어" 생성
305
- ##############################################################################
306
- def generate_two_objects_interaction(obj1, obj2):
307
- results = {}
308
- for category, transformations in physical_transformation_categories.items():
309
- transformation = choose_alternative(random.choice(transformations))
310
- template = random.choice([
311
- "{obj1}이(κ°€) {obj2}에 κ²°ν•©ν•˜μ—¬ {change}κ°€ λ°œμƒν–ˆλ‹€",
312
- "{obj1}κ³Ό(와) {obj2}이(κ°€) μΆ©λŒν•˜λ©΄μ„œ {change}κ°€ 일어났닀"
313
- ])
314
- base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
315
- results[category] = {"base": base_description, "enhanced": None}
316
- return results
317
 
318
- ##############################################################################
319
- # μ„Έ ν‚€μ›Œλ“œμ— λŒ€ν•œ "창의적 λ³€ν™” 아이디어" 생성
320
- ##############################################################################
321
- def generate_three_objects_interaction(obj1, obj2, obj3):
322
- results = {}
323
- for category, transformations in physical_transformation_categories.items():
324
- transformation = choose_alternative(random.choice(transformations))
325
- template = random.choice([
326
- "{obj1}, {obj2}, {obj3}이(κ°€) μ‚Όκ°ν˜• ꡬ쑰둜 κ²°ν•©ν•˜μ—¬ {change}κ°€ λ°œμƒν–ˆλ‹€",
327
- "{obj1}이(κ°€) {obj2}와(κ³Ό) {obj3} μ‚¬μ΄μ—μ„œ 맀개체 역할을 ν•˜λ©° {change}λ₯Ό μ΄‰μ§„ν–ˆλ‹€"
328
- ])
329
- base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
330
- results[category] = {"base": base_description, "enhanced": None}
331
- return results
332
 
333
  ##############################################################################
334
- # μƒμ„±λœ κΈ°λ³Έ μ„€λͺ…을 LLM을 톡해 ν™•μž₯
335
  ##############################################################################
336
  def enhance_descriptions(results, objects):
337
  obj_name = " 및 ".join([obj for obj in objects if obj])
@@ -340,17 +338,17 @@ def enhance_descriptions(results, objects):
340
  return results
341
 
342
  ##############################################################################
343
- # μ‚¬μš©μž μž…λ ₯(μ΅œλŒ€ 3개 ν‚€μ›Œλ“œ)에 따라 창의적 λ³€ν™” 아이디어 생성
344
  ##############################################################################
345
- def generate_transformations(text1, text2=None, text3=None):
346
  if text2 and text3:
347
- results = generate_three_objects_interaction(text1, text2, text3)
348
  objects = [text1, text2, text3]
349
  elif text2:
350
- results = generate_two_objects_interaction(text1, text2)
351
  objects = [text1, text2]
352
  else:
353
- results = generate_single_object_transformations(text1)
354
  objects = [text1]
355
  return enhance_descriptions(results, objects)
356
 
@@ -378,13 +376,8 @@ def process_inputs(text1, text2, text3, selected_category, progress=gr.Progress(
378
  time.sleep(0.3)
379
  progress(0.1, desc="창의���인 아이디어 생성 μ‹œμž‘...")
380
 
381
- results = generate_transformations(text1, text2, text3)
382
-
383
- # μ„ νƒν•œ μΉ΄ν…Œκ³ λ¦¬ 결과만 필터링
384
- if selected_category in results:
385
- results = {selected_category: results[selected_category]}
386
- else:
387
- return "μ„ νƒν•œ μΉ΄ν…Œκ³ λ¦¬κ°€ 결과에 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."
388
 
389
  progress(0.8, desc="κ²°κ³Ό ν¬λ§·νŒ… 쀑...")
390
  formatted = format_results(results)
@@ -395,9 +388,7 @@ def process_inputs(text1, text2, text3, selected_category, progress=gr.Progress(
395
  # μƒˆλ‘œμš΄ 톡합 ν•¨μˆ˜: 아이디어 ν…μŠ€νŠΈ 생성 및 이미지 생성
396
  ##############################################################################
397
  def process_all(text1, text2, text3, selected_category, progress=gr.Progress()):
398
- # ν™•μž₯ 아이디어 ν…μŠ€νŠΈ 생성
399
  idea_result = process_inputs(text1, text2, text3, selected_category, progress)
400
- # μƒμ„±λœ 아이디어λ₯Ό κ·ΈλŒ€λ‘œ 이미지 생성 ν”„λ‘¬ν”„νŠΈλ‘œ μ‚¬μš©
401
  image_result = generate_design_image(idea_result, seed=42, randomize_seed=True, width=1024, height=1024, num_inference_steps=4)
402
  return idea_result, image_result
403
 
@@ -444,7 +435,7 @@ with gr.Blocks(title="ν‚€μ›Œλ“œ 기반 창의적 λ³€ν™” 아이디어 및 λ””μž
444
  value=list(physical_transformation_categories.keys())[0],
445
  info="좜λ ₯ν•  μΉ΄ν…Œκ³ λ¦¬λ₯Ό μ„ νƒν•˜μ„Έμš”."
446
  )
447
- status_msg = gr.Markdown("πŸ’‘ '아이디어 μƒμ„±ν•˜κΈ°' λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ 아이디어 생성과 ν•¨κ»˜ λ””μžμΈ 이미지가 μƒμ„±λ©λ‹ˆλ‹€.")
448
  processing_indicator = gr.HTML("""
449
  <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
450
  <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
 
10
  from diffusers import DiffusionPipeline
11
  from transformers import pipeline as hf_pipeline
12
 
13
+ # ---------------------- ZeroGPU ν™˜κ²½μ—μ„œ GPU μ‚¬μš© μ„€μ • ----------------------
14
+ # Hugging Face Spaces의 ZeroGPU ν™˜κ²½μ΄λ©΄ ν™˜κ²½ λ³€μˆ˜ ZERO_GPUκ°€ μ„€μ •λ˜μ–΄ μžˆλ‹€κ³  κ°€μ •
15
+ if os.getenv("ZERO_GPU"):
16
+ device = "cuda"
17
+ torch.cuda.set_device(0)
18
+ else:
19
+ device = "cuda" if torch.cuda.is_available() else "cpu"
20
+
21
+ dtype = torch.bfloat16 if device == "cuda" else torch.float32
22
 
23
+ # ---------------------- 이미지 생성 κ΄€λ ¨ μ„€μ • ----------------------
24
  # ν•œκ΅­μ–΄-μ˜μ–΄ λ²ˆμ—­ λͺ¨λΈ λ‘œλ“œ (μž₯μΉ˜μ— 따라 CPU λ˜λŠ” GPU μ‚¬μš©)
25
  translator = hf_pipeline("translation", model="Helsinki-NLP/opus-mt-ko-en", device=0 if device=="cuda" else -1)
26
 
 
86
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
87
  genai.configure(api_key=GEMINI_API_KEY)
88
 
 
89
  def choose_alternative(transformation):
90
  if "/" not in transformation:
91
  return transformation
 
107
  else:
108
  return random.choice([left, right])
109
 
110
+ # 창의적인 λͺ¨λΈ/컨셉/ν˜•μƒ λ³€ν™” 아이디어λ₯Ό μœ„ν•œ μΉ΄ν…Œκ³ λ¦¬ (총 15개)
111
  physical_transformation_categories = {
112
  "곡간 이동": [
113
  "μ•ž/λ’€ 이동", "쒌/우 이동", "μœ„/μ•„λž˜ 이동", "μ„Έλ‘œμΆ• νšŒμ „(고개 λ„λ•μž„)",
 
215
  "음ν–₯ λ°˜μ‚¬/흑수", "음ν–₯ λ„ν”ŒλŸ¬ 효과", "음파 κ°„μ„­", "음ν–₯ 곡진",
216
  "진동 νŒ¨ν„΄ λ³€ν™”", "타악 효과", "음ν–₯ ν”Όλ“œλ°±", "음ν–₯ 차폐/증폭",
217
  "μ†Œλ¦¬ μ§€ν–₯μ„±", "음ν–₯ μ™œκ³‘", "λΉ„νŠΈ 생성", "ν•˜λͺ¨λ‹‰μŠ€ 생성", "주파수 λ³€μ‘°",
218
+ "음ν–₯ 좩격파", "음ν–₯ 필터링"
219
  ],
220
 
221
  "생물학적 λ³€ν™”": [
 
250
  }
251
 
252
  ##############################################################################
253
+ # Gemini API 호좜 ν•¨μˆ˜ (λͺ¨λΈ: gemini-2.0-flash-thinking-exp-01-21)
254
  ##############################################################################
255
  def query_gemini_api(prompt):
256
  try:
 
259
  try:
260
  if hasattr(response, 'text'):
261
  return response.text
 
262
  if hasattr(response, 'candidates') and response.candidates:
263
+ candidate = response.candidates[0]
264
+ if hasattr(candidate, 'content'):
265
+ content = candidate.content
266
+ if hasattr(content, 'parts') and content.parts:
267
+ if len(content.parts) > 0:
268
+ return content.parts[0].text
 
269
  if hasattr(response, 'parts') and response.parts:
270
  if len(response.parts) > 0:
271
  return response.parts[0].text
 
294
  return query_gemini_api(prompt)
295
 
296
  ##############################################################################
297
+ # μ„ νƒλœ μΉ΄ν…Œκ³ λ¦¬λ§Œμ„ λŒ€μƒμœΌλ‘œ ν•œ 창의적 λ³€ν™” 아이디어 생성 ν•¨μˆ˜λ“€
298
  ##############################################################################
299
+ def generate_single_object_transformation_for_category(obj, selected_category):
300
+ transformations = physical_transformation_categories.get(selected_category)
301
+ if not transformations:
302
+ return {}
303
+ transformation = choose_alternative(random.choice(transformations))
304
+ base_description = f"{obj}이(κ°€) {transformation} ν˜„μƒμ„ 보인닀"
305
+ return {selected_category: {"base": base_description, "enhanced": None}}
306
 
307
+ def generate_two_objects_interaction_for_category(obj1, obj2, selected_category):
308
+ transformations = physical_transformation_categories.get(selected_category)
309
+ if not transformations:
310
+ return {}
311
+ transformation = choose_alternative(random.choice(transformations))
312
+ template = random.choice([
313
+ "{obj1}이(κ°€) {obj2}에 κ²°ν•©ν•˜μ—¬ {change}κ°€ λ°œμƒν–ˆλ‹€",
314
+ "{obj1}κ³Ό(와) {obj2}이(κ°€) μΆ©λŒν•˜λ©΄μ„œ {change}κ°€ 일어났닀"
315
+ ])
316
+ base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
317
+ return {selected_category: {"base": base_description, "enhanced": None}}
 
 
 
318
 
319
+ def generate_three_objects_interaction_for_category(obj1, obj2, obj3, selected_category):
320
+ transformations = physical_transformation_categories.get(selected_category)
321
+ if not transformations:
322
+ return {}
323
+ transformation = choose_alternative(random.choice(transformations))
324
+ template = random.choice([
325
+ "{obj1}, {obj2}, {obj3}이(κ°€) μ‚Όκ°ν˜• ꡬ쑰둜 κ²°ν•©ν•˜μ—¬ {change}κ°€ λ°œμƒν–ˆλ‹€",
326
+ "{obj1}이(κ°€) {obj2}와(κ³Ό) {obj3} μ‚¬μ΄μ—μ„œ 맀개체 역할을 ν•˜λ©° {change}λ₯Ό μ΄‰μ§„ν–ˆλ‹€"
327
+ ])
328
+ base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
329
+ return {selected_category: {"base": base_description, "enhanced": None}}
 
 
 
330
 
331
  ##############################################################################
332
+ # μƒμ„±λœ κΈ°λ³Έ μ„€λͺ…을 LLM을 톡해 ν™•μž₯ (μ„ νƒλœ μΉ΄ν…Œκ³ λ¦¬λ§Œ ν•΄λ‹Ή)
333
  ##############################################################################
334
  def enhance_descriptions(results, objects):
335
  obj_name = " 및 ".join([obj for obj in objects if obj])
 
338
  return results
339
 
340
  ##############################################################################
341
+ # μ‚¬μš©μž μž…λ ₯(μ΅œλŒ€ 3개 ν‚€μ›Œλ“œ)와 μ„ νƒλœ μΉ΄ν…Œκ³ λ¦¬μ— 따라 창의적 λ³€ν™” 아이디어 생성
342
  ##############################################################################
343
+ def generate_transformations(text1, text2, text3, selected_category):
344
  if text2 and text3:
345
+ results = generate_three_objects_interaction_for_category(text1, text2, text3, selected_category)
346
  objects = [text1, text2, text3]
347
  elif text2:
348
+ results = generate_two_objects_interaction_for_category(text1, text2, selected_category)
349
  objects = [text1, text2]
350
  else:
351
+ results = generate_single_object_transformation_for_category(text1, selected_category)
352
  objects = [text1]
353
  return enhance_descriptions(results, objects)
354
 
 
376
  time.sleep(0.3)
377
  progress(0.1, desc="창의���인 아이디어 생성 μ‹œμž‘...")
378
 
379
+ # μ„ νƒλœ μΉ΄ν…Œκ³ λ¦¬λ§Œ λŒ€μƒμœΌλ‘œ 아이디어 생성
380
+ results = generate_transformations(text1, text2, text3, selected_category)
 
 
 
 
 
381
 
382
  progress(0.8, desc="κ²°κ³Ό ν¬λ§·νŒ… 쀑...")
383
  formatted = format_results(results)
 
388
  # μƒˆλ‘œμš΄ 톡합 ν•¨μˆ˜: 아이디어 ν…μŠ€νŠΈ 생성 및 이미지 생성
389
  ##############################################################################
390
  def process_all(text1, text2, text3, selected_category, progress=gr.Progress()):
 
391
  idea_result = process_inputs(text1, text2, text3, selected_category, progress)
 
392
  image_result = generate_design_image(idea_result, seed=42, randomize_seed=True, width=1024, height=1024, num_inference_steps=4)
393
  return idea_result, image_result
394
 
 
435
  value=list(physical_transformation_categories.keys())[0],
436
  info="좜λ ₯ν•  μΉ΄ν…Œκ³ λ¦¬λ₯Ό μ„ νƒν•˜μ„Έμš”."
437
  )
438
+ status_msg = gr.Markdown("πŸ’‘ '아이디어 μƒμ„±ν•˜κΈ°' λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ μ„ νƒν•œ μΉ΄ν…Œκ³ λ¦¬μ— ν•΄λ‹Ήν•˜λŠ” 아이디어와 λ””μžμΈ 이미지가 μƒμ„±λ©λ‹ˆλ‹€.")
439
  processing_indicator = gr.HTML("""
440
  <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
441
  <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>