chansung commited on
Commit
80a1334
·
verified ·
1 Parent(s): f2b68e4

Upload folder using huggingface_hub

Browse files
.claude/settings.local.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python3 -c \"import platform; import psutil; import torch; print(f'Python: {platform.python_version()}'); print(f'Platform: {platform.system()} {platform.release()}'); print(f'CPU: {platform.processor()}'); print(f'CPU Cores: {psutil.cpu_count()}'); print(f'RAM: {psutil.virtual_memory().total // (1024**3)} GB'); print(f'PyTorch: {torch.__version__}' if 'torch' in globals() else 'PyTorch: Not installed'); print(f'CUDA Available: {torch.cuda.is_available()}' if 'torch' in globals() else 'CUDA: Check needed'); print(f'CUDA Devices: {torch.cuda.device_count()}' if 'torch' in globals() and torch.cuda.is_available() else '')\")",
5
+ "Bash(python3 -c \"import platform; import os; print(f'Python: {platform.python_version()}'); print(f'Platform: {platform.system()} {platform.release()}'); print(f'Machine: {platform.machine()}'); print(f'Processor: {platform.processor()}'); print(f'CPU Count: {os.cpu_count()}'); print('Checking for GPU...'); import subprocess; result = subprocess.run(['nvidia-smi', '--query-gpu=name,memory.total', '--format=csv,noheader,nounits'], capture_output=True, text=True); print(f'NVIDIA GPUs: {result.stdout.strip()}' if result.returncode == 0 else 'No NVIDIA GPU detected')\")",
6
+ "Bash(conda create -n auto-diffusers python=3.11 -y)",
7
+ "Bash(source /opt/miniconda3/etc/profile.d/conda.sh)",
8
+ "Bash(conda activate auto-diffusers)",
9
+ "Bash(python hardware_detector.py)",
10
+ "Bash(pip install psutil torch)",
11
+ "Bash(python -c \"from hardware_detector import HardwareDetector; h = HardwareDetector(); h.print_specs(); print(f''Profile: {h.get_optimization_profile()}'')\")",
12
+ "Bash(pip install google-generativeai)",
13
+ "Bash(pip install python-dotenv)",
14
+ "Bash(python test_generation.py)",
15
+ "Bash(python test_flux_specific.py)",
16
+ "Bash(python -c \"from hardware_detector import HardwareDetector; h = HardwareDetector(); print(''Hardware detection: OK''); print(f''Profile: {h.get_optimization_profile()}'')\")",
17
+ "Bash(python -c \"import os; from dotenv import load_dotenv; load_dotenv(); print(''API key loaded:'', ''Yes'' if os.getenv(''GOOGLE_API_KEY'') else ''No'')\")",
18
+ "Bash(ls -la *.py)",
19
+ "Bash(pip install gradio)",
20
+ "Bash(python -c \"from gradio_app import create_gradio_interface; print(''✅ Gradio app imports successfully'')\")",
21
+ "Bash(python -c \"from model_memory_calculator import ModelMemoryCalculator; calc = ModelMemoryCalculator(); print(''Testing memory calculator...''); result = calc.get_model_memory_requirements(''black-forest-labs/FLUX.1-schnell''); print(f''Model has {result.get(\"\"total_params_billions\"\", 0):.1f}B parameters'')\")",
22
+ "Bash(python -c \"from model_memory_calculator import ModelMemoryCalculator; calc = ModelMemoryCalculator(); result = calc.get_model_memory_requirements(''black-forest-labs/FLUX.1-schnell'')\")",
23
+ "Bash(python simple_memory_calculator.py)",
24
+ "Bash(python gradio_app.py)",
25
+ "Bash(python -c \"\nfrom simple_memory_calculator import SimpleMemoryCalculator\ncalc = SimpleMemoryCalculator()\nprint(calc.format_memory_info('stabilityai/stable-diffusion-2'))\n\")",
26
+ "Bash(python -m py_compile gradio_app.py)",
27
+ "Bash(python -c \"\nimport gradio_app\nprint('✅ Gradio app syntax is valid!')\n\")",
28
+ "Bash(python -c \"print('App is ready!')\")",
29
+ "Bash(grep -n \"copy_btn.click\\|collapse_btn.click\" /Users/deep-diver/Developers/auto-diffusers/gradio_app.py)",
30
+ "Bash(grep -n \"📋\\|🔽\\|🔼\" /Users/deep-diver/Developers/auto-diffusers/gradio_app.py)",
31
+ "Bash(grep -n \"💡 Tip:\" /Users/deep-diver/Developers/auto-diffusers/gradio_app.py)"
32
+ ],
33
+ "deny": []
34
+ }
35
+ }
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_API_KEY=AIzaSyA-rA_Gnw_jMx4QeaRQ639f1d8PQkvA6hA
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
3
+ TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
4
+ cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
5
+ WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
6
+ ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
7
+ MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
8
+ h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
9
+ 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
10
+ A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
11
+ T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
12
+ B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
13
+ B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
14
+ KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
15
+ OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
16
+ jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
17
+ qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
18
+ rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
19
+ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
20
+ hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
21
+ ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
22
+ 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
23
+ NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
24
+ ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
25
+ TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
26
+ jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
27
+ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
28
+ 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
29
+ mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
30
+ emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
31
+ -----END CERTIFICATE-----
README.md CHANGED
@@ -1,12 +1,103 @@
1
  ---
2
- title: Auto Diffuser Config
3
- emoji: 📈
4
- colorFrom: green
5
- colorTo: yellow
6
  sdk: gradio
7
  sdk_version: 5.31.0
8
- app_file: app.py
9
- pinned: false
10
  ---
 
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: auto-diffuser-config
3
+ app_file: gradio_app.py
 
 
4
  sdk: gradio
5
  sdk_version: 5.31.0
 
 
6
  ---
7
+ # Auto-Diffusers
8
 
