mirror of
https://github.com/R0m1k3/LiveFlow.git
synced 2026-10-11 17:27:19 +02:00
166 lines
8.7 KiB
Markdown
166 lines
8.7 KiB
Markdown
# 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.
|