# 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]
```
