github-actions[bot] commited on
Commit
2a94f77
·
1 Parent(s): 910f57f

Deploy hyper3labs/HyperView from Hyper3Labs/hyperview-spaces@13b0870

Browse files
Files changed (3) hide show
  1. Dockerfile +3 -9
  2. README.md +39 -12
  3. demo.py +48 -120
Dockerfile CHANGED
@@ -21,7 +21,7 @@ WORKDIR $HOME/app
21
 
22
  RUN pip install --upgrade pip
23
 
24
- ARG HYPERVIEW_VERSION=0.2.0
25
  ARG HYPER_MODELS_VERSION=0.1.0
26
 
27
  # Pin package versions so Docker cache cannot silently hold an older PyPI release.
@@ -30,17 +30,11 @@ RUN pip install "hyper-models==${HYPER_MODELS_VERSION}" && python -c "import hyp
30
 
31
  COPY --chown=user demo.py ./demo.py
32
 
33
- ARG DEMO_SAMPLES=300
34
-
35
  ENV HYPERVIEW_DATASETS_DIR=/home/user/app/demo_data/datasets \
36
- HYPERVIEW_MEDIA_DIR=/home/user/app/demo_data/media \
37
- DEMO_SAMPLES=${DEMO_SAMPLES}
38
 
39
  # Precompute at build time so the Space starts fast.
40
- RUN python demo.py --precompute
41
-
42
- ENV HOST=0.0.0.0 \
43
- PORT=7860
44
 
45
  EXPOSE 7860
46
 
 
21
 
22
  RUN pip install --upgrade pip
23
 
24
+ ARG HYPERVIEW_VERSION=0.3.1
25
  ARG HYPER_MODELS_VERSION=0.1.0
26
 
27
  # Pin package versions so Docker cache cannot silently hold an older PyPI release.
 
30
 
31
  COPY --chown=user demo.py ./demo.py
32
 
 
 
33
  ENV HYPERVIEW_DATASETS_DIR=/home/user/app/demo_data/datasets \
34
+ HYPERVIEW_MEDIA_DIR=/home/user/app/demo_data/media
 
35
 
36
  # Precompute at build time so the Space starts fast.
37
+ RUN python -c "from demo import build_dataset; build_dataset()"
 
 
 
38
 
39
  EXPOSE 7860
40
 
README.md CHANGED
@@ -10,25 +10,52 @@ pinned: false
10
 
11
  # HyperView — Imagenette (CLIP + HyCoCLIP)
12
 
13
- This Hugging Face Space runs HyperView with:
 
 
 
 
14
 
15
  - CLIP embeddings (`openai/clip-vit-base-patch32`) for Euclidean layout
16
  - HyCoCLIP embeddings (`hycoclip-vit-s`) for Poincaré layout
17
 
18
- The Docker image installs the **latest HyperView from PyPI** and precomputes
19
- embeddings/layouts during build for fast runtime startup.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- ## Configuration
22
 
23
- Environment variables:
24
 
25
- - `DEMO_HF_DATASET` (default: `Multimodal-Fatima/Imagenette_validation`)
26
- - `DEMO_HF_SPLIT` (default: `validation`)
27
- - `DEMO_HF_IMAGE_KEY` (default: `image`)
28
- - `DEMO_HF_LABEL_KEY` (default: `label`)
29
- - `DEMO_SAMPLES` (default: `300`)
30
- - `DEMO_CLIP_MODEL` (default: `openai/clip-vit-base-patch32`)
31
- - `DEMO_HYPER_MODEL` (default: `hycoclip-vit-s`)
32
 
33
  ## Deploy source
34
 
 
10
 
11
  # HyperView — Imagenette (CLIP + HyCoCLIP)
12
 
13
+ This folder is the simplest copyable HyperView Space example in this repo.
14
+ It keeps all dataset-specific settings in the constants block at the top of
15
+ [demo.py](demo.py), so a coding agent can usually adapt it by editing one file.
16
+
17
+ This example runs HyperView with:
18
 
19
  - CLIP embeddings (`openai/clip-vit-base-patch32`) for Euclidean layout
20
  - HyCoCLIP embeddings (`hycoclip-vit-s`) for Poincaré layout
21
 
22
+ The Docker image installs released HyperView packages from PyPI and precomputes
23
+ the dataset, embeddings, and layouts during build for fast runtime startup.
24
+
25
+ ## Reuse This Template
26
+
27
+ When you copy this folder for your own dataset, change these parts first:
28
+
29
+ 1. Edit the constants block in [demo.py](demo.py).
30
+ 2. Rename the copied Space from `HyperView` to your own project name such as `yourproject-HyperView` or `HyperView-yourproject`.
31
+ 3. Update this README frontmatter, title, and H1.
32
+ 4. Point a deploy workflow at your new folder.
33
+
34
+ This starter currently installs `hyperview==0.3.1` and `hyper-models==0.1.0`.
35
+
36
+ The defaults in [demo.py](demo.py) are:
37
+
38
+ - Hugging Face dataset: `Multimodal-Fatima/Imagenette_validation`
39
+ - Split: `validation`
40
+ - Image field: `image`
41
+ - Label field: `label`
42
+ - Sample count: `300`
43
+ - Layouts: CLIP + Euclidean, HyCoCLIP + Poincaré
44
+
45
+ If you only want one model in your own Space, keep a single entry in
46
+ `EMBEDDING_LAYOUTS` and delete the rest.
47
+
48
+ When contributing your own Space back to this repository, add a row to the
49
+ community table in the root `README.md` and include your Hugging Face Space ID
50
+ in the pull request description.
51
 
