NLag commited on
Commit
29e24be
·
1 Parent(s): 43c7537

Set default exercise router repo

Browse files
README.md CHANGED
@@ -265,8 +265,9 @@ comparison or fallback.
265
 
266
  To publish and load the router from Hugging Face, use the setup notes in
267
  [docs/huggingface-router-release.md](docs/huggingface-router-release.md). The draft model card is in
268
- [docs/huggingface-router-model-card.md](docs/huggingface-router-model-card.md). The current model
269
- repository is `NLag/pozify-exercise-router`.
 
270
 
271
  Custom unknown clips can be uploaded into the data volume at `/data/raw/custom_unknown/` before the
272
  `features` stage. Use consented clips only; useful unknown examples include idle standing, walking
 
265
 
266
  To publish and load the router from Hugging Face, use the setup notes in
267
  [docs/huggingface-router-release.md](docs/huggingface-router-release.md). The draft model card is in
268
+ [docs/huggingface-router-model-card.md](docs/huggingface-router-model-card.md). Runtime loading uses
269
+ `build-small-hackathon/pozify-exercise-router` by default; set `POZIFY_ROUTER_HF_REPO_ID` only to
270
+ override it.
271
 
272
  Custom unknown clips can be uploaded into the data volume at `/data/raw/custom_unknown/` before the
273
  `features` stage. Use consented clips only; useful unknown examples include idle standing, walking
docs/huggingface-router-model-card.md CHANGED
@@ -88,10 +88,11 @@ Summary:
88
 
89
  ## Runtime Loading
90
 
91
- Pozify can load this repository by setting:
 
92
 
93
  ```bash
94
- export POZIFY_ROUTER_HF_REPO_ID=NLag/pozify-exercise-router
95
  ```
96
 
97
  For private repositories, authenticate with `hf auth login` or set `HF_TOKEN`.
 
88
 
89
  ## Runtime Loading
90
 
91
+ Pozify loads this repository by default. Set `POZIFY_ROUTER_HF_REPO_ID` only to override the default
92
+ with another compatible router repo:
93
 
94
  ```bash
95
+ export POZIFY_ROUTER_HF_REPO_ID=owner/other-pozify-router
96
  ```
97
 
98
  For private repositories, authenticate with `hf auth login` or set `HF_TOKEN`.
docs/huggingface-router-release.md CHANGED
@@ -15,7 +15,7 @@ Official references:
15
  The configured model repository is:
16
 
17
  ```text
18
- NLag/pozify-exercise-router
19
  ```
20
 
21
  Create a user access token at:
@@ -53,7 +53,7 @@ Upload the model card and artifacts:
53
 
54
  ```bash
55
  uv run python scripts/upload_exercise_router_to_hf.py \
56
- --repo-id NLag/pozify-exercise-router \
57
  --private
58
  ```
59
 
@@ -69,10 +69,11 @@ The upload script creates the repository if needed and uploads:
69
 
70
  ## Runtime Configuration
71
 
72
- Set the model repository ID for runtime loading:
 
73
 
74
  ```bash
75
- export POZIFY_ROUTER_HF_REPO_ID=NLag/pozify-exercise-router
76
  ```
77
 
78
  Optional:
@@ -82,8 +83,8 @@ export POZIFY_ROUTER_HF_REVISION=main
82
  ```
83
 
84
  For private repositories, authenticate with `uv run hf auth login` or set `HF_TOKEN` before running
85
- the app. The loader first tries Hugging Face when `POZIFY_ROUTER_HF_REPO_ID` is set. If Hub loading
86
- fails or the variable is unset, it falls back to local files under `models/exercise_router/active/`.
87
 
88
  Disable Hub loading explicitly:
89
 
 
15
  The configured model repository is:
16
 
17
  ```text
18
+ build-small-hackathon/pozify-exercise-router
19
  ```
20
 
21
  Create a user access token at:
 
53
 
54
  ```bash
