ImageStudio Maintainer Claude Opus 4.8 (1M context) commited on
Commit
50c4793
·
1 Parent(s): 4f84136

feat: switch both pipelines to custom dataset checkpoints

Browse files

Load single-file checkpoints from the nsfwalex/checkpoint_n_lora dataset
instead of the stock HF models:
- Z-Image pipeline -> Moody Pro Mix (ZIT V12 DPO), a transformer-only
Z-Image-Turbo finetune swapped into the base pipeline via
ZImageTransformer2DModel.from_single_file.
- SDXL pipeline -> One Obsession v2.1 Anime (Illustrious) via
StableDiffusionXLPipeline.from_single_file, keeping the fp16-fix VAE
and Compel prompt weighting.

Relabels the model dropdown and helper text to the new model names.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +62 -17
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import io
 
2
  import random
3
  import re
4
 
@@ -6,8 +7,14 @@ import numpy as np
6
  import torch
7
  import spaces
8
  import gradio as gr
9
- from diffusers import DiffusionPipeline, AutoPipelineForText2Image, AutoencoderKL
 
 
 
 
 
10
  from compel import Compel, ReturnedEmbeddingsType
 
11
 
12
  import r2_uploader
13
 
@@ -19,13 +26,39 @@ R2_NAMESPACE = "s01"
19
  # =============================================================================
20
  # Model registry
21
  # =============================================================================
22
- # Two pipelines are exposed through a single UI via the selector below:
23
- # * Z-Image-Turbo -> fast, guidance-free distilled model (8 DiT forwards)
24
- # * NoobAI-XL v1.1 -> SDXL anime model with Compel prompt weighting
25
- MODEL_ZIMAGE = "Z-Image-Turbo"
26
- MODEL_NOOBXL = "NoobAI-XL v1.1"
 
 
 
 
27
  MODEL_CHOICES = [MODEL_ZIMAGE, MODEL_NOOBXL]
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  MAX_SEED = np.iinfo(np.int32).max
30
 
