feat(douanier): torch-free light V/A emotion engine + engine selector (#37 rapid slice)
The SRE reply (armada/api/SRE.md) revealed the public host is erable — Debian 9,
no GPU, ~2 GB RAM, ~3 GB disk free — where the ~4 GB CLAP/torch image can't fit.
This unblocks deployment in principle: a CPU-native emotion path that needs no
torch, behind a selector so the rich CLAP engine stays the dev/GPU default.
WHY: the SRE is "blocking on a CPU-deployable image". The emotion read must work
within ~2 GB RAM and sub-second, without torch — but the API response shape must
not change, so hexa's integration and the cache are unaffected by the swap.
WHAT:
- engines/ears_light.py — heuristic valence/arousal from librosa features only
(no torch): arousal from RMS energy + tempo + spectral brightness; valence from
major/minor mode (Krumhansl key-profile correlation) + brightness. Mapped onto
the SAME 12 emotion-ontology anchors by V/A distance → a CLAP-shaped {valence,
arousal, top, dist, confidence} dict, tagged engine="light". Honest baseline;
an Essentia/CLAP-grade precise tier lands later behind the same shape.
- config.DOUANIER_EMOTION_ENGINE (clap|light); ears.emotion_read() dispatches;
cache keys on the engine so clap/light reads don't collide; healthz reports the
selected engine + availability.
VALIDATION:
- 27/27 tests green (+5): anchors drift-guarded == emotion_ontology.EMOTIONS;
mode-valence major>minor; light read shape + V/A in range + dist sums to 1;
arousal orders loud/bright/noisy above quiet/low; and the endpoint runs
end-to-end via TestClient with engine=light — the torch-free erable path proven.
REMAINING in #37 (queued, not rapid): Dockerfile (light image, no torch, fits
~3 GB / 2 GB RAM, bind 127.0.0.1:9780, --env-file); Essentia MusiCNN upgrade for
the light tier; separation /v1/separate → 503 + env-selected GPU-runner dispatch
seam (with #29/#30); /v1/metrics; 2 GB cache hard-cap. See SRE.md + memory
project_douanier_api 'HOSTING REALITY'.
Showing
armada/api/engines/ears_light.py
0 → 100644
armada/api/tests/test_ears_light.py
0 → 100644
Please
register
or
sign in
to comment