# Parakeet ASR NVIDIA Parakeet-TDT 0.6B (int8 ONNX) served by our own thin FastAPI wrapper over [sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx) (ONNX Runtime + CUDA). **Server:** irv-ml1 (Irvine, WireGuard-only) **Port:** 8765 (container 8000) **GPU:** both exposed (`NVIDIA_VISIBLE_DEVICES=all`); sherpa-onnx uses whichever CUDA ExecutionProvider picks **Image:** `local/parakeet:sherpa-onnx-v1` — built from `Dockerfile` + `app.py` + `entrypoint.sh` in this directory; **we own all the code** ## Why not the FastAPI community wrappers Both `Shadowfita/parakeet-tdt-0.6b-v2-fastapi` and `pnivek/Parakeet-ASR-FastAPI` look appealing on paper but have open, unfixed bugs in the actual transcribe path (return-shape mismatches after an unpinned `torchaudio` upgrade, `torchaudio.tensor` which doesn't exist, etc.). We tried Shadowfita and hit #16+#10 on the first real request. Rather than babysit someone else's half-tested code, we moved to sherpa-onnx — ONNX Runtime is a stable base, k2-fsa publishes prebuilt int8 Parakeet weights per release, and the recognizer API is a three-line call. ## API endpoints | Method + path | Purpose | |---|---| | `POST /transcribe` | Multipart file upload → `{"text": "..."}` | | `POST /v1/audio/transcriptions` | Same body; OpenAI-compatible path | | `GET /healthz` | Health probe (used by docker healthcheck) | ## Path layout | Host path | Container path | Purpose | Restic? | |---|---|---|---| | `/worktank/parakeet/models/` | `/models` | ONNX encoder+decoder+joiner+tokens (~400 MB int8) | excluded (regenerable — re-downloads from the URL on first run if absent) | ## First-time deploy on irv-ml1 ```bash # 1. Push compose + Dockerfile + app + entrypoint scripts/deploy-stack.sh irv-ml1 parakeet # 2. Make sure the models dir exists (one-time, already done from the # earlier Shadowfita deploy; this is idempotent) ssh -t irv-ml1 'sudo mkdir -p /worktank/parakeet/models && \ sudo chown -R lkraven:lkraven /worktank/parakeet' # 3. Build the image and bring up. First boot does a ~400 MB model # download via the entrypoint; allow 1–2 minutes before /healthz # flips healthy. ssh irv-ml1 ' cd /opt/docker/compose/parakeet && \ cp -n .env.example .env && \ docker compose config >/dev/null && \ docker compose build && \ docker compose up -d && \ docker compose logs -f --tail=30 ' ``` ## Smoke test ```bash # Over WG from the workstation curl -F "file=@sample.wav" http://10.100.79.3:8765/transcribe # → {"text": "hello world"} # OpenAI-shape alias (for clients that only know /v1/audio/transcriptions) curl -F "file=@sample.wav" http://10.100.79.3:8765/v1/audio/transcriptions ``` ## Switching to the v3 (multilingual) model The env var `PARAKEET_MODEL_URL` picks the release tarball. To swap from the English-only v2 to the 25-language v3: ```bash ssh irv-ml1 ' cd /opt/docker/compose/parakeet && \ sed -i "s|v2-int8|v3-int8|" .env && \ # Wipe the v2 weights so the entrypoint re-downloads v3 on next up: rm -f /worktank/parakeet/models/*.onnx /worktank/parakeet/models/tokens.txt && \ docker compose up -d && \ docker compose logs -f --tail=30 ' ``` ## Upgrade sherpa-onnx or change the base image Bump `PARAKEET_TAG` in `.env` to force a rebuild of the local image after editing the `Dockerfile`, then: ```bash scripts/deploy-stack.sh irv-ml1 parakeet ssh irv-ml1 'cd /opt/docker/compose/parakeet && docker compose build && docker compose up -d' ``` Model files under `/worktank/parakeet/models/` are preserved across image rebuilds. ## File layout ``` stacks/parakeet/ ├── Dockerfile # CUDA 12.8 + cuDNN 9 base, sherpa-onnx-cu12 wheel ├── app.py # FastAPI — ~60 lines ├── entrypoint.sh # downloads model on first run, then uvicorn ├── compose.yaml # one service, bind-mounts the models dir ├── .env.example # template; real .env lives on the server └── README.md # this file ```