Spaces:
Running
on
Zero
Running
on
Zero
File size: 4,586 Bytes
4f81869 |
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 |
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Build a Hugging Face Spaces-ready bundle directory from this repo.
The output folder can be uploaded (or git-pushed) to a new Gradio Space.
We intentionally do NOT rename files in this repo. Instead, the Space README
will specify `app_file: webui_gradio.py` to avoid conflicts with the `app/` package.
Usage:
python scripts/make_hf_space_bundle.py --out hf_space
"""
from __future__ import annotations
import argparse
import shutil
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
def copy_file(src: Path, dst: Path) -> None:
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src, dst)
def copy_tree(src: Path, dst: Path, *, ignore_globs: list[str] | None = None) -> None:
ignore = None
if ignore_globs:
ignore = shutil.ignore_patterns(*ignore_globs)
if dst.exists():
shutil.rmtree(dst)
shutil.copytree(src, dst, ignore=ignore)
def write_space_readme(dst: Path) -> None:
text = """---
title: ArtistEmbeddingClassifier
sdk: gradio
app_file: webui_gradio.py
license: gpl-3.0
---
### ArtistEmbeddingClassifier (Gradio Space)
This Space bundles the model checkpoint + prototype DB and runs the Gradio UI.
Notes:
- This project is GPL-3.0.
- `yolov5_anime/` is from [zymk9/yolov5_anime](https://github.com/zymk9/yolov5_anime) (GPL-3.0).
- `anime-eyes-cascade.xml` is from [recette-lemon/Haar-Cascade-Anime-Eye-Detector](https://github.com/recette-lemon/Haar-Cascade-Anime-Eye-Detector) (GPL-3.0).
"""
(dst / "README.md").write_text(text, encoding="utf-8")
def write_space_requirements(dst: Path) -> None:
# IMPORTANT for Spaces:
# - HF GPU base images already install torch + gradio + spaces.
# - If we pin/downgrade these here, pip will try to replace huge packages and may fail.
# Keep this list minimal and only add what is NOT guaranteed by the base image.
text = """pillow
pyyaml
tqdm
# OpenCV for face/eye extraction (headless build for Spaces)
opencv-python-headless
"""
(dst / "requirements.txt").write_text(text, encoding="utf-8")
def write_space_packages(dst: Path) -> None:
# Helps OpenCV on Spaces.
text = """libgl1
libglib2.0-0
"""
(dst / "packages.txt").write_text(text, encoding="utf-8")
def write_lfs_gitattributes(dst: Path) -> None:
# If you push via git, this ensures large weights are handled via LFS.
text = """*.pt filter=lfs diff=lfs merge=lfs -text
"""
(dst / ".gitattributes").write_text(text, encoding="utf-8")
def main() -> None:
ap = argparse.ArgumentParser(description="Create Hugging Face Space bundle directory")
ap.add_argument("--out", type=str, default="hf_space", help="Output folder name")
args = ap.parse_args()
out_dir = (ROOT / args.out).resolve()
if out_dir.exists():
shutil.rmtree(out_dir)
out_dir.mkdir(parents=True, exist_ok=True)
# Core app code
copy_file(ROOT / "webui_gradio.py", out_dir / "webui_gradio.py")
copy_tree(ROOT / "app", out_dir / "app", ignore_globs=["__pycache__"])
# Assets required by the UI
copy_file(ROOT / "anime-eyes-cascade.xml", out_dir / "anime-eyes-cascade.xml")
copy_file(ROOT / "yolov5x_anime.pt", out_dir / "yolov5x_anime.pt")
# Bundle checkpoints/prototypes
(out_dir / "checkpoints_style").mkdir(exist_ok=True)
copy_file(ROOT / "checkpoints_style" / "stage3_epoch24.pt", out_dir / "checkpoints_style" / "stage3_epoch24.pt")
copy_file(
ROOT / "checkpoints_style" / "per_artist_prototypes_90_10_full.pt",
out_dir / "checkpoints_style" / "per_artist_prototypes_90_10_full.pt",
)
# Vendor yolov5_anime (strip heavy demo assets)
copy_tree(
ROOT / "yolov5_anime",
out_dir / "yolov5_anime",
ignore_globs=[
"__pycache__",
".git",
"inference",
"tutorial.ipynb",
"Dockerfile",
# We bundle yolov5x_anime.pt at repo root; don't include extra weights.
"*.pt",
"weights/*.pt",
],
)
# Licensing/attribution
for fn in ("LICENSE", "THIRD_PARTY_NOTICES.md"):
if (ROOT / fn).exists():
copy_file(ROOT / fn, out_dir / fn)
# Space metadata
write_space_readme(out_dir)
write_space_requirements(out_dir)
write_space_packages(out_dir)
write_lfs_gitattributes(out_dir)
print("✅ Created Space bundle at:", out_dir)
print("Next: upload/push the contents of that folder to your Hugging Face Space repo.")
if __name__ == "__main__":
main()
|