#!/bin/sh # Start von whisper-server für NEX (Spracherkennung, OpenAI-kompatibel). # - Parameter laut Auftrag: -l de -bs 5 --convert, ohne --print-realtime (kein Text im Log). # - Temp-Dateien nur im tmpfs; Reste (Fehlerpfad von whisper-server) werden regelmäßig gelöscht. # - Nach dem Start einmal mit 1 s Stille aufwärmen. set -eu MODEL="${WHISPER_MODEL:-/models/whisper/ggml-large-v3-turbo.bin}" PORT="${WHISPER_PORT:-8178}" HOST="${WHISPER_HOST:-0.0.0.0}" TMP_DIR="${WHISPER_TMP_DIR:-/run/nex-whisper}" BEAM="${WHISPER_BEAM_SIZE:-5}" LANGUAGE="${WHISPER_LANGUAGE:-de}" # Zusätzliche Schalter, z. B. "-nfa" (Flash-Attention aus) oder "-t 4" EXTRA="${WHISPER_EXTRA_ARGS:-}" mkdir -p "$TMP_DIR" chmod 0700 "$TMP_DIR" # Aufräumer: Dateien älter als 10 Minuten im tmpfs löschen ( while sleep 300; do find "$TMP_DIR" -type f -mmin +10 -delete 2>/dev/null || true; done ) & cleaner=$! # shellcheck disable=SC2086 whisper-server -m "$MODEL" -l "$LANGUAGE" -bs "$BEAM" --convert --tmp-dir "$TMP_DIR" \ --inference-path /v1/audio/transcriptions --host "$HOST" --port "$PORT" $EXTRA & pid=$! stop() { kill -TERM "$pid" 2>/dev/null || true; kill "$cleaner" 2>/dev/null || true; } trap stop TERM INT # Warten, bis das Modell geladen ist (/health liefert bis dahin 503) i=0 until curl -fsS "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1; do kill -0 "$pid" 2>/dev/null || { echo "whisper-server beendet sich beim Start" >&2; wait "$pid" || exit $?; exit 1; } i=$((i + 1)) [ "$i" -le 600 ] || { echo "whisper-server nach 600 s nicht bereit" >&2; stop; exit 1; } sleep 1 done # Aufwärmen: 1 s Stille, Ergebnis wird verworfen warm="$TMP_DIR/warmup.wav" if ffmpeg -f lavfi -i anullsrc=r=16000:cl=mono -t 1 -c:a pcm_s16le -y "$warm" \ && curl -fsS -o /dev/null -F "file=@${warm}" -F response_format=json \ "http://127.0.0.1:${PORT}/v1/audio/transcriptions"; then echo "whisper-server bereit und aufgewärmt (Port ${PORT})" else echo "Aufwärmen fehlgeschlagen, Dienst läuft trotzdem" >&2 fi rm -f "$warm" # Auf whisper-server warten; nach einem Signal erneut warten, bis er wirklich beendet ist rc=0 wait "$pid" || rc=$? while kill -0 "$pid" 2>/dev/null; do wait "$pid" || rc=$?; done kill "$cleaner" 2>/dev/null || true exit "$rc"