From b1551fe5f8b1311e7765a9bd28df75c3cda1243e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 11 Jun 2026 16:17:17 +0000 Subject: [PATCH] Ajout des 3 propositions d'architecture pour LiveFlow https://claude.ai/code/session_01YHMp3EKzr4s6o8w1ygxuUe --- ARCHITECTURE.md | 165 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 ARCHITECTURE.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..e1b9a56 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,165 @@ +# LiveFlow — Propositions d'architecture + +Application de transcription de réunions en direct, 100 % locale, hébergée dans Docker. + +**Besoins couverts :** +- Capturer l'audio en live depuis un micro (PC ou téléphone) +- Transcrire en texte, en local, sans aucun service cloud +- Afficher le texte en temps réel dans une interface web +- Récupérer / exporter la transcription (TXT, Markdown, SRT…) + +**Contrainte technique commune importante :** pour accéder au micro depuis un +navigateur (surtout sur téléphone), l'API `getUserMedia` exige du **HTTPS** +(sauf sur `localhost`). Toutes les propositions incluent donc un reverse proxy +TLS (Caddy ou Traefik) avec certificat auto-signé ou `mkcert` sur le réseau local. + +--- + +## Proposition 1 — Monolithe simple (1 conteneur) + +> *La plus simple à mettre en place et à maintenir. Idéale pour un usage perso +> ou une petite équipe, sur une machine unique (avec ou sans GPU).* + +``` +[Navigateur PC / Téléphone] + │ micro → MediaRecorder / Web Audio + │ WebSocket (audio chunks PCM/Opus) + ▼ +┌──────────────────────────────────────────┐ +│ Conteneur "liveflow" │ +│ ┌────────────────────────────────────┐ │ +│ │ FastAPI (Python) │ │ +│ │ • sert le frontend (HTML/JS) │ │ +│ │ • WebSocket /transcribe │ │ +│ │ • VAD Silero (découpe la parole) │ │ +│ │ • faster-whisper (ASR embarqué) │ │ +│ │ • SQLite (réunions + segments) │ │ +│ └────────────────────────────────────┘ │ +└──────────────────────────────────────────┘ + ▲ +Caddy (HTTPS local) — peut être dans le même compose +``` + +**Stack :** Python / FastAPI · faster-whisper (modèles Whisper `small` → `large-v3`, +CPU ou GPU) · Silero VAD · SQLite · frontend vanilla JS ou Svelte/Vue léger. + +**Fonctionnement :** le navigateur capture le micro, envoie l'audio par +WebSocket ; le VAD détecte les fins de phrases ; chaque segment est transcrit +et renvoyé au navigateur (texte qui s'affiche au fil de l'eau) ; tout est +stocké en SQLite ; bouton « Exporter » → TXT/MD/SRT. + +| ✅ Avantages | ❌ Limites | +|---|---| +| 1 seul conteneur, un `docker compose up` et c'est fini | Modèle ASR couplé à l'app (changer de moteur = modifier le code) | +| Aucune dépendance réseau, très peu de pièces mobiles | Une seule réunion simultanée confortable (selon machine) | +| Fonctionne sur CPU (modèle `small`/`medium`) | Pas de diarisation (qui parle) | + +--- + +## Proposition 2 — App + moteur ASR séparé (2-3 conteneurs) ⭐ Recommandée + +> *Le meilleur compromis simple / puissant / évolutif. On réutilise un conteneur +> de transcription existant exposant une API standard, comme demandé.* + +``` +[Navigateur PC / Téléphone] + │ HTTPS + WebSocket + ▼ +┌─────────────┐ ┌──────────────────────────────┐ +│ Caddy (TLS) │ ──▶ │ Conteneur "app" (FastAPI) │ +└─────────────┘ │ • frontend + API + WebSocket│ + │ • VAD + découpage │ + │ • SQLite/Postgres │ + └──────────┬───────────────────┘ + │ HTTP (API style OpenAI /v1/audio/transcriptions) + ▼ + ┌──────────────────────────────┐ + │ Conteneur ASR (interchangeable)│ + │ ex. Speaches (faster-whisper),│ + │ whisper.cpp server, ou un │ + │ modèle Qwen audio via vLLM │ + └──────────────────────────────┘ +``` + +**Stack :** docker-compose à 3 services : `caddy` + `app` + `asr`. +Pour le service ASR, des images Docker prêtes à l'emploi existent : +- **Speaches** (ex *faster-whisper-server*) : API compatible OpenAI, streaming, CPU/GPU +- **whisper.cpp server** : très léger, idéal CPU +- **vLLM / autre runtime** servant un modèle audio de la famille Qwen si vous voulez rester sur Qwen + +L'app ne connaît que l'URL `ASR_BASE_URL` : **changer de moteur = changer une +ligne dans le compose**, zéro modification de code. + +| ✅ Avantages | ❌ Limites | +|---|---| +| Moteur ASR interchangeable (Whisper aujourd'hui, Qwen demain) | 2-3 conteneurs à orchestrer (reste trivial avec compose) | +| On réutilise des images Docker existantes et maintenues | Légère latence en plus (HTTP entre app et ASR) | +| Le GPU est isolé dans le conteneur ASR ; l'app reste légère | | +| Évolutif : on peut répliquer le service ASR plus tard | | + +--- + +## Proposition 3 — Pipeline temps réel complet (le plus puissant) + +> *Pour plusieurs réunions simultanées, plusieurs participants, diarisation +> (« qui a dit quoi ») et résumé automatique par LLM local. Plus de pièces, +> mais chaque besoin avancé est couvert.* + +``` +[PC / Téléphones des participants] + │ WebRTC (latence < 200 ms, gestion réseau mobile) + ▼ +┌────────────────────────────────────────────────────────────┐ +│ docker-compose │ +│ │ +│ Traefik/Caddy (TLS) ── LiveKit (SFU WebRTC auto-hébergé) │ +│ │ pistes audio par participant│ +│ ▼ │ +│ Worker(s) de transcription (Python) │ +│ • VAD Silero + streaming ASR (faster-whisper/WhisperX) │ +│ • Diarisation pyannote OU 1 piste = 1 participant via │ +│ WebRTC (diarisation "gratuite") │ +│ │ │ +│ Redis (pub/sub live) ── Postgres (réunions, segments) │ +│ │ │ +│ Ollama (Qwen3 / LLM local) ◀ résumé, comptes-rendus, │ +│ points d'action en fin de │ +│ réunion │ +│ │ │ +│ Frontend (React/Svelte) : texte live par locuteur, │ +│ historique, recherche, export TXT/MD/SRT/JSON │ +└────────────────────────────────────────────────────────────┘ +``` + +**Stack :** LiveKit (self-hosted) · workers Python (faster-whisper/WhisperX + +pyannote) · Redis · Postgres · Ollama avec Qwen3 pour le résumé · frontend SPA. + +| ✅ Avantages | ❌ Limites | +|---|---| +| Multi-réunions, multi-participants, latence minimale | 6-7 conteneurs : nettement plus complexe à opérer | +| Diarisation : transcription attribuée à chaque locuteur | GPU quasi indispensable (ASR + diarisation + LLM) | +| Résumé / compte-rendu automatique par LLM local (Qwen3) | Surdimensionné pour un usage solo | +| Toujours 100 % local | | + +--- + +## Comparatif et recommandation + +| | P1 Monolithe | P2 App + ASR ⭐ | P3 Pipeline complet | +|---|---|---|---| +| Conteneurs | 1 (+TLS) | 3 | 6-7 | +| Complexité | ★ | ★★ | ★★★★ | +| Réutilise des images ASR existantes | Non | **Oui** | Oui | +| Moteur interchangeable (Whisper ↔ Qwen…) | Non | **Oui** | Oui | +| Diarisation (qui parle) | Non | Optionnelle plus tard | Oui | +| Résumé LLM (Qwen3 via Ollama) | Non | Facile à ajouter | Oui | +| GPU requis | Non (CPU ok) | Non (CPU ok) | Recommandé | +| Multi-réunions simultanées | Limité | Moyen | Oui | + +**Recommandation : Proposition 2.** Elle reste « simple, efficace et +puissante » : un compose de 3 services, l'interface fait tout +(transcrire → afficher → exporter), et elle répond exactement à votre idée de +« dépendre de dockers qui font déjà de la transcription » — le moteur ASR est +un conteneur sur étagère qu'on peut remplacer à tout moment. Le jour où il +faut la diarisation ou le résumé automatique, on ajoute un service au compose +et on migre en douceur vers la proposition 3, sans rien jeter.