Spaces:
Runtime error
Runtime error
import os | |
import gradio as gr | |
import random | |
import time | |
import logging | |
import google.generativeai as genai | |
import torch | |
import numpy as np | |
from diffusers import DiffusionPipeline | |
from transformers import pipeline as hf_pipeline | |
############################################################################## | |
# 1) ZeroGPU ํ๊ฒฝ ์ฒ๋ฆฌ + device, dtype ์ค์ | |
############################################################################## | |
############################################################################## | |
# 1) ZeroGPU ํ๊ฒฝ ์ฒ๋ฆฌ + device, dtype ์ค์ | |
############################################################################## | |
# ZeroGPU ์ด๊ธฐํ ์๋ | |
try: | |
import zerogpu | |
zerogpu.init() | |
print("ZeroGPU initialized successfully") | |
device = "cuda" if torch.cuda.is_available() else "cpu" | |
except ImportError: | |
# ZeroGPU๊ฐ ์ค์น๋์ง ์์ ๊ฒฝ์ฐ | |
print("ZeroGPU package not installed, continuing without it") | |
if os.getenv("ZERO_GPU"): | |
print("ZeroGPU environment variable is set but zerogpu package is not installed.") | |
device = "cuda" if torch.cuda.is_available() else "cpu" | |
except Exception as e: | |
# ZeroGPU ์ด๊ธฐํ ์ค ๋ค๋ฅธ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ | |
print(f"Error initializing ZeroGPU: {e}") | |
print("Continuing without ZeroGPU") | |
device = "cuda" if torch.cuda.is_available() else "cpu" | |
# GPU์ผ ๋๋ง bfloat16, ๊ทธ ์ธ์๋ float32 | |
dtype = torch.bfloat16 if device == "cuda" else torch.float32 | |
print(f"Using device: {device}, dtype: {dtype}") | |
############################################################################## | |
# 2) ๋ชจ๋ธ ๋ก๋: ๋ฒ์ญ ๋ชจ๋ธ, DiffusionPipeline | |
############################################################################## | |
try: | |
translator = hf_pipeline( | |
"translation", | |
model="Helsinki-NLP/opus-mt-ko-en", | |
device=0 if device == "cuda" else -1 | |
) | |
pipe = DiffusionPipeline.from_pretrained( | |
"black-forest-labs/FLUX.1-schnell", | |
torch_dtype=dtype | |
).to(device) | |
print("Models loaded successfully") | |
except Exception as e: | |
print(f"Error loading models: {e}") | |
# ๋ชจ๋ธ ๋ก๋ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋๋ฏธ ํจ์๋ค | |
def dummy_translator(text): | |
return [{'translation_text': text}] | |
class DummyPipe: | |
def __call__(self, **kwargs): | |
from PIL import Image | |
import numpy as np | |
dummy_img = Image.fromarray(np.zeros((512, 512, 3), dtype=np.uint8)) | |
class DummyResult: | |
def __init__(self, img): | |
self.images = [img] | |
return DummyResult(dummy_img) | |
translator = dummy_translator | |
pipe = DummyPipe() | |
MAX_SEED = np.iinfo(np.int32).max | |
MAX_IMAGE_SIZE = 2048 | |
############################################################################## | |
# ํ๊ตญ์ด ๊ฐ์ง ํจ์ | |
############################################################################## | |
def contains_korean(text): | |
for char in text: | |
if ord('๊ฐ') <= ord(char) <= ord('ํฃ'): | |
return True | |
return False | |
############################################################################## | |
# ์ด๋ฏธ์ง ์์ฑ ํจ์ | |
############################################################################## | |
def generate_design_image(prompt, seed=42, randomize_seed=True, width=1024, height=1024, num_inference_steps=4): | |
""" | |
์์ฑ๋ ํ์ฅ ์์ด๋์ด ํ ์คํธ(prompt)๋ฅผ ์ ๋ ฅ๋ฐ์, | |
ํ์์ ํ๊ตญ์ด๋ฅผ ์์ด๋ก ๋ฒ์ญํ ํ DiffusionPipeline์ผ๋ก ์ด๋ฏธ์ง๋ฅผ ์์ฑํฉ๋๋ค. | |
""" | |
original_prompt = prompt | |
translated = False | |
# ํ๊ตญ์ด๊ฐ ํฌํจ๋์ด ์์ผ๋ฉด ์์ด๋ก ๋ฒ์ญ | |
if contains_korean(prompt): | |
translation = translator(prompt) | |
prompt = translation[0]['translation_text'] | |
translated = True | |
# ๋๋ค ์๋ ์ค์ | |
if randomize_seed: | |
seed = random.randint(0, MAX_SEED) | |
generator = torch.Generator(device=device).manual_seed(seed) | |
image = pipe( | |
prompt=prompt, | |
width=width, | |
height=height, | |
num_inference_steps=num_inference_steps, | |
generator=generator, | |
guidance_scale=0.0 | |
).images[0] | |
return image | |
############################################################################## | |
# ๋ก๊น ์ค์ | |
############################################################################## | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', | |
handlers=[ | |
logging.FileHandler("api_debug.log"), | |
logging.StreamHandler() | |
] | |
) | |
logger = logging.getLogger("idea_generator") | |
############################################################################## | |
# Gemini API ํค | |
############################################################################## | |
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") | |
genai.configure(api_key=GEMINI_API_KEY) | |
############################################################################## | |
# ์ ํ์ ๋ณํ ์ ํ ํจ์ | |
############################################################################## | |
def choose_alternative(transformation): | |
if "/" not in transformation: | |
return transformation | |
parts = transformation.split("/") | |
if len(parts) != 2: | |
return random.choice([part.strip() for part in parts]) | |
left = parts[0].strip() | |
right = parts[1].strip() | |
if " " in left: | |
tokens = left.split(" ", 1) | |
prefix = tokens[0] | |
if not right.startswith(prefix): | |
option1 = left | |
option2 = prefix + " " + right | |
else: | |
option1 = left | |
option2 = right | |
return random.choice([option1, option2]) | |
else: | |
return random.choice([left, right]) | |
############################################################################## | |
# ๋ฌผ๋ฆฌ์ ๋ณํ ์นดํ ๊ณ ๋ฆฌ ์ฌ์ (์ด 15๊ฐ) | |
############################################################################## | |
physical_transformation_categories = { | |
"๊ณต๊ฐ ์ด๋": [ | |
"์/๋ค ์ด๋", "์ข/์ฐ ์ด๋", "์/์๋ ์ด๋", "์ธ๋ก์ถ ํ์ (๊ณ ๊ฐ ๋๋์)", | |
"๊ฐ๋ก์ถ ํ์ (๊ณ ๊ฐ ์ ๊ธฐ)", "๊ธธ์ด์ถ ํ์ (์์ผ๋ก ๊ธฐ์ธ์)", "์ ์ด๋", "๋์ ํ ์ด๋", | |
"๊ด์ฑ์ ์ํ ๋ฏธ๋๋ฌ์ง", "ํ์ ์ถ ๋ณํ", "๋ถ๊ท์น ํ์ ", "ํ๋ค๋ฆผ ์ด๋", "ํฌ๋ฌผ์ ์ด๋", | |
"๋ฌด์ค๋ ฅ ๋ถ์ ", "์๋ฉด ์ ๋ถ์ ", "์ ํ/๋์ฝ", "์ฌ๋ผ์ด๋ฉ", "๋กค๋ง", "์์ ๋ํ", | |
"์๋ณต ์ด๋", "ํ์ฑ ํ๊น", "๊ดํต", "ํํผ ์์ง์", "์ง๊ทธ์ฌ๊ทธ ์ด๋", "์ค์ ์ด๋" | |
], | |
"ํฌ๊ธฐ์ ํํ ๋ณํ": [ | |
"๋ถํผ ๋์ด๋จ/์ค์ด๋ฆ", "๊ธธ์ด ๋์ด๋จ/์ค์ด๋ฆ", "๋๋น ๋์ด๋จ/์ค์ด๋ฆ", "๋์ด ๋์ด๋จ/์ค์ด๋ฆ", | |
"๋ฐ๋ ๋ณํ", "๋ฌด๊ฒ ์ฆ๊ฐ/๊ฐ์", "๋ชจ์ ๋ณํ", "์ํ ๋ณํ", "๋ถ๊ท ๋ฑ ๋ณํ", | |
"๋ณต์กํ ํํ ๋ณํ", "๋นํ๋ฆผ/๊ผฌ์", "๋ถ๊ท ์ผํ ํ์ฅ/์ถ์", "๋ชจ์๋ฆฌ ๋ฅ๊ธ๊ฒ/๋ ์นด๋กญ๊ฒ", | |
"๊นจ์ง/๊ฐ๋ผ์ง", "์ฌ๋ฌ ์กฐ๊ฐ ๋๋ ์ง", "๋ฌผ ์ ํญ", "๋จผ์ง ์ ํญ", "์ฐ๊ทธ๋ฌ์ง/๋ณต์", | |
"์ ํ/ํผ์ณ์ง", "์์ฐฉ/ํฝ์ฐฝ", "๋์ด๋จ/์์ถ", "๊ตฌ๊ฒจ์ง/ํํํด์ง", "๋ญ๊ฐ์ง/๋จ๋จํด์ง", | |
"๋ง๋ฆผ/ํด์ง", "๊บพ์/๊ตฌ๋ถ๋ฌ์ง" | |
], | |
"ํ๋ฉด ๋ฐ ์ธ๊ด ๋ณํ": [ | |
"์์ ๋ณํ", "์ง๊ฐ ๋ณํ", "ํฌ๋ช /๋ถํฌ๋ช ๋ณํ", "๋ฐ์ง์/๋ฌด๊ด ๋ณํ", | |
"๋น ๋ฐ์ฌ ์ ๋ ๋ณํ", "๋ฌด๋ฌ ๋ณํ", "๊ฐ๋์ ๋ฐ๋ฅธ ์์ ๋ณํ", "๋น์ ๋ฐ๋ฅธ ์์ ๋ณํ", | |
"์จ๋์ ๋ฐ๋ฅธ ์์ ๋ณํ", "ํ๋ก๊ทธ๋จ ํจ๊ณผ", "ํ๋ฉด ๊ฐ๋๋ณ ๋น ๋ฐ์ฌ", "ํ๋ฉด ๋ชจ์ ๋ณํ", | |
"์ด๋ฏธ์ธ ํ๋ฉด ๊ตฌ์กฐ ๋ณํ", "์๊ฐ ์ธ์ ํจ๊ณผ", "์ผ๋ฃฉ/ํจํด ์์ฑ", "ํ๋ฆผ/์ ๋ช ํจ ๋ณํ", | |
"๊ดํ/์ค๊ธฐ ๋ณํ", "์์กฐ/์ฑ๋ ๋ณํ", "๋ฐ๊ด/ํ๊ด", "๋น ์ฐ๋ ํจ๊ณผ", | |
"๋น ํก์ ๋ณํ", "๋ฐํฌ๋ช ํจ๊ณผ", "๊ทธ๋ฆผ์ ํจ๊ณผ ๋ณํ", "์์ธ์ ๋ฐ์ ๋ณํ", | |
"์ผ๊ด ํจ๊ณผ" | |
], | |
"๋ฌผ์ง์ ์ํ ๋ณํ": [ | |
"๊ณ ์ฒด/์ก์ฒด/๊ธฐ์ฒด ์ ํ", "๊ฒฐ์ ํ/์ฉํด", "์ฐํ/๋ถ์", "๋ฑ๋ฑํด์ง/๋ถ๋๋ฌ์์ง", | |
"ํน์ ์ํ ์ ํ", "๋ฌด์ ํ/๊ฒฐ์ ํ ์ ํ", "์ฑ๋ถ ๋ถ๋ฆฌ", "๋ฏธ์ธ ์ ์ ํ์ฑ/๋ถํด", | |
"์ ค ํ์ฑ/ํ์ด์ง", "์ค์์ ์ํ ๋ณํ", "๋ถ์ ์๊ฐ ์ ๋ ฌ/๋ถํด", "์ํ๋ณํ ์ง์ฐ ํ์", | |
"๋ น์", "๊ตณ์", "์ฆ๋ฐ/์์ถ", "์นํ/์ฆ์ฐฉ", "์นจ์ /๋ถ์ ", "๋ถ์ฐ/์์ง", | |
"๊ฑด์กฐ/์ต์ค", "ํฝ์ค/์์ถ", "๋๊ฒฐ/ํด๋", "ํํ/์นจ์", "์ถฉ์ /๋ฐฉ์ ", | |
"๊ฒฐํฉ/๋ถ๋ฆฌ", "๋ฐํจ/๋ถํจ" | |
], | |
"์ด ๊ด๋ จ ๋ณํ": [ | |
"์จ๋ ์์น/ํ๊ฐ", "์ด์ ์ํ ํฝ์ฐฝ/์์ถ", "์ด ์ ๋ฌ/์ฐจ๋จ", "์๋ ฅ ์์น/ํ๊ฐ", | |
"์ด ๋ณํ์ ๋ฐ๋ฅธ ์ํ", "๋ฌด์ง์๋ ๋ณํ", "์ด์ ๊ธฐ ํ์", "์๊ธฐ์ฅ์ ์ํ ์ด ๋ณํ", | |
"์ํ๋ณํ ์ค ์ด ์ ์ฅ/๋ฐฉ์ถ", "์ด ์คํธ๋ ์ค ๋ฐ์/ํด์", "๊ธ๊ฒฉํ ์จ๋ ๋ณํ ์ํฅ", | |
"๋ณต์ฌ์ด์ ์ํ ๋๊ฐ/๊ฐ์ด", "๋ฐ์ด/ํก์ด", "์ด ๋ถํฌ ๋ณํ", "์ด ๋ฐ์ฌ/ํก์", | |
"๋๊ฐ ์์ถ", "์ด ํ์ฑํ", "์ด ๋ณ์", "์ด ํฝ์ฐฝ ๊ณ์ ๋ณํ", "์ด ์์ ์ฑ ๋ณํ", | |
"๋ด์ด์ฑ/๋ดํ์ฑ", "์๊ธฐ๋ฐ์ด", "์ด์ ํํ/๋ถ๊ท ํ", "์ด์ ๋ณํ", "์ด ๋ถ์ฐ/์ง์ค" | |
], | |
"์์ง์ ํน์ฑ ๋ณํ": [ | |
"๊ฐ์/๊ฐ์", "์ผ์ ์๋ ์ ์ง", "์ง๋/์ง๋ ๊ฐ์", "๋ถ๋ชํ/ํ๊น", | |
"ํ์ ์๋ ์ฆ๊ฐ/๊ฐ์", "ํ์ ๋ฐฉํฅ ๋ณํ", "๋ถ๊ท์น ์์ง์", "๋ฉ์ท๋ค ๋ฏธ๋๋ฌ์ง๋ ํ์", | |
"๊ณต์ง/๋ฐ๊ณต์ง", "์ ์ฒด ์ ์ ํญ/์๋ ฅ ๋ณํ", "์์ง์ ์ ํญ ๋ณํ", "๋ณตํฉ ์ง๋ ์์ง์", | |
"ํน์ ์ ์ฒด ์ ์์ง์", "ํ์ -์ด๋ ์ฐ๊ณ ์์ง์", "๊ด์ฑ ์ ์ง", "์ถฉ๊ฒฉ ํก์", | |
"์ถฉ๊ฒฉ ์ ๋ฌ", "์ด๋๋ ๋ณด์กด", "๋ง์ฐฐ๋ ฅ ๋ณํ", "๊ด์ฑ ํ์ถ", "๋ถ์์ ๊ท ํ", | |
"๋์ ์์ ์ฑ", "ํ๋ค๋ฆผ ๊ฐ์ ", "๊ฒฝ๋ก ์์ธก์ฑ", "ํํผ ์์ง์" | |
], | |
"๊ตฌ์กฐ์ ๋ณํ": [ | |
"๋ถํ ์ถ๊ฐ/์ ๊ฑฐ", "์กฐ๋ฆฝ/๋ถํด", "์ ๊ธฐ/ํด๊ธฐ", "๋ณํ/์์๋ณต๊ตฌ", "์ต์ ๊ตฌ์กฐ ๋ณํ", | |
"์๊ฐ ์ฌ๋ฐฐ์ด", "์์ฐ ํจํด ํ์ฑ/์๋ฉธ", "๊ท์น์ ํจํด ๋ณํ", "๋ชจ๋์ ๋ณํ", | |
"๋ณต์ก์ฑ ์ฆ๊ฐ ๊ตฌ์กฐ", "์๋ ๋ชจ์ ๊ธฐ์ต ํจ๊ณผ", "์๊ฐ์ ๋ฐ๋ฅธ ํํ ๋ณํ", "๋ถ๋ถ ์ ๊ฑฐ", | |
"๋ถ๋ถ ๊ต์ฒด", "๊ฒฐํฉ", "๋ถ๋ฆฌ", "๋ถํ /ํตํฉ", "์ค์ฒฉ/๊ฒน์นจ", "๋ด๋ถ ๊ตฌ์กฐ ๋ณํ", | |
"์ธ๋ถ ๊ตฌ์กฐ ๋ณํ", "์ค์ฌ์ถ ์ด๋", "๊ท ํ์ ๋ณํ", "๊ณ์ธต ๊ตฌ์กฐ ๋ณํ", "์ง์ง ๊ตฌ์กฐ ๋ณํ", | |
"์๋ ฅ ๋ถ์ฐ ๊ตฌ์กฐ", "์ถฉ๊ฒฉ ํก์ ๊ตฌ์กฐ", "๊ทธ๋ฆฌ๋/๋งคํธ๋ฆญ์ค ๊ตฌ์กฐ ๋ณํ", "์ํธ ์ฐ๊ฒฐ์ฑ ๋ณํ" | |
], | |
"์ ๊ธฐ ๋ฐ ์๊ธฐ ๋ณํ": [ | |
"์์ฑ ์์ฑ/์๋ฉธ", "์ ํ๋ ์ฆ๊ฐ/๊ฐ์", "์ ๊ธฐ์ฅ ์์ฑ/์๋ฉธ", "์๊ธฐ์ฅ ์์ฑ/์๋ฉธ", | |
"์ด์ ๋ ์ํ ์ ํ", "๊ฐ์ ์ ์ฒด ํน์ฑ ๋ณํ", "์์ ์ํ ๋ณํ", "ํ๋ผ์ฆ๋ง ์ํ ํ์ฑ/์๋ฉธ", | |
"์คํํ ์ ๋ฌ", "๋น์ ์ํ ์ ๊ธฐ ๋ฐ์", "์๋ ฅ์ ์ํ ์ ๊ธฐ ๋ฐ์", "์๊ธฐ์ฅ ์ ์ ๋ฅ ๋ณํ", | |
"์ ๊ธฐ ์ ํญ ๋ณํ", "์ ๊ธฐ ์ ๋์ฑ ๋ณํ", "์ ์ ๊ธฐ ๋ฐ์/๋ฐฉ์ ", "์ ์๊ธฐ ์ ๋", | |
"์ ์๊ธฐํ ๋ฐฉ์ถ/ํก์", "์ ๊ธฐ ์ฉ๋ ๋ณํ", "์๊ธฐ ์ด๋ ฅ ํ์", "์ ๊ธฐ์ ๋ถ๊ทน", | |
"์ ์ ํ๋ฆ ๋ฐฉํฅ ๋ณํ", "์ ๊ธฐ์ ๊ณต๋ช ", "์ ๊ธฐ์ ์ฐจํ/๋ ธ์ถ", "์๊ธฐ ์ฐจํ/๋ ธ์ถ", | |
"์๊ธฐ์ฅ ๋ฐฉํฅ ์ ๋ ฌ" | |
], | |
"ํํ์ ๋ณํ": [ | |
"ํ๋ฉด ์ฝํ ๋ณํ", "๋ฌผ์ง ์ฑ๋ถ ๋ณํ", "ํํ ๋ฐ์ ๋ณํ", "์ด๋งค ์์ฉ ์์/์ค๋จ", | |
"๋น์ ์ํ ํํ ๋ฐ์", "์ ๊ธฐ์ ์ํ ํํ ๋ฐ์", "๋จ๋ถ์๋ง ํ์ฑ", "๋ถ์ ์์ค ๊ณ์ฐ ๋ณํ", | |
"์์ฐ ๋ชจ๋ฐฉ ํ๋ฉด ๋ณํ", "ํ๊ฒฝ ๋ฐ์ํ ๋ฌผ์ง ๋ณํ", "์ฃผ๊ธฐ์ ํํ ๋ฐ์", "์ฐํ", "ํ์", | |
"๊ณ ๋ถ์ํ", "๋ฌผ ๋ถํด", "ํํฉ", "๋ฐฉ์ฌ์ ์ํฅ", "์ฐ-์ผ๊ธฐ ๋ฐ์", "์คํ ๋ฐ์", | |
"์ด์จํ", "ํํ์ ํก์ฐฉ/ํ์ฐฉ", "์ด๋งค ํจ์จ ๋ณํ", "ํจ์ ํ์ฑ ๋ณํ", "๋ฐ์ ๋ฐ์", | |
"pH ๋ณํ", "ํํ์ ํํ ์ด๋", "๊ฒฐํฉ ํ์ฑ/๋ถํด", "์ฉํด๋ ๋ณํ" | |
], | |
"์๊ฐ ๊ด๋ จ ๋ณํ": [ | |
"๋ ธํ/ํํ", "๋ง๋ชจ/๋ถ์", "์ ๋ฐ๋จ/๋ณ์", "์์/ํ๋ณต", "์๋ช ์ฃผ๊ธฐ ๋ณํ", | |
"์ฌ์ฉ์ ์ํธ์์ฉ์ ๋ฐ๋ฅธ ์ ์", "ํ์ต ๊ธฐ๋ฐ ํํ ์ต์ ํ", "์๊ฐ์ ๋ฐ๋ฅธ ๋ฌผ์ฑ ๋ณํ", | |
"์ง๋จ ๊ธฐ์ต ํจ๊ณผ", "๋ฌธํ์ ์๋ฏธ ๋ณํ", "์ง์ฐ ๋ฐ์", "์ด์ ์ํ ์์กด ๋ณํ", | |
"์ ์ง์ ์๊ฐ ๋ณํ", "์งํ์ ๋ณํ", "์ฃผ๊ธฐ์ ์ฌ์", "๊ณ์ ๋ณํ ์ ์", | |
"์์ฒด๋ฆฌ๋ฌ ๋ณํ", "์์ ์ฃผ๊ธฐ ๋จ๊ณ", "์ฑ์ฅ/ํดํ", "์๊ธฐ ๋ณต๊ตฌ/์ฌ์", | |
"์์ฐ ์ํ ์ ์", "์ง์์ฑ/์ผ์์ฑ", "๊ธฐ์ต ํจ๊ณผ", "์ง์ฐ๋ ์์ฉ", "๋์ ํจ๊ณผ" | |
], | |
"๋น๊ณผ ์๊ฐ ํจ๊ณผ": [ | |
"๋ฐ๊ด/์๋ฑ", "๋น ํฌ๊ณผ/์ฐจ๋จ", "๋น ์ฐ๋/์ง์ค", "์์ ์คํํธ๋ผ ๋ณํ", "๋น ํ์ ", | |
"๋น ๊ฐ์ญ", "ํ๋ก๊ทธ๋จ ์์ฑ", "๋ ์ด์ ํจ๊ณผ", "๋น ํธ๊ด", "ํ๊ด/์ธ๊ด", | |
"์์ธ์ /์ ์ธ์ ๋ฐ๊ด", "๊ดํ์ ์ฐฉ์", "๋น ๊ตด์ ", "๊ทธ๋ฆผ์ ์์ฑ/์ ๊ฑฐ", | |
"์์์ฐจ ํจ๊ณผ", "๋ฌด์ง๊ฐ ํจ๊ณผ", "๊ธ๋ก์ฐ ํจ๊ณผ", "ํ๋์ ํจ๊ณผ", "์กฐ๋ช ํจํด", | |
"๋น ํจ๊ณผ", "๊ด ํํฐ ํจ๊ณผ", "๋น์ ๋ฐฉํฅ์ฑ ๋ณํ", "ํฌ์ ํจ๊ณผ", "๋น ๊ฐ์ง/๋ฐ์", | |
"๊ด๋ ๋ณํ" | |
], | |
"์๋ฆฌ์ ์ง๋ ํจ๊ณผ": [ | |
"์๋ฆฌ ๋ฐ์/์๋ฉธ", "์๋ฆฌ ๋๋ฎ์ด ๋ณํ", "์๋ฆฌ ํฌ๊ธฐ ๋ณํ", "์์ ๋ณํ", | |
"๊ณต๋ช /๋ฐ๊ณต๋ช ", "์ํฅ ์ง๋", "์ด์ํ/์ ์ํ ๋ฐ์", "์ํฅ ์ง์ค/๋ถ์ฐ", | |
"์ํฅ ๋ฐ์ฌ/ํก์", "์ํฅ ๋ํ๋ฌ ํจ๊ณผ", "์ํ ๊ฐ์ญ", "์ํฅ ๊ณต์ง", | |
"์ง๋ ํจํด ๋ณํ", "ํ์ ํจ๊ณผ", "์ํฅ ํผ๋๋ฐฑ", "์ํฅ ์ฐจํ/์ฆํญ", | |
"์๋ฆฌ ์งํฅ์ฑ", "์ํฅ ์๊ณก", "๋นํธ ์์ฑ", "ํ๋ชจ๋์ค ์์ฑ", "์ฃผํ์ ๋ณ์กฐ", | |
"์ํฅ ์ถฉ๊ฒฉํ", "์ํฅ ํํฐ๋ง" | |
], | |
"์๋ฌผํ์ ๋ณํ": [ | |
"์์ฅ/์์ถ", "์ธํฌ ๋ถ์ด/์ฌ๋ฉธ", "์๋ฌผ ๋ฐ๊ด", "์ ์ง๋์ฌ ๋ณํ", "๋ฉด์ญ ๋ฐ์", | |
"ํธ๋ฅด๋ชฌ ๋ถ๋น", "์ ๊ฒฝ ๋ฐ์", "์ ์ ์ ๋ฐํ", "์ ์/์งํ", "์์ฒด๋ฆฌ๋ฌ ๋ณํ", | |
"์ฌ์/์น์ ", "๋ ธํ/์ฑ์", "์์ฒด ๋ชจ๋ฐฉ ๋ณํ", "๋ฐ์ด์คํ๋ฆ ํ์ฑ", "์๋ฌผํ์ ๋ถํด", | |
"ํจ์ ํ์ฑํ/๋นํ์ฑํ", "์๋ฌผํ์ ์ ํธ ์ ๋ฌ", "์คํธ๋ ์ค ๋ฐ์", "์ฒด์จ ์กฐ์ ", | |
"์๋ฌผํ์ ์๊ณ ๋ณํ", "์ธํฌ์ธ ๊ธฐ์ง ๋ณํ", "์์ฒด ์ญํ์ ๋ฐ์", "์ธํฌ ์ด๋์ฑ", | |
"์ธํฌ ๊ทน์ฑ ๋ณํ", "์์ ์ํ ๋ณํ" | |
], | |
"ํ๊ฒฝ ์ํธ์์ฉ": [ | |
"์จ๋ ๋ฐ์", "์ต๋ ๋ฐ์", "๊ธฐ์ ๋ฐ์", "์ค๋ ฅ ๋ฐ์", "์๊ธฐ์ฅ ๋ฐ์", | |
"๋น ๋ฐ์", "์๋ฆฌ ๋ฐ์", "ํํ ๋ฌผ์ง ๊ฐ์ง", "๊ธฐ๊ณ์ ์๊ทน ๊ฐ์ง", "์ ๊ธฐ ์๊ทน ๋ฐ์", | |
"๋ฐฉ์ฌ์ ๋ฐ์", "์ง๋ ๊ฐ์ง", "pH ๋ฐ์", "์ฉ๋งค ๋ฐ์", "๊ธฐ์ฒด ๊ตํ", | |
"ํ๊ฒฝ ์ค์ผ ๋ฐ์", "๋ ์จ ๋ฐ์", "๊ณ์ ๋ณํ ๋ฐ์", "์ผ์ฃผ๊ธฐ ๋ฐ์", "์ํ๊ณ ์ํธ์์ฉ", | |
"๊ณต์/๊ฒฝ์ ๋ฐ์", "ํฌ์/ํผ์ ๊ด๊ณ", "๊ตฐ์ง ํ์ฑ", "์์ญ ์ค์ ", "์ด์ฃผ/์ ์ฐฉ ํจํด" | |
], | |
"์ผ์ ๊ธฐ๋ฅ": [ | |
"์๊ฐ ์ผ์/๊ฐ์ง", "์ฒญ๊ฐ ์ผ์/๊ฐ์ง", "์ด๊ฐ ์ผ์/๊ฐ์ง", "๋ฏธ๊ฐ ์ผ์/๊ฐ์ง", "ํ๊ฐ ์ผ์/๊ฐ์ง", | |
"์จ๋ ์ผ์/๊ฐ์ง", "์ต๋ ์ผ์/๊ฐ์ง", "์๋ ฅ ์ผ์/๊ฐ์ง", "๊ฐ์๋ ์ผ์/๊ฐ์ง", "ํ์ ์ผ์/๊ฐ์ง", | |
"๊ทผ์ ์ผ์/๊ฐ์ง", "์์น ์ผ์/๊ฐ์ง", "์ด๋ ์ผ์/๊ฐ์ง", "๊ฐ์ค ์ผ์/๊ฐ์ง", "์ ์ธ์ ์ผ์/๊ฐ์ง", | |
"์์ธ์ ์ผ์/๊ฐ์ง", "๋ฐฉ์ฌ์ ์ผ์/๊ฐ์ง", "์๊ธฐ์ฅ ์ผ์/๊ฐ์ง", "์ ๊ธฐ์ฅ ์ผ์/๊ฐ์ง", "ํํ๋ฌผ์ง ์ผ์/๊ฐ์ง", | |
"์์ฒด์ ํธ ์ผ์/๊ฐ์ง", "์ง๋ ์ผ์/๊ฐ์ง", "์์ ์ผ์/๊ฐ์ง", "๋น ์ธ๊ธฐ ์ผ์/๊ฐ์ง", "๋น ํ์ฅ ์ผ์/๊ฐ์ง", | |
"๊ธฐ์ธ๊ธฐ ์ผ์/๊ฐ์ง", "pH ์ผ์/๊ฐ์ง", "์ ๋ฅ ์ผ์/๊ฐ์ง", "์ ์ ์ผ์/๊ฐ์ง", "์ด๋ฏธ์ง ์ผ์/๊ฐ์ง", | |
"๊ฑฐ๋ฆฌ ์ผ์/๊ฐ์ง", "๊น์ด ์ผ์/๊ฐ์ง", "์ค๋ ฅ ์ผ์/๊ฐ์ง", "์๋ ์ผ์/๊ฐ์ง", "ํ๋ฆ ์ผ์/๊ฐ์ง", | |
"์์ ์ผ์/๊ฐ์ง", "ํ๋ ์ผ์/๊ฐ์ง", "์ผ๋ ์ผ์/๊ฐ์ง", "๊ธ์ ๊ฐ์ง", "์์ ์ผ์/๊ฐ์ง", | |
"๊ด์ ์ผ์/๊ฐ์ง", "์ด์ ๋ ์ผ์/๊ฐ์ง", "ํ ํจ๊ณผ ์ผ์/๊ฐ์ง", "์ด์ํ ์ผ์/๊ฐ์ง", "๋ ์ด๋ ์ผ์/๊ฐ์ง", | |
"๋ผ์ด๋ค ์ผ์/๊ฐ์ง", "ํฐ์น ์ผ์/๊ฐ์ง", "์ ์ค์ฒ ์ผ์/๊ฐ์ง", "์ฌ๋ฐ ์ผ์/๊ฐ์ง", "ํ์ ์ผ์/๊ฐ์ง" | |
] | |
} | |
############################################################################## | |
# Gemini API ํธ์ถ ํจ์ | |
############################################################################## | |
def query_gemini_api(prompt): | |
try: | |
model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21') | |
response = model.generate_content(prompt) | |
try: | |
if hasattr(response, 'text'): | |
return response.text | |
if hasattr(response, 'candidates') and response.candidates: | |
candidate = response.candidates[0] | |
if hasattr(candidate, 'content'): | |
content = candidate.content | |
if hasattr(content, 'parts') and content.parts: | |
if len(content.parts) > 0: | |
return content.parts[0].text | |
if hasattr(response, 'parts') and response.parts: | |
if len(response.parts) > 0: | |
return response.parts[0].text | |
return "Unable to generate a response. API response structure is different than expected." | |
except Exception as inner_e: | |
logger.error(f"Error processing response: {inner_e}") | |
return f"An error occurred while processing the response: {str(inner_e)}" | |
except Exception as e: | |
logger.error(f"Error calling Gemini API: {e}") | |
if "API key not valid" in str(e): | |
return "API key is not valid. Please check your GEMINI_API_KEY environment variable." | |
return f"An error occurred while calling the API: {str(e)}" | |
############################################################################## | |
# ์ค๋ช ํ์ฅ ํจ์ (LLM ์ด์ฉ) | |
############################################################################## | |
def enhance_with_llm(base_description, obj_name, category): | |
prompt = f""" | |
๋ค์์ '{obj_name}'์ '{category}' ๊ด๋ จ ๊ฐ๋จํ ์ค๋ช ์ ๋๋ค: | |
"{base_description}" | |
์ ๋ด์ฉ์ ๋ณด๋ค ๊ตฌ์ฒดํํ์ฌ, | |
1) ์ฐฝ์์ ์ธ ๋ชจ๋ธ/์ปจ์ /ํ์์ ๋ณํ์ ๋ํ ์ดํด, | |
2) ํ์ ํฌ์ธํธ์ ๊ธฐ๋ฅ์ฑ ๋ฑ์ ์ค์ฌ์ผ๋ก | |
3~4๋ฌธ์ฅ์ ์์ด๋์ด๋ก ํ์ฅํด ์ฃผ์ธ์. | |
""" | |
return query_gemini_api(prompt) | |
############################################################################## | |
# ๊ฐ ๊ฐ์ฒด์(1, 2, 3)์ ๋ฐ๋ฅธ ๋ณํ ์์ด๋์ด ์์ฑ | |
############################################################################## | |
def generate_single_object_transformation_for_category(obj, selected_category): | |
transformations = physical_transformation_categories.get(selected_category) | |
if not transformations: | |
return {} | |
transformation = choose_alternative(random.choice(transformations)) | |
base_description = f"{obj}์ด(๊ฐ) {transformation} ํ์์ ๋ณด์ธ๋ค" | |
return {selected_category: {"base": base_description, "enhanced": None}} | |
def generate_two_objects_interaction_for_category(obj1, obj2, selected_category): | |
transformations = physical_transformation_categories.get(selected_category) | |
if not transformations: | |
return {} | |
transformation = choose_alternative(random.choice(transformations)) | |
template = random.choice([ | |
"{obj1}์ด(๊ฐ) {obj2}์ ๊ฒฐํฉํ์ฌ {change}๊ฐ ๋ฐ์ํ๋ค", | |
"{obj1}๊ณผ(์) {obj2}์ด(๊ฐ) ์ถฉ๋ํ๋ฉด์ {change}๊ฐ ์ผ์ด๋ฌ๋ค" | |
]) | |
base_description = template.format(obj1=obj1, obj2=obj2, change=transformation) | |
return {selected_category: {"base": base_description, "enhanced": None}} | |
def generate_three_objects_interaction_for_category(obj1, obj2, obj3, selected_category): | |
transformations = physical_transformation_categories.get(selected_category) | |
if not transformations: | |
return {} | |
transformation = choose_alternative(random.choice(transformations)) | |
template = random.choice([ | |
"{obj1}, {obj2}, {obj3}์ด(๊ฐ) ์ผ๊ฐํ ๊ตฌ์กฐ๋ก ๊ฒฐํฉํ์ฌ {change}๊ฐ ๋ฐ์ํ๋ค", | |
"{obj1}์ด(๊ฐ) {obj2}์(๊ณผ) {obj3} ์ฌ์ด์์ ๋งค๊ฐ์ฒด ์ญํ ์ ํ๋ฉฐ {change}๋ฅผ ์ด์งํ๋ค" | |
]) | |
base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation) | |
return {selected_category: {"base": base_description, "enhanced": None}} | |
############################################################################## | |
# ์์ฑ๋ ๊ธฐ๋ณธ ์ค๋ช ์ LLM์ ํตํด ํ์ฅ (๊ฐ ์นดํ ๊ณ ๋ฆฌ๋ณ) | |
############################################################################## | |
def enhance_descriptions(results, objects): | |
obj_name = " ๋ฐ ".join([obj for obj in objects if obj]) | |
for category, result in results.items(): | |
result["enhanced"] = enhance_with_llm(result["base"], obj_name, category) | |
return results | |
############################################################################## | |
# ์ฌ์ฉ์ ์ ๋ ฅ(์ต๋ 3๊ฐ ํค์๋) + ์ ํ ์นดํ ๊ณ ๋ฆฌ โ ๋ณํ ์์ด๋์ด ์์ฑ | |
############################################################################## | |
def generate_transformations(text1, text2, text3, selected_category): | |
if text2 and text3: | |
results = generate_three_objects_interaction_for_category(text1, text2, text3, selected_category) | |
objects = [text1, text2, text3] | |
elif text2: | |
results = generate_two_objects_interaction_for_category(text1, text2, selected_category) | |
objects = [text1, text2] | |
else: | |
results = generate_single_object_transformation_for_category(text1, selected_category) | |
objects = [text1] | |
return enhance_descriptions(results, objects) | |
############################################################################## | |
# ๊ฒฐ๊ณผ ํฌ๋งทํ | |
############################################################################## | |
def format_results(results): | |
formatted = "" | |
for category, result in results.items(): | |
formatted += f"## {category}\n**๊ธฐ๋ณธ ์์ด๋์ด**: {result['base']}\n\n**ํ์ฅ๋ ์์ด๋์ด**: {result['enhanced']}\n\n---\n\n" | |
return formatted | |
############################################################################## | |
# Gradio UI์์ ํธ์ถ๋ ํจ์ (ํ ์คํธ ์์ด๋์ด๋ง ์์ฑ) | |
############################################################################## | |
def process_inputs(text1, text2, text3, selected_category, progress=gr.Progress()): | |
text1 = text1.strip() if text1 else None | |
text2 = text2.strip() if text2 else None | |
text3 = text3.strip() if text3 else None | |
if not text1: | |
return "์ค๋ฅ: ์ต์ ํ๋์ ํค์๋๋ฅผ ์ ๋ ฅํด์ฃผ์ธ์." | |
progress(0.05, desc="์์ด๋์ด ์์ฑ ์ค๋น ์ค...") | |
time.sleep(0.3) | |
progress(0.1, desc="์ฐฝ์์ ์ธ ์์ด๋์ด ์์ฑ ์์...") | |
# ์นดํ ๊ณ ๋ฆฌ์ ํด๋นํ๋ ์์ด๋์ด ์์ฑ | |
results = generate_transformations(text1, text2, text3, selected_category) | |
progress(0.8, desc="๊ฒฐ๊ณผ ํฌ๋งทํ ์ค...") | |
formatted = format_results(results) | |
progress(1.0, desc="์๋ฃ!") | |
return formatted | |
############################################################################## | |
# ์์ด๋์ด์ ์ด๋ฏธ์ง๋ฅผ ํจ๊ป ์์ฑํ๋ ์ต์ข ํจ์ | |
############################################################################## | |
def process_all(text1, text2, text3, selected_category, progress=gr.Progress()): | |
idea_result = process_inputs(text1, text2, text3, selected_category, progress) | |
image_result = generate_design_image( | |
idea_result, | |
seed=42, | |
randomize_seed=True, | |
width=1024, | |
height=1024, | |
num_inference_steps=4 | |
) | |
return idea_result, image_result | |
############################################################################## | |
# API ํค ๊ฒฝ๊ณ ๋ฉ์์ง | |
############################################################################## | |
def get_warning_message(): | |
if not GEMINI_API_KEY: | |
return "โ ๏ธ ํ๊ฒฝ ๋ณ์ GEMINI_API_KEY๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค. Gemini API ํค๋ฅผ ์ค์ ํ์ธ์." | |
return "" | |
############################################################################## | |
# Gradio UI | |
############################################################################## | |
with gr.Blocks( | |
title="ํค์๋ ๊ธฐ๋ฐ ์ฐฝ์์ ๋ณํ ์์ด๋์ด ๋ฐ ๋์์ธ ์์ฑ๊ธฐ", | |
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral") | |
) as demo: | |
gr.HTML(""" | |
<style> | |
body { | |
background: linear-gradient(135deg, #e0eafc, #cfdef3); | |
font-family: 'Arial', sans-serif; | |
} | |
.gradio-container { | |
padding: 20px; | |
} | |
h1, h2 { | |
text-align: center; | |
} | |
h1 { | |
color: #333; | |
} | |
h2 { | |
color: #555; | |
} | |
.output { | |
background-color: #ffffff; | |
padding: 15px; | |
border-radius: 8px; | |
} | |
.gr-button { | |
background-color: #4CAF50; | |
color: white; | |
border: none; | |
border-radius: 4px; | |
padding: 8px 16px; | |
} | |
.progress-message { | |
color: #2196F3; | |
font-weight: bold; | |
margin-top: 10px; | |
} | |
</style> | |
""") | |
gr.Markdown("# ๐ ํค์๋ ๊ธฐ๋ฐ ์ฐฝ์์ ๋ณํ ์์ด๋์ด ๋ฐ ๋์์ธ ์์ฑ๊ธฐ") | |
gr.Markdown("์ ๋ ฅํ **ํค์๋**(์ต๋ 3๊ฐ)์ **์นดํ ๊ณ ๋ฆฌ**๋ฅผ ๋ฐํ์ผ๋ก, ์ฐฝ์์ ์ธ ๋ชจ๋ธ/์ปจ์ /ํ์ ๋ณํ ์์ด๋์ด๋ฅผ ์์ฑํ๊ณ , ํด๋น ํ์ฅ ์์ด๋์ด๋ฅผ ํ๋กฌํํธ๋ก ํ์ฌ ๋์์ธ ์ด๋ฏธ์ง๋ฅผ ์์ฑํฉ๋๋ค.") | |
warning = gr.Markdown(get_warning_message()) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
text_input1 = gr.Textbox(label="ํค์๋ 1 (ํ์)", placeholder="์: ์ค๋งํธํฐ") | |
text_input2 = gr.Textbox(label="ํค์๋ 2 (์ ํ)", placeholder="์: ์ธ๊ณต์ง๋ฅ") | |
text_input3 = gr.Textbox(label="ํค์๋ 3 (์ ํ)", placeholder="์: ํฌ์ค์ผ์ด") | |
category_dropdown = gr.Dropdown( | |
label="์นดํ ๊ณ ๋ฆฌ ์ ํ", | |
choices=list(physical_transformation_categories.keys()), | |
value=list(physical_transformation_categories.keys())[0], | |
info="์ถ๋ ฅํ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ ํํ์ธ์." | |
) | |
status_msg = gr.Markdown("๐ก '์์ด๋์ด ์์ฑํ๊ธฐ' ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์ ํํ ์นดํ ๊ณ ๋ฆฌ์ ํด๋นํ๋ ์์ด๋์ด์ ๋์์ธ ์ด๋ฏธ์ง๊ฐ ์์ฑ๋ฉ๋๋ค.") | |
processing_indicator = gr.HTML(""" | |
<div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;"> | |
<div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div> | |
<p style="margin-left: 10px; font-weight: bold; color: #3498db;">์ฒ๋ฆฌ ์ค์ ๋๋ค...</p> | |
</div> | |
<style> | |
@keyframes spin { | |
0% { transform: rotate(0deg); } | |
100% { transform: rotate(360deg); } | |
} | |
</style> | |
""", visible=False) | |
submit_button = gr.Button("์์ด๋์ด ์์ฑํ๊ธฐ", variant="primary") | |
with gr.Column(scale=2): | |
idea_output = gr.Markdown(label="์์ด๋์ด ๊ฒฐ๊ณผ") | |
generated_image = gr.Image(label="์์ฑ๋ ๋์์ธ ์ด๋ฏธ์ง", type="pil") | |
# ์์ | |
gr.Examples( | |
examples=[ | |
["์ค๋งํธํฐ", "", "", list(physical_transformation_categories.keys())[0]], | |
["์๋์ฐจ", "", "", list(physical_transformation_categories.keys())[0]], | |
["์๋์ฐจ", "์ธ๊ณต์ง๋ฅ", "", list(physical_transformation_categories.keys())[0]], | |
["๋๋ก ", "์ธ๊ณต์ง๋ฅ", "", list(physical_transformation_categories.keys())[0]], | |
["์ด๋ํ", "์จ์ด๋ฌ๋ธ", "๊ฑด๊ฐ", list(physical_transformation_categories.keys())[0]], | |
], | |
inputs=[text_input1, text_input2, text_input3, category_dropdown], | |
) | |
# ์ฒ๋ฆฌ์ค ์์ด์ฝ ๋ณด์ด๊ธฐ | |
def show_processing_indicator(): | |
return gr.update(visible=True) | |
# ์ฒ๋ฆฌ์ค ์์ด์ฝ ์จ๊ธฐ๊ธฐ | |
def hide_processing_indicator(): | |
return gr.update(visible=False) | |
# ๋ฒํผ ํด๋ฆญ ์ ์ฒ๋ฆฌ ๋ก์ง | |
submit_button.click( | |
fn=show_processing_indicator, | |
inputs=None, | |
outputs=processing_indicator | |
).then( | |
fn=process_all, | |
inputs=[text_input1, text_input2, text_input3, category_dropdown], | |
outputs=[idea_output, generated_image] | |
).then( | |
fn=hide_processing_indicator, | |
inputs=None, | |
outputs=processing_indicator | |
) | |
# ๋ฉ์ธ ์คํ | |
if __name__ == "__main__": | |
demo.launch(debug=True) | |