Skip to content

fr dev Diarization

rcspam edited this page Jul 7, 2026 · 3 revisions

🌐 Langue : English | Français

Diarisation β€” rΓ©fΓ©rence dΓ©veloppeur

Intro utilisateur : fr-Diarization.

Modèle Sortformer

Sortformer de NVIDIA (ONNX), diarisation neuronale end-to-end mono-transformer. Streame nativement par chunks de 10 s avec overlap. PlafonnΓ© dur Γ  4 locuteurs (propriΓ©tΓ© du modΓ¨le, pas un paramΓ¨tre). Agnostique Γ  la langue. ImplΓ©mentation Rust dans src/sortformer.rs via ONNX Runtime ; backend CUDA avec fallback CPU silencieux (diarize_only.rs:122-128) β€” 5–10Γ— plus lent en CPU.

Moteur multi-locuteurs (v1.4, src/diar/)

Pipeline maison sans plafond de nombre de locuteurs, inspiré de speakrs (Apache-2.0, crédité dans NOTICE) : pyannote segmentation-3.0 (ONNX) → décodage powerset → embeddings WeSpeaker ResNet34 (ONNX) → clustering AHC + PLDA + VBx → tours de parole. Algèbre linéaire en Rust pur (src/diar/linalg.rs, nalgebra) — délibérément aucun BLAS/LAPACK dans l'arbre de dépendances. Benché à parité DER exacte avec le pipeline Python pyannote community-1 (7,9 / 13,2 DIHARD sur les sous-ensembles AISHELL-4 / VoxConverse, contre 27,4 / 26,5 pour Sortformer).

  • Binaire : diarize-multi [--num-speakers N] [--threshold 0.0-2.0] [--models-dir DIR] [--rttm ID] <audio> β€” mΓͺme contrat stdout que diarize-only (start end speaker_id par ligne), donc remplaΓ§ant direct dans les pipelines two-phase. NΓ©cessite la feature cargo diar.
  • ModΓ¨les : ~57 Mo, tΓ©lΓ©chargΓ©s depuis dictee-setup (Β« Diarisation multi-locuteurs Β»), installΓ©s dans ~/.local/share/dictee/diar ou /usr/share/dictee/diar (sentinelle : segmentation-3.0.onnx).
  • Routage : quand binaire + modΓ¨les sont prΓ©sents, dictee-transcribe prΓ©fΓ¨re diarize-multi Γ  diarize-only pour la diarisation de fichiers (phase 2 du chunked et two-phase). Le mode Meeting en direct garde Sortformer (streaming ; ce moteur est offline par nature). Le slider Seuil de l'UI correspond au seuil de distance AHC (slider/100 Γ— 1,2, 50 % β†’ 0,6).
  • Performances : RTF GPU ~0,075 (262 s diarisΓ©es en ~20 s sur une RTX 4070 laptop) ; RTF CPU ~0,9. Sur les fichiers longs, c'est le clustering (CPU) qui domine.
  • --num-speakers impose le nombre exact de locuteurs (coupe du dendrogramme AHC par comptage). Le mode auto est le dΓ©faut et fait gΓ©nΓ©ralement mieux qu'un nombre imposΓ©.

VRAM & limites de durΓ©e

Mode streaming (transcribe-stream-diarize, EN seul via Nemotron)

DurΓ©e audio Pic VRAM
1 min … 10 h ~1,2 GB (constant)

Pas de limite de durΓ©e effective ; la mΓ©moire est bornΓ©e par la taille du chunk.

Mode batch chunked (transcribe-diarize-batch, dΓ©faut UI)

Le transcribe-diarize mono-coup fait tourner Parakeet sur le mel complet en une passe → Parakeet seul heurte un plafond dur ~5:20 min sur tout GPU à cause d'un attention-mask à shape fixe dans l'export ONNX du Parakeet-TDT v3 (indépendant de la VRAM). Le pipeline chunked transcribe-diarize-batch garde chaque chunk sous 320 s et lève le plafond. Depuis v1.3.4, l'interface dictee-transcribe route automatiquement tout fichier plus long qu'un chunk par lui, quel que soit le paquet GPU ou l'état du toggle diarize.

Pipeline :

  1. Sortformer une fois sur l'audio complet (streaming, sans cap)
  2. Chunk l'audio en segments de 10 min avec overlap, via ffmpeg
  3. Parakeet-TDT par chunk (transcribe-diarize-batch --no-diarize)
  4. Fusion des labels via les timestamps globaux Sortformer (argmax overlap)

Validations terrain :

  • Keynote 29 min, CUDA 8 GB β†’ 04:56
  • Keynote 54 min, 3 locuteurs, RTX 4070 (8 GB) β†’ 122 s, 94 % de prΓ©cision vs ground truth

Edge cases :

  • 4 GB VRAM, ou 8 GB avec Ollama dΓ©jΓ  chargΓ© β†’ Parakeet OOM (pas encore de garde min-VRAM)
  • Token tombant dans un silence entre deux segments globaux Sortformer β†’ taguΓ© UNKNOWN: <texte> (prΓ©visible, non bloquant)

Binaires CLI

Binaire Usage Backend ASR Streaming DurΓ©e max
transcribe-diarize Fichier, mono-coup Parakeet-TDT ❌ ~5:20 min (bug attention-mask ONNX, tout GPU)
transcribe-stream-diarize Fichier, streaming Nemotron (EN) βœ… illimitΓ©
transcribe-diarize-batch Fichier, chunked Parakeet-TDT ⚠ chunked illimité
transcribe-diarize meeting.wav \
  --sortformer-model /usr/share/dictee/sortformer/ \
  --parakeet-model   /usr/share/dictee/tdt/ \
  --lang fr

Sortie sur stdout.

Formats de sortie

Format texte par dΓ©faut, ligne par locuteur :

Speaker 1: Bonjour Γ  tous, on commence la revue trimestrielle.
Speaker 2: Merci, on attaque par les chiffres ?
Speaker 3: Question rapide β€” l'appel est enregistrΓ© ?

Flags CLI :

  • --format=rttm β€” IDs locuteurs frame-level (format diarisation standard)
  • --format=json β€” timestamps + IDs + confidence
  • --format=srt β€” sous-titres avec timestamps

Fusion des locuteurs entre chunks

UtilisΓ© par transcribe-diarize-batch :

  1. Sortformer une fois sur l'audio complet β†’ timestamps globaux
  2. Chunk l'audio (10 min, 10 s d'overlap)
  3. Parakeet-TDT par chunk β†’ timestamps token-level
  4. Pour chaque mot transcrit, lookup son locuteur global via la sortie Sortformer (argmax overlap)
  5. Emit avec labels Speaker N cohΓ©rents

Source : src/bin/transcribe_diarize_batch.rs.

Pourquoi le post-traitement est contournΓ©

Le mode Meeting saute entièrement le pipeline en 12 étapes :

Γ‰tape Pourquoi Γ§a casserait la diarisation
5/7. Règles regex Commandes vocales insérées dans le mauvais tour
6. Correction LLM Reflow du texte, fusion des tours en monologue
8/9. Keepcaps Gestion d'acronymes par phrase, pas par locuteur
10. Capitalisation Conflit dΓ©but-de-phrase / dΓ©but-de-tour
11. Traduction Traduction multi-locuteurs rarement cohΓ©rente

Seuls le nettoyage d'espaces, l'insertion du prΓ©fixe locuteur et le \n final sont conservΓ©s.

Pour une sortie polie, voir Analyse LLM de la diarisation β€” conΓ§ue spΓ©cifiquement pour ce cas.

Pipeline (Mermaid)

flowchart TB
    A["πŸŽ™ Audio (N locuteurs)"] --> B["Sortformer<br/>(streaming, chunks 10s)"]
    B --> C1["Timestamps locuteur 1"]
    B --> C2["Timestamps locuteur 2"]
    B --> C3["Timestamps locuteur 3"]
    B --> C4["Timestamps locuteur 4"]
    C1 --> D["Parakeet-TDT<br/>(transcription)"]
    C2 --> D
    C3 --> D
    C4 --> D
    D --> E["Fusion par timestamps<br/>(argmax overlap)"]
    E --> F["Speaker 1: texte<br/>Speaker 2: texte<br/>Speaker 3: texte"]
Loading

Voir aussi

πŸ“– dictee Wiki

πŸ‡¬πŸ‡§ Home Β· πŸ‡«πŸ‡· Accueil


Getting started / Premiers pas

Speech recognition / ASR

Translation / Traduction

Post-processing / Post-traitement

CLI

Reference / RΓ©fΓ©rence


🏠 Repo Β· πŸ“¦ Releases Β· πŸ› Issues

Clone this wiki locally