Spaces:
Runtime error
Runtime error
| # ๐จ Connect AI LAB โ ๋ฌด๋ฃ ์คํ์์ค AI ์ด๋ฏธ์ง ์์ฑ + ํธ์ง (ZeroGPU) | |
| # ๐จ ์์ฑ = Krea-2-Turbo (12B) ยท โ๏ธ ํธ์ง = FLUX.1-Kontext(์ต๊ณ ๊ธ, ํ ํฐ ์์ผ๋ฉด) / InstructPix2Pix(ํด๋ฐฑ) | |
| # ์ ํ๋ธ(@CONNECT-AI-LAB) ํ๋ณด ยท ๋์์ธ์ ๊ธฐ๋ณธ ํ ๋ง + ์๋จ ๋ฐฐ๋. | |
| import random | |
| import gradio as gr | |
| import numpy as np | |
| import spaces | |
| import torch | |
| GEN_ID = "krea/Krea-2-Turbo" | |
| EDIT_ID = "black-forest-labs/FLUX.2-klein-4B" # ์ต์ ยทungatedยทApache 2.0ยท์์ฑ+ํธ์ง ํตํฉ(4B) | |
| IP2P_ID = "timbrooks/instruct-pix2pix" # ํด๋ฐฑ(ungated) | |
| YOUTUBE = "https://www.youtube.com/@CONNECT-AI-LAB" | |
| DEVICE = "cuda" if torch.cuda.is_available() else "cpu" | |
| MAX_SEED = np.iinfo(np.int32).max | |
| # โโ ๐จ ์์ฑ (Krea-2-Turbo) โโ | |
| try: | |
| from diffusers import Krea2Pipeline | |
| gen_pipe = Krea2Pipeline.from_pretrained(GEN_ID, torch_dtype=torch.bfloat16) | |
| except Exception: | |
| from diffusers import DiffusionPipeline | |
| gen_pipe = DiffusionPipeline.from_pretrained(GEN_ID, torch_dtype=torch.bfloat16, trust_remote_code=True) | |
| gen_pipe = gen_pipe.to(DEVICE) | |
| # โโ โ๏ธ ํธ์ง: FLUX.2-klein-4B(์ต์ ยทungated) ์ฐ์ , ์คํจ ์ InstructPix2Pix ํด๋ฐฑ โโ | |
| EDIT_MODE = "ip2p" | |
| try: | |
| from diffusers import Flux2KleinPipeline | |
| edit_pipe = Flux2KleinPipeline.from_pretrained(EDIT_ID, torch_dtype=torch.bfloat16) | |
| EDIT_MODE = "flux2" | |
| except Exception as e: | |
| print(f"[edit] FLUX.2-klein ๋ถ๊ฐ({e}); InstructPix2Pix๋ก ํด๋ฐฑ") | |
| from diffusers import StableDiffusionInstructPix2PixPipeline | |
| edit_pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained( | |
| IP2P_ID, torch_dtype=torch.float16, safety_checker=None) | |
| edit_pipe = edit_pipe.to(DEVICE) | |
| def generate(prompt, seed, randomize_seed, steps, progress=gr.Progress(track_tqdm=True)): | |
| if not prompt or not prompt.strip(): | |
| raise gr.Error("๋ฌด์์ ๊ทธ๋ฆด์ง ์ ๋ ฅํด์ฃผ์ธ์ ๐ (์: ๋ ์์ ๊ท์ฌ์ด ์ฌ์ฐ)") | |
| if randomize_seed: | |
| seed = random.randint(0, MAX_SEED) | |
| g = torch.Generator(device=DEVICE).manual_seed(int(seed)) | |
| image = gen_pipe(prompt, num_inference_steps=int(steps), generator=g).images[0] | |
| return image, seed | |
| def edit(image, instruction, steps, strength, progress=gr.Progress(track_tqdm=True)): | |
| if image is None: | |
| raise gr.Error("ํธ์งํ ์ด๋ฏธ์ง๋ฅผ ๋จผ์ ์ฌ๋ ค์ฃผ์ธ์ ๐") | |
| if not instruction or not instruction.strip(): | |
| raise gr.Error("์ด๋ป๊ฒ ๋ฐ๊ฟ์ง ์ ์ด์ฃผ์ธ์ (์: ํ๋์ ๋ณด๋ผ์์ผ๋ก, ๊ฒจ์ธ๋ก ๋ฐ๊ฟ์ค)") | |
| img = image.convert("RGB") | |
| img.thumbnail((1024, 1024)) | |
| if EDIT_MODE == "flux2": | |
| out = edit_pipe(image=img, prompt=instruction, | |
| guidance_scale=float(strength), num_inference_steps=int(steps)).images[0] | |
| else: | |
| out = edit_pipe(instruction, image=img, num_inference_steps=int(steps), | |
| image_guidance_scale=1.5, guidance_scale=7.5).images[0] | |
| return out | |
| GEN_EXAMPLES = [ | |
| "๋ ์์ ๊ฑท๋ ๊ท์ฌ์ด ์๊ธฐ ์ฌ์ฐ, ๋ฐ๋ปํ ์กฐ๋ช , ์๋ค๋งํฑ, ๊ณ ํ์ง", | |
| "๋ค์จ ์ฌ์ธ ๊ฐ๋ํ ๋ฐค์ ์์ธ ๊ฑฐ๋ฆฌ, ๋น ์ค๋ ์ฌ์ด๋ฒํํฌ, ๋ํ ์ผ", | |
| "๋ฏธ๋๋ฉํ ๋ก๊ณ : ์ด๋ก๋น AI ๋๋, ์ฌํ, ๋ฒกํฐ ์คํ์ผ, ํฐ ๋ฐฐ๊ฒฝ", | |
| "์ฐ์ฃผ์์ ์ง๊ตฌ๋ฅผ ๋ฐ๋ผ๋ณด๋ ์ฐ์ฃผ๋นํ์ฌ, ์ฌ์ค์ , 4k, ์ํ ๊ฐ์", | |
| ] | |
| EDIT_EXAMPLES = ["ํ๋์ ๋ณด๋ผ์ ๋ ธ์๋ก ๋ฐ๊ฟ์ค", "๊ฒจ์ธ ๋ ๋ด๋ฆฌ๋ ์ฅ๋ฉด์ผ๋ก", "์์ฑํ ๊ทธ๋ฆผ ์คํ์ผ๋ก", | |
| "๋ค์จ ์ฌ์ด๋ฒํํฌ ๋๋์ผ๋ก", "๋ฐฐ๊ฒฝ์ ์ฐ์ฃผ๋ก ๋ฐ๊ฟ์ค"] | |
| CSS = """ | |
| .gradio-container {max-width: 960px !important; margin: auto !important;} | |
| #hero {text-align:center; padding: 26px 16px; margin-bottom: 8px; border-radius: 18px; | |
| background: linear-gradient(135deg, #0c2a1a, #0a1830); border: 1px solid rgba(57,255,20,.25);} | |
| #hero .brand {font-family: ui-monospace, monospace; letter-spacing: 6px; color: #58ff86; font-size: 12px;} | |
| #hero h1 {color:#ffffff; font-size: 34px; font-weight: 800; margin: 8px 0 4px;} | |
| #hero .sub {color:#bfeecf; font-size: 14px; margin: 2px 0 0;} | |
| #hero .grn {color:#39ff14; font-weight:700;} | |
| .yt-btn {display:inline-flex; align-items:center; gap:8px; margin-top:14px; padding:12px 24px; border-radius:12px; | |
| text-decoration:none; font-weight:800; font-size:14px; color:#ffffff !important; | |
| background:linear-gradient(135deg,#ff2d55,#ff0000); box-shadow:0 6px 22px rgba(255,0,0,.35);} | |
| .yt-btn:hover {filter:brightness(1.08);} | |
| #foot {text-align:center; color:#8a8f98; font-size:13px; padding:16px 8px;} | |
| #foot a {color:#e11d48; text-decoration:none; font-weight:700;} | |
| """ | |
| _edit_note = ("โ๏ธ ํธ์ง: FLUX.2-klein (์ต์ ยท๊ณ ๊ธ)" if EDIT_MODE == "flux2" | |
| else "โ๏ธ ํธ์ง: ๊ธฐ๋ณธ ๋ชจ๋ (FLUX.2 ๋ก๋ ๋๊ธฐ)") | |
| with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="green"), title="Connect AI LAB") as demo: | |
| gr.HTML(f""" | |
| <div id="hero"> | |
| <div class="brand">โ CONNECT ยท AI ยท LAB</div> | |
| <h1>๐จ AI ์ด๋ฏธ์ง ์์ฑ & ํธ์ง</h1> | |
| <div class="sub">ํ ์คํธ๋ก <span class="grn">๊ทธ๋ฆฌ๊ณ </span>, ์ด๋ฏธ์ง๋ฅผ <span class="grn">ํธ์ง</span>๊น์ง ยท ๋ฌด๋ฃ ยท ์คํ์์ค</div> | |
| <a class="yt-btn" href="{YOUTUBE}" target="_blank">โถ ์ ํ๋ธ ๊ตฌ๋ ยท @CONNECT-AI-LAB</a> | |
| </div> | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("๐จ ์์ฑ"): | |
| with gr.Row(): | |
| g_prompt = gr.Textbox(label="๋ฌด์์ ๊ทธ๋ฆด๊น์?", | |
| placeholder="์: ๋ ์์ ๊ท์ฌ์ด ์๊ธฐ ์ฌ์ฐ, ๋ฐ๋ปํ ์กฐ๋ช , ์๋ค๋งํฑ", | |
| scale=5, lines=2) | |
| g_run = gr.Button("๐จ ๊ทธ๋ฆฌ๊ธฐ", variant="primary", scale=1) | |
| g_result = gr.Image(label="๊ฒฐ๊ณผ", height=520) | |
| with gr.Accordion("โ๏ธ ์ธ๋ถ ์ค์ ", open=False): | |
| with gr.Row(): | |
| g_steps = gr.Slider(4, 16, value=8, step=1, label="์คํ ") | |
| g_seed = gr.Slider(0, MAX_SEED, value=42, step=1, label="์๋") | |
| g_rand = gr.Checkbox(label="์๋ ๋๋ค(๋งค๋ฒ ๋ค๋ฅธ ๊ทธ๋ฆผ)", value=True) | |
| gr.Examples(examples=GEN_EXAMPLES, inputs=[g_prompt], label="โจ ์์") | |
| g_in = [g_prompt, g_seed, g_rand, g_steps] | |
| g_run.click(generate, inputs=g_in, outputs=[g_result, g_seed]) | |
| g_prompt.submit(generate, inputs=g_in, outputs=[g_result, g_seed]) | |
| with gr.TabItem("โ๏ธ ํธ์ง"): | |
| gr.Markdown(f"##### {_edit_note}") | |
| with gr.Row(): | |
| e_img = gr.Image(label="ํธ์งํ ์ด๋ฏธ์ง ์ฌ๋ฆฌ๊ธฐ", type="pil", height=340) | |
| e_out = gr.Image(label="ํธ์ง ๊ฒฐ๊ณผ", height=340) | |
| with gr.Row(): | |
| e_inst = gr.Textbox(label="์ด๋ป๊ฒ ๋ฐ๊ฟ๊น์? (์ง์)", | |
| placeholder="์: ํ๋์ ๋ณด๋ผ์ ๋ ธ์๋ก, ๊ฒจ์ธ๋ก ๋ฐ๊ฟ์ค, ์์ฑํ ์คํ์ผ๋ก", | |
| scale=5, lines=2) | |
| e_run = gr.Button("โ๏ธ ํธ์ง", variant="primary", scale=1) | |
| with gr.Accordion("โ๏ธ ์ธ๋ถ ์ค์ ", open=False): | |
| e_steps = gr.Slider(8, 40, value=18, step=1, label="์คํ (๋ฎ์์๋ก ๋น ๋ฆยท์ฟผํฐ ์ ์ฝ)") | |
| e_str = gr.Slider(1.0, 5.0, value=2.5, step=0.1, label="์ง์ ๋ฐ์ ๊ฐ๋") | |
| gr.Examples(examples=EDIT_EXAMPLES, inputs=[e_inst], label="โจ ํธ์ง ์์") | |
| e_run.click(edit, inputs=[e_img, e_inst, e_steps, e_str], outputs=[e_out]) | |
| gr.HTML(f""" | |
| <div id="foot">๐ฑ Powered by <b>Connect AI LAB</b> ยท ๋ ๋ง์ AI ํ์ฉ๋ฒ์ | |
| ๐ <a href="{YOUTUBE}" target="_blank">์ ํ๋ธ @CONNECT-AI-LAB</a> ๊ตฌ๋ !</div> | |
| """) | |
| if __name__ == "__main__": | |
| demo.launch() | |