File size: 5,360 Bytes
e5f4c09
8bcd035
e5f4c09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dffff08
 
 
 
 
642c04b
 
 
 
 
e5f4c09
 
 
 
 
 
8bcd035
 
 
 
 
e5f4c09
 
 
 
 
 
 
 
8bcd035
 
 
e5f4c09
8bcd035
 
 
e5f4c09
 
 
 
 
 
 
 
 
 
 
 
dffff08
 
642c04b
 
dffff08
642c04b
 
 
e5f4c09
 
 
16650dd
 
 
 
e5f4c09
 
 
 
 
8bcd035
 
e5f4c09
 
 
 
 
8bcd035
e5f4c09
 
 
 
8bcd035
e5f4c09
 
 
 
 
 
 
 
 
dffff08
 
e5f4c09
 
 
 
 
 
 
 
 
 
 
 
642c04b
 
 
 
 
e5f4c09
 
 
8bcd035
e5f4c09
 
 
 
 
 
 
8bcd035
e5f4c09
 
 
 
 
 
 
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
#!/usr/bin/env python3
"""Upload the toolkit and genuine model weights to personal HF repositories."""

from __future__ import annotations

import argparse
import json
from pathlib import Path

from huggingface_hub import HfApi

from model_registry import COLLECTION_SLUG, MODEL_SPECS, NAMESPACE, TOOLKIT_REPO


SCRIPT_DIR = Path(__file__).resolve().parent
DEFAULT_ROOT = SCRIPT_DIR.parent


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument("--root", type=Path, default=DEFAULT_ROOT)
    parser.add_argument("--model", action="append", choices=sorted(MODEL_SPECS))
    parser.add_argument(
        "--toolkit-only",
        action="store_true",
        help="Upload only the shared toolkit repository, not model repositories.",
    )
    parser.add_argument(
        "--models-only",
        action="store_true",
        help="Upload only the selected model repositories, not the shared toolkit.",
    )
    parser.add_argument("--token", help="Normally omitted; the saved HF token is used.")
    parser.add_argument(
        "--execute",
        action="store_true",
        help="Perform uploads. Without this flag, only print the intended operations.",
    )
    parser.add_argument(
        "--private",
        action="store_true",
        help="Keep uploaded repositories private. The approved release default is public.",
    )
    return parser.parse_args()


def available_count(family_dir: Path) -> int:
    availability = json.loads((family_dir / "availability.json").read_text())
    return sum(bool(entry["available"]) for entry in availability["entries"])


def assert_visibility(
    api: HfApi, repo_id: str, token: str | None, *, private: bool
) -> None:
    info = api.repo_info(repo_id=repo_id, repo_type="model", token=token)
    if bool(info.private) != private:
        expected = "private" if private else "public"
        raise RuntimeError(f"Visibility verification failed: {repo_id} is not {expected}.")


def main() -> None:
    args = parse_args()
    root = args.root.resolve()
    api = HfApi(token=args.token)
    identity = api.whoami(token=args.token)
    username = identity.get("name") or identity.get("fullname")
    if username != NAMESPACE:
        raise RuntimeError(
            f"Authenticated as {username!r}; refusing to upload outside {NAMESPACE!r}."
        )
    if args.toolkit_only and args.model:
        raise RuntimeError("--toolkit-only cannot be combined with --model.")
    if args.toolkit_only and args.models_only:
        raise RuntimeError("--toolkit-only cannot be combined with --models-only.")
    selected = [] if args.toolkit_only else (args.model or list(MODEL_SPECS))
    operations: list[tuple[str, Path, bool]] = []
    if not args.models_only:
        operations.append((TOOLKIT_REPO, root, True))
    for model_name in selected:
        family = root / "models" / model_name
        if available_count(family) == 0:
            print(
                f"METADATA ONLY {model_name}: no saved checkpoint weights exist.",
                flush=True,
            )
        operations.append((MODEL_SPECS[model_name]["hf_repo"], family, False))

    for repo_id, folder, is_toolkit in operations:
        if not repo_id.startswith(f"{NAMESPACE}/"):
            raise RuntimeError(f"Namespace guard rejected {repo_id}.")
        visibility = "PRIVATE" if args.private else "PUBLIC"
        print(f"{visibility} UPLOAD {folder} -> {repo_id}", flush=True)
        if not args.execute:
            continue
        api.create_repo(
            repo_id=repo_id,
            repo_type="model",
            private=args.private,
            exist_ok=True,
            token=args.token,
        )
        api.update_repo_settings(
            repo_id=repo_id, repo_type="model", private=args.private, token=args.token
        )
        if is_toolkit:
            api.upload_folder(
                repo_id=repo_id,
                repo_type="model",
                folder_path=folder,
                ignore_patterns=[
                    "models/**",
                    "validation-report.json",
                    "validation-runs/**",
                    "logs/**",
                    "**/__pycache__/**",
                    "**/*.pyc",
                    ".gitignore",
                ],
                commit_message="Restructure reusable AspectBench inference toolkit",
                token=args.token,
            )
        else:
            api.upload_folder(
                repo_id=repo_id,
                repo_type="model",
                folder_path=folder,
                ignore_patterns=[
                    "**/__pycache__/**",
                    "**/*.pyc",
                    "training/**",
                ],
                commit_message="Add canonical HBS and Slovenian checkpoints",
                token=args.token,
            )
        assert_visibility(api, repo_id, args.token, private=args.private)
        api.add_collection_item(
            collection_slug=COLLECTION_SLUG,
            item_id=repo_id,
            item_type="model",
            exists_ok=True,
            token=args.token,
        )
        print(f"VERIFIED {visibility} {repo_id}", flush=True)

    if not args.execute:
        print("Dry run only. Re-run with --execute to upload.", flush=True)


if __name__ == "__main__":
    main()