parakeet: rewrite on sherpa-onnx; own the wrapper end-to-end
The Shadowfita FastAPI wrapper hit two unfixed upstream bugs on the first real /transcribe call — chunker return-shape mismatch (open issue #16) and a `torchaudio.tensor` that doesn't exist (open #10). Rather than babysit someone else's half-tested code, switched to sherpa-onnx with the prebuilt int8 Parakeet-TDT tarball from k2-fsa, and wrote our own ~60-line FastAPI wrapper. Moving parts now owned in-tree: Dockerfile CUDA 12.8 + cuDNN 9 runtime base, installs sherpa-onnx==1.12.39+cuda12.cudnn9 + fastapi + soundfile + libasound2 (sherpa-onnx links to ALSA at load time even when we never touch a mic). app.py OfflineRecognizer.from_transducer() once at startup; /transcribe and /v1/audio/transcriptions both accept multipart uploads and return {"text": ...}. entrypoint.sh Idempotent model download to /models on first run (~400 MB int8 tarball), then exec uvicorn. Smoke test: 0.wav (bundled in the tarball, The House of the Seven Gables excerpt) transcribes cleanly in ~1.2s on GPU. PARAKEET_MODEL_URL in .env lets you swap to the v3 (25-language) tarball without touching any other files. Wipe *.onnx + tokens.txt from the models dir and the entrypoint re-downloads.
This commit is contained in:
@@ -1,37 +1,28 @@
|
||||
# Parakeet ASR — NVIDIA Parakeet-TDT 0.6B v2 speech-to-text.
|
||||
# Parakeet ASR via sherpa-onnx + our own thin FastAPI wrapper.
|
||||
#
|
||||
# Wraps Shadowfita/parakeet-tdt-0.6b-v2-fastapi (FastAPI + Silero VAD +
|
||||
# WebSocket streaming). Upstream provides no prebuilt image, so we
|
||||
# build from a pinned git commit via docker buildx's git URL context
|
||||
# — no source files vendored into this repo.
|
||||
# We previously wrapped Shadowfita/parakeet-tdt-0.6b-v2-fastapi but hit two
|
||||
# unfixed upstream bugs (open issues #16 + #10) the first time we actually sent
|
||||
# a transcription request. Switched to sherpa-onnx — ONNX Runtime + CUDA, a
|
||||
# prebuilt int8 quantized Parakeet-TDT from k2-fsa — and wrote our own ~50-line
|
||||
# wrapper we own end-to-end.
|
||||
#
|
||||
# Runs on irv-ml1 (dual GPU). Both GPUs exposed; upstream respects
|
||||
# CUDA_VISIBLE_DEVICES if you want to pin later.
|
||||
# Model weights (~400 MB int8) download on first run via the entrypoint to
|
||||
# ${PARAKEET_MODELS_DIR}/ (persistent host bind mount). Subsequent starts skip
|
||||
# the download.
|
||||
#
|
||||
# HF weights (~2.5 GB for parakeet-tdt-0.6b-v2) cache to
|
||||
# ${PARAKEET_MODELS_DIR} via HF_HOME=/models, persistent across
|
||||
# container recreates.
|
||||
#
|
||||
# API routes (per upstream README):
|
||||
# POST /transcribe — batch transcription
|
||||
# WS /ws/transcribe — streaming with Silero VAD
|
||||
# API:
|
||||
# POST /transcribe — multipart file upload, returns {"text": "..."}
|
||||
# POST /v1/audio/transcriptions — same body, OpenAI-compatible path alias
|
||||
# GET /healthz
|
||||
#
|
||||
# Not a literal OpenAI `/v1/audio/transcriptions` path; point clients
|
||||
# at /transcribe directly, or add a reverse-proxy alias if drop-in
|
||||
# compat is needed later.
|
||||
#
|
||||
# First `up` triggers a fresh docker build (python:3.10-slim +
|
||||
# torch + NeMo ≈ 5–10 min). Subsequent starts reuse the cached
|
||||
# image unless PARAKEET_SHA changes.
|
||||
#
|
||||
# All tunables live in .env — edit that, not this file.
|
||||
|
||||
services:
|
||||
parakeet:
|
||||
image: local/parakeet:${PARAKEET_SHA}
|
||||
image: local/parakeet:${PARAKEET_TAG}
|
||||
build:
|
||||
context: https://github.com/Shadowfita/parakeet-tdt-0.6b-v2-fastapi.git#${PARAKEET_SHA}
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: parakeet
|
||||
restart: unless-stopped
|
||||
runtime: nvidia
|
||||
@@ -39,14 +30,10 @@ services:
|
||||
- "${PARAKEET_BIND:-0.0.0.0}:${PARAKEET_PORT}:8000"
|
||||
environment:
|
||||
- NVIDIA_VISIBLE_DEVICES=all
|
||||
- HF_HOME=/models
|
||||
- DEVICE=cuda
|
||||
- MODEL_PRECISION=${PARAKEET_MODEL_PRECISION:-fp16}
|
||||
- BATCH_SIZE=${PARAKEET_BATCH_SIZE:-4}
|
||||
- TARGET_SAMPLE_RATE=16000
|
||||
- MAX_AUDIO_DURATION=${PARAKEET_MAX_AUDIO_DURATION:-30}
|
||||
- VAD_THRESHOLD=${PARAKEET_VAD_THRESHOLD:-0.5}
|
||||
- PROCESSING_TIMEOUT=${PARAKEET_PROCESSING_TIMEOUT:-60}
|
||||
- MODEL_DIR=/models
|
||||
- MODEL_URL=${PARAKEET_MODEL_URL}
|
||||
- PROVIDER=${PARAKEET_PROVIDER:-cuda}
|
||||
- NUM_THREADS=${PARAKEET_NUM_THREADS:-1}
|
||||
- LOG_LEVEL=${PARAKEET_LOG_LEVEL:-INFO}
|
||||
volumes:
|
||||
- ${PARAKEET_MODELS_DIR}:/models
|
||||
@@ -55,13 +42,11 @@ services:
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
# First `up` may spend several minutes on torch/NeMo install
|
||||
# during the image build phase; after the image exists, startup
|
||||
# is ~30-60s (NeMo model load).
|
||||
start_period: 180s
|
||||
# First boot may include a ~400 MB model download.
|
||||
start_period: 300s
|
||||
labels:
|
||||
- homepage.group=AI Systems
|
||||
- homepage.name=Parakeet ASR
|
||||
- homepage.icon=mdi-microphone
|
||||
- homepage.description=Parakeet-TDT speech-to-text (irv-ml1)
|
||||
- homepage.description=Parakeet-TDT speech-to-text via sherpa-onnx (irv-ml1)
|
||||
- homepage.href=http://10.100.79.3:${PARAKEET_PORT}
|
||||
|
||||
Reference in New Issue
Block a user