Spaces:
Sleeping
Sleeping
| title: DECLARE User Study | |
| emoji: ποΈ | |
| colorFrom: blue | |
| colorTo: green | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| # DECLARE User Study | |
| Blind comparison of three ASR conditions (BASELINE / VANILLA-FT / DECLARE) on | |
| real spoken FairSpeech-style commands. Single-file Flask app (`app.py`), | |
| matching the flat repo layout used elsewhere (RailVaani), with the frontend in | |
| `templates/` + `static/`. | |
| Participants record themselves speaking a prompted command via the browser's | |
| native microphone API; audio is routed blindly to one of three ASR conditions | |
| (Latin-square rotation per session); a rule-based intent/entity extractor | |
| summarises what the system understood; the participant judges | |
| intent-correctness and (if applicable) entity-correctness separately. After | |
| all trials, a validated 4-item UMUX usability questionnaire is shown. Model | |
| identity is never revealed during the session. | |
| ## Folder structure | |
| ``` | |
| app.py -- everything: Flask routes, NLU, routing, logging, ASR | |
| templates/index.html -- page shell | |
| static/style.css -- styling | |
| static/app.js -- consent form, MediaRecorder, all fetch() calls | |
| data/sample_commands.csv -- 38 stratified FairSpeech commands | |
| checkpoints/ -- put your .nemo files here | |
| requirements.txt | |
| Dockerfile | |
| README.md | |
| ``` | |
| **Important constraint:** session state lives in an in-memory Python dict in | |
| `app.py` (`SESSIONS`). This assumes a **single worker process**. Do not run | |
| behind multiple gunicorn/Flask workers without first moving session state to | |
| a shared store (Redis, a database) β otherwise a participant's session can | |
| "disappear" if a later request lands on a different worker. | |
| ## Before deploying with real models | |
| The app ships in **MOCK mode** by default so the full flow β consent, | |
| recording, routing, judgement, UMUX β can be tested without any model weights. | |
| To run real inference: | |
| 1. Uncomment the `torch` / `nemo_toolkit[asr]` lines in `requirements.txt`. | |
| 2. Add your `VANILLA_FT` and `DECLARE` `.nemo` checkpoints under `checkpoints/`. | |
| 3. Set Space secrets/variables if you don't want to hardcode paths: | |
| - `BASELINE_MODEL_ID` (default: `stt_en_conformer_ctc_small_ls`) | |
| - `VANILLA_FT_CKPT` | |
| - `DECLARE_CKPT` | |
| ## Audio pipeline | |
| Browser records via `MediaRecorder` (typically webm/opus) β `app.py` saves the | |
| raw upload β converts to 16kHz mono WAV via `ffmpeg` β runs ASR β **deletes | |
| both the raw upload and the WAV file**. The WAV deletion happens inside | |
| `transcribe()`'s own `finally` block (so it happens even if inference fails); | |
| the raw upload is deleted separately right after, in the route handler. | |
| ## Results | |
| - `results/trial_log.csv` β per-trial ASR output + intent/entity correctness | |
| - `results/participants.csv` β demographics + consent (keyed by session ID) | |
| - `results/umux_responses.csv` β usability questionnaire responses + score | |
| **HF Spaces' local disk is ephemeral** β sync these to a private HF Dataset | |
| repo regularly if running more than a quick pilot. | |
| ## Analysis | |
| Join `trial_log.csv` back to its (unblinded) `condition` column and run: | |
| - Friedman test across the three conditions (per-participant correctness rate, | |
| computed separately for `intent_correct` and `entity_correct` β filter or | |
| stratify `entity_correct == "not_applicable"` rows out of that specific test) | |
| - Wilcoxon signed-rank, pairwise (DECLARE vs. VANILLA-FT is the key comparison) | |
| - Disaggregate both by the demographic columns in `participants.csv` for the | |
| fairness question | |