89 lines
2.7 KiB
Python
89 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from huggingface_hub import snapshot_download
|
|
except ImportError as exc:
|
|
raise SystemExit(
|
|
"Missing dependency: huggingface_hub. Install dependencies with `pip install -r requirements.txt`."
|
|
) from exc
|
|
|
|
from common import load_model_card
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Download a Hugging Face model from a model card.")
|
|
parser.add_argument("card_id", help="Model card id, for example qwen3-4b-instruct-2507")
|
|
parser.add_argument(
|
|
"--local-dir",
|
|
help="Override destination directory. Defaults to the card storage_path.",
|
|
)
|
|
parser.add_argument(
|
|
"--dry-run",
|
|
action="store_true",
|
|
help="Print what would be downloaded without downloading files.",
|
|
)
|
|
parser.add_argument(
|
|
"--allow-pattern",
|
|
action="append",
|
|
dest="allow_patterns",
|
|
help="Optional Hugging Face allow pattern. Can be passed multiple times.",
|
|
)
|
|
parser.add_argument(
|
|
"--ignore-pattern",
|
|
action="append",
|
|
dest="ignore_patterns",
|
|
default=["*.msgpack", "*.h5", "*.ot"],
|
|
help="Optional Hugging Face ignore pattern. Can be passed multiple times.",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
card = load_model_card(args.card_id)
|
|
repo_id = card.get("upstream_id")
|
|
if not repo_id:
|
|
print(f"Model card `{args.card_id}` has no upstream_id.", file=sys.stderr)
|
|
return 1
|
|
|
|
destination_raw = args.local_dir or card.get("storage_path") or ""
|
|
if not str(destination_raw):
|
|
print(f"Model card `{args.card_id}` has no storage_path.", file=sys.stderr)
|
|
return 1
|
|
|
|
token = os.environ.get("HF_TOKEN") or None
|
|
|
|
print(f"Model card: {args.card_id}")
|
|
print(f"Repository: {repo_id}")
|
|
print(f"Destination: {destination_raw}")
|
|
print(f"Token: {'set' if token else 'not set'}")
|
|
|
|
if args.dry_run:
|
|
return 0
|
|
|
|
if os.name == "nt" and not args.local_dir and str(destination_raw).startswith("/"):
|
|
print(
|
|
"The model card storage_path is a Linux path. On Windows, pass --local-dir "
|
|
"or run this script on the GPU/Linux host where /models exists.",
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
|
|
destination = Path(destination_raw)
|
|
destination.mkdir(parents=True, exist_ok=True)
|
|
downloaded_path = snapshot_download(
|
|
repo_id=repo_id,
|
|
local_dir=destination,
|
|
token=token,
|
|
allow_patterns=args.allow_patterns,
|
|
ignore_patterns=args.ignore_patterns,
|
|
)
|
|
print(f"Downloaded to: {downloaded_path}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|