""" FLUX.2 Turbo LoRA Explorer - HuggingFace Space A unique space for exploring LoRA styles with FLUX's fast inference Features: - 8+ Style LoRA Presets (Anime, Realistic, Sketch, Cyberpunk, etc.) - AI-Powered Random Prompt Generator - Image-to-Image generation - Side-by-side comparison mode - LoRA strength control - Full parameter control """ # Monkey-patch to fix Gradio bug: TypeError: argument of type 'bool' is not iterable # and APIInfoParseError: Cannot parse schema True # See: https://github.com/gradio-app/gradio/issues/11084 def _patch_gradio_client(): try: import gradio_client.utils as client_utils # Patch get_type to handle boolean schemas original_get_type = getattr(client_utils, 'get_type', None) if original_get_type: def patched_get_type(schema): if isinstance(schema, bool): return "Any" return original_get_type(schema) client_utils.get_type = patched_get_type # Patch _json_schema_to_python_type to handle boolean schemas original_json_schema = getattr(client_utils, '_json_schema_to_python_type', None) if original_json_schema: def patched_json_schema(schema, defs): if isinstance(schema, bool): return "Any" return original_json_schema(schema, defs) client_utils._json_schema_to_python_type = patched_json_schema except Exception: pass # If patch fails, continue anyway _patch_gradio_client() import gradio as gr import modal import os import random from PIL import Image from io import BytesIO from dotenv import load_dotenv # Load environment variables from .env file (for local development) load_dotenv() # Modal configuration APP_NAME = "flux2-turbo-lora-explorer" # Style LoRA presets with descriptions STYLE_LORAS = { "None (Base Model)": { "id": "none", "description": "Pure FLUX output without any style modification", }, "Anime": { "id": "anime", "description": "Japanese anime style with vibrant colors and clean lines", }, "Realistic": { "id": "realistic", "description": "Photorealistic enhancement for lifelike images", }, "Sketch": { "id": "sketch", "description": "Hand-drawn sketch style with pencil textures", }, "Vintage": { "id": "vintage", "description": "Retro vintage poster aesthetic from the 50s-60s", }, "Cyberpunk": { "id": "cyberpunk", "description": "80s cyberpunk with neon lights and futuristic vibes", }, "Watercolor": { "id": "watercolor", "description": "Soft watercolor painting with flowing colors", }, "Pixel Art": { "id": "pixel", "description": "Retro pixel art style for gaming aesthetics", }, } ASPECT_RATIOS = { "1:1 (1024x1024)": (1024, 1024), "16:9 (1344x768)": (1344, 768), "9:16 (768x1344)": (768, 1344), "4:3 (1152x896)": (1152, 896), "3:2 (1216x832)": (1216, 832), } def generate_ai_prompt(style: str): """Generate a creative prompt - using local fallbacks for now""" # Local prompts (Modal integration disabled temporarily) fallback_prompts = [ "a mystical forest with glowing mushrooms and ethereal mist, magical atmosphere", "an astronaut riding a horse on Mars, cinematic lighting, epic scale", "a cozy coffee shop interior with warm lighting and rain outside the window", "a dragon sleeping on a pile of gold coins in a crystal cave", "a futuristic city skyline at sunset with flying cars and neon signs", "a portrait of a wise old wizard with a long white beard, detailed face", "an underwater palace with mermaids and bioluminescent creatures", "a steampunk airship flying through clouds at golden hour", ] return random.choice(fallback_prompts) def generate_image( prompt: str, style: str, lora_scale: float, aspect_ratio: str, num_steps: int, guidance_scale: float, seed: int, ): """Generate image using Modal backend""" if not prompt.strip(): raise gr.Error("Please enter a prompt") width, height = ASPECT_RATIOS.get(aspect_ratio, (1024, 1024)) lora_id = STYLE_LORAS.get(style, {}).get("id", "none") if seed == -1: seed = random.randint(0, 2**32 - 1) try: Flux2TurboLoRA = modal.Cls.from_name(APP_NAME, "Flux2TurboLoRA") image_bytes = Flux2TurboLoRA().generate.remote( prompt=prompt, lora_id=lora_id, lora_scale=lora_scale, num_steps=num_steps, guidance_scale=guidance_scale, width=width, height=height, seed=seed, ) image = Image.open(BytesIO(image_bytes)) info = f""" **Generation Info:** - Style: {style} - LoRA Scale: {lora_scale} - Steps: {num_steps} - Guidance: {guidance_scale} - Seed: {seed} - Size: {width}x{height} """ return image, info, seed except Exception as e: raise gr.Error(f"Generation failed: {str(e)}") def compare_styles( prompt: str, styles: list[str], aspect_ratio: str, num_steps: int, guidance_scale: float, seed: int, ): """Generate comparison images with different styles""" if not prompt.strip(): raise gr.Error("Please enter a prompt") if len(styles) < 2: raise gr.Error("Please select at least 2 styles to compare") width, height = ASPECT_RATIOS.get(aspect_ratio, (1024, 1024)) if seed == -1: seed = random.randint(0, 2**32 - 1) Flux2TurboLoRA = modal.Cls.from_name(APP_NAME, "Flux2TurboLoRA") model = Flux2TurboLoRA() images = [] for i, style in enumerate(styles): lora_id = STYLE_LORAS.get(style, {}).get("id", "none") try: image_bytes = model.generate.remote( prompt=prompt, lora_id=lora_id, lora_scale=1.0, num_steps=num_steps, guidance_scale=guidance_scale, width=width, height=height, seed=seed, ) img = Image.open(BytesIO(image_bytes)) images.append((img, style)) except Exception as e: images.append((None, f"{style} - Error")) return images def random_seed(): """Generate random seed""" return random.randint(0, 2**32 - 1) # Build Gradio Interface with gr.Blocks( title="FLUX LoRA Explorer", theme=gr.themes.Soft( primary_hue="violet", secondary_hue="slate", ), css=""" .header { text-align: center; margin-bottom: 1.5rem; } .header h1 { font-size: 2.5rem; margin-bottom: 0.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .style-card { border: 2px solid #e0e0e0; border-radius: 12px; padding: 1rem; margin: 0.5rem; transition: all 0.2s; } .style-card:hover { border-color: #667eea; transform: translateY(-2px); } footer { display: none !important; } """ ) as demo: gr.HTML("""
6x faster image generation with 8-step Turbo inference
⥠8-Step Turbo âĸ 8+ Style LoRAs âĸ đ¤ AI Prompts âĸ đŧī¸ Image-to-Image