from __future__ import annotations import os import random import uuid import gradio as gr import spaces import numpy as np from diffusers import PixArtAlphaPipeline, LCMScheduler import torch from typing import Tuple from datetime import datetime # Description for the app DESCRIPTION = """ # Instant Image ### Super fast text to Image Generator. ### You may change the steps from 4 to 8, if you didn't get satisfied results. ### First Image processing takes time then images generate faster. ### Must Try -> Instant Video https://huggingface.co/spaces/KingNish/Instant-Video """ if not torch.cuda.is_available(): DESCRIPTION += "\n

Running on CPU 🥶 This demo does not work on CPU.

" # Configuration and constants MAX_SEED = np.iinfo(np.int32).max CACHE_EXAMPLES = torch.cuda.is_available() and os.getenv("CACHE_EXAMPLES", "1") == "1" MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "4192")) USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE", "0") == "1" ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD", "0") == "1" PORT = int(os.getenv("DEMO_PORT", "15432")) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # Define color-based attributes color_attributes = { "Purple": {"verbs": ["assist", "befriend", "care", "collaborate", "connect", "embrace", "empower", "encourage", "foster", "give", "help", "nourish", "nurture", "promote", "protect", "provide", "serve", "share", "shepherd", "steward", "tend", "uplift", "value", "welcome"], "adjectives": ["caring", "encouraging", "attentive", "compassionate", "empathetic", "generous", "hospitable", "nurturing", "protective", "selfless", "supportive", "welcoming"]}, "Green": {"verbs": ["analyze", "discover", "examine", "expand", "explore", "extend", "inquire", "journey", "launch", "move", "pioneer", "pursue", "question", "reach", "search", "uncover", "venture", "wonder"], "adjectives": ["adventurous", "curious", "discerning", "examining", "experiential", "exploratory", "inquisitive", "investigative", "intrepid", "philosophical"]}, "Maroon": {"verbs": ["accomplish", "achieve", "build", "challenge", "commit", "compete", "contend", "dedicate", "defend", "devote", "drive", "endeavor", "entrust", "endure", "fight", "grapple", "grow", "improve", "increase", "overcome", "persevere", "persist", "press on", "pursue", "resolve"], "adjectives": ["competitive", "determined", "gritty", "industrious", "persevering", "relentless", "resilient", "tenacious", "tough", "unwavering"]}, "Orange": {"verbs": ["compose", "conceptualize", "conceive", "craft", "create", "design", "dream", "envision", "express", "fashion", "form", "imagine", "interpret", "make", "originate", "paint", "perform", "portray", "realize", "shape"], "adjectives": ["artistic", "conceptual", "creative", "eclectic", "expressive", "imaginative", "interpretive", "novel", "original", "whimsical"]}, "Yellow": {"verbs": ["accelerate", "advance", "change", "conceive", "create", "engineer", "envision", "experiment", "dream", "ignite", "illuminate", "imagine", "innovate", "inspire", "invent", "pioneer", "progress", "shape", "spark", "solve", "transform", "unleash", "unlock"], "adjectives": ["advanced", "analytical", "brilliant", "experimental", "forward-thinking", "innovative", "intelligent", "inventive", "leading-edge", "visionary"]}, "Red": {"verbs": ["animate", "amuse", "captivate", "cheer", "delight", "encourage", "energize", "engage", "enjoy", "enliven", "entertain", "excite", "express", "inspire", "joke", "motivate", "play", "stir", "uplift"], "adjectives": ["dynamic", "energetic", "engaging", "entertaining", "enthusiastic", "exciting", "fun", "lively", "magnetic", "playful", "humorous"]}, "Blue": {"verbs": ["accomplish", "achieve", "affect", "assert", "cause", "command", "determine", "direct", "dominate", "drive", "empower", "establish", "guide", "impact", "impress", "influence", "inspire", "lead", "outpace", "outshine", "realize", "shape", "succeed", "transform", "win"], "adjectives": ["accomplished", "assertive", "confident", "decisive", "elite", "influential", "powerful", "prominent", "proven", "strong"]}, "Pink": {"verbs": ["arise", "aspire", "detail", "dream", "elevate", "enchant", "enrich", "envision", "exceed", "excel", "experience", "improve", "idealize", "imagine", "inspire", "perfect", "poise", "polish", "prepare", "refine", "uplift"], "adjectives": ["aesthetic", "charming", "classic", "dignified", "idealistic", "meticulous", "poised", "polished", "refined", "sophisticated", "elegant"]}, "Silver": {"verbs": ["activate", "campaign", "challenge", "commit", "confront", "dare", "defy", "disrupt", "drive", "excite", "face", "ignite", "incite", "influence", "inspire", "inspirit", "motivate", "move", "push", "rebel", "reimagine", "revolutionize", "rise", "spark", "stir", "fight", "free"], "adjectives": ["bold", "daring", "fearless", "independent", "non-conformist", "radical", "rebellious", "resolute", "unconventional", "valiant"]}, "Beige": {"verbs": ["dedicate", "humble", "collaborate", "empower", "inspire", "empassion", "transform"], "adjectives": ["dedicated", "collaborative", "consistent", "empowering", "enterprising", "humble", "inspiring", "passionate", "proud", "traditional", "transformative"]}, } # Image styles for Gradio interface style_list = [ {"name": "(No style)", "prompt": "{prompt}", "negative_prompt": ""}, {"name": "Cinematic", "prompt": "cinematic still {prompt} . emotional, harmonious, vignette, highly detailed, high budget, bokeh, cinemascope, moody, epic, gorgeous, film grain, grainy", "negative_prompt": "anime, cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured"}, {"name": "Realistic", "prompt": "Photorealistic {prompt} . Ulta-realistic, professional, 4k, highly detailed", "negative_prompt": "drawing, painting, crayon, sketch, graphite, impressionist, noisy, blurry, soft, deformed, ugly, disfigured"}, {"name": "Anime", "prompt": "anime artwork {prompt} . anime style, key visual, vibrant, studio anime, highly detailed", "negative_prompt": "photo, deformed, black and white, realism, disfigured, low contrast"}, {"name": "Digital Art", "prompt": "concept art {prompt} . digital artwork, illustrative, painterly, matte painting, highly detailed", "negative_prompt": "photo, photorealistic, realism, ugly"}, {"name": "Pixel art", "prompt": "pixel-art {prompt} . low-res, blocky, pixel art style, 8-bit graphics", "negative_prompt": "sloppy, messy, blurry, noisy, highly detailed, ultra textured, photo, realistic"}, {"name": "Fantasy art", "prompt": "ethereal fantasy concept art of {prompt} . magnificent, celestial, ethereal, painterly, epic, majestic, magical, fantasy art, cover art, dreamy", "negative_prompt": "photographic, realistic, realism, 35mm film, dslr, cropped, frame, text, deformed, glitch, noise, noisy, off-center, deformed, cross-eyed, closed eyes, bad anatomy, ugly, disfigured, sloppy, duplicate, mutated, black and white"}, {"name": "3D Model", "prompt": "professional 3d model {prompt} . octane render, highly detailed, volumetric, dramatic lighting", "negative_prompt": "ugly, deformed, noisy, low poly, blurry, painting"}, ] # Create dictionary of styles styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list} STYLE_NAMES = list(styles.keys()) DEFAULT_STYLE_NAME = "(No style)" NUM_IMAGES_PER_PROMPT = 1 # Function to apply style and modify prompt based on selected colors def apply_style(style_name: str, positive: str, color_selections: dict) -> Tuple[str, str]: p, n = styles.get(style_name, styles[DEFAULT_STYLE_NAME]) color_prompt = "" # Aggregate verbs and adjectives from selected colors based on their ratios for color, attributes in color_selections.items(): if attributes["selected"]: verbs = random.sample(color_attributes[color]["verbs"], min(3, len(color_attributes[color]["verbs"]))) adjectives = random.sample(color_attributes[color]["adjectives"], min(3, len(color_attributes[color]["adjectives"]))) color_prompt += " ".join(verbs) + " " + " ".join(adjectives) + " " # Form the final prompt final_prompt = p.replace("{prompt}", positive + " " + color_prompt.strip()) return final_prompt, n # Check if CUDA is available and set up the pipeline if torch.cuda.is_available(): pipe = PixArtAlphaPipeline.from_pretrained( "PixArt-alpha/PixArt-LCM-XL-2-1024-MS", torch_dtype=torch.float16, use_safetensors=True, ) if os.getenv('CONSISTENCY_DECODER', False): print("Using DALL-E 3 Consistency Decoder") pipe.vae = ConsistencyDecoderVAE.from_pretrained("openai/consistency-decoder", torch_dtype=torch.float16) if ENABLE_CPU_OFFLOAD: pipe.enable_model_cpu_offload() else: pipe.to(device) print("Loaded on Device!") if USE_TORCH_COMPILE: pipe.transformer = torch.compile(pipe.transformer, mode="reduce-overhead", fullgraph=True) print("Model Compiled!") # Function to save image def save_image(img): unique_name = str(uuid.uuid4()) + ".png" img.save(unique_name) return unique_name # Function to randomize seed if needed def randomize_seed_fn(seed: int, randomize_seed: bool) -> int: if randomize_seed: seed = random.randint(0, MAX_SEED) return seed # Main function to generate images based on user inputs @spaces.GPU(duration=30) def generate( prompt: str, negative_prompt: str = "", style: str = DEFAULT_STYLE_NAME, use_negative_prompt: bool = False, seed: int = 0, width: int = 1024, height: int = 1024, inference_steps: int = 4, randomize_seed: bool = False, use_resolution_binning: bool = True, **kwargs # This will capture all the dynamic inputs like color selections and ratios ): seed = int(randomize_seed_fn(seed, randomize_seed)) generator = torch.Generator().manual_seed(seed) if not use_negative_prompt: negative_prompt = None # Extract color selections and ratios from kwargs color_selections = { color: { "selected": kwargs.get(f"{color.lower()}_selected", False), "ratio": kwargs.get(f"{color.lower()}_ratio", 0) } for color in color_attributes } prompt, negative_prompt = apply_style(style, prompt, color_selections) try: images = pipe( prompt=prompt, negative_prompt=negative_prompt, width=width, height=height, guidance_scale=0, num_inference_steps=inference_steps, generator=generator, num_images_per_prompt=NUM_IMAGES_PER_PROMPT, use_resolution_binning=use_resolution_binning, output_type="pil", ).images except Exception as e: print(f"Error during image generation: {e}") return [], seed image_paths = [save_image(img) for img in images] return image_paths, seed # Example prompts examples = [ "A Monkey with a happy face in the Sahara desert.", "Eiffel Tower was Made up of ICE.", "Color photo of a corgi made of transparent glass, standing on the riverside in Yosemite National Park.", "A close-up photo of a woman. She wore a blue coat with a gray dress underneath and has blue eyes.", "A litter of golden retriever puppies playing in the snow. Their heads pop out of the snow, covered in.", "an astronaut sitting in a diner, eating fries, cinematic, analog film", ] # Initialize dictionaries for dynamic UI components color_checkboxes = {} color_sliders = {} # Set up the Gradio interface # Initialize color checkboxes and sliders before using them color_checkboxes = {color: gr.Checkbox(label=f"{color} Selected", value=False) for color in color_attributes} color_sliders = {color: gr.Slider(label=f"{color} Influence Ratio", minimum=0, maximum=1, step=0.01, value=0) for color in color_attributes} with gr.Blocks() as demo: gr.Markdown(DESCRIPTION) with gr.Row(): prompt = gr.Text(label="Prompt", placeholder="Enter your prompt") run_button = gr.Button("Run") result = gr.Gallery(label="Result", columns=NUM_IMAGES_PER_PROMPT) with gr.Accordion("Color Influences", open=False): for color in color_attributes: with gr.Row(): color_checkboxes[color] color_sliders[color] with gr.Accordion("Advanced options", open=False): with gr.Column(): negative_prompt = gr.Text(label="Negative Prompt", placeholder="Enter a negative prompt") use_negative_prompt = gr.Checkbox(label="Use Negative Prompt", value=False) style_selection = gr.Radio(choices=STYLE_NAMES, label="Style", value=DEFAULT_STYLE_NAME) seed = gr.Number(label="Seed", value=0) width = gr.Number(label="Width", value=1024) height = gr.Number(label="Height", value=1024) inference_steps = gr.Slider(minimum=4, maximum=20, label="Inference Steps", value=4) randomize_seed = gr.Checkbox(label="Randomize Seed", value=True) # Set examples for predefined prompts gr.Examples( examples=examples, inputs=prompt, outputs=[result, seed], fn=generate, cache_examples=CACHE_EXAMPLES, ) use_negative_prompt.change( fn=lambda visible: gr.update(visible=visible), inputs=use_negative_prompt, outputs=negative_prompt, ) # Define the inputs for the generate function using a dictionary for clear mapping generate_inputs = { "prompt": prompt, "negative_prompt": negative_prompt, "style": style_selection, "use_negative_prompt": use_negative_prompt, "seed": seed, "width": width, "height": height, "inference_steps": inference_steps, "randomize_seed": randomize_seed, **{f"{color.lower()}_selected": color_checkboxes[color] for color in color_attributes}, **{f"{color.lower()}_ratio": color_sliders[color] for color in color_attributes} } # Connect the UI with the generate function run_button.click( fn=generate, inputs=generate_inputs, outputs=[result, seed] ) if __name__ == "__main__": demo.launch()