52
+ ## Build Model
53
 
54
+ The Dockerfile runs `build_dataset()` during image build. That means:
55
 
56
+ - the first expensive download/embedding pass happens at build time
57
+ - the runtime container mostly just launches HyperView
58
+ - there is no extra runtime configuration path to keep in sync
 
 
 
 
59
 
60
  ## Deploy source
61
 
demo.py CHANGED
@@ -1,147 +1,75 @@
1
  #!/usr/bin/env python
2
- """HyperView Hugging Face Space demo: CLIP + HyCoCLIP on Imagenette.
3
 
4
- Usage:
5
- python demo.py --precompute # run during Docker build
6
- python demo.py # run as app entrypoint
7
  """
8
 
9
  from __future__ import annotations
10
 
11
- import os
12
- import sys
13
-
14
  import hyperview as hv
15
 
16
- HOST = os.environ.get("HOST", "0.0.0.0")
17
- PORT = int(os.environ.get("PORT", "7860"))
18
-
19
- DATASET_NAME = os.environ.get("DEMO_DATASET", "imagenette_clip_hycoclip")
20
- HF_DATASET = os.environ.get("DEMO_HF_DATASET", "Multimodal-Fatima/Imagenette_validation")
21
- HF_SPLIT = os.environ.get("DEMO_HF_SPLIT", "validation")
22
- HF_IMAGE_KEY = os.environ.get("DEMO_HF_IMAGE_KEY", "image")
23
- HF_LABEL_KEY = os.environ.get("DEMO_HF_LABEL_KEY", "label")
24
- NUM_SAMPLES = int(os.environ.get("DEMO_SAMPLES", "300"))
25
- SAMPLE_SEED = int(os.environ.get("DEMO_SEED", "42"))
26
-
27
- CLIP_MODEL_ID = os.environ.get("DEMO_CLIP_MODEL", "openai/clip-vit-base-patch32")
28
- HYPER_MODEL_ID = os.environ.get("DEMO_HYPER_MODEL", "hycoclip-vit-s")
29
-
30
-
31
- def _truthy_env(name: str, default: bool = True) -> bool:
32
- value = os.environ.get(name)
33
- if value is None:
34
- return default
35
- return value.strip().lower() not in {"0", "false", "no", "off", ""}
36
-
 
 
 
 
 
 
 
 
 
 
37
 
38
- def _ensure_demo_ready(dataset: hv.Dataset) -> None:
39
  if len(dataset) == 0:
40
- print(f"Loading samples from {HF_DATASET} ({HF_SPLIT})...")
41
  dataset.add_from_huggingface(
42
  HF_DATASET,
43
  split=HF_SPLIT,
44
  image_key=HF_IMAGE_KEY,
45
  label_key=HF_LABEL_KEY,
46
- max_samples=NUM_SAMPLES,
47
  shuffle=True,
48
  seed=SAMPLE_SEED,
49
  )
50
 
51
- spaces = dataset.list_spaces()
52
-
53
- clip_space = next(
54
- (
55
- space
56
- for space in spaces
57
- if getattr(space, "provider", None) == "embed-anything"
58
- and getattr(space, "model_id", None) == CLIP_MODEL_ID
59
- ),
60
- None,
61
- )
62
-
63
- if clip_space is None:
64
- print(f"Computing CLIP embeddings ({CLIP_MODEL_ID})...")
65
- dataset.compute_embeddings(model=CLIP_MODEL_ID, provider="embed-anything", show_progress=True)
66
- spaces = dataset.list_spaces()
67
- clip_space = next(
68
- (
69
- space
70
- for space in spaces
71
- if getattr(space, "provider", None) == "embed-anything"
72
- and getattr(space, "model_id", None) == CLIP_MODEL_ID
73
- ),
74
- None,
75
  )
76
 
77
- if clip_space is None:
78
- raise RuntimeError("Failed to create CLIP embedding space")
79
-
80
- compute_hyperbolic = _truthy_env("DEMO_COMPUTE_HYPERBOLIC", default=True)
81
- hyper_space = next(
82
- (
83
- space
84
- for space in spaces
85
- if getattr(space, "provider", None) == "hyper-models"
86
- and getattr(space, "model_id", None) == HYPER_MODEL_ID
87
- ),
88
- None,
89
- )
90
-
91
- if compute_hyperbolic and hyper_space is None:
92
- try:
93
- print(f"Computing hyperbolic embeddings ({HYPER_MODEL_ID})...")
94
- dataset.compute_embeddings(model=HYPER_MODEL_ID, provider="hyper-models", show_progress=True)
95
- spaces = dataset.list_spaces()
96
- hyper_space = next(
97
- (
98
- space
99
- for space in spaces
100
- if getattr(space, "provider", None) == "hyper-models"
101
- and getattr(space, "model_id", None) == HYPER_MODEL_ID
102
- ),
103
- None,
104
- )
105
- except Exception as exc:
106
- print(f"WARNING: hyperbolic embeddings failed ({type(exc).__name__}: {exc})")
107
-
108
- layouts = dataset.list_layouts()
109
- geometries = {getattr(layout, "geometry", None) for layout in layouts}
110
-
111
- if "euclidean" not in geometries:
112
- print("Computing euclidean layout...")
113
- dataset.compute_visualization(space_key=clip_space.space_key, geometry="euclidean")
114
-
115
- if "poincare" not in geometries:
116
- print("Computing poincaré layout...")
117
- poincare_space_key = hyper_space.space_key if hyper_space is not None else clip_space.space_key
118
- dataset.compute_visualization(space_key=poincare_space_key, geometry="poincare")
119
 
 
120
 
121
- def main() -> None:
122
- dataset = hv.Dataset(DATASET_NAME)
123
-
124
- if len(dataset) == 0 or not dataset.list_layouts():
125
- print("Preparing demo dataset...")
126
- try:
127
- _ensure_demo_ready(dataset)
128
- except Exception as exc:
129
- import traceback
130
- traceback.print_exc()
131
- print(f"\nFATAL: demo setup failed: {type(exc).__name__}: {exc}", file=sys.stderr)
132
- sys.exit(1)
133
- else:
134
- print(
135
- f"Loaded cached dataset '{DATASET_NAME}' with "
136
- f"{len(dataset.list_spaces())} spaces and {len(dataset.list_layouts())} layouts"
137
- )
138
-
139
- if "--precompute" in sys.argv:
140
- print("Precompute complete")
141
- return
142
 
143
- print(f"Starting HyperView on {HOST}:{PORT}")
144
- hv.launch(dataset, host=HOST, port=PORT, open_browser=False)
 
 
145
 
146
 
147
  if __name__ == "__main__":
 
1
  #!/usr/bin/env python
2
+ """HyperView Hugging Face Space template example.
3
 
4
+ Copy this folder, then edit the constants below for your dataset.
 
 
5
  """
6
 
7
  from __future__ import annotations
8
 
 
 
 
9
  import hyperview as hv
10
 
11
+ # Edit this block when you reuse the template for another Space.
12
+ SPACE_HOST = "0.0.0.0"
13
+ SPACE_PORT = 7860
14
+
15
+ DATASET_NAME = "imagenette_clip_hycoclip"
16
+ HF_DATASET = "Multimodal-Fatima/Imagenette_validation"
17
+ HF_SPLIT = "validation"
18
+ HF_IMAGE_KEY = "image"
19
+ HF_LABEL_KEY = "label"
20
+ SAMPLE_COUNT = 300
21
+ SAMPLE_SEED = 42
22
+
23
+ # Keep one or more entries here. Most reuses only need one model/layout pair.
24
+ EMBEDDING_LAYOUTS = [
25
+ {
26
+ "name": "CLIP",
27
+ "provider": "embed-anything",
28
+ "model": "openai/clip-vit-base-patch32",
29
+ "layout": "euclidean",
30
+ },
31
+ {
32
+ "name": "HyCoCLIP",
33
+ "provider": "hyper-models",
34
+ "model": "hycoclip-vit-s",
35
+ "layout": "poincare",
36
+ },
37
+ ]
38
+
39
+
40
+ def build_dataset() -> hv.Dataset:
41
+ dataset = hv.Dataset(DATASET_NAME)
42
 
 
43
  if len(dataset) == 0:
44
+ print(f"Loading {SAMPLE_COUNT} samples from {HF_DATASET} ({HF_SPLIT})...")
45
  dataset.add_from_huggingface(
46
  HF_DATASET,
47
  split=HF_SPLIT,
48
  image_key=HF_IMAGE_KEY,
49
  label_key=HF_LABEL_KEY,
50
+ max_samples=SAMPLE_COUNT,
51
  shuffle=True,
52
  seed=SAMPLE_SEED,
53
  )
54
 
55
+ for embedding in EMBEDDING_LAYOUTS:
56
+ print(f"Ensuring {embedding['name']} embeddings ({embedding['model']})...")
57
+ space_key = dataset.compute_embeddings(
58
+ model=embedding["model"],
59
+ provider=embedding["provider"],
60
+ show_progress=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  )
62
 
63
+ print(f"Ensuring {embedding['layout']} layout...")
64
+ dataset.compute_visualization(space_key=space_key, layout=embedding["layout"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
+ return dataset
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
+ def main() -> None:
70
+ dataset = build_dataset()
71
+ print(f"Starting HyperView on {SPACE_HOST}:{SPACE_PORT}")
72
+ hv.launch(dataset, host=SPACE_HOST, port=SPACE_PORT, open_browser=False)
73
 
74
 
75
  if __name__ == "__main__":