OminduAnjana's picture
Update app.py
cb9126f verified
import os
import random
import uuid
import gradio as gr
import numpy as np
from PIL import Image
import spaces
import torch
from diffusers import StableDiffusionXLPipeline, EulerAncestralDiscreteScheduler
from typing import Tuple
css = '''
.gradio-container{max-width: 575px !important}
h1{text-align:center}
footer {
visibility: hidden
}
'''
DESCRIPTIONXX = """## LENNOX TEXT 2 IMAGE🥠"""
examples = [
"Neon-lit futuristic city at night, towering skyscrapers, flying cars, and glowing billboards. People in cyberpunk attire walk below a starry sky.",
"Mystical forest with glowing plants, bioluminescent trees, and magical creatures like fairies and fireflies. Mist and soft light create a dreamlike feel.",
"Medieval knight in detailed armor on a cliff, sword in hand, sunset light highlighting a kingdom and castle in the background.",
"Modern, minimalist living room with soft gray and wood tones, large window with natural light, a simple couch, and potted plants for a cozy vibe.",
"Majestic lion on a rock in the African savanna at sunrise, mane blowing in the wind, with acacia trees and golden grass under warm light."
]
MODEL_OPTIONS = {
"LENNOX-AI V2.0": "SG161222/RealVisXL_V5.0_Lightning",
"LENNOX-AI V1.0": "SG161222/RealVisXL_V4.0_Lightning",
}
MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "4096"))
USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE", "0") == "1"
ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD", "0") == "1"
BATCH_SIZE = int(os.getenv("BATCH_SIZE", "1"))
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
style_list = [
{
"name": "3840 x 2160",
"prompt": "hyper-realistic 8K image of {prompt}. ultra-detailed, lifelike, high-resolution, sharp, vibrant colors, photorealistic",
"negative_prompt": "cartoonish, low resolution, blurry, simplistic, abstract, deformed, ugly",
},
{
"name": "2560 x 1440",
"prompt": "hyper-realistic 4K image of {prompt}. ultra-detailed, lifelike, high-resolution, sharp, vibrant colors, photorealistic",
"negative_prompt": "cartoonish, low resolution, blurry, simplistic, abstract, deformed, ugly",
},
{
"name": "HD+",
"prompt": "hyper-realistic 2K image of {prompt}. ultra-detailed, lifelike, high-resolution, sharp, vibrant colors, photorealistic",
"negative_prompt": "cartoonish, low resolution, blurry, simplistic, abstract, deformed, ugly",
},
{
"name": "Style Zero",
"prompt": "{prompt}",
"negative_prompt": "",
},
]
styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list}
DEFAULT_STYLE_NAME = "3840 x 2160"
STYLE_NAMES = list(styles.keys())
def apply_style(style_name: str, positive: str, negative: str = "") -> Tuple[str, str]:
if style_name in styles:
p, n = styles.get(style_name, styles[DEFAULT_STYLE_NAME])
else:
p, n = styles[DEFAULT_STYLE_NAME]
if not negative:
negative = ""
return p.replace("{prompt}", positive), n + negative
def load_and_prepare_model(model_id):
pipe = StableDiffusionXLPipeline.from_pretrained(
model_id,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
use_safetensors=True,
add_watermarker=False,
).to(device)
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
if USE_TORCH_COMPILE:
pipe.compile()
if ENABLE_CPU_OFFLOAD:
pipe.enable_model_cpu_offload()
return pipe
# Preload and compile both models
models = {key: load_and_prepare_model(value) for key, value in MODEL_OPTIONS.items()}
MAX_SEED = np.iinfo(np.int32).max
def save_image(img):
unique_name = str(uuid.uuid4()) + ".png"
img.save(unique_name)
return unique_name
def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
if randomize_seed:
seed = random.randint(0, MAX_SEED)
return seed
@spaces.GPU(duration=60, enable_queue=True)
def generate(
model_choice: str,
prompt: str,
negative_prompt: str = "",
use_negative_prompt: bool = False,
style_selection: str = DEFAULT_STYLE_NAME,
seed: int = 1,
width: int = 1024,
height: int = 1024,
guidance_scale: float = 3,
num_inference_steps: int = 25,
randomize_seed: bool = False,
use_resolution_binning: bool = True,
num_images: int = 1,
progress=gr.Progress(track_tqdm=True),
):
global models
pipe = models[model_choice]
seed = int(randomize_seed_fn(seed, randomize_seed))
generator = torch.Generator(device=device).manual_seed(seed)
prompt, negative_prompt = apply_style(style_selection, prompt, negative_prompt)
options = {
"prompt": [prompt] * num_images,
"negative_prompt": [negative_prompt] * num_images if use_negative_prompt else None,
"width": width,
"height": height,
"guidance_scale": guidance_scale,
"num_inference_steps": num_inference_steps,
"generator": generator,
"output_type": "pil",
}
if use_resolution_binning:
options["use_resolution_binning"] = True
images = []
for i in range(0, num_images, BATCH_SIZE):
batch_options = options.copy()
batch_options["prompt"] = options["prompt"][i:i+BATCH_SIZE]
if "negative_prompt" in batch_options:
batch_options["negative_prompt"] = options["negative_prompt"][i:i+BATCH_SIZE]
images.extend(pipe(**batch_options).images)
image_paths = [save_image(img) for img in images]
return image_paths, seed
with gr.Blocks(css=css, theme="bethecloud/storj_theme") as demo:
gr.Markdown(DESCRIPTIONXX)
with gr.Row():
prompt = gr.Text(
label="Prompt",
show_label=False,
max_lines=1,
placeholder="Enter your prompt",
container=False,
)
run_button = gr.Button("Run", scale=0)
result = gr.Gallery(label="Result", columns=1, show_label=False)
with gr.Row():
model_choice = gr.Dropdown(
label="Model Selection⬇️",
choices=list(MODEL_OPTIONS.keys()),
value="LENNOX-AI V2.0"
)
with gr.Accordion("Advanced options", open=False, visible=False):
style_selection = gr.Radio(
show_label=True,
container=True,
interactive=True,
choices=STYLE_NAMES,
value=DEFAULT_STYLE_NAME,
label="Quality Style",
)
num_images = gr.Slider(
label="Number of Images",
minimum=1,
maximum=5,
step=1,
value=1,
)
with gr.Row():
with gr.Column(scale=1):
use_negative_prompt = gr.Checkbox(label="Use negative prompt", value=True)
negative_prompt = gr.Text(
label="Negative prompt",
max_lines=5,
lines=4,
placeholder="Enter a negative prompt",
value="(deformed, distorted, disfigured:1.3), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, (mutated hands and fingers:1.4), disconnected limbs, mutation, mutated, ugly, disgusting, blurry, amputation",
visible=True,
)
seed = gr.Slider(
label="Seed",
minimum=0,
maximum=MAX_SEED,
step=1,
value=0,
)
randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
with gr.Row():
width = gr.Slider(
label="Width",
minimum=512,
maximum=MAX_IMAGE_SIZE,
step=8,
value=1024,
)
height = gr.Slider(
label="Height",
minimum=512,
maximum=MAX_IMAGE_SIZE,
step=8,
value=1024,
)
with gr.Row():
guidance_scale = gr.Slider(
label="Guidance Scale",
minimum=0.1,
maximum=6,
step=0.1,
value=3.0,
)
num_inference_steps = gr.Slider(
label="Number of inference steps",
minimum=1,
maximum=60,
step=1,
value=28,
)
gr.Examples(
examples=examples,
inputs=prompt,
cache_examples=False
)
use_negative_prompt.change(
fn=lambda x: gr.update(visible=x),
inputs=use_negative_prompt,
outputs=negative_prompt,
api_name=False,
)
gr.on(
triggers=[
prompt.submit,
negative_prompt.submit,
run_button.click,
],
fn=generate,
inputs=[
model_choice,
prompt,
negative_prompt,
use_negative_prompt,
style_selection,
seed,
width,
height,
guidance_scale,
num_inference_steps,
randomize_seed,
num_images,
],
outputs=[result, seed],
)
#gr.Markdown("### Image Gallery")
#predefined_gallery = gr.Gallery(label="Image Gallery", columns=3, show_label=False, value=load_predefined_images())
gr.Markdown(
"""
<div style="text-align: justify;">
🖌️ Image Generation by Omindu Dissanayaka: Using LENNOX-AI V2.0 and LENNOX-AI V1.0 models for high-quality images. This demo space showcases image generation with the Stable Diffusion XL model variants, available for experimenting with different styles and models.
</div>
"""
)
gr.Markdown(
"""
<div style="text-align: justify;">
🎨 Explore the demo space for Stable Diffusion XL, designed by Omindu Dissanayaka. Generate images with diverse styles and models for higher-quality results. Experiment with sample prompts to create unique, high-quality images.
</div>
"""
)
gr.Markdown(
"""
<div style="text-align: justify;">
⚠️ Disclaimer: Users are responsible for ensuring that generated content complies with ethical standards.
</div>
"""
)
if __name__ == "__main__":
demo.queue(max_size=50).launch(show_api=True)