small-functional-movement-screening / tests /test_judge_backend.py
BladeSzaSza's picture
fix: define REPO_NAME in hf_upload.sh (ensure_blade_space referenced it)
4948993 verified
Raw
History Blame Contribute Delete
3.23 kB
"""Judge backend selection + transformers-fallback β€” no GPU, no downloads."""
import importlib
import formscout.config as config
from formscout.serving import get_vlm_client
from formscout.serving.llama_cpp import LlamaCppClient
def _reload_config(monkeypatch, **env):
for k, v in env.items():
if v is None:
monkeypatch.delenv(k, raising=False)
else:
monkeypatch.setenv(k, v)
importlib.reload(config)
return config
def test_resolve_backend_default_local(monkeypatch):
cfg = _reload_config(monkeypatch, FORMSCOUT_JUDGE_BACKEND=None, SPACE_ID=None)
assert cfg.resolve_judge_backend() == "llama_cpp"
def test_resolve_backend_auto_on_zero_gpu_space(monkeypatch):
cfg = _reload_config(monkeypatch, FORMSCOUT_JUDGE_BACKEND="auto",
SPACE_ID="me/space", SPACES_ZERO_GPU="true")
assert cfg.resolve_judge_backend() == "transformers"
importlib.reload(config)
def test_resolve_backend_auto_on_cpu_space_stays_llama(monkeypatch):
# A CPU-only Space must NOT load the 17 GB transformers model.
cfg = _reload_config(monkeypatch, FORMSCOUT_JUDGE_BACKEND="auto",
SPACE_ID="me/space", SPACES_ZERO_GPU=None, ZERO_GPU=None)
assert cfg.resolve_judge_backend() == "llama_cpp"
importlib.reload(config)
def test_resolve_backend_explicit(monkeypatch):
cfg = _reload_config(monkeypatch, FORMSCOUT_JUDGE_BACKEND="llama_cpp", SPACE_ID="me/space")
assert cfg.resolve_judge_backend() == "llama_cpp"
importlib.reload(config) # restore
def test_factory_returns_llama_cpp_locally(monkeypatch):
_reload_config(monkeypatch, FORMSCOUT_JUDGE_BACKEND="llama_cpp", SPACE_ID=None)
client = get_vlm_client()
assert isinstance(client, LlamaCppClient)
importlib.reload(config)
def test_transformers_client_available_is_cheap_bool():
# available must not load/download the model β€” just report a bool
from formscout.serving.transformers_vlm import TransformersVLMClient
c = TransformersVLMClient()
assert isinstance(c.available, bool)
c._failed = True
assert c.available is False
def test_judge_uses_rubric_on_fallback_sentinel():
from formscout.agents.judge import JudgeAgent
from formscout.types import BiomechFeatures, ScoreResult, MovementResult, IngestResult
import numpy as np
agent = JudgeAgent()
class _FakeClient:
available = True
def complete(self, *a, **k):
return {"error": "no gpu", "fallback": True, "text": ""}
agent._client = _FakeClient()
features = BiomechFeatures(test_name="deep_squat", view="2d", side="na",
angles={}, alignments={}, symmetry_delta=None,
timing={}, confidence=0.9)
rubric = ScoreResult(score=2, rationale="rubric says 2", confidence=0.8)
movement = MovementResult(test_name="deep_squat", side="na", confidence=1.0)
ingest = IngestResult(frames=[np.zeros((10, 10, 3), np.uint8)], fps=30.0,
duration=0.03, n_people=1, width=10, height=10)
res = agent.run(features, rubric, movement, ingest)
assert res.score == 2
assert "rubric-only" in res.rationale