auto-diffuser-config / gradio_app.py
chansung's picture
Upload folder using huggingface_hub
aae35f1 verified
raw
history blame
63.4 kB
import os
import logging
import gradio as gr
from dotenv import load_dotenv
import google.generativeai as genai
from auto_diffusers import AutoDiffusersGenerator
from simple_memory_calculator import SimpleMemoryCalculator
load_dotenv()
# Configure logging for Gradio app
logger = logging.getLogger(__name__)
class GradioAutodiffusers:
def __init__(self):
logger.info("Initializing GradioAutodiffusers")
self.api_key = os.getenv('GOOGLE_API_KEY')
if not self.api_key:
logger.error("GOOGLE_API_KEY not found in environment variables")
raise ValueError("GOOGLE_API_KEY not found in .env file")
logger.debug(f"API key found, length: {len(self.api_key)}")
try:
self.generator = AutoDiffusersGenerator(self.api_key)
logger.info("AutoDiffusersGenerator initialized successfully")
except Exception as e:
logger.error(f"Failed to initialize AutoDiffusersGenerator: {e}")
raise
try:
self.memory_calculator = SimpleMemoryCalculator()
logger.info("SimpleMemoryCalculator initialized successfully")
except Exception as e:
logger.error(f"Failed to initialize SimpleMemoryCalculator: {e}")
raise
# Default settings
self.current_model = 'gemini-2.5-flash-preview-05-20'
self.temperature = 0.7
self.max_output_tokens = 8192
self.top_p = 0.9
self.top_k = 40
logger.debug(f"Default model settings: {self.current_model}, temp={self.temperature}")
def update_model_settings(self, model_name, temperature, max_output_tokens, top_p, top_k):
"""Update Gemini model settings."""
logger.info(f"Updating model settings: {model_name}")
logger.debug(f"New settings: temp={temperature}, max_tokens={max_output_tokens}, top_p={top_p}, top_k={top_k}")
try:
self.current_model = model_name
self.temperature = temperature
self.max_output_tokens = max_output_tokens
self.top_p = top_p
self.top_k = top_k
# Update the generator's model with new settings
genai.configure(api_key=self.api_key)
generation_config = genai.types.GenerationConfig(
temperature=temperature,
max_output_tokens=max_output_tokens,
top_p=top_p,
top_k=top_k
)
self.generator.model = genai.GenerativeModel(model_name, generation_config=generation_config)
logger.info("Model settings updated successfully")
return f"✅ Model updated to {model_name} with new settings"
except Exception as e:
logger.error(f"Failed to update model settings: {e}")
return f"❌ Failed to update model: {str(e)}"
def get_generation_prompt(self, model_name, prompt_text, image_size, num_inference_steps, hardware_specs, optimization_profile):
"""Get the actual prompt that will be sent to Gemini API."""
return self.generator._create_generation_prompt(
model_name, prompt_text, image_size, num_inference_steps,
hardware_specs, optimization_profile
)
def analyze_model_memory(self, model_name, vram_gb):
"""Analyze model memory requirements and provide recommendations."""
try:
if not vram_gb:
vram_gb = 8 # Default
memory_info = self.memory_calculator.get_model_memory_requirements(model_name)
recommendations = self.memory_calculator.get_memory_recommendation(model_name, float(vram_gb))
formatted_info = self.memory_calculator.format_memory_info(model_name)
return memory_info, recommendations, formatted_info
except Exception as e:
error_msg = f"Error analyzing model memory: {str(e)}"
return {'error': error_msg}, {'error': error_msg}, error_msg
def generate_code_with_manual_specs(self,
gpu_name,
vram_gb,
ram_gb,
platform,
model_name,
prompt_text,
dtype_selection,
width,
height,
inference_steps,
memory_analysis=None):
"""Generate optimized code with manual hardware specifications."""
try:
# Create manual hardware specs
# Parse dtype selection
if dtype_selection == "Auto (Let AI decide)":
user_dtype = None
else:
user_dtype = dtype_selection
manual_specs = {
'platform': platform,
'architecture': 'manual_input',
'cpu_count': 8, # Default
'python_version': '3.11',
'cuda_available': 'nvidia' in gpu_name.lower() if gpu_name else False,
'mps_available': platform == 'Darwin' and 'apple' in gpu_name.lower() if gpu_name else False,
'torch_version': '2.0+',
'manual_input': True,
'ram_gb': int(ram_gb) if ram_gb else 16,
'user_dtype': user_dtype
}
# Add GPU info if provided
if gpu_name and vram_gb:
manual_specs['gpu_info'] = [{
'name': gpu_name,
'memory_mb': int(vram_gb) * 1024
}]
if 'nvidia' in gpu_name.lower():
manual_specs['cuda_available'] = True
manual_specs['cuda_device_count'] = 1
manual_specs['cuda_device_name'] = gpu_name
manual_specs['cuda_memory'] = int(vram_gb)
else:
manual_specs['gpu_info'] = None
# Generate optimized code with manual specs and memory analysis
optimized_code = self.generator.generate_optimized_code(
model_name=model_name,
prompt_text=prompt_text,
image_size=(int(height), int(width)),
num_inference_steps=int(inference_steps),
use_manual_specs=True,
manual_specs=manual_specs,
memory_analysis=memory_analysis
)
# Clean up any markdown formatting
if optimized_code.startswith('```python'):
optimized_code = optimized_code[9:]
if optimized_code.endswith('```'):
optimized_code = optimized_code[:-3]
return optimized_code.strip()
except Exception as e:
return f"Error generating code: {str(e)}"
def create_gradio_interface():
"""Create and configure the Gradio interface."""
app = GradioAutodiffusers()
with gr.Blocks(
title="Auto-Diffusers Code Generator",
theme=gr.themes.Soft(
primary_hue="violet",
secondary_hue="blue",
neutral_hue="slate",
radius_size=gr.themes.sizes.radius_lg,
font=[gr.themes.GoogleFont("Poppins"), gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"]
).set(
background_fill_primary="*neutral_25",
background_fill_secondary="*neutral_50",
block_background_fill="rgba(255, 255, 255, 0.95)",
block_border_width="0px",
block_shadow="0 8px 32px rgba(0, 0, 0, 0.08)",
panel_background_fill="rgba(255, 255, 255, 0.9)",
button_primary_background_fill="*primary_500",
button_primary_background_fill_hover="*primary_600",
button_secondary_background_fill="rgba(255, 255, 255, 0.8)",
button_secondary_background_fill_hover="rgba(255, 255, 255, 0.95)"
),
css="""
/* Global Styles */
.gradio-container {
background: linear-gradient(135deg,
#667eea 0%,
#764ba2 25%,
#f093fb 50%,
#f5576c 75%,
#4facfe 100%) !important;
min-height: 100vh;
}
.main-container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
/* Removed position: relative that can interfere with dropdown positioning */
}
/* Floating Background Elements */
.main-container::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 70%, rgba(124, 58, 237, 0.1) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
}
/* Glass Morphism Effects - Fixed for Dropdown Compatibility */
.glass-card {
background: rgba(255, 255, 255, 0.25) !important;
border: 1px solid rgba(255, 255, 255, 0.2) !important;
border-radius: 20px !important;
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
/* Removed backdrop-filter and transforms that break dropdown positioning */
}
.ultra-glass {
background: rgba(255, 255, 255, 0.15) !important;
border: 1px solid rgba(255, 255, 255, 0.3) !important;
border-radius: 24px !important;
box-shadow:
0 12px 40px rgba(0, 0, 0, 0.15),
inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
/* Removed backdrop-filter that interferes with dropdown positioning */
}
/* Premium Header */
.hero-header {
background: linear-gradient(135deg,
rgba(124, 58, 237, 0.9) 0%,
rgba(236, 72, 153, 0.9) 50%,
rgba(59, 130, 246, 0.9) 100%) !important;
backdrop-filter: blur(20px) !important;
border: 1px solid rgba(255, 255, 255, 0.2) !important;
border-radius: 24px !important;
box-shadow:
0 20px 60px rgba(124, 58, 237, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
position: relative;
overflow: hidden;
}
.hero-header::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.2),
transparent);
animation: shimmer 3s infinite;
}
@keyframes shimmer {
0% { left: -100%; }
50% { left: 100%; }
100% { left: 100%; }
}
/* Premium Buttons */
.generate-btn {
background: linear-gradient(135deg,
#667eea 0%,
#764ba2 50%,
#f093fb 100%) !important;
border: none !important;
color: white !important;
font-weight: 700 !important;
font-size: 1.1rem !important;
padding: 1rem 3rem !important;
border-radius: 16px !important;
box-shadow:
0 8px 32px rgba(102, 126, 234, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important;
position: relative;
overflow: hidden;
}
.generate-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent);
transition: left 0.5s;
}
.generate-btn:hover::before {
left: 100%;
}
.generate-btn:hover {
transform: translateY(-4px) scale(1.02) !important;
box-shadow:
0 16px 48px rgba(102, 126, 234, 0.6),
inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
}
.generate-btn:active {
transform: translateY(-2px) scale(1.01) !important;
}
/* Section Headers */
.section-header {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.9) 0%,
rgba(248, 250, 252, 0.9) 100%) !important;
backdrop-filter: blur(10px) !important;
border: 1px solid rgba(255, 255, 255, 0.4) !important;
border-radius: 16px !important;
padding: 1.5rem !important;
margin-bottom: 1.5rem !important;
box-shadow:
0 4px 20px rgba(0, 0, 0, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.4) !important;
}
/* Premium Inputs - Simplified for Dropdown Compatibility */
input[type="text"],
input[type="number"],
textarea {
background: rgba(255, 255, 255, 0.9) !important;
border: 1px solid rgba(255, 255, 255, 0.3) !important;
border-radius: 12px !important;
padding: 0.75rem 1rem !important;
font-weight: 500 !important;
transition: all 0.3s ease !important;
}
input[type="text"]:focus,
input[type="number"]:focus,
textarea:focus {
background: rgba(255, 255, 255, 0.95) !important;
border-color: rgba(124, 58, 237, 0.5) !important;
box-shadow:
0 0 0 4px rgba(124, 58, 237, 0.1),
0 4px 20px rgba(124, 58, 237, 0.2) !important;
}
/* CRITICAL: Reset all problematic CSS for dropdowns */
label:has(+ [data-testid="dropdown"]),
div:has([data-testid="dropdown"]),
[data-testid="dropdown"],
[data-testid="dropdown"] *,
.gradio-dropdown,
.gradio-dropdown * {
position: static !important;
transform: none !important;
backdrop-filter: none !important;
filter: none !important;
}
/* AGGRESSIVE FIX: Override ALL possible transparency sources */
* {
--dropdown-bg: #ffffff !important;
--dropdown-opacity: 1 !important;
}
/* Target every possible dropdown element with maximum specificity */
.gradio-container [data-testid="dropdown"] div[role="listbox"],
.gradio-container .gradio-dropdown .dropdown-content,
.gradio-container .dropdown-menu,
.gradio-container div[role="listbox"],
.gradio-container .svelte-1gfkn6j,
body [data-testid="dropdown"] div[role="listbox"],
body .dropdown-menu,
body div[role="listbox"],
html [data-testid="dropdown"] div[role="listbox"] {
background: #ffffff !important;
background-color: #ffffff !important;
opacity: 1 !important;
position: absolute !important;
z-index: 99999 !important;
border: 2px solid #d1d5db !important;
border-radius: 8px !important;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25) !important;
max-height: 200px !important;
overflow-y: auto !important;
backdrop-filter: none !important;
filter: none !important;
background-image: none !important;
background-blend-mode: normal !important;
/* Force solid with CSS variables */
background: var(--dropdown-bg, #ffffff) !important;
opacity: var(--dropdown-opacity, 1) !important;
}
/* Aggressive option styling */
.gradio-container [data-testid="dropdown"] div[role="listbox"] > *,
.gradio-container .dropdown-menu > *,
.gradio-container div[role="listbox"] > *,
body [data-testid="dropdown"] div[role="listbox"] > *,
body .dropdown-menu > *,
body div[role="listbox"] > * {
background: #ffffff !important;
background-color: #ffffff !important;
padding: 0.75rem 1rem !important;
color: #1f2937 !important;
cursor: pointer !important;
opacity: 1 !important;
border: none !important;
margin: 0 !important;
display: block !important;
width: 100% !important;
text-align: left !important;
}
/* Ensure dropdown menus appear correctly with SOLID background */
[data-testid="dropdown"] div[role="listbox"],
.gradio-dropdown .dropdown-content,
.dropdown-menu,
div[role="listbox"],
.svelte-1gfkn6j,
.gradio-container div[role="listbox"] {
position: absolute !important;
z-index: 9999 !important;
background: #ffffff !important;
background-color: #ffffff !important;
opacity: 1 !important;
border: 1px solid #d1d5db !important;
border-radius: 8px !important;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15) !important;
max-height: 200px !important;
overflow-y: auto !important;
backdrop-filter: none !important;
/* Force solid background */
background-image: none !important;
background-blend-mode: normal !important;
}
/* Dropdown option styling - SOLID background for each option */
[data-testid="dropdown"] div[role="listbox"] > *,
.dropdown-menu > *,
div[role="listbox"] > *,
.svelte-1gfkn6j > * {
background: #ffffff !important;
background-color: #ffffff !important;
padding: 0.5rem 0.75rem !important;
color: #374151 !important;
cursor: pointer !important;
transition: background-color 0.2s ease !important;
opacity: 1 !important;
}
/* Dropdown option hover effect */
[data-testid="dropdown"] div[role="listbox"] > *:hover,
.dropdown-menu > *:hover,
div[role="listbox"] > *:hover {
background: #f3f4f6 !important;
color: #1f2937 !important;
}
/* Dropdown option selected state */
[data-testid="dropdown"] div[role="listbox"] > *[aria-selected="true"],
.dropdown-menu > *.selected,
div[role="listbox"] > *[aria-selected="true"] {
background: #e0e7ff !important;
color: #3730a3 !important;
}
/* Code Areas - Ultra Premium Styling */
.code-container {
background: linear-gradient(145deg,
rgba(15, 23, 42, 0.98) 0%,
rgba(30, 41, 59, 0.95) 50%,
rgba(15, 23, 42, 0.98) 100%) !important;
backdrop-filter: blur(30px) !important;
border: 2px solid transparent !important;
background-clip: padding-box !important;
border-radius: 20px !important;
position: relative !important;
overflow: hidden !important;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.4),
0 8px 32px rgba(15, 23, 42, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1),
inset 0 -1px 0 rgba(71, 85, 105, 0.2) !important;
}
.code-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg,
rgba(99, 102, 241, 0.1) 0%,
rgba(139, 92, 246, 0.1) 25%,
rgba(59, 130, 246, 0.1) 50%,
rgba(139, 92, 246, 0.1) 75%,
rgba(99, 102, 241, 0.1) 100%) !important;
border-radius: 20px !important;
z-index: -1 !important;
animation: code-shimmer 3s ease-in-out infinite !important;
}
@keyframes code-shimmer {
0%, 100% { opacity: 0.3; }
50% { opacity: 0.6; }
}
/* Code editor styling */
.code-container .cm-editor {
background: transparent !important;
border-radius: 16px !important;
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Fira Code', monospace !important;
font-size: 13px !important;
line-height: 1.6 !important;
}
.code-container .cm-focused {
outline: none !important;
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.4) !important;
}
.code-container .cm-content {
padding: 1.5rem !important;
color: #e2e8f0 !important;
}
.code-container .cm-line {
padding-left: 0.5rem !important;
}
/* Syntax highlighting for Python */
.code-container .cm-keyword { color: #f472b6 !important; }
.code-container .cm-string { color: #34d399 !important; }
.code-container .cm-comment { color: #94a3b8 !important; font-style: italic !important; }
.code-container .cm-number { color: #fbbf24 !important; }
.code-container .cm-variable { color: #60a5fa !important; }
.code-container .cm-function { color: #a78bfa !important; }
.code-container .cm-operator { color: #fb7185 !important; }
/* Code header styling */
.code-container label {
background: linear-gradient(90deg,
rgba(99, 102, 241, 0.9) 0%,
rgba(139, 92, 246, 0.9) 50%,
rgba(59, 130, 246, 0.9) 100%) !important;
color: white !important;
padding: 1rem 1.5rem !important;
border-radius: 16px 16px 0 0 !important;
font-weight: 600 !important;
font-size: 1rem !important;
letter-spacing: 0.025em !important;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) !important;
margin: 0 !important;
border: none !important;
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.2) !important;
}
/* Custom scrollbar for code area */
.code-container .cm-scroller::-webkit-scrollbar {
width: 8px !important;
height: 8px !important;
}
.code-container .cm-scroller::-webkit-scrollbar-track {
background: rgba(15, 23, 42, 0.3) !important;
border-radius: 4px !important;
}
.code-container .cm-scroller::-webkit-scrollbar-thumb {
background: linear-gradient(135deg,
rgba(99, 102, 241, 0.6) 0%,
rgba(139, 92, 246, 0.6) 100%) !important;
border-radius: 4px !important;
border: 1px solid rgba(255, 255, 255, 0.1) !important;
}
.code-container .cm-scroller::-webkit-scrollbar-thumb:hover {
background: linear-gradient(135deg,
rgba(99, 102, 241, 0.8) 0%,
rgba(139, 92, 246, 0.8) 100%) !important;
}
/* Line numbers styling */
.code-container .cm-lineNumbers {
background: rgba(15, 23, 42, 0.3) !important;
color: rgba(148, 163, 184, 0.6) !important;
border-right: 1px solid rgba(71, 85, 105, 0.3) !important;
padding-right: 0.5rem !important;
}
.code-container .cm-lineNumbers .cm-gutterElement {
color: rgba(148, 163, 184, 0.5) !important;
font-weight: 500 !important;
}
/* Memory Analysis Cards */
.memory-card {
background: linear-gradient(135deg,
rgba(251, 191, 36, 0.1) 0%,
rgba(245, 158, 11, 0.1) 100%) !important;
backdrop-filter: blur(15px) !important;
border: 1px solid rgba(251, 191, 36, 0.2) !important;
border-radius: 16px !important;
padding: 1.5rem !important;
box-shadow:
0 8px 32px rgba(245, 158, 11, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
}
/* Labels with icons */
label {
font-weight: 600 !important;
color: rgba(30, 41, 59, 0.9) !important;
font-size: 0.95rem !important;
}
/* Floating Animation */
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
.floating {
animation: float 6s ease-in-out infinite;
}
/* Pulse Effect */
@keyframes pulse-glow {
0%, 100% {
box-shadow:
0 8px 32px rgba(102, 126, 234, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
50% {
box-shadow:
0 12px 48px rgba(102, 126, 234, 0.6),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
}
.pulse-glow {
animation: pulse-glow 3s ease-in-out infinite;
}
/* FINAL OVERRIDE: Nuclear option for dropdown transparency */
[role="listbox"] {
background: white !important;
opacity: 1 !important;
}
[role="listbox"] > * {
background: white !important;
opacity: 1 !important;
}
/* Gradio-specific nuclear option */
.gradio-app [role="listbox"],
.gradio-app [role="listbox"] > * {
background: #ffffff !important;
background-color: #ffffff !important;
opacity: 1 !important;
}
/* Last resort: override all possible transparent backgrounds */
div[style*="background"] {
background: unset !important;
}
[role="listbox"][style*="background"] {
background: #ffffff !important;
}
/* Mobile Responsive Styles */
@media (max-width: 768px) {
.main-container {
margin: 0 1px !important;
padding: 1rem !important;
max-width: calc(100% - 2px) !important;
}
.gradio-container {
margin: 0 1px !important;
padding: 0 !important;
}
/* Set left/right margins to 1px for mobile */
.gradio-container > * {
margin-left: 1px !important;
margin-right: 1px !important;
}
/* Adjust hero header for mobile */
.hero-header {
padding: 2rem 1rem !important;
margin-bottom: 2rem !important;
}
.hero-header h1 {
font-size: 2.5rem !important;
}
.hero-header h2 {
font-size: 1.4rem !important;
}
/* Mobile-friendly glass panels */
.glass-panel {
margin: 0.5rem 0 !important;
padding: 1rem !important;
border-radius: 12px !important;
}
/* Responsive button sizing */
.primary-button {
padding: 0.8rem 2rem !important;
font-size: 1rem !important;
}
/* Mobile code container */
.code-container {
margin: 0 !important;
border-radius: 8px !important;
}
/* Stack columns on mobile */
.gradio-row {
flex-direction: column !important;
}
}
/* Small mobile devices */
@media (max-width: 480px) {
.main-container {
margin: 0 1px !important;
padding: 0.5rem !important;
}
.hero-header {
padding: 1.5rem 0.5rem !important;
}
.hero-header h1 {
font-size: 2rem !important;
}
.hero-header h2 {
font-size: 1.2rem !important;
}
.glass-panel {
padding: 0.8rem !important;
margin: 0.25rem 0 !important;
}
}
"""
) as interface:
with gr.Column(elem_classes="main-container"):
# Ultra Premium Header
with gr.Row():
with gr.Column(scale=1):
gr.HTML("""
<div class="hero-header floating" style="text-align: center; padding: 3rem 2rem; margin-bottom: 3rem; position: relative;">
<div style="position: relative; z-index: 2;">
<h1 style="color: white; font-size: 3.5rem; margin: 0; font-weight: 800; text-shadow: 0 4px 8px rgba(0,0,0,0.3); letter-spacing: -0.02em; background: linear-gradient(135deg, #ffffff 0%, #f8fafc 50%, #e2e8f0 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">
✨ Auto-Diffusers
</h1>
<h2 style="color: rgba(255,255,255,0.95); font-size: 1.8rem; margin: 0.5rem 0 1rem 0; font-weight: 600; text-shadow: 0 2px 4px rgba(0,0,0,0.2);">
Code Generator
</h2>
<p style="color: rgba(255,255,255,0.9); font-size: 1.2rem; margin: 0; font-weight: 400; text-shadow: 0 2px 4px rgba(0,0,0,0.2); max-width: 600px; margin: 0 auto; line-height: 1.6;">
Generate stunning, optimized diffusers code tailored perfectly for your hardware using advanced AI
</p>
<div style="margin-top: 2rem;">
<span style="display: inline-block; background: rgba(255,255,255,0.2); padding: 0.5rem 1rem; border-radius: 20px; color: white; font-size: 0.9rem; backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.3);">
🤖 Powered by Google Gemini 2.5
</span>
</div>
</div>
</div>
""")
# Main Content Area
# Hardware Selection Section
with gr.Group(elem_classes="glass-card"):
gr.HTML("""
<div class="section-header" style="text-align: center;">
<h3 style="margin: 0 0 0.5rem 0; color: #1e293b; font-size: 1.5rem; font-weight: 700;">
⚙️ Hardware Specifications
</h3>
<p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
Configure your system hardware for optimal code generation
</p>
</div>
""")
with gr.Row():
with gr.Column(scale=1):
platform = gr.Dropdown(
choices=["Linux", "Darwin", "Windows"],
label="🖥️ Platform",
value="Linux",
info="Your operating system"
)
gpu_vendor = gr.Dropdown(
choices=[
"Custom (Manual Input)",
"NVIDIA Consumer (GeForce RTX)",
"NVIDIA Professional (RTX A-Series)",
"NVIDIA Data Center",
"Apple Silicon",
"AMD",
"Intel",
"CPU Only"
],
label="🎮 GPU Vendor/Category",
value="Custom (Manual Input)",
info="Select your GPU category"
)
gpu_series = gr.Dropdown(
choices=[],
label="📊 GPU Series",
visible=False,
interactive=True,
info="Choose your GPU series"
)
gpu_model = gr.Dropdown(
choices=[],
label="🔧 GPU Model",
visible=False,
interactive=True,
info="Select your specific GPU model"
)
gpu_name_custom = gr.Textbox(
label="💾 Custom GPU Name",
placeholder="e.g., RTX 4090, GTX 1080 Ti",
visible=True,
info="Enter your GPU name manually"
)
gpu_name = gr.Textbox(
label="Selected GPU",
visible=False
)
with gr.Column(scale=1):
vram_gb = gr.Number(
label="🎯 VRAM/Memory (GB)",
value=8,
minimum=0,
maximum=200,
info="GPU memory available"
)
ram_gb = gr.Number(
label="💻 System RAM (GB)",
value=16,
minimum=4,
maximum=256,
info="Total system memory"
)
# Model Configuration Section
with gr.Group(elem_classes="glass-card"):
gr.HTML("""
<div class="section-header" style="text-align: center;">
<h3 style="margin: 0 0 0.5rem 0; color: #1e293b; font-size: 1.5rem; font-weight: 700;">
🤖 Model Configuration
</h3>
<p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
Configure the AI model and generation parameters
</p>
</div>
""")
with gr.Row():
with gr.Column(scale=1):
model_name = gr.Textbox(
label="🏷️ Model Name",
value="black-forest-labs/FLUX.1-schnell",
placeholder="e.g., black-forest-labs/FLUX.1-schnell",
info="HuggingFace model identifier"
)
dtype_selection = gr.Dropdown(
choices=["Auto (Let AI decide)", "torch.float32", "torch.float16", "torch.bfloat16"],
label="⚡ Data Type (dtype)",
value="Auto (Let AI decide)",
info="Precision mode - Auto is recommended"
)
with gr.Column(scale=1):
with gr.Row():
width = gr.Number(
label="📏 Width (px)",
value=1360,
minimum=256,
maximum=2048,
step=64,
info="Image width"
)
height = gr.Number(
label="📐 Height (px)",
value=768,
minimum=256,
maximum=2048,
step=64,
info="Image height"
)
inference_steps = gr.Number(
label="🔄 Inference Steps",
value=4,
minimum=1,
maximum=50,
info="Number of denoising steps (higher = better quality, slower)"
)
# Memory Analysis Section
with gr.Group(elem_classes="ultra-glass"):
gr.HTML("""
<div class="section-header" style="text-align: center;">
<h3 style="margin: 0 0 0.5rem 0; color: #1e293b; font-size: 1.5rem; font-weight: 700;">
🧠 Memory Analysis
</h3>
<p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
Real-time analysis of model memory requirements and optimization strategies
</p>
</div>
""")
memory_analysis_output = gr.Markdown(
value="✨ Select a model and configure your hardware to see memory requirements and optimization recommendations.",
elem_classes="memory-card"
)
# Generate Button
with gr.Row():
with gr.Column():
gr.HTML("""
<div style="text-align: center; margin: 2rem 0;">
</div>
""")
generate_btn = gr.Button(
"✨ Generate Optimized Code",
variant="primary",
size="lg",
elem_classes="generate-btn pulse-glow"
)
# Generated Code Section
with gr.Group(elem_classes="ultra-glass"):
gr.HTML("""
<div class="section-header" style="text-align: center; position: relative; overflow: hidden;">
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(45deg, rgba(99, 102, 241, 0.1), rgba(139, 92, 246, 0.1)); border-radius: 16px; z-index: -1;"></div>
<h3 style="margin: 0 0 0.5rem 0; color: #1e293b; font-size: 1.5rem; font-weight: 700; text-shadow: 0 2px 4px rgba(0,0,0,0.1);">
💻 Generated Code
</h3>
<p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
✨ Ultra-optimized Python code with hardware-specific acceleration
</p>
<div style="margin-top: 1rem; padding: 0.75rem 1.5rem; background: linear-gradient(90deg, rgba(34, 197, 94, 0.1), rgba(59, 130, 246, 0.1)); border-radius: 12px; border: 1px solid rgba(34, 197, 94, 0.2);">
<span style="color: #059669; font-weight: 600; font-size: 0.9rem;">
🚀 Ready-to-run • Memory optimized • Performance tuned
</span>
</div>
</div>
""")
# Code Summary
code_summary = gr.Markdown(
value="🎯 Generated code summary will appear here after generation.",
elem_classes="memory-card"
)
# Code Output
code_output = gr.Code(
label="🚀 Hardware-Optimized Diffusion Pipeline",
language="python",
lines=20,
interactive=True,
show_label=True,
elem_classes="code-container",
value="# 🎨 Your optimized diffusion code will appear here after generation\n# Click 'Generate Optimized Code' to create hardware-specific Python code\n\nprint('✨ Ready to generate amazing AI art with optimized performance!')"
)
def on_gpu_vendor_change(vendor):
"""Handle GPU vendor selection and update series dropdown."""
if vendor == "Custom (Manual Input)":
return (gr.update(visible=True),
gr.update(visible=False, choices=[]),
gr.update(visible=False, choices=[]),
"", gr.update())
elif vendor == "CPU Only":
return (gr.update(visible=False),
gr.update(visible=False, choices=[]),
gr.update(visible=False, choices=[]),
"", 0)
elif vendor == "NVIDIA Consumer (GeForce RTX)":
return (gr.update(visible=False),
gr.update(visible=True, choices=["RTX 50 Series", "RTX 40 Series", "RTX 30 Series"]),
gr.update(visible=False, choices=[]),
"", gr.update())
elif vendor == "NVIDIA Professional (RTX A-Series)":
return (gr.update(visible=False),
gr.update(visible=True, choices=["RTX A6000 Series", "RTX A5000 Series", "RTX A4000 Series"]),
gr.update(visible=False, choices=[]),
"", gr.update())
elif vendor == "NVIDIA Data Center":
return (gr.update(visible=False),
gr.update(visible=True, choices=["Blackwell (B-Series)", "Hopper (H-Series)", "Ada Lovelace (L-Series)", "Ampere (A-Series)", "Volta/Tesla"]),
gr.update(visible=False, choices=[]),
"", gr.update())
elif vendor == "Apple Silicon":
return (gr.update(visible=False),
gr.update(visible=True, choices=["M4 Series", "M3 Series", "M2 Series", "M1 Series"]),
gr.update(visible=False, choices=[]),
"", gr.update())
elif vendor == "AMD":
return (gr.update(visible=False),
gr.update(visible=True, choices=["Radeon RX 7000", "Radeon RX 6000", "Instinct MI Series"]),
gr.update(visible=False, choices=[]),
"", gr.update())
elif vendor == "Intel":
return (gr.update(visible=False),
gr.update(visible=True, choices=["Arc A-Series"]),
gr.update(visible=False, choices=[]),
"", gr.update())
else:
return (gr.update(visible=True),
gr.update(visible=False, choices=[]),
gr.update(visible=False, choices=[]),
"", gr.update())
def on_gpu_series_change(vendor, series):
"""Handle GPU series selection and update model dropdown."""
models = []
if vendor == "NVIDIA Consumer (GeForce RTX)":
if series == "RTX 50 Series":
models = ["RTX 5090 (32GB)", "RTX 5080 (16GB)", "RTX 5070 Ti (16GB)", "RTX 5070 (12GB)", "RTX 5060 Ti (16GB)", "RTX 5060 (12GB)"]
elif series == "RTX 40 Series":
models = ["RTX 4090 (24GB)", "RTX 4080 Super (16GB)", "RTX 4070 Ti Super (16GB)", "RTX 4070 Super (12GB)", "RTX 4070 (12GB)", "RTX 4060 Ti (16GB)", "RTX 4060 Ti (8GB)", "RTX 4060 (8GB)"]
elif series == "RTX 30 Series":
models = ["RTX 3090 Ti (24GB)", "RTX 3090 (24GB)", "RTX 3080 Ti (12GB)", "RTX 3080 (12GB)", "RTX 3080 (10GB)", "RTX 3070 Ti (8GB)", "RTX 3070 (8GB)", "RTX 3060 Ti (8GB)", "RTX 3060 (12GB)"]
elif vendor == "NVIDIA Professional (RTX A-Series)":
if series == "RTX A6000 Series":
models = ["RTX A6000 (48GB)", "RTX A6000 Ada (48GB)", "RTX 6000 Ada (48GB)"]
elif series == "RTX A5000 Series":
models = ["RTX A5000 (24GB)", "RTX A5500 (24GB)", "RTX 5000 Ada (32GB)"]
elif series == "RTX A4000 Series":
models = ["RTX A4000 (16GB)", "RTX A4500 (20GB)", "RTX 4000 Ada (20GB)", "RTX 4000 SFF Ada (20GB)"]
elif vendor == "NVIDIA Data Center":
if series == "Blackwell (B-Series)":
models = ["B200 (192GB)", "B100 (192GB)", "GB200 NVL72 (192GB per GPU)"]
elif series == "Hopper (H-Series)":
models = ["H200 (141GB)", "H100 SXM (80GB)", "H100 PCIe (80GB)"]
elif series == "Ada Lovelace (L-Series)":
models = ["L40S (48GB)", "L40 (48GB)", "L4 (24GB)"]
elif series == "Ampere (A-Series)":
models = ["A100 SXM (80GB)", "A100 PCIe (80GB)", "A100 PCIe (40GB)", "A40 (48GB)", "A30 (24GB)", "A16 (16GB)", "A10 (24GB)"]
elif series == "Volta/Tesla":
models = ["V100 SXM2 (32GB)", "V100 PCIe (16GB)", "P100 (16GB)"]
elif vendor == "Apple Silicon":
if series == "M4 Series":
models = ["M4 Max (128GB Unified)", "M4 Pro (64GB Unified)", "M4 (32GB Unified)"]
elif series == "M3 Series":
models = ["M3 Ultra (192GB Unified)", "M3 Max (128GB Unified)", "M3 Pro (36GB Unified)", "M3 (24GB Unified)"]
elif series == "M2 Series":
models = ["M2 Ultra (192GB Unified)", "M2 Max (96GB Unified)", "M2 Pro (32GB Unified)", "M2 (24GB Unified)"]
elif series == "M1 Series":
models = ["M1 Ultra (128GB Unified)", "M1 Max (64GB Unified)", "M1 Pro (32GB Unified)", "M1 (16GB Unified)"]
elif vendor == "AMD":
if series == "Radeon RX 7000":
models = ["RX 7900 XTX (24GB)", "RX 7900 XT (20GB)"]
elif series == "Radeon RX 6000":
models = ["RX 6900 XT (16GB)"]
elif series == "Instinct MI Series":
models = ["Instinct MI300X (192GB)", "Instinct MI250X (128GB)", "Instinct MI100 (32GB)"]
elif vendor == "Intel":
if series == "Arc A-Series":
models = ["Arc A770 (16GB)", "Arc A750 (8GB)"]
return gr.update(visible=True, choices=models)
def on_gpu_model_change(model):
"""Handle GPU model selection and auto-fill values."""
if not model or model == "":
return "", gr.update()
# Extract GPU name and VRAM from model
if "(" in model and "GB" in model:
gpu_name_part = model.split(" (")[0]
vram_part = model.split("(")[1].split("GB")[0]
try:
vram_value = int(vram_part)
except:
vram_value = 8
return gpu_name_part, vram_value
else:
return model, gr.update()
def get_final_gpu_name(vendor, series, model, custom_name):
"""Get the final GPU name based on vendor selection or custom input."""
if vendor == "Custom (Manual Input)":
return custom_name
elif vendor == "CPU Only":
return ""
elif model and "(" in model and "GB" in model:
return model.split(" (")[0]
elif model:
return model
else:
return custom_name
def update_memory_analysis(model_name, vram_gb):
"""Update memory analysis in real-time based on selections."""
if not model_name or not model_name.strip():
return "Select a model to see memory requirements."
if not vram_gb or vram_gb <= 0:
return f"**Model:** {model_name}\n\nConfigure your GPU to see memory analysis."
try:
memory_info, recommendations, formatted_info = app.analyze_model_memory(model_name, vram_gb)
return formatted_info
except Exception as e:
# Enhanced error reporting with full traceback
import traceback
error_details = traceback.format_exc()
print(f"Memory analysis error for {model_name}: {error_details}")
# More specific error messages
error_msg = str(e)
if "Too many arguments" in error_msg:
detailed_error = f"❌ **HuggingFace API Error**\n\nModel: `{model_name}`\n\n**Issue:** The model repository might not exist or is private.\n\n**Details:** {error_msg}\n\n**Suggestion:** Check the model name spelling and ensure it's a public model on HuggingFace."
elif "404" in error_msg or "not found" in error_msg.lower():
detailed_error = f"❌ **Model Not Found**\n\nModel: `{model_name}`\n\n**Issue:** This model doesn't exist on HuggingFace.\n\n**Suggestion:** Verify the model name is correct (e.g., 'black-forest-labs/FLUX.1-schnell')."
elif "403" in error_msg or "private" in error_msg.lower():
detailed_error = f"❌ **Access Denied**\n\nModel: `{model_name}`\n\n**Issue:** This model is private or requires authentication.\n\n**Suggestion:** Use a public model or check access permissions."
elif "timeout" in error_msg.lower():
detailed_error = f"❌ **Timeout Error**\n\nModel: `{model_name}`\n\n**Issue:** HuggingFace API is slow or unresponsive.\n\n**Suggestion:** Try again in a moment."
else:
detailed_error = f"❌ **Memory Analysis Error**\n\nModel: `{model_name}`\n\n**Error Type:** {type(e).__name__}\n\n**Details:** {error_msg}\n\n**Full Error:**\n```\n{error_details}\n```"
return detailed_error
# Connect GPU dropdown change handlers with memory analysis updates
gpu_vendor.change(
on_gpu_vendor_change,
inputs=[gpu_vendor],
outputs=[gpu_name_custom, gpu_series, gpu_model, gpu_name, vram_gb]
).then(
update_memory_analysis,
inputs=[model_name, vram_gb],
outputs=memory_analysis_output
)
gpu_series.change(
on_gpu_series_change,
inputs=[gpu_vendor, gpu_series],
outputs=[gpu_model]
)
gpu_model.change(
on_gpu_model_change,
inputs=[gpu_model],
outputs=[gpu_name, vram_gb]
).then(
update_memory_analysis,
inputs=[model_name, vram_gb],
outputs=memory_analysis_output
)
# Update memory analysis when custom GPU name changes
gpu_name_custom.change(
update_memory_analysis,
inputs=[model_name, vram_gb],
outputs=memory_analysis_output
)
# Update memory analysis when model name or VRAM changes
model_name.change(
update_memory_analysis,
inputs=[model_name, vram_gb],
outputs=memory_analysis_output
)
vram_gb.change(
update_memory_analysis,
inputs=[model_name, vram_gb],
outputs=memory_analysis_output
)
# Load initial memory analysis on startup
interface.load(
update_memory_analysis,
inputs=[model_name, vram_gb],
outputs=memory_analysis_output
)
def create_code_summary(generated_code, model_name, final_gpu_name, vram_gb):
"""Create a concise summary of the generated code."""
if generated_code.startswith("Error"):
return "❌ **Code Generation Failed** - See error details in the code output below."
# Analyze the generated code to extract key optimizations
optimizations = []
if "torch.float16" in generated_code or "fp16" in generated_code.lower():
optimizations.append("FP16 precision")
if "torch.bfloat16" in generated_code or "bf16" in generated_code.lower():
optimizations.append("BF16 precision")
if "enable_model_cpu_offload" in generated_code:
optimizations.append("CPU offloading")
if "enable_sequential_cpu_offload" in generated_code:
optimizations.append("Sequential CPU offload")
if "low_cpu_mem_usage=True" in generated_code:
optimizations.append("Low CPU memory usage")
if "torch.compile" in generated_code:
optimizations.append("Torch compile")
if "attention_slicing" in generated_code:
optimizations.append("Attention slicing")
if "vae_slicing" in generated_code:
optimizations.append("VAE slicing")
device = "CUDA" if "cuda" in generated_code else "MPS" if "mps" in generated_code else "CPU"
summary = f"""
### ✅ Code Generated Successfully
**Model:** `{model_name}`
**Hardware:** {final_gpu_name} ({vram_gb}GB) - {device}
**Optimizations:** {', '.join(optimizations) if optimizations else 'Standard configuration'}
**Key Features:**
- Memory-optimized pipeline loading
- Hardware-specific device configuration
- Performance tuning for your GPU
- Ready-to-run diffusion code
"""
return summary
def strip_comments(code):
"""Remove all comments from the code for collapsed view."""
if not code:
return code
lines = code.split('\n')
filtered_lines = []
for line in lines:
stripped = line.strip()
# Skip comment-only lines and empty lines
if stripped.startswith('#') or stripped == '':
continue
# For lines with inline comments, keep only the code part
if '#' in line and not stripped.startswith('#'):
code_part = line.split('#')[0].rstrip()
if code_part.strip(): # Only add if there's actual code
filtered_lines.append(code_part)
else:
filtered_lines.append(line)
return '\n'.join(filtered_lines)
def generate_with_combined_gpu_name(gpu_vendor, gpu_series, gpu_model, gpu_name_custom, vram_gb, ram_gb, platform, model_name, dtype_selection, width, height, inference_steps):
"""Generate code with the correct GPU name from multi-level selection or custom input, including memory analysis."""
final_gpu_name = get_final_gpu_name(gpu_vendor, gpu_series, gpu_model, gpu_name_custom)
# Constant prompt text
prompt_text = "A cat holding a sign that says hello world"
# STEP 1: Perform memory analysis BEFORE code generation
memory_analysis_data = None
memory_header = ""
try:
if model_name and vram_gb and vram_gb > 0:
memory_info, recommendations, _ = app.analyze_model_memory(model_name, vram_gb)
# Package memory analysis for Gemini API
memory_analysis_data = {
'memory_info': memory_info,
'recommendations': recommendations
}
# Create header for the generated code
def get_optimization_strategy(recommendations):
"""Generate optimization strategy text based on recommendations."""
strategies = []
if recommendations.get('cpu_offload'):
strategies.append("CPU offloading")
if recommendations.get('sequential_offload'):
strategies.append("Sequential CPU offload")
if recommendations.get('attention_slicing'):
strategies.append("Attention slicing")
if recommendations.get('vae_slicing'):
strategies.append("VAE slicing")
precision = recommendations.get('recommended_precision', 'float16')
if precision:
strategies.append(f"{precision} precision")
if not strategies:
# No special optimizations needed
if recommendations.get('recommendations') and any('Full model can fit' in rec for rec in recommendations.get('recommendations', [])):
return "Full VRAM utilization with optimal performance"
else:
return "Standard optimization"
return ", ".join(strategies)
optimization_strategy = get_optimization_strategy(recommendations)
memory_header = f"""# Memory Analysis for {model_name}:
# GPU: {final_gpu_name if final_gpu_name else 'Not specified'} ({vram_gb}GB VRAM)
# Model Memory Requirements: {memory_info.get('estimated_inference_memory_fp16_gb', 'Unknown')} GB
# Recommendation: {', '.join(recommendations.get('recommendations', ['N/A']))}
# Optimization Strategy: {optimization_strategy}
"""
except Exception as e:
memory_header = f"""# Memory Analysis for {model_name}:
# GPU: {final_gpu_name if final_gpu_name else 'Not specified'} ({vram_gb}GB VRAM)
# Note: Memory analysis failed - {str(e)}
"""
# STEP 2: Generate the optimized code WITH memory analysis information
generated_code = app.generate_code_with_manual_specs(
final_gpu_name, vram_gb, ram_gb, platform,
model_name, prompt_text, dtype_selection, width, height, inference_steps,
memory_analysis_data
)
# STEP 3: Prepend memory analysis header to the generated code
final_code = memory_header + generated_code if memory_header and not generated_code.startswith("Error") else generated_code
# STEP 4: Create code summary
summary = create_code_summary(generated_code, model_name, final_gpu_name, vram_gb)
return summary, final_code
# Add states for tracking code view and storing full code
code_collapsed = gr.State(value=False)
full_code_storage = gr.State(value="")
def generate_and_store_code(gpu_vendor, gpu_series, gpu_model, gpu_name_custom, vram_gb, ram_gb, platform, model_name, dtype_selection, width, height, inference_steps):
"""Generate code and return summary, code for display, and full code for storage."""
summary, full_code = generate_with_combined_gpu_name(
gpu_vendor, gpu_series, gpu_model, gpu_name_custom, vram_gb, ram_gb, platform,
model_name, dtype_selection, width, height, inference_steps
)
return summary, full_code, full_code, False # summary, display_code, stored_code, reset_collapsed_state
generate_btn.click(
generate_and_store_code,
inputs=[
gpu_vendor, gpu_series, gpu_model, gpu_name_custom, vram_gb, ram_gb, platform,
model_name, dtype_selection, width, height, inference_steps
],
outputs=[code_summary, code_output, full_code_storage, code_collapsed]
)
# Ultra Premium Footer
gr.HTML("""
<div class="ultra-glass" style="text-align: center; padding: 3rem 2rem; margin-top: 4rem; position: relative; overflow: hidden;">
<div style="position: relative; z-index: 2;">
<h4 style="color: #1e293b; font-size: 1.3rem; margin: 0 0 1rem 0; font-weight: 700;">
✨ Pro Tips & Insights
</h4>
<p style="color: #475569; font-size: 1rem; margin: 0 0 1.5rem 0; font-weight: 500; line-height: 1.6; max-width: 600px; margin: 0 auto;">
🚀 The generated code includes hardware-specific optimizations for memory efficiency and peak performance<br>
🎯 Fine-tuned for your exact GPU configuration and model requirements
</p>
<div style="margin-top: 2rem;">
<span style="display: inline-block; background: rgba(124, 58, 237, 0.1); padding: 0.75rem 1.5rem; border-radius: 20px; color: #7c3aed; font-size: 0.9rem; backdrop-filter: blur(10px); border: 1px solid rgba(124, 58, 237, 0.2); margin: 0 0.5rem;">
🤖 Powered by Google Gemini 2.5
</span>
<span style="display: inline-block; background: rgba(236, 72, 153, 0.1); padding: 0.75rem 1.5rem; border-radius: 20px; color: #ec4899; font-size: 0.9rem; backdrop-filter: blur(10px); border: 1px solid rgba(236, 72, 153, 0.2); margin: 0 0.5rem;">
❤️ Built for the Community
</span>
</div>
</div>
</div>
""")
return interface
def main():
"""Launch the Gradio application."""
try:
interface = create_gradio_interface()
interface.launch(
server_name="0.0.0.0",
server_port=7860,
share=True,
show_error=True
)
except Exception as e:
print(f"Error launching Gradio app: {e}")
print("Make sure you have set GOOGLE_API_KEY in your .env file")
if __name__ == "__main__":
main()