openfree commited on
Commit
e714f1c
·
verified ·
1 Parent(s): 862b58a

Update app-backup.py

Browse files
Files changed (1) hide show
  1. app-backup.py +282 -173
app-backup.py CHANGED
@@ -1,5 +1,3 @@
1
-
2
-
3
  import os
4
  import gradio as gr
5
  import random
@@ -7,7 +5,124 @@ import time
7
  import logging
8
  import google.generativeai as genai
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  # 로깅 설정
 
11
  logging.basicConfig(
12
  level=logging.INFO,
13
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
@@ -18,11 +133,15 @@ logging.basicConfig(
18
  )
19
  logger = logging.getLogger("idea_generator")
20
 
21
- # Gemini API 키는 환경 변수 GEMINI_API_KEY에서 가져옵니다.
 
 
22
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
23
  genai.configure(api_key=GEMINI_API_KEY)
24
 
25
- # 슬래시("/")가 포함된 변환 문자열에서 두 옵션 중 하나만 선택하는 헬퍼 함수
 
 
26
  def choose_alternative(transformation):
27
  if "/" not in transformation:
28
  return transformation
@@ -44,19 +163,17 @@ def choose_alternative(transformation):
44
  else:
45
  return random.choice([left, right])
46
 
47
- # 창의적인 모델/컨셉/형상 변화 아이디어를 위한 카테고리 (기존 '물리적 변화' 사전 유지)
48
-
49
-
50
- # 창의적인 모델/컨셉/형상 변화 아이디어를 위한 카테고리 (기존 '물리적 변화' 사전 유지)
51
  physical_transformation_categories = {
52
  "공간 이동": [
53
- "앞/뒤 이동", "좌/우 이동", "위/아래 이동", "세로축 회전(고개 끄덕임)",
54
- "가로축 회전(고개 젓기)", "길이축 회전(옆으로 기울임)", "원 운동", "나선형 이동",
55
  "관성에 의한 미끄러짐", "회전축 변화", "불규칙 회전", "흔들림 운동", "포물선 이동",
56
  "무중력 부유", "수면 위 부유", "점프/도약", "슬라이딩", "롤링", "자유 낙하",
57
  "왕복 운동", "탄성 튕김", "관통", "회피 움직임", "지그재그 이동", "스윙 운동"
58
  ],
59
-
60
  "크기와 형태 변화": [
61
  "부피 늘어남/줄어듦", "길이 늘어남/줄어듦", "너비 늘어남/줄어듦", "높이 늘어남/줄어듦",
62
  "밀도 변화", "무게 증가/감소", "모양 변형", "상태 변화", "불균등 변형",
@@ -65,63 +182,56 @@ physical_transformation_categories = {
65
  "접힘/펼쳐짐", "압착/팽창", "늘어남/수축", "구겨짐/평평해짐", "뭉개짐/단단해짐",
66
  "말림/펴짐", "꺾임/구부러짐"
67
  ],
68
-
69
  "표면 및 외관 변화": [
70
- "색상 변화", "질감 변화", "투명/불투명 변화", "반짝임/무광 변화",
71
- "빛 반사 정도 변화", "무늬 변화", "각도에 따른 색상 변화", "빛에 따른 색상 변화",
72
- "온도에 따른 색상 변화", "홀로그램 효과", "표면 각도별 빛 반사", "표면 모양 변형",
73
  "초미세 표면 구조 변화", "자가 세정 효과", "얼룩/패턴 생성", "흐림/선명함 변화",
74
- "광택/윤기 변화", "색조/채도 변화", "발광/형광", "빛 산란 효과",
75
  "빛 흡수 변화", "반투명 효과", "그림자 효과 변화", "자외선 반응 변화",
76
  "야광 효과"
77
  ],
78
-
79
  "물질의 상태 변화": [
80
- "고체/액체/기체 전환", "결정화/용해", "산화/부식", "딱딱해짐/부드러워짐",
81
- "특수 상태 전환", "무정형/결정형 전환", "성분 분리", "미세 입자 형성/분해",
82
- "젤 형성/풀어짐", "준안정 상태 변화", "분자 자가 정렬/분해", "상태변화 지연 현상",
83
  "녹음", "굳음", "증발/응축", "승화/증착", "침전/부유", "분산/응집",
84
  "건조/습윤", "팽윤/수축", "동결/해동", "풍화/침식", "충전/방전",
85
  "결합/분리", "발효/부패"
86
  ],
87
-
88
  "열 관련 변화": [
89
- "온도 상승/하강", "열에 의한 팽창/수축", "열 전달/차단", "압력 상승/하강",
90
- "열 변화에 따른 자화", "무질서도 변화", "열전기 현상", "자기장에 의한 열 변화",
91
- "상태변화 중 열 저장/방출", "열 스트레스 발생/해소", "급격한 온도 변화 영향",
92
  "복사열에 의한 냉각/가열", "발열/흡열", "열 분포 변화", "열 반사/흡수",
93
  "냉각 응축", "열 활성화", "열 변색", "열 팽창 계수 변화", "열 안정성 변화",
94
  "내열성/내한성", "자기발열", "열적 평형/불균형", "열적 변형", "열 분산/집중"
95
  ],
96
-
97
  "움직임 특성 변화": [
98
- "가속/감속", "일정 속도 유지", "진동/진동 감소", "부딪힘/튕김",
99
- "회전 속도 증가/감소", "회전 방향 변화", "불규칙 움직임", "멈췄다 미끄러지는 현상",
100
- "공진/반공진", "유체 속 저항/양력 변화", "움직임 저항 변화", "복합 진동 움직임",
101
  "특수 유체 속 움직임", "회전-이동 연계 움직임", "관성 정지", "충격 흡수",
102
  "충격 전달", "운동량 보존", "마찰력 변화", "관성 탈출", "불안정 균형",
103
  "동적 안정성", "흔들림 감쇠", "경로 예측성", "회피 움직임"
104
  ],
105
-
106
  "구조적 변화": [
107
  "부품 추가/제거", "조립/분해", "접기/펴기", "변형/원상복구", "최적 구조 변화",
108
  "자가 재배열", "자연 패턴 형성/소멸", "규칙적 패턴 변화", "모듈식 변형",
109
- "복잡성 증가 구조", "원래 모양 기억 효과", "시간에 따른 형태 변화", "부분 제거",
110
  "부분 교체", "결합", "분리", "분할/통합", "중첩/겹침", "내부 구조 변화",
111
  "외부 구조 변화", "중심축 이동", "균형점 변화", "계층 구조 변화", "지지 구조 변화",
112
  "응력 분산 구조", "충격 흡수 구조", "그리드/매트릭스 구조 변화", "상호 연결성 변화"
113
  ],
114
-
115
  "전기 및 자기 변화": [
116
- "자성 생성/소멸", "전하량 증가/감소", "전기장 생성/소멸", "자기장 생성/소멸",
117
- "초전도 상태 전환", "강유전체 특성 변화", "양자 상태 변화", "플라즈마 상태 형성/소멸",
118
  "스핀파 전달", "빛에 의한 전기 발생", "압력에 의한 전기 발생", "자기장 속 전류 변화",
119
  "전기 저항 변화", "전기 전도성 변화", "정전기 발생/방전", "전자기 유도",
120
  "전자기파 방출/흡수", "전기 용량 변화", "자기 이력 현상", "전기적 분극",
121
  "전자 흐름 방향 변화", "전기적 공명", "전기적 차폐/노출", "자기 차폐/노출",
122
  "자기장 방향 정렬"
123
  ],
124
-
125
  "화학적 변화": [
126
  "표면 코팅 변화", "물질 성분 변화", "화학 반응 변화", "촉매 작용 시작/중단",
127
  "빛에 의한 화학 반응", "전기에 의한 화학 반응", "단분자막 형성", "분자 수준 계산 변화",
@@ -130,16 +240,14 @@ physical_transformation_categories = {
130
  "이온화", "화학적 흡착/탈착", "촉매 효율 변화", "효소 활성 변화", "발색 반응",
131
  "pH 변화", "화학적 평형 이동", "결합 형성/분해", "용해도 변화"
132
  ],
133
-
134
  "시간 관련 변화": [
135
  "노화/풍화", "마모/부식", "색 바램/변색", "손상/회복", "수명 주기 변화",
136
- "사용자 상호작용에 따른 적응", "학습 기반 형태 최적화", "시간에 따른 물성 변화",
137
- "집단 기억 효과", "문화적 의미 변화", "지연 반응", "이전 상태 의존 변화",
138
  "점진적 시간 변화", "진화적 변화", "주기적 재생", "계절 변화 적응",
139
- "생체리듬 변화", "생애 주기 단계", "성장/퇴화", "자기 복구/재생",
140
  "자연 순환 적응", "지속성/일시성", "기억 효과", "지연된 작용", "누적 효과"
141
  ],
142
-
143
  "빛과 시각 효과": [
144
  "발광/소등", "빛 투과/차단", "빛 산란/집중", "색상 스펙트럼 변화", "빛 회절",
145
  "빛 간섭", "홀로그램 생성", "레이저 효과", "빛 편광", "형광/인광",
@@ -148,16 +256,14 @@ physical_transformation_categories = {
148
  "빔 효과", "광 필터 효과", "빛의 방향성 변화", "투영 효과", "빛 감지/반응",
149
  "광도 변화"
150
  ],
151
-
152
  "소리와 진동 효과": [
153
  "소리 발생/소멸", "소리 높낮이 변화", "소리 크기 변화", "음색 변화",
154
  "공명/반공명", "음향 진동", "초음파/저음파 발생", "음향 집중/분산",
155
  "음향 반사/흡수", "음향 도플러 효과", "음파 간섭", "음향 공진",
156
  "진동 패턴 변화", "타악 효과", "음향 피드백", "음향 차폐/증폭",
157
  "소리 지향성", "음향 왜곡", "비트 생성", "하모닉스 생성", "주파수 변조",
158
- "음향 충격파", "음향 필터링", "음파 전파 패턴", "진동 댐핑"
159
  ],
160
-
161
  "생물학적 변화": [
162
  "생장/위축", "세포 분열/사멸", "생물 발광", "신진대사 변화", "면역 반응",
163
  "호르몬 분비", "신경 반응", "유전적 발현", "적응/진화", "생체리듬 변화",
@@ -166,7 +272,6 @@ physical_transformation_categories = {
166
  "생물학적 시계 변화", "세포외 기질 변화", "생체 역학적 반응", "세포 운동성",
167
  "세포 극성 변화", "영양 상태 변화"
168
  ],
169
-
170
  "환경 상호작용": [
171
  "온도 반응", "습도 반응", "기압 반응", "중력 반응", "자기장 반응",
172
  "빛 반응", "소리 반응", "화학 물질 감지", "기계적 자극 감지", "전기 자극 반응",
@@ -174,7 +279,6 @@ physical_transformation_categories = {
174
  "환경 오염 반응", "날씨 반응", "계절 변화 반응", "일주기 반응", "생태계 상호작용",
175
  "공생/경쟁 반응", "포식/피식 관계", "군집 형성", "영역 설정", "이주/정착 패턴"
176
  ],
177
-
178
  "센서 기능": [
179
  "시각 센서/감지", "청각 센서/감지", "촉각 센서/감지", "미각 센서/감지", "후각 센서/감지",
180
  "온도 센서/감지", "습도 센서/감지", "압력 센서/감지", "가속도 센서/감지", "회전 센서/감지",
@@ -183,45 +287,36 @@ physical_transformation_categories = {
183
  "생체신호 센서/감지", "진동 센서/감지", "소음 센서/감지", "빛 세기 센서/감지", "빛 파장 센서/감지",
184
  "기울기 센서/감지", "pH 센서/감지", "전류 센서/감지", "전압 센서/감지", "이미지 센서/감지",
185
  "거리 센서/감지", "깊이 센서/감지", "중력 센서/감지", "속도 센서/감지", "흐름 센서/감지",
186
- "수위 센서/감지", "탁도 센서/감지", "염도 센서/감지", "금속 감지", "압전 센서/감지",
187
  "광전 센서/감지", "열전대 센서/감지", "홀 효과 센서/감지", "초음파 센서/감지", "레이더 센서/감지",
188
  "라이다 센서/감지", "터치 센서/감지", "제스처 센서/감지", "심박 센서/감지", "혈압 센서/감지"
189
  ]
190
  }
191
 
192
  ##############################################################################
193
- # Gemini API 호출 함수 (예: gemini-2.0-flash-thinking-exp-01-21 -> 다른 모델 사용 시 수정)
194
  ##############################################################################
195
  def query_gemini_api(prompt):
196
  try:
197
- # 예시: 기존 gemini-2.0... 대신, 다른 모델이 필요하다면 교체하세요.
198
  model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21')
199
-
200
  response = model.generate_content(prompt)
201
-
202
- # 응답 구조 방어적으로 처리
203
  try:
204
  if hasattr(response, 'text'):
205
  return response.text
206
-
207
  if hasattr(response, 'candidates') and response.candidates:
208
- if len(response.candidates) > 0:
209
- candidate = response.candidates[0]
210
- if hasattr(candidate, 'content'):
211
- content = candidate.content
212
- if hasattr(content, 'parts') and content.parts:
213
- if len(content.parts) > 0:
214
- return content.parts[0].text
215
  if hasattr(response, 'parts') and response.parts:
216
  if len(response.parts) > 0:
217
  return response.parts[0].text
218
-
219
  return "Unable to generate a response. API response structure is different than expected."
220
-
221
  except Exception as inner_e:
222
  logger.error(f"Error processing response: {inner_e}")
223
  return f"An error occurred while processing the response: {str(inner_e)}"
224
-
225
  except Exception as e:
226
  logger.error(f"Error calling Gemini API: {e}")
227
  if "API key not valid" in str(e):
@@ -229,7 +324,7 @@ def query_gemini_api(prompt):
229
  return f"An error occurred while calling the API: {str(e)}"
230
 
231
  ##############################################################################
232
- # 설명 확장 함수: "모델/컨셉/형상의 변화에 대한 이해와 혁신 포인트, 기능성 등을 중심"으로
233
  ##############################################################################
234
  def enhance_with_llm(base_description, obj_name, category):
235
  prompt = f"""
@@ -243,74 +338,62 @@ def enhance_with_llm(base_description, obj_name, category):
243
  return query_gemini_api(prompt)
244
 
245
  ##############################################################################
246
- # 단일 키워드(오브젝트)에 대한 "창의적 변화 아이디어" 생성
247
  ##############################################################################
248
- def generate_single_object_transformations(obj):
249
- results = {}
250
- for category, transformations in physical_transformation_categories.items():
251
- transformation = choose_alternative(random.choice(transformations))
252
- base_description = f"{obj}이() {transformation} 현상을 보인다"
253
- results[category] = {"base": base_description, "enhanced": None}
254
- return results
255
 
256
- ##############################################################################
257
- # 키워드에 대한 "창의적 변화 아이디어" 생성
258
- ##############################################################################
259
- def generate_two_objects_interaction(obj1, obj2):
260
- results = {}
261
- for category, transformations in physical_transformation_categories.items():
262
- transformation = choose_alternative(random.choice(transformations))
263
- template = random.choice([
264
- "{obj1}이(가) {obj2}에 결합하여 {change}가 발생했다",
265
- "{obj1}과(와) {obj2}이(가) 충돌하면서 {change}가 일어났다"
266
- ])
267
- base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
268
- results[category] = {"base": base_description, "enhanced": None}
269
- return results
270
 
271
- ##############################################################################
272
- # 키워드에 대한 "창의적 변화 아이디어" 생성
273
- ##############################################################################
274
- def generate_three_objects_interaction(obj1, obj2, obj3):
275
- results = {}
276
- for category, transformations in physical_transformation_categories.items():
277
- transformation = choose_alternative(random.choice(transformations))
278
- template = random.choice([
279
- "{obj1}, {obj2}, {obj3}이(가) 삼각형 구조로 결합하여 {change}가 발생했다",
280
- "{obj1}이(가) {obj2}와(과) {obj3} 사이에서 매개체 역할을 하며 {change}를 촉진했다"
281
- ])
282
- base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
283
- results[category] = {"base": base_description, "enhanced": None}
284
- return results
285
 
286
  ##############################################################################
287
- # 생성된 기본 설명을 LLM을 통해 확장
288
  ##############################################################################
289
  def enhance_descriptions(results, objects):
290
- # progress 인자 제거
291
  obj_name = " 및 ".join([obj for obj in objects if obj])
292
-
293
  for category, result in results.items():
294
  result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
295
-
296
  return results
297
 
298
  ##############################################################################
299
- # 사용자 입력(최대 3개 키워드) 따라 창의적 변화 아이디어 생성
300
  ##############################################################################
301
- def generate_transformations(text1, text2=None, text3=None):
302
- # progress 인자 제거
303
-
304
  if text2 and text3:
305
- results = generate_three_objects_interaction(text1, text2, text3)
306
  objects = [text1, text2, text3]
307
  elif text2:
308
- results = generate_two_objects_interaction(text1, text2)
309
  objects = [text1, text2]
310
  else:
311
- results = generate_single_object_transformations(text1)
312
  objects = [text1]
313
-
314
  return enhance_descriptions(results, objects)
315
 
316
  ##############################################################################
@@ -323,9 +406,9 @@ def format_results(results):
323
  return formatted
324
 
325
  ##############################################################################
326
- # Gradio UI에서 호출할 함수
327
  ##############################################################################
328
- def process_inputs(text1, text2, text3, progress=gr.Progress()):
329
  text1 = text1.strip() if text1 else None
330
  text2 = text2.strip() if text2 else None
331
  text3 = text3.strip() if text3 else None
@@ -333,36 +416,32 @@ def process_inputs(text1, text2, text3, progress=gr.Progress()):
333
  if not text1:
334
  return "오류: 최소 하나의 키워드를 입력해주세요."
335
 
336
- # 진행 상태 메시지 (중첩 리스트 대신 단순 문자열 사용)
337
- status_message = ""
 
338
 
339
- # 키워드 정보 확인
340
- keyword_info = f"키워드: {text1}"
341
- if text2:
342
- keyword_info += f", {text2}"
343
- if text3:
344
- keyword_info += f", {text3}"
345
 
346
- # 결과 생성 (progress 인자 전달하지 않음)
347
- try:
348
- # 진행 상태를 단계별로 표시
349
- progress(0.05, desc="아이디어 생성 준비 중...")
350
- time.sleep(0.3) # 시각적 효과를 위한 짧은 지연
351
-
352
- progress(0.1, desc="창의적인 모델/컨셉/형상 변화 아이디어 생성 시작...")
353
-
354
- # text1, text2, text3 전달하고 progress는 전달하지 않음
355
- results = generate_transformations(text1, text2, text3)
356
-
357
- progress(0.8, desc="결과 포맷팅 중...")
358
- formatted = format_results(results)
359
-
360
- progress(1.0, desc="완료!")
361
- return formatted
362
-
363
- except Exception as e:
364
- logger.error(f"Error in process_inputs: {e}")
365
- return f"처리 중 오류가 발생했습니다: {str(e)}"
366
 
367
  ##############################################################################
368
  # API 키 경고 메시지
@@ -375,38 +454,67 @@ def get_warning_message():
375
  ##############################################################################
376
  # Gradio UI
377
  ##############################################################################
378
- with gr.Blocks(title="키워드 기반 창의적 변화 아이디어 생성기",
379
- theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")) as demo:
 
 
380
 
381
  gr.HTML("""
382
  <style>
383
- body { background: linear-gradient(135deg, #e0eafc, #cfdef3); font-family: 'Arial', sans-serif; }
384
- .gradio-container { padding: 20px; }
385
- h1, h2 { text-align: center; }
386
- h1 { color: #333; }
387
- h2 { color: #555; }
388
- .output { background-color: #ffffff; padding: 15px; border-radius: 8px; }
389
- .gr-button { background-color: #4CAF50; color: white; border: none; border-radius: 4px; padding: 8px 16px; }
390
- .progress-message { color: #2196F3; font-weight: bold; margin-top: 10px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
  </style>
392
  """)
393
 
394
- gr.Markdown("# 🚀 키워드 기반 창의적 변화 아이디어 생성기")
395
- gr.Markdown("입력한 **키워드**(최대 3개) 바탕으로, **창의적인 모델/컨셉/형상 변화**에 대한 이해와 **혁신 포인트**, **기능성** 등을 중심으로 확장된 아이디어를 제시합니다.")
396
 
397
  warning = gr.Markdown(get_warning_message())
398
 
399
- # 좌측 입력 영역
400
  with gr.Row():
401
  with gr.Column(scale=1):
402
  text_input1 = gr.Textbox(label="키워드 1 (필수)", placeholder="예: 스마트폰")
403
  text_input2 = gr.Textbox(label="키워드 2 (선택)", placeholder="예: 인공지능")
404
  text_input3 = gr.Textbox(label="키워드 3 (선택)", placeholder="예: 헬스케어")
 
 
 
 
 
 
 
405
 
406
- # 입력과 버튼 사이에 상태 메시지를 표시할 영역 추가
407
- status_msg = gr.Markdown("💡 '아이디어 생성하기' 버튼을 클릭하면 아이디어 생성이 시작됩니다.")
408
-
409
- # 처리 중일 때만 표시되는 상태 메시지
410
  processing_indicator = gr.HTML("""
411
  <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
412
  <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
@@ -422,44 +530,45 @@ with gr.Blocks(title="키워드 기반 창의적 변화 아이디어 생성기",
422
 
423
  submit_button = gr.Button("아이디어 생성하기", variant="primary")
424
 
425
- # 우측 출력 영역
426
  with gr.Column(scale=2):
427
  idea_output = gr.Markdown(label="아이디어 결과")
428
-
429
- # 예시 입력
 
430
  gr.Examples(
431
  examples=[
432
- ["스마트폰", "", ""],
433
- ["자동차", "", ""],
434
- ["자동차", "인공지능", ""],
435
- ["드론", "인공지능", ""],
436
- ["운동화", "웨어러블", "건강"],
437
  ],
438
- inputs=[text_input1, text_input2, text_input3],
439
  )
440
 
441
- # 처리 시작 전 함수 (로딩 표시기 보이게)
442
  def show_processing_indicator():
443
  return gr.update(visible=True)
444
 
445
- # 처리 완료 후 함수 (로딩 표시기 숨기기)
446
  def hide_processing_indicator():
447
  return gr.update(visible=False)
448
 
449
- # 버튼 이벤트 - 여러 함수 순차 실행
450
  submit_button.click(
451
  fn=show_processing_indicator,
452
  inputs=None,
453
  outputs=processing_indicator
454
  ).then(
455
- fn=process_inputs,
456
- inputs=[text_input1, text_input2, text_input3],
457
- outputs=idea_output
458
  ).then(
459
  fn=hide_processing_indicator,
460
  inputs=None,
461
  outputs=processing_indicator
462
  )
463
 
 
464
  if __name__ == "__main__":
465
- demo.launch(debug=True)
 
 
 
1
  import os
2
  import gradio as gr
3
  import random
 
5
  import logging
6
  import google.generativeai as genai
7
 
8
+ import torch
9
+ import numpy as np
10
+ from diffusers import DiffusionPipeline
11
+ from transformers import pipeline as hf_pipeline
12
+
13
+ ##############################################################################
14
+ # 1) ZeroGPU 환경 처리 + device, dtype 설정
15
+ ##############################################################################
16
+ ##############################################################################
17
+ # 1) ZeroGPU 환경 처리 + device, dtype 설정
18
+ ##############################################################################
19
+ # ZeroGPU 초기화 시도
20
+ try:
21
+ import zerogpu
22
+ zerogpu.init()
23
+ print("ZeroGPU initialized successfully")
24
+ device = "cuda" if torch.cuda.is_available() else "cpu"
25
+ except ImportError:
26
+ # ZeroGPU가 설치되지 않은 경우
27
+ print("ZeroGPU package not installed, continuing without it")
28
+ if os.getenv("ZERO_GPU"):
29
+ print("ZeroGPU environment variable is set but zerogpu package is not installed.")
30
+ device = "cuda" if torch.cuda.is_available() else "cpu"
31
+ except Exception as e:
32
+ # ZeroGPU 초기화 중 다른 오류가 발생한 경우
33
+ print(f"Error initializing ZeroGPU: {e}")
34
+ print("Continuing without ZeroGPU")
35
+ device = "cuda" if torch.cuda.is_available() else "cpu"
36
+
37
+ # GPU일 때만 bfloat16, 그 외에는 float32
38
+ dtype = torch.bfloat16 if device == "cuda" else torch.float32
39
+
40
+ print(f"Using device: {device}, dtype: {dtype}")
41
+
42
+ ##############################################################################
43
+ # 2) 모델 로드: 번역 모델, DiffusionPipeline
44
+ ##############################################################################
45
+ try:
46
+ translator = hf_pipeline(
47
+ "translation",
48
+ model="Helsinki-NLP/opus-mt-ko-en",
49
+ device=0 if device == "cuda" else -1
50
+ )
51
+
52
+ pipe = DiffusionPipeline.from_pretrained(
53
+ "black-forest-labs/FLUX.1-schnell",
54
+ torch_dtype=dtype
55
+ ).to(device)
56
+
57
+ print("Models loaded successfully")
58
+ except Exception as e:
59
+ print(f"Error loading models: {e}")
60
+ # 모델 로드 에러 처리를 위한 더미 함수들
61
+ def dummy_translator(text):
62
+ return [{'translation_text': text}]
63
+
64
+ class DummyPipe:
65
+ def __call__(self, **kwargs):
66
+ from PIL import Image
67
+ import numpy as np
68
+ dummy_img = Image.fromarray(np.zeros((512, 512, 3), dtype=np.uint8))
69
+ class DummyResult:
70
+ def __init__(self, img):
71
+ self.images = [img]
72
+ return DummyResult(dummy_img)
73
+
74
+ translator = dummy_translator
75
+ pipe = DummyPipe()
76
+
77
+ MAX_SEED = np.iinfo(np.int32).max
78
+ MAX_IMAGE_SIZE = 2048
79
+
80
+ ##############################################################################
81
+ # 한국어 감지 함수
82
+ ##############################################################################
83
+ def contains_korean(text):
84
+ for char in text:
85
+ if ord('가') <= ord(char) <= ord('힣'):
86
+ return True
87
+ return False
88
+
89
+ ##############################################################################
90
+ # 이미지 생성 함수
91
+ ##############################################################################
92
+ def generate_design_image(prompt, seed=42, randomize_seed=True, width=1024, height=1024, num_inference_steps=4):
93
+ """
94
+ 생성된 확장 아이디어 텍스트(prompt)를 입력받아,
95
+ 필요시 한국어를 영어로 번역한 후 DiffusionPipeline으로 이미지를 생성합니다.
96
+ """
97
+ original_prompt = prompt
98
+ translated = False
99
+
100
+ # 한국어가 포함되어 있으면 영어로 번역
101
+ if contains_korean(prompt):
102
+ translation = translator(prompt)
103
+ prompt = translation[0]['translation_text']
104
+ translated = True
105
+
106
+ # 랜덤 시드 설정
107
+ if randomize_seed:
108
+ seed = random.randint(0, MAX_SEED)
109
+
110
+ generator = torch.Generator(device=device).manual_seed(seed)
111
+
112
+ image = pipe(
113
+ prompt=prompt,
114
+ width=width,
115
+ height=height,
116
+ num_inference_steps=num_inference_steps,
117
+ generator=generator,
118
+ guidance_scale=0.0
119
+ ).images[0]
120
+
121
+ return image
122
+
123
+ ##############################################################################
124
  # 로깅 설정
125
+ ##############################################################################
126
  logging.basicConfig(
127
  level=logging.INFO,
128
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
 
133
  )
134
  logger = logging.getLogger("idea_generator")
135
 
136
+ ##############################################################################
137
+ # Gemini API 키
138
+ ##############################################################################
139
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
140
  genai.configure(api_key=GEMINI_API_KEY)
141
 
142
+ ##############################################################################
143
+ # 선택적 변형 선택 함수
144
+ ##############################################################################
145
  def choose_alternative(transformation):
146
  if "/" not in transformation:
147
  return transformation
 
163
  else:
164
  return random.choice([left, right])
165
 
166
+ ##############################################################################
167
+ # 물리적 변화 카테고리 사전 (총 15개)
168
+ ##############################################################################
 
169
  physical_transformation_categories = {
170
  "공간 이동": [
171
+ "앞/뒤 이동", "좌/우 이동", "위/아래 이동", "세로축 회전(고개 끄덕임)",
172
+ "가로축 회전(고개 젓기)", "길이축 회전(옆으로 기울임)", "원 운동", "나선형 이동",
173
  "관성에 의한 미끄러짐", "회전축 변화", "불규칙 회전", "흔들림 운동", "포물선 이동",
174
  "무중력 부유", "수면 위 부유", "점프/도약", "슬라이딩", "롤링", "자유 낙하",
175
  "왕복 운동", "탄성 튕김", "관통", "회피 움직임", "지그재그 이동", "스윙 운동"
176
  ],
 
177
  "크기와 형태 변화": [
178
  "부피 늘어남/줄어듦", "길이 늘어남/줄어듦", "너비 늘어남/줄어듦", "높이 늘어남/줄어듦",
179
  "밀도 변화", "무게 증가/감소", "모양 변형", "상태 변화", "불균등 변형",
 
182
  "접힘/펼쳐짐", "압착/팽창", "늘어남/수축", "구겨짐/평평해짐", "뭉개짐/단단해짐",
183
  "말림/펴짐", "꺾임/구부러짐"
184
  ],
 
185
  "표면 및 외관 변화": [
186
+ "색상 변화", "질감 변화", "투명/불투명 변화", "반짝임/무광 변화",
187
+ "빛 반사 정도 변화", "무늬 변화", "각도에 따른 색상 변화", "빛에 따른 색상 변화",
188
+ "온도에 따른 색상 변화", "홀로그램 효과", "표면 각도별 빛 반사", "표면 모양 변형",
189
  "초미세 표면 구조 변화", "자가 세정 효과", "얼룩/패턴 생성", "흐림/선명함 변화",
190
+ "광택/윤기 변화", "색조/채도 변화", "발광/형광", "빛 산란 효과",
191
  "빛 흡수 변화", "반투명 효과", "그림자 효과 변화", "자외선 반응 변화",
192
  "야광 효과"
193
  ],
 
194
  "물질의 상태 변화": [
195
+ "고체/액체/기체 전환", "결정화/용해", "산화/부식", "딱딱해짐/부드러워짐",
196
+ "특수 상태 전환", "무정형/결정형 전환", "성분 분리", "미세 입자 형성/분해",
197
+ "젤 형성/풀어짐", "준안정 상태 변화", "분자 자가 정렬/분해", "상태변화 지연 현상",
198
  "녹음", "굳음", "증발/응축", "승화/증착", "침전/부유", "분산/응집",
199
  "건조/습윤", "팽윤/수축", "동결/해동", "풍화/침식", "충전/방전",
200
  "결합/분리", "발효/부패"
201
  ],
 
202
  "열 관련 변화": [
203
+ "온도 상승/하강", "열에 의한 팽창/수축", "열 전달/차단", "압력 상승/하강",
204
+ "열 변화에 따른 자화", "무질서도 변화", "열전기 현상", "자기장에 의한 열 변화",
205
+ "상태변화 중 열 저���/방출", "열 스트레스 발생/해소", "급격한 온도 변화 영향",
206
  "복사열에 의한 냉각/가열", "발열/흡열", "열 분포 변화", "열 반사/흡수",
207
  "냉각 응축", "열 활성화", "열 변색", "열 팽창 계수 변화", "열 안정성 변화",
208
  "내열성/내한성", "자기발열", "열적 평형/불균형", "열적 변형", "열 분산/집중"
209
  ],
 
210
  "움직임 특성 변화": [
211
+ "가속/감속", "일정 속도 유지", "진동/진동 감소", "부딪힘/튕김",
212
+ "회전 속도 증가/감소", "회전 방향 변화", "불규칙 움직임", "멈췄다 미끄러지는 현상",
213
+ "공진/반공진", "유체 속 저항/양력 변화", "움직임 저항 변화", "복합 진동 움직임",
214
  "특수 유체 속 움직임", "회전-이동 연계 움직임", "관성 정지", "충격 흡수",
215
  "충격 전달", "운동량 보존", "마찰력 변화", "관성 탈출", "불안정 균형",
216
  "동적 안정성", "흔들림 감쇠", "경로 예측성", "회피 움직임"
217
  ],
 
218
  "구조적 변화": [
219
  "부품 추가/제거", "조립/분해", "접기/펴기", "변형/원상복구", "최적 구조 변화",
220
  "자가 재배열", "자연 패턴 형성/소멸", "규칙적 패턴 변화", "모듈식 변형",
221
+ "복잡성 증가 구조", "원래 모양 기억 효과", "시간에 따른 형태 변화", "부분 제거",
222
  "부분 교체", "결합", "분리", "분할/통합", "중첩/겹침", "내부 구조 변화",
223
  "외부 구조 변화", "중심축 이동", "균형점 변화", "계층 구조 변화", "지지 구조 변화",
224
  "응력 분산 구조", "충격 흡수 구조", "그리드/매트릭스 구조 변화", "상호 연결성 변화"
225
  ],
 
226
  "전기 및 자기 변화": [
227
+ "자성 생성/소멸", "전하량 증가/감소", "전기장 생성/소멸", "자기장 생성/소멸",
228
+ "초전도 상태 전환", "강유전체 특성 변화", "양자 상태 변화", "플라즈마 상태 형성/소멸",
229
  "스핀파 전달", "빛에 의한 전기 발생", "압력에 의한 전기 발생", "자기장 속 전류 변화",
230
  "전기 저항 변화", "전기 전도성 변화", "정전기 발생/방전", "전자기 유도",
231
  "전자기파 방출/흡수", "전기 용량 변화", "자기 이력 현상", "전기적 분극",
232
  "전자 흐름 방향 변화", "전기적 공명", "전기적 차폐/노출", "자기 차폐/노출",
233
  "자기장 방향 정렬"
234
  ],
 
235
  "화학적 변화": [
236
  "표면 코팅 변화", "물질 성분 변화", "화학 반응 변화", "촉매 작용 시작/중단",
237
  "빛에 의한 화학 반응", "전기에 의한 화학 반응", "단분자막 형성", "분자 수준 계산 변화",
 
240
  "이온화", "화학적 흡착/탈착", "촉매 효율 변화", "효소 활성 변화", "발색 반응",
241
  "pH 변화", "화학적 평형 이동", "결합 형성/분해", "용해도 변화"
242
  ],
 
243
  "시간 관련 변화": [
244
  "노화/풍화", "마모/부식", "색 바램/변색", "손상/회복", "수명 주기 변화",
245
+ "사용자 상호작용에 따른 적응", "학습 기반 형태 최적화", "시간에 따른 물성 변화",
246
+ "집단 기억 효과", "문화적 의미 변화", "지연 반응", "이전 상태 의존 변화",
247
  "점진적 시간 변화", "진화적 변화", "주기적 재생", "계절 변화 적응",
248
+ "생체리듬 변화", "생애 주기 단계", "성장/퇴화", "자기 복구/재생",
249
  "자연 순환 적응", "지속성/일시성", "기억 효과", "지연된 작용", "누적 효과"
250
  ],
 
251
  "빛과 시각 효과": [
252
  "발광/소등", "빛 투과/차단", "빛 산란/집중", "색상 스펙트럼 변화", "빛 회절",
253
  "빛 간섭", "홀로그램 생성", "레이저 효과", "빛 편광", "형광/인광",
 
256
  "빔 효과", "광 필터 효과", "빛의 방향성 변화", "투영 효과", "빛 감지/반응",
257
  "광도 변화"
258
  ],
 
259
  "소리와 진동 효과": [
260
  "소리 발생/소멸", "소리 높낮이 변화", "소리 크기 변화", "음색 변화",
261
  "공명/반공명", "음향 진동", "초음파/저음파 발생", "음향 집중/분산",
262
  "음향 반사/흡수", "음향 도플러 효과", "음파 간섭", "음향 공진",
263
  "진동 패턴 변화", "타악 효과", "음향 피드백", "음향 차폐/증폭",
264
  "소리 지향성", "음향 왜곡", "비트 생성", "하모닉스 생성", "주파수 변조",
265
+ "음향 충격파", "음향 필터링"
266
  ],
 
267
  "생물학적 변화": [
268
  "생장/위축", "세포 분열/사멸", "생물 발광", "신진대사 변화", "면역 반응",
269
  "호르몬 분비", "신경 반응", "유전적 발현", "적응/진화", "생체리듬 변화",
 
272
  "생물학적 시계 변화", "세포외 기질 변화", "생체 역학적 반응", "세포 운동성",
273
  "세포 극성 변화", "영양 상태 변화"
274
  ],
 
275
  "환경 상호작용": [
276
  "온도 반응", "습도 반응", "기압 반응", "중력 반응", "자기장 반응",
277
  "빛 반응", "소리 반응", "화학 물질 감지", "기계적 자극 감지", "전기 자극 반응",
 
279
  "환경 오염 반응", "날씨 반응", "계절 변화 반응", "일주기 반응", "생태계 상호작용",
280
  "공생/경쟁 반응", "포식/피식 관계", "군집 형성", "영역 설정", "이주/정착 패턴"
281
  ],
 
282
  "센서 기능": [
283
  "시각 센서/감지", "청각 센서/감지", "촉각 센서/감지", "미각 센서/감지", "후각 센서/감지",
284
  "온도 센서/감지", "습도 센서/감지", "압력 센서/감지", "가속도 센서/감지", "회전 센서/감지",
 
287
  "생체신호 센서/감지", "진동 센서/감지", "소음 센서/감지", "빛 세기 센서/감지", "빛 파장 센서/감지",
288
  "기울기 센서/감지", "pH 센서/감지", "전류 센서/감지", "전압 센서/감지", "이미지 센서/감지",
289
  "거리 센서/감지", "깊이 센서/감지", "중력 센서/감지", "속도 센서/감지", "흐름 센서/감지",
290
+ "수위 센서/감지", "탁도 센서/감지", "염도 센서/감지", "금속 감지", "압전 센서/감지",
291
  "광전 센서/감지", "열전대 센서/감지", "홀 효과 센서/감지", "초음파 센서/감지", "레이더 센서/감지",
292
  "라이다 센서/감지", "터치 센서/감지", "제스처 센서/감지", "심박 센서/감지", "혈압 센서/감지"
293
  ]
294
  }
295
 
296
  ##############################################################################
297
+ # Gemini API 호출 함수
298
  ##############################################################################
299
  def query_gemini_api(prompt):
300
  try:
 
301
  model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21')
 
302
  response = model.generate_content(prompt)
 
 
303
  try:
304
  if hasattr(response, 'text'):
305
  return response.text
 
306
  if hasattr(response, 'candidates') and response.candidates:
307
+ candidate = response.candidates[0]
308
+ if hasattr(candidate, 'content'):
309
+ content = candidate.content
310
+ if hasattr(content, 'parts') and content.parts:
311
+ if len(content.parts) > 0:
312
+ return content.parts[0].text
 
313
  if hasattr(response, 'parts') and response.parts:
314
  if len(response.parts) > 0:
315
  return response.parts[0].text
 
316
  return "Unable to generate a response. API response structure is different than expected."
 
317
  except Exception as inner_e:
318
  logger.error(f"Error processing response: {inner_e}")
319
  return f"An error occurred while processing the response: {str(inner_e)}"
 
320
  except Exception as e:
321
  logger.error(f"Error calling Gemini API: {e}")
322
  if "API key not valid" in str(e):
 
324
  return f"An error occurred while calling the API: {str(e)}"
325
 
326
  ##############################################################################
327
+ # 설명 확장 함수 (LLM 이용)
328
  ##############################################################################
329
  def enhance_with_llm(base_description, obj_name, category):
330
  prompt = f"""
 
338
  return query_gemini_api(prompt)
339
 
340
  ##############################################################################
341
+ # 객체수(1, 2, 3)에 따른 변형 아이디어 생성
342
  ##############################################################################
343
+ def generate_single_object_transformation_for_category(obj, selected_category):
344
+ transformations = physical_transformation_categories.get(selected_category)
345
+ if not transformations:
346
+ return {}
347
+ transformation = choose_alternative(random.choice(transformations))
348
+ base_description = f"{obj}이(가) {transformation} 현상을 보인다"
349
+ return {selected_category: {"base": base_description, "enhanced": None}}
350
 
351
+ def generate_two_objects_interaction_for_category(obj1, obj2, selected_category):
352
+ transformations = physical_transformation_categories.get(selected_category)
353
+ if not transformations:
354
+ return {}
355
+ transformation = choose_alternative(random.choice(transformations))
356
+ template = random.choice([
357
+ "{obj1}이(가) {obj2}에 결합하여 {change}가 발생했다",
358
+ "{obj1}과(와) {obj2}이(가) 충돌하면서 {change}가 일어났다"
359
+ ])
360
+ base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
361
+ return {selected_category: {"base": base_description, "enhanced": None}}
 
 
 
362
 
363
+ def generate_three_objects_interaction_for_category(obj1, obj2, obj3, selected_category):
364
+ transformations = physical_transformation_categories.get(selected_category)
365
+ if not transformations:
366
+ return {}
367
+ transformation = choose_alternative(random.choice(transformations))
368
+ template = random.choice([
369
+ "{obj1}, {obj2}, {obj3}이() 삼각형 구조로 결합하여 {change}가 발생했다",
370
+ "{obj1}이(가) {obj2}와(과) {obj3} 사이에서 매개체 역할을 하며 {change}를 촉진했다"
371
+ ])
372
+ base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
373
+ return {selected_category: {"base": base_description, "enhanced": None}}
 
 
 
374
 
375
  ##############################################################################
376
+ # 생성된 기본 설명을 LLM을 통해 확장 (각 카테고리별)
377
  ##############################################################################
378
  def enhance_descriptions(results, objects):
 
379
  obj_name = " 및 ".join([obj for obj in objects if obj])
 
380
  for category, result in results.items():
381
  result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
 
382
  return results
383
 
384
  ##############################################################################
385
+ # 사용자 입력(최대 3개 키워드) + 선택 카테고리 → 변화 아이디어 생성
386
  ##############################################################################
387
+ def generate_transformations(text1, text2, text3, selected_category):
 
 
388
  if text2 and text3:
389
+ results = generate_three_objects_interaction_for_category(text1, text2, text3, selected_category)
390
  objects = [text1, text2, text3]
391
  elif text2:
392
+ results = generate_two_objects_interaction_for_category(text1, text2, selected_category)
393
  objects = [text1, text2]
394
  else:
395
+ results = generate_single_object_transformation_for_category(text1, selected_category)
396
  objects = [text1]
 
397
  return enhance_descriptions(results, objects)
398
 
399
  ##############################################################################
 
406
  return formatted
407
 
408
  ##############################################################################
409
+ # Gradio UI에서 호출될 함수 (텍스트 아이디어만 생성)
410
  ##############################################################################
411
+ def process_inputs(text1, text2, text3, selected_category, progress=gr.Progress()):
412
  text1 = text1.strip() if text1 else None
413
  text2 = text2.strip() if text2 else None
414
  text3 = text3.strip() if text3 else None
 
416
  if not text1:
417
  return "오류: 최소 하나의 키워드를 입력해주세요."
418
 
419
+ progress(0.05, desc="아이디어 생성 준비 중...")
420
+ time.sleep(0.3)
421
+ progress(0.1, desc="창의적인 아이디어 생성 시작...")
422
 
423
+ # 카테고리에 해당하는 아이디어 생성
424
+ results = generate_transformations(text1, text2, text3, selected_category)
 
 
 
 
425
 
426
+ progress(0.8, desc="결과 포맷팅 중...")
427
+ formatted = format_results(results)
428
+ progress(1.0, desc="완료!")
429
+ return formatted
430
+
431
+ ##############################################################################
432
+ # 아이디어와 이미지를 함께 생성하는 최종 함수
433
+ ##############################################################################
434
+ def process_all(text1, text2, text3, selected_category, progress=gr.Progress()):
435
+ idea_result = process_inputs(text1, text2, text3, selected_category, progress)
436
+ image_result = generate_design_image(
437
+ idea_result,
438
+ seed=42,
439
+ randomize_seed=True,
440
+ width=1024,
441
+ height=1024,
442
+ num_inference_steps=4
443
+ )
444
+ return idea_result, image_result
 
445
 
446
  ##############################################################################
447
  # API 키 경고 메시지
 
454
  ##############################################################################
455
  # Gradio UI
456
  ##############################################################################
457
+ with gr.Blocks(
458
+ title="키워드 기반 창의적 변화 아이디어 및 디자인 생성기",
459
+ theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")
460
+ ) as demo:
461
 
462
  gr.HTML("""
463
  <style>
464
+ body {
465
+ background: linear-gradient(135deg, #e0eafc, #cfdef3);
466
+ font-family: 'Arial', sans-serif;
467
+ }
468
+ .gradio-container {
469
+ padding: 20px;
470
+ }
471
+ h1, h2 {
472
+ text-align: center;
473
+ }
474
+ h1 {
475
+ color: #333;
476
+ }
477
+ h2 {
478
+ color: #555;
479
+ }
480
+ .output {
481
+ background-color: #ffffff;
482
+ padding: 15px;
483
+ border-radius: 8px;
484
+ }
485
+ .gr-button {
486
+ background-color: #4CAF50;
487
+ color: white;
488
+ border: none;
489
+ border-radius: 4px;
490
+ padding: 8px 16px;
491
+ }
492
+ .progress-message {
493
+ color: #2196F3;
494
+ font-weight: bold;
495
+ margin-top: 10px;
496
+ }
497
  </style>
498
  """)
499
 
500
+ gr.Markdown("# 🚀 키워드 기반 창의적 변화 아이디어 및 디자인 생성기")
501
+ gr.Markdown("입력한 **키워드**(최대 3개) **카테고리**를 바탕으로, 창의적인 모델/컨셉/형상 변화 아이디어를 생성하고, 해당 확장 아이디어를 프롬프트로 하여 디자인 이미지를 생성합니다.")
502
 
503
  warning = gr.Markdown(get_warning_message())
504
 
 
505
  with gr.Row():
506
  with gr.Column(scale=1):
507
  text_input1 = gr.Textbox(label="키워드 1 (필수)", placeholder="예: 스마트폰")
508
  text_input2 = gr.Textbox(label="키워드 2 (선택)", placeholder="예: 인공지능")
509
  text_input3 = gr.Textbox(label="키워드 3 (선택)", placeholder="예: 헬스케어")
510
+ category_dropdown = gr.Dropdown(
511
+ label="카테고리 선택",
512
+ choices=list(physical_transformation_categories.keys()),
513
+ value=list(physical_transformation_categories.keys())[0],
514
+ info="출력할 카테고리를 선택하세요."
515
+ )
516
+ status_msg = gr.Markdown("💡 '아이디어 생성하기' 버튼을 클릭하면 선택한 카테고리에 해당하는 아이디어와 디자인 이미지가 생성됩니다.")
517
 
 
 
 
 
518
  processing_indicator = gr.HTML("""
519
  <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
520
  <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
 
530
 
531
  submit_button = gr.Button("아이디어 생성하기", variant="primary")
532
 
 
533
  with gr.Column(scale=2):
534
  idea_output = gr.Markdown(label="아이디어 결과")
535
+ generated_image = gr.Image(label="생성된 디자인 이미지", type="pil")
536
+
537
+ # 예제
538
  gr.Examples(
539
  examples=[
540
+ ["스마트폰", "", "", list(physical_transformation_categories.keys())[0]],
541
+ ["자동차", "", "", list(physical_transformation_categories.keys())[0]],
542
+ ["자동차", "인공지능", "", list(physical_transformation_categories.keys())[0]],
543
+ ["드론", "인공지능", "", list(physical_transformation_categories.keys())[0]],
544
+ ["운동화", "웨어러블", "건강", list(physical_transformation_categories.keys())[0]],
545
  ],
546
+ inputs=[text_input1, text_input2, text_input3, category_dropdown],
547
  )
548
 
549
+ # 처리중 아이콘 보이기
550
  def show_processing_indicator():
551
  return gr.update(visible=True)
552
 
553
+ # 처리중 아이콘 숨기기
554
  def hide_processing_indicator():
555
  return gr.update(visible=False)
556
 
557
+ # 버튼 클릭 처리 로직
558
  submit_button.click(
559
  fn=show_processing_indicator,
560
  inputs=None,
561
  outputs=processing_indicator
562
  ).then(
563
+ fn=process_all,
564
+ inputs=[text_input1, text_input2, text_input3, category_dropdown],
565
+ outputs=[idea_output, generated_image]
566
  ).then(
567
  fn=hide_processing_indicator,
568
  inputs=None,
569
  outputs=processing_indicator
570
  )
571
 
572
+ # 메인 실행
573
  if __name__ == "__main__":
574
+ demo.launch(debug=True)