31
  NOOBXL_NEGATIVE = (
@@ -38,20 +71,32 @@ NOOBXL_NEGATIVE = (
38
  # Load both pipelines once at startup. On ZeroGPU the `.to("cuda")` calls are
39
  # captured by the runtime and the work happens inside the @spaces.GPU function.
40
  # -----------------------------------------------------------------------------
41
- print("Loading Z-Image-Turbo pipeline...")
 
 
 
 
 
 
 
 
 
 
42
  zimage_pipe = DiffusionPipeline.from_pretrained(
43
- "Tongyi-MAI/Z-Image-Turbo",
 
44
  torch_dtype=torch.bfloat16,
45
  low_cpu_mem_usage=False,
46
  )
47
  zimage_pipe.to("cuda")
48
 
49
- print("Loading NoobAI-XL v1.1 pipeline...")
 
50
  noobxl_vae = AutoencoderKL.from_pretrained(
51
  "madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16
52
  )
53
- noobxl_pipe = AutoPipelineForText2Image.from_pretrained(
54
- "Menyu/noobaiXLNAIXL_epsilonPred11Version",
55
  vae=noobxl_vae,
56
  torch_dtype=torch.float16,
57
  use_safetensors=True,
@@ -397,7 +442,7 @@ def apply_model_defaults(model_name):
397
  return (
398
  gr.update(value=d["steps"]),
399
  gr.update(value=d["guidance"], interactive=is_noob,
400
- info="Z-Image-Turbo is guidance-free (forced to 0)" if not is_noob else "Classifier-free guidance"),
401
  gr.update(value=d["height"]),
402
  gr.update(value=d["width"]),
403
  gr.update(visible=is_noob),
@@ -484,7 +529,7 @@ with gr.Blocks(fill_height=True) as demo:
484
  choices=MODEL_CHOICES,
485
  value=MODEL_ZIMAGE,
486
  label="🧠 Model",
487
- info="Z-Image-Turbo: fast & general • NoobAI-XL: anime / illustration",
488
  )
489
 
490
  prompt = gr.Textbox(
@@ -522,13 +567,13 @@ with gr.Blocks(fill_height=True) as demo:
522
  num_inference_steps = gr.Slider(
523
  minimum=1, maximum=50, value=9, step=1,
524
  label="Inference Steps",
525
- info="Z-Image: ~9 • NoobAI-XL: ~28",
526
  )
527
 
528
  guidance_scale = gr.Slider(
529
  minimum=0.0, maximum=10.0, value=0.0, step=0.1,
530
  label="Guidance Scale",
531
- info="Z-Image-Turbo is guidance-free (forced to 0)",
532
  interactive=False,
533
  )
534
 
@@ -567,8 +612,8 @@ with gr.Blocks(fill_height=True) as demo:
567
  ---
568
  <div style="text-align: center; opacity: 0.7; font-size: 0.9em; margin-top: 1rem;">
569
  <strong>Models:</strong>
570
- <a href="https://huggingface.co/Tongyi-MAI/Z-Image-Turbo" target="_blank">Z-Image-Turbo</a> •
571
- <a href="https://huggingface.co/Menyu/noobaiXLNAIXL_epsilonPred11Version" target="_blank">NoobAI-XL v1.1</a> •
572
  <strong>Demo by:</strong> <a href="https://x.com/realmrfakename" target="_blank">@mrfakename</a>
573
  </div>
574
  """,
 
1
  import io
2
+ import os
3
  import random
4
  import re
5
 
 
7
  import torch
8
  import spaces
9
  import gradio as gr
10
+ from diffusers import (
11
+ DiffusionPipeline,
12
+ StableDiffusionXLPipeline,
13
+ AutoencoderKL,
14
+ ZImageTransformer2DModel,
15
+ )
16
  from compel import Compel, ReturnedEmbeddingsType
17
+ from huggingface_hub import hf_hub_download
18
 
19
  import r2_uploader
20
 
 
26
  # =============================================================================
27
  # Model registry
28
  # =============================================================================
29
+ # Two pipelines are exposed through a single UI via the selector below. Both now
30
+ # run custom single-file checkpoints pulled from the nsfwalex/checkpoint_n_lora
31
+ # dataset (populated by the model_downloader Space):
32
+ # * Moody Pro Mix -> Z-Image-Turbo finetune (fast, guidance-free DiT)
33
+ # * One Obsession -> Illustrious / SDXL anime model with Compel weighting
34
+ # Constant names keep their pipeline meaning (zimage = the Z-Image DiT pipeline,
35
+ # noobxl = the SDXL pipeline); only the displayed labels / weights changed.
36
+ MODEL_ZIMAGE = "Moody Pro Mix (ZIT V12 DPO)"
37
+ MODEL_NOOBXL = "One Obsession v2.1 Anime"
38
  MODEL_CHOICES = [MODEL_ZIMAGE, MODEL_NOOBXL]
39
 
40
+ # Custom checkpoints live in this HF dataset; HF_TOKEN (a Space secret) grants
41
+ # read access. Paths mirror the model_downloader index.json layout.
42
+ CHECKPOINT_DATASET = "nsfwalex/checkpoint_n_lora"
43
+ ZIMAGE_CHECKPOINT = "checkpoints/zimageturbo/moodyProMix_zitV12DPO.safetensors"
44
+ NOOBXL_CHECKPOINT = "checkpoints/il/oneObsession_v21Anime.safetensors"
45
+ # Base Z-Image repo supplies the VAE / text encoder / tokenizer / scheduler and
46
+ # the transformer config; the single-file checkpoint only carries the DiT.
47
+ ZIMAGE_BASE = "Tongyi-MAI/Z-Image-Turbo"
48
+
49
+ HF_TOKEN = os.getenv("HF_TOKEN")
50
+
51
+
52
+ def _checkpoint_path(filename):
53
+ """Download a checkpoint from the dataset and return its local cache path."""
54
+ return hf_hub_download(
55
+ repo_id=CHECKPOINT_DATASET,
56
+ repo_type="dataset",
57
+ filename=filename,
58
+ token=HF_TOKEN,
59
+ )
60
+
61
+
62
  MAX_SEED = np.iinfo(np.int32).max
63
 
64
  NOOBXL_NEGATIVE = (
 
71
  # Load both pipelines once at startup. On ZeroGPU the `.to("cuda")` calls are
72
  # captured by the runtime and the work happens inside the @spaces.GPU function.
73
  # -----------------------------------------------------------------------------
74
+ print("Loading Z-Image pipeline (Moody Pro Mix)...")
75
+ # The CivitAI checkpoint is a transformer-only (model.diffusion_model.*) file, so
76
+ # load the base Z-Image-Turbo pipeline for the other components and swap in the
77
+ # custom DiT loaded from the single-file checkpoint.
78
+ zimage_transformer = ZImageTransformer2DModel.from_single_file(
79
+ _checkpoint_path(ZIMAGE_CHECKPOINT),
80
+ config=ZIMAGE_BASE,
81
+ subfolder="transformer",
82
+ torch_dtype=torch.bfloat16,
83
+ token=HF_TOKEN,
84
+ )
85
  zimage_pipe = DiffusionPipeline.from_pretrained(
86
+ ZIMAGE_BASE,
87
+ transformer=zimage_transformer,
88
  torch_dtype=torch.bfloat16,
89
  low_cpu_mem_usage=False,
90
  )
91
  zimage_pipe.to("cuda")
92
 
93
+ print("Loading SDXL pipeline (One Obsession)...")
94
+ # Override the in-checkpoint VAE with the fp16-fix VAE to avoid black/NaN images.
95
  noobxl_vae = AutoencoderKL.from_pretrained(
96
  "madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16
97
  )
98
+ noobxl_pipe = StableDiffusionXLPipeline.from_single_file(
99
+ _checkpoint_path(NOOBXL_CHECKPOINT),
100
  vae=noobxl_vae,
101
  torch_dtype=torch.float16,
102
  use_safetensors=True,
 
442
  return (
443
  gr.update(value=d["steps"]),
444
  gr.update(value=d["guidance"], interactive=is_noob,
445
+ info="Moody Pro Mix (Z-Image) is guidance-free (forced to 0)" if not is_noob else "Classifier-free guidance"),
446
  gr.update(value=d["height"]),
447
  gr.update(value=d["width"]),
448
  gr.update(visible=is_noob),
 
529
  choices=MODEL_CHOICES,
530
  value=MODEL_ZIMAGE,
531
  label="🧠 Model",
532
+ info="Moody Pro Mix: fast & general (Z-Image) • One Obsession: anime / illustration (SDXL)",
533
  )
534
 
535
  prompt = gr.Textbox(
 
567
  num_inference_steps = gr.Slider(
568
  minimum=1, maximum=50, value=9, step=1,
569
  label="Inference Steps",
570
+ info="Moody Pro Mix: ~9 • One Obsession: ~28",
571
  )
572
 
573
  guidance_scale = gr.Slider(
574
  minimum=0.0, maximum=10.0, value=0.0, step=0.1,
575
  label="Guidance Scale",
576
+ info="Moody Pro Mix (Z-Image) is guidance-free (forced to 0)",
577
  interactive=False,
578
  )
579
 
 
612
  ---
613
  <div style="text-align: center; opacity: 0.7; font-size: 0.9em; margin-top: 1rem;">
614
  <strong>Models:</strong>
615
+ Moody Pro Mix (ZIT V12 DPO, Z-Image-Turbo finetune) •
616
+ One Obsession v2.1 Anime (Illustrious / SDXL) •
617
  <strong>Demo by:</strong> <a href="https://x.com/realmrfakename" target="_blank">@mrfakename</a>
618
  </div>
619
  """,