Spaces:
Running on Zero
Running on Zero
| title: ScriptFlow Hausa Inference | |
| emoji: π¬ | |
| colorFrom: indigo | |
| colorTo: purple | |
| sdk: gradio | |
| sdk_version: 6.24.0 | |
| python_version: '3.12' | |
| app_file: app.py | |
| pinned: false | |
| license: other | |
| short_description: Hausa ASR + MT for ScriptFlow | |
| # ScriptFlow inference service | |
| Hausa ASR + HausaβEnglish MT, served over HTTP so the Render backend does not | |
| have to hold ~2GB of model weights in a 512MB process. | |
| - **ASR** β [`NCAIR1/Hausa-ASR`](https://huggingface.co/NCAIR1/Hausa-ASR) (Whisper-small fine-tune) | |
| - **MT** β [`Helsinki-NLP/opus-mt-ha-en`](https://huggingface.co/Helsinki-NLP/opus-mt-ha-en) | |
| ## Deploying | |
| 1. Create a Space: **New Space β Gradio β Blank**, hardware **CPU basic (free)**. | |
| Gradio rather than Docker because Docker Spaces need PRO. It costs nothing | |
| here: Gradio is FastAPI underneath, so `/asr` and `/translate` sit at the | |
| root exactly as they would have, with a status UI at `/ui`. `Dockerfile` is | |
| kept for anyone who does have PRO β switch `sdk:` back to `docker` to use it. | |
| 2. Push the contents of this directory to it. `packages.txt` installs ffmpeg. | |
| 3. On the model page for `NCAIR1/Hausa-ASR`, **accept the licence** β the model | |
| is gated (`gated: auto`), and without acceptance the download 403s. | |
| 4. In **Space β Settings β Secrets**, set: | |
| - `HF_TOKEN` β a read token from the account that accepted the licence | |
| - `SERVICE_TOKEN` β any random string; the backend must send the same value | |
| Gradio serves its status page at `/`. The first request downloads weights and can take several minutes. `GET /` | |
| answers immediately throughout and reports load state, so you can watch it come | |
| up without holding a request open. | |
| ## API | |
| `POST /asr` β raw audio bytes as the body, `X-Service-Token` header. | |
| ```json | |
| { | |
| "text": "...", | |
| "duration": 41.2, | |
| "wordLevel": true, | |
| "words": [{"word": "sannu", "start": 0.4, "end": 0.9, "speaker": null}] | |
| } | |
| ``` | |
| Times are relative to the audio posted; the backend adds each chunk's offset. | |
| `end` may be `null` β that is meaningful, and the backend infers a real end from | |
| the following word rather than inventing a duration here. | |
| `POST /translate` β `{"texts": [...]}`, returns `{"translations": [...]}` with | |
| one entry per input, same order. | |
| ## Notes | |
| - Free Spaces sleep after inactivity; the first call after a sleep pays the | |
| cold start again. | |
| - CPU inference on Whisper-small runs roughly 1β3Γ realtime, so a 20-minute | |
| chunk is minutes of compute, not seconds. | |
| - `NCAIR1/Hausa-ASR` is licensed with a 1000 active end-user cap for | |
| non-commercial use. Check that against how ScriptFlow ships. | |