9
+ An intelligent code generator that creates optimized diffusers library snippets based on your hardware specifications using Google's Gemini API.
10
+
11
+ ## Features
12
+
13
+ - **Hardware Detection**: Automatically detects your system specs (CPU, GPU, VRAM) or allows manual input
14
+ - **Real-time Optimization**: Fetches latest optimization techniques from HuggingFace documentation
15
+ - **Smart Code Generation**: Uses Gemini API to generate hardware-optimized diffusers code
16
+ - **Multiple Profiles**: Supports high-end GPU, mid-range GPU, low VRAM, Apple Silicon, and CPU-only configurations
17
+
18
+ ## Setup
19
+
20
+ 1. Create and activate conda environment:
21
+ ```bash
22
+ conda create -n auto-diffusers python=3.11 -y
23
+ conda activate auto-diffusers
24
+ ```
25
+
26
+ 2. Install dependencies:
27
+ ```bash
28
+ pip install -r requirements.txt
29
+ ```
30
+
31
+ 3. Set up Gemini API key:
32
+ ```bash
33
+ export GEMINI_API_KEY="your_api_key_here"
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ### Interactive Mode
39
+ ```bash
40
+ python auto_diffusers.py
41
+ ```
42
+
43
+ ### Hardware Detection Only
44
+ ```bash
45
+ python hardware_detector.py
46
+ ```
47
+
48
+ ### Programmatic Usage
49
+ ```python
50
+ from auto_diffusers import AutoDiffusersGenerator
51
+
52
+ generator = AutoDiffusersGenerator(api_key="your_key")
53
+ code = generator.generate_optimized_code(
54
+ model_name="black-forest-labs/FLUX.1-schnell",
55
+ prompt_text="A cat holding a sign that says hello world",
56
+ image_size=(768, 1360),
57
+ num_inference_steps=4
58
+ )
59
+ print(code)
60
+ ```
61
+
62
+ ## Hardware Profiles
63
+
64
+ - **high_end_gpu**: 20+ GB VRAM (RTX 4090, A100, etc.)
65
+ - **mid_range_gpu**: 8-20 GB VRAM (RTX 3080, RTX 4070, etc.)
66
+ - **low_vram_gpu**: <8 GB VRAM (GTX 1660, RTX 3060, etc.)
67
+ - **apple_silicon**: M1/M2/M3 Macs with MPS support
68
+ - **cpu_only**: No GPU acceleration
69
+
70
+ ## Optimization Techniques Applied
71
+
72
+ The generator automatically applies appropriate optimizations based on your hardware:
73
+
74
+ - Memory optimizations (model offloading, attention slicing, VAE slicing)
75
+ - Speed optimizations (torch.compile, optimal dtypes)
76
+ - Hardware-specific optimizations (CUDA, MPS, CPU fallbacks)
77
+ - Model-specific configurations (schedulers, inference parameters)
78
+
79
+ ## Example Output
80
+
81
+ ```python
82
+ import torch
83
+ from diffusers import FluxPipeline
84
+
85
+ # Optimized for Apple Silicon (MPS)
86
+ pipe = FluxPipeline.from_pretrained(
87
+ "black-forest-labs/FLUX.1-schnell",
88
+ torch_dtype=torch.bfloat16
89
+ )
90
+ pipe.to("mps")
91
+ pipe.enable_attention_slicing()
92
+
93
+ prompt = "A cat holding a sign that says hello world"
94
+ out = pipe(
95
+ prompt=prompt,
96
+ guidance_scale=0.,
97
+ height=768,
98
+ width=1360,
99
+ num_inference_steps=4,
100
+ max_sequence_length=256,
101
+ ).images[0]
102
+ out.save("image.png")
103
+ ```
__pycache__/auto_diffusers.cpython-311.pyc ADDED
Binary file (11.9 kB). View file
 
__pycache__/auto_diffusers.cpython-312.pyc ADDED
Binary file (10.8 kB). View file
 
__pycache__/gradio_app.cpython-311.pyc ADDED
Binary file (20.6 kB). View file
 
__pycache__/gradio_app.cpython-312.pyc ADDED
Binary file (59.2 kB). View file
 
__pycache__/hardware_detector.cpython-311.pyc ADDED
Binary file (7.57 kB). View file
 
__pycache__/hardware_detector.cpython-312.pyc ADDED
Binary file (6.83 kB). View file
 
__pycache__/model_memory_calculator.cpython-311.pyc ADDED
Binary file (9.83 kB). View file
 
__pycache__/simple_memory_calculator.cpython-311.pyc ADDED
Binary file (10.5 kB). View file
 
__pycache__/simple_memory_calculator.cpython-312.pyc ADDED
Binary file (9.55 kB). View file
 
auto_diffusers.py ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ import google.generativeai as genai
4
+ from hardware_detector import HardwareDetector
5
+ from typing import Dict, List
6
+
7
+ load_dotenv()
8
+
9
+
10
+ class AutoDiffusersGenerator:
11
+ def __init__(self, api_key: str):
12
+ genai.configure(api_key=api_key)
13
+ self.model = genai.GenerativeModel('gemini-2.5-flash-preview-05-20')
14
+ self.hardware_detector = HardwareDetector()
15
+
16
+ def generate_optimized_code(self,
17
+ model_name: str,
18
+ prompt_text: str,
19
+ image_size: tuple = (768, 1360),
20
+ num_inference_steps: int = 4,
21
+ use_manual_specs: bool = False,
22
+ manual_specs: Dict = None,
23
+ memory_analysis: Dict = None) -> str:
24
+ """Generate optimized diffusers code based on hardware specs and memory analysis."""
25
+
26
+ # Get hardware specifications
27
+ if use_manual_specs and manual_specs:
28
+ hardware_specs = manual_specs
29
+ # Determine optimization profile based on manual specs
30
+ if hardware_specs.get('gpu_info') and hardware_specs['gpu_info']:
31
+ vram_gb = hardware_specs['gpu_info'][0]['memory_mb'] / 1024
32
+ if vram_gb >= 16:
33
+ optimization_profile = 'performance'
34
+ elif vram_gb >= 8:
35
+ optimization_profile = 'balanced'
36
+ else:
37
+ optimization_profile = 'memory_efficient'
38
+ else:
39
+ optimization_profile = 'cpu_only'
40
+ else:
41
+ hardware_specs = self.hardware_detector.specs
42
+ optimization_profile = self.hardware_detector.get_optimization_profile()
43
+
44
+ # Create the prompt for Gemini API
45
+ system_prompt = self._create_generation_prompt(
46
+ model_name, prompt_text, image_size, num_inference_steps,
47
+ hardware_specs, optimization_profile, memory_analysis
48
+ )
49
+
50
+ try:
51
+ response = self.model.generate_content(system_prompt)
52
+ return response.text
53
+ except Exception as e:
54
+ return f"Error generating code: {str(e)}"
55
+
56
+ def _create_generation_prompt(self,
57
+ model_name: str,
58
+ prompt_text: str,
59
+ image_size: tuple,
60
+ num_inference_steps: int,
61
+ hardware_specs: Dict,
62
+ optimization_profile: str,
63
+ memory_analysis: Dict = None) -> str:
64
+ """Create the prompt for Gemini API to generate optimized code."""
65
+
66
+ base_prompt = f"""
67
+ You are an expert in optimizing diffusers library code for different hardware configurations.
68
+
69
+ TASK: Generate optimized Python code for running a diffusion model with the following specifications:
70
+ - Model: {model_name}
71
+ - Prompt: "{prompt_text}"
72
+ - Image size: {image_size[0]}x{image_size[1]}
73
+ - Inference steps: {num_inference_steps}
74
+
75
+ HARDWARE SPECIFICATIONS:
76
+ - Platform: {hardware_specs['platform']} ({hardware_specs['architecture']})
77
+ - CPU Cores: {hardware_specs['cpu_count']}
78
+ - CUDA Available: {hardware_specs['cuda_available']}
79
+ - MPS Available: {hardware_specs['mps_available']}
80
+ - Optimization Profile: {optimization_profile}
81
+ """
82
+
83
+ if hardware_specs.get('gpu_info'):
84
+ base_prompt += f"- GPU: {hardware_specs['gpu_info'][0]['name']} ({hardware_specs['gpu_info'][0]['memory_mb']/1024:.1f} GB VRAM)\n"
85
+
86
+ # Add user dtype preference if specified
87
+ if hardware_specs.get('user_dtype'):
88
+ base_prompt += f"- User specified dtype: {hardware_specs['user_dtype']}\n"
89
+
90
+ # Add memory analysis information
91
+ if memory_analysis:
92
+ memory_info = memory_analysis.get('memory_info', {})
93
+ recommendations = memory_analysis.get('recommendations', {})
94
+
95
+ base_prompt += f"\nMEMORY ANALYSIS:\n"
96
+ if memory_info.get('estimated_inference_memory_fp16_gb'):
97
+ base_prompt += f"- Model Memory Requirements: {memory_info['estimated_inference_memory_fp16_gb']} GB (FP16 inference)\n"
98
+ if memory_info.get('memory_fp16_gb'):
99
+ base_prompt += f"- Model Weights Size: {memory_info['memory_fp16_gb']} GB (FP16)\n"
100
+ if recommendations.get('recommendations'):
101
+ base_prompt += f"- Memory Recommendation: {', '.join(recommendations['recommendations'])}\n"
102
+ if recommendations.get('recommended_precision'):
103
+ base_prompt += f"- Recommended Precision: {recommendations['recommended_precision']}\n"
104
+ if recommendations.get('cpu_offload'):
105
+ base_prompt += f"- CPU Offloading Required: {recommendations['cpu_offload']}\n"
106
+ if recommendations.get('attention_slicing'):
107
+ base_prompt += f"- Attention Slicing Recommended: {recommendations['attention_slicing']}\n"
108
+ if recommendations.get('vae_slicing'):
109
+ base_prompt += f"- VAE Slicing Recommended: {recommendations['vae_slicing']}\n"
110
+
111
+ base_prompt += f"""
112
+ OPTIMIZATION REQUIREMENTS:
113
+ Please scrape and analyze the latest optimization techniques from this URL: https://huggingface.co/docs/diffusers/main/en/optimization
114
+
115
+ IMPORTANT: For FLUX.1-schnell models, do NOT include guidance_scale parameter as it's not needed.
116
+
117
+ Based on the hardware specs and optimization profile, generate Python code that includes:
118
+
119
+ 1. **Memory Optimizations** (if low VRAM):
120
+ - Model offloading (enable_model_cpu_offload, enable_sequential_cpu_offload)
121
+ - Attention slicing (enable_attention_slicing)
122
+ - VAE slicing (enable_vae_slicing)
123
+ - Memory efficient attention
124
+
125
+ 2. **Speed Optimizations**:
126
+ - Appropriate torch.compile() usage
127
+ - Optimal dtype selection (torch.float16, torch.bfloat16)
128
+ - Device placement optimization
129
+
130
+ 3. **Hardware-Specific Optimizations**:
131
+ - CUDA optimizations for NVIDIA GPUs
132
+ - MPS optimizations for Apple Silicon
133
+ - CPU fallbacks when needed
134
+
135
+ 4. **Model-Specific Optimizations**:
136
+ - Appropriate scheduler selection
137
+ - Optimal inference parameters
138
+ - Pipeline configuration
139
+
140
+ 5. **Data Type (dtype) Selection**:
141
+ - If user specified a dtype, use that exact dtype in the code
142
+ - If no dtype specified, automatically select the optimal dtype based on hardware:
143
+ * Apple Silicon (MPS): prefer torch.bfloat16
144
+ * NVIDIA GPUs: prefer torch.float16 or torch.bfloat16 based on capability
145
+ * CPU only: use torch.float32
146
+ - Add a comment explaining why that dtype was chosen
147
+
148
+ IMPORTANT GUIDELINES:
149
+ - Include all necessary imports
150
+ - Add brief comments explaining optimization choices
151
+ - Use the most current and effective optimization techniques
152
+ - Ensure code is production-ready
153
+
154
+ CODE STYLE REQUIREMENTS - GENERATE COMPACT CODE:
155
+ - Assign static values directly to function arguments instead of using variables when possible
156
+ - Minimize variable declarations - inline values where it improves readability
157
+ - Reduce exception handling to essential cases only - assume normal operation
158
+ - Use concise, direct code patterns
159
+ - Combine operations where logical and readable
160
+ - Avoid unnecessary intermediate variables
161
+ - Keep code clean and minimal while maintaining functionality
162
+
163
+ Examples of preferred compact style:
164
+ - pipe = Pipeline.from_pretrained("model", torch_dtype=torch.float16) instead of storing dtype in variable
165
+ - image = pipe("prompt", num_inference_steps=4, height=768, width=1360) instead of separate variables
166
+ - Direct assignment: device = "cuda" if torch.cuda.is_available() else "cpu"
167
+
168
+ Generate ONLY the Python code, no explanations before or after the code block.
169
+ """
170
+
171
+ return base_prompt
172
+
173
+ def run_interactive_mode(self):
174
+ """Run the generator in interactive mode."""
175
+ print("=== Auto-Diffusers Code Generator ===")
176
+ print("This tool generates optimized diffusers code based on your hardware.\n")
177
+
178
+ # Check hardware
179
+ print("=== Hardware Detection ===")
180
+ self.hardware_detector.print_specs()
181
+
182
+ use_manual = input("\nUse manual hardware input? (y/n): ").lower() == 'y'
183
+
184
+ # Get user inputs
185
+ print("\n=== Model Configuration ===")
186
+ model_name = input("Model name (default: black-forest-labs/FLUX.1-schnell): ").strip()
187
+ if not model_name:
188
+ model_name = "black-forest-labs/FLUX.1-schnell"
189
+
190
+ prompt_text = input("Prompt text (default: A cat holding a sign that says hello world): ").strip()
191
+ if not prompt_text:
192
+ prompt_text = "A cat holding a sign that says hello world"
193
+
194
+ try:
195
+ width = int(input("Image width (default: 1360): ") or "1360")
196
+ height = int(input("Image height (default: 768): ") or "768")
197
+ steps = int(input("Inference steps (default: 4): ") or "4")
198
+ except ValueError:
199
+ width, height, steps = 1360, 768, 4
200
+
201
+ print("\n=== Generating Optimized Code ===")
202
+
203
+ # Generate code
204
+ optimized_code = self.generate_optimized_code(
205
+ model_name=model_name,
206
+ prompt_text=prompt_text,
207
+ image_size=(height, width),
208
+ num_inference_steps=steps,
209
+ use_manual_specs=use_manual
210
+ )
211
+
212
+ print("\n" + "="*60)
213
+ print("OPTIMIZED DIFFUSERS CODE:")
214
+ print("="*60)
215
+ print(optimized_code)
216
+ print("="*60)
217
+
218
+
219
+ def main():
220
+ # Get API key from .env file
221
+ api_key = os.getenv('GOOGLE_API_KEY')
222
+ if not api_key:
223
+ api_key = os.getenv('GEMINI_API_KEY') # fallback
224
+ if not api_key:
225
+ api_key = input("Enter your Gemini API key: ").strip()
226
+ if not api_key:
227
+ print("API key is required!")
228
+ return
229
+
230
+ generator = AutoDiffusersGenerator(api_key)
231
+ generator.run_interactive_mode()
232
+
233
+
234
+ if __name__ == "__main__":
235
+ main()
flux_optimized_apple_silicon.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from diffusers import FluxPipeline
3
+
4
+ try:
5
+ model_id = "black-forest-labs/FLUX.1-schnell"
6
+ pipe = FluxPipeline.from_pretrained(model_id, torch_dtype=torch.bfloat16)
7
+ pipe = pipe.to("mps")
8
+
9
+ prompt = "A cat holding a sign that says hello world"
10
+ image_size = (768, 1360)
11
+ num_inference_steps = 4
12
+ guidance_scale = 0.0
13
+ max_sequence_length = 256
14
+
15
+
16
+ with torch.inference_mode():
17
+ image = pipe(prompt,
18
+ image_size=image_size,
19
+ num_inference_steps=num_inference_steps,
20
+ guidance_scale=guidance_scale,
21
+ max_sequence_length=max_sequence_length,
22
+ attention_slicing=True,
23
+ vae_slicing=True).images[0]
24
+ image.save("output.png")
25
+
26
+ except Exception as e:
27
+ print(f"An error occurred: {e}")
28
+ except ImportError as e:
29
+ print(f"An import error occurred: {e}. Please make sure you have the required libraries installed.")
30
+
31
+ except RuntimeError as e:
32
+ if "CUDA out of memory" in str(e):
33
+ print("Out of MPS memory. Try reducing image size or batch size.")
34
+ else:
35
+ print(f"A runtime error occurred: {e}")
generated_optimized.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```python
2
+ import torch
3
+ from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
4
+
5
+ # Model selection and device placement
6
+ model_id = "black-forest-labs/FLUX.1-schnell"
7
+ device = "mps" if torch.backends.mps.is_available() else "cpu" # Prioritize MPS
8
+
9
+ # Optimization parameters
10
+ torch.backends.mps.graph_mode = False # Disable graph mode for MPS for better debugging and potential performance in some cases
11
+ pipe = StableDiffusionPipeline.from_pretrained(
12
+ model_id,
13
+ torch_dtype=torch.float16, # Use float16 for better performance on MPS
14
+ scheduler=DPMSolverMultistepScheduler.from_config(model_id, algorithm_type="dpmsolver"), # Optimized scheduler for speed
15
+ )
16
+ pipe.to(device)
17
+
18
+ # Memory optimization
19
+ pipe.enable_attention_slicing() # Enable attention slicing for memory efficiency
20
+ pipe.enable_vae_slicing() # Enable VAE slicing for memory efficiency
21
+
22
+ # Speed optimization with torch.compile
23
+ pipe = torch.compile(pipe) # Compile the pipeline for better performance
24
+
25
+ # Inference parameters
26
+ prompt = "A cat holding a sign that says hello world"
27
+ height = 768
28
+ width = 1360
29
+ num_inference_steps = 4
30
+
31
+ # Inference
32
+ image = pipe(prompt, height=height, width=width, num_inference_steps=num_inference_steps).images[0]
33
+
34
+ # Save the image (optional)
35
+ image.save("cat_with_sign.png")
36
+
37
+ ```
gradio_app.py ADDED
@@ -0,0 +1,1336 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from dotenv import load_dotenv
4
+ import google.generativeai as genai
5
+ from auto_diffusers import AutoDiffusersGenerator
6
+ from simple_memory_calculator import SimpleMemoryCalculator
7
+
8
+ load_dotenv()
9
+
10
+ class GradioAutodiffusers:
11
+ def __init__(self):
12
+ self.api_key = os.getenv('GOOGLE_API_KEY')
13
+ if not self.api_key:
14
+ raise ValueError("GOOGLE_API_KEY not found in .env file")
15
+
16
+ self.generator = AutoDiffusersGenerator(self.api_key)
17
+ self.memory_calculator = SimpleMemoryCalculator()
18
+
19
+ # Default settings
20
+ self.current_model = 'gemini-2.5-flash-preview-05-20'
21
+ self.temperature = 0.7
22
+ self.max_output_tokens = 8192
23
+ self.top_p = 0.9
24
+ self.top_k = 40
25
+
26
+ def update_model_settings(self, model_name, temperature, max_output_tokens, top_p, top_k):
27
+ """Update Gemini model settings."""
28
+ self.current_model = model_name
29
+ self.temperature = temperature
30
+ self.max_output_tokens = max_output_tokens
31
+ self.top_p = top_p
32
+ self.top_k = top_k
33
+
34
+ # Update the generator's model with new settings
35
+ genai.configure(api_key=self.api_key)
36
+ generation_config = genai.types.GenerationConfig(
37
+ temperature=temperature,
38
+ max_output_tokens=max_output_tokens,
39
+ top_p=top_p,
40
+ top_k=top_k
41
+ )
42
+ self.generator.model = genai.GenerativeModel(model_name, generation_config=generation_config)
43
+
44
+ return f"✅ Model updated to {model_name} with new settings"
45
+
46
+ def get_generation_prompt(self, model_name, prompt_text, image_size, num_inference_steps, hardware_specs, optimization_profile):
47
+ """Get the actual prompt that will be sent to Gemini API."""
48
+ return self.generator._create_generation_prompt(
49
+ model_name, prompt_text, image_size, num_inference_steps,
50
+ hardware_specs, optimization_profile
51
+ )
52
+
53
+ def analyze_model_memory(self, model_name, vram_gb):
54
+ """Analyze model memory requirements and provide recommendations."""
55
+ try:
56
+ if not vram_gb:
57
+ vram_gb = 8 # Default
58
+
59
+ memory_info = self.memory_calculator.get_model_memory_requirements(model_name)
60
+ recommendations = self.memory_calculator.get_memory_recommendation(model_name, float(vram_gb))
61
+ formatted_info = self.memory_calculator.format_memory_info(model_name)
62
+
63
+ return memory_info, recommendations, formatted_info
64
+
65
+ except Exception as e:
66
+ error_msg = f"Error analyzing model memory: {str(e)}"
67
+ return {'error': error_msg}, {'error': error_msg}, error_msg
68
+
69
+ def generate_code_with_manual_specs(self,
70
+ gpu_name,
71
+ vram_gb,
72
+ ram_gb,
73
+ platform,
74
+ model_name,
75
+ prompt_text,
76
+ dtype_selection,
77
+ width,
78
+ height,
79
+ inference_steps,
80
+ memory_analysis=None):
81
+ """Generate optimized code with manual hardware specifications."""
82
+
83
+ try:
84
+ # Create manual hardware specs
85
+ # Parse dtype selection
86
+ if dtype_selection == "Auto (Let AI decide)":
87
+ user_dtype = None
88
+ else:
89
+ user_dtype = dtype_selection
90
+
91
+ manual_specs = {
92
+ 'platform': platform,
93
+ 'architecture': 'manual_input',
94
+ 'cpu_count': 8, # Default
95
+ 'python_version': '3.11',
96
+ 'cuda_available': 'nvidia' in gpu_name.lower() if gpu_name else False,
97
+ 'mps_available': platform == 'Darwin' and 'apple' in gpu_name.lower() if gpu_name else False,
98
+ 'torch_version': '2.0+',
99
+ 'manual_input': True,
100
+ 'ram_gb': int(ram_gb) if ram_gb else 16,
101
+ 'user_dtype': user_dtype
102
+ }
103
+
104
+ # Add GPU info if provided
105
+ if gpu_name and vram_gb:
106
+ manual_specs['gpu_info'] = [{
107
+ 'name': gpu_name,
108
+ 'memory_mb': int(vram_gb) * 1024
109
+ }]
110
+
111
+ if 'nvidia' in gpu_name.lower():
112
+ manual_specs['cuda_available'] = True
113
+ manual_specs['cuda_device_count'] = 1
114
+ manual_specs['cuda_device_name'] = gpu_name
115
+ manual_specs['cuda_memory'] = int(vram_gb)
116
+ else:
117
+ manual_specs['gpu_info'] = None
118
+
119
+ # Generate optimized code with manual specs and memory analysis
120
+ optimized_code = self.generator.generate_optimized_code(
121
+ model_name=model_name,
122
+ prompt_text=prompt_text,
123
+ image_size=(int(height), int(width)),
124
+ num_inference_steps=int(inference_steps),
125
+ use_manual_specs=True,
126
+ manual_specs=manual_specs,
127
+ memory_analysis=memory_analysis
128
+ )
129
+
130
+ # Clean up any markdown formatting
131
+ if optimized_code.startswith('```python'):
132
+ optimized_code = optimized_code[9:]
133
+ if optimized_code.endswith('```'):
134
+ optimized_code = optimized_code[:-3]
135
+
136
+ return optimized_code.strip()
137
+
138
+ except Exception as e:
139
+ return f"Error generating code: {str(e)}"
140
+
141
+
142
+ def create_gradio_interface():
143
+ """Create and configure the Gradio interface."""
144
+
145
+ app = GradioAutodiffusers()
146
+
147
+ with gr.Blocks(
148
+ title="Auto-Diffusers Code Generator",
149
+ theme=gr.themes.Soft(
150
+ primary_hue="violet",
151
+ secondary_hue="blue",
152
+ neutral_hue="slate",
153
+ radius_size=gr.themes.sizes.radius_lg,
154
+ font=[gr.themes.GoogleFont("Poppins"), gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"]
155
+ ).set(
156
+ background_fill_primary="*neutral_25",
157
+ background_fill_secondary="*neutral_50",
158
+ block_background_fill="rgba(255, 255, 255, 0.95)",
159
+ block_border_width="0px",
160
+ block_shadow="0 8px 32px rgba(0, 0, 0, 0.08)",
161
+ panel_background_fill="rgba(255, 255, 255, 0.9)",
162
+ button_primary_background_fill="*primary_500",
163
+ button_primary_background_fill_hover="*primary_600",
164
+ button_secondary_background_fill="rgba(255, 255, 255, 0.8)",
165
+ button_secondary_background_fill_hover="rgba(255, 255, 255, 0.95)"
166
+ ),
167
+ css="""
168
+ /* Global Styles */
169
+ .gradio-container {
170
+ background: linear-gradient(135deg,
171
+ #667eea 0%,
172
+ #764ba2 25%,
173
+ #f093fb 50%,
174
+ #f5576c 75%,
175
+ #4facfe 100%) !important;
176
+ min-height: 100vh;
177
+ }
178
+
179
+ .main-container {
180
+ max-width: 1400px;
181
+ margin: 0 auto;
182
+ padding: 2rem;
183
+ /* Removed position: relative that can interfere with dropdown positioning */
184
+ }
185
+
186
+ /* Floating Background Elements */
187
+ .main-container::before {
188
+ content: '';
189
+ position: fixed;
190
+ top: 0;
191
+ left: 0;
192
+ right: 0;
193
+ bottom: 0;
194
+ background:
195
+ radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
196
+ radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
197
+ radial-gradient(circle at 40% 70%, rgba(124, 58, 237, 0.1) 0%, transparent 50%);
198
+ pointer-events: none;
199
+ z-index: -1;
200
+ }
201
+
202
+ /* Glass Morphism Effects - Fixed for Dropdown Compatibility */
203
+ .glass-card {
204
+ background: rgba(255, 255, 255, 0.25) !important;
205
+ border: 1px solid rgba(255, 255, 255, 0.2) !important;
206
+ border-radius: 20px !important;
207
+ box-shadow:
208
+ 0 8px 32px rgba(0, 0, 0, 0.1),
209
+ inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
210
+ /* Removed backdrop-filter and transforms that break dropdown positioning */
211
+ }
212
+
213
+ .ultra-glass {
214
+ background: rgba(255, 255, 255, 0.15) !important;
215
+ border: 1px solid rgba(255, 255, 255, 0.3) !important;
216
+ border-radius: 24px !important;
217
+ box-shadow:
218
+ 0 12px 40px rgba(0, 0, 0, 0.15),
219
+ inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
220
+ /* Removed backdrop-filter that interferes with dropdown positioning */
221
+ }
222
+
223
+ /* Premium Header */
224
+ .hero-header {
225
+ background: linear-gradient(135deg,
226
+ rgba(124, 58, 237, 0.9) 0%,
227
+ rgba(236, 72, 153, 0.9) 50%,
228
+ rgba(59, 130, 246, 0.9) 100%) !important;
229
+ backdrop-filter: blur(20px) !important;
230
+ border: 1px solid rgba(255, 255, 255, 0.2) !important;
231
+ border-radius: 24px !important;
232
+ box-shadow:
233
+ 0 20px 60px rgba(124, 58, 237, 0.3),
234
+ inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
235
+ position: relative;
236
+ overflow: hidden;
237
+ }
238
+
239
+ .hero-header::before {
240
+ content: '';
241
+ position: absolute;
242
+ top: 0;
243
+ left: -100%;
244
+ width: 100%;
245
+ height: 100%;
246
+ background: linear-gradient(90deg,
247
+ transparent,
248
+ rgba(255, 255, 255, 0.2),
249
+ transparent);
250
+ animation: shimmer 3s infinite;
251
+ }
252
+
253
+ @keyframes shimmer {
254
+ 0% { left: -100%; }
255
+ 50% { left: 100%; }
256
+ 100% { left: 100%; }
257
+ }
258
+
259
+ /* Premium Buttons */
260
+ .generate-btn {
261
+ background: linear-gradient(135deg,
262
+ #667eea 0%,
263
+ #764ba2 50%,
264
+ #f093fb 100%) !important;
265
+ border: none !important;
266
+ color: white !important;
267
+ font-weight: 700 !important;
268
+ font-size: 1.1rem !important;
269
+ padding: 1rem 3rem !important;
270
+ border-radius: 16px !important;
271
+ box-shadow:
272
+ 0 8px 32px rgba(102, 126, 234, 0.4),
273
+ inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
274
+ transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important;
275
+ position: relative;
276
+ overflow: hidden;
277
+ }
278
+
279
+ .generate-btn::before {
280
+ content: '';
281
+ position: absolute;
282
+ top: 0;
283
+ left: -100%;
284
+ width: 100%;
285
+ height: 100%;
286
+ background: linear-gradient(90deg,
287
+ transparent,
288
+ rgba(255, 255, 255, 0.3),
289
+ transparent);
290
+ transition: left 0.5s;
291
+ }
292
+
293
+ .generate-btn:hover::before {
294
+ left: 100%;
295
+ }
296
+
297
+ .generate-btn:hover {
298
+ transform: translateY(-4px) scale(1.02) !important;
299
+ box-shadow:
300
+ 0 16px 48px rgba(102, 126, 234, 0.6),
301
+ inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
302
+ }
303
+
304
+ .generate-btn:active {
305
+ transform: translateY(-2px) scale(1.01) !important;
306
+ }
307
+
308
+ /* Section Headers */
309
+ .section-header {
310
+ background: linear-gradient(135deg,
311
+ rgba(255, 255, 255, 0.9) 0%,
312
+ rgba(248, 250, 252, 0.9) 100%) !important;
313
+ backdrop-filter: blur(10px) !important;
314
+ border: 1px solid rgba(255, 255, 255, 0.4) !important;
315
+ border-radius: 16px !important;
316
+ padding: 1.5rem !important;
317
+ margin-bottom: 1.5rem !important;
318
+ box-shadow:
319
+ 0 4px 20px rgba(0, 0, 0, 0.08),
320
+ inset 0 1px 0 rgba(255, 255, 255, 0.4) !important;
321
+ }
322
+
323
+ /* Premium Inputs - Simplified for Dropdown Compatibility */
324
+ input[type="text"],
325
+ input[type="number"],
326
+ textarea {
327
+ background: rgba(255, 255, 255, 0.9) !important;
328
+ border: 1px solid rgba(255, 255, 255, 0.3) !important;
329
+ border-radius: 12px !important;
330
+ padding: 0.75rem 1rem !important;
331
+ font-weight: 500 !important;
332
+ transition: all 0.3s ease !important;
333
+ }
334
+
335
+ input[type="text"]:focus,
336
+ input[type="number"]:focus,
337
+ textarea:focus {
338
+ background: rgba(255, 255, 255, 0.95) !important;
339
+ border-color: rgba(124, 58, 237, 0.5) !important;
340
+ box-shadow:
341
+ 0 0 0 4px rgba(124, 58, 237, 0.1),
342
+ 0 4px 20px rgba(124, 58, 237, 0.2) !important;
343
+ }
344
+
345
+ /* CRITICAL: Reset all problematic CSS for dropdowns */
346
+ label:has(+ [data-testid="dropdown"]),
347
+ div:has([data-testid="dropdown"]),
348
+ [data-testid="dropdown"],
349
+ [data-testid="dropdown"] *,
350
+ .gradio-dropdown,
351
+ .gradio-dropdown * {
352
+ position: static !important;
353
+ transform: none !important;
354
+ backdrop-filter: none !important;
355
+ filter: none !important;
356
+ }
357
+
358
+ /* AGGRESSIVE FIX: Override ALL possible transparency sources */
359
+ * {
360
+ --dropdown-bg: #ffffff !important;
361
+ --dropdown-opacity: 1 !important;
362
+ }
363
+
364
+ /* Target every possible dropdown element with maximum specificity */
365
+ .gradio-container [data-testid="dropdown"] div[role="listbox"],
366
+ .gradio-container .gradio-dropdown .dropdown-content,
367
+ .gradio-container .dropdown-menu,
368
+ .gradio-container div[role="listbox"],
369
+ .gradio-container .svelte-1gfkn6j,
370
+ body [data-testid="dropdown"] div[role="listbox"],
371
+ body .dropdown-menu,
372
+ body div[role="listbox"],
373
+ html [data-testid="dropdown"] div[role="listbox"] {
374
+ background: #ffffff !important;
375
+ background-color: #ffffff !important;
376
+ opacity: 1 !important;
377
+ position: absolute !important;
378
+ z-index: 99999 !important;
379
+ border: 2px solid #d1d5db !important;
380
+ border-radius: 8px !important;
381
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25) !important;
382
+ max-height: 200px !important;
383
+ overflow-y: auto !important;
384
+ backdrop-filter: none !important;
385
+ filter: none !important;
386
+ background-image: none !important;
387
+ background-blend-mode: normal !important;
388
+ /* Force solid with CSS variables */
389
+ background: var(--dropdown-bg, #ffffff) !important;
390
+ opacity: var(--dropdown-opacity, 1) !important;
391
+ }
392
+
393
+ /* Aggressive option styling */
394
+ .gradio-container [data-testid="dropdown"] div[role="listbox"] > *,
395
+ .gradio-container .dropdown-menu > *,
396
+ .gradio-container div[role="listbox"] > *,
397
+ body [data-testid="dropdown"] div[role="listbox"] > *,
398
+ body .dropdown-menu > *,
399
+ body div[role="listbox"] > * {
400
+ background: #ffffff !important;
401
+ background-color: #ffffff !important;
402
+ padding: 0.75rem 1rem !important;
403
+ color: #1f2937 !important;
404
+ cursor: pointer !important;
405
+ opacity: 1 !important;
406
+ border: none !important;
407
+ margin: 0 !important;
408
+ display: block !important;
409
+ width: 100% !important;
410
+ text-align: left !important;
411
+ }
412
+
413
+ /* Ensure dropdown menus appear correctly with SOLID background */
414
+ [data-testid="dropdown"] div[role="listbox"],
415
+ .gradio-dropdown .dropdown-content,
416
+ .dropdown-menu,
417
+ div[role="listbox"],
418
+ .svelte-1gfkn6j,
419
+ .gradio-container div[role="listbox"] {
420
+ position: absolute !important;
421
+ z-index: 9999 !important;
422
+ background: #ffffff !important;
423
+ background-color: #ffffff !important;
424
+ opacity: 1 !important;
425
+ border: 1px solid #d1d5db !important;
426
+ border-radius: 8px !important;
427
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15) !important;
428
+ max-height: 200px !important;
429
+ overflow-y: auto !important;
430
+ backdrop-filter: none !important;
431
+ /* Force solid background */
432
+ background-image: none !important;
433
+ background-blend-mode: normal !important;
434
+ }
435
+
436
+ /* Dropdown option styling - SOLID background for each option */
437
+ [data-testid="dropdown"] div[role="listbox"] > *,
438
+ .dropdown-menu > *,
439
+ div[role="listbox"] > *,
440
+ .svelte-1gfkn6j > * {
441
+ background: #ffffff !important;
442
+ background-color: #ffffff !important;
443
+ padding: 0.5rem 0.75rem !important;
444
+ color: #374151 !important;
445
+ cursor: pointer !important;
446
+ transition: background-color 0.2s ease !important;
447
+ opacity: 1 !important;
448
+ }
449
+
450
+ /* Dropdown option hover effect */
451
+ [data-testid="dropdown"] div[role="listbox"] > *:hover,
452
+ .dropdown-menu > *:hover,
453
+ div[role="listbox"] > *:hover {
454
+ background: #f3f4f6 !important;
455
+ color: #1f2937 !important;
456
+ }
457
+
458
+ /* Dropdown option selected state */
459
+ [data-testid="dropdown"] div[role="listbox"] > *[aria-selected="true"],
460
+ .dropdown-menu > *.selected,
461
+ div[role="listbox"] > *[aria-selected="true"] {
462
+ background: #e0e7ff !important;
463
+ color: #3730a3 !important;
464
+ }
465
+
466
+
467
+ /* Code Areas - Ultra Premium Styling */
468
+ .code-container {
469
+ background: linear-gradient(145deg,
470
+ rgba(15, 23, 42, 0.98) 0%,
471
+ rgba(30, 41, 59, 0.95) 50%,
472
+ rgba(15, 23, 42, 0.98) 100%) !important;
473
+ backdrop-filter: blur(30px) !important;
474
+ border: 2px solid transparent !important;
475
+ background-clip: padding-box !important;
476
+ border-radius: 20px !important;
477
+ position: relative !important;
478
+ overflow: hidden !important;
479
+ box-shadow:
480
+ 0 20px 60px rgba(0, 0, 0, 0.4),
481
+ 0 8px 32px rgba(15, 23, 42, 0.3),
482
+ inset 0 1px 0 rgba(255, 255, 255, 0.1),
483
+ inset 0 -1px 0 rgba(71, 85, 105, 0.2) !important;
484
+ }
485
+
486
+ .code-container::before {
487
+ content: '';
488
+ position: absolute;
489
+ top: 0;
490
+ left: 0;
491
+ right: 0;
492
+ bottom: 0;
493
+ background: linear-gradient(45deg,
494
+ rgba(99, 102, 241, 0.1) 0%,
495
+ rgba(139, 92, 246, 0.1) 25%,
496
+ rgba(59, 130, 246, 0.1) 50%,
497
+ rgba(139, 92, 246, 0.1) 75%,
498
+ rgba(99, 102, 241, 0.1) 100%) !important;
499
+ border-radius: 20px !important;
500
+ z-index: -1 !important;
501
+ animation: code-shimmer 3s ease-in-out infinite !important;
502
+ }
503
+
504
+ @keyframes code-shimmer {
505
+ 0%, 100% { opacity: 0.3; }
506
+ 50% { opacity: 0.6; }
507
+ }
508
+
509
+ /* Code editor styling */
510
+ .code-container .cm-editor {
511
+ background: transparent !important;
512
+ border-radius: 16px !important;
513
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Fira Code', monospace !important;
514
+ font-size: 13px !important;
515
+ line-height: 1.6 !important;
516
+ }
517
+
518
+ .code-container .cm-focused {
519
+ outline: none !important;
520
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.4) !important;
521
+ }
522
+
523
+ .code-container .cm-content {
524
+ padding: 1.5rem !important;
525
+ color: #e2e8f0 !important;
526
+ }
527
+
528
+ .code-container .cm-line {
529
+ padding-left: 0.5rem !important;
530
+ }
531
+
532
+ /* Syntax highlighting for Python */
533
+ .code-container .cm-keyword { color: #f472b6 !important; }
534
+ .code-container .cm-string { color: #34d399 !important; }
535
+ .code-container .cm-comment { color: #94a3b8 !important; font-style: italic !important; }
536
+ .code-container .cm-number { color: #fbbf24 !important; }
537
+ .code-container .cm-variable { color: #60a5fa !important; }
538
+ .code-container .cm-function { color: #a78bfa !important; }
539
+ .code-container .cm-operator { color: #fb7185 !important; }
540
+
541
+ /* Code header styling */
542
+ .code-container label {
543
+ background: linear-gradient(90deg,
544
+ rgba(99, 102, 241, 0.9) 0%,
545
+ rgba(139, 92, 246, 0.9) 50%,
546
+ rgba(59, 130, 246, 0.9) 100%) !important;
547
+ color: white !important;
548
+ padding: 1rem 1.5rem !important;
549
+ border-radius: 16px 16px 0 0 !important;
550
+ font-weight: 600 !important;
551
+ font-size: 1rem !important;
552
+ letter-spacing: 0.025em !important;
553
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) !important;
554
+ margin: 0 !important;
555
+ border: none !important;
556
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.2) !important;
557
+ }
558
+
559
+
560
+ /* Custom scrollbar for code area */
561
+ .code-container .cm-scroller::-webkit-scrollbar {
562
+ width: 8px !important;
563
+ height: 8px !important;
564
+ }
565
+
566
+ .code-container .cm-scroller::-webkit-scrollbar-track {
567
+ background: rgba(15, 23, 42, 0.3) !important;
568
+ border-radius: 4px !important;
569
+ }
570
+
571
+ .code-container .cm-scroller::-webkit-scrollbar-thumb {
572
+ background: linear-gradient(135deg,
573
+ rgba(99, 102, 241, 0.6) 0%,
574
+ rgba(139, 92, 246, 0.6) 100%) !important;
575
+ border-radius: 4px !important;
576
+ border: 1px solid rgba(255, 255, 255, 0.1) !important;
577
+ }
578
+
579
+ .code-container .cm-scroller::-webkit-scrollbar-thumb:hover {
580
+ background: linear-gradient(135deg,
581
+ rgba(99, 102, 241, 0.8) 0%,
582
+ rgba(139, 92, 246, 0.8) 100%) !important;
583
+ }
584
+
585
+ /* Line numbers styling */
586
+ .code-container .cm-lineNumbers {
587
+ background: rgba(15, 23, 42, 0.3) !important;
588
+ color: rgba(148, 163, 184, 0.6) !important;
589
+ border-right: 1px solid rgba(71, 85, 105, 0.3) !important;
590
+ padding-right: 0.5rem !important;
591
+ }
592
+
593
+ .code-container .cm-lineNumbers .cm-gutterElement {
594
+ color: rgba(148, 163, 184, 0.5) !important;
595
+ font-weight: 500 !important;
596
+ }
597
+
598
+ /* Memory Analysis Cards */
599
+ .memory-card {
600
+ background: linear-gradient(135deg,
601
+ rgba(251, 191, 36, 0.1) 0%,
602
+ rgba(245, 158, 11, 0.1) 100%) !important;
603
+ backdrop-filter: blur(15px) !important;
604
+ border: 1px solid rgba(251, 191, 36, 0.2) !important;
605
+ border-radius: 16px !important;
606
+ padding: 1.5rem !important;
607
+ box-shadow:
608
+ 0 8px 32px rgba(245, 158, 11, 0.1),
609
+ inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
610
+ }
611
+
612
+ /* Labels with icons */
613
+ label {
614
+ font-weight: 600 !important;
615
+ color: rgba(30, 41, 59, 0.9) !important;
616
+ font-size: 0.95rem !important;
617
+ }
618
+
619
+ /* Floating Animation */
620
+ @keyframes float {
621
+ 0%, 100% { transform: translateY(0px); }
622
+ 50% { transform: translateY(-10px); }
623
+ }
624
+
625
+ .floating {
626
+ animation: float 6s ease-in-out infinite;
627
+ }
628
+
629
+ /* Pulse Effect */
630
+ @keyframes pulse-glow {
631
+ 0%, 100% {
632
+ box-shadow:
633
+ 0 8px 32px rgba(102, 126, 234, 0.4),
634
+ inset 0 1px 0 rgba(255, 255, 255, 0.2);
635
+ }
636
+ 50% {
637
+ box-shadow:
638
+ 0 12px 48px rgba(102, 126, 234, 0.6),
639
+ inset 0 1px 0 rgba(255, 255, 255, 0.3);
640
+ }
641
+ }
642
+
643
+ .pulse-glow {
644
+ animation: pulse-glow 3s ease-in-out infinite;
645
+ }
646
+
647
+ /* FINAL OVERRIDE: Nuclear option for dropdown transparency */
648
+ [role="listbox"] {
649
+ background: white !important;
650
+ opacity: 1 !important;
651
+ }
652
+
653
+ [role="listbox"] > * {
654
+ background: white !important;
655
+ opacity: 1 !important;
656
+ }
657
+
658
+ /* Gradio-specific nuclear option */
659
+ .gradio-app [role="listbox"],
660
+ .gradio-app [role="listbox"] > * {
661
+ background: #ffffff !important;
662
+ background-color: #ffffff !important;
663
+ opacity: 1 !important;
664
+ }
665
+
666
+ /* Last resort: override all possible transparent backgrounds */
667
+ div[style*="background"] {
668
+ background: unset !important;
669
+ }
670
+
671
+ [role="listbox"][style*="background"] {
672
+ background: #ffffff !important;
673
+ }
674
+ """
675
+ ) as interface:
676
+
677
+ with gr.Column(elem_classes="main-container"):
678
+ # Ultra Premium Header
679
+ with gr.Row():
680
+ with gr.Column(scale=1):
681
+ gr.HTML("""
682
+ <div class="hero-header floating" style="text-align: center; padding: 3rem 2rem; margin-bottom: 3rem; position: relative;">
683
+ <div style="position: relative; z-index: 2;">
684
+ <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;">
685
+ ✨ Auto-Diffusers
686
+ </h1>
687
+ <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);">
688
+ Code Generator
689
+ </h2>
690
+ <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;">
691
+ Generate stunning, optimized diffusers code tailored perfectly for your hardware using advanced AI
692
+ </p>
693
+ <div style="margin-top: 2rem;">
694
+ <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);">
695
+ 🤖 Powered by Google Gemini 2.5
696
+ </span>
697
+ </div>
698
+ </div>
699
+ </div>
700
+ """)
701
+
702
+ # Main Content Area
703
+
704
+ # Hardware Selection Section
705
+ with gr.Group(elem_classes="glass-card"):
706
+ gr.HTML("""
707
+ <div class="section-header" style="text-align: center;">
708
+ <h3 style="margin: 0 0 0.5rem 0; color: #1e293b; font-size: 1.5rem; font-weight: 700;">
709
+ ⚙️ Hardware Specifications
710
+ </h3>
711
+ <p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
712
+ Configure your system hardware for optimal code generation
713
+ </p>
714
+ </div>
715
+ """)
716
+
717
+ with gr.Row():
718
+ with gr.Column(scale=1):
719
+ platform = gr.Dropdown(
720
+ choices=["Linux", "Darwin", "Windows"],
721
+ label="🖥️ Platform",
722
+ value="Linux",
723
+ info="Your operating system"
724
+ )
725
+
726
+ gpu_vendor = gr.Dropdown(
727
+ choices=[
728
+ "Custom (Manual Input)",
729
+ "NVIDIA Consumer (GeForce RTX)",
730
+ "NVIDIA Professional (RTX A-Series)",
731
+ "NVIDIA Data Center",
732
+ "Apple Silicon",
733
+ "AMD",
734
+ "Intel",
735
+ "CPU Only"
736
+ ],
737
+ label="🎮 GPU Vendor/Category",
738
+ value="Custom (Manual Input)",
739
+ info="Select your GPU category"
740
+ )
741
+
742
+ gpu_series = gr.Dropdown(
743
+ choices=[],
744
+ label="📊 GPU Series",
745
+ visible=False,
746
+ interactive=True,
747
+ info="Choose your GPU series"
748
+ )
749
+
750
+ gpu_model = gr.Dropdown(
751
+ choices=[],
752
+ label="🔧 GPU Model",
753
+ visible=False,
754
+ interactive=True,
755
+ info="Select your specific GPU model"
756
+ )
757
+
758
+ gpu_name_custom = gr.Textbox(
759
+ label="💾 Custom GPU Name",
760
+ placeholder="e.g., RTX 4090, GTX 1080 Ti",
761
+ visible=True,
762
+ info="Enter your GPU name manually"
763
+ )
764
+
765
+ gpu_name = gr.Textbox(
766
+ label="Selected GPU",
767
+ visible=False
768
+ )
769
+
770
+ with gr.Column(scale=1):
771
+ vram_gb = gr.Number(
772
+ label="🎯 VRAM/Memory (GB)",
773
+ value=8,
774
+ minimum=0,
775
+ maximum=200,
776
+ info="GPU memory available"
777
+ )
778
+ ram_gb = gr.Number(
779
+ label="💻 System RAM (GB)",
780
+ value=16,
781
+ minimum=4,
782
+ maximum=256,
783
+ info="Total system memory"
784
+ )
785
+
786
+ # Model Configuration Section
787
+ with gr.Group(elem_classes="glass-card"):
788
+ gr.HTML("""
789
+ <div class="section-header" style="text-align: center;">
790
+ <h3 style="margin: 0 0 0.5rem 0; color: #1e293b; font-size: 1.5rem; font-weight: 700;">
791
+ 🤖 Model Configuration
792
+ </h3>
793
+ <p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
794
+ Configure the AI model and generation parameters
795
+ </p>
796
+ </div>
797
+ """)
798
+
799
+ with gr.Row():
800
+ with gr.Column(scale=1):
801
+ model_name = gr.Textbox(
802
+ label="🏷️ Model Name",
803
+ value="black-forest-labs/FLUX.1-schnell",
804
+ placeholder="e.g., black-forest-labs/FLUX.1-schnell",
805
+ info="HuggingFace model identifier"
806
+ )
807
+
808
+ dtype_selection = gr.Dropdown(
809
+ choices=["Auto (Let AI decide)", "torch.float32", "torch.float16", "torch.bfloat16"],
810
+ label="⚡ Data Type (dtype)",
811
+ value="Auto (Let AI decide)",
812
+ info="Precision mode - Auto is recommended"
813
+ )
814
+
815
+ with gr.Column(scale=1):
816
+ with gr.Row():
817
+ width = gr.Number(
818
+ label="📏 Width (px)",
819
+ value=1360,
820
+ minimum=256,
821
+ maximum=2048,
822
+ step=64,
823
+ info="Image width"
824
+ )
825
+ height = gr.Number(
826
+ label="📐 Height (px)",
827
+ value=768,
828
+ minimum=256,
829
+ maximum=2048,
830
+ step=64,
831
+ info="Image height"
832
+ )
833
+
834
+ inference_steps = gr.Number(
835
+ label="🔄 Inference Steps",
836
+ value=4,
837
+ minimum=1,
838
+ maximum=50,
839
+ info="Number of denoising steps (higher = better quality, slower)"
840
+ )
841
+
842
+ # Memory Analysis Section
843
+ with gr.Group(elem_classes="ultra-glass"):
844
+ gr.HTML("""
845
+ <div class="section-header" style="text-align: center;">
846
+ <h3 style="margin: 0 0 0.5rem 0; color: #1e293b; font-size: 1.5rem; font-weight: 700;">
847
+ 🧠 Memory Analysis
848
+ </h3>
849
+ <p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
850
+ Real-time analysis of model memory requirements and optimization strategies
851
+ </p>
852
+ </div>
853
+ """)
854
+
855
+ memory_analysis_output = gr.Markdown(
856
+ value="✨ Select a model and configure your hardware to see memory requirements and optimization recommendations.",
857
+ elem_classes="memory-card"
858
+ )
859
+
860
+ # Generate Button
861
+ with gr.Row():
862
+ with gr.Column():
863
+ gr.HTML("""
864
+ <div style="text-align: center; margin: 2rem 0;">
865
+ </div>
866
+ """)
867
+ generate_btn = gr.Button(
868
+ "✨ Generate Optimized Code",
869
+ variant="primary",
870
+ size="lg",
871
+ elem_classes="generate-btn pulse-glow"
872
+ )
873
+
874
+ # Generated Code Section
875
+ with gr.Group(elem_classes="ultra-glass"):
876
+ gr.HTML("""
877
+ <div class="section-header" style="text-align: center; position: relative; overflow: hidden;">
878
+ <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>
879
+ <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);">
880
+ 💻 Generated Code
881
+ </h3>
882
+ <p style="margin: 0; color: #64748b; font-size: 1rem; font-weight: 500;">
883
+ ✨ Ultra-optimized Python code with hardware-specific acceleration
884
+ </p>
885
+ <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);">
886
+ <span style="color: #059669; font-weight: 600; font-size: 0.9rem;">
887
+ 🚀 Ready-to-run • Memory optimized • Performance tuned
888
+ </span>
889
+ </div>
890
+ </div>
891
+ """)
892
+
893
+ # Code Summary
894
+ code_summary = gr.Markdown(
895
+ value="🎯 Generated code summary will appear here after generation.",
896
+ elem_classes="memory-card"
897
+ )
898
+
899
+ # Code Output
900
+ code_output = gr.Code(
901
+ label="🚀 Hardware-Optimized Diffusion Pipeline",
902
+ language="python",
903
+ lines=20,
904
+ interactive=True,
905
+ show_label=True,
906
+ elem_classes="code-container",
907
+ 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!')"
908
+ )
909
+
910
+ def on_gpu_vendor_change(vendor):
911
+ """Handle GPU vendor selection and update series dropdown."""
912
+ if vendor == "Custom (Manual Input)":
913
+ return (gr.update(visible=True),
914
+ gr.update(visible=False, choices=[]),
915
+ gr.update(visible=False, choices=[]),
916
+ "", gr.update())
917
+ elif vendor == "CPU Only":
918
+ return (gr.update(visible=False),
919
+ gr.update(visible=False, choices=[]),
920
+ gr.update(visible=False, choices=[]),
921
+ "", 0)
922
+ elif vendor == "NVIDIA Consumer (GeForce RTX)":
923
+ return (gr.update(visible=False),
924
+ gr.update(visible=True, choices=["RTX 50 Series", "RTX 40 Series", "RTX 30 Series"]),
925
+ gr.update(visible=False, choices=[]),
926
+ "", gr.update())
927
+ elif vendor == "NVIDIA Professional (RTX A-Series)":
928
+ return (gr.update(visible=False),
929
+ gr.update(visible=True, choices=["RTX A6000 Series", "RTX A5000 Series", "RTX A4000 Series"]),
930
+ gr.update(visible=False, choices=[]),
931
+ "", gr.update())
932
+ elif vendor == "NVIDIA Data Center":
933
+ return (gr.update(visible=False),
934
+ gr.update(visible=True, choices=["Blackwell (B-Series)", "Hopper (H-Series)", "Ada Lovelace (L-Series)", "Ampere (A-Series)", "Volta/Tesla"]),
935
+ gr.update(visible=False, choices=[]),
936
+ "", gr.update())
937
+ elif vendor == "Apple Silicon":
938
+ return (gr.update(visible=False),
939
+ gr.update(visible=True, choices=["M4 Series", "M3 Series", "M2 Series", "M1 Series"]),
940
+ gr.update(visible=False, choices=[]),
941
+ "", gr.update())
942
+ elif vendor == "AMD":
943
+ return (gr.update(visible=False),
944
+ gr.update(visible=True, choices=["Radeon RX 7000", "Radeon RX 6000", "Instinct MI Series"]),
945
+ gr.update(visible=False, choices=[]),
946
+ "", gr.update())
947
+ elif vendor == "Intel":
948
+ return (gr.update(visible=False),
949
+ gr.update(visible=True, choices=["Arc A-Series"]),
950
+ gr.update(visible=False, choices=[]),
951
+ "", gr.update())
952
+ else:
953
+ return (gr.update(visible=True),
954
+ gr.update(visible=False, choices=[]),
955
+ gr.update(visible=False, choices=[]),
956
+ "", gr.update())
957
+
958
+ def on_gpu_series_change(vendor, series):
959
+ """Handle GPU series selection and update model dropdown."""
960
+ models = []
961
+
962
+ if vendor == "NVIDIA Consumer (GeForce RTX)":
963
+ if series == "RTX 50 Series":
964
+ models = ["RTX 5090 (32GB)", "RTX 5080 (16GB)", "RTX 5070 Ti (16GB)", "RTX 5070 (12GB)", "RTX 5060 Ti (16GB)", "RTX 5060 (12GB)"]
965
+ elif series == "RTX 40 Series":
966
+ 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)"]
967
+ elif series == "RTX 30 Series":
968
+ 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)"]
969
+
970
+ elif vendor == "NVIDIA Professional (RTX A-Series)":
971
+ if series == "RTX A6000 Series":
972
+ models = ["RTX A6000 (48GB)", "RTX A6000 Ada (48GB)", "RTX 6000 Ada (48GB)"]
973
+ elif series == "RTX A5000 Series":
974
+ models = ["RTX A5000 (24GB)", "RTX A5500 (24GB)", "RTX 5000 Ada (32GB)"]
975
+ elif series == "RTX A4000 Series":
976
+ models = ["RTX A4000 (16GB)", "RTX A4500 (20GB)", "RTX 4000 Ada (20GB)", "RTX 4000 SFF Ada (20GB)"]
977
+
978
+ elif vendor == "NVIDIA Data Center":
979
+ if series == "Blackwell (B-Series)":
980
+ models = ["B200 (192GB)", "B100 (192GB)", "GB200 NVL72 (192GB per GPU)"]
981
+ elif series == "Hopper (H-Series)":
982
+ models = ["H200 (141GB)", "H100 SXM (80GB)", "H100 PCIe (80GB)"]
983
+ elif series == "Ada Lovelace (L-Series)":
984
+ models = ["L40S (48GB)", "L40 (48GB)", "L4 (24GB)"]
985
+ elif series == "Ampere (A-Series)":
986
+ models = ["A100 SXM (80GB)", "A100 PCIe (80GB)", "A100 PCIe (40GB)", "A40 (48GB)", "A30 (24GB)", "A16 (16GB)", "A10 (24GB)"]
987
+ elif series == "Volta/Tesla":
988
+ models = ["V100 SXM2 (32GB)", "V100 PCIe (16GB)", "P100 (16GB)"]
989
+
990
+ elif vendor == "Apple Silicon":
991
+ if series == "M4 Series":
992
+ models = ["M4 Max (128GB Unified)", "M4 Pro (64GB Unified)", "M4 (32GB Unified)"]
993
+ elif series == "M3 Series":
994
+ models = ["M3 Ultra (192GB Unified)", "M3 Max (128GB Unified)", "M3 Pro (36GB Unified)", "M3 (24GB Unified)"]
995
+ elif series == "M2 Series":
996
+ models = ["M2 Ultra (192GB Unified)", "M2 Max (96GB Unified)", "M2 Pro (32GB Unified)", "M2 (24GB Unified)"]
997
+ elif series == "M1 Series":
998
+ models = ["M1 Ultra (128GB Unified)", "M1 Max (64GB Unified)", "M1 Pro (32GB Unified)", "M1 (16GB Unified)"]
999
+
1000
+ elif vendor == "AMD":
1001
+ if series == "Radeon RX 7000":
1002
+ models = ["RX 7900 XTX (24GB)", "RX 7900 XT (20GB)"]
1003
+ elif series == "Radeon RX 6000":
1004
+ models = ["RX 6900 XT (16GB)"]
1005
+ elif series == "Instinct MI Series":
1006
+ models = ["Instinct MI300X (192GB)", "Instinct MI250X (128GB)", "Instinct MI100 (32GB)"]
1007
+
1008
+ elif vendor == "Intel":
1009
+ if series == "Arc A-Series":
1010
+ models = ["Arc A770 (16GB)", "Arc A750 (8GB)"]
1011
+
1012
+ return gr.update(visible=True, choices=models)
1013
+
1014
+ def on_gpu_model_change(model):
1015
+ """Handle GPU model selection and auto-fill values."""
1016
+ if not model or model == "":
1017
+ return "", gr.update()
1018
+
1019
+ # Extract GPU name and VRAM from model
1020
+ if "(" in model and "GB" in model:
1021
+ gpu_name_part = model.split(" (")[0]
1022
+ vram_part = model.split("(")[1].split("GB")[0]
1023
+ try:
1024
+ vram_value = int(vram_part)
1025
+ except:
1026
+ vram_value = 8
1027
+ return gpu_name_part, vram_value
1028
+ else:
1029
+ return model, gr.update()
1030
+
1031
+ def get_final_gpu_name(vendor, series, model, custom_name):
1032
+ """Get the final GPU name based on vendor selection or custom input."""
1033
+ if vendor == "Custom (Manual Input)":
1034
+ return custom_name
1035
+ elif vendor == "CPU Only":
1036
+ return ""
1037
+ elif model and "(" in model and "GB" in model:
1038
+ return model.split(" (")[0]
1039
+ elif model:
1040
+ return model
1041
+ else:
1042
+ return custom_name
1043
+
1044
+ def update_memory_analysis(model_name, vram_gb):
1045
+ """Update memory analysis in real-time based on selections."""
1046
+ if not model_name or not model_name.strip():
1047
+ return "Select a model to see memory requirements."
1048
+
1049
+ if not vram_gb or vram_gb <= 0:
1050
+ return f"**Model:** {model_name}\n\nConfigure your GPU to see memory analysis."
1051
+
1052
+ try:
1053
+ memory_info, recommendations, formatted_info = app.analyze_model_memory(model_name, vram_gb)
1054
+ return formatted_info
1055
+ except Exception as e:
1056
+ # Enhanced error reporting with full traceback
1057
+ import traceback
1058
+ error_details = traceback.format_exc()
1059
+ print(f"Memory analysis error for {model_name}: {error_details}")
1060
+
1061
+ # More specific error messages
1062
+ error_msg = str(e)
1063
+ if "Too many arguments" in error_msg:
1064
+ 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."
1065
+ elif "404" in error_msg or "not found" in error_msg.lower():
1066
+ 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')."
1067
+ elif "403" in error_msg or "private" in error_msg.lower():
1068
+ 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."
1069
+ elif "timeout" in error_msg.lower():
1070
+ 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."
1071
+ else:
1072
+ 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```"
1073
+
1074
+ return detailed_error
1075
+
1076
+ # Connect GPU dropdown change handlers with memory analysis updates
1077
+ gpu_vendor.change(
1078
+ on_gpu_vendor_change,
1079
+ inputs=[gpu_vendor],
1080
+ outputs=[gpu_name_custom, gpu_series, gpu_model, gpu_name, vram_gb]
1081
+ ).then(
1082
+ update_memory_analysis,
1083
+ inputs=[model_name, vram_gb],
1084
+ outputs=memory_analysis_output
1085
+ )
1086
+
1087
+ gpu_series.change(
1088
+ on_gpu_series_change,
1089
+ inputs=[gpu_vendor, gpu_series],
1090
+ outputs=[gpu_model]
1091
+ )
1092
+
1093
+ gpu_model.change(
1094
+ on_gpu_model_change,
1095
+ inputs=[gpu_model],
1096
+ outputs=[gpu_name, vram_gb]
1097
+ ).then(
1098
+ update_memory_analysis,
1099
+ inputs=[model_name, vram_gb],
1100
+ outputs=memory_analysis_output
1101
+ )
1102
+
1103
+ # Update memory analysis when custom GPU name changes
1104
+ gpu_name_custom.change(
1105
+ update_memory_analysis,
1106
+ inputs=[model_name, vram_gb],
1107
+ outputs=memory_analysis_output
1108
+ )
1109
+
1110
+ # Update memory analysis when model name or VRAM changes
1111
+ model_name.change(
1112
+ update_memory_analysis,
1113
+ inputs=[model_name, vram_gb],
1114
+ outputs=memory_analysis_output
1115
+ )
1116
+
1117
+ vram_gb.change(
1118
+ update_memory_analysis,
1119
+ inputs=[model_name, vram_gb],
1120
+ outputs=memory_analysis_output
1121
+ )
1122
+
1123
+ # Load initial memory analysis on startup
1124
+ interface.load(
1125
+ update_memory_analysis,
1126
+ inputs=[model_name, vram_gb],
1127
+ outputs=memory_analysis_output
1128
+ )
1129
+
1130
+ def create_code_summary(generated_code, model_name, final_gpu_name, vram_gb):
1131
+ """Create a concise summary of the generated code."""
1132
+ if generated_code.startswith("Error"):
1133
+ return "❌ **Code Generation Failed** - See error details in the code output below."
1134
+
1135
+ # Analyze the generated code to extract key optimizations
1136
+ optimizations = []
1137
+ if "torch.float16" in generated_code or "fp16" in generated_code.lower():
1138
+ optimizations.append("FP16 precision")
1139
+ if "torch.bfloat16" in generated_code or "bf16" in generated_code.lower():
1140
+ optimizations.append("BF16 precision")
1141
+ if "enable_model_cpu_offload" in generated_code:
1142
+ optimizations.append("CPU offloading")
1143
+ if "enable_sequential_cpu_offload" in generated_code:
1144
+ optimizations.append("Sequential CPU offload")
1145
+ if "low_cpu_mem_usage=True" in generated_code:
1146
+ optimizations.append("Low CPU memory usage")
1147
+ if "torch.compile" in generated_code:
1148
+ optimizations.append("Torch compile")
1149
+ if "attention_slicing" in generated_code:
1150
+ optimizations.append("Attention slicing")
1151
+ if "vae_slicing" in generated_code:
1152
+ optimizations.append("VAE slicing")
1153
+
1154
+ device = "CUDA" if "cuda" in generated_code else "MPS" if "mps" in generated_code else "CPU"
1155
+
1156
+ summary = f"""
1157
+ ### ✅ Code Generated Successfully
1158
+
1159
+ **Model:** `{model_name}`
1160
+ **Hardware:** {final_gpu_name} ({vram_gb}GB) - {device}
1161
+ **Optimizations:** {', '.join(optimizations) if optimizations else 'Standard configuration'}
1162
+
1163
+ **Key Features:**
1164
+ - Memory-optimized pipeline loading
1165
+ - Hardware-specific device configuration
1166
+ - Performance tuning for your GPU
1167
+ - Ready-to-run diffusion code
1168
+ """
1169
+ return summary
1170
+
1171
+ def strip_comments(code):
1172
+ """Remove all comments from the code for collapsed view."""
1173
+ if not code:
1174
+ return code
1175
+
1176
+ lines = code.split('\n')
1177
+ filtered_lines = []
1178
+
1179
+ for line in lines:
1180
+ stripped = line.strip()
1181
+ # Skip comment-only lines and empty lines
1182
+ if stripped.startswith('#') or stripped == '':
1183
+ continue
1184
+ # For lines with inline comments, keep only the code part
1185
+ if '#' in line and not stripped.startswith('#'):
1186
+ code_part = line.split('#')[0].rstrip()
1187
+ if code_part.strip(): # Only add if there's actual code
1188
+ filtered_lines.append(code_part)
1189
+ else:
1190
+ filtered_lines.append(line)
1191
+
1192
+ return '\n'.join(filtered_lines)
1193
+
1194
+ 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):
1195
+ """Generate code with the correct GPU name from multi-level selection or custom input, including memory analysis."""
1196
+ final_gpu_name = get_final_gpu_name(gpu_vendor, gpu_series, gpu_model, gpu_name_custom)
1197
+
1198
+ # Constant prompt text
1199
+ prompt_text = "A cat holding a sign that says hello world"
1200
+
1201
+ # STEP 1: Perform memory analysis BEFORE code generation
1202
+ memory_analysis_data = None
1203
+ memory_header = ""
1204
+
1205
+ try:
1206
+ if model_name and vram_gb and vram_gb > 0:
1207
+ memory_info, recommendations, _ = app.analyze_model_memory(model_name, vram_gb)
1208
+
1209
+ # Package memory analysis for Gemini API
1210
+ memory_analysis_data = {
1211
+ 'memory_info': memory_info,
1212
+ 'recommendations': recommendations
1213
+ }
1214
+
1215
+ # Create header for the generated code
1216
+ def get_optimization_strategy(recommendations):
1217
+ """Generate optimization strategy text based on recommendations."""
1218
+ strategies = []
1219
+
1220
+ if recommendations.get('cpu_offload'):
1221
+ strategies.append("CPU offloading")
1222
+ if recommendations.get('sequential_offload'):
1223
+ strategies.append("Sequential CPU offload")
1224
+ if recommendations.get('attention_slicing'):
1225
+ strategies.append("Attention slicing")
1226
+ if recommendations.get('vae_slicing'):
1227
+ strategies.append("VAE slicing")
1228
+
1229
+ precision = recommendations.get('recommended_precision', 'float16')
1230
+ if precision:
1231
+ strategies.append(f"{precision} precision")
1232
+
1233
+ if not strategies:
1234
+ # No special optimizations needed
1235
+ if recommendations.get('recommendations') and any('Full model can fit' in rec for rec in recommendations.get('recommendations', [])):
1236
+ return "Full VRAM utilization with optimal performance"
1237
+ else:
1238
+ return "Standard optimization"
1239
+
1240
+ return ", ".join(strategies)
1241
+
1242
+ optimization_strategy = get_optimization_strategy(recommendations)
1243
+
1244
+ memory_header = f"""# Memory Analysis for {model_name}:
1245
+ # GPU: {final_gpu_name if final_gpu_name else 'Not specified'} ({vram_gb}GB VRAM)
1246
+ # Model Memory Requirements: {memory_info.get('estimated_inference_memory_fp16_gb', 'Unknown')} GB
1247
+ # Recommendation: {', '.join(recommendations.get('recommendations', ['N/A']))}
1248
+ # Optimization Strategy: {optimization_strategy}
1249
+
1250
+ """
1251
+ except Exception as e:
1252
+ memory_header = f"""# Memory Analysis for {model_name}:
1253
+ # GPU: {final_gpu_name if final_gpu_name else 'Not specified'} ({vram_gb}GB VRAM)
1254
+ # Note: Memory analysis failed - {str(e)}
1255
+
1256
+ """
1257
+
1258
+ # STEP 2: Generate the optimized code WITH memory analysis information
1259
+ generated_code = app.generate_code_with_manual_specs(
1260
+ final_gpu_name, vram_gb, ram_gb, platform,
1261
+ model_name, prompt_text, dtype_selection, width, height, inference_steps,
1262
+ memory_analysis_data
1263
+ )
1264
+
1265
+ # STEP 3: Prepend memory analysis header to the generated code
1266
+ final_code = memory_header + generated_code if memory_header and not generated_code.startswith("Error") else generated_code
1267
+
1268
+ # STEP 4: Create code summary
1269
+ summary = create_code_summary(generated_code, model_name, final_gpu_name, vram_gb)
1270
+
1271
+ return summary, final_code
1272
+
1273
+ # Add states for tracking code view and storing full code
1274
+ code_collapsed = gr.State(value=False)
1275
+ full_code_storage = gr.State(value="")
1276
+
1277
+ 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):
1278
+ """Generate code and return summary, code for display, and full code for storage."""
1279
+ summary, full_code = generate_with_combined_gpu_name(
1280
+ gpu_vendor, gpu_series, gpu_model, gpu_name_custom, vram_gb, ram_gb, platform,
1281
+ model_name, dtype_selection, width, height, inference_steps
1282
+ )
1283
+ return summary, full_code, full_code, False # summary, display_code, stored_code, reset_collapsed_state
1284
+
1285
+ generate_btn.click(
1286
+ generate_and_store_code,
1287
+ inputs=[
1288
+ gpu_vendor, gpu_series, gpu_model, gpu_name_custom, vram_gb, ram_gb, platform,
1289
+ model_name, dtype_selection, width, height, inference_steps
1290
+ ],
1291
+ outputs=[code_summary, code_output, full_code_storage, code_collapsed]
1292
+ )
1293
+
1294
+
1295
+
1296
+ # Ultra Premium Footer
1297
+ gr.HTML("""
1298
+ <div class="ultra-glass" style="text-align: center; padding: 3rem 2rem; margin-top: 4rem; position: relative; overflow: hidden;">
1299
+ <div style="position: relative; z-index: 2;">
1300
+ <h4 style="color: #1e293b; font-size: 1.3rem; margin: 0 0 1rem 0; font-weight: 700;">
1301
+ ✨ Pro Tips & Insights
1302
+ </h4>
1303
+ <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;">
1304
+ 🚀 The generated code includes hardware-specific optimizations for memory efficiency and peak performance<br>
1305
+ 🎯 Fine-tuned for your exact GPU configuration and model requirements
1306
+ </p>
1307
+ <div style="margin-top: 2rem;">
1308
+ <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;">
1309
+ 🤖 Powered by Google Gemini 2.5
1310
+ </span>
1311
+ <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;">
1312
+ ❤️ Built for the Community
1313
+ </span>
1314
+ </div>
1315
+ </div>
1316
+ </div>
1317
+ """)
1318
+
1319
+ return interface
1320
+
1321
+ def main():
1322
+ """Launch the Gradio application."""
1323
+ try:
1324
+ interface = create_gradio_interface()
1325
+ interface.launch(
1326
+ server_name="0.0.0.0",
1327
+ server_port=7860,
1328
+ share=True,
1329
+ show_error=True
1330
+ )
1331
+ except Exception as e:
1332
+ print(f"Error launching Gradio app: {e}")
1333
+ print("Make sure you have set GOOGLE_API_KEY in your .env file")
1334
+
1335
+ if __name__ == "__main__":
1336
+ main()
hardware_detector.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import platform
2
+ import subprocess
3
+ import os
4
+ from typing import Dict, Optional
5
+
6
+
7
+ class HardwareDetector:
8
+ def __init__(self):
9
+ self.specs = self._detect_system_specs()
10
+
11
+ def _detect_system_specs(self) -> Dict:
12
+ """Detect system hardware specifications automatically."""
13
+ specs = {
14
+ 'platform': platform.system(),
15
+ 'architecture': platform.machine(),
16
+ 'cpu_count': os.cpu_count(),
17
+ 'python_version': platform.python_version(),
18
+ 'gpu_info': self._detect_gpu(),
19
+ 'cuda_available': False,
20
+ 'mps_available': False
21
+ }
22
+
23
+ # Check for PyTorch and device availability
24
+ try:
25
+ import torch
26
+ specs['torch_version'] = torch.__version__
27
+ specs['cuda_available'] = torch.cuda.is_available()
28
+ specs['mps_available'] = torch.backends.mps.is_available()
29
+
30
+ if specs['cuda_available']:
31
+ specs['cuda_device_count'] = torch.cuda.device_count()
32
+ specs['cuda_device_name'] = torch.cuda.get_device_name(0)
33
+ specs['cuda_memory'] = torch.cuda.get_device_properties(0).total_memory // (1024**3)
34
+
35
+ except ImportError:
36
+ specs['torch_version'] = 'Not installed'
37
+
38
+ return specs
39
+
40
+ def _detect_gpu(self) -> Optional[Dict]:
41
+ """Attempt to detect GPU information using nvidia-smi."""
42
+ try:
43
+ result = subprocess.run([
44
+ 'nvidia-smi',
45
+ '--query-gpu=name,memory.total',
46
+ '--format=csv,noheader,nounits'
47
+ ], capture_output=True, text=True, check=True)
48
+
49
+ lines = result.stdout.strip().split('\n')
50
+ gpus = []
51
+ for line in lines:
52
+ if line.strip():
53
+ name, memory = line.split(', ')
54
+ gpus.append({'name': name.strip(), 'memory_mb': int(memory)})
55
+ return gpus
56
+
57
+ except (subprocess.CalledProcessError, FileNotFoundError):
58
+ return None
59
+
60
+ def get_manual_input(self) -> Dict:
61
+ """Get hardware specifications via manual user input."""
62
+ print("Enter your hardware specifications manually:")
63
+
64
+ gpu_name = input("GPU Name (e.g., RTX 4090, A100, leave empty if none): ").strip()
65
+ if gpu_name:
66
+ try:
67
+ vram_gb = int(input("VRAM in GB (e.g., 24): "))
68
+ gpu_info = [{'name': gpu_name, 'memory_mb': vram_gb * 1024}]
69
+ except ValueError:
70
+ gpu_info = None
71
+ else:
72
+ gpu_info = None
73
+
74
+ try:
75
+ ram_gb = int(input("System RAM in GB (e.g., 32): "))
76
+ except ValueError:
77
+ ram_gb = 16 # Default
78
+
79
+ specs = self.specs.copy()
80
+ specs['gpu_info'] = gpu_info
81
+ specs['ram_gb'] = ram_gb
82
+ specs['manual_input'] = True
83
+
84
+ return specs
85
+
86
+ def get_optimization_profile(self) -> str:
87
+ """Determine the best optimization profile based on hardware."""
88
+ if self.specs['cuda_available']:
89
+ if self.specs.get('cuda_memory', 0) >= 20:
90
+ return 'high_end_gpu'
91
+ elif self.specs.get('cuda_memory', 0) >= 8:
92
+ return 'mid_range_gpu'
93
+ else:
94
+ return 'low_vram_gpu'
95
+ elif self.specs['mps_available']:
96
+ return 'apple_silicon'
97
+ else:
98
+ return 'cpu_only'
99
+
100
+ def print_specs(self):
101
+ """Print detected hardware specifications."""
102
+ print(f"Platform: {self.specs['platform']} ({self.specs['architecture']})")
103
+ print(f"CPU Cores: {self.specs['cpu_count']}")
104
+ print(f"Python: {self.specs['python_version']}")
105
+ print(f"PyTorch: {self.specs.get('torch_version', 'Not detected')}")
106
+ print(f"CUDA Available: {self.specs['cuda_available']}")
107
+ print(f"MPS Available: {self.specs['mps_available']}")
108
+
109
+ if self.specs['gpu_info']:
110
+ print("GPU Information:")
111
+ for i, gpu in enumerate(self.specs['gpu_info']):
112
+ vram_gb = gpu['memory_mb'] / 1024
113
+ print(f" GPU {i}: {gpu['name']} ({vram_gb:.1f} GB VRAM)")
114
+ else:
115
+ print("No GPU detected")
116
+
117
+
118
+ if __name__ == "__main__":
119
+ detector = HardwareDetector()
120
+
121
+ print("=== Auto-detected Hardware ===")
122
+ detector.print_specs()
123
+
124
+ choice = input("\nUse auto-detected specs? (y/n): ").lower()
125
+ if choice != 'y':
126
+ specs = detector.get_manual_input()
127
+ detector.specs = specs
128
+ print("\n=== Final Hardware Specs ===")
129
+ detector.print_specs()
130
+
131
+ print(f"\nRecommended optimization profile: {detector.get_optimization_profile()}")
launch_gradio.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple launcher script for the Gradio app with better error handling.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ from dotenv import load_dotenv
9
+
10
+ # Load environment variables
11
+ load_dotenv()
12
+
13
+ def check_requirements():
14
+ """Check if all required packages are installed."""
15
+ required_packages = [
16
+ 'gradio', 'google.generativeai', 'torch', 'psutil'
17
+ ]
18
+
19
+ missing = []
20
+ for package in required_packages:
21
+ try:
22
+ __import__(package.replace('-', '_'))
23
+ except ImportError:
24
+ missing.append(package)
25
+
26
+ if missing:
27
+ print(f"Missing packages: {', '.join(missing)}")
28
+ print("Please run: pip install -r requirements.txt")
29
+ return False
30
+ return True
31
+
32
+ def check_api_key():
33
+ """Check if API key is configured."""
34
+ api_key = os.getenv('GOOGLE_API_KEY')
35
+ if not api_key:
36
+ print("ERROR: GOOGLE_API_KEY not found in .env file")
37
+ print("Please add your Gemini API key to the .env file:")
38
+ print("GOOGLE_API_KEY=your_api_key_here")
39
+ return False
40
+ return True
41
+
42
+ def main():
43
+ print("🚀 Starting Auto-Diffusers Gradio App...")
44
+
45
+ # Check requirements
46
+ if not check_requirements():
47
+ sys.exit(1)
48
+
49
+ if not check_api_key():
50
+ sys.exit(1)
51
+
52
+ try:
53
+ from gradio_app import create_gradio_interface
54
+
55
+ print("✅ All requirements satisfied")
56
+ print("🌐 Launching Gradio interface...")
57
+
58
+ interface = create_gradio_interface()
59
+ interface.launch(
60
+ server_name="0.0.0.0",
61
+ server_port=7860,
62
+ share=True,
63
+ show_error=True,
64
+ inbrowser=True
65
+ )
66
+
67
+ except ImportError as e:
68
+ print(f"Import error: {e}")
69
+ print("Make sure all dependencies are installed: pip install -r requirements.txt")
70
+ except Exception as e:
71
+ print(f"Error launching app: {e}")
72
+
73
+ if __name__ == "__main__":
74
+ main()
model_memory_calculator.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from huggingface_hub import HfApi
3
+ from typing import Dict, Optional, Tuple
4
+ import json
5
+
6
+
7
+ class ModelMemoryCalculator:
8
+ def __init__(self):
9
+ self.hf_api = HfApi()
10
+ self.cache = {} # Cache results to avoid repeated API calls
11
+
12
+ def get_model_memory_requirements(self, model_id: str) -> Dict:
13
+ """
14
+ Calculate memory requirements for a given HuggingFace model.
15
+
16
+ Args:
17
+ model_id: HuggingFace model identifier (e.g., "black-forest-labs/FLUX.1-schnell")
18
+
19
+ Returns:
20
+ Dict with memory information including:
21
+ - total_params: Total parameter count
22
+ - memory_fp32: Memory in GB at FP32 precision
23
+ - memory_fp16: Memory in GB at FP16 precision
24
+ - memory_bf16: Memory in GB at BF16 precision
25
+ - safetensors_files: List of safetensor files and their sizes
26
+ """
27
+
28
+ if model_id in self.cache:
29
+ return self.cache[model_id]
30
+
31
+ try:
32
+ print(f"Fetching model info for {model_id}...")
33
+
34
+ # Get model info
35
+ model_info = self.hf_api.model_info(model_id)
36
+ print(f"Model info retrieved successfully")
37
+
38
+ # Get safetensors metadata
39
+ print(f"Fetching safetensors metadata...")
40
+ safetensors_metadata = self.hf_api.get_safetensors_metadata(model_id)
41
+ print(f"Found {len(safetensors_metadata)} safetensor files")
42
+
43
+ total_params = 0
44
+ safetensors_files = []
45
+
46
+ # Iterate through all safetensor files
47
+ for filename, metadata in safetensors_metadata.items():
48
+ file_params = 0
49
+ file_size_bytes = 0
50
+
51
+ # Calculate parameters from tensor metadata
52
+ if 'metadata' in metadata and metadata['metadata']:
53
+ for tensor_name, tensor_info in metadata['metadata'].items():
54
+ if 'shape' in tensor_info and 'dtype' in tensor_info:
55
+ # Calculate tensor size
56
+ shape = tensor_info['shape']
57
+ tensor_params = 1
58
+ for dim in shape:
59
+ tensor_params *= dim
60
+ file_params += tensor_params
61
+
62
+ # Calculate byte size based on dtype
63
+ dtype = tensor_info['dtype']
64
+ bytes_per_param = self._get_bytes_per_param(dtype)
65
+ file_size_bytes += tensor_params * bytes_per_param
66
+
67
+ total_params += file_params
68
+ safetensors_files.append({
69
+ 'filename': filename,
70
+ 'parameters': file_params,
71
+ 'size_bytes': file_size_bytes,
72
+ 'size_mb': file_size_bytes / (1024 * 1024)
73
+ })
74
+
75
+ # Calculate memory requirements for different precisions
76
+ memory_requirements = {
77
+ 'model_id': model_id,
78
+ 'total_params': total_params,
79
+ 'total_params_billions': total_params / 1e9,
80
+ 'memory_fp32_gb': (total_params * 4) / (1024**3), # 4 bytes per param
81
+ 'memory_fp16_gb': (total_params * 2) / (1024**3), # 2 bytes per param
82
+ 'memory_bf16_gb': (total_params * 2) / (1024**3), # 2 bytes per param
83
+ 'memory_int8_gb': (total_params * 1) / (1024**3), # 1 byte per param
84
+ 'safetensors_files': safetensors_files,
85
+ 'estimated_inference_memory_fp16_gb': self._estimate_inference_memory(total_params, 'fp16'),
86
+ 'estimated_inference_memory_bf16_gb': self._estimate_inference_memory(total_params, 'bf16'),
87
+ }
88
+
89
+ # Cache the result
90
+ self.cache[model_id] = memory_requirements
91
+
92
+ return memory_requirements
93
+
94
+ except Exception as e:
95
+ return {
96
+ 'error': str(e),
97
+ 'model_id': model_id,
98
+ 'total_params': 0,
99
+ 'memory_fp32_gb': 0,
100
+ 'memory_fp16_gb': 0,
101
+ 'memory_bf16_gb': 0,
102
+ }
103
+
104
+ def _get_bytes_per_param(self, dtype: str) -> int:
105
+ """Get bytes per parameter for different data types."""
106
+ dtype_map = {
107
+ 'F32': 4, 'float32': 4,
108
+ 'F16': 2, 'float16': 2,
109
+ 'BF16': 2, 'bfloat16': 2,
110
+ 'I8': 1, 'int8': 1,
111
+ 'I32': 4, 'int32': 4,
112
+ 'I64': 8, 'int64': 8,
113
+ }
114
+ return dtype_map.get(dtype, 4) # Default to 4 bytes (FP32)
115
+
116
+ def _estimate_inference_memory(self, total_params: int, precision: str) -> float:
117
+ """
118
+ Estimate memory requirements during inference.
119
+ This includes model weights + activations + intermediate tensors.
120
+ """
121
+ bytes_per_param = 2 if precision in ['fp16', 'bf16'] else 4
122
+
123
+ # Model weights
124
+ model_memory = (total_params * bytes_per_param) / (1024**3)
125
+
126
+ # Estimate activation memory (rough approximation)
127
+ # For diffusion models, activations can be 1.5-3x model size during inference
128
+ activation_multiplier = 2.0
129
+
130
+ total_inference_memory = model_memory * (1 + activation_multiplier)
131
+
132
+ return total_inference_memory
133
+
134
+ def get_memory_recommendation(self, model_id: str, available_vram_gb: float) -> Dict:
135
+ """
136
+ Get memory recommendations based on available VRAM.
137
+
138
+ Args:
139
+ model_id: HuggingFace model identifier
140
+ available_vram_gb: Available VRAM in GB
141
+
142
+ Returns:
143
+ Dict with recommendations for precision, offloading, etc.
144
+ """
145
+ memory_info = self.get_model_memory_requirements(model_id)
146
+
147
+ if 'error' in memory_info:
148
+ return {'error': memory_info['error']}
149
+
150
+ recommendations = {
151
+ 'model_id': model_id,
152
+ 'available_vram_gb': available_vram_gb,
153
+ 'model_memory_fp16_gb': memory_info['memory_fp16_gb'],
154
+ 'estimated_inference_memory_fp16_gb': memory_info['estimated_inference_memory_fp16_gb'],
155
+ 'recommendations': []
156
+ }
157
+
158
+ inference_memory_fp16 = memory_info['estimated_inference_memory_fp16_gb']
159
+ inference_memory_bf16 = memory_info['estimated_inference_memory_bf16_gb']
160
+
161
+ # Determine recommendations
162
+ if available_vram_gb >= inference_memory_bf16:
163
+ recommendations['recommendations'].append("✅ Full model can fit in VRAM with BF16 precision")
164
+ recommendations['recommended_precision'] = 'bfloat16'
165
+ recommendations['cpu_offload'] = False
166
+ recommendations['attention_slicing'] = False
167
+
168
+ elif available_vram_gb >= inference_memory_fp16:
169
+ recommendations['recommendations'].append("✅ Full model can fit in VRAM with FP16 precision")
170
+ recommendations['recommended_precision'] = 'float16'
171
+ recommendations['cpu_offload'] = False
172
+ recommendations['attention_slicing'] = False
173
+
174
+ elif available_vram_gb >= memory_info['memory_fp16_gb']:
175
+ recommendations['recommendations'].append("⚠️ Model weights fit, but may need memory optimizations")
176
+ recommendations['recommended_precision'] = 'float16'
177
+ recommendations['cpu_offload'] = False
178
+ recommendations['attention_slicing'] = True
179
+ recommendations['vae_slicing'] = True
180
+
181
+ else:
182
+ recommendations['recommendations'].append("🔄 Requires CPU offloading and memory optimizations")
183
+ recommendations['recommended_precision'] = 'float16'
184
+ recommendations['cpu_offload'] = True
185
+ recommendations['sequential_offload'] = True
186
+ recommendations['attention_slicing'] = True
187
+ recommendations['vae_slicing'] = True
188
+
189
+ return recommendations
190
+
191
+ def format_memory_info(self, model_id: str) -> str:
192
+ """Format memory information for display."""
193
+ info = self.get_model_memory_requirements(model_id)
194
+
195
+ if 'error' in info:
196
+ return f"❌ Error calculating memory for {model_id}: {info['error']}"
197
+
198
+ output = f"""
199
+ 📊 **Memory Requirements for {model_id}**
200
+
201
+ 🔢 **Parameters**: {info['total_params_billions']:.2f}B parameters
202
+ 💾 **Model Memory**:
203
+ • FP32: {info['memory_fp32_gb']:.2f} GB
204
+ • FP16/BF16: {info['memory_fp16_gb']:.2f} GB
205
+ • INT8: {info['memory_int8_gb']:.2f} GB
206
+
207
+ 🚀 **Estimated Inference Memory**:
208
+ • FP16: {info['estimated_inference_memory_fp16_gb']:.2f} GB
209
+ • BF16: {info['estimated_inference_memory_bf16_gb']:.2f} GB
210
+
211
+ 📁 **SafeTensor Files**: {len(info['safetensors_files'])} files
212
+ """
213
+ return output.strip()
214
+
215
+
216
+ # Example usage and testing
217
+ if __name__ == "__main__":
218
+ calculator = ModelMemoryCalculator()
219
+
220
+ # Test with FLUX.1-schnell
221
+ model_id = "black-forest-labs/FLUX.1-schnell"
222
+ print(f"Testing memory calculation for {model_id}...")
223
+
224
+ memory_info = calculator.get_model_memory_requirements(model_id)
225
+ print(json.dumps(memory_info, indent=2))
226
+
227
+ # Test recommendations
228
+ print("\n" + "="*50)
229
+ print("MEMORY RECOMMENDATIONS")
230
+ print("="*50)
231
+
232
+ vram_options = [8, 16, 24, 40]
233
+ for vram in vram_options:
234
+ rec = calculator.get_memory_recommendation(model_id, vram)
235
+ print(f"\n🎯 For {vram}GB VRAM:")
236
+ if 'recommendations' in rec:
237
+ for r in rec['recommendations']:
238
+ print(f" {r}")
239
+
240
+ # Format for display
241
+ print("\n" + "="*50)
242
+ print("FORMATTED OUTPUT")
243
+ print("="*50)
244
+ print(calculator.format_memory_info(model_id))
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ google-generativeai>=0.8.0
2
+ diffusers>=0.30.0
3
+ torch>=2.0.0
4
+ transformers>=4.30.0
5
+ accelerate>=0.20.0
6
+ psutil>=5.9.0
7
+ gradio>=4.0.0
8
+ python-dotenv>=1.0.0
9
+ huggingface-hub>=0.20.0
sample_optimized_apple_silicon.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from diffusers import FluxPipeline
3
+
4
+ # Optimized for Apple Silicon (MPS) - 16 CPU cores, MPS available
5
+ # Memory-efficient configuration for Apple Silicon
6
+
7
+ # Load pipeline with bfloat16 for better MPS performance
8
+ pipe = FluxPipeline.from_pretrained(
9
+ "black-forest-labs/FLUX.1-schnell",
10
+ torch_dtype=torch.bfloat16,
11
+ use_safetensors=True
12
+ )
13
+
14
+ # Move to MPS device for GPU acceleration on Apple Silicon
15
+ pipe.to("mps")
16
+
17
+ # Apple Silicon optimizations
18
+ pipe.enable_attention_slicing() # Reduce memory usage
19
+ pipe.enable_vae_slicing() # VAE memory optimization
20
+
21
+ # Optional: Enable model CPU offload if memory is tight
22
+ # pipe.enable_model_cpu_offload()
23
+
24
+ # For Apple Silicon, compile the UNet for speed (if supported)
25
+ try:
26
+ pipe.unet = torch.compile(pipe.unet, mode="reduce-overhead", fullgraph=True)
27
+ except Exception:
28
+ print("Torch compile not supported, proceeding without compilation")
29
+
30
+ prompt = "A cat holding a sign that says hello world"
31
+
32
+ # Generate image with optimized settings for Apple Silicon
33
+ with torch.inference_mode():
34
+ out = pipe(
35
+ prompt=prompt,
36
+ guidance_scale=0.0, # FLUX.1-schnell works best with guidance_scale=0
37
+ height=768,
38
+ width=1360,
39
+ num_inference_steps=4, # FLUX.1-schnell is optimized for 4 steps
40
+ max_sequence_length=256, # Reduced for memory efficiency
41
+ generator=torch.Generator(device="mps").manual_seed(42) # Reproducible results
42
+ ).images[0]
43
+
44
+ # Save the generated image
45
+ out.save("image.png")
46
+
47
+ print("Image generated and saved as 'image.png'")
48
+ print("Optimizations applied: MPS device, bfloat16 precision, attention slicing, VAE slicing")
simple_memory_calculator.py ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import HfApi, hf_hub_download
2
+ from typing import Dict, Optional
3
+ import json
4
+ import os
5
+
6
+
7
+ class SimpleMemoryCalculator:
8
+ def __init__(self):
9
+ self.hf_api = HfApi()
10
+ self.cache = {}
11
+
12
+ # Known model memory requirements (in GB for FP16)
13
+ self.known_models = {
14
+ "black-forest-labs/FLUX.1-schnell": {
15
+ "params_billions": 12.0,
16
+ "fp16_gb": 24.0,
17
+ "inference_fp16_gb": 36.0
18
+ },
19
+ "black-forest-labs/FLUX.1-dev": {
20
+ "params_billions": 12.0,
21
+ "fp16_gb": 24.0,
22
+ "inference_fp16_gb": 36.0
23
+ },
24
+ "stabilityai/stable-diffusion-xl-base-1.0": {
25
+ "params_billions": 3.5,
26
+ "fp16_gb": 7.0,
27
+ "inference_fp16_gb": 12.0
28
+ },
29
+ "runwayml/stable-diffusion-v1-5": {
30
+ "params_billions": 0.86,
31
+ "fp16_gb": 1.7,
32
+ "inference_fp16_gb": 4.0
33
+ }
34
+ }
35
+
36
+ def get_model_memory_requirements(self, model_id: str) -> Dict:
37
+ """
38
+ Get memory requirements for a model, using known values or estimating from file sizes.
39
+ """
40
+ if model_id in self.cache:
41
+ return self.cache[model_id]
42
+
43
+ # Check if we have known values
44
+ if model_id in self.known_models:
45
+ known = self.known_models[model_id]
46
+ result = {
47
+ 'model_id': model_id,
48
+ 'total_params': int(known['params_billions'] * 1e9),
49
+ 'total_params_billions': known['params_billions'],
50
+ 'memory_fp32_gb': known['fp16_gb'] * 2,
51
+ 'memory_fp16_gb': known['fp16_gb'],
52
+ 'memory_bf16_gb': known['fp16_gb'],
53
+ 'memory_int8_gb': known['fp16_gb'] / 2,
54
+ 'estimated_inference_memory_fp16_gb': known['inference_fp16_gb'],
55
+ 'estimated_inference_memory_bf16_gb': known['inference_fp16_gb'],
56
+ 'source': 'known_values'
57
+ }
58
+ self.cache[model_id] = result
59
+ return result
60
+
61
+ # Try to estimate from HuggingFace API
62
+ try:
63
+ return self._estimate_from_api(model_id)
64
+ except Exception as e:
65
+ # Fallback to generic estimation
66
+ return self._generic_estimation(model_id, str(e))
67
+
68
+ def _estimate_from_api(self, model_id: str) -> Dict:
69
+ """Estimate memory from HuggingFace model info."""
70
+ try:
71
+ print(f"Fetching model info for: {model_id}")
72
+ model_info = self.hf_api.model_info(model_id)
73
+ print(f"Successfully fetched model info for: {model_id}")
74
+
75
+ # Get file sizes from model repo
76
+ total_size_bytes = 0
77
+ safetensor_files = []
78
+ files_without_size = 0
79
+
80
+ for sibling in model_info.siblings:
81
+ if sibling.rfilename.endswith('.safetensors'):
82
+ file_size_bytes = sibling.size
83
+ if file_size_bytes is None or file_size_bytes == 0:
84
+ files_without_size += 1
85
+ print(f"Warning: No size info for {sibling.rfilename}")
86
+ # Try to estimate based on typical safetensor file sizes
87
+ if 'unet' in sibling.rfilename.lower():
88
+ file_size_bytes = 3_400_000_000 # ~3.4GB typical for UNet
89
+ elif 'text_encoder' in sibling.rfilename.lower():
90
+ file_size_bytes = 500_000_000 # ~500MB typical for text encoder
91
+ elif 'vae' in sibling.rfilename.lower():
92
+ file_size_bytes = 160_000_000 # ~160MB typical for VAE
93
+ else:
94
+ file_size_bytes = 500_000_000 # Default fallback
95
+ print(f" → Using estimated size: {file_size_bytes / (1024**3):.2f} GB")
96
+ else:
97
+ print(f"File {sibling.rfilename}: {file_size_bytes / (1024**3):.2f} GB")
98
+
99
+ size_mb = file_size_bytes / (1024 * 1024)
100
+ safetensor_files.append({
101
+ 'filename': sibling.rfilename,
102
+ 'size_mb': size_mb,
103
+ 'estimated': file_size_bytes != sibling.size
104
+ })
105
+ total_size_bytes += file_size_bytes
106
+
107
+ print(f"Found {len(safetensor_files)} safetensor files, total size: {total_size_bytes / (1024**3):.2f} GB")
108
+ if files_without_size > 0:
109
+ print(f"Warning: {files_without_size} files had no size info, used estimates")
110
+
111
+ # Estimate parameters from file size (assuming FP16)
112
+ total_size_gb = total_size_bytes / (1024**3)
113
+ estimated_params = int((total_size_bytes / 2)) # 2 bytes per param for FP16
114
+ estimated_params_billions = estimated_params / 1e9
115
+
116
+ # Estimate inference memory (model + activations)
117
+ inference_multiplier = 1.5 # Conservative estimate
118
+ estimated_inference_memory = total_size_gb * inference_multiplier
119
+
120
+ result = {
121
+ 'model_id': model_id,
122
+ 'total_params': estimated_params,
123
+ 'total_params_billions': estimated_params_billions,
124
+ 'memory_fp32_gb': total_size_gb * 2,
125
+ 'memory_fp16_gb': total_size_gb,
126
+ 'memory_bf16_gb': total_size_gb,
127
+ 'memory_int8_gb': total_size_gb / 2,
128
+ 'estimated_inference_memory_fp16_gb': estimated_inference_memory,
129
+ 'estimated_inference_memory_bf16_gb': estimated_inference_memory,
130
+ 'safetensors_files': safetensor_files,
131
+ 'files_without_size': files_without_size,
132
+ 'source': 'api_estimation'
133
+ }
134
+
135
+ self.cache[model_id] = result
136
+ return result
137
+
138
+ except Exception as api_error:
139
+ print(f"API Error for model {model_id}: {type(api_error).__name__}: {str(api_error)}")
140
+ # Re-raise with more context
141
+ raise Exception(f"HuggingFace API Error: {type(api_error).__name__}: {str(api_error)}")
142
+
143
+ def _generic_estimation(self, model_id: str, error_msg: str) -> Dict:
144
+ """Generic fallback estimation."""
145
+ # Default to medium-sized model estimates
146
+ default_params_billions = 3.0
147
+ default_fp16_gb = 6.0
148
+
149
+ return {
150
+ 'model_id': model_id,
151
+ 'total_params': int(default_params_billions * 1e9),
152
+ 'total_params_billions': default_params_billions,
153
+ 'memory_fp32_gb': default_fp16_gb * 2,
154
+ 'memory_fp16_gb': default_fp16_gb,
155
+ 'memory_bf16_gb': default_fp16_gb,
156
+ 'memory_int8_gb': default_fp16_gb / 2,
157
+ 'estimated_inference_memory_fp16_gb': default_fp16_gb * 1.5,
158
+ 'estimated_inference_memory_bf16_gb': default_fp16_gb * 1.5,
159
+ 'source': 'generic_fallback',
160
+ 'error': error_msg
161
+ }
162
+
163
+ def get_memory_recommendation(self, model_id: str, available_vram_gb: float) -> Dict:
164
+ """Get memory recommendations based on available VRAM."""
165
+ memory_info = self.get_model_memory_requirements(model_id)
166
+
167
+ recommendations = {
168
+ 'model_id': model_id,
169
+ 'available_vram_gb': available_vram_gb,
170
+ 'model_memory_fp16_gb': memory_info['memory_fp16_gb'],
171
+ 'estimated_inference_memory_fp16_gb': memory_info['estimated_inference_memory_fp16_gb'],
172
+ 'recommendations': []
173
+ }
174
+
175
+ inference_memory_fp16 = memory_info['estimated_inference_memory_fp16_gb']
176
+ model_memory_fp16 = memory_info['memory_fp16_gb']
177
+
178
+ # Determine recommendations
179
+ if available_vram_gb >= inference_memory_fp16:
180
+ recommendations['recommendations'].append("✅ Full model can fit in VRAM")
181
+ recommendations['recommended_precision'] = 'float16'
182
+ recommendations['cpu_offload'] = False
183
+ recommendations['attention_slicing'] = False
184
+
185
+ elif available_vram_gb >= model_memory_fp16:
186
+ recommendations['recommendations'].append("⚠️ Model weights fit, enable memory optimizations")
187
+ recommendations['recommended_precision'] = 'float16'
188
+ recommendations['cpu_offload'] = False
189
+ recommendations['attention_slicing'] = True
190
+ recommendations['vae_slicing'] = True
191
+
192
+ elif available_vram_gb >= model_memory_fp16 * 0.7:
193
+ recommendations['recommendations'].append("🔄 Use CPU offloading for some components")
194
+ recommendations['recommended_precision'] = 'float16'
195
+ recommendations['cpu_offload'] = True
196
+ recommendations['attention_slicing'] = True
197
+ recommendations['vae_slicing'] = True
198
+
199
+ else:
200
+ recommendations['recommendations'].append("🔄 Requires sequential CPU offloading")
201
+ recommendations['recommended_precision'] = 'float16'
202
+ recommendations['sequential_offload'] = True
203
+ recommendations['attention_slicing'] = True
204
+ recommendations['vae_slicing'] = True
205
+
206
+ return recommendations
207
+
208
+ def format_memory_info(self, model_id: str) -> str:
209
+ """Format memory information for display."""
210
+ info = self.get_model_memory_requirements(model_id)
211
+
212
+ source_text = {
213
+ 'known_values': '📊 Known model specifications',
214
+ 'api_estimation': '🔍 Estimated from model files',
215
+ 'generic_fallback': '⚠️ Generic estimation (API error)'
216
+ }.get(info.get('source', 'unknown'), '❓ Unknown source')
217
+
218
+ # Add warning if file sizes were estimated
219
+ if info.get('files_without_size', 0) > 0:
220
+ source_text += f" (⚠️ {info['files_without_size']} files used size estimates)"
221
+
222
+ output = f"""
223
+ 🤖 **Memory Analysis for {model_id}**
224
+
225
+ {source_text}
226
+
227
+ 🔢 **Parameters**: {info['total_params_billions']:.1f}B parameters
228
+
229
+ 💾 **Model Memory Requirements**:
230
+ • FP32: {info['memory_fp32_gb']:.1f} GB
231
+ • FP16/BF16: {info['memory_fp16_gb']:.1f} GB
232
+ • INT8: {info['memory_int8_gb']:.1f} GB
233
+
234
+ 🚀 **Estimated Inference Memory**:
235
+ • FP16: {info['estimated_inference_memory_fp16_gb']:.1f} GB
236
+ • BF16: {info['estimated_inference_memory_bf16_gb']:.1f} GB
237
+ """
238
+
239
+ if 'error' in info:
240
+ output += f"\n⚠️ **Note**: {info['error']}"
241
+
242
+ return output.strip()
243
+
244
+
245
+ # Quick test
246
+ if __name__ == "__main__":
247
+ calc = SimpleMemoryCalculator()
248
+
249
+ models = [
250
+ "black-forest-labs/FLUX.1-schnell",
251
+ "stabilityai/stable-diffusion-xl-base-1.0",
252
+ "runwayml/stable-diffusion-v1-5"
253
+ ]
254
+
255
+ for model in models:
256
+ print(f"\n{'='*60}")
257
+ print(calc.format_memory_info(model))
258
+
259
+ # Test recommendations
260
+ for vram in [8, 16, 24]:
261
+ rec = calc.get_memory_recommendation(model, vram)
262
+ print(f"\n💡 {vram}GB VRAM: {rec['recommendations'][0]}")
test_flux_specific.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ import google.generativeai as genai
4
+
5
+ load_dotenv()
6
+
7
+ def generate_flux_optimized():
8
+ api_key = os.getenv('GOOGLE_API_KEY')
9
+ genai.configure(api_key=api_key)
10
+ model = genai.GenerativeModel('gemini-2.5-flash-preview-05-20')
11
+
12
+ prompt = """
13
+ Generate optimized Python code for running FLUX.1-schnell diffusion model on Apple Silicon (MPS) hardware.
14
+
15
+ Requirements:
16
+ - Use FluxPipeline from diffusers library
17
+ - Model: "black-forest-labs/FLUX.1-schnell"
18
+ - Target device: MPS (Apple Silicon)
19
+ - Image size: 768x1360
20
+ - Inference steps: 4
21
+ - Prompt: "A cat holding a sign that says hello world"
22
+
23
+ Apply these Apple Silicon optimizations:
24
+ 1. Use torch.bfloat16 (better than float16 for MPS)
25
+ 2. Enable attention slicing and VAE slicing for memory efficiency
26
+ 3. Use guidance_scale=0.0 for FLUX.1-schnell
27
+ 4. Add max_sequence_length=256 for memory optimization
28
+ 5. Include proper error handling
29
+ 6. Add torch.inference_mode() for speed
30
+
31
+ Generate ONLY Python code without markdown formatting.
32
+ """
33
+
34
+ try:
35
+ response = model.generate_content(prompt)
36
+ code = response.text.strip()
37
+
38
+ # Clean up any markdown formatting
39
+ if code.startswith('```python'):
40
+ code = code[9:]
41
+ if code.endswith('```'):
42
+ code = code[:-3]
43
+
44
+ print("FLUX-Optimized Code for Apple Silicon:")
45
+ print("=" * 50)
46
+ print(code)
47
+ print("=" * 50)
48
+
49
+ except Exception as e:
50
+ print(f"Error: {e}")
51
+
52
+ if __name__ == "__main__":
53
+ generate_flux_optimized()
test_generation.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from auto_diffusers import AutoDiffusersGenerator
4
+
5
+ load_dotenv()
6
+
7
+ def test_generation():
8
+ api_key = os.getenv('GOOGLE_API_KEY')
9
+ if not api_key:
10
+ print("No API key found in .env file")
11
+ return
12
+
13
+ print("Testing auto-diffusers code generation...")
14
+ print("API key loaded successfully")
15
+
16
+ generator = AutoDiffusersGenerator(api_key)
17
+
18
+ # Test with default FLUX model
19
+ print("\nGenerating optimized code for FLUX.1-schnell...")
20
+
21
+ try:
22
+ optimized_code = generator.generate_optimized_code(
23
+ model_name="black-forest-labs/FLUX.1-schnell",
24
+ prompt_text="A cat holding a sign that says hello world",
25
+ image_size=(768, 1360),
26
+ num_inference_steps=4,
27
+ use_manual_specs=False
28
+ )
29
+
30
+ print("\n" + "="*60)
31
+ print("GENERATED OPTIMIZED CODE:")
32
+ print("="*60)
33
+ print(optimized_code)
34
+ print("="*60)
35
+
36
+ except Exception as e:
37
+ print(f"Error generating code: {e}")
38
+
39
+ if __name__ == "__main__":
40
+ test_generation()