5a0bfba6a3
Replaces the manual rsync+build+run with a proper spark-control feature.
First in the audio path that doesn't require shell access on Spark 2.
What's in the box
─────────────────
* image/whisperx_container/ - the build context (Dockerfile, requirements,
app/main.py FastAPI wrapper). Mainline pipeline: faster-whisper for STT +
pyannote 3.1 for diarization + wav2vec2 forced alignment. Single endpoint
/v1/audio/transcribe-with-speakers returns the exact same shape spark-
control's existing endpoint does, so the recap-relay PR spec needs no
changes when we cut over.
* image/app/whisperx_install.py - install manager. ships build context to
Spark 2 over SSH, runs `docker build`, runs `docker run` with 40 GB
memory cap (vs Sortformer's unbounded which thrashed Spark 2 on a 90-min
file), polls /health until both Whisper + pyannote report loaded.
* Audio proxy: /api/audio/transcribe-with-speakers now prefers WhisperX
when its /health reports diarizer_loaded=true, falls back to the legacy
Parakeet + Sortformer path otherwise. Same response shape either way.
Clean cutover, easy rollback (`docker rm whisperx-asr`).
* Dashboard (Audio / Speech tab):
- "Add WhisperX" banner appears when not installed, with a primary
"Install WhisperX" button. One click triggers the install.
- Build progress dialog with phase + elapsed timer + live build log via
SSE (`/api/whisperx/install/{job_id}/stream`).
- After install, WhisperX auto-registers as a managed service alongside
Parakeet and Magpie (Start/Restart/Stop, deep-check, auto-restart).
- Banner self-hides once /api/whisperx/status reports healthy.
New endpoints
─────────────
GET /api/whisperx/status
POST /api/whisperx/install
GET /api/whisperx/install/{job_id}
GET /api/whisperx/install/{job_id}/stream (SSE phase + log)
Config additions (env)
──────────────────────
WHISPERX_HOST (defaults to spark2_host)
WHISPERX_USER (defaults to spark2_user)
WHISPERX_CONTAINER (default: whisperx-asr)
WHISPERX_PORT (default: 8002)
WHISPERX_MODEL (default: medium; tiny/base/small/medium/large-v3)
Dockerfile
──────────
Added COPY whisperx_container /app/whisperx_container so the runtime
install manager can read the build context from inside the spark-control
image and ship it over SSH.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
32 lines
1.1 KiB
Docker
32 lines
1.1 KiB
Docker
FROM python:3.12-slim
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends openssh-client curl ca-certificates \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /app
|
|
COPY pyproject.toml /app/
|
|
COPY app /app/app
|
|
COPY entrypoint.sh /app/entrypoint.sh
|
|
RUN chmod +x /app/entrypoint.sh
|
|
|
|
COPY models.yaml /app/models.yaml
|
|
|
|
# Parakeet container wrapper patches (diarizer.py + main.py overlay).
|
|
# Shipped inside spark-control so the "Reapply speech-model patches" action
|
|
# can copy these into the parakeet-asr container on Spark 2 over SSH at any
|
|
# time — survives docker rm + redeploy of the parakeet container.
|
|
COPY parakeet_patches /app/parakeet_patches
|
|
|
|
# WhisperX container build context (Dockerfile + requirements.txt + app/).
|
|
# The "Install WhisperX" action in spark-control ships these files to Spark 2
|
|
# over SSH, then runs `docker build` + `docker run` there. The container
|
|
# becomes a managed always-on service alongside parakeet-asr and magpie-tts.
|
|
COPY whisperx_container /app/whisperx_container
|
|
|
|
RUN pip install --no-cache-dir -e .
|
|
|
|
ENV BIND_PORT=9999
|
|
EXPOSE 9999
|
|
ENTRYPOINT ["/app/entrypoint.sh"]
|