Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -1,9 +1,14 @@
|
|
|
|
|
|
1 |
import os
|
2 |
import gradio as gr
|
3 |
import random
|
4 |
import time
|
5 |
import logging
|
|
|
|
|
6 |
import google.generativeai as genai
|
|
|
7 |
|
8 |
logging.basicConfig(
|
9 |
level=logging.INFO,
|
@@ -15,10 +20,16 @@ logging.basicConfig(
|
|
15 |
)
|
16 |
logger = logging.getLogger("idea_generator")
|
17 |
|
|
|
18 |
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
|
19 |
genai.configure(api_key=GEMINI_API_KEY)
|
20 |
|
|
|
|
|
21 |
|
|
|
|
|
|
|
22 |
def choose_alternative(transformation):
|
23 |
if "/" not in transformation:
|
24 |
return transformation
|
@@ -40,6 +51,9 @@ def choose_alternative(transformation):
|
|
40 |
else:
|
41 |
return random.choice([left, right])
|
42 |
|
|
|
|
|
|
|
43 |
|
44 |
physical_transformation_categories = {
|
45 |
"๊ณต๊ฐ ์ด๋": [
|
@@ -181,38 +195,60 @@ physical_transformation_categories = {
|
|
181 |
"๋ผ์ด๋ค ์ผ์/๊ฐ์ง", "ํฐ์น ์ผ์/๊ฐ์ง", "์ ์ค์ฒ ์ผ์/๊ฐ์ง", "์ฌ๋ฐ ์ผ์/๊ฐ์ง", "ํ์ ์ผ์/๊ฐ์ง"
|
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 |
prompt = f"""
|
217 |
๋ค์์ '{obj_name}'์ '{category}' ๊ด๋ จ ๊ฐ๋จํ ์ค๋ช
์
๋๋ค:
|
218 |
"{base_description}"
|
@@ -221,18 +257,24 @@ def enhance_with_llm(base_description, obj_name, category):
|
|
221 |
2) ํ์ ํฌ์ธํธ์ ๊ธฐ๋ฅ์ฑ ๋ฑ์ ์ค์ฌ์ผ๋ก
|
222 |
3~4๋ฌธ์ฅ์ ์์ด๋์ด๋ก ํ์ฅํด ์ฃผ์ธ์.
|
223 |
"""
|
224 |
-
|
225 |
-
|
|
|
226 |
|
|
|
|
|
|
|
227 |
def generate_single_object_transformations(obj):
|
228 |
results = {}
|
229 |
for category, transformations in physical_transformation_categories.items():
|
230 |
transformation = choose_alternative(random.choice(transformations))
|
231 |
base_description = f"{obj}์ด(๊ฐ) {transformation} ํ์์ ๋ณด์ธ๋ค"
|
232 |
-
results[category] = {"base": base_description, "enhanced":
|
233 |
return results
|
234 |
|
235 |
-
|
|
|
|
|
236 |
def generate_two_objects_interaction(obj1, obj2):
|
237 |
results = {}
|
238 |
for category, transformations in physical_transformation_categories.items():
|
@@ -242,10 +284,12 @@ def generate_two_objects_interaction(obj1, obj2):
|
|
242 |
"{obj1}๊ณผ(์) {obj2}์ด(๊ฐ) ์ถฉ๋ํ๋ฉด์ {change}๊ฐ ์ผ์ด๋ฌ๋ค"
|
243 |
])
|
244 |
base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
|
245 |
-
results[category] = {"base": base_description, "enhanced":
|
246 |
return results
|
247 |
|
248 |
-
|
|
|
|
|
249 |
def generate_three_objects_interaction(obj1, obj2, obj3):
|
250 |
results = {}
|
251 |
for category, transformations in physical_transformation_categories.items():
|
@@ -255,17 +299,12 @@ def generate_three_objects_interaction(obj1, obj2, obj3):
|
|
255 |
"{obj1}์ด(๊ฐ) {obj2}์(๊ณผ) {obj3} ์ฌ์ด์์ ๋งค๊ฐ์ฒด ์ญํ ์ ํ๋ฉฐ {change}๋ฅผ ์ด์งํ๋ค"
|
256 |
])
|
257 |
base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
|
258 |
-
results[category] = {"base": base_description, "enhanced":
|
259 |
-
return results
|
260 |
-
|
261 |
-
|
262 |
-
def enhance_descriptions(results, objects):
|
263 |
-
obj_name = " ๋ฐ ".join([obj for obj in objects if obj])
|
264 |
-
for category, result in results.items():
|
265 |
-
result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
|
266 |
return results
|
267 |
|
268 |
-
|
|
|
|
|
269 |
def generate_transformations(text1, text2=None, text3=None):
|
270 |
if text2 and text3:
|
271 |
results = generate_three_objects_interaction(text1, text2, text3)
|
@@ -276,106 +315,137 @@ def generate_transformations(text1, text2=None, text3=None):
|
|
276 |
else:
|
277 |
results = generate_single_object_transformations(text1)
|
278 |
objects = [text1]
|
279 |
-
return
|
280 |
-
|
281 |
-
|
282 |
-
def format_results(results):
|
283 |
-
formatted = ""
|
284 |
-
for category, result in results.items():
|
285 |
-
formatted += f"## {category}\n**๊ธฐ๋ณธ ์์ด๋์ด**: {result['base']}\n\n**ํ์ฅ๋ ์์ด๋์ด**: {result['enhanced']}\n\n---\n\n"
|
286 |
-
return formatted
|
287 |
-
|
288 |
|
289 |
##############################################################################
|
290 |
-
#
|
291 |
##############################################################################
|
292 |
-
def process_inputs_stream(text1, text2, text3):
|
293 |
-
|
294 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
295 |
time.sleep(0.3)
|
296 |
-
|
297 |
text1 = text1.strip() if text1 else None
|
298 |
text2 = text2.strip() if text2 else None
|
299 |
text3 = text3.strip() if text3 else None
|
300 |
if not text1:
|
301 |
-
yield "์ค๋ฅ: ์ต์ ํ๋์ ํค์๋๋ฅผ ์
๋ ฅํด์ฃผ์ธ์."
|
302 |
-
return
|
303 |
-
|
304 |
-
# 2)
|
305 |
-
yield "์ฐฝ์์ ์ธ ๋ชจ๋ธ/์ปจ์
/ํ์ ๋ณํ ์์ด๋์ด ์์ฑ ์ค..."
|
306 |
-
time.sleep(0.3)
|
307 |
-
|
308 |
-
# 3) ์ค์ ์์ด๋์ด ์์ฑ
|
309 |
-
results = generate_transformations(text1, text2, text3)
|
310 |
-
|
311 |
-
# 4) ์ค๊ฐ ๋จ๊ณ ์ถ๋ ฅ
|
312 |
-
yield "๊ฒฐ๊ณผ ํฌ๋งทํ
์ค..."
|
313 |
time.sleep(0.3)
|
314 |
-
|
315 |
-
# 5) ์ต์ข
๊ฒฐ๊ณผ ์ ๋ฆฌ
|
316 |
-
formatted = format_results(results)
|
317 |
-
|
318 |
-
# 6) ๊ฒฐ๊ณผ ์ถ๋ ฅ
|
319 |
-
yield formatted
|
320 |
-
|
321 |
-
# 7) ์๋ฃ
|
322 |
-
yield "์๋ฃ!"
|
323 |
|
324 |
-
|
325 |
-
if
|
326 |
-
return "โ ๏ธ ํ๊ฒฝ ๋ณ์ GEMINI_API_KEY๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค. Gemini API ํค๋ฅผ ์ค์ ํ์ธ์."
|
327 |
-
return ""
|
328 |
|
|
|
|
|
329 |
|
330 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")) as demo:
|
332 |
-
|
333 |
-
gr.
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
</style>
|
343 |
-
""")
|
344 |
-
|
345 |
-
gr.Markdown("# ๐ ํค์๋ ๊ธฐ๋ฐ ์ฐฝ์์ ๋ณํ ์์ด๋์ด ์์ฑ๊ธฐ")
|
346 |
-
gr.Markdown("์
๋ ฅํ **ํค์๋**(์ต๋ 3๊ฐ)๋ฅผ ๋ฐํ์ผ๋ก, **์ฐฝ์์ ์ธ ๋ชจ๋ธ/์ปจ์
/ํ์ ๋ณํ**์ ๋ํ ์ดํด์ **ํ์ ํฌ์ธํธ**, **๊ธฐ๋ฅ์ฑ** ๋ฑ์ ์ค์ฌ์ผ๋ก ํ์ฅ๋ ์์ด๋์ด๋ฅผ ์ ์ํฉ๋๋ค.")
|
347 |
-
|
348 |
-
warning = gr.Markdown(get_warning_message())
|
349 |
-
|
350 |
with gr.Row():
|
351 |
with gr.Column(scale=1):
|
352 |
-
text_input1 = gr.Textbox(label="ํค์๋ 1 (ํ์)", placeholder="์:
|
353 |
-
text_input2 = gr.Textbox(label="ํค์๋ 2 (์ ํ)", placeholder="์:
|
354 |
-
text_input3 = gr.Textbox(label="ํค์๋ 3 (์ ํ)", placeholder="์:
|
355 |
submit_button = gr.Button("์์ด๋์ด ์์ฑํ๊ธฐ")
|
|
|
|
|
356 |
|
357 |
with gr.Column(scale=2):
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
],
|
369 |
-
|
370 |
-
)
|
371 |
-
|
372 |
-
# stream=True ์ต์
์ ํตํด ํจ์๊ฐ yieldํ๋ ๋ฌธ์์ด์ ์ค์๊ฐ ์ถ๋ ฅ
|
373 |
submit_button.click(
|
374 |
-
fn=process_inputs_stream,
|
375 |
inputs=[text_input1, text_input2, text_input3],
|
376 |
-
outputs=
|
377 |
-
stream=True
|
|
|
|
|
|
|
|
|
|
|
378 |
)
|
379 |
|
380 |
if __name__ == "__main__":
|
381 |
demo.launch(debug=True)
|
|
|
|
1 |
+
|
2 |
+
|
3 |
import os
|
4 |
import gradio as gr
|
5 |
import random
|
6 |
import time
|
7 |
import logging
|
8 |
+
from typing import Iterator
|
9 |
+
|
10 |
import google.generativeai as genai
|
11 |
+
from gradio import ChatMessage # ChatMessage ๊ตฌ์กฐ ์ฌ์ฉ (Thinking/Response ๊ตฌ๋ถ ๊ฐ๋ฅ)
|
12 |
|
13 |
logging.basicConfig(
|
14 |
level=logging.INFO,
|
|
|
20 |
)
|
21 |
logger = logging.getLogger("idea_generator")
|
22 |
|
23 |
+
# Gemini API ํค ์ค์
|
24 |
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
|
25 |
genai.configure(api_key=GEMINI_API_KEY)
|
26 |
|
27 |
+
# ์ฌ์ฉํ Gemini 2.0 Flash ๋ชจ๋ธ (Thinking ๊ธฐ๋ฅ ํฌํจ)
|
28 |
+
model = genai.GenerativeModel("gemini-2.0-flash-thinking-exp-01-21")
|
29 |
|
30 |
+
##############################################################################
|
31 |
+
# ๋ณํ ๋ฌธ์์ด์์ ์ฌ๋์("/")๋ก ๊ตฌ๋ถ๋ ๋ ์ต์
์ค ํ๋ ์ ํ
|
32 |
+
##############################################################################
|
33 |
def choose_alternative(transformation):
|
34 |
if "/" not in transformation:
|
35 |
return transformation
|
|
|
51 |
else:
|
52 |
return random.choice([left, right])
|
53 |
|
54 |
+
##############################################################################
|
55 |
+
# ์นดํ
๊ณ ๋ฆฌ ์ฌ์ (์ผ๋ถ๋ง ๋ฐ์ท ๊ฐ๋ฅ. ์ฌ๊ธฐ์๋ ์์๋ก 3๊ฐ๋ง ์ ์ง)
|
56 |
+
##############################################################################
|
57 |
|
58 |
physical_transformation_categories = {
|
59 |
"๊ณต๊ฐ ์ด๋": [
|
|
|
195 |
"๋ผ์ด๋ค ์ผ์/๊ฐ์ง", "ํฐ์น ์ผ์/๊ฐ์ง", "์ ์ค์ฒ ์ผ์/๊ฐ์ง", "์ฌ๋ฐ ์ผ์/๊ฐ์ง", "ํ์ ์ผ์/๊ฐ์ง"
|
196 |
]
|
197 |
}
|
198 |
+
##############################################################################
|
199 |
+
# ์คํธ๋ฆฌ๋ฐ์ฉ Gemini API ํจ์:
|
200 |
+
# - 'Thinking' ๋จ๊ณ(์์ด๋์ด ๋ด๋ถ ์ถ๋ก )์ ์ต์ข
'Response' ๋จ๊ณ๋ก ๊ตฌ์ฑ
|
201 |
+
##############################################################################
|
202 |
+
def query_gemini_api_stream(prompt: str) -> Iterator[str]:
|
203 |
+
"""
|
204 |
+
Gemini 2.0 Flash with 'Thinking' ๋ถ๋ถ๊ณผ 'Response' ๋ถ๋ถ์
|
205 |
+
๋ถ๋ฆฌํ์ฌ ์คํธ๋ฆฌ๋ฐ(Chunk)์ผ๋ก ์ ๊ณตํ๋ค.
|
206 |
+
"""
|
207 |
+
# chat ์ด๊ธฐํ (history ์์ด ๋จ๋ฐ์ฑ ํธ์ถ)
|
208 |
+
chat = model.start_chat(history=[])
|
209 |
+
response = chat.send_message(prompt, stream=True)
|
210 |
+
|
211 |
+
thought_buffer = ""
|
212 |
+
response_buffer = ""
|
213 |
+
thinking_complete = False
|
214 |
|
215 |
+
for chunk in response:
|
216 |
+
# ๊ฐ chunk์๋ candidates[0].content.parts๊ฐ ๋ค์ด์๋ค
|
217 |
+
parts = chunk.candidates[0].content.parts
|
218 |
+
|
219 |
+
# ์์) parts๊ฐ 2๊ฐ์ด๋ฉด (0: Thinking, 1: Response ์์)
|
220 |
+
# ๊ทธ ์ธ์๋ 1๊ฐ์ฉ ๋์ด์ ๋ค์ด์ฌ ์ ์์
|
221 |
+
if len(parts) == 2 and not thinking_complete:
|
222 |
+
# ์์ง Thinking ์ค์ธ๋ฐ, ์์ฑ๋ Thinking + Response ์์์ด ํ ๋ฒ์ ์ด
|
223 |
+
thought_buffer += parts[0].text
|
224 |
+
yield f"[Thinking Chunk] {parts[0].text}"
|
225 |
+
|
226 |
+
response_buffer = parts[1].text
|
227 |
+
yield f"[Response Start] {parts[1].text}"
|
228 |
+
|
229 |
+
thinking_complete = True
|
230 |
+
elif thinking_complete:
|
231 |
+
# ์ด๋ฏธ Thinking์ ๋๋จ โ Response๋ฅผ ์ด์ด์ ์คํธ๋ฆฌ๋ฐ
|
232 |
+
current_chunk = parts[0].text
|
233 |
+
response_buffer += current_chunk
|
234 |
+
yield current_chunk
|
235 |
+
else:
|
236 |
+
# Thinking ์งํ ์ค (parts๊ฐ 1๊ฐ์ฉ ์ถ๊ฐ๋จ)
|
237 |
+
current_chunk = parts[0].text
|
238 |
+
thought_buffer += current_chunk
|
239 |
+
yield f"[Thinking Chunk] {current_chunk}"
|
240 |
+
|
241 |
+
# ์คํธ๋ฆฌ๋ฐ ๏ฟฝ๏ฟฝ๏ฟฝ๋ฃ ํ ์ต์ข
๊ฒฐ๊ณผ ํ๋ฒ์ ์ ๊ณตํ ์๋ ์์
|
242 |
+
yield f"\n[Final Response]\n{response_buffer}"
|
243 |
+
|
244 |
+
##############################################################################
|
245 |
+
# ์นดํ
๊ณ ๋ฆฌ๋ณ ๊ฐ๋จ ์ค๋ช
์ 'Thinking' + 'Response'๋ก ํ์ฅ (์คํธ๋ฆฌ๋ฐ)
|
246 |
+
##############################################################################
|
247 |
+
def enhance_with_llm_stream(base_description, obj_name, category) -> Iterator[str]:
|
248 |
+
"""
|
249 |
+
๊ธฐ์กด enhance_with_llm๋ฅผ ์คํธ๋ฆฌ๋ฐ ํํ๋ก ๋ฐ๊พผ ํจ์:
|
250 |
+
'Thinking' + 'Response' ๋จ๊ณ๋ฅผ chunk๋ก ์์ฐจ ์ ๋ฌ
|
251 |
+
"""
|
252 |
prompt = f"""
|
253 |
๋ค์์ '{obj_name}'์ '{category}' ๊ด๋ จ ๊ฐ๋จํ ์ค๋ช
์
๋๋ค:
|
254 |
"{base_description}"
|
|
|
257 |
2) ํ์ ํฌ์ธํธ์ ๊ธฐ๋ฅ์ฑ ๋ฑ์ ์ค์ฌ์ผ๋ก
|
258 |
3~4๋ฌธ์ฅ์ ์์ด๋์ด๋ก ํ์ฅํด ์ฃผ์ธ์.
|
259 |
"""
|
260 |
+
# query_gemini_api_stream()๋ก๋ถํฐ chunk๋ฅผ ๋ฐ์ ๊ทธ๋๋ก yield
|
261 |
+
for chunk in query_gemini_api_stream(prompt):
|
262 |
+
yield chunk
|
263 |
|
264 |
+
##############################################################################
|
265 |
+
# ํ ํค์๋(์ค๋ธ์ ํธ)์ ๋ํ ๊ธฐ๋ณธ ์์ด๋์ด(์นดํ
๊ณ ๋ฆฌ๋ณ) ์์ฑ
|
266 |
+
##############################################################################
|
267 |
def generate_single_object_transformations(obj):
|
268 |
results = {}
|
269 |
for category, transformations in physical_transformation_categories.items():
|
270 |
transformation = choose_alternative(random.choice(transformations))
|
271 |
base_description = f"{obj}์ด(๊ฐ) {transformation} ํ์์ ๋ณด์ธ๋ค"
|
272 |
+
results[category] = {"base": base_description, "enhanced": ""}
|
273 |
return results
|
274 |
|
275 |
+
##############################################################################
|
276 |
+
# 2๊ฐ ํค์๋ ์ํธ์์ฉ
|
277 |
+
##############################################################################
|
278 |
def generate_two_objects_interaction(obj1, obj2):
|
279 |
results = {}
|
280 |
for category, transformations in physical_transformation_categories.items():
|
|
|
284 |
"{obj1}๊ณผ(์) {obj2}์ด(๊ฐ) ์ถฉ๋ํ๋ฉด์ {change}๊ฐ ์ผ์ด๋ฌ๋ค"
|
285 |
])
|
286 |
base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
|
287 |
+
results[category] = {"base": base_description, "enhanced": ""}
|
288 |
return results
|
289 |
|
290 |
+
##############################################################################
|
291 |
+
# 3๊ฐ ํค์๋ ์ํธ์์ฉ
|
292 |
+
##############################################################################
|
293 |
def generate_three_objects_interaction(obj1, obj2, obj3):
|
294 |
results = {}
|
295 |
for category, transformations in physical_transformation_categories.items():
|
|
|
299 |
"{obj1}์ด(๊ฐ) {obj2}์(๊ณผ) {obj3} ์ฌ์ด์์ ๋งค๊ฐ์ฒด ์ญํ ์ ํ๋ฉฐ {change}๋ฅผ ์ด์งํ๋ค"
|
300 |
])
|
301 |
base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
|
302 |
+
results[category] = {"base": base_description, "enhanced": ""}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
return results
|
304 |
|
305 |
+
##############################################################################
|
306 |
+
# ์ค์ ๋ณํ ์์ฑ ๋ก์ง
|
307 |
+
##############################################################################
|
308 |
def generate_transformations(text1, text2=None, text3=None):
|
309 |
if text2 and text3:
|
310 |
results = generate_three_objects_interaction(text1, text2, text3)
|
|
|
315 |
else:
|
316 |
results = generate_single_object_transformations(text1)
|
317 |
objects = [text1]
|
318 |
+
return results, objects
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
|
320 |
##############################################################################
|
321 |
+
# ์คํธ๋ฆฌ๋ฐ: ๊ฐ ์นดํ
๊ณ ๋ฆฌ๋ณ๋ก 'Thinking' + 'Response' ๋ถ๋ถ์ ์ค์๊ฐ ์ ๋ฌ
|
322 |
##############################################################################
|
323 |
+
def process_inputs_stream(text1, text2, text3) -> Iterator[list]:
|
324 |
+
"""
|
325 |
+
Gradio์ Chatbot ํ์์ ๋ง์ถฐ์,
|
326 |
+
[(role='assistant'|'user', content=...), ...] ํํ๋ก yieldํ๋ค.
|
327 |
+
์๊ฐ(Thinking) ๋จ๊ณ์ ์ต์ข
์๋ต์ ๋ถ๋ฆฌํด์ ์ค์๊ฐ ์ ์ก.
|
328 |
+
"""
|
329 |
+
messages = []
|
330 |
+
|
331 |
+
# 1) ์
๋ ฅ๊ฐ ํ์ธ
|
332 |
+
yield [("assistant", "์
๋ ฅ๊ฐ ํ์ธ ์ค...")]
|
333 |
time.sleep(0.3)
|
334 |
+
|
335 |
text1 = text1.strip() if text1 else None
|
336 |
text2 = text2.strip() if text2 else None
|
337 |
text3 = text3.strip() if text3 else None
|
338 |
if not text1:
|
339 |
+
yield [("assistant", "์ค๋ฅ: ์ต์ ํ๋์ ํค์๋๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.")]
|
340 |
+
return
|
341 |
+
|
342 |
+
# 2) ์์ด๋์ด ์์ฑ
|
343 |
+
yield [("assistant", "์ฐฝ์์ ์ธ ๋ชจ๋ธ/์ปจ์
/ํ์ ๋ณํ ์์ด๋์ด ์์ฑ ์ค... (์นดํ
๊ณ ๋ฆฌ๋ณ ๋ถ์)")]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
time.sleep(0.3)
|
345 |
+
results, objects = generate_transformations(text1, text2, text3)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
|
347 |
+
# ์นดํ
๊ณ ๋ฆฌ๋ณ ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ
|
348 |
+
obj_name = " ๋ฐ ".join([obj for obj in objects if obj])
|
|
|
|
|
349 |
|
350 |
+
for i, (category, result_dict) in enumerate(results.items(), start=1):
|
351 |
+
base_desc = result_dict["base"]
|
352 |
|
353 |
+
# ์นดํ
๊ณ ๋ฆฌ ์๋ด ์ถ๋ ฅ
|
354 |
+
yield [("assistant", f"**[{i}/{len(results)}] ์นดํ
๊ณ ๋ฆฌ:** {category}\n\n๊ธฐ๋ณธ ์์ด๋์ด: {base_desc}\n\n์ง๊ธ๋ถํฐ Thinking + Response๋ฅผ ๋จ๊ณ์ ์ผ๋ก ์คํธ๋ฆฌ๋ฐํฉ๋๋ค...")]
|
355 |
+
time.sleep(0.5)
|
356 |
+
|
357 |
+
# ์คํธ๋ฆฌ๋ฐ LLM ํธ์ถ
|
358 |
+
thinking_text = ""
|
359 |
+
response_text = ""
|
360 |
+
is_thinking_done = False
|
361 |
+
|
362 |
+
# enhance_with_llm_stream ํธ์ถ
|
363 |
+
for chunk in enhance_with_llm_stream(base_desc, obj_name, category):
|
364 |
+
if chunk.startswith("[Thinking Chunk]"):
|
365 |
+
# ์๊ฐ ํํธ
|
366 |
+
thinking_text += chunk.replace("[Thinking Chunk]", "")
|
367 |
+
messages_to_user = f"**[Thinking]**\n{thinking_text}"
|
368 |
+
yield [("assistant", messages_to_user)]
|
369 |
+
elif chunk.startswith("[Response Start]"):
|
370 |
+
# ์๋ต ์์ ์์
|
371 |
+
is_thinking_done = True
|
372 |
+
# ๋จ์์๋ ๋ถ๋ถ์ response_text๋ก
|
373 |
+
partial = chunk.replace("[Response Start]", "")
|
374 |
+
response_text += partial
|
375 |
+
messages_to_user = f"**[Final Response ์์]**\n{partial}"
|
376 |
+
yield [("assistant", messages_to_user)]
|
377 |
+
elif chunk.startswith("[Final Response]"):
|
378 |
+
# ์ต์ข
์ข
๋ฃ
|
379 |
+
final = chunk.replace("[Final Response]", "")
|
380 |
+
response_text += f"\n{final}"
|
381 |
+
yield [("assistant", f"**[์ต์ข
Response]**\n{response_text.strip()}")]
|
382 |
+
else:
|
383 |
+
# ์ผ๋ฐ ์๋ต ์คํธ๋ฆฌ๋ฐ
|
384 |
+
if is_thinking_done:
|
385 |
+
response_text += chunk
|
386 |
+
yield [("assistant", f"**[์๋ต ์งํ]**\n{response_text}") ]
|
387 |
+
else:
|
388 |
+
thinking_text += chunk
|
389 |
+
yield [("assistant", f"**[Thinking]**\n{thinking_text}")]
|
390 |
+
|
391 |
+
# ํ ์นดํ
๊ณ ๋ฆฌ ์๋ต ์๋ฃ
|
392 |
+
result_dict["enhanced"] = response_text
|
393 |
+
|
394 |
+
# 3) ์ ์ฒด ์นดํ
๊ณ ๋ฆฌ ์๋ฃ
|
395 |
+
yield [("assistant", "**๋ชจ๋ ์นดํ
๊ณ ๋ฆฌ์ ๋ํ ์คํธ๋ฆฌ๋ฐ์ด ์๋ฃ๋์์ต๋๋ค!**")]
|
396 |
+
|
397 |
+
|
398 |
+
##############################################################################
|
399 |
+
# Gradio UI
|
400 |
+
##############################################################################
|
401 |
+
with gr.Blocks(title="์คํธ๋ฆฌ๋ฐ ์์ : Gemini 2.0 Flash Thinking",
|
402 |
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")) as demo:
|
403 |
+
|
404 |
+
gr.Markdown("# ๐ ํค์๋ ๊ธฐ๋ฐ ์ฐฝ์์ ๋ณํ ์์ด๋์ด (Gemini 2.0 Flash Thinking, Streaming)")
|
405 |
+
gr.Markdown("ํค์๋ 1~3๊ฐ๋ฅผ ์
๋ ฅํ๋ฉด, **์นดํ
๊ณ ๋ฆฌ๋ณ๋ก** 'Thinking'๊ณผ 'Response'๊ฐ ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ๋ฉ๋๋ค.")
|
406 |
+
|
407 |
+
chatbot = gr.Chatbot(
|
408 |
+
label="์นดํ
๊ณ ๋ฆฌ๋ณ ์์ด๋์ด(Thinking + Response) ์คํธ๋ฆฌ๋ฐ",
|
409 |
+
type="tuple", # (role, content) ์์ ๋ฆฌ์คํธ๋ก ์ ๋ฌ
|
410 |
+
render_markdown=True
|
411 |
+
)
|
412 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
413 |
with gr.Row():
|
414 |
with gr.Column(scale=1):
|
415 |
+
text_input1 = gr.Textbox(label="ํค์๋ 1 (ํ์)", placeholder="์: ์๋์ฐจ")
|
416 |
+
text_input2 = gr.Textbox(label="ํค์๋ 2 (์ ํ)", placeholder="์: ๋ก๋ด")
|
417 |
+
text_input3 = gr.Textbox(label="ํค์๋ 3 (์ ํ)", placeholder="์: ์ธ๊ณต์ง๋ฅ")
|
418 |
submit_button = gr.Button("์์ด๋์ด ์์ฑํ๊ธฐ")
|
419 |
+
|
420 |
+
clear_button = gr.Button("๋ํ ์ง์ฐ๊ธฐ")
|
421 |
|
422 |
with gr.Column(scale=2):
|
423 |
+
# ์ด๋ฏธ chatbot์ด ์๋ฆฌ๋ฅผ ์ฐจ์งํ๋ฏ๋ก ํจ์ค
|
424 |
+
pass
|
425 |
+
|
426 |
+
def clear_chat():
|
427 |
+
return []
|
428 |
+
|
429 |
+
examples = [
|
430 |
+
["์๋์ฐจ", "", ""],
|
431 |
+
["์ค๋งํธํฐ", "์ธ๊ณต์ง๋ฅ", ""],
|
432 |
+
["๋๋ก ", "์ธ๊ณต์ง๋ฅ", ""],
|
433 |
+
["์ด๋ํ", "์จ์ด๋ฌ๋ธ", "๊ฑด๊ฐ"],
|
434 |
+
]
|
435 |
+
gr.Examples(examples=examples, inputs=[text_input1, text_input2, text_input3])
|
436 |
+
|
|
|
437 |
submit_button.click(
|
438 |
+
fn=process_inputs_stream,
|
439 |
inputs=[text_input1, text_input2, text_input3],
|
440 |
+
outputs=chatbot,
|
441 |
+
stream=True # ์คํธ๋ฆฌ๋ฐ ์ถ๋ ฅ
|
442 |
+
)
|
443 |
+
|
444 |
+
clear_button.click(
|
445 |
+
fn=clear_chat,
|
446 |
+
outputs=chatbot
|
447 |
)
|
448 |
|
449 |
if __name__ == "__main__":
|
450 |
demo.launch(debug=True)
|
451 |
+
|