Up_G / app.py
ssboost's picture
Update app.py
02748b3 verified
raw
history blame
9.78 kB
import os
import sys
import logging
import replicate
import gradio as gr
from PIL import Image
import tempfile
import uuid
# ๋กœ๊น… ์„ค์ •
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger("clarity-upscaler")
# Replicate API ํ† ํฐ ์„ค์ •
REPLICATE_API_TOKEN = os.environ.get("REPLICATE_API_TOKEN", "")
if not REPLICATE_API_TOKEN:
logger.warning("REPLICATE_API_TOKEN์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
# ์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
TEMP_DIR = os.path.join(tempfile.gettempdir(), "clarity_upscaler")
os.makedirs(TEMP_DIR, exist_ok=True)
logger.info(f"์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ: {TEMP_DIR}")
def upscale_image(
image,
scale_factor=2,
output_format="jpg",
sd_model="juggernaut_reborn.safetensors [338b85bc4f]",
resemblance=0.6,
creativity=0.35,
prompt="masterpiece, best quality, highres, <lora:more_details:0.5> <lora:SDXLrender_v2.0:1>",
negative_prompt="(worst quality, low quality, normal quality:2) JuggernautNegative-neg",
seed=1337,
dynamic=6,
sharpen=0
):
"""
Clarity Upscaler๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํ™”์งˆ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.
Args:
image: ์ž…๋ ฅ ์ด๋ฏธ์ง€
scale_factor: ํ™•๋Œ€ ๋น„์œจ (๊ธฐ๋ณธ๊ฐ’: 2)
output_format: ์ถœ๋ ฅ ํ˜•์‹ (๊ธฐ๋ณธ๊ฐ’: jpg)
sd_model: ์‚ฌ์šฉํ•  SD ๋ชจ๋ธ
resemblance: ์›๋ณธ๊ณผ์˜ ์œ ์‚ฌ๋„ (0.0-1.0)
creativity: ์ฐฝ์˜์„ฑ ์ˆ˜์ค€ (0.0-1.0)
prompt: ์—…์Šค์ผ€์ผ๋ง ๊ฐ€์ด๋“œ ํ”„๋กฌํ”„ํŠธ
negative_prompt: ๋„ค๊ฑฐํ‹ฐ๋ธŒ ํ”„๋กฌํ”„ํŠธ
seed: ๋žœ๋ค ์‹œ๋“œ
dynamic: ๋‹ค์ด๋‚˜๋ฏน ์ž„๊ณ„๊ฐ’ (1-10)
sharpen: ์„ ๋ช…๋„ (0-2)
Returns:
๊ฐœ์„ ๋œ ์ด๋ฏธ์ง€
"""
if REPLICATE_API_TOKEN == "":
raise ValueError("REPLICATE_API_TOKEN์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
try:
# ์ด๋ฏธ์ง€ ์ €์žฅ
temp_input_path = os.path.join(TEMP_DIR, f"input_{uuid.uuid4()}.png")
image.save(temp_input_path)
logger.info(f"์ž…๋ ฅ ์ด๋ฏธ์ง€ ์ €์žฅ: {temp_input_path}")
# Replicate ์„ค์ •
replicate.client.Client(api_token=REPLICATE_API_TOKEN)
# ๋กœ๊ทธ ์ •๋ณด ์ถœ๋ ฅ
logger.info("=== Clarity Upscaler ์‹คํ–‰ ์ •๋ณด ===")
logger.info(f"๋ชจ๋ธ: philz1337x/clarity-upscaler")
logger.info(f"SD ๋ชจ๋ธ: {sd_model}")
logger.info(f"์Šค์ผ€์ผ ํŒฉํ„ฐ: {scale_factor}")
logger.info(f"์ถœ๋ ฅ ํ˜•์‹: {output_format}")
logger.info(f"์œ ์‚ฌ๋„: {resemblance}")
logger.info(f"์ฐฝ์˜์„ฑ: {creativity}")
logger.info(f"๋‹ค์ด๋‚˜๋ฏน: {dynamic}")
logger.info(f"์„ ๋ช…๋„: {sharpen}")
logger.info(f"์‹œ๋“œ: {seed}")
# API ํ˜ธ์ถœ
output = replicate.run(
"philz1337x/clarity-upscaler:dfad41707589d68ecdccd1dfa600d55a208f9310748e44bfe35b4a6291453d5e",
input={
"seed": seed,
"image": open(temp_input_path, "rb"),
"prompt": prompt,
"dynamic": dynamic,
"handfix": "disabled",
"pattern": False,
"sharpen": sharpen,
"sd_model": sd_model,
"scheduler": "DPM++ 3M SDE Karras",
"creativity": creativity,
"lora_links": "",
"downscaling": False,
"resemblance": resemblance,
"scale_factor": scale_factor,
"tiling_width": 112,
"output_format": output_format,
"tiling_height": 144,
"custom_sd_model": "",
"negative_prompt": negative_prompt,
"num_inference_steps": 18,
"downscaling_resolution": 768
}
)
logger.info(f"Replicate API ์‘๋‹ต: {output}")
# ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ๋ฐ ๋ฐ˜ํ™˜
if output and isinstance(output, list) and len(output) > 0:
import requests
from io import BytesIO
response = requests.get(output[0])
if response.status_code == 200:
result_image = Image.open(BytesIO(response.content))
# JPG๋กœ ๋ณ€ํ™˜ (output_format์ด jpg์ธ ๊ฒฝ์šฐ)
if output_format.lower() == "jpg":
temp_output = BytesIO()
if result_image.mode == 'RGBA':
result_image = result_image.convert('RGB')
result_image.save(temp_output, format='JPEG', quality=95)
temp_output.seek(0)
result_image = Image.open(temp_output)
logger.info("์ด๋ฏธ์ง€ ํ™”์งˆ ๊ฐœ์„  ์™„๋ฃŒ!")
return result_image
else:
logger.error(f"๊ฒฐ๊ณผ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์‹คํŒจ: {response.status_code}")
return None
else:
logger.error("API ์‘๋‹ต์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
return None
except Exception as e:
logger.error(f"ํ™”์งˆ ๊ฐœ์„  ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
raise
finally:
# ์ž„์‹œ ํŒŒ์ผ ์ •๋ฆฌ
if os.path.exists(temp_input_path):
os.remove(temp_input_path)
# Gradio ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ
def create_interface():
with gr.Blocks(title="Clarity Upscaler - ์ด๋ฏธ์ง€ ํ™”์งˆ ๊ฐœ์„ ") as demo:
gr.Markdown("# Clarity Upscaler - ์ด๋ฏธ์ง€ ํ™”์งˆ ๊ฐœ์„  ๋„๊ตฌ")
gr.Markdown("Replicate์˜ Clarity Upscaler ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์˜ ํ™”์งˆ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.")
with gr.Row():
with gr.Column():
input_image = gr.Image(label="์›๋ณธ ์ด๋ฏธ์ง€", type="pil")
with gr.Accordion("๊ณ ๊ธ‰ ์„ค์ •", open=False):
scale_factor = gr.Slider(minimum=1, maximum=4, value=2, step=0.5, label="ํ™•๋Œ€ ๋น„์œจ")
output_format = gr.Radio(["jpg", "png"], value="jpg", label="์ถœ๋ ฅ ํ˜•์‹")
sd_model = gr.Dropdown(
choices=[
"juggernaut_reborn.safetensors [338b85bc4f]",
"sd_xl_base_1.0.safetensors [39d4e625d]",
"sdxl_base_v0.9-9961.safetensors [3048045c]",
"realisticVisionV51_v51VAE.safetensors [5ecbfa0ac]",
],
value="juggernaut_reborn.safetensors [338b85bc4f]",
label="SD ๋ชจ๋ธ"
)
resemblance = gr.Slider(minimum=0.0, maximum=1.0, value=0.6, step=0.05, label="์›๋ณธ ์œ ์‚ฌ๋„")
creativity = gr.Slider(minimum=0.0, maximum=1.0, value=0.35, step=0.05, label="์ฐฝ์˜์„ฑ")
dynamic = gr.Slider(minimum=1, maximum=10, value=6, step=1, label="๋‹ค์ด๋‚˜๋ฏน ์ž„๊ณ„๊ฐ’")
sharpen = gr.Slider(minimum=0, maximum=2, value=0, step=0.1, label="์„ ๋ช…๋„")
seed = gr.Number(value=1337, label="์‹œ๋“œ", precision=0)
submit_btn = gr.Button("ํ™”์งˆ ๊ฐœ์„  ์‹œ์ž‘", variant="primary")
with gr.Column():
output_image = gr.Image(label="๊ฐœ์„ ๋œ ์ด๋ฏธ์ง€")
log_output = gr.Textbox(label="๋กœ๊ทธ", lines=10)
# ๋กœ๊ทธ ์บก์ฒ˜ ํ•จ์ˆ˜
class LogCapture:
def __init__(self):
self.logs = []
self.handler = self.create_handler()
def create_handler(self):
handler = logging.StreamHandler(stream=self)
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
return handler
def write(self, message):
self.logs.append(message)
def flush(self):
pass
def get_logs(self):
return "".join(self.logs)
def clear(self):
self.logs.clear()
log_capture = LogCapture()
logger.addHandler(log_capture.handler)
# ์ œ์ถœ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋™์ž‘
def process_image(image, scale_factor, output_format, sd_model, resemblance, creativity, dynamic, sharpen, seed):
if image is None:
return None, "์˜ค๋ฅ˜: ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”."
log_capture.clear()
try:
result = upscale_image(
image=image,
scale_factor=scale_factor,
output_format=output_format,
sd_model=sd_model,
resemblance=resemblance,
creativity=creativity,
dynamic=dynamic,
sharpen=sharpen,
seed=int(seed)
)
return result, log_capture.get_logs()
except Exception as e:
logger.error(f"์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
return None, log_capture.get_logs()
submit_btn.click(
process_image,
inputs=[
input_image, scale_factor, output_format, sd_model,
resemblance, creativity, dynamic, sharpen, seed
],
outputs=[output_image, log_output]
)
return demo
# ๋ฉ”์ธ ์‹คํ–‰
if __name__ == "__main__":
demo = create_interface()
demo.launch(share=True)