Spaces:
Running on Zero
Running on Zero
Commit ·
5cc4c4c
1
Parent(s): 2e15546
Quality fix: majicMIX model, Euler a, CLIP skip 2, 512x768 default, stronger negatives (#8)
Browse files- Quality fix: majicMIX model, Euler a, CLIP skip 2, 512x768 default, stronger negatives (903bdd98b974777129df83dab9891a00b1634498)
Co-authored-by: pormungtailaw <pormungtai@users.noreply.huggingface.co>
- app.py +5 -4
- models.json +41 -5
- pipeline_manager.py +11 -0
app.py
CHANGED
|
@@ -109,8 +109,7 @@ def _apply_model(models, model_id):
|
|
| 109 |
"""Shared: given a selected model id, return the dependent UI updates."""
|
| 110 |
cfg = pm.get_model(models, model_id)
|
| 111 |
if not cfg:
|
| 112 |
-
return (gr.update()
|
| 113 |
-
"ไม่พบโมเดล / model not found")
|
| 114 |
choices = modes_for(models, model_id)
|
| 115 |
return (
|
| 116 |
gr.update(choices=choices, value=choices[0][1]), # mode radio
|
|
@@ -118,6 +117,8 @@ def _apply_model(models, model_id):
|
|
| 118 |
gr.update(value=cfg.get("negative_prompt", "")), # negative
|
| 119 |
gr.update(value=cfg.get("default_steps", 28)), # steps
|
| 120 |
gr.update(value=cfg.get("default_guidance", 6.0)), # guidance
|
|
|
|
|
|
|
| 121 |
f"**เลือก / Selected:** {cfg['label']}", # selected label
|
| 122 |
)
|
| 123 |
|
|
@@ -208,7 +209,7 @@ with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="blue"),
|
|
| 208 |
steps = gr.Slider(1, 50, value=28, step=1, label="Steps")
|
| 209 |
guidance = gr.Slider(0.0, 15.0, value=6.5, step=0.1, label="Guidance (CFG)")
|
| 210 |
with gr.Row():
|
| 211 |
-
width = gr.Slider(384, 1280, value=
|
| 212 |
height = gr.Slider(384, 1280, value=768, step=64, label="Height")
|
| 213 |
with gr.Row():
|
| 214 |
seed = gr.Number(value=-1, label="Seed (-1 = random)", precision=0)
|
|
@@ -218,7 +219,7 @@ with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="blue"),
|
|
| 218 |
model_gallery.select(
|
| 219 |
on_gallery_select, inputs=[ids_state],
|
| 220 |
outputs=[selected_id, mode_radio, prompt, negative_prompt,
|
| 221 |
-
steps, guidance, selected_md],
|
| 222 |
)
|
| 223 |
reload_btn.click(
|
| 224 |
reload_registry,
|
|
|
|
| 109 |
"""Shared: given a selected model id, return the dependent UI updates."""
|
| 110 |
cfg = pm.get_model(models, model_id)
|
| 111 |
if not cfg:
|
| 112 |
+
return (*[gr.update() for _ in range(7)], "ไม่พบโมเดล / model not found")
|
|
|
|
| 113 |
choices = modes_for(models, model_id)
|
| 114 |
return (
|
| 115 |
gr.update(choices=choices, value=choices[0][1]), # mode radio
|
|
|
|
| 117 |
gr.update(value=cfg.get("negative_prompt", "")), # negative
|
| 118 |
gr.update(value=cfg.get("default_steps", 28)), # steps
|
| 119 |
gr.update(value=cfg.get("default_guidance", 6.0)), # guidance
|
| 120 |
+
gr.update(value=cfg.get("default_width", 768)), # width
|
| 121 |
+
gr.update(value=cfg.get("default_height", 768)), # height
|
| 122 |
f"**เลือก / Selected:** {cfg['label']}", # selected label
|
| 123 |
)
|
| 124 |
|
|
|
|
| 209 |
steps = gr.Slider(1, 50, value=28, step=1, label="Steps")
|
| 210 |
guidance = gr.Slider(0.0, 15.0, value=6.5, step=0.1, label="Guidance (CFG)")
|
| 211 |
with gr.Row():
|
| 212 |
+
width = gr.Slider(384, 1280, value=512, step=64, label="Width")
|
| 213 |
height = gr.Slider(384, 1280, value=768, step=64, label="Height")
|
| 214 |
with gr.Row():
|
| 215 |
seed = gr.Number(value=-1, label="Seed (-1 = random)", precision=0)
|
|
|
|
| 219 |
model_gallery.select(
|
| 220 |
on_gallery_select, inputs=[ids_state],
|
| 221 |
outputs=[selected_id, mode_radio, prompt, negative_prompt,
|
| 222 |
+
steps, guidance, width, height, selected_md],
|
| 223 |
)
|
| 224 |
reload_btn.click(
|
| 225 |
reload_registry,
|
models.json
CHANGED
|
@@ -1,7 +1,25 @@
|
|
| 1 |
{
|
| 2 |
-
"_comment": "Editable model registry. Add/remove entries freely, then restart
|
| 3 |
|
| 4 |
"models": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
{
|
| 6 |
"id": "sd15-realistic-base",
|
| 7 |
"label": "SD1.5 · Realistic Base",
|
|
@@ -11,8 +29,11 @@
|
|
| 11 |
"single_file_url": null,
|
| 12 |
"preview": "previews/sd15-realistic-base.webp",
|
| 13 |
"trigger": "",
|
|
|
|
|
|
|
|
|
|
| 14 |
"recommended_prompt": "RAW photo, a beautiful woman, detailed skin, soft lighting, 50mm, depth of field",
|
| 15 |
-
"negative_prompt": "(worst quality, low quality:1.4),
|
| 16 |
"default_steps": 28,
|
| 17 |
"default_guidance": 6.5,
|
| 18 |
"enabled": true
|
|
@@ -29,8 +50,11 @@
|
|
| 29 |
"lora_scale": 0.8,
|
| 30 |
"preview": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/031e4408-3098-4f4a-9a05-d499cedf513a/width=450/747945.jpeg",
|
| 31 |
"trigger": "",
|
|
|
|
|
|
|
|
|
|
| 32 |
"recommended_prompt": "RAW photo, asian girl, pretty face, natural skin texture, cinematic light",
|
| 33 |
-
"negative_prompt": "(worst quality, low quality:1.4), deformed, watermark, text",
|
| 34 |
"default_steps": 28,
|
| 35 |
"default_guidance": 6.5,
|
| 36 |
"enabled": true
|
|
@@ -44,8 +68,11 @@
|
|
| 44 |
"single_file_url": "https://civitai.com/api/download/models/127016",
|
| 45 |
"preview": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/9c67da8b-5e57-413c-a5ca-135f5ed9af18/width=450/1743066.jpeg",
|
| 46 |
"trigger": "",
|
|
|
|
|
|
|
|
|
|
| 47 |
"recommended_prompt": "RAW photo, beautiful asian woman, elegant dress, soft cinematic light, ultra detailed",
|
| 48 |
-
"negative_prompt": "(worst quality, low quality:1.4), deformed, watermark, text",
|
| 49 |
"default_steps": 28,
|
| 50 |
"default_guidance": 6.0,
|
| 51 |
"enabled": true
|
|
@@ -59,6 +86,9 @@
|
|
| 59 |
"single_file_url": null,
|
| 60 |
"preview": "previews/sdxl-base.webp",
|
| 61 |
"trigger": "",
|
|
|
|
|
|
|
|
|
|
| 62 |
"recommended_prompt": "cinematic photo of a beautiful woman, 35mm, highly detailed, soft natural light",
|
| 63 |
"negative_prompt": "lowres, bad anatomy, worst quality, watermark, text",
|
| 64 |
"default_steps": 30,
|
|
@@ -74,6 +104,9 @@
|
|
| 74 |
"single_file_url": null,
|
| 75 |
"preview": "previews/flux-schnell.webp",
|
| 76 |
"trigger": "",
|
|
|
|
|
|
|
|
|
|
| 77 |
"recommended_prompt": "a photorealistic portrait of a young woman, studio light, sharp focus, ultra detailed",
|
| 78 |
"negative_prompt": "",
|
| 79 |
"default_steps": 4,
|
|
@@ -87,8 +120,11 @@
|
|
| 87 |
"type": "checkpoint",
|
| 88 |
"repo_id": "black-forest-labs/FLUX.1-dev",
|
| 89 |
"single_file_url": null,
|
| 90 |
-
"preview": "
|
| 91 |
"trigger": "",
|
|
|
|
|
|
|
|
|
|
| 92 |
"recommended_prompt": "a photorealistic portrait of a young woman, golden hour, 85mm, bokeh, ultra detailed",
|
| 93 |
"negative_prompt": "",
|
| 94 |
"default_steps": 25,
|
|
|
|
| 1 |
{
|
| 2 |
+
"_comment": "Editable model registry. Add/remove entries freely, then restart (or click 🔄 Reload models). `clip_skip` uses A1111 convention (2 = skip one layer, common for SD1.5 community models). `default_width`/`default_height` set the canvas when the model is picked. See README_TH.md.",
|
| 3 |
|
| 4 |
"models": [
|
| 5 |
+
{
|
| 6 |
+
"id": "majicmix-realistic-v7",
|
| 7 |
+
"label": "majicMIX Realistic V7 (SD1.5)",
|
| 8 |
+
"base": "sd15",
|
| 9 |
+
"type": "checkpoint",
|
| 10 |
+
"repo_id": "digiplay/majicMIX_realistic_v7",
|
| 11 |
+
"single_file_url": null,
|
| 12 |
+
"preview": "previews/majicmix-realistic-v7.webp",
|
| 13 |
+
"trigger": "",
|
| 14 |
+
"clip_skip": 2,
|
| 15 |
+
"default_width": 512,
|
| 16 |
+
"default_height": 768,
|
| 17 |
+
"recommended_prompt": "RAW photo, portrait of a beautiful woman, detailed skin, soft cinematic light, 50mm, depth of field, ultra detailed",
|
| 18 |
+
"negative_prompt": "(worst quality, low quality, normal quality:1.4), lowres, bad anatomy, bad hands, extra digits, fewer digits, deformed, disfigured, mutated, extra limbs, duplicate, cropped, watermark, text, signature, jpeg artifacts",
|
| 19 |
+
"default_steps": 28,
|
| 20 |
+
"default_guidance": 7.0,
|
| 21 |
+
"enabled": true
|
| 22 |
+
},
|
| 23 |
{
|
| 24 |
"id": "sd15-realistic-base",
|
| 25 |
"label": "SD1.5 · Realistic Base",
|
|
|
|
| 29 |
"single_file_url": null,
|
| 30 |
"preview": "previews/sd15-realistic-base.webp",
|
| 31 |
"trigger": "",
|
| 32 |
+
"clip_skip": 1,
|
| 33 |
+
"default_width": 512,
|
| 34 |
+
"default_height": 768,
|
| 35 |
"recommended_prompt": "RAW photo, a beautiful woman, detailed skin, soft lighting, 50mm, depth of field",
|
| 36 |
+
"negative_prompt": "(worst quality, low quality:1.4), lowres, bad anatomy, bad hands, extra digits, deformed, duplicate, watermark, text",
|
| 37 |
"default_steps": 28,
|
| 38 |
"default_guidance": 6.5,
|
| 39 |
"enabled": true
|
|
|
|
| 50 |
"lora_scale": 0.8,
|
| 51 |
"preview": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/031e4408-3098-4f4a-9a05-d499cedf513a/width=450/747945.jpeg",
|
| 52 |
"trigger": "",
|
| 53 |
+
"clip_skip": 2,
|
| 54 |
+
"default_width": 512,
|
| 55 |
+
"default_height": 768,
|
| 56 |
"recommended_prompt": "RAW photo, asian girl, pretty face, natural skin texture, cinematic light",
|
| 57 |
+
"negative_prompt": "(worst quality, low quality:1.4), lowres, bad anatomy, bad hands, deformed, duplicate, watermark, text",
|
| 58 |
"default_steps": 28,
|
| 59 |
"default_guidance": 6.5,
|
| 60 |
"enabled": true
|
|
|
|
| 68 |
"single_file_url": "https://civitai.com/api/download/models/127016",
|
| 69 |
"preview": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/9c67da8b-5e57-413c-a5ca-135f5ed9af18/width=450/1743066.jpeg",
|
| 70 |
"trigger": "",
|
| 71 |
+
"clip_skip": 2,
|
| 72 |
+
"default_width": 512,
|
| 73 |
+
"default_height": 768,
|
| 74 |
"recommended_prompt": "RAW photo, beautiful asian woman, elegant dress, soft cinematic light, ultra detailed",
|
| 75 |
+
"negative_prompt": "(worst quality, low quality:1.4), lowres, bad anatomy, bad hands, deformed, duplicate, watermark, text",
|
| 76 |
"default_steps": 28,
|
| 77 |
"default_guidance": 6.0,
|
| 78 |
"enabled": true
|
|
|
|
| 86 |
"single_file_url": null,
|
| 87 |
"preview": "previews/sdxl-base.webp",
|
| 88 |
"trigger": "",
|
| 89 |
+
"clip_skip": 1,
|
| 90 |
+
"default_width": 1024,
|
| 91 |
+
"default_height": 1024,
|
| 92 |
"recommended_prompt": "cinematic photo of a beautiful woman, 35mm, highly detailed, soft natural light",
|
| 93 |
"negative_prompt": "lowres, bad anatomy, worst quality, watermark, text",
|
| 94 |
"default_steps": 30,
|
|
|
|
| 104 |
"single_file_url": null,
|
| 105 |
"preview": "previews/flux-schnell.webp",
|
| 106 |
"trigger": "",
|
| 107 |
+
"clip_skip": 1,
|
| 108 |
+
"default_width": 1024,
|
| 109 |
+
"default_height": 1024,
|
| 110 |
"recommended_prompt": "a photorealistic portrait of a young woman, studio light, sharp focus, ultra detailed",
|
| 111 |
"negative_prompt": "",
|
| 112 |
"default_steps": 4,
|
|
|
|
| 120 |
"type": "checkpoint",
|
| 121 |
"repo_id": "black-forest-labs/FLUX.1-dev",
|
| 122 |
"single_file_url": null,
|
| 123 |
+
"preview": "previews/flux-schnell.webp",
|
| 124 |
"trigger": "",
|
| 125 |
+
"clip_skip": 1,
|
| 126 |
+
"default_width": 1024,
|
| 127 |
+
"default_height": 1024,
|
| 128 |
"recommended_prompt": "a photorealistic portrait of a young woman, golden hour, 85mm, bokeh, ultra detailed",
|
| 129 |
"negative_prompt": "",
|
| 130 |
"default_steps": 25,
|
pipeline_manager.py
CHANGED
|
@@ -165,6 +165,12 @@ def _build_base_pipeline(cfg):
|
|
| 165 |
except Exception as e: # noqa
|
| 166 |
print(f"[lora] fuse skipped: {e}")
|
| 167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
pipe.set_progress_bar_config(disable=True)
|
| 169 |
pipe._cs_adapter = None # track loaded IP-Adapter / FaceID state
|
| 170 |
return pipe
|
|
@@ -284,6 +290,11 @@ def run_generation(cfg, mode, prompt, negative_prompt, ref_image,
|
|
| 284 |
else:
|
| 285 |
call["guidance_scale"] = float(guidance)
|
| 286 |
call["negative_prompt"] = negative_prompt or None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
|
| 288 |
# ----- mode wiring -----
|
| 289 |
if mode == "txt2img":
|
|
|
|
| 165 |
except Exception as e: # noqa
|
| 166 |
print(f"[lora] fuse skipped: {e}")
|
| 167 |
|
| 168 |
+
# SD1.5 / SDXL community checkpoints are tuned for the Euler Ancestral sampler;
|
| 169 |
+
# it matches the look people get in A1111 / ComfyUI far better than the default.
|
| 170 |
+
if base in ("sd15", "sdxl"):
|
| 171 |
+
from diffusers import EulerAncestralDiscreteScheduler
|
| 172 |
+
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
|
| 173 |
+
|
| 174 |
pipe.set_progress_bar_config(disable=True)
|
| 175 |
pipe._cs_adapter = None # track loaded IP-Adapter / FaceID state
|
| 176 |
return pipe
|
|
|
|
| 290 |
else:
|
| 291 |
call["guidance_scale"] = float(guidance)
|
| 292 |
call["negative_prompt"] = negative_prompt or None
|
| 293 |
+
# CLIP skip: registry stores the A1111 value (2 = skip one layer); diffusers
|
| 294 |
+
# counts skipped layers, so A1111 "2" == diffusers clip_skip=1.
|
| 295 |
+
a1111_cs = int(cfg.get("clip_skip", 1))
|
| 296 |
+
if a1111_cs > 1:
|
| 297 |
+
call["clip_skip"] = a1111_cs - 1
|
| 298 |
|
| 299 |
# ----- mode wiring -----
|
| 300 |
if mode == "txt2img":
|