JSCPPProgrammer's picture
Upload Z-Anime Distill-8 FP8 Gradio ZeroGPU Space
610a02a verified
Raw
History Blame Contribute Delete
5.3 kB
"""
Runtime configuration for Z-Anime Distill-8-Step (FP8) Gradio + embedded ComfyUI.
Defaults align with SeeSee21/Z-Anime model card and official workflow guidance.
"""
from __future__ import annotations
import os
from dataclasses import dataclass
from typing import Final
# --- Z-Anime Distill-8-Step defaults ---
DEFAULT_WIDTH: Final[int] = 1024
DEFAULT_HEIGHT: Final[int] = 1024
DEFAULT_STEPS: Final[int] = 8
DEFAULT_CFG: Final[float] = 1.0
DEFAULT_SAMPLER: Final[str] = "euler_ancestral"
DEFAULT_SCHEDULER: Final[str] = "beta"
DEFAULT_DENOISE: Final[float] = 1.0
DEFAULT_BATCH_SIZE: Final[int] = 1
DEFAULT_NEGATIVE_PROMPT: Final[str] = ""
DEFAULT_SEED: Final[int] = 42
DEFAULT_RANDOMIZE_SEED: Final[bool] = True
# ModelSamplingAuraFlow.shift — matches workflows/Z-Anime-Workflow-v1.json (⚙️ Model Sampling)
DEFAULT_AURA_SHIFT: Final[float] = 3.5
# Model filenames (standard split, FP8)
DISTILL_UNET_NAME: Final[str] = "z-anime-distill-8step-fp8.safetensors"
CLIP_NAME: Final[str] = "qwen_3_4b-fp8.safetensors"
CLIP_TYPE: Final[str] = "qwen_image"
VAE_NAME: Final[str] = "ae.safetensors"
UNET_WEIGHT_DTYPE: Final[str] = "default"
# --- UI / validation ranges ---
MIN_WH: Final[int] = 512
MAX_WH: Final[int] = 2048
MIN_STEPS: Final[int] = 1
MAX_STEPS: Final[int] = 50
MIN_CFG: Final[float] = 1.0
MAX_CFG: Final[float] = 1.5
CFG_STEP: Final[float] = 0.1
MIN_DENOISE: Final[float] = 0.0
MAX_DENOISE: Final[float] = 1.0
DENOISE_STEP: Final[float] = 0.01
MIN_BATCH: Final[int] = 1
MAX_BATCH: Final[int] = 4
MIN_SEED: Final[int] = 0
MAX_SEED: Final[int] = 2**32 - 1
SAMPLER_CHOICES: Final[tuple[str, ...]] = (
"euler",
"euler_ancestral",
"euler_ancestral_cfg_pp",
"heun",
"heunpp2",
"dpm_2",
"dpm_2_ancestral",
"lms",
"dpm_adaptive",
"dpm_fast",
"dpmpp_2m",
"dpmpp_2m_sde",
"dpmpp_2m_sde_gpu",
"dpmpp_3m_sde",
"dpmpp_3m_sde_gpu",
"dpmpp_sde",
"dpmpp_sde_gpu",
"ddim",
"uni_pc",
"uni_pc_bh2",
"res_multistep",
"res_multistep_cfg_pp",
"res_multistep_ancestral",
"res_multistep_ancestral_cfg_pp",
"ddpm",
"lcm",
"ipndm",
"ipndm_v",
"deis",
"er_sde",
)
SCHEDULER_CHOICES: Final[tuple[str, ...]] = (
"normal",
"karras",
"exponential",
"sgm_uniform",
"simple",
"ddim_uniform",
"beta",
"linear_quadratic",
"kl_optimal",
)
SAVE_PREFIX: Final[str] = "ZAnimeDistill8_Gradio"
HUB_MODEL_REPO: Final[str] = "SeeSee21/Z-Anime"
# Hub files downloaded at startup into the Comfy model layout.
ARTIFACTS: Final[list[tuple[str, str, str]]] = [
(
HUB_MODEL_REPO,
f"diffusion_models/{DISTILL_UNET_NAME}",
f"diffusion_models/{DISTILL_UNET_NAME}",
),
(
HUB_MODEL_REPO,
f"text_encoder/{CLIP_NAME}",
f"text_encoders/{CLIP_NAME}",
),
(
HUB_MODEL_REPO,
f"vae/{VAE_NAME}",
f"vae/{VAE_NAME}",
),
]
MIN_SIZES: Final[dict[str, int]] = {
DISTILL_UNET_NAME: 5_000_000_000,
CLIP_NAME: 3_000_000_000,
VAE_NAME: 50_000_000,
}
MAX_RETRIES: Final[int] = 8
BACKOFF_CAP_S: Final[int] = 60
def comfy_root() -> str:
"""ComfyUI source tree root (contains nodes.py). Default ./ComfyUI."""
d = os.environ.get("ZANIME_COMFY_ROOT", "").strip()
if d:
return os.path.abspath(d)
return os.path.abspath(os.path.join(os.getcwd(), "ComfyUI"))
def model_artifacts_root() -> str:
"""
Directory containing diffusion_models/, text_encoders/, vae/, clip/.
If ZANIME_MODELS_ROOT is set, it must point to that *models* directory.
"""
d = os.environ.get("ZANIME_MODELS_ROOT", "").strip()
if d:
return os.path.abspath(d)
return os.path.abspath(os.path.join(comfy_root(), "models"))
def skip_startup_bootstrap() -> bool:
"""If true, skip import-time file bootstrap (tests, local dev without downloads)."""
return os.environ.get("ZANIME_SKIP_STARTUP_BOOTSTRAP", "").strip() == "1"
def disable_aura_sampling() -> bool:
"""If true, skip ModelSamplingAuraFlow (fallback; may diverge from official workflow)."""
return os.environ.get("ZANIME_DISABLE_AURA_SAMPLING", "").strip() == "1"
def aura_shift() -> float:
raw = os.environ.get("ZANIME_AURA_SHIFT", "").strip()
if not raw:
return float(DEFAULT_AURA_SHIFT)
try:
return float(raw)
except ValueError:
return float(DEFAULT_AURA_SHIFT)
def text_encoder_file_path() -> str:
return os.path.join(model_artifacts_root(), "text_encoders", CLIP_NAME)
def vae_file_path() -> str:
return os.path.join(model_artifacts_root(), "vae", VAE_NAME)
def clip_mirror_file_path() -> str:
"""Optional mirror under models/clip/ for layouts that expect CLIP-named folders."""
return os.path.join(model_artifacts_root(), "clip", CLIP_NAME)
@dataclass(frozen=True)
class GenerationParams:
prompt: str
negative_prompt: str
width: int
height: int
steps: int
cfg: float
batch_size: int
sampler_name: str
scheduler: str
denoise: float
seed: int
warnings: tuple[str, ...] = ()