Whisper Self-Hosted Strategy
Insurance Intelligence System — Transkrypcja Audio
Status: Do wdrożenia w Fazie 2
Data decyzji: 2026-09-17
Priorytet: Po uruchomieniu Poziomu 1 (YouTube captions)
Architektura transkrypcji — 3 poziomy
Poziom 1 — YouTube captions (teraz, bezpłatne)
youtube-transcript-api → tabela transcriptions
source_type = 'youtube_captions'
czas: natychmiastowy
Poziom 2 — faster-whisper small INT8 (Faza 2, bezkosztowy)
nocny batch przez n8n (02:00 UTC)
tylko filmy z transcription_queue = 'pending'
source_type = 'whisper_small'
czas: ~15-20 min / godzina audio
Poziom 3 — faster-whisper medium INT8 (opcjonalnie)
dla kluczowych wywiadów C-suite
source_type = 'whisper_medium'
lepsza jakość polskiego języka
Instalacja faster-whisper (gdy czas)
cd /opt/youtube-mcp
source venv/bin/activate
pip install faster-whisper yt-dlp
# Model pobierze się automatycznie przy pierwszym użyciu
# small INT8: ~500MB RAM, ~244M parametrów
from faster_whisper import WhisperModel
model = WhisperModel(
"small",
device="cpu",
compute_type="int8" # kluczowe — 4x szybciej, minimal quality loss
)
segments, info = model.transcribe("audio.mp3", language="pl")
Benchmarki na CPU (bez GPU)
| Model | Czas / 60 min audio | RAM | Jakość PL |
|---|---|---|---|
| whisper tiny INT8 | ~5 min | ~250MB | dostateczna |
| whisper small INT8 | ~15-20 min | ~500MB | dobra |
| whisper medium INT8 | ~35-40 min | ~780MB | bardzo dobra |
Rekomendacja: small INT8 dla batch nocnego, medium INT8 dla wywiadów C-suite
Schemat kolejkowania — flagi w bazie
Dodatkowe kolumny w tabeli transcriptions
ALTER TABLE transcriptions ADD COLUMN IF NOT EXISTS
transcription_status VARCHAR(20) DEFAULT 'none';
-- 'none' — nie sprawdzano
-- 'captions' — ma napisy YT, transkrypcja gotowa
-- 'pending' — brak napisów YT, czeka na Whisper
-- 'processing'— Whisper w trakcie
-- 'done' — Whisper gotowy
-- 'skipped' — niewystarczający relevance score
-- 'failed' — błąd transkrypcji
ALTER TABLE transcriptions ADD COLUMN IF NOT EXISTS
whisper_priority VARCHAR(10) DEFAULT 'normal';
-- 'high' — wywiad C-suite, wymienione TU w tytule
-- 'normal' — standardowy film
-- 'low' — niska wartość domenowa
ALTER TABLE transcriptions ADD COLUMN IF NOT EXISTS
whisper_queued_at TIMESTAMPTZ;
-- kiedy dodano do kolejki Whisper
ALTER TABLE transcriptions ADD COLUMN IF NOT EXISTS
whisper_model_used VARCHAR(20);
-- 'small' | 'medium' | 'large-v3'
Logika przypisywania flagi (Agent 2 Classifier)
def assign_transcription_flag(video: dict) -> str:
"""
Decyduje czy film idzie do kolejki Whisper i z jakim priorytetem.
Wywoływany po próbie pobrania napisów YT.
"""
title = video['title'].lower()
relevance = video['relevance_score']
# Ma napisy YT → nie potrzebujemy Whispera
if video['has_youtube_captions']:
return 'captions', None
# Brak napisów YT → oceniamy czy warto transkrybować
# Wysoki priorytet — sygnały C-suite
high_priority_signals = [
'prezes', 'ceo', 'cfo', 'cto', 'dyrektor',
'wywiad', 'strategia', 'wyniki', 'konferencja',
'pzu', 'warta', 'ergo', 'allianz', 'generali',
'knf', 'piu', 'bancassurance'
]
if any(s in title for s in high_priority_signals) or relevance >= 70:
return 'pending', 'high'
# Normalny priorytet
if relevance >= 50:
return 'pending', 'normal'
# Zbyt niski relevance — pomijamy
return 'skipped', None
Workflow n8n — nocny Whisper batch
Trigger: Cron 02:00 UTC (włączany/wyłączany przełącznikiem)
↓
Pobierz z bazy: SELECT * FROM transcriptions
WHERE transcription_status = 'pending'
ORDER BY whisper_priority DESC, whisper_queued_at ASC
LIMIT 10
↓
Dla każdego filmu:
1. Pobierz audio przez yt-dlp (MP3, max 192kbps)
2. Uruchom faster-whisper (model zależny od priority)
3. Zapisz transkrypcję do tabeli transcriptions
4. Ustaw transcription_status = 'done'
5. Usuń plik audio z dysku
↓
Log: ile przetworzone, ile błędów, czas CPU
Dashboard — widok kolejki
Widok w dashboardzie pokazujący: - Filmy czekające na Whisper (pending) z priorytetem - Historia transkrypcji (done) z czasem przetwarzania - Przycisk "Dodaj do kolejki high priority" dla ręcznego dodania - Toggle włącz/wyłącz nocny scheduler
Decyzje do podjęcia w Fazie 2
- Który model Whisper jako domyślny (small vs medium)?
- Limit filmów per noc (10? 20? zależnie od długości)?
- Czy medium tylko dla high priority, small dla normal?
- Czy chcemy diarization (kto mówi) — wymaga WhisperX?
- Retencja plików audio — usuwać po transkrypcji (tak)?