55
  uv run python scripts/upload_exercise_router_to_hf.py \
56
+ --repo-id build-small-hackathon/pozify-exercise-router \
57
  --private
58
  ```
59
 
 
69
 
70
  ## Runtime Configuration
71
 
72
+ The runtime loader uses `build-small-hackathon/pozify-exercise-router` by default. Override the
73
+ model repository ID only when you want to test or deploy a different router repo:
74
 
75
  ```bash
76
+ export POZIFY_ROUTER_HF_REPO_ID=owner/other-pozify-router
77
  ```
78
 
79
  Optional:
 
83
  ```
84
 
85
  For private repositories, authenticate with `uv run hf auth login` or set `HF_TOKEN` before running
86
+ the app. The loader first tries Hugging Face using the default repo or the override above. If Hub
87
+ loading fails, it falls back to local files under `models/exercise_router/active/`.
88
 
89
  Disable Hub loading explicitly:
90
 
src/pozify/ml/exercise_router_inference.py CHANGED
@@ -14,6 +14,7 @@ from pozify.ml.exercise_router_temporal import TorchTemporalRouter
14
 
15
  DEFAULT_MODEL_DIR = Path("models/exercise_router/active")
16
  ACTIVE_SELECTION_FILENAME = "router_selection.json"
 
17
  HF_REPO_ID_ENV = "POZIFY_ROUTER_HF_REPO_ID"
18
  HF_REVISION_ENV = "POZIFY_ROUTER_HF_REVISION"
19
  HF_DISABLE_ENV = "POZIFY_ROUTER_DISABLE_HF"
@@ -84,7 +85,7 @@ def load_router_model_from_hf(
84
  if _env_truthy(os.getenv(HF_DISABLE_ENV)):
85
  return None
86
 
87
- repo_id = repo_id or os.getenv(HF_REPO_ID_ENV)
88
  if not repo_id:
89
  return None
90
 
 
14
 
15
  DEFAULT_MODEL_DIR = Path("models/exercise_router/active")
16
  ACTIVE_SELECTION_FILENAME = "router_selection.json"
17
+ DEFAULT_HF_REPO_ID = "build-small-hackathon/pozify-exercise-router"
18
  HF_REPO_ID_ENV = "POZIFY_ROUTER_HF_REPO_ID"
19
  HF_REVISION_ENV = "POZIFY_ROUTER_HF_REVISION"
20
  HF_DISABLE_ENV = "POZIFY_ROUTER_DISABLE_HF"
 
85
  if _env_truthy(os.getenv(HF_DISABLE_ENV)):
86
  return None
87
 
88
+ repo_id = repo_id or os.getenv(HF_REPO_ID_ENV) or DEFAULT_HF_REPO_ID
89
  if not repo_id:
90
  return None
91
 
tests/test_exercise_classifier.py CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
2
 
3
  import json
4
  import math
 
5
  from pathlib import Path
6
  import sys
7
  import tempfile
@@ -22,6 +23,8 @@ from pozify.ml.exercise_router_features import (
22
  window_vector_feature_names,
23
  )
24
  from pozify.ml.exercise_router_inference import (
 
 
25
  RouterModelBundle,
26
  WindowRouterPrediction,
27
  aggregate_window_predictions,
@@ -210,7 +213,8 @@ class ExerciseRouterModelLoadingTests(unittest.TestCase):
210
  encoding="utf-8",
211
  )
212
 
213
- bundle = load_router_model(model_dir)
 
214
 
215
  self.assertIsNotNone(bundle)
216
  assert bundle is not None
@@ -258,6 +262,43 @@ class ExerciseRouterModelLoadingTests(unittest.TestCase):
258
  self.assertEqual(bundle.model_kind, "baseline")
259
  self.assertEqual(bundle.labels, tuple(ROUTER_LABELS))
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
 
262
  class ExerciseClassifierStepTests(unittest.TestCase):
263
  def test_manual_override_bypasses_model_and_validates_contract(self) -> None:
@@ -274,12 +315,13 @@ class ExerciseClassifierStepTests(unittest.TestCase):
274
 
275
  def test_missing_model_falls_back_to_unknown(self) -> None:
276
  with tempfile.TemporaryDirectory() as temp_dir:
277
- result = exercise_classifier.run(
278
- _sequence("push_up"),
279
- _profile("auto"),
280
- mock=False,
281
- model_dir=Path(temp_dir),
282
- )
 
283
 
284
  self.assertEqual(result.exercise, "unknown")
285
  self.assertTrue(result.fallback_required)
 
2
 
3
  import json
4
  import math
5
+ import os
6
  from pathlib import Path
7
  import sys
8
  import tempfile
 
23
  window_vector_feature_names,
24
  )
25
  from pozify.ml.exercise_router_inference import (
26
+ DEFAULT_HF_REPO_ID,
27
+ HF_DISABLE_ENV,
28
  RouterModelBundle,
29
  WindowRouterPrediction,
30
  aggregate_window_predictions,
 
213
  encoding="utf-8",
214
  )
215
 
216
+ with patch.dict(os.environ, {HF_DISABLE_ENV: "1"}):
217
+ bundle = load_router_model(model_dir)
218
 
219
  self.assertIsNotNone(bundle)
220
  assert bundle is not None
 
262
  self.assertEqual(bundle.model_kind, "baseline")
263
  self.assertEqual(bundle.labels, tuple(ROUTER_LABELS))
264
 
265
+ def test_hf_loader_defaults_to_pozify_router_repo(self) -> None:
266
+ with tempfile.TemporaryDirectory() as temp_dir:
267
+ model_dir = Path(temp_dir)
268
+ artifact_path = model_dir / "router.joblib"
269
+ selection_path = model_dir / "router_selection.json"
270
+ joblib.dump(
271
+ {
272
+ "model": _FakePushUpModel(),
273
+ "labels": list(ROUTER_LABELS),
274
+ "model_kind": "baseline",
275
+ },
276
+ artifact_path,
277
+ )
278
+ selection_path.write_text(
279
+ json.dumps({"selected_artifact": artifact_path.name}),
280
+ encoding="utf-8",
281
+ )
282
+
283
+ def fake_download(*, repo_id: str, filename: str, revision: str | None) -> Path:
284
+ self.assertEqual(repo_id, DEFAULT_HF_REPO_ID)
285
+ self.assertIsNone(revision)
286
+ return {"router_selection.json": selection_path, "router.joblib": artifact_path}[filename]
287
+
288
+ with (
289
+ patch.dict(os.environ, {}, clear=True),
290
+ patch(
291
+ "pozify.ml.exercise_router_inference._hf_hub_download",
292
+ side_effect=fake_download,
293
+ ),
294
+ ):
295
+ bundle = load_router_model_from_hf()
296
+
297
+ self.assertIsNotNone(bundle)
298
+ assert bundle is not None
299
+ self.assertEqual(bundle.model_kind, "baseline")
300
+ self.assertEqual(bundle.labels, tuple(ROUTER_LABELS))
301
+
302
 
303
  class ExerciseClassifierStepTests(unittest.TestCase):
304
  def test_manual_override_bypasses_model_and_validates_contract(self) -> None:
 
315
 
316
  def test_missing_model_falls_back_to_unknown(self) -> None:
317
  with tempfile.TemporaryDirectory() as temp_dir:
318
+ with patch.dict(os.environ, {HF_DISABLE_ENV: "1"}):
319
+ result = exercise_classifier.run(
320
+ _sequence("push_up"),
321
+ _profile("auto"),
322
+ mock=False,
323
+ model_dir=Path(temp_dir),
324
+ )
325
 
326
  self.assertEqual(result.exercise, "unknown")
327
  self.assertTrue(result.fallback_required)