# Erfaring: faster-whisper oppsett **Dato:** 2026-03-17 ## Kontekst Oppgave 7.1 — sette opp faster-whisper som Docker-tjeneste for norsk tale-til-tekst (STT). Serveren er en Hetzner VPS (8 vCPU, 16 GB RAM) uten GPU. ## Valg ### Image: `fedirz/faster-whisper-server` - Gir OpenAI-kompatibelt HTTP API (`/v1/audio/transcriptions`) - CPU-variant: `fedirz/faster-whisper-server:latest-cpu` - GPU-variant: `fedirz/faster-whisper-server:latest-cuda` (for fremtidig bruk) - Laster modell automatisk fra HuggingFace ved første request (lazy loading) ### Modell: `large-v3` - Best norsk kvalitet blant standard Whisper-modeller - ~2.5 GB RAM med int8-kvantisering (CPU) - Treigere enn `medium` på CPU, men akseptabelt for bakgrunnsjobber - Alternativ: `NbAiLab/nb-whisper-large` (norsk-finjustert) — ikke testet ### Kvantisering: `int8` - Halverer RAM-bruk vs float32, minimal kvalitetstap - Obligatorisk for CPU — float16 krever GPU ## Docker Compose-konfigurasjon ```yaml faster-whisper: image: fedirz/faster-whisper-server:latest-cpu restart: unless-stopped environment: WHISPER__MODEL: large-v3 WHISPER__INFERENCE_DEVICE: cpu WHISPER__COMPUTE_TYPE: int8 volumes: - /srv/synops/data/whisper-models:/root/.cache/huggingface - /srv/synops/media/cas:/srv/synops/media/cas:ro networks: - sidelinja-net healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen(\"http://localhost:8000/health\")"] interval: 30s timeout: 10s retries: 3 start_period: 120s ``` ## API-bruk Endepunkt fra Docker-nettverket: `http://faster-whisper:8000` ```bash # Enkel transkripsjon curl -X POST http://faster-whisper:8000/v1/audio/transcriptions \ -F "file=@lydfil.wav" \ -F "model=large-v3" \ -F "language=no" \ -F "response_format=verbose_json" ``` Respons (verbose_json): ```json { "task": "transcribe", "language": "no", "duration": 1.0, "text": "...", "segments": [ { "id": 1, "start": 0.0, "end": 3.5, "text": "...", "no_speech_prob": 0.01 } ] } ``` ## Ressursbruk - **RAM:** ~2.5 GB (idle, modell lastet) - **CPU:** Minimal ved idle. Bruker alle tilgjengelige kjerner under transkripsjon. - **Disk:** ~3 GB for large-v3 modell (i `/srv/synops/data/whisper-models/`) ## Gotchas 1. **Healthcheck:** Containeren har ikke `curl` installert. Bruk python3 urllib i stedet. 2. **Modellnedlasting:** Første request etter oppstart trigger modellnedlasting (~3 GB). `start_period: 120s` i healthcheck gir tid til dette. 3. **CAS-tilgang:** Containeren monterer CAS read-only for direkte filtilgang. Alternativt kan maskinrommet sende filer via multipart upload. 4. **Hallusinering:** Whisper hallusinerer tekst på stille/tone-filer (høy `no_speech_prob`). Filtrér segmenter med `no_speech_prob > 0.6` i postprosessering. ## Integrasjon med maskinrommet (oppgave 7.2) Transkripsjons-pipelinen er implementert i maskinrommet via jobbkøen: 1. **Trigger:** Når `upload_media` mottar en lydfil (MIME `audio/*`), opprettes en `whisper_transcribe`-jobb i `job_queue`. 2. **Worker:** Maskinrommet kjører en intern worker-loop som poller `job_queue` hvert 2. sekund. 3. **Prosessering:** Worker leser lydfilen fra CAS, sender den som multipart til faster-whisper API (`verbose_json`-format). 4. **Postprosessering:** Segmenter med `no_speech_prob > 0.6` filtreres bort (hallusinering). 5. **Lagring:** Transkripsjonstekst skrives til nodens `content`-felt. Metadata (`duration`, `language`, `segment_count`, `transcribed_at`) legges i `metadata.transcription`. 6. **Retry:** Ved feil, eksponentiell backoff (30s × 2^n), maks 3 forsøk. Kode: `maskinrommet/src/transcribe.rs`, `maskinrommet/src/jobs.rs` ## Ved GPU-oppgradering Bytt til CUDA-image og float16: ```yaml faster-whisper: image: fedirz/faster-whisper-server:latest-cuda environment: WHISPER__MODEL: large-v3 WHISPER__INFERENCE_DEVICE: cuda WHISPER__COMPUTE_TYPE: float16 deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ```