File size: 6,460 Bytes
6001e3c 6bc9074 e845246 8ee496d 922fdb6 6bc9074 6001e3c 70f555c 8ee496d e845246 6bc9074 70f555c 922fdb6 70f555c 922fdb6 223ef25 70f555c 223ef25 70f555c 5de7ece 70f555c 922fdb6 70f555c 922fdb6 8c7013a 70f555c 8c7013a 70f555c 8c7013a 70f555c 6bc9074 70f555c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
import gradio as gr
import spaces
import torch
import os
from compel import Compel, ReturnedEmbeddingsType
from diffusers import DiffusionPipeline
# 모델 로드
model_name = os.environ.get('MODEL_NAME', 'UnfilteredAI/NSFW-gen-v2')
pipe = DiffusionPipeline.from_pretrained(
model_name,
torch_dtype=torch.float16
)
pipe.to('cuda')
# Compel 설정
compel = Compel(
tokenizer=[pipe.tokenizer, pipe.tokenizer_2],
text_encoder=[pipe.text_encoder, pipe.text_encoder_2],
returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,
requires_pooled=[False, True]
)
# 기본 네거티브 프롬프트
default_negative_prompt = "(low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn, (deformed | distorted | disfigured:1.3), bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, mutated hands and fingers:1.4, disconnected limbs, blurry, amputation."
# 예제 프롬프트 목록
example_prompts = [
["a beautiful woman in a summer dress at the beach, golden sunset, professional photography, 8k", default_negative_prompt, 40, 7.5, 1024, 1024, 4],
["portrait of a cyberpunk character, highly detailed, neon lights, futuristic cityscape in background, 8k, ultra realistic", default_negative_prompt, 50, 8.0, 768, 1024, 4],
["detailed fantasy art of magical forest with fairies, ethereal lighting, mystical atmosphere", default_negative_prompt, 60, 7.0, 1024, 768, 4],
["photorealistic portrait of a stunning model, studio lighting, fashion photography", default_negative_prompt, 45, 7.0, 1024, 1024, 4],
]
# 이미지 생성 함수
@spaces.GPU(duration=120)
def generate(prompt, negative_prompt, num_inference_steps, guidance_scale, width, height, num_samples, progress=gr.Progress()):
progress(0, desc="Preparing")
embeds, pooled = compel(prompt)
neg_embeds, neg_pooled = compel(negative_prompt)
progress(0.1, desc="Generating images")
images = pipe(
prompt_embeds=embeds,
pooled_prompt_embeds=pooled,
negative_prompt_embeds=neg_embeds,
negative_pooled_prompt_embeds=neg_pooled,
num_inference_steps=num_inference_steps,
guidance_scale=guidance_scale,
width=width,
height=height,
num_images_per_prompt=num_samples,
callback=lambda i, t, latents: progress((i + 1) / num_inference_steps)
).images
return images
# CSS 스타일
css = """
.gallery-item {
transition: transform 0.2s;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
border-radius: 10px;
}
.gallery-item:hover {
transform: scale(1.03);
box-shadow: 0 8px 16px rgba(0,0,0,0.2);
}
.container {
max-width: 1200px;
margin: auto;
}
.header {
text-align: center;
margin-bottom: 2rem;
padding: 1rem;
background: linear-gradient(90deg, rgba(76,0,161,0.8) 0%, rgba(28,110,164,0.8) 100%);
border-radius: 10px;
color: white;
}
.slider-container {
background-color: #f5f5f5;
padding: 1rem;
border-radius: 10px;
margin-bottom: 1rem;
}
.prompt-container {
background-color: #f0f8ff;
padding: 1rem;
border-radius: 10px;
margin-bottom: 1rem;
border: 1px solid #d0e8ff;
}
.examples-header {
background: linear-gradient(90deg, rgba(41,128,185,0.7) 0%, rgba(142,68,173,0.7) 100%);
color: white;
padding: 0.5rem;
border-radius: 8px;
text-align: center;
margin-bottom: 0.5rem;
}
"""
# Gradio 인터페이스
with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
gr.HTML("""
<div class="header">
<h1>🎨 UnfilteredAI NSFW-gen-v2 이미지 생성기</h1>
<p>창의적인 프롬프트를 입력하고 고품질 이미지를 생성해보세요.</p>
</div>
""")
with gr.Row():
with gr.Column(scale=2):
with gr.Group(elem_classes="prompt-container"):
prompt = gr.Textbox(label="프롬프트", placeholder="원하는 이미지를 설명해주세요...", lines=3)
negative_prompt = gr.Textbox(
label="네거티브 프롬프트",
value=default_negative_prompt,
lines=3
)
with gr.Group(elem_classes="slider-container"):
with gr.Row():
with gr.Column():
steps = gr.Slider(minimum=20, maximum=100, value=60, step=1, label="추론 단계 (Quality)", info="높을수록 품질 향상 (시간 증가)")
guidance = gr.Slider(minimum=1, maximum=15, value=7, step=0.1, label="가이던스 스케일 (Creativity)", info="낮을수록 더 창의적인 결과")
with gr.Column():
with gr.Row():
width = gr.Slider(minimum=512, maximum=1536, value=1024, step=128, label="너비")
height = gr.Slider(minimum=512, maximum=1536, value=1024, step=128, label="높이")
num_samples = gr.Slider(minimum=1, maximum=8, value=4, step=1, label="생성할 이미지 수", info="한 번에 생성할 이미지 수")
generate_btn = gr.Button("🚀 이미지 생성", variant="primary", size="lg")
with gr.Column(scale=3):
output_gallery = gr.Gallery(label="생성된 이미지", elem_classes="gallery-item", columns=2, object_fit="contain", height=650)
gr.HTML("""<div class="examples-header"><h3>✨ 예제 프롬프트</h3></div>""")
gr.Examples(
examples=example_prompts,
inputs=[prompt, negative_prompt, steps, guidance, width, height, num_samples],
outputs=output_gallery,
fn=generate,
cache_examples=True,
)
# 이벤트 연결
generate_btn.click(
fn=generate,
inputs=[prompt, negative_prompt, steps, guidance, width, height, num_samples],
outputs=output_gallery
)
gr.HTML("""
<div style="text-align: center; margin-top: 20px; padding: 10px; background-color: #f0f0f0; border-radius: 10px;">
<p>💡 팁: 고품질 이미지를 위해서는 세부적인 프롬프트와 더 높은 추론 단계를 사용하세요.</p>
<p>예) "professional photography, 8k, highly detailed, sharp focus, HDR" 등의 품질 관련 용어를 추가해보세요.</p>
</div>
""")
demo.launch() |