Spaces:
Running on Zero
Running on Zero
File size: 7,104 Bytes
1b2e96f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | """Locate the model files used by 4DAnyone.
Every published file is anchored by one immutable Hugging Face revision and
downloaded on demand. ``fdanyone.download`` fetches missing files;
the resolvers here only locate them.
"""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import TYPE_CHECKING
from fdanyone.errors import AssetError
if TYPE_CHECKING:
from fdanyone.config import ModeSettings
HF_REPO_ID = "AntResearch/4DAnyone"
HF_REVISION = "7850985888b56aabf09e69480b73248f1a76bcbe"
BIREFNET_REPO_ID = "ZhengPeng7/BiRefNet"
BIREFNET_REVISION = "e2bf8e4460fc8fa32bba5ea4d94b3233d367b0e4"
BIREFNET_DIR = "birefnet"
BIREFNET_FILES = (
"BiRefNet_config.py",
"birefnet.py",
"config.json",
"model.safetensors",
)
CHECKPOINT = "4danyone/model.safetensors"
MHR70_REGRESSOR = "4danyone/smplx_to_goliath70.pt"
WAN_VAE = "4danyone/Wan2.2_VAE.pth"
TEXT_ENCODER = "4danyone/models_t5_umt5-xxl-enc-bf16.pth"
TOKENIZER_DIR = "4danyone/umt5-xxl"
TOKENIZER_FILES = tuple(
f"{TOKENIZER_DIR}/{name}"
for name in ("special_tokens_map.json", "spiece.model", "tokenizer.json", "tokenizer_config.json")
)
GVHMR_CHECKPOINT = "gvhmr/gvhmr_siga24_release.ckpt"
HMR2_CHECKPOINT = "gvhmr/epoch=10-step=25000.ckpt"
VITPOSE_CHECKPOINT = "gvhmr/vitpose-h-multi-coco.pth"
YOLO_CHECKPOINT = "gvhmr/yolov8x.pt"
PERCEPTUAL_VGG19 = "perceptual/imagenet-vgg-verydeep-19-conv.safetensors"
TAEW2_2 = "fps-assets/taehv/taew2_2.pth"
TAEW2_2_URL = (
"https://raw.githubusercontent.com/madebyollin/taehv/"
"e743234f3217ab3d1570f65642ab06596d1bd7c5/taew2_2.pth"
)
TAEW2_2_SHA256 = "d053e216ca50e2bb837bbcd79b85f0366bea00e5938025572382a773b74c559a"
TURBO_LORA = (
"fps-assets/turbo-lora/LoRAs/Wan22-Turbo/"
"Wan22_TI2V_5B_Turbo_lora_rank_64_fp16.safetensors"
)
TURBO_LORA_REPO_ID = "Kijai/WanVideo_comfy"
TURBO_LORA_REVISION = "86c2b0442e01eeee630b48fd7efc0cd37af03252"
TURBO_LORA_REPO_FILE = (
"LoRAs/Wan22-Turbo/Wan22_TI2V_5B_Turbo_lora_rank_64_fp16.safetensors"
)
TURBO_LORA_SHA256 = "0ace5244e3d1256f884662c261b017249796cf5b95f05d5ed93cc02a478967b8"
SMPLX_MODEL = "body_models/smplx/SMPLX_NEUTRAL.npz"
# Space patch (sync_vendor.sh): the exported prompt embedding replaces the
# UMT5-XXL encoder and its tokenizer, and reconstruction never runs here.
MODEL_FILES = (
CHECKPOINT,
MHR70_REGRESSOR,
WAN_VAE,
GVHMR_CHECKPOINT,
HMR2_CHECKPOINT,
VITPOSE_CHECKPOINT,
YOLO_CHECKPOINT,
)
EXAMPLE_FILES = (
"data/source/pexels/10331522-uhd_2160_4096_25fps.mp4",
"data/source/pexels/2785536-uhd_2160_3840_25fps.mp4",
"data/source/pexels/5435720-uhd_2160_4096_25fps.mp4",
"data/source/pexels/5885633-hd_1080_1920_25fps.mp4",
"data/source/pexels/5999210-uhd_2160_4096_25fps.mp4",
"data/source/pexels/6980035-uhd_2160_4096_30fps.mp4",
"data/source/pexels/7080903-hd_1080_1920_30fps.mp4",
"data/source/pexels/7480858-uhd_2160_3840_25fps.mp4",
)
# Upstream GVHMR resolves its model files relative to its own checkout, so the
# install commands link each downloaded file to the location GVHMR expects.
GVHMR_LINKS = (
(GVHMR_CHECKPOINT, "inputs/checkpoints/gvhmr/gvhmr_siga24_release.ckpt"),
(HMR2_CHECKPOINT, "inputs/checkpoints/hmr2/epoch=10-step=25000.ckpt"),
(VITPOSE_CHECKPOINT, "inputs/checkpoints/vitpose/vitpose-h-multi-coco.pth"),
(YOLO_CHECKPOINT, "inputs/checkpoints/yolo/yolov8x.pt"),
(SMPLX_MODEL, "inputs/checkpoints/body_models/smplx/SMPLX_NEUTRAL.npz"),
)
@dataclass(frozen=True, slots=True)
class BaseAssets:
vae: Path
"""Wan VAE checkpoint."""
text_encoder: Path | None
"""UMT5 text-encoder checkpoint; ``None`` when a prompt embedding replaces it."""
tokenizer: Path | None
"""UMT5 tokenizer directory; ``None`` when a prompt embedding replaces it."""
tiny_decoder: Path | None
"""Pinned TAEW2.2 checkpoint when turbo mode needs it."""
turbo_lora: Path | None
"""Pinned Wan2.2 Turbo-LoRA when turbo mode needs it."""
def _require_file(path: Path, label: str, command: str) -> Path:
resolved = path.expanduser().resolve()
if not resolved.is_file():
raise AssetError(f"{label} does not exist: {resolved}. Run `python {command}` to install it.")
return resolved
def resolve_checkpoint(path: str | Path | None = None, model_dir: str | Path = "models") -> Path:
if path is not None:
resolved = Path(path).expanduser().resolve()
if not resolved.is_file():
raise AssetError(f"Checkpoint override does not exist: {resolved}")
return resolved
return _require_file(Path(model_dir) / CHECKPOINT, "Checkpoint", "scripts/download_model.py")
def resolve_regressor(path: str | Path | None = None, model_dir: str | Path = "models") -> Path:
if path is not None:
resolved = Path(path).expanduser().resolve()
if not resolved.is_file():
raise AssetError(f"MHR70 regressor override does not exist: {resolved}")
return resolved
return _require_file(Path(model_dir) / MHR70_REGRESSOR, "MHR70 regressor", "scripts/download_model.py")
def resolve_foreground_model(model_dir: str | Path = "models") -> Path:
root = Path(model_dir).expanduser() / BIREFNET_DIR
for relative in BIREFNET_FILES:
_require_file(root / relative, "BiRefNet file", "scripts/download_model.py")
return root.resolve()
def resolve_perceptual_vgg19(model_dir: str | Path = "models") -> Path:
"""Resolve the converted VGG-19 weights used by perceptual reconstruction."""
return _require_file(
Path(model_dir) / PERCEPTUAL_VGG19,
"Perceptual VGG-19 weights",
"scripts/download_model.py",
)
def resolve_base_assets(
model_dir: str | Path,
settings: ModeSettings,
*,
have_prompt_embedding: bool = False,
) -> BaseAssets:
"""Resolve the local VAE, T5 encoder, and tokenizer.
The encoder and its tokenizer serve only the single fixed prompt, so a
caller that already holds the exported embedding needs neither and must
not be asked for the 11 GB checkpoint.
"""
root = Path(model_dir).expanduser()
text_encoder: Path | None = None
tokenizer: Path | None = None
if not have_prompt_embedding:
for relative in TOKENIZER_FILES:
_require_file(root / relative, "Tokenizer file", "scripts/download_model.py")
text_encoder = _require_file(root / TEXT_ENCODER, "Text encoder", "scripts/download_model.py")
tokenizer = (root / TOKENIZER_DIR).expanduser().resolve()
return BaseAssets(
vae=_require_file(root / WAN_VAE, "VAE", "scripts/download_model.py"),
text_encoder=text_encoder,
tokenizer=tokenizer,
tiny_decoder=(
_require_file(root / TAEW2_2, "TAEW2.2 checkpoint", "scripts/download_model.py")
if settings.tiny_decoders
else None
),
turbo_lora=(
_require_file(root / TURBO_LORA, "Turbo-LoRA", "scripts/download_model.py")
if settings.turbo_lora
else None
),
)
|