File size: 4,459 Bytes
585c960
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Download or verify WorldGen Vulkan model assets.

Gated FLUX files require a Hugging Face token with access to
black-forest-labs/FLUX.1-dev and FLUX.1-Fill-dev.
"""

import argparse
import hashlib
import os
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
MODELS = Path(os.environ.get("WORLDGEN_MODELS", ROOT / "models"))

ASSETS = {
    "flux-dev/flux1-dev-q4_k.gguf": (
        None,
        6925526176,
        "962d536a2a51342b4793e46cb2c491f3ea5fa62a66fbfc38684638fa7bff646b",
    ),
    "flux-dev/ae.safetensors": (
        "https://huggingface.co/black-forest-labs/FLUX.1-dev/resolve/main/ae.safetensors",
        335304388,
        "afc8e28272cd15db3919bacdb6918ce9c1ed22e96cb12c4d5ed0fba823529e38",
    ),
    "flux-dev/clip_l.safetensors": (
        "https://huggingface.co/black-forest-labs/FLUX.1-dev/resolve/main/clip_l.safetensors",
        246144152,
        "660c6f5b1abae9dc498ac2d21e1347d2abdb0cf6c0c0c8576cd796491d9a6cdd",
    ),
    "flux-dev/t5xxl_fp8_e4m3fn.safetensors": (
        "https://huggingface.co/black-forest-labs/FLUX.1-dev/resolve/main/t5xxl_fp8_e4m3fn.safetensors",
        4893934904,
        "315fadec5f39e44cdaa20af56446fcb1c7c9b17091209ee7ba0f03d47160518f",
    ),
    "flux-fill/flux1-fill-dev.safetensors": (
        "https://huggingface.co/black-forest-labs/FLUX.1-Fill-dev/resolve/main/flux1-fill-dev.safetensors",
        23804922408,
        "03e289f530df51d014f48e675a9ffa2141bc003259bf5f25d75b957e920a41ca",
    ),
    "flux-fill/flux-fill-official-q4.gguf": (
        None,
        6793133088,
        "096c26692c17a99a8e86961bcc3aafe1de01af7ee7a1b56218a01f6c48624c5d",
    ),
    "flux-dev/worldgen_text2scene.safetensors": (
        "https://huggingface.co/LeoXie/WorldGen/resolve/main/models--WorldGen-Flux-Lora/worldgen_text2scene.safetensors",
        34647632,
        "5349c785650892914b32e74d88d16baa5863981a63a8747b70332e67e0feb10b",
    ),
    "flux-dev/worldgen_img2scene.safetensors": (
        "https://huggingface.co/LeoXie/WorldGen/resolve/main/models--WorldGen-Flux-Lora/worldgen_img2scene.safetensors",
        44917720,
        "b10a1fa212fcff58c87a8264b1b9a8c01853febcd4d3f5c239ab7d7fd35d17ef",
    ),
    "da2/model.safetensors": (
        "https://huggingface.co/haodongli/DA-2/resolve/main/model.safetensors",
        1378513064,
        "d8ea568fc3dfb7d7432e5b763de499dd03fb6dc1c2020d84639f35e2dfa4f78e",
    ),
    "da2/da2_trace_1024.ncnn.param": (
        None,
        46271,
        "cd0a3fcb3d8e143e7b65e6706a15d60467bdf6e49bc584c4351bfbcd9436ac86",
    ),
    "da2/da2_trace_1024.ncnn.bin": (
        None,
        744102084,
        "e7773c23b2d117ac9f5085a92e8df06b46abba05011ac90da33c65b53ea479d9",
    ),
}


def sha256(path: Path) -> str:
    h = hashlib.sha256()
    with path.open("rb") as f:
        for b in iter(lambda: f.read(1 << 24), b""):
            h.update(b)
    return h.hexdigest()


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--download", action="store_true")
    ap.add_argument("--check", action="store_true")
    ap.add_argument("--token", default=os.environ.get("HF_TOKEN"))
    args = ap.parse_args()
    MODELS.mkdir(parents=True, exist_ok=True)

    missing = []
    for rel, (url, size, digest) in ASSETS.items():
        path = MODELS / rel
        ok = path.exists()
        if ok and size and path.stat().st_size != size:
            ok = False
        if ok and args.check and digest and sha256(path) != digest:
            ok = False
        print(("OK   " if ok else "MISS ") + str(path))
        if not ok:
            missing.append((rel, url))

    if missing:
        print("\nMissing:")
        for rel, url in missing:
            print(f"  {rel}\n    {url}")
        print("\nFLUX.1-dev / Fill are gated; accept the license and set HF_TOKEN.")
        print("The FLUX dev q4 GGUF is user-supplied; expected SHA256:")
        print("  962d536a2a51342b4793e46cb2c491f3ea5fa62a66fbfc38684638fa7bff646b")
        print("Convert the official Fill safetensors with:")
        print("  sd-cli --mode convert -m models/flux-fill/flux1-fill-dev.safetensors \\")
        print("    -o models/flux-fill/flux-fill-official-q4.gguf --type q4_K")
        sys.exit(1)

    if args.download:
        print("automatic download of gated files is intentionally not implemented;")
        print("use scripts/download_one.py or huggingface-cli with HF_TOKEN.")


if __name__ == "__main__":
    main()