TranscrIA

August 2, 2026 · View on GitHub

Statut : 🟱 ImplĂ©mentĂ© — sert de rĂ©fĂ©rence SÉMANTIQUE du contrat du inference_service (les renvois §4bis dans inference_service/ pointent ici) ; la liste des routes est dĂ©sormais GÉNÉRÉE dans API_REFERENCE.md (vague C8, gardĂ©e en CI). Diarisation, empreinte vocale et STT distants sont en production ; voir aussi SERVICE_RESSOURCES_GPU.md (autonomie VRAM, A/B/C, admission §7.2) et CONCURRENCE_ET_CHARGE_PHASE_B.md (failover des nƓuds, rĂŽles).
Auteur : Martossien · Cadrage initial : 2026-05-30
Objectif : faire de TranscrIA un frontend / orchestrateur qui appelle des serveurs d'infĂ©rence distants (vLLM, vLLM-omni, service maison) oĂč rĂ©sident les ressources GPU/VRAM, plutĂŽt que de charger les modĂšles dans le process applicatif.


0. Résumé exécutif

Aujourd'hui TranscrIA charge la plupart de ses modĂšles dans son propre process (transformers, faster-whisper, NeMo, pyannote) et gĂšre lui-mĂȘme la VRAM via VRAMManager/GPUSession. Exception notable : le LLM d'arbitrage est dĂ©jĂ  consommĂ© en API OpenAI-compatible (http://host:port/v1). C'est le modĂšle de rĂ©fĂ©rence vers lequel tendre.

La cible : séparer le plan de contrÎle (TranscrIA) du plan de calcul (serveurs GPU).

┌──────────────────────────────┐         ┌────────────────────────────────────────┐
│  TranscrIA — Frontend         │  HTTP   │  Plan de calcul (GPU distant)            │
│  (CPU, pas de modĂšle chargĂ©)  │ ──────â–ș │                                          │
│  ‱ Web / workflow / file      │         │  vLLM  → LLM + Cohere + Whisper (ASR)    │
│  ‱ QualitĂ© / lexique / DOCX   │         │          + Granite (omni, chat audio)    │
│  ‱ Audit / notifications      │         │  Service dĂ©diĂ© (FastAPI / Riva-Triton) → │
│  ‱ Preflight / scene (CPU)    │ ◄────── │    diarisation, embeddings voix,         │
│                               │  JSON   │    Parakeet                              │
└──────────────────────────────┘         └────────────────────────────────────────┘

Trois catégories de composants, par difficulté de bascule :

  1. DĂ©jĂ  API — le LLM (texte). Rien Ă  faire, valider la config distante.
  2. Servable par vLLM (vĂ©rifiĂ© sur doc officielle, voir §2.2) — Whisper, Cohere Transcribe et Granite Speech. C'est la bonne surprise : la majoritĂ© du STT passe par vLLM, pas par un service maison. RĂ©serve sur la richesse des rĂ©ponses (§3.2) et distinction ASR-dĂ©diĂ© vs LLM-audio (§2.2).
  3. Aucun standard / service dĂ©diĂ© — diarisation (pyannote, Sortformer), Parakeet (NeMo, pas de support vLLM trouvĂ©), embeddings voix. → service d'infĂ©rence dĂ©diĂ© (FastAPI maison et/ou NVIDIA Riva/Triton pour les modĂšles NeMo).

Point dur central, confirmé : la diarisation n'a aucune API standard (ni vLLM, ni OpenAI). C'est elle qui justifie le « service pour ce qui ne passe pas en API ». Le périmÚtre de ce service est cependant plus réduit que prévu : essentiellement diarisation + embeddings voix (+ Parakeet à confirmer), puisque Cohere/Granite/Whisper rejoignent vLLM.


1. État des lieux — qui charge quoi, et oĂč

1.1 Inventaire des composants GPU

ComposantChargement actuelServable par vLLM ?Cible
LLM arbitrage / rĂ©sumĂ©Serveur OpenAI-compatible :8080 (HttpLLMBackend)✅ dĂ©jĂ  (/v1/chat/completions)DĂ©jĂ  fait
Whisper large-v3faster-whisper, in-process✅ vLLM, ASR (/v1/audio/transcriptions)vLLM
Cohere Transcribetransformers, in-process✅ vLLM confirmĂ© (vllm serve CohereLabs/cohere-transcribe-03-2026 --trust-remote-code, vllm[audio])vLLM
Granite Speech 4.1transformers, in-process✅ vLLM confirmĂ© (LLM audio-in, /v1/chat/completions multimodal)vLLM (omni)
Parakeet TDT (NeMo)NeMo, in-process❌ pas de support vLLM trouvĂ©service dĂ©diĂ© / Riva-Triton
pyannote community-1pyannote.audio, in-process❌ aucun standardservice maison
Sortformer 4spk (NeMo)NeMo, in-process❌ (NeMo)service maison / Riva-Triton
Embeddings voixin-process❌ (/v1/embeddings = texte)service maison
VAD Silero, preflight, scÚnelibrosa/CPUn/a (CPU)reste cÎté frontend

1.2 Abstractions dĂ©jĂ  en place — les points d'insertion

Le code a déjà les bonnes coutures pour brancher des implémentations « remote » sans réécrire le pipeline :

  • transcria/stt/base_transcriber.py — ABC BaseTranscriber : available(), load(), transcribe(audio_path|audio_array, language, 
) -> list[dict], offload(). → un RemoteTranscriber(BaseTranscriber) qui poste l'audio Ă  une API implĂ©mente cette interface tel quel.
  • transcria/stt/base_diarizer.py — ABC BaseDiarizer (+ diarizer_factory). → un RemoteDiarizer(BaseDiarizer).
  • transcria/gpu/llm_backend.py — HttpLLMBackend.base_url pointe dĂ©jĂ  vers un /v1 arbitraire. → la bascule LLM distant est une affaire de config.
  • transcria/stt/transcriber_factory.py / diarizer_factory.py — sĂ©lection du backend par config. → ajouter un backend remote au factory.

Conséquence architecturale forte : la migration n'impose pas de refonte du pipeline. Elle consiste à fournir des implémentations Remote* des ABC existantes et à les cùbler dans les factories. Le VRAMManager/GPUSession devient optionnel cÎté client (voir §4.3).


2. Protocoles cibles

2.1 LLM texte — OpenAI-compatible (dĂ©jĂ  opĂ©rationnel)

/v1/chat/completions et /v1/completions. Servi par vLLM, llama-server, ollama. Le contrat est stable et riche. Aucune action sauf : permettre une base_url non-localhost + clé API + TLS (voir §3.9).

2.2 STT via vLLM — deux familles de modùles, deux endpoints

vLLM sert trois des backends STT historiques du projet (cohere, whisper, parakeet — le projet en compte davantage depuis), mais via deux mĂ©canismes diffĂ©rents qu'il faut bien distinguer car ils n'ont pas le mĂȘme contrat de rĂ©ponse.

Famille A — ASR dĂ©diĂ©s → /v1/audio/transcriptions

ModÚles spécialisés transcription, exposés sur l'endpoint OpenAI Audio.

  • Whisper : supportĂ© par vLLM (AudioAsset, ASR).
  • Cohere Transcribe : ✅ confirmĂ© doc officielle —
    uv pip install -U vllm==0.19.0 --torch-backend=auto
    uv pip install vllm[audio] librosa
    vllm serve CohereLabs/cohere-transcribe-03-2026 --trust-remote-code
    
    Sert un endpoint de transcription audio. C'est le chemin privilégié puisque Cohere est le backend par défaut du projet.

Réponse : texte + segments, verbose_json ajoute des timestamps de segment.

Famille B — LLM audio-in (omni) → /v1/chat/completions multimodal

ModÚles génératifs qui prennent de l'audio en entrée et produisent du texte. Ce ne sont pas des ASR classiques.

  • Granite Speech 4.1 : ✅ confirmĂ© doc officielle — exemple vLLM avec LLM / SamplingParams / AudioAsset. C'est un LLM audio-in : en serving, l'audio est passĂ© comme contenu multimodal d'un message /v1/chat/completions, la rĂ©ponse est du texte gĂ©nĂ©rĂ©.

ConsĂ©quence importante : la famille B ne renvoie pas de structure native segment/timestamp/confiance — c'est de la gĂ©nĂ©ration de texte. La perte de champs (§3.2) y est maximale. Granite reste donc un backend d'appoint, pas un remplaçant direct de Cohere/Whisper pour le pipeline qui s'appuie sur les timestamps et no_speech_prob.

⚠ RĂ©serve critique — perte de champs (vaut pour les deux familles)

Le pipeline dépend de signaux que ces endpoints ne renvoient pas toujours :

  • no_speech_prob par segment (utilisĂ© par reliability)
  • avg_logprob / confiance mot-Ă -mot (reliability → mots_faible_confiance)
  • timestamps mot-Ă -mot (alignement et rĂ©alignement locuteurs)

→ Options : (a) configurer vLLM pour exposer ces champs si le modĂšle/endpoint le permet, (b) enrichir via un wrapper, ou (c) dĂ©gradation documentĂ©e du reliability en mode distant. À trancher — principal compromis fonctionnel de la bascule STT, et c'est prĂ©cisĂ©ment ce que le mode hybride (STT_ADAPTATIF_ET_HYBRIDE.md) peut compenser (re-transcription ciblĂ©e).

2.3 Parakeet — pas de vLLM

Aucun support vLLM trouvé pour Parakeet TDT (modÚle NeMo). Options : le servir via NVIDIA Riva / Triton (serving natif NeMo) ou l'intégrer au service maison. Comme c'est un backend expérimental, il peut rester en dernier dans la migration (voire local le temps de la transition).

2.4 Le service d'inférence dédié (« TranscrIA Inference Service »)

PĂ©rimĂštre rĂ©duit depuis la confirmation vLLM : ce service ne porte plus les STT principaux (Cohere/Granite/Whisper → vLLM), mais ce qui n'a aucun standard :

  • diarisation (pyannote community-1, Sortformer) — le vrai point dur ;
  • embeddings voix (empreintes locales) ;
  • Parakeet (optionnel, si on ne passe pas par Riva/Triton).

Un service FastAPI hébergé prÚs des GPU, contrat propre à TranscrIA :

POST /infer/diarize        body: audio (ref ou upload) + num/min/max_speakers (optionnels)  → tours, embeddings, samples
POST /infer/voice-embed    body: audio  → vecteur d'empreinte
POST /infer/transcribe     body: audio + backend(parakeet) + lang  → segments enrichis  (optionnel)
GET  /health  /ready  /models                                     → supervision

Alternative pour les modĂšles NeMo (Sortformer, Parakeet) : NVIDIA Riva / Triton offre un serving natif NeMo. À Ă©valuer contre le service FastAPI maison — Triton apporte le batching/scaling, le FastAPI maison apporte le contrĂŽle du format de rĂ©ponse (le format speaker_turns.json actuel devient le contrat).

Ce service rĂ©utilise le code STT/diarisation existant de TranscrIA (les classes actuelles), simplement dĂ©placĂ© derriĂšre une API. Il porte aussi le VRAMManager/GPUSession cĂŽtĂ© serveur (lĂ  oĂč sont rĂ©ellement les GPU).


3. ProblĂšmes techniques Ă  anticiper (exhaustif)

Section centrale. Chaque point est un risque réel à traiter avant ou pendant la migration.

3.1 Transfert de l'audio vers le serveur

Le STT/diarisation distant a besoin de l'audio. Trois stratégies, chacune avec un coût :

  • Upload multipart par requĂȘte : simple, mais fichiers de rĂ©union volumineux (1h ≈ 100+ Mo WAV) → limites de taille HTTP, mĂ©moire, timeouts.
  • Base64 inline : +33 % de volume, Ă  proscrire pour le gros audio.
  • Stockage partagĂ© (NFS / objet S3-like) : le frontend dĂ©pose l'audio, le serveur lit une rĂ©fĂ©rence. Plus efficace mais ajoute une dĂ©pendance d'infra et un sujet de droits/RGPD (oĂč vit l'audio).

→ Recommandation : stockage partagĂ© pour le batch, upload pour les petits extraits. À cadrer selon l'infra cible.

3.2 Richesse des réponses STT (cf. §2.2)

Le pipeline « casse » silencieusement si no_speech_prob / confiance mot-Ă -mot / timestamps mot disparaissent : reliability perd ses signaux, le rĂ©alignement locuteurs se dĂ©grade. → dĂ©finir un contrat minimal de rĂ©ponse STT que tout backend distant doit honorer, et un mode dĂ©gradĂ© explicite sinon.

3.3 Diarisation — aucun standard

Pas de /v1/diarization. Le service maison doit exposer : tours exclusifs, embeddings par locuteur, extraits audio (samples), genre vocal. Le format de speaker_turns.json / speaker_stats.json actuel devient le contrat de l'API. Attention au volume (embeddings, clips audio renvoyés).

3.4 Le VRAMManager local perd son sens

VRAMManager mesure la VRAM locale et choisit un GPU local. Si les GPU sont distants, le client ne les voit plus. Conséquences :

  • La logique « meilleur GPU libre » migre cĂŽtĂ© serveur.
  • La file d'attente (queue) ne doit plus raisonner en « GPU local » mais en capacitĂ© serveur (slots, concurrence acceptĂ©e par l'endpoint). Le QueueScheduler doit interroger la disponibilitĂ© distante, pas nvidia-smi.
  • CUDA_VISIBLE_DEVICES, le remapping, le nettoyage des process LLM concurrents → deviennent des prĂ©occupations serveur.

3.5 Latence et timeouts

Transfert rĂ©seau + infĂ©rence distante + retour. Sur 1h d'audio, le temps total peut dĂ©passer les timeouts HTTP par dĂ©faut. Les timeouts actuels (summary_llm.timeout_seconds=1800) sont pensĂ©s local. → timeouts dĂ©diĂ©s par type d'appel, et traitement asynchrone (job cĂŽtĂ© serveur + polling) plutĂŽt que requĂȘte synchrone longue pour le gros audio.

3.6 Gestion d'erreur réseau et résilience

Un serveur distant tombe, sature, ou répond en erreur. Le pipeline ne doit pas mourir :

  • Retry avec backoff sur erreurs transitoires.
  • Circuit breaker : ne pas marteler un serveur down.
  • Fallback : repli sur un autre serveur, ou sur le mode local si le modĂšle est encore installable cĂŽtĂ© client (option de transition).
  • Distinguer erreur rĂ©seau (retry) d'erreur mĂ©tier (audio invalide → pas de retry).

3.7 Concurrence et batching

Plusieurs jobs TranscrIA simultanĂ©s → N requĂȘtes au serveur. vLLM gĂšre le batching nativement ; le service maison doit gĂ©rer sa propre file/concurrence (sinon OOM GPU cĂŽtĂ© serveur). La concurrence cĂŽtĂ© client (workflow.execution.max_concurrent_jobs) doit ĂȘtre alignĂ©e avec la capacitĂ© rĂ©elle du serveur.

3.8 Cohérence et versionnement des modÚles

Le transcription_metadata.backend doit reflĂ©ter le modĂšle rĂ©ellement servi cĂŽtĂ© serveur, pas le modĂšle demandĂ©. Risque de dĂ©rive : le serveur met Ă  jour un modĂšle, les rĂ©sultats changent sans que le client le sache. → exposer la version du modĂšle via /models et la tracer dans les mĂ©tadonnĂ©es job.

3.9 Sécurité et secrets

  • ✅ ImplĂ©mentĂ© (Phase 0, inference_service/security.py) : clĂ© API partagĂ©e sur /infer/* (Bearer / X-API-Key, comparaison Ă  temps constant, sondes libres), allowlist de chemins file_ref anti-traversal (403 hors racines), limite d'upload (413). ClĂ© via variable d'env (auth.api_key_env), pas de secret en clair.
  • 🔜 TLS si le rĂ©seau n'est pas de confiance (terminaison cĂŽtĂ© reverse-proxy ou serveur WSGI).
  • L'audio quitte le frontend → vĂ©rifier la conformitĂ© RGPD (le serveur GPU est-il dans le mĂȘme pĂ©rimĂštre ?). CohĂ©rent avec la philosophie « tout local » actuelle du projet : si le serveur est externe, c'est une dĂ©cision Ă  auditer.

3.10 Observabilité

/metrics, /health, /ready doivent remonter l'Ă©tat des serveurs distants (joignables ? prĂȘts ? latence ?). Le health check actuel ne teste que la base locale. → ajouter des sondes vers chaque endpoint distant, et un Ă©tat « dĂ©gradĂ© » si un backend est injoignable.

3.11 Installation et empreinte client

Avantage de la bascule : le frontend n'a plus besoin de tĂ©lĂ©charger les modĂšles (gain d'install, moins de VRAM cĂŽtĂ© client, voire client CPU-only). Mais le serveur devient le point critique unique — sa disponibilitĂ© conditionne tout le pipeline. À documenter dans INSTALL.md (deux profils : client lĂ©ger / serveur GPU).

3.12 Chunking et préparation audio

Le dĂ©coupage (VAD, tours pyannote, chunks 30s) est aujourd'hui fait avant la transcription, cĂŽtĂ© pipeline. À dĂ©cider : le chunking reste-t-il cĂŽtĂ© frontend (envoi de chunks) ou migre-t-il cĂŽtĂ© serveur (envoi du fichier entier) ? Impacte le volume rĂ©seau et le contrat d'API.


4. Architecture cible détaillée

4.1 Ce qui reste cÎté frontend (TranscrIA)

Tout le plan de contrÎle, CPU-bound : web/auth/rÎles, workflow et états, file et planification (adaptée §3.4), lexiques, qualité, rapport DOCX, audit, notifications, preflight/scene/VAD (CPU). Le frontend devient déployable sans GPU.

4.2 Ce qui migre cÎté serveur(s)

  • vLLM : LLM (dĂ©jĂ ) + Cohere Transcribe + Whisper (ASR, /v1/audio/transcriptions) + Granite (omni, /v1/chat/completions). C'est le serveur principal d'infĂ©rence du projet.
  • TranscrIA Inference Service (FastAPI maison) et/ou Riva/Triton : diarisation (pyannote/Sortformer), embeddings voix, Parakeet. RĂ©utilise les classes existantes derriĂšre une API.

4.3 Le point d'insertion dans le code

# transcria/stt/transcriber_factory.py
if backend == "remote":
    return RemoteTranscriber(endpoint=cfg["remote_stt"]["url"], ...)   # implémente BaseTranscriber

# transcria/stt/diarizer_factory.py
if backend == "remote":
    return RemoteDiarizer(endpoint=cfg["remote_diar"]["url"], ...)     # implémente BaseDiarizer

Les Remote* postent l'audio, parsent la rĂ©ponse au mĂȘme format que les implĂ©mentations locales (list[dict] de segments enrichis, speaker_turns
). Le reste du pipeline ne voit aucune diffĂ©rence.

4.4 Configuration cible (esquisse)

inference:
  mode: local | remote | hybrid     # hybrid = certains backends distants, d'autres locaux
  llm:        { url: "http://gpu-host:8080/v1", api_key_env: "TRANSCRIA_LLM_KEY" }
  # STT via vLLM (Cohere/Whisper = ASR ; Granite = chat multimodal)
  stt:
    backend: remote
    cohere:  { url: "http://gpu-host:8001/v1", endpoint: audio_transcriptions, model: "CohereLabs/cohere-transcribe-03-2026" }
    whisper: { url: "http://gpu-host:8001/v1", endpoint: audio_transcriptions, model: "whisper-large-v3" }
    granite: { url: "http://gpu-host:8001/v1", endpoint: chat_completions,     model: "ibm-granite/granite-speech-4.1-2b" }
  # diarisation + embeddings : service dédié (pas de standard)
  diarization:{ backend: remote, url: "http://gpu-host:8002/infer/diarize" }
  voice_embed:{ url: "http://gpu-host:8002/infer/voice-embed" }
  transport:  { audio: shared_storage | upload, shared_root: "/mnt/transcria" }
  resilience: { timeout_s: 1800, retries: 2, circuit_breaker: true }

4bis. Phase 0 — Service maison en localhost (strangler pattern)

DĂ©cision (2026-05-30) : dĂ©marrer la migration en extrayant un seul composant (ce qui n'a aucun standard API) derriĂšre un service FastAPI tournant d'abord en 127.0.0.1, avant tout dĂ©mĂ©nagement distant. On valide la mĂ©canique client↔serveur sans la complexitĂ© rĂ©seau ; le passage distant ne sera qu'un changement d'URL.

4bis.1 PĂ©rimĂštre — uniquement ce qui doit absolument y passer

Le service ne porte que ce qui n'a pas de standard (les STT vont sur vLLM, §2.2) :

  1. Embeddings voix — petit, autonome → premier endpoint, valide tout le circuit avec un minimum de surface.
  2. Diarisation (pyannote + Sortformer) — le cƓur, plus riche (tours + samples + genre) → ensuite, mĂȘme patron.

4bis.2 Double topologie supportée dÚs le départ

Le mĂȘme service, le mĂȘme contrat, sert deux cas :

  • Mono-machine : frontend + service sur la mĂȘme machine → url: http://127.0.0.1:8002, transport audio par rĂ©fĂ©rence fichier (mĂȘme filesystem).
  • Frontal sĂ©parĂ© : service sur l'hĂŽte GPU → url: http://gpu-host:8002, transport upload / stockage partagĂ©.

→ Contrat identique, seule l'URL et le mode de transport changent. Le contrat audio supporte donc les deux modes (rĂ©fĂ©rence + upload) dĂšs la v1.

4bis.3 Gestion VRAM — pattern A/B/C (transposĂ© du LLM)

Quand une requĂȘte arrive, le service applique la mĂȘme logique que le LLM d'arbitrage :

CasSituationAction
AModÚle déjà résident en VRAMSert directement
BModÚle non chargé, VRAM libreCharge puis sert
CVRAM occupĂ©e (STT/LLM tient le GPU)503 + Retry-After → le QueueScheduler existant remet le job en file

Le CAS C rĂ©utilise la file existante cĂŽtĂ© frontend — pas de nouvelle file Ă  inventer cĂŽtĂ© service.

4bis.4 Allocation GPU — assignation statique, pas de nĂ©gociation

Pas de dialogue frontend↔service (couplage fragile, race conditions). À la place, selon la topologie :

  • Machine multi-GPU (ex. 8 cartes) : assignation statique par rĂŽle via CUDA_VISIBLE_DEVICES. Ex. GPU 0-2 → vLLM (LLM+STT), GPU 3 → service diarisation, etc. Aucun conflit, aucune nĂ©gociation. Le service a son GPU → modĂšle rĂ©sident avec idle-timeout (dĂ©charge aprĂšs N min d'inactivitĂ©).
  • Machine mono-GPU : un seul arbitre VRAM (jamais deux). Le service charge/dĂ©charge Ă  la demande en respectant l'arbitre → modĂšle Ă  la demande, CAS C via la file.

ConsĂ©quence : « modĂšle rĂ©sident vs Ă  la demande » dĂ©coule de la topologie, ce n'est pas un choix indĂ©pendant. Et l'assignation statique (multi-GPU) rend le CAS C quasi inutile en pratique — c'est un filet de sĂ©curitĂ©.

4bis.5 Squelette envisagé

inference_service/                 # FastAPI, hors package frontend
  app.py                           # /health /ready /models
  routes/voice_embed.py            # POST /infer/voice-embed   ← Ă©tape 1 (simple)
  routes/diarize.py                # POST /infer/diarize        ← Ă©tape 2 (cƓur)
  engine/                          # réutilise transcria.voice.embedding / stt.diarization
  vram.py                          # logique A/B/C + idle-timeout (multi-GPU) ou arbitre (mono)

Config cĂŽtĂ© frontend (mode: hybrid → fallback local si le service ne rĂ©pond pas) :

inference:
  mode: hybrid
  diarization:{ backend: remote, url: "http://127.0.0.1:8002/infer/diarize", fallback_local: true }
  voice_embed:{ url: "http://127.0.0.1:8002/infer/voice-embed", fallback_local: true }
  transport:  { audio: file_ref }   # file_ref en mono-machine, upload en distant

5. Plan de migration progressif

ÉtapeContenuRisquePrĂ©requis
0Valider le LLM distant (dĂ©jĂ  API) avec base_url non-localhost + clĂ©Faible—
1RemoteTranscriber Cohere via vLLM (vllm serve CohereLabs/cohere-transcribe-03-2026) — backend par dĂ©faut, gain immĂ©diat. DĂ©cider du sort des champs perdus (§3.2)MoyenvLLM[audio]
2Ajouter Whisper (mĂȘme endpoint ASR) puis Granite (chat multimodal) au RemoteTranscriberFaibleĂ©tape 1
3✅ TranscrIA Inference Service (Flask) : /health /ready /models, sĂ©curitĂ© des fluxFait—
3b✅ Embeddings voix distants (/infer/voice-embed)FaitĂ©tape 3
4✅ Diarisation distante (RemoteDiarizer + /infer/diarize + factory backend=remote) + client frontend InferenceClient (auth, transports, retry, fallback local)FaitĂ©tape 3
5✅ Empreinte vocale distante (RemoteVoiceEmbeddingBackend + create_voice_embedding_backend(), contrĂŽle d'intĂ©gritĂ© sha256, fallback local) cĂąblĂ©e dans VoiceEnrollmentService ; reste Parakeet (service maison ou Riva/Triton)Fait (Parakeet Ă  part)client OK
6Adapter QueueScheduler au scheduling « capacitĂ© serveur » (§3.4), neutraliser VRAMManager cĂŽtĂ© clientÉlevéétapes 1-5
7RĂ©silience transverse : ✅ retry/backoff + fallback faits cĂŽtĂ© client ; reste circuit breaker, sondes /metrics distantes (§3.6, §3.10)Partieltoutes
8Profil d'install « client léger » dans INSTALL.mdFaibletoutes

RĂ©ordonnancement clĂ© vs version initiale : les STT (Cohere/Whisper/Granite) passent en tĂȘte car vLLM les sert directement — c'est rapide et Ă  fort gain. Le service maison se concentre dĂ©sormais sur la diarisation + embeddings (Ă©tapes 3-5), pĂ©rimĂštre rĂ©duit.

Ordre conseillĂ© : 0 → 1/2 (STT via vLLM, gain rapide) → 3/4 (le cƓur dur : service maison + diarisation) → 5 → 6/7 (industrialisation) → 8.

Le mode hybride de STT_ADAPTATIF_ET_HYBRIDE.md devient trivial une fois cette migration faite : re-transcrire les segments douteux = appels API parallĂšles, sans charge/dĂ©charge GPU. Les deux chantiers sont complĂ©mentaires — l'API d'abord, l'hybride ensuite.


6. Questions ouvertes (Ă  trancher avec les retours users / infra)

  • PĂ©rimĂštre RGPD : le serveur GPU est-il dans le mĂȘme pĂ©rimĂštre de confiance que le frontend ? L'audio peut-il en sortir ? (cohĂ©rence avec la philosophie « tout local » actuelle).
  • Transport audio : stockage partagĂ© (NFS/S3) ou upload par requĂȘte ? DĂ©pend de l'infra cible.
  • Champs STT : exige-t-on un contrat enrichi (no_speech_prob, logprobs, timestamps mot) cĂŽtĂ© serveur, ou accepte-t-on un reliability dĂ©gradĂ© en mode distant ? (Critique pour Granite-omni qui ne renvoie que du texte.)
  • Granite via chat vs ASR : Granite (famille B) ne produit pas de timestamps. Le garde-t-on comme backend secondaire, ou seulement pour des cas oĂč la structure segment importe peu ?
  • Diarisation NeMo : service FastAPI maison ou NVIDIA Riva/Triton pour Sortformer (et Parakeet) ?
  • Synchrone vs asynchrone : requĂȘte longue bloquante ou job serveur + polling pour le gros audio ?
  • Mode hybrid : autorise-t-on certains backends distants et d'autres locaux simultanĂ©ment (transition douce) ?
  • Un seul serveur ou plusieurs : vLLM unifiĂ© (LLM + Cohere + Whisper + Granite) + service diarisation, ou un serveur par fonction ?

7. Fichiers concernés (au moment de l'implémentation)

transcria/stt/base_transcriber.py        # ABC — dĂ©jĂ  le bon contrat
transcria/stt/transcriber_factory.py      # ajouter backend "remote"
transcria/stt/remote_transcriber.py       # NOUVEAU — RemoteTranscriber vers vLLM
                                          #   (Cohere/Whisper → /v1/audio/transcriptions ;
                                          #    Granite → /v1/chat/completions multimodal)
transcria/stt/base_diarizer.py            # ABC
transcria/stt/diarizer_factory.py         # ajouter backend "remote"
transcria/stt/remote_diarizer.py          # NOUVEAU — RemoteDiarizer vers service dĂ©diĂ©
transcria/gpu/llm_backend.py              # HttpLLMBackend : base_url distante + clĂ© (quasi prĂȘt)
transcria/gpu/vram_manager.py             # neutralisable / conditionnel cÎté client (§3.4)
transcria/queue/scheduler.py              # scheduling "capacité serveur" au lieu de nvidia-smi
transcria/web/routes.py                   # /health /ready /metrics : sondes serveurs distants
inference_service/                        # NOUVEAU service FastAPI : diarisation + embeddings (+ Parakeet)
config.example.yaml                       # section `inference:` (§4.4)
docs/INSTALL.md                           # profils client léger / serveur GPU
docs/CONFIG_REFERENCE.md                  # documentation de la section inference

Aucune refonte du pipeline : la migration s'appuie sur les ABC BaseTranscriber / BaseDiarizer existantes. Le risque principal n'est pas le code applicatif mais l'infrastructure (transport audio, diarisation sans standard, résilience réseau).