Spaces:
Running on Zero
Running on Zero
File size: 5,423 Bytes
4b98524 | 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 | """Fetch the artefacts the committed model cards describe.
Run by a person, once, before the service starts. **Not** a runtime download:
the service never calls this, and a model that is not on disk leaves its
capability unavailable rather than triggering a fetch (brief Β§30, ADR 0005).
The cards are the input, not this file. Each one already names its source URL
and the sha256 of the bytes that were reviewed, so this script has no list of
its own to drift out of date β it reads what review approved and refuses
anything else.
.venv/bin/python scripts/install_models.py
.venv/bin/python scripts/install_models.py --check # verify, never fetch
"""
from __future__ import annotations
import argparse
import hashlib
import json
import ssl
import sys
import urllib.request
from pathlib import Path
MODELS_DIR = Path(__file__).resolve().parent.parent / "models"
CHUNK = 1 << 20
TIMEOUT_SECONDS = 300
def _digest(path: Path) -> str:
sha = hashlib.sha256()
with path.open("rb") as handle:
while chunk := handle.read(CHUNK):
sha.update(chunk)
return sha.hexdigest()
def _ssl_context() -> ssl.SSLContext:
"""Verify certificates, using certifi's bundle where the platform has none.
A python.org build on macOS ships no CA store, so `urlopen` fails on every
HTTPS URL. Disabling verification would be the quick fix and the wrong one:
this script's whole job is fetching a binary that will later run against
farm photographs.
"""
try:
import certifi
except ImportError:
return ssl.create_default_context()
return ssl.create_default_context(cafile=certifi.where())
def _download(url: str, destination: Path) -> None:
destination.parent.mkdir(parents=True, exist_ok=True)
# Downloaded beside the target and renamed, so an interrupted fetch cannot
# leave a truncated file that looks installed.
partial = destination.with_suffix(destination.suffix + ".partial")
request = urllib.request.Request(url, headers={"User-Agent": "animap-inference"})
with urllib.request.urlopen(
request, timeout=TIMEOUT_SECONDS, context=_ssl_context()
) as response, partial.open("wb") as handle:
while chunk := response.read(CHUNK):
handle.write(chunk)
partial.replace(destination)
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--check", action="store_true",
help="Report what is missing or mismatched; download nothing.")
args = parser.parse_args(argv)
# Deeper than `discover()` looks on purpose. Cards under `alternates/` are
# installed and verified but never registered, so the backend that keeps the
# licence decision reversible stays runnable without ever being able to
# answer a request by accident.
cards = sorted(MODELS_DIR.glob("**/model_card.json"))
if not cards:
print(f"No model cards under {MODELS_DIR}.")
return 1
failures = 0
seen: dict[Path, str] = {}
for card_path in cards:
card = json.loads(card_path.read_text())
target = (card_path.parent / card["artefact"]).resolve()
expected = card["sha256"]
label = f"{card_path.parent.name} β {target.name}"
# Several capabilities share one detector. Two cards naming the same
# file with different checksums is a review error, and the download
# would silently make one of them right.
if target in seen and seen[target] != expected:
print(f" β {label}: two cards claim different checksums for this file.")
failures += 1
continue
seen[target] = expected
if target.is_file():
actual = _digest(target)
if actual == expected:
print(f" β {label}")
continue
print(f" β {label}: on disk is {actual[:12]}β¦, card says {expected[:12]}β¦")
failures += 1
continue
if args.check:
print(f" β {label}: not installed.")
failures += 1
continue
# Some artefacts have no URL to fetch because they are produced here β
# an ONNX export of a published checkpoint is not a file the publisher
# hosts. `source` still records where the weights came from, because
# that is the provenance question; `produced_by` records how the bytes
# on disk were made from them. Downloading `source` would write a model
# card page into a .onnx file, so this refuses instead.
producer = card.get("produced_by")
if producer:
print(f" β {label}: not installed, and it is a local export rather "
f"than a download. Run: {producer}")
failures += 1
continue
print(f" β¦ {label}: fetching {card['source']}")
_download(card["source"], target)
actual = _digest(target)
if actual != expected:
target.unlink()
print(f" β {label}: downloaded {actual[:12]}β¦, card says {expected[:12]}β¦. "
f"Removed.")
failures += 1
continue
print(f" β {label} ({target.stat().st_size / 1e6:.1f} MB, {card['license']})")
return 1 if failures else 0
if __name__ == "__main__":
sys.exit(main())
|