AriaVale2 commited on
Commit
c489f83
·
verified ·
1 Parent(s): e5233f7

minenotpublic

Browse files
Files changed (12) hide show
  1. .gitattributes +35 -35
  2. README.md +14 -13
  3. app.py +982 -0
  4. app.py backup +800 -0
  5. app_log.txt +21 -0
  6. app_run_log.txt +3 -0
  7. launch.log +28 -0
  8. list_models.py +10 -0
  9. requirements.txt +27 -0
  10. run_sample.py +54 -0
  11. run_sample_small.py +33 -0
  12. run_small_log.txt +20 -0
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,14 @@
1
- ---
2
- title: Minenotpublic
3
- emoji: 🏃
4
- colorFrom: red
5
- colorTo: red
6
- sdk: gradio
7
- sdk_version: 6.14.0
8
- python_version: '3.12'
9
- app_file: app.py
10
- pinned: false
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
+ ---
2
+ title: ADULT.NSFW.AI.Anime&Comic
3
+ emoji: 🚀
4
+ colorFrom: purple
5
+ colorTo: red
6
+ sdk: gradio
7
+ sdk_version: 6.2.0
8
+ app_file: app.py
9
+ pinned: false
10
+ short_description: Adult AI images,anima & comic,non-realistic
11
+ tag: not-for-all-audiences
12
+ ---
13
+
14
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,982 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ if hasattr(sys.stdout, "reconfigure"):
4
+ sys.stdout.reconfigure(encoding="utf-8")
5
+ if hasattr(sys.stderr, "reconfigure"):
6
+ sys.stderr.reconfigure(encoding="utf-8")
7
+
8
+ # ===== 必须首先导入spaces =====
9
+ try:
10
+ import spaces
11
+ SPACES_AVAILABLE = True
12
+ print("✅ Spaces available - ZeroGPU mode")
13
+ except ImportError:
14
+ SPACES_AVAILABLE = False
15
+ print("⚠️ Spaces not available - running in regular mode")
16
+
17
+ # ===== 其他导入 =====
18
+ import os
19
+ import socket
20
+ import uuid
21
+ import importlib.util
22
+ from datetime import datetime
23
+ import random
24
+ import torch
25
+ import gradio as gr
26
+ from diffusers import StableDiffusionPipeline, StableDiffusionXLPipeline, EulerDiscreteScheduler
27
+ from PIL import Image
28
+ import traceback
29
+ import numpy as np
30
+
31
+ if hasattr(sys.stdout, "reconfigure"):
32
+ sys.stdout.reconfigure(encoding="utf-8")
33
+ if hasattr(sys.stderr, "reconfigure"):
34
+ sys.stderr.reconfigure(encoding="utf-8")
35
+
36
+ # ===== 长提示词处理 =====
37
+ try:
38
+ from compel import Compel, ReturnedEmbeddingsType
39
+ COMPEL_AVAILABLE = True
40
+ print("✅ Compel available for long prompt processing")
41
+ except ImportError:
42
+ COMPEL_AVAILABLE = False
43
+ print("⚠️ Compel not available - using standard prompt processing")
44
+
45
+ # ===== 优化后的配置 =====
46
+ # Kageillustrious风格核心关键词 - 使用Danbooru标签风格
47
+ STYLE_KEYWORDS = {
48
+ "None": {
49
+ "prefix": "",
50
+ "suffix": ""
51
+ },
52
+ "Standard Quality": {
53
+ "prefix": "(RAW photo:1.3), (photorealistic:1.4), (hyperrealistic:1.3), 8k uhd, (ultra realistic skin texture:1.2), cinematic lighting, vibrant colors,masterpiece, realistic skin texture, detailed anatomy, professional photography",
54
+ "suffix": "sharp focus, (everything in focus:1.3), (no bokeh:1.2), realistic skin texture, subsurface scattering, detailed anatomy, (perfect anatomy:1.2),detailed face, detailed background, lifelike, professional photography, realistic proportions, (detailed face:1.1), natural pose,expressive eyes, 8k resolution"
55
+ },
56
+ "High Detail": {
57
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, high resolution, ultra-detailed, absurdres, newest, colorful, rim light, backlit, highest detailed",
58
+ "suffix": ""
59
+ },
60
+ "Realistic": {
61
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, absurdres, (photorealistic:1.3), (realistic:1.4), detailed skin texture, cinematic lighting",
62
+ "suffix": "sharp focus, detailed anatomy, realistic proportions, detailed face, natural pose, expressive eyes, 8k resolution"
63
+ },
64
+ "Anime": {
65
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, absurdres, anime style, vibrant colors, detailed anime",
66
+ "suffix": "cel shading, clean linework, vibrant anime colors, detailed anime eyes, smooth anime skin"
67
+ },
68
+ "Artistic": {
69
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, absurdres, artistic, illustration, detailed artwork",
70
+ "suffix": "vibrant colors, expressive, detailed composition, artistic rendering"
71
+ }
72
+ }
73
+
74
+ # 通用质量增强词
75
+ QUALITY_TAGS = "very awa, masterpiece, best quality, high resolution, highly detailed, professional"
76
+
77
+ # 本地模型目录 - 只使用本机或挂载盘中的 safetensors
78
+ LOCAL_MODEL_DIRECTORY = os.environ.get(
79
+ "LOCAL_SD_MODEL_DIR",
80
+ r"G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion"
81
+ )
82
+ SUPPORTED_MODEL_EXTENSIONS = [".safetensors", ".ckpt"]
83
+
84
+ RANDOM_PROMPTS = [
85
+ "1girl, fantasy city at night, neon lights, detailed eyes, cinematic lighting",
86
+ "1boy, solo, forest clearing, soft lighting, highly detailed, realistic skin",
87
+ "couple, cozy bedroom, warm atmosphere, expressive eyes, perfect anatomy",
88
+ "anime style, elegant outfit, flowing hair, dynamic pose, dramatic lighting",
89
+ "portrait, close-up face, sharp focus, beautiful makeup, shiny hair"
90
+ ]
91
+
92
+ def get_random_prompt():
93
+ return random.choice(RANDOM_PROMPTS)
94
+
95
+ current_model_name = None
96
+ current_model_path = None
97
+
98
+
99
+ def get_server_port(default_port: int = 7860) -> int:
100
+ try:
101
+ requested_port = int(os.environ.get("GRADIO_SERVER_PORT", default_port))
102
+ except ValueError:
103
+ requested_port = default_port
104
+
105
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
106
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
107
+ try:
108
+ sock.bind(("0.0.0.0", requested_port))
109
+ return requested_port
110
+ except OSError:
111
+ sock.bind(("0.0.0.0", 0))
112
+ return sock.getsockname()[1]
113
+
114
+ # 本地模型扫描
115
+
116
+ def get_local_models():
117
+ if not os.path.isdir(LOCAL_MODEL_DIRECTORY):
118
+ return []
119
+ valid_files = []
120
+ for filename in os.listdir(LOCAL_MODEL_DIRECTORY):
121
+ extension = os.path.splitext(filename)[1].lower()
122
+ if extension not in SUPPORTED_MODEL_EXTENSIONS:
123
+ continue
124
+ file_path = os.path.join(LOCAL_MODEL_DIRECTORY, filename)
125
+ try:
126
+ if os.path.getsize(file_path) < 20 * 1024 * 1024:
127
+ continue
128
+ except OSError:
129
+ continue
130
+ valid_files.append(filename)
131
+ return sorted(valid_files)
132
+
133
+ LOCAL_MODEL_CHOICES = get_local_models()
134
+
135
+ # LoRA 配置 - 保留原有的LoRA(可能需要测试兼容性)
136
+ LORA_CONFIGS = [
137
+ {
138
+ "repo_id": "artificialguybr/LogoRedmond-LogoLoraForSDXL-V2",
139
+ "weight_name": "LogoRedAF.safetensors",
140
+ "adapter_name": "logo_lora",
141
+ "scale": 0.8
142
+ }
143
+ ]
144
+
145
+ SAVE_DIR = "generated_images"
146
+ os.makedirs(SAVE_DIR, exist_ok=True)
147
+
148
+ # ===== 模型相关变量 =====
149
+ pipeline = None
150
+ compel_processor = None
151
+ device = None
152
+ model_loaded = False
153
+
154
+ def initialize_model(model_filename: str):
155
+ """优化的模型初始化 - 从本地 safetensors 文件加载模型"""
156
+ global pipeline, compel_processor, device, model_loaded, current_model_name, current_model_path
157
+
158
+ if not model_filename:
159
+ print("❌ No model selected")
160
+ return False
161
+
162
+ model_path = os.path.join(LOCAL_MODEL_DIRECTORY, model_filename)
163
+ if not os.path.isfile(model_path):
164
+ print(f"❌ Model file not found: {model_path}")
165
+ return False
166
+
167
+ if model_loaded and pipeline is not None and model_filename == current_model_name:
168
+ print(f"✅ Model already loaded: {current_model_name}")
169
+ return True
170
+
171
+ if pipeline is not None and model_filename != current_model_name:
172
+ cleanup_pipeline()
173
+ pipeline = None
174
+ model_loaded = False
175
+
176
+ try:
177
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
178
+ print(f"🖥️ Using device: {device}")
179
+ print(f"📦 Loading local model from: {model_path}")
180
+
181
+ tried_low_mem = False
182
+ use_accelerate = importlib.util.find_spec('accelerate') is not None
183
+ low_mem_kwargs = {
184
+ 'torch_dtype': torch.float16 if torch.cuda.is_available() else torch.float32,
185
+ 'safety_checker': None,
186
+ 'requires_safety_checker': False
187
+ }
188
+ if use_accelerate:
189
+ low_mem_kwargs.update({
190
+ 'device_map': 'auto',
191
+ 'offload_folder': 'offload',
192
+ 'low_cpu_mem_usage': True
193
+ })
194
+
195
+ try:
196
+ pipeline = StableDiffusionXLPipeline.from_single_file(
197
+ model_path,
198
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
199
+ use_safetensors=True,
200
+ safety_checker=None,
201
+ requires_safety_checker=False
202
+ )
203
+ print("✅ Loaded model as SDXL pipeline")
204
+ except Exception as xlp_error:
205
+ print(f"⚠️ SDXL load failed: {xlp_error}")
206
+ # Try a low-memory loading strategy if available
207
+ try:
208
+ print("ℹ️ Attempting low-memory load (may use device mapping / lower precision)...")
209
+ tried_low_mem = True
210
+ pipeline = StableDiffusionXLPipeline.from_single_file(
211
+ model_path,
212
+ use_safetensors=True,
213
+ **low_mem_kwargs
214
+ )
215
+ print("✅ Loaded SDXL pipeline with low-memory options")
216
+ except Exception as lowmem_err:
217
+ print(f"⚠️ Low-memory SDXL load failed: {lowmem_err}")
218
+ try:
219
+ print("ℹ️ Falling back to standard Stable Diffusion loader")
220
+ pipeline = StableDiffusionPipeline.from_single_file(
221
+ model_path,
222
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
223
+ safety_checker=None,
224
+ requires_safety_checker=False
225
+ )
226
+ print("✅ Loaded model as standard Stable Diffusion pipeline")
227
+ except Exception as sd_err:
228
+ print(f"⚠️ Standard SD load failed: {sd_err}")
229
+ # Try low-memory for standard pipeline
230
+ try:
231
+ if not tried_low_mem:
232
+ pipeline = StableDiffusionPipeline.from_single_file(
233
+ model_path,
234
+ **low_mem_kwargs
235
+ )
236
+ print("✅ Loaded standard pipeline with low-memory options")
237
+ except Exception as final_err:
238
+ print(f"❌ Model loading error: {final_err}")
239
+ # Detect common low-memory / paging-file errors and provide guidance
240
+ err_msg = str(final_err).lower()
241
+ if "paging file" in err_msg or "memoryerror" in err_msg or "out of memory" in err_msg:
242
+ print("❗ Model is too large to load on the current machine (CPU memory / paging file insufficient).")
243
+ print("Suggestions: 1) Use a GPU with more VRAM; 2) Increase Windows virtual memory (page file); 3) Use a smaller model (.safetensors/.ckpt); 4) Run with `low_cpu_mem_usage=True` or enable device mapping via accelerate.)")
244
+ return False
245
+
246
+ if hasattr(pipeline, 'scheduler'):
247
+ pipeline.scheduler = EulerDiscreteScheduler.from_config(
248
+ pipeline.scheduler.config,
249
+ timestep_spacing="trailing"
250
+ )
251
+
252
+ if pipeline is None:
253
+ print("❌ No pipeline object created, aborting model initialization")
254
+ return False
255
+
256
+ pipeline = pipeline.to(device)
257
+
258
+ # 加载 LoRA
259
+ print("🎨 Loading LoRA models...")
260
+ adapter_names = []
261
+ adapter_scales = []
262
+
263
+ for lora_config in LORA_CONFIGS:
264
+ try:
265
+ pipeline.load_lora_weights(
266
+ lora_config["repo_id"],
267
+ weight_name=lora_config["weight_name"],
268
+ adapter_name=lora_config["adapter_name"]
269
+ )
270
+ adapter_names.append(lora_config["adapter_name"])
271
+ adapter_scales.append(lora_config.get("scale", 0.8))
272
+ print(f"✅ LoRA loaded: {lora_config['adapter_name']} (scale: {lora_config.get('scale', 0.8)})")
273
+ except Exception as lora_error:
274
+ print(f"⚠️ Failed to load LoRA {lora_config['adapter_name']}: {lora_error}")
275
+
276
+ if adapter_names:
277
+ try:
278
+ pipeline.set_adapters(adapter_names, adapter_weights=adapter_scales)
279
+ print(f"✅ LoRA adapters activated with scales: {adapter_scales}")
280
+ except Exception as e:
281
+ print(f"⚠️ Failed to set adapter scales: {e}")
282
+
283
+ if torch.cuda.is_available():
284
+ try:
285
+ pipeline.enable_vae_slicing()
286
+ pipeline.enable_vae_tiling()
287
+ try:
288
+ pipeline.enable_xformers_memory_efficient_attention()
289
+ print("✅ xFormers enabled")
290
+ except Exception:
291
+ print("⚠️ xFormers not available, using default attention")
292
+ print("ℹ️ Skipping torch.compile for ZeroGPU compatibility")
293
+ except Exception as opt_error:
294
+ print(f"⚠️ Optimization warning: {opt_error}")
295
+
296
+ if COMPEL_AVAILABLE:
297
+ try:
298
+ compel_processor = Compel(
299
+ tokenizer=[pipeline.tokenizer, pipeline.tokenizer_2],
300
+ text_encoder=[pipeline.text_encoder, pipeline.text_encoder_2],
301
+ returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,
302
+ requires_pooled=[False, True],
303
+ truncate_long_prompts=False
304
+ )
305
+ print("✅ Compel processor initialized")
306
+ except Exception as compel_error:
307
+ print(f"⚠️ Compel initialization failed: {compel_error}")
308
+ compel_processor = None
309
+
310
+ current_model_name = model_filename
311
+ current_model_path = model_path
312
+ model_loaded = True
313
+ print(f"✅ Local model initialization complete: {model_filename}")
314
+ return True
315
+
316
+ except Exception as e:
317
+ print(f"❌ Model loading error: {e}")
318
+ print(traceback.format_exc())
319
+ model_loaded = False
320
+ return False
321
+
322
+ def enhance_prompt(prompt: str, style: str) -> str:
323
+ """优化的提示词增强 - 适配Kageillustrious的Danbooru标签风格"""
324
+ if not prompt or prompt.strip() == "":
325
+ return ""
326
+
327
+ # 获取风格关键词
328
+ style_config = STYLE_KEYWORDS.get(style, STYLE_KEYWORDS["None"])
329
+
330
+ # 组合顺序:风格前缀 → 用户提示词 → 风格后缀 → 质量标签
331
+ parts = []
332
+
333
+ if style_config["prefix"]:
334
+ parts.append(style_config["prefix"])
335
+
336
+ parts.append(prompt.strip())
337
+
338
+ if style_config["suffix"]:
339
+ parts.append(style_config["suffix"])
340
+
341
+ parts.append(QUALITY_TAGS)
342
+
343
+ enhanced = ", ".join(parts)
344
+
345
+ print(f"\n🎨 Style: {style}")
346
+ print(f"📝 User prompt: {prompt[:100]}...")
347
+ print(f"✨ Enhanced: {enhanced[:200]}...\n")
348
+
349
+ return enhanced
350
+
351
+ def build_negative_prompt(style: str, custom_negative: str = "") -> str:
352
+ """根据风格构建负面提示词 - 适配Illustrious系列"""
353
+ # Illustrious系列推荐的负面提示词
354
+ base_negative = "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
355
+
356
+ # 风格特定的负面词
357
+ style_negatives = {
358
+ "Standard Quality": ", (cartoon:1.3), (anime:1.3), (3d render:1.2), (illustration:1.2), (painting:1.2), (drawing:1.2), (art:1.2), (sketch:1.2), artificial, unrealistic, (depth of field:1.2), (bokeh:1.2)",
359
+ "Realistic": ", (cartoon:1.3), (anime:1.3), (3d render:1.2), (illustration:1.2)",
360
+ "Anime": ", (realistic:1.3), (photorealistic:1.3), (photo:1.2)",
361
+ "Artistic": ", (photo:1.2), (photorealistic:1.2)"
362
+ }
363
+
364
+ negative = base_negative
365
+ if style in style_negatives:
366
+ negative += style_negatives[style]
367
+
368
+ # 添加用户自定义负面词
369
+ if custom_negative.strip():
370
+ negative += f", {custom_negative.strip()}"
371
+
372
+ return negative
373
+
374
+ def process_with_compel(prompt, negative_prompt):
375
+ """使用Compel处理长提示词"""
376
+ if not compel_processor:
377
+ return None, None
378
+
379
+ try:
380
+ # Compel会自动处理超过77 tokens的提示词
381
+ conditioning, pooled = compel_processor([prompt, negative_prompt])
382
+ print("✅ Long prompt processed with Compel")
383
+ return conditioning, pooled
384
+ except Exception as e:
385
+ print(f"⚠️ Compel processing failed: {e}")
386
+ return None, None
387
+
388
+ def apply_spaces_decorator(func):
389
+ """应用spaces装饰器"""
390
+ if SPACES_AVAILABLE:
391
+ return spaces.GPU(duration=45)(func)
392
+ return func
393
+
394
+ def create_metadata_content(prompt, enhanced_prompt, seed, steps, cfg_scale, width, height, style):
395
+ """创建元数据"""
396
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
397
+
398
+ # 获取 LoRA 信息
399
+ lora_info = ", ".join([f"{lora['adapter_name']}({lora.get('scale', 1.0)})" for lora in LORA_CONFIGS])
400
+
401
+ return f"""Generated Image Metadata
402
+ ======================
403
+ Timestamp: {timestamp}
404
+ Original Prompt: {prompt}
405
+ Seed: {seed}
406
+ Steps: {steps}
407
+ CFG Scale: {cfg_scale}
408
+ Dimensions: {width}x{height}
409
+ Style: {style}
410
+ """
411
+
412
+ def cleanup_pipeline():
413
+ """清理 pipeline 状态,防止污染"""
414
+ global pipeline
415
+
416
+ if pipeline is None:
417
+ return
418
+
419
+ try:
420
+ # 清理 CUDA 缓存
421
+ if torch.cuda.is_available():
422
+ torch.cuda.empty_cache()
423
+ torch.cuda.ipc_collect()
424
+
425
+ # 清理 pipeline 的内部缓存
426
+ if hasattr(pipeline, 'unet'):
427
+ # 清空 UNet 的注意力缓存
428
+ if hasattr(pipeline.unet, 'set_attn_processor'):
429
+ try:
430
+ from diffusers.models.attention_processor import AttnProcessor
431
+ pipeline.unet.set_attn_processor(AttnProcessor())
432
+ except:
433
+ pass
434
+
435
+ # 清理 VAE 缓存
436
+ if hasattr(pipeline, 'vae'):
437
+ pipeline.vae.to('cpu')
438
+ pipeline.vae.to(device)
439
+
440
+ print("🧹 Pipeline cleaned")
441
+
442
+ except Exception as e:
443
+ print(f"⚠️ Cleanup warning: {e}")
444
+
445
+ @apply_spaces_decorator
446
+ def generate_image(prompt: str, style: str, negative_prompt: str = "",
447
+ steps: int = 20, cfg_scale: float = 6.0,
448
+ seed: int = -1, width: int = 896, height: int = 1152,
449
+ model_name: str = None, num_images: int = 1,
450
+ progress=gr.Progress()):
451
+ """图像生成主函数 - 使用选择的本地模型进行生成"""
452
+
453
+ # 验证输入
454
+ if not prompt or prompt.strip() == "":
455
+ return None, "", "❌ Please enter a prompt"
456
+ if not model_name:
457
+ return None, "", "❌ Please select a local model"
458
+
459
+ progress(0.05, desc="Initializing...")
460
+
461
+ # 初始化模型
462
+ if not initialize_model(model_name):
463
+ return None, "", "❌ Failed to load selected model"
464
+
465
+ # 清理之前的状态
466
+ cleanup_pipeline()
467
+
468
+ progress(0.1, desc="Processing prompt...")
469
+
470
+ try:
471
+ # prepare seeds for each image
472
+ if seed == -1:
473
+ seeds = [random.randint(0, np.iinfo(np.int32).max) for _ in range(max(1, num_images))]
474
+ else:
475
+ seeds = [int(seed) + i for i in range(max(1, num_images))]
476
+
477
+ # 增强提示词
478
+ enhanced_prompt = enhance_prompt(prompt, style)
479
+
480
+ # 构建负面提示词
481
+ final_negative = build_negative_prompt(style, negative_prompt)
482
+
483
+ print(f"🔧 Generation params: seed={seed}, steps={steps}, cfg={cfg_scale}, size={width}x{height}")
484
+ print(f"📝 Prompt preview: {enhanced_prompt[:100]}...")
485
+
486
+ progress(0.2, desc="Generating images...")
487
+
488
+ # 检查提示词长度并决定是否使用Compel
489
+ prompt_length = len(enhanced_prompt.split())
490
+ use_compel = prompt_length > 50 and compel_processor is not None
491
+
492
+ images = []
493
+
494
+ if use_compel:
495
+ print(f"📏 Long prompt detected ({prompt_length} words), using Compel")
496
+ conditioning, pooled = process_with_compel(enhanced_prompt, final_negative)
497
+
498
+ if conditioning is not None:
499
+ # 使用embeddings生成
500
+ for idx in range(len(seeds)):
501
+ generator = torch.Generator(device).manual_seed(seeds[idx])
502
+ out = pipeline(
503
+ prompt_embeds=conditioning[0:1],
504
+ pooled_prompt_embeds=pooled[0:1],
505
+ negative_prompt_embeds=conditioning[1:2],
506
+ negative_pooled_prompt_embeds=pooled[1:2],
507
+ num_inference_steps=steps,
508
+ guidance_scale=cfg_scale,
509
+ width=width,
510
+ height=height,
511
+ generator=generator,
512
+ output_type="pil"
513
+ ).images[0]
514
+ images.append(out)
515
+ else:
516
+ # Compel失败,回退到普通模式
517
+ print("⚠️ Falling back to standard generation")
518
+ for idx in range(len(seeds)):
519
+ generator = torch.Generator(device).manual_seed(seeds[idx])
520
+ out = pipeline(
521
+ prompt=enhanced_prompt,
522
+ negative_prompt=final_negative,
523
+ num_inference_steps=steps,
524
+ guidance_scale=cfg_scale,
525
+ width=width,
526
+ height=height,
527
+ generator=generator,
528
+ output_type="pil"
529
+ ).images[0]
530
+ images.append(out)
531
+ else:
532
+ # 标准生成
533
+ print(f"📝 Standard generation ({prompt_length} words)")
534
+ for idx in range(len(seeds)):
535
+ generator = torch.Generator(device).manual_seed(seeds[idx])
536
+ out = pipeline(
537
+ prompt=enhanced_prompt,
538
+ negative_prompt=final_negative,
539
+ num_inference_steps=steps,
540
+ guidance_scale=cfg_scale,
541
+ width=width,
542
+ height=height,
543
+ generator=generator,
544
+ output_type="pil"
545
+ ).images[0]
546
+ images.append(out)
547
+
548
+ progress(0.95, desc="Finalizing...")
549
+
550
+ # 确保结果是PIL Image
551
+ for i, res in enumerate(images):
552
+ if not isinstance(res, Image.Image):
553
+ if isinstance(res, np.ndarray):
554
+ if res.dtype != np.uint8:
555
+ res = (res * 255).astype(np.uint8)
556
+ res = Image.fromarray(res)
557
+ images[i] = res
558
+
559
+ # 创建元数据
560
+ metadata = create_metadata_content(
561
+ prompt, enhanced_prompt, seeds[0] if seeds else -1, steps, cfg_scale,
562
+ width, height, style
563
+ )
564
+
565
+ generation_info = f"Model: {model_name} | Style: {style} | Seeds: {', '.join(str(s) for s in seeds)} | Size: {width}×{height} | Steps: {steps} | CFG: {cfg_scale}"
566
+
567
+ # 生成后立即清理
568
+ if torch.cuda.is_available():
569
+ torch.cuda.empty_cache()
570
+
571
+ progress(1.0, desc="Complete!")
572
+ print("✅ Generation successful\n")
573
+
574
+ return images, generation_info, metadata
575
+
576
+ except Exception as e:
577
+ error_msg = str(e)
578
+ print(f"❌ Generation error: {error_msg}")
579
+ print(traceback.format_exc())
580
+
581
+ # 错误后也要清理
582
+ try:
583
+ cleanup_pipeline()
584
+ except:
585
+ pass
586
+
587
+ return None, "", f"❌ Generation failed: {error_msg}"
588
+
589
+ # ===== CSS样式 =====
590
+ css = """
591
+ .gradio-container {overflow-y: auto !important; height: 100vh !important;}
592
+ #gallery {min-height: 800px !important; overflow-y: visible !important;}
593
+ .scroll-hide {overflow-y: auto !important;}
594
+
595
+ .gradio-container {overflow-y: auto !important; height: 100vh !important;}
596
+ #gallery {min-height: 800px !important; overflow-y: visible !important;}
597
+ .scroll-hide {overflow-y: auto !important;}
598
+
599
+ .gradio-container {overflow-y: auto !important;}
600
+ #gallery {min-height: 800px !important;}
601
+ .scroll-hide {overflow-y: auto !important;}
602
+
603
+ .gradio-container {overflow-y: auto !important;}
604
+ #gallery {min-height: 800px !important;}
605
+ .scroll-hide {overflow-y: auto !important;}
606
+
607
+ .gradio-container {
608
+ max-width: 100% !important;
609
+ margin: 0 !important;
610
+ padding: 0 !important;
611
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
612
+ min-height: 100vh !important;
613
+ font-family: 'Segoe UI', Arial, sans-serif !important;
614
+ }
615
+
616
+ .main-content {
617
+ background: rgba(255, 255, 255, 0.95) !important;
618
+ border-radius: 20px !important;
619
+ padding: 20px !important;
620
+ margin: 15px !important;
621
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2) !important;
622
+ min-height: calc(100vh - 30px) !important;
623
+ color: #3e3e3e !important;
624
+ backdrop-filter: blur(10px) !important;
625
+ }
626
+
627
+ .title {
628
+ text-align: center !important;
629
+ background: linear-gradient(45deg, #667eea, #764ba2) !important;
630
+ -webkit-background-clip: text !important;
631
+ -webkit-text-fill-color: transparent !important;
632
+ background-clip: text !important;
633
+ font-size: 2rem !important;
634
+ margin-bottom: 15px !important;
635
+ font-weight: bold !important;
636
+ }
637
+
638
+ .warning-box {
639
+ background: linear-gradient(45deg, #667eea, #764ba2) !important;
640
+ color: white !important;
641
+ padding: 8px !important;
642
+ border-radius: 8px !important;
643
+ margin-bottom: 15px !important;
644
+ text-align: center !important;
645
+ font-weight: bold !important;
646
+ font-size: 14px !important;
647
+ }
648
+
649
+ .model-info {
650
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.1), rgba(118, 75, 162, 0.1)) !important;
651
+ color: #764ba2 !important;
652
+ padding: 10px !important;
653
+ border-radius: 8px !important;
654
+ margin-bottom: 15px !important;
655
+ text-align: center !important;
656
+ font-weight: 600 !important;
657
+ font-size: 13px !important;
658
+ border: 2px solid rgba(118, 75, 162, 0.3) !important;
659
+ }
660
+
661
+ .prompt-box textarea, .prompt-box input {
662
+ border-radius: 10px !important;
663
+ border: 2px solid #667eea !important;
664
+ padding: 15px !important;
665
+ font-size: 18px !important;
666
+ background: linear-gradient(135deg, rgba(245, 243, 255, 0.9), rgba(237, 233, 254, 0.9)) !important;
667
+ color: #2d2d2d !important;
668
+ }
669
+
670
+ .prompt-box textarea:focus, .prompt-box input:focus {
671
+ border-color: #764ba2 !important;
672
+ box-shadow: 0 0 15px rgba(118, 75, 162, 0.3) !important;
673
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.95), rgba(248, 249, 250, 0.95)) !important;
674
+ }
675
+
676
+ .controls-section {
677
+ background: linear-gradient(135deg, rgba(224, 218, 255, 0.8), rgba(196, 181, 253, 0.8)) !important;
678
+ border-radius: 12px !important;
679
+ padding: 15px !important;
680
+ margin-bottom: 8px !important;
681
+ border: 2px solid rgba(102, 126, 234, 0.3) !important;
682
+ backdrop-filter: blur(5px) !important;
683
+ }
684
+
685
+ .controls-section label {
686
+ font-weight: 600 !important;
687
+ color: #2d2d2d !important;
688
+ margin-bottom: 8px !important;
689
+ }
690
+
691
+ .controls-section input[type="radio"] {
692
+ accent-color: #667eea !important;
693
+ }
694
+
695
+ .controls-section input[type="number"],
696
+ .controls-section input[type="range"] {
697
+ background: rgba(255, 255, 255, 0.9) !important;
698
+ border: 1px solid #667eea !important;
699
+ border-radius: 6px !important;
700
+ padding: 8px !important;
701
+ color: #2d2d2d !important;
702
+ }
703
+
704
+ .generate-btn {
705
+ background: linear-gradient(45deg, #667eea, #764ba2) !important;
706
+ color: white !important;
707
+ border: none !important;
708
+ padding: 15px 25px !important;
709
+ border-radius: 25px !important;
710
+ font-size: 16px !important;
711
+ font-weight: bold !important;
712
+ width: 100% !important;
713
+ cursor: pointer !important;
714
+ transition: all 0.3s ease !important;
715
+ text-transform: uppercase !important;
716
+ letter-spacing: 1px !important;
717
+ }
718
+
719
+ .generate-btn:hover {
720
+ transform: translateY(-2px) !important;
721
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.5) !important;
722
+ }
723
+
724
+ .image-output {
725
+ border-radius: 15px !important;
726
+ overflow: hidden !important;
727
+ max-width: 100% !important;
728
+ max-height: 70vh !important;
729
+ border: 3px solid #764ba2 !important;
730
+ box-shadow: 0 8px 20px rgba(0,0,0,0.15) !important;
731
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(248, 249, 250, 0.9)) !important;
732
+ }
733
+
734
+ .image-info {
735
+ background: linear-gradient(135deg, rgba(248, 249, 250, 0.9), rgba(233, 236, 239, 0.9)) !important;
736
+ border-radius: 8px !important;
737
+ padding: 12px !important;
738
+ margin-top: 10px !important;
739
+ font-size: 12px !important;
740
+ color: #495057 !important;
741
+ border: 2px solid rgba(102, 126, 234, 0.2) !important;
742
+ backdrop-filter: blur(5px) !important;
743
+ }
744
+
745
+ .metadata-box {
746
+ background: linear-gradient(135deg, rgba(248, 249, 250, 0.9), rgba(233, 236, 239, 0.9)) !important;
747
+ border-radius: 8px !important;
748
+ padding: 15px !important;
749
+ margin-top: 15px !important;
750
+ font-family: 'Courier New', monospace !important;
751
+ font-size: 12px !important;
752
+ color: #495057 !important;
753
+ border: 2px solid rgba(102, 126, 234, 0.2) !important;
754
+ backdrop-filter: blur(5px) !important;
755
+ white-space: pre-wrap !important;
756
+ overflow-y: auto !important;
757
+ max-height: 300px !important;
758
+ }
759
+
760
+ @media (max-width: 768px) {
761
+ .main-content {
762
+ margin: 10px !important;
763
+ padding: 15px !important;
764
+ }
765
+ .title {
766
+ font-size: 1.5rem !important;
767
+ }
768
+ }
769
+ """
770
+
771
+ # ===== 创建UI =====
772
+ def create_interface():
773
+ with gr.Blocks(title="ADULT AI Image Generator") as interface:
774
+ with gr.Column(elem_classes=["main-content"]):
775
+ gr.HTML('<div class="title">🎨 ADULT AI Image Generator</div>')
776
+ gr.HTML('<div class="warning-box">⚠️ 18+ CONTENT WARNING ⚠️</div>')
777
+
778
+ with gr.Row():
779
+ with gr.Column(scale=2):
780
+ prompt_input = gr.Textbox(
781
+ label="Detailed Prompt (Use Danbooru tags style)",
782
+ placeholder="1boy, solo, messy hair, blue eyes, detailed face, handsome...",
783
+ value=get_random_prompt(),
784
+ lines=15,
785
+ elem_classes=["prompt-box"]
786
+ )
787
+
788
+ negative_prompt_input = gr.Textbox(
789
+ label="Negative Prompt (Optional)",
790
+ placeholder="Additional things you don't want...",
791
+ lines=4,
792
+ elem_classes=["prompt-box"]
793
+ )
794
+
795
+ with gr.Column(scale=1):
796
+ with gr.Group(elem_classes=["controls-section"]):
797
+ model_input = gr.Dropdown(
798
+ label="Choose Local Model",
799
+ choices=LOCAL_MODEL_CHOICES,
800
+ value=LOCAL_MODEL_CHOICES[0] if LOCAL_MODEL_CHOICES else None,
801
+ interactive=True,
802
+ allow_custom_value=False
803
+ )
804
+ if not LOCAL_MODEL_CHOICES:
805
+ gr.HTML(
806
+ f'<div class="warning-box">⚠️ No local models found in <code>{LOCAL_MODEL_DIRECTORY}</code>. Add .safetensors files or set LOCAL_SD_MODEL_DIR.</div>'
807
+ )
808
+
809
+ with gr.Group(elem_classes=["controls-section"]):
810
+ style_input = gr.Radio(
811
+ label="Style Preset",
812
+ choices=list(STYLE_KEYWORDS.keys()),
813
+ value="Standard Quality"
814
+ )
815
+
816
+ with gr.Group(elem_classes=["controls-section"]):
817
+ seed_input = gr.Number(
818
+ label="Seed (-1 for random)",
819
+ value=-1,
820
+ precision=0
821
+ )
822
+
823
+ with gr.Group(elem_classes=["controls-section"]):
824
+ width_input = gr.Slider(
825
+ label="Width",
826
+ minimum=512,
827
+ maximum=2048,
828
+ value=896,
829
+ step=64,
830
+ info="Recommended: 896"
831
+ )
832
+
833
+ with gr.Group(elem_classes=["controls-section"]):
834
+ height_input = gr.Slider(
835
+ label="Height",
836
+ minimum=512,
837
+ maximum=2048,
838
+ value=1152,
839
+ step=64,
840
+ info="Recommended: 1152"
841
+ )
842
+
843
+ with gr.Group(elem_classes=["controls-section"]):
844
+ steps_input = gr.Slider(
845
+ label="Steps",
846
+ minimum=10,
847
+ maximum=50,
848
+ value=20,
849
+ step=1,
850
+ info="Recommended: 20"
851
+ )
852
+
853
+ cfg_input = gr.Slider(
854
+ label="CFG Scale",
855
+ minimum=1.0,
856
+ maximum=15.0,
857
+ value=6.0,
858
+ step=0.1,
859
+ info="Recommended: 6.0"
860
+ )
861
+
862
+ num_images_input = gr.Slider(
863
+ label="Number of Images",
864
+ minimum=1,
865
+ maximum=50,
866
+ value=1,
867
+ step=1,
868
+ info="Generate multiple images (each with different seed)"
869
+ )
870
+
871
+ generate_button = gr.Button(
872
+ "GENERATE",
873
+ elem_classes=["generate-btn"],
874
+ variant="primary"
875
+ )
876
+
877
+ image_output = gr.Gallery(
878
+ label="Generated Images",
879
+ elem_classes=["image-output"],
880
+ show_label=False,
881
+ container=True,
882
+ columns=2
883
+ )
884
+
885
+ with gr.Row():
886
+ generation_info = gr.Textbox(
887
+ label="Generation Info",
888
+ interactive=False,
889
+ elem_classes=["image-info"],
890
+ show_label=True,
891
+ visible=False
892
+ )
893
+
894
+ with gr.Row():
895
+ metadata_display = gr.Textbox(
896
+ label="Image Metadata",
897
+ interactive=True,
898
+ elem_classes=["metadata-box"],
899
+ show_label=True,
900
+ lines=15,
901
+ visible=False
902
+ )
903
+
904
+ def on_generate(prompt, model_name, style, neg_prompt, steps, cfg, seed, num_images, width, height):
905
+ images, info, metadata = generate_image(
906
+ prompt, style, neg_prompt, steps, cfg, seed, width, height, model_name, num_images
907
+ )
908
+
909
+ if image is not None:
910
+ return (
911
+ images,
912
+ info,
913
+ metadata,
914
+ gr.update(visible=True, value=info),
915
+ gr.update(visible=True, value=metadata)
916
+ )
917
+ else:
918
+ return (
919
+ None,
920
+ info,
921
+ "",
922
+ gr.update(visible=False),
923
+ gr.update(visible=False)
924
+ )
925
+
926
+ generate_button.click(
927
+ fn=on_generate,
928
+ inputs=[
929
+ prompt_input, model_input, style_input, negative_prompt_input,
930
+ steps_input, cfg_input, seed_input, num_images_input, width_input, height_input
931
+ ],
932
+ outputs=[
933
+ image_output, generation_info, metadata_display,
934
+ generation_info, metadata_display
935
+ ],
936
+ show_progress=True
937
+ )
938
+
939
+ prompt_input.submit(
940
+ fn=on_generate,
941
+ inputs=[
942
+ prompt_input, model_input, style_input, negative_prompt_input,
943
+ steps_input, cfg_input, seed_input, num_images_input, width_input, height_input
944
+ ],
945
+ outputs=[
946
+ image_output, generation_info, metadata_display,
947
+ generation_info, metadata_display
948
+ ],
949
+ show_progress=True
950
+ )
951
+
952
+ return interface
953
+
954
+ # ===== 启动应用 =====
955
+ if __name__ == "__main__":
956
+ print("\n" + "="*50)
957
+ print("🚀 Starting ADULT AI Image Generator (YAOI Friendly) ")
958
+ print("="*50)
959
+ print(f"📂 Local model directory: {LOCAL_MODEL_DIRECTORY}")
960
+ print(f"📄 Available local models: {', '.join(LOCAL_MODEL_CHOICES) if LOCAL_MODEL_CHOICES else 'NONE FOUND'}")
961
+ print(f"🖥️ Device: {'CUDA' if torch.cuda.is_available() else 'CPU'}")
962
+ print(f"⚡ ZeroGPU: {'Enabled' if SPACES_AVAILABLE else 'Disabled'}")
963
+ print(f"📝 Compel: {'Available' if COMPEL_AVAILABLE else 'Not Available'}")
964
+ if LORA_CONFIGS:
965
+ print(f"🎨 LoRA: LogoRedmond-LogoLoraForSDXL-V2 (scale: {LORA_CONFIGS[0].get('scale', 0.8)})")
966
+ print("="*50 + "\n")
967
+
968
+ # 不预加载模型,让ZeroGPU按需分配
969
+ # 这样可以避免GPU分配冲突
970
+
971
+ app = create_interface()
972
+ app.queue(max_size=10, default_concurrency_limit=2)
973
+
974
+ server_port = get_server_port(7860)
975
+ print(f"🚪 Launching Gradio on port: {server_port}")
976
+
977
+ app.launch(
978
+ server_name="0.0.0.0",
979
+ server_port=server_port,
980
+ share=True,
981
+ css=css
982
+ )
app.py backup ADDED
@@ -0,0 +1,800 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ===== 必须首先导入spaces =====
2
+ try:
3
+ import spaces
4
+ SPACES_AVAILABLE = True
5
+ print("✅ Spaces available - ZeroGPU mode")
6
+ except ImportError:
7
+ SPACES_AVAILABLE = False
8
+ print("⚠️ Spaces not available - running in regular mode")
9
+
10
+ # ===== 其他导入 =====
11
+ import os
12
+ import uuid
13
+ from datetime import datetime
14
+ import random
15
+ import torch
16
+ import gradio as gr
17
+ from diffusers import StableDiffusionXLPipeline, EulerDiscreteScheduler
18
+ from PIL import Image
19
+ import traceback
20
+ import numpy as np
21
+
22
+ # ===== 长提示词处理 =====
23
+ try:
24
+ from compel import Compel, ReturnedEmbeddingsType
25
+ COMPEL_AVAILABLE = True
26
+ print("✅ Compel available for long prompt processing")
27
+ except ImportError:
28
+ COMPEL_AVAILABLE = False
29
+ print("⚠️ Compel not available - using standard prompt processing")
30
+
31
+ # ===== 优化后的配置 =====
32
+ # Kageillustrious风格核心关键词 - 使用Danbooru标签风格
33
+ STYLE_KEYWORDS = {
34
+ "None": {
35
+ "prefix": "",
36
+ "suffix": ""
37
+ },
38
+ "Standard Quality": {
39
+ "prefix": "(RAW photo:1.3), (photorealistic:1.4), (hyperrealistic:1.3), 8k uhd, (ultra realistic skin texture:1.2), cinematic lighting, vibrant colors,masterpiece, realistic skin texture, detailed anatomy, professional photography",
40
+ "suffix": "sharp focus, (everything in focus:1.3), (no bokeh:1.2), realistic skin texture, subsurface scattering, detailed anatomy, (perfect anatomy:1.2),detailed face, detailed background, lifelike, professional photography, realistic proportions, (detailed face:1.1), natural pose,expressive eyes, 8k resolution"
41
+ },
42
+ "High Detail": {
43
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, high resolution, ultra-detailed, absurdres, newest, colorful, rim light, backlit, highest detailed",
44
+ "suffix": ""
45
+ },
46
+ "Realistic": {
47
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, absurdres, (photorealistic:1.3), (realistic:1.4), detailed skin texture, cinematic lighting",
48
+ "suffix": "sharp focus, detailed anatomy, realistic proportions, detailed face, natural pose, expressive eyes, 8k resolution"
49
+ },
50
+ "Anime": {
51
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, absurdres, anime style, vibrant colors, detailed anime",
52
+ "suffix": "cel shading, clean linework, vibrant anime colors, detailed anime eyes, smooth anime skin"
53
+ },
54
+ "Artistic": {
55
+ "prefix": "masterpiece, best quality, amazing quality, very aesthetic, absurdres, artistic, illustration, detailed artwork",
56
+ "suffix": "vibrant colors, expressive, detailed composition, artistic rendering"
57
+ }
58
+ }
59
+
60
+ # 通用质量增强词
61
+ QUALITY_TAGS = "very awa, masterpiece, best quality, high resolution, highly detailed, professional"
62
+
63
+ # 修改为Kageillustrious模型 - 使用from_single_file加载
64
+ FIXED_MODEL_REPO = "PutiLeslie/kageillustrious_v60NLXLVersion"
65
+ FIXED_MODEL_FILE = "kageillustrious_v60NLXLVersion.safetensors"
66
+
67
+ # LoRA 配置 - 保留原有的LoRA(可能需要测试兼容性)
68
+ LORA_CONFIGS = [
69
+ {
70
+ "repo_id": "artificialguybr/LogoRedmond-LogoLoraForSDXL-V2",
71
+ "weight_name": "LogoRedAF.safetensors",
72
+ "adapter_name": "logo_lora",
73
+ "scale": 0.8
74
+ }
75
+ ]
76
+
77
+ SAVE_DIR = "generated_images"
78
+ os.makedirs(SAVE_DIR, exist_ok=True)
79
+
80
+ # ===== 模型相关变量 =====
81
+ pipeline = None
82
+ compel_processor = None
83
+ device = None
84
+ model_loaded = False
85
+
86
+ def initialize_model():
87
+ """优化的模型初始化 - 使用from_single_file加载Kageillustrious"""
88
+ global pipeline, compel_processor, device, model_loaded
89
+
90
+ if model_loaded and pipeline is not None:
91
+ print("✅ Model already loaded, skipping initialization")
92
+ return True
93
+
94
+ try:
95
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
96
+ print(f"🖥️ Using device: {device}")
97
+
98
+ print(f"📦 Loading Kageillustrious model from: {FIXED_MODEL_REPO}")
99
+
100
+ # 使用from_single_file加载单个safetensors文件
101
+ from huggingface_hub import hf_hub_download
102
+
103
+ # 下载模型文件
104
+ model_path = hf_hub_download(
105
+ repo_id=FIXED_MODEL_REPO,
106
+ filename=FIXED_MODEL_FILE
107
+ )
108
+
109
+ print(f"📥 Model downloaded to: {model_path}")
110
+
111
+ # 使用from_single_file加载
112
+ pipeline = StableDiffusionXLPipeline.from_single_file(
113
+ model_path,
114
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
115
+ use_safetensors=True,
116
+ safety_checker=None,
117
+ requires_safety_checker=False
118
+ )
119
+
120
+ # 优化调度器 - 使用Euler适合Illustrious系列
121
+ pipeline.scheduler = EulerDiscreteScheduler.from_config(
122
+ pipeline.scheduler.config,
123
+ timestep_spacing="trailing"
124
+ )
125
+
126
+ pipeline = pipeline.to(device)
127
+
128
+ # 加载 LoRA
129
+ print("🎨 Loading LoRA models...")
130
+ adapter_names = []
131
+ adapter_scales = []
132
+
133
+ for lora_config in LORA_CONFIGS:
134
+ try:
135
+ pipeline.load_lora_weights(
136
+ lora_config["repo_id"],
137
+ weight_name=lora_config["weight_name"],
138
+ adapter_name=lora_config["adapter_name"]
139
+ )
140
+ adapter_names.append(lora_config["adapter_name"])
141
+ adapter_scales.append(lora_config.get("scale", 0.8))
142
+ print(f"✅ LoRA loaded: {lora_config['adapter_name']} (scale: {lora_config.get('scale', 0.8)})")
143
+ except Exception as lora_error:
144
+ print(f"⚠️ Failed to load LoRA {lora_config['adapter_name']}: {lora_error}")
145
+
146
+ # 设置 LoRA 强度
147
+ if adapter_names:
148
+ try:
149
+ pipeline.set_adapters(adapter_names, adapter_weights=adapter_scales)
150
+ print(f"✅ LoRA adapters activated with scales: {adapter_scales}")
151
+ except Exception as e:
152
+ print(f"⚠️ Failed to set adapter scales: {e}")
153
+
154
+ # GPU优化 - 适配ZeroGPU环境
155
+ if torch.cuda.is_available():
156
+ try:
157
+ # VAE优化
158
+ pipeline.enable_vae_slicing()
159
+ pipeline.enable_vae_tiling()
160
+
161
+ # 尝试启用xformers
162
+ try:
163
+ pipeline.enable_xformers_memory_efficient_attention()
164
+ print("✅ xFormers enabled")
165
+ except:
166
+ print("⚠️ xFormers not available, using default attention")
167
+
168
+ # 不使用torch.compile,因为它在ZeroGPU环境中不稳定
169
+ print("ℹ️ Skipping torch.compile for ZeroGPU compatibility")
170
+
171
+ except Exception as opt_error:
172
+ print(f"⚠️ Optimization warning: {opt_error}")
173
+
174
+ # 初始化Compel用于长提示词
175
+ if COMPEL_AVAILABLE:
176
+ try:
177
+ compel_processor = Compel(
178
+ tokenizer=[pipeline.tokenizer, pipeline.tokenizer_2],
179
+ text_encoder=[pipeline.text_encoder, pipeline.text_encoder_2],
180
+ returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,
181
+ requires_pooled=[False, True],
182
+ truncate_long_prompts=False
183
+ )
184
+ print("✅ Compel processor initialized")
185
+ except Exception as compel_error:
186
+ print(f"⚠️ Compel initialization failed: {compel_error}")
187
+ compel_processor = None
188
+
189
+ model_loaded = True
190
+ print("✅ Kageillustrious model initialization complete")
191
+ return True
192
+
193
+ except Exception as e:
194
+ print(f"❌ Model loading error: {e}")
195
+ print(traceback.format_exc())
196
+ model_loaded = False
197
+ return False
198
+
199
+ def enhance_prompt(prompt: str, style: str) -> str:
200
+ """优化的提示词增强 - 适配Kageillustrious的Danbooru标签风格"""
201
+ if not prompt or prompt.strip() == "":
202
+ return ""
203
+
204
+ # 获取风格关键词
205
+ style_config = STYLE_KEYWORDS.get(style, STYLE_KEYWORDS["None"])
206
+
207
+ # 组合顺序:风格前缀 → 用户提示词 → 风格后缀 → 质量标签
208
+ parts = []
209
+
210
+ if style_config["prefix"]:
211
+ parts.append(style_config["prefix"])
212
+
213
+ parts.append(prompt.strip())
214
+
215
+ if style_config["suffix"]:
216
+ parts.append(style_config["suffix"])
217
+
218
+ parts.append(QUALITY_TAGS)
219
+
220
+ enhanced = ", ".join(parts)
221
+
222
+ print(f"\n🎨 Style: {style}")
223
+ print(f"📝 User prompt: {prompt[:100]}...")
224
+ print(f"✨ Enhanced: {enhanced[:200]}...\n")
225
+
226
+ return enhanced
227
+
228
+ def build_negative_prompt(style: str, custom_negative: str = "") -> str:
229
+ """根据风格构建负面提示词 - 适配Illustrious系列"""
230
+ # Illustrious系列推荐的负面提示词
231
+ base_negative = "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
232
+
233
+ # 风格特定的负面词
234
+ style_negatives = {
235
+ "Standard Quality": ", (cartoon:1.3), (anime:1.3), (3d render:1.2), (illustration:1.2), (painting:1.2), (drawing:1.2), (art:1.2), (sketch:1.2), artificial, unrealistic, (depth of field:1.2), (bokeh:1.2)",
236
+ "Realistic": ", (cartoon:1.3), (anime:1.3), (3d render:1.2), (illustration:1.2)",
237
+ "Anime": ", (realistic:1.3), (photorealistic:1.3), (photo:1.2)",
238
+ "Artistic": ", (photo:1.2), (photorealistic:1.2)"
239
+ }
240
+
241
+ negative = base_negative
242
+ if style in style_negatives:
243
+ negative += style_negatives[style]
244
+
245
+ # 添加用户自定义负面词
246
+ if custom_negative.strip():
247
+ negative += f", {custom_negative.strip()}"
248
+
249
+ return negative
250
+
251
+ def process_with_compel(prompt, negative_prompt):
252
+ """使用Compel处理长提示词"""
253
+ if not compel_processor:
254
+ return None, None
255
+
256
+ try:
257
+ # Compel会自动处理超过77 tokens的提示词
258
+ conditioning, pooled = compel_processor([prompt, negative_prompt])
259
+ print("✅ Long prompt processed with Compel")
260
+ return conditioning, pooled
261
+ except Exception as e:
262
+ print(f"⚠️ Compel processing failed: {e}")
263
+ return None, None
264
+
265
+ def apply_spaces_decorator(func):
266
+ """应用spaces装饰器"""
267
+ if SPACES_AVAILABLE:
268
+ return spaces.GPU(duration=45)(func)
269
+ return func
270
+
271
+ def create_metadata_content(prompt, enhanced_prompt, seed, steps, cfg_scale, width, height, style):
272
+ """创建元数据"""
273
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
274
+
275
+ # 获取 LoRA 信息
276
+ lora_info = ", ".join([f"{lora['adapter_name']}({lora.get('scale', 1.0)})" for lora in LORA_CONFIGS])
277
+
278
+ return f"""Generated Image Metadata
279
+ ======================
280
+ Timestamp: {timestamp}
281
+ Original Prompt: {prompt}
282
+ Seed: {seed}
283
+ Steps: {steps}
284
+ CFG Scale: {cfg_scale}
285
+ Dimensions: {width}x{height}
286
+ Style: {style}
287
+ """
288
+
289
+ def cleanup_pipeline():
290
+ """清理 pipeline 状态,防止污染"""
291
+ global pipeline
292
+
293
+ if pipeline is None:
294
+ return
295
+
296
+ try:
297
+ # 清理 CUDA 缓存
298
+ if torch.cuda.is_available():
299
+ torch.cuda.empty_cache()
300
+ torch.cuda.ipc_collect()
301
+
302
+ # 清理 pipeline 的内部缓存
303
+ if hasattr(pipeline, 'unet'):
304
+ # 清空 UNet 的注意力缓存
305
+ if hasattr(pipeline.unet, 'set_attn_processor'):
306
+ try:
307
+ from diffusers.models.attention_processor import AttnProcessor
308
+ pipeline.unet.set_attn_processor(AttnProcessor())
309
+ except:
310
+ pass
311
+
312
+ # 清理 VAE 缓存
313
+ if hasattr(pipeline, 'vae'):
314
+ pipeline.vae.to('cpu')
315
+ pipeline.vae.to(device)
316
+
317
+ print("🧹 Pipeline cleaned")
318
+
319
+ except Exception as e:
320
+ print(f"⚠️ Cleanup warning: {e}")
321
+
322
+ @apply_spaces_decorator
323
+ def generate_image(prompt: str, style: str, negative_prompt: str = "",
324
+ steps: int = 20, cfg_scale: float = 6.0,
325
+ seed: int = -1, width: int = 896, height: int = 1152,
326
+ progress=gr.Progress()):
327
+ """图像生成主函数 - 使用Kageillustrious推荐参数"""
328
+
329
+ # 验证输入
330
+ if not prompt or prompt.strip() == "":
331
+ return None, "", "❌ Please enter a prompt"
332
+
333
+ progress(0.05, desc="Initializing...")
334
+
335
+ # 初始化模型
336
+ if not initialize_model():
337
+ return None, "", "❌ Failed to load model"
338
+
339
+ # 清理之前的状态
340
+ cleanup_pipeline()
341
+
342
+ progress(0.1, desc="Processing prompt...")
343
+
344
+ try:
345
+ # 处理seed
346
+ if seed == -1:
347
+ seed = random.randint(0, np.iinfo(np.int32).max)
348
+
349
+ # 重要:为每次生成创建新的 generator,避免状态污染
350
+ generator = torch.Generator(device).manual_seed(seed)
351
+
352
+ # 增强提示词
353
+ enhanced_prompt = enhance_prompt(prompt, style)
354
+
355
+ # 构建负面提示词
356
+ final_negative = build_negative_prompt(style, negative_prompt)
357
+
358
+ print(f"🔧 Generation params: seed={seed}, steps={steps}, cfg={cfg_scale}, size={width}x{height}")
359
+ print(f"📝 Prompt preview: {enhanced_prompt[:100]}...")
360
+
361
+ progress(0.2, desc="Generating image...")
362
+
363
+ # 检查提示词长度并决定是否使用Compel
364
+ prompt_length = len(enhanced_prompt.split())
365
+ use_compel = prompt_length > 50 and compel_processor is not None
366
+
367
+ if use_compel:
368
+ print(f"📏 Long prompt detected ({prompt_length} words), using Compel")
369
+ conditioning, pooled = process_with_compel(enhanced_prompt, final_negative)
370
+
371
+ if conditioning is not None:
372
+ # 使用embeddings生成
373
+ result = pipeline(
374
+ prompt_embeds=conditioning[0:1],
375
+ pooled_prompt_embeds=pooled[0:1],
376
+ negative_prompt_embeds=conditioning[1:2],
377
+ negative_pooled_prompt_embeds=pooled[1:2],
378
+ num_inference_steps=steps,
379
+ guidance_scale=cfg_scale,
380
+ width=width,
381
+ height=height,
382
+ generator=generator,
383
+ output_type="pil"
384
+ ).images[0]
385
+ else:
386
+ # Compel失败,回退到普通模式
387
+ print("⚠️ Falling back to standard generation")
388
+ result = pipeline(
389
+ prompt=enhanced_prompt,
390
+ negative_prompt=final_negative,
391
+ num_inference_steps=steps,
392
+ guidance_scale=cfg_scale,
393
+ width=width,
394
+ height=height,
395
+ generator=generator,
396
+ output_type="pil"
397
+ ).images[0]
398
+ else:
399
+ # 标准生成
400
+ print(f"📝 Standard generation ({prompt_length} words)")
401
+ result = pipeline(
402
+ prompt=enhanced_prompt,
403
+ negative_prompt=final_negative,
404
+ num_inference_steps=steps,
405
+ guidance_scale=cfg_scale,
406
+ width=width,
407
+ height=height,
408
+ generator=generator,
409
+ output_type="pil"
410
+ ).images[0]
411
+
412
+ progress(0.95, desc="Finalizing...")
413
+
414
+ # 确保结果是PIL Image
415
+ if not isinstance(result, Image.Image):
416
+ if isinstance(result, np.ndarray):
417
+ if result.dtype != np.uint8:
418
+ result = (result * 255).astype(np.uint8)
419
+ result = Image.fromarray(result)
420
+
421
+ # 创建元数据
422
+ metadata = create_metadata_content(
423
+ prompt, enhanced_prompt, seed, steps, cfg_scale,
424
+ width, height, style
425
+ )
426
+
427
+ generation_info = f"Style: {style} | Seed: {seed} | Size: {width}×{height} | Steps: {steps} | CFG: {cfg_scale}"
428
+
429
+ # 生成后立即清理
430
+ if torch.cuda.is_available():
431
+ torch.cuda.empty_cache()
432
+
433
+ progress(1.0, desc="Complete!")
434
+ print("✅ Generation successful\n")
435
+
436
+ return result, generation_info, metadata
437
+
438
+ except Exception as e:
439
+ error_msg = str(e)
440
+ print(f"❌ Generation error: {error_msg}")
441
+ print(traceback.format_exc())
442
+
443
+ # 错误后也要清理
444
+ try:
445
+ cleanup_pipeline()
446
+ except:
447
+ pass
448
+
449
+ return None, "", f"❌ Generation failed: {error_msg}"
450
+
451
+ # ===== CSS样式 =====
452
+ css = """
453
+ .gradio-container {
454
+ max-width: 100% !important;
455
+ margin: 0 !important;
456
+ padding: 0 !important;
457
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
458
+ min-height: 100vh !important;
459
+ font-family: 'Segoe UI', Arial, sans-serif !important;
460
+ }
461
+
462
+ .main-content {
463
+ background: rgba(255, 255, 255, 0.95) !important;
464
+ border-radius: 20px !important;
465
+ padding: 20px !important;
466
+ margin: 15px !important;
467
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2) !important;
468
+ min-height: calc(100vh - 30px) !important;
469
+ color: #3e3e3e !important;
470
+ backdrop-filter: blur(10px) !important;
471
+ }
472
+
473
+ .title {
474
+ text-align: center !important;
475
+ background: linear-gradient(45deg, #667eea, #764ba2) !important;
476
+ -webkit-background-clip: text !important;
477
+ -webkit-text-fill-color: transparent !important;
478
+ background-clip: text !important;
479
+ font-size: 2rem !important;
480
+ margin-bottom: 15px !important;
481
+ font-weight: bold !important;
482
+ }
483
+
484
+ .warning-box {
485
+ background: linear-gradient(45deg, #667eea, #764ba2) !important;
486
+ color: white !important;
487
+ padding: 8px !important;
488
+ border-radius: 8px !important;
489
+ margin-bottom: 15px !important;
490
+ text-align: center !important;
491
+ font-weight: bold !important;
492
+ font-size: 14px !important;
493
+ }
494
+
495
+ .model-info {
496
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.1), rgba(118, 75, 162, 0.1)) !important;
497
+ color: #764ba2 !important;
498
+ padding: 10px !important;
499
+ border-radius: 8px !important;
500
+ margin-bottom: 15px !important;
501
+ text-align: center !important;
502
+ font-weight: 600 !important;
503
+ font-size: 13px !important;
504
+ border: 2px solid rgba(118, 75, 162, 0.3) !important;
505
+ }
506
+
507
+ .prompt-box textarea, .prompt-box input {
508
+ border-radius: 10px !important;
509
+ border: 2px solid #667eea !important;
510
+ padding: 15px !important;
511
+ font-size: 18px !important;
512
+ background: linear-gradient(135deg, rgba(245, 243, 255, 0.9), rgba(237, 233, 254, 0.9)) !important;
513
+ color: #2d2d2d !important;
514
+ }
515
+
516
+ .prompt-box textarea:focus, .prompt-box input:focus {
517
+ border-color: #764ba2 !important;
518
+ box-shadow: 0 0 15px rgba(118, 75, 162, 0.3) !important;
519
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.95), rgba(248, 249, 250, 0.95)) !important;
520
+ }
521
+
522
+ .controls-section {
523
+ background: linear-gradient(135deg, rgba(224, 218, 255, 0.8), rgba(196, 181, 253, 0.8)) !important;
524
+ border-radius: 12px !important;
525
+ padding: 15px !important;
526
+ margin-bottom: 8px !important;
527
+ border: 2px solid rgba(102, 126, 234, 0.3) !important;
528
+ backdrop-filter: blur(5px) !important;
529
+ }
530
+
531
+ .controls-section label {
532
+ font-weight: 600 !important;
533
+ color: #2d2d2d !important;
534
+ margin-bottom: 8px !important;
535
+ }
536
+
537
+ .controls-section input[type="radio"] {
538
+ accent-color: #667eea !important;
539
+ }
540
+
541
+ .controls-section input[type="number"],
542
+ .controls-section input[type="range"] {
543
+ background: rgba(255, 255, 255, 0.9) !important;
544
+ border: 1px solid #667eea !important;
545
+ border-radius: 6px !important;
546
+ padding: 8px !important;
547
+ color: #2d2d2d !important;
548
+ }
549
+
550
+ .generate-btn {
551
+ background: linear-gradient(45deg, #667eea, #764ba2) !important;
552
+ color: white !important;
553
+ border: none !important;
554
+ padding: 15px 25px !important;
555
+ border-radius: 25px !important;
556
+ font-size: 16px !important;
557
+ font-weight: bold !important;
558
+ width: 100% !important;
559
+ cursor: pointer !important;
560
+ transition: all 0.3s ease !important;
561
+ text-transform: uppercase !important;
562
+ letter-spacing: 1px !important;
563
+ }
564
+
565
+ .generate-btn:hover {
566
+ transform: translateY(-2px) !important;
567
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.5) !important;
568
+ }
569
+
570
+ .image-output {
571
+ border-radius: 15px !important;
572
+ overflow: hidden !important;
573
+ max-width: 100% !important;
574
+ max-height: 70vh !important;
575
+ border: 3px solid #764ba2 !important;
576
+ box-shadow: 0 8px 20px rgba(0,0,0,0.15) !important;
577
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(248, 249, 250, 0.9)) !important;
578
+ }
579
+
580
+ .image-info {
581
+ background: linear-gradient(135deg, rgba(248, 249, 250, 0.9), rgba(233, 236, 239, 0.9)) !important;
582
+ border-radius: 8px !important;
583
+ padding: 12px !important;
584
+ margin-top: 10px !important;
585
+ font-size: 12px !important;
586
+ color: #495057 !important;
587
+ border: 2px solid rgba(102, 126, 234, 0.2) !important;
588
+ backdrop-filter: blur(5px) !important;
589
+ }
590
+
591
+ .metadata-box {
592
+ background: linear-gradient(135deg, rgba(248, 249, 250, 0.9), rgba(233, 236, 239, 0.9)) !important;
593
+ border-radius: 8px !important;
594
+ padding: 15px !important;
595
+ margin-top: 15px !important;
596
+ font-family: 'Courier New', monospace !important;
597
+ font-size: 12px !important;
598
+ color: #495057 !important;
599
+ border: 2px solid rgba(102, 126, 234, 0.2) !important;
600
+ backdrop-filter: blur(5px) !important;
601
+ white-space: pre-wrap !important;
602
+ overflow-y: auto !important;
603
+ max-height: 300px !important;
604
+ }
605
+
606
+ @media (max-width: 768px) {
607
+ .main-content {
608
+ margin: 10px !important;
609
+ padding: 15px !important;
610
+ }
611
+ .title {
612
+ font-size: 1.5rem !important;
613
+ }
614
+ }
615
+ """
616
+
617
+ # ===== 创建UI =====
618
+ def create_interface():
619
+ with gr.Blocks(css=css, title="ADULT AI Image Generator") as interface:
620
+ with gr.Column(elem_classes=["main-content"]):
621
+ gr.HTML('<div class="title">🎨 ADULT AI Image Generator</div>')
622
+ gr.HTML('<div class="warning-box">⚠️ 18+ CONTENT WARNING ⚠️</div>')
623
+
624
+ with gr.Row():
625
+ with gr.Column(scale=2):
626
+ prompt_input = gr.Textbox(
627
+ label="Detailed Prompt (Use Danbooru tags style)",
628
+ placeholder="1boy, solo, messy hair, blue eyes, detailed face, handsome...",
629
+ lines=15,
630
+ elem_classes=["prompt-box"]
631
+ )
632
+
633
+ negative_prompt_input = gr.Textbox(
634
+ label="Negative Prompt (Optional)",
635
+ placeholder="Additional things you don't want...",
636
+ lines=4,
637
+ elem_classes=["prompt-box"]
638
+ )
639
+
640
+ with gr.Column(scale=1):
641
+ with gr.Group(elem_classes=["controls-section"]):
642
+ style_input = gr.Radio(
643
+ label="Style Preset",
644
+ choices=list(STYLE_KEYWORDS.keys()),
645
+ value="Standard Quality"
646
+ )
647
+
648
+ with gr.Group(elem_classes=["controls-section"]):
649
+ seed_input = gr.Number(
650
+ label="Seed (-1 for random)",
651
+ value=-1,
652
+ precision=0
653
+ )
654
+
655
+ with gr.Group(elem_classes=["controls-section"]):
656
+ width_input = gr.Slider(
657
+ label="Width",
658
+ minimum=512,
659
+ maximum=2048,
660
+ value=896,
661
+ step=64,
662
+ info="Recommended: 896"
663
+ )
664
+
665
+ with gr.Group(elem_classes=["controls-section"]):
666
+ height_input = gr.Slider(
667
+ label="Height",
668
+ minimum=512,
669
+ maximum=2048,
670
+ value=1152,
671
+ step=64,
672
+ info="Recommended: 1152"
673
+ )
674
+
675
+ with gr.Group(elem_classes=["controls-section"]):
676
+ steps_input = gr.Slider(
677
+ label="Steps",
678
+ minimum=10,
679
+ maximum=50,
680
+ value=20,
681
+ step=1,
682
+ info="Recommended: 20"
683
+ )
684
+
685
+ cfg_input = gr.Slider(
686
+ label="CFG Scale",
687
+ minimum=1.0,
688
+ maximum=15.0,
689
+ value=6.0,
690
+ step=0.1,
691
+ info="Recommended: 6.0"
692
+ )
693
+
694
+ generate_button = gr.Button(
695
+ "GENERATE",
696
+ elem_classes=["generate-btn"],
697
+ variant="primary"
698
+ )
699
+
700
+ image_output = gr.Image(
701
+ label="Generated Image",
702
+ elem_classes=["image-output"],
703
+ show_label=False,
704
+ container=True
705
+ )
706
+
707
+ with gr.Row():
708
+ generation_info = gr.Textbox(
709
+ label="Generation Info",
710
+ interactive=False,
711
+ elem_classes=["image-info"],
712
+ show_label=True,
713
+ visible=False
714
+ )
715
+
716
+ with gr.Row():
717
+ metadata_display = gr.Textbox(
718
+ label="Image Metadata",
719
+ interactive=True,
720
+ elem_classes=["metadata-box"],
721
+ show_label=True,
722
+ lines=15,
723
+ visible=False
724
+ )
725
+
726
+ def on_generate(prompt, style, neg_prompt, steps, cfg, seed, width, height):
727
+ image, info, metadata = generate_image(
728
+ prompt, style, neg_prompt, steps, cfg, seed, width, height
729
+ )
730
+
731
+ if image is not None:
732
+ return (
733
+ image,
734
+ info,
735
+ metadata,
736
+ gr.update(visible=True, value=info),
737
+ gr.update(visible=True, value=metadata)
738
+ )
739
+ else:
740
+ return (
741
+ None,
742
+ info,
743
+ "",
744
+ gr.update(visible=False),
745
+ gr.update(visible=False)
746
+ )
747
+
748
+ generate_button.click(
749
+ fn=on_generate,
750
+ inputs=[
751
+ prompt_input, style_input, negative_prompt_input,
752
+ steps_input, cfg_input, seed_input, width_input, height_input
753
+ ],
754
+ outputs=[
755
+ image_output, generation_info, metadata_display,
756
+ generation_info, metadata_display
757
+ ],
758
+ show_progress=True
759
+ )
760
+
761
+ prompt_input.submit(
762
+ fn=on_generate,
763
+ inputs=[
764
+ prompt_input, style_input, negative_prompt_input,
765
+ steps_input, cfg_input, seed_input, width_input, height_input
766
+ ],
767
+ outputs=[
768
+ image_output, generation_info, metadata_display,
769
+ generation_info, metadata_display
770
+ ],
771
+ show_progress=True
772
+ )
773
+
774
+ return interface
775
+
776
+ # ===== 启动应用 =====
777
+ if __name__ == "__main__":
778
+ print("\n" + "="*50)
779
+ print("🚀 Starting ADULT AI Image Generator (YAOI Friendly) ")
780
+ print("="*50)
781
+ print(f"📦 Model: {FIXED_MODEL_REPO}")
782
+ print(f"📄 Model File: {FIXED_MODEL_FILE}")
783
+ print(f"🖥️ Device: {'CUDA' if torch.cuda.is_available() else 'CPU'}")
784
+ print(f"⚡ ZeroGPU: {'Enabled' if SPACES_AVAILABLE else 'Disabled'}")
785
+ print(f"📝 Compel: {'Available' if COMPEL_AVAILABLE else 'Not Available'}")
786
+ if LORA_CONFIGS:
787
+ print(f"🎨 LoRA: LogoRedmond-LogoLoraForSDXL-V2 (scale: {LORA_CONFIGS[0].get('scale', 0.8)})")
788
+ print("="*50 + "\n")
789
+
790
+ # 不预加载模���,让ZeroGPU按需分配
791
+ # 这样可以避免GPU分配冲突
792
+
793
+ app = create_interface()
794
+ app.queue(max_size=10, default_concurrency_limit=2)
795
+
796
+ app.launch(
797
+ server_name="0.0.0.0",
798
+ server_port=7860,
799
+ share=False
800
+ )
app_log.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ⚠️ Spaces not available - running in regular mode
2
+ 2026-05-16 18:12:52.886593: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
3
+ 2026-05-16 18:13:11.504646: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
4
+ ✅ Compel available for long prompt processing
5
+
6
+ ==================================================
7
+ 🚀 Starting ADULT AI Image Generator (YAOI Friendly)
8
+ ==================================================
9
+ 📂 Local model directory: G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion
10
+ 📄 Available local models: Cartoonish.safetensors, add-micro-details-concept-illustrious-or-pony-or-noobai.safetensors, ass-ripple-also-known-.safetensors, kageillustrious_v60NLXLVersion.safetensors, nova-anime-xl.safetensors, nova-furry-xl.safetensors, nova-orange-xl.safetensors, novaAnimeXL.safetensors, ntrnetorare.safetensors, ramthrusts-nsfw-pink-alchemy-mix.safetensors, wai-illustrious-sdxl.safetensors
11
+ 🖥️ Device: CPU
12
+ ΓÜí ZeroGPU: Disabled
13
+ 📝 Compel: Available
14
+ 🎨 LoRA: LogoRedmond-LogoLoraForSDXL-V2 (scale: 0.8)
15
+ ==================================================
16
+
17
+ 🚪 Launching Gradio on port: 62173
18
+ * Running on local URL: http://0.0.0.0:62173
19
+ * Running on public URL: https://b4d65e015773a6fbb5.gradio.live
20
+
21
+ This share link expires in 1 week. For free permanent hosting and GPU upgrades, run `gradio deploy` from the terminal in the working directory to deploy to Hugging Face Spaces (https://huggingface.co/spaces)
app_run_log.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ 2026-05-16 18:19:20.540581: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2
+ 2026-05-16 18:19:31.317168: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
3
+ ⚠️ Spaces not available - running in regular mode
launch.log ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ⚠️ Spaces not available - running in regular mode
2
+ 2026-05-16 17:45:18.175228: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
3
+ 2026-05-16 17:46:31.210179: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
4
+ ✅ Compel available for long prompt processing
5
+
6
+ ==================================================
7
+ 🚀 Starting ADULT AI Image Generator (YAOI Friendly)
8
+ ==================================================
9
+ � Local model directory: G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion
10
+ 📄 Available local models: Cartoonish.safetensors, add-micro-details-concept-illustrious-or-pony-or-noobai.safetensors, ass-ripple-also-known-.safetensors, kageillustrious_v60NLXLVersion.safetensors, nova-anime-xl.safetensors, nova-furry-xl.safetensors, nova-orange-xl.safetensors, novaAnimeXL.safetensors, ntrnetorare.safetensors, ramthrusts-nsfw-pink-alchemy-mix.safetensors, wai-illustrious-sdxl.safetensors
11
+ 🖥️ Device: CPU
12
+ ⚡ ZeroGPU: Disabled
13
+ 📝 Compel: Available
14
+ 🎨 LoRA: LogoRedmond-LogoLoraForSDXL-V2 (scale: 0.8)
15
+ ==================================================
16
+
17
+ c:\Users\LAPTOP_PC\Desktop\New Folder\Raw_Alexander\app.py:675: UserWarning: The parameters have been moved from the Blocks constructor to the launch() method in Gradio 6.0: css. Please pass these parameters to launch() instead.
18
+ with gr.Blocks(css=css, title="ADULT AI Image Generator") as interface:
19
+ ERROR: [Errno 10048] error while attempting to bind on address ('0.0.0.0', 7860): only one usage of each socket address (protocol/network address/port) is normally permitted
20
+ Traceback (most recent call last):
21
+ File "c:\Users\LAPTOP_PC\Desktop\New Folder\Raw_Alexander\app.py", line 864, in <module>
22
+ app.launch(server_name="0.0.0.0",
23
+ File "C:\Users\LAPTOP_PC\AppData\Local\Programs\Python\Python311\Lib\site-packages\gradio\blocks.py", line 2774, in launch
24
+ ) = http_server.start_server(
25
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
26
+ File "C:\Users\LAPTOP_PC\AppData\Local\Programs\Python\Python311\Lib\site-packages\gradio\http_server.py", line 182, in start_server
27
+ raise OSError(
28
+ OSError: Cannot find empty port in range: 7860-7860. You can specify a different port by setting the GRADIO_SERVER_PORT environment variable or passing the `server_port` parameter to `launch()`.
list_models.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ p=r'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion'
3
+ files=[f for f in os.listdir(p) if os.path.splitext(f)[1].lower() in ['.safetensors','.ckpt']]
4
+ for f in sorted(files):
5
+ fp=os.path.join(p,f)
6
+ try:
7
+ s=os.path.getsize(fp)
8
+ except Exception as e:
9
+ s=0
10
+ print(f, s//(1024*1024), 'MB')
requirements.txt ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ===== Core ML Stack =====
2
+ # torch 和 torchvision 由 ZeroGPU 自动管理,不要写死版本
3
+
4
+ # Stable Diffusion + LoRA
5
+ diffusers==0.31.0
6
+ transformers==4.46.3
7
+ accelerate==1.1.1
8
+ safetensors==0.4.5
9
+ peft==0.13.2
10
+ compel==2.0.3
11
+
12
+ # huggingface_hub 版本必须 <1.0 以兼容 transformers 4.46.3
13
+ huggingface-hub>=0.23.2,<1.0
14
+
15
+ # Gradio 和 spaces 由 ZeroGPU 自动管理,不要写死版本
16
+
17
+ # Core Utilities
18
+ Pillow==11.0.0
19
+ numpy==1.26.4
20
+ python-dateutil==2.9.0.post0
21
+
22
+ # For logging / error handling
23
+ requests==2.32.3
24
+ tqdm==4.66.5
25
+
26
+ # Optional visualization/debugging
27
+ matplotlib==3.9.2
run_sample.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from app import LOCAL_MODEL_DIRECTORY, get_local_models, initialize_model, generate_image
2
+ import os
3
+
4
+ models = get_local_models()
5
+ if not models:
6
+ print('No local models found')
7
+ raise SystemExit(1)
8
+
9
+ models_with_size = []
10
+ for model_name in models:
11
+ model_path = os.path.join(LOCAL_MODEL_DIRECTORY, model_name)
12
+ try:
13
+ size = os.path.getsize(model_path)
14
+ except OSError:
15
+ size = float('inf')
16
+ if size >= 50 * 1024 * 1024:
17
+ models_with_size.append((size, model_name))
18
+
19
+ if not models_with_size:
20
+ print('No valid model files found with size >= 50MB')
21
+ raise SystemExit(1)
22
+
23
+ model = min(models_with_size, key=lambda x: x[0])[1]
24
+ print('Using model:', model)
25
+
26
+ ok = initialize_model(model)
27
+ if not ok:
28
+ print('Failed to initialize model')
29
+ raise SystemExit(1)
30
+
31
+ prompt = "A cinematic, photorealistic landscape, dramatic lighting, 8k"
32
+
33
+ images, info, meta = generate_image(
34
+ prompt=prompt,
35
+ style='Standard Quality',
36
+ negative_prompt='',
37
+ steps=20,
38
+ cfg_scale=6.0,
39
+ seed=-1,
40
+ width=896,
41
+ height=1152,
42
+ model_name=model,
43
+ num_images=2,
44
+ progress=lambda *a, **k: None
45
+ )
46
+
47
+ print(info)
48
+ print(meta)
49
+
50
+ os.makedirs('generated_images', exist_ok=True)
51
+ for i, img in enumerate(images):
52
+ path = os.path.join('generated_images', f'sample_{i}.png')
53
+ img.save(path)
54
+ print('Saved', path)
run_sample_small.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from app import get_local_models, initialize_model, generate_image
2
+ import os
3
+ models = get_local_models()
4
+ # pick smallest non-zero model
5
+ p=r'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion'
6
+ models_with_size = []
7
+ for m in models:
8
+ fp=os.path.join(p,m)
9
+ try:
10
+ s=os.path.getsize(fp)
11
+ except:
12
+ s=0
13
+ if s>0:
14
+ models_with_size.append((s,m))
15
+ if not models_with_size:
16
+ print('No usable models found')
17
+ raise SystemExit(1)
18
+ models_with_size.sort()
19
+ model=models_with_size[0][1]
20
+ print('Using model:', model)
21
+ ok=initialize_model(model)
22
+ if not ok:
23
+ print('Failed to initialize model')
24
+ raise SystemExit(1)
25
+ prompt='A cinematic, photorealistic landscape, dramatic lighting, 8k'
26
+ images, info, meta = generate_image(prompt=prompt, style='Standard Quality', negative_prompt='', steps=20, cfg_scale=6.0, seed=-1, width=896, height=1152, model_name=model, num_images=2, progress=lambda *a, **k: None)
27
+ print(info)
28
+ print(meta)
29
+ os.makedirs('generated_images', exist_ok=True)
30
+ for i, img in enumerate(images):
31
+ path=os.path.join('generated_images', f'small_sample_{i}.png')
32
+ img.save(path)
33
+ print('Saved', path)
run_small_log.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2026-05-16 18:29:52.087943: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2
+ 2026-05-16 18:30:00.633376: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
3
+ ⚠️ Spaces not available - running in regular mode
4
+ ✅ Compel available for long prompt processing
5
+ Using model: ass-ripple-also-known-.safetensors
6
+ 🖥️ Using device: cpu
7
+ 📦 Loading local model from: G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion\ass-ripple-also-known-.safetensors
8
+ ⚠️ SDXL load failed: Unable to load weights from checkpoint file for 'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion\ass-ripple-also-known-.safetensors' at 'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion\ass-ripple-also-known-.safetensors'.
9
+ ℹ️ Attempting low-memory load (may use device mapping / lower precision)...
10
+ ⚠️ Low-memory SDXL load failed: Unable to load weights from checkpoint file for 'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion\ass-ripple-also-known-.safetensors' at 'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion\ass-ripple-also-known-.safetensors'.
11
+ ℹ️ Falling back to standard Stable Diffusion loader
12
+ ⚠️ Standard SD load failed: Unable to load weights from checkpoint file for 'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion\ass-ripple-also-known-.safetensors' at 'G:\My Drive\sd\stable-diffusion-webui\models\Stable-diffusion\ass-ripple-also-known-.safetensors'.
13
+ ❌ Model loading error: 'NoneType' object has no attribute 'to'
14
+ Traceback (most recent call last):
15
+ File "C:\Users\LAPTOP_PC\Desktop\New Folder\Raw_Alexander\app.py", line 226, in initialize_model
16
+ pipeline = pipeline.to(device)
17
+ ^^^^^^^^^^^
18
+ AttributeError: 'NoneType' object has no attribute 'to'
19
+
20
+ Failed to initialize model