RuinedHugg / space_models.py
jhonier23's picture
Stage Ragnarok locally before SDXL pipeline load
98334dd
Raw History Blame Contribute Delete
5.11 kB
"""Checkpoint catalogue and cached downloads for the ZeroGPU Space."""
import hashlib
import os
import tempfile
from pathlib import Path
import requests
SDXL_BASE = "SDXL Base 1.0"
RAGNAROK = "Juggernaut XL - Ragnarok"
MODEL_ID = "stabilityai/stable-diffusion-xl-base-1.0"
RAGNAROK_FILENAME = "juggernautXL_ragnarokBy.safetensors"
RAGNAROK_URL = "https://civitai.com/api/download/models/1759168"
RAGNAROK_SHA256 = "dd08fa32f98d05a2443ca1419e46df1575a0811f6e3b246d9dd47ff20f5eb66a"
RAGNAROK_SIZE = 7105350162
MODEL_CHOICES = (RAGNAROK,)
def model_cache_dir():
"""Use an attached persistent volume when available, otherwise local disk."""
configured = os.getenv("RF_MODEL_CACHE_DIR")
if configured:
return Path(configured)
if Path("/data").is_dir():
return Path("/data/ruinedfooocus/checkpoints")
return Path(__file__).resolve().parent / "model_cache" / "checkpoints"
def file_sha256(path):
digest = hashlib.sha256()
with Path(path).open("rb") as stream:
for chunk in iter(lambda: stream.read(4 * 1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
_verified_paths = set()
def download_verified_file(target, url, expected_sha256, progress=None, cached_size=None):
"""Cache one remote file, accepting it only when its checksum matches."""
target = Path(target)
target.parent.mkdir(parents=True, exist_ok=True)
if target.is_file():
if (str(target) in _verified_paths
or (cached_size is not None and target.stat().st_size == cached_size)
or file_sha256(target) == expected_sha256):
_verified_paths.add(str(target))
return str(target)
target.unlink()
partial = target.with_suffix(target.suffix + ".part")
headers = {}
if os.getenv("CIVITAI_TOKEN"):
headers["Authorization"] = f"Bearer {os.environ['CIVITAI_TOKEN']}"
try:
with requests.get(url, headers=headers, stream=True, timeout=(15, 120)) as response:
response.raise_for_status()
total = int(response.headers.get("content-length", 0))
digest = hashlib.sha256()
downloaded = 0
with partial.open("wb") as stream:
for chunk in response.iter_content(chunk_size=4 * 1024 * 1024):
if not chunk:
continue
stream.write(chunk)
digest.update(chunk)
downloaded += len(chunk)
if progress and total:
progress(min(downloaded / total, 1), desc=f"Downloading {target.name}")
if digest.hexdigest() != expected_sha256:
raise ValueError(f"{target.name} download failed SHA-256 verification")
partial.replace(target)
_verified_paths.add(str(target))
return str(target)
finally:
partial.unlink(missing_ok=True)
def stage_checkpoint(source, target, expected_sha256):
"""Copy a bucket checkpoint to local disk and verify it in one sequential read."""
source = Path(source)
target = Path(target)
target.parent.mkdir(parents=True, exist_ok=True)
if target.is_file() and target.stat().st_size == source.stat().st_size:
if file_sha256(target) == expected_sha256:
return str(target)
partial = target.with_suffix(target.suffix + ".part")
digest = hashlib.sha256()
try:
with source.open("rb") as input_file, partial.open("wb") as output_file:
for chunk in iter(lambda: input_file.read(16 * 1024 * 1024), b""):
output_file.write(chunk)
digest.update(chunk)
if digest.hexdigest() != expected_sha256:
raise ValueError(f"{source.name} cache failed SHA-256 verification")
partial.replace(target)
return str(target)
finally:
partial.unlink(missing_ok=True)
def prepare_model(model_name, progress=None):
"""Return a local checkpoint path, downloading Ragnarok only if needed."""
if model_name == SDXL_BASE:
return ""
if model_name != RAGNAROK:
raise ValueError(f"Unknown model: {model_name}")
cached_path = download_verified_file(
model_cache_dir() / RAGNAROK_FILENAME,
RAGNAROK_URL,
RAGNAROK_SHA256,
progress=progress,
cached_size=RAGNAROK_SIZE if Path("/data").is_dir() else None,
)
if Path("/data").is_dir() and not os.getenv("RF_MODEL_CACHE_DIR"):
local_path = Path(tempfile.gettempdir()) / "ruinedfooocus" / RAGNAROK_FILENAME
try:
return stage_checkpoint(cached_path, local_path, RAGNAROK_SHA256)
except ValueError:
Path(cached_path).unlink()
_verified_paths.discard(cached_path)
cached_path = download_verified_file(
model_cache_dir() / RAGNAROK_FILENAME,
RAGNAROK_URL,
RAGNAROK_SHA256,
progress=progress,
)
return stage_checkpoint(cached_path, local_path, RAGNAROK_SHA256)
return cached_path