badrex-endpoint / README.md
filipok's picture
redeploy: sync endpoint-badrex handler
afe40c9 verified
|
Raw
History Blame Contribute Delete
3.96 kB
# badrex Ethio-ASR Inference Endpoint
Custom HuggingFace Inference Endpoint handler for **badrex Ethio-ASR**
(wav2vec2-bert CTC) models β€” the endpoint counterpart of
`src/transcribers/badrex.py`. Native Tigrinya ASR that beat MMS in the
2026-06-14 eval.
The model served is chosen by the **`BADREX_MODEL`** environment variable
(default `badrex/Ethio-ASR-multilingual-1B`). The handler holds no weights β€”
they're pulled from the Hub on cold start, same as the MMS endpoint.
Long audio is chunked **inside the HF ASR pipeline** (`chunk_length_s=30`,
`stride_length_s=5`), so a full broadcast goes through in one request β€” no
client-side splitting, and no OOM on hour-long audio.
---
## Deploy
### 1. Create a HuggingFace repo
huggingface.co β†’ New model β†’ e.g. `badrex-endpoint`.
### 2. Push this directory
```bash
cd endpoint-badrex/
git init
git remote add origin https://huggingface.co/YOUR_USERNAME/badrex-endpoint
git add handler.py requirements.txt config.json
git commit -m "add badrex custom handler"
git push origin main
```
### 3. Create the Inference Endpoint
[ui.endpoints.huggingface.co](https://ui.endpoints.huggingface.co) β†’ New endpoint:
| Setting | Value |
|---|---|
| Model repository | `YOUR_USERNAME/badrex-endpoint` |
| Task | `Custom` |
| Hardware | `GPU Β· T4 Β· 1x` |
| Min replicas | `0` (scale to zero) |
| Max replicas | `1` |
**Pick the model** under the endpoint's **Environment variables**:
| Variable | Value |
|---|---|
| `BADREX_MODEL` | `badrex/Ethio-ASR-multilingual-1B` (default; auto-detects am/ti, robust to Amharic-leakage on bilingual ti channels) |
| | or `badrex/Ethio-ASR-tigrinya` (lighter, monolingual, slightly cleaner on pure Tigrinya) |
### 4. Point newsgrab at it
In `channels.yaml`:
```yaml
settings:
asr_routing: {ti: badrex} # send Tigrinya to badrex; everything else stays on MMS
badrex:
device: api
api_url: https://YOUR-ENDPOINT-ID.endpoints.huggingface.cloud
api_token: null # set HF_TOKEN environment variable instead
```
In `api` mode the endpoint **is** the model, so `badrex.models` /
`badrex.default_model` are ignored β€” the served checkpoint is whatever
`BADREX_MODEL` selects.
---
## Updating / rolling back
Same as the MMS endpoint: push the new `handler.py`, then **Settings β†’ Revision**
(pin a commit SHA, or track `main`) β†’ **Update Endpoint**. The URL is unchanged,
so `channels.yaml` needs no edit. Switching the served model is just an env-var
change (`BADREX_MODEL`) + endpoint restart β€” no code push.
---
## Request format
```python
import base64, requests
with open("audio.webm", "rb") as f:
b64 = base64.b64encode(f.read()).decode()
r = requests.post(
"https://YOUR-ENDPOINT-ID.endpoints.huggingface.cloud",
headers={"Authorization": "Bearer hf_...", "Content-Type": "application/json"},
json={"inputs": b64},
)
print(r.json()["text"]) # the multilingual model's leading [TIR] tag is stripped client-side
```
No `language` parameter β€” the deployed model is the language selector. The
multilingual model emits a leading `[TIR]`/`[AMH]` tag; the newsgrab client
(`src/transcribers/badrex.py`) strips it. If you call the endpoint directly,
strip `^\s*\[[A-Za-z]{2,4}\]\s*` yourself.
---
## Hardware
**Use T4** (16 GB). The 1B checkpoint fits comfortably; the 0.6B models more so.
Scale-to-zero (`min replicas: 0`) means no idle cost; cold start (model load)
is ~60–90 s. HF Endpoints accept up to ~100 MB per request β€” fine for full
broadcasts as base64.
---
## Notes
- `torch`/`torchaudio` are pre-installed in the HF endpoint base image; only
`transformers>=4.44.0` is declared (wav2vec2-bert + pipeline support).
- Tags transcripts `Source: badrex-api` on the newsgrab side β€” distinct from
`mms`/`gcp`, so `recheck-captions` and `prefer_mms` are untouched.