Intermédiaire 18 minAudio

Whisper + Ollama : pipeline transcription et résumé 100% local

Transcrire une réunion d'une heure puis en sortir un compte-rendu structuré : c'est exactement ce que vendent Otter, Fireflies ou Tactiq — moyennant l'envoi de votre audio chez un tiers. Whisper (OpenAI, mais open source et exécutable hors-ligne) couplé à un LLM Ollama fait la même chose sur votre machine, sans abonnement et sans fuite. Ce guide monte le pipeline whisper.cpp → Ollama de bout en bout : install, choix du modèle, script bash, script Python, et un cas concret de transcription locale d'une réunion d'1h.

Par Mohamed Meguedmi·Màj 2026-05-19·Testé sur Windows, macOS, Linux

#Pourquoi un pipeline whisper + ollama de transcription locale ?

Un enregistrement de réunion contient des noms de clients, des chiffres, des arbitrages stratégiques, parfois des données RH. Les services SaaS de transcription stockent ces audios sur leurs serveurs et les utilisent (selon les CGU) pour entraîner leurs propres modèles. Pour une équipe qui prend la confidentialité au sérieux, ce n'est pas négociable.

Whisper d'OpenAI est librement téléchargeable et tourne offline. whisper.cpp (le port C++ par Georgi Gerganov) le fait tourner efficacement sur CPU et GPU, sans Python ni CUDA obligatoire. Ollama, de son côté, expose un LLM local sur http://localhost:11434. Les deux brique à brique : audio → texte (Whisper) → résumé structuré (Ollama). Tout reste sur votre disque.

i
Le découpage
Whisper ≠ LLM. Whisper est un modèle de reconnaissance vocale (ASR) : il convertit du son en texte brut. Le résumé, la mise en forme, l'extraction des décisions, c'est le travail d'un LLM derrière. Ces deux modèles n'ont rien à voir et ne se remplacent pas.

#Prérequis

macOS, Linux ou Windows (WSL2)
whisper.cpp compile partout. Sous Windows pur, utilisez WSL2 — la compilation native marche mais demande plus de bricolage.
Ollama installé et opérationnel
Un ollama run mistral doit répondre. Sinon, repassez par le guide d'installation pour votre OS.
Compilateur C++ et CMake
build-essential cmake sur Debian/Ubuntu, Xcode Command Line Tools sur macOS.
ffmpeg
Pour convertir vos .m4a/.mp3/.mp4 en WAV 16 kHz, le seul format que whisper.cpp accepte en entrée.
8 Go de RAM minimum
16 Go confortable. Le modèle large-v3 charge ~3 Go en RAM/VRAM. Un LLM 7B Q4 en plus, ~5 Go.
GPU optionnel
Une RTX 3060 12 Go transcrit 1h d'audio en ~4 min avec large-v3. Sur Apple Silicon, Metal est activé automatiquement et c'est tout aussi rapide.

#1. Installer whisper.cpp

Pas de paquet officiel : on clone le dépôt et on compile. C'est 2 minutes et ça donne un binaire portable que vous pouvez bouger où vous voulez.

Clone + build CPU
git clone https://github.com/ggerganov/whisper.cpp.git
cd whisper.cpp
cmake -B build
cmake --build build --config Release -j

Le binaire principal arrive dans build/bin/whisper-cli (anciennement nommé main avant la refonte CMake). C'est lui que vous appellerez pour transcrire.

Accélération GPU
Pour CUDA (NVIDIA), ajoutez -DGGML_CUDA=1 à la commande cmake -B build. Pour Apple Silicon, Metal est activé par défaut — rien à configurer. Pour AMD (ROCm) : -DGGML_HIPBLAS=1. Le binaire détecte ensuite le GPU au lancement.
Variante CUDA
cmake -B build -DGGML_CUDA=1
cmake --build build --config Release -j

Installez ffmpeg séparément si ce n'est pas déjà fait :

ffmpeg
# Debian / Ubuntu / WSL2
sudo apt install ffmpeg

# macOS
brew install ffmpeg

#2. Choisir le bon modèle Whisper (tiny → large-v3)

Whisper existe en cinq tailles, multipliées par deux variantes : multilingue (par défaut) et anglais uniquement (suffixe .en). Pour du français, restez multilingue. Le tableau ci-dessous résume ce qui change vraiment.

tiny (75 Mo)
Rapide mais médiocre en français. Réservé aux tests rapides ou aux Raspberry Pi. WER (taux d'erreur) ~30% en français spontané.
base (142 Mo)
Acceptable pour de l'anglais clair, faiblard en français bruité. Bonne option si vous avez très peu de ressources.
small (466 Mo)
Le premier palier sérieux. WER ~10–12% en français propre. Transcrit 1h d'audio en ~3 min sur GPU modeste.
medium (1.5 Go)
Très bon compromis qualité/vitesse pour le français de réunion. WER ~7–8%. Reconnaît bien la ponctuation.
large-v3 (3.1 Go)
État de l'art. Quasi parfait en français propre, robuste sur accents et bruit de fond. À privilégier dès que vous avez >6 Go de RAM/VRAM libres.

Pour transcrire une réunion en français, la recommandation pratique : medium par défaut, large-v3 si vous avez le GPU pour. small est un bon repli sur laptop sans GPU dédié.

Télécharger un modèle
# Depuis le dossier whisper.cpp
./models/download-ggml-model.sh medium
# ou
./models/download-ggml-model.sh large-v3

Les modèles arrivent dans models/ au format ggml (l'équivalent de gguf pour les LLM). Vous pouvez télécharger plusieurs tailles et alterner selon le besoin.

i
Versions quantisées
Si la VRAM est tendue, le script accepte les variantes quantisées : large-v3-q5_0 (≈1.1 Go) ou medium-q5_0 (≈540 Mo). La perte de qualité est marginale en français, l'économie mémoire est réelle. À tester sur vos propres audios.

#3. Transcrire un fichier audio

whisper.cpp ne lit que du WAV 16 kHz mono. On utilise ffmpeg pour préparer l'audio, puis whisper-cli pour transcrire.

Conversion vers WAV 16 kHz
ffmpeg -i reunion.m4a -ar 16000 -ac 1 -c:a pcm_s16le reunion.wav
-ar 16000
Resample à 16 kHz (la fréquence d'entraînement de Whisper).
-ac 1
Force le mono. Whisper ignore la stéréo de toute façon.
-c:a pcm_s16le
PCM 16-bit little-endian, le format WAV non compressé attendu.
Transcription
./build/bin/whisper-cli \
  -m models/ggml-medium.bin \
  -f reunion.wav \
  -l fr \
  -otxt \
  -of reunion

Le résultat sort dans reunion.txt avec les segments timestampés. Quelques flags utiles à connaître :

-l fr
Force le français. Sans ce flag, Whisper détecte la langue automatiquement — mais se trompe parfois sur les phrases courtes.
-otxt / -osrt / -ovtt / -ojson
Format de sortie : texte brut, sous-titres SRT, VTT, ou JSON structuré avec timestamps. Vous pouvez les combiner.
-of <prefixe>
Préfixe des fichiers de sortie (sans extension).
-t 8
Nombre de threads CPU. Par défaut, whisper.cpp en utilise 4 — montez à 8 ou 16 sur un CPU récent.
--print-progress
Affiche une barre de progression. Pratique pour les longs fichiers.
Format JSON pour le pipeline
Pour enchaîner avec un LLM, préférez -ojson : vous récupérez les segments avec leurs timestamps de début/fin. Vous pouvez ainsi citer un horodatage précis dans le résumé final ("décision prise à 23:14").

#4. Résumer la transcription avec Ollama

Une fois la transcription brute en main, on l'envoie à Ollama via son API HTTP locale. L'endpoint /api/chat est le plus direct pour un usage one-shot.

Pré-requis Ollama
ollama pull mistral
# Ou pour une réunion longue, un modèle avec gros contexte :
ollama pull qwen2.5:14b-instruct

Pour une réunion de 1h, la transcription pèse facilement 10 000 à 15 000 tokens. Mistral 7B accepte 32k de contexte natif, c'est confortable. Pour plus long, Qwen 2.5 14B monte à 128k.

Test rapide via curl
curl -s http://localhost:11434/api/chat -d '{
  "model": "mistral",
  "stream": false,
  "options": {"temperature": 0.2, "num_ctx": 16384},
  "messages": [
    {"role": "system", "content": "Tu résumes une réunion de travail en français."},
    {"role": "user", "content": "<COLLE ICI LE CONTENU DE reunion.txt>"}
  ]
}' | jq -r '.message.content'
!
num_ctx, pas par défaut
Ollama charge ses modèles avec un contexte de 2048 tokens par défaut, ce qui tronquerait silencieusement votre transcription. Passez explicitement num_ctx (8192, 16384, 32768…) dans options à chaque appel — ou figez-le via un Modelfile.

#5. Pipeline complet : exemple compte-rendu de réunion (1h)

On assemble tout dans un script Python qui prend un fichier audio en entrée et sort un compte-rendu Markdown. C'est le cœur d'un pipeline whisper ollama de transcription locale réutilisable.

Dépendances Python
pip install requests
pipeline_reunion.py
#!/usr/bin/env python3
"""Audio -> transcription Whisper -> compte-rendu via Ollama."""
import subprocess, sys, requests, pathlib, json

WHISPER_BIN = "./build/bin/whisper-cli"
WHISPER_MODEL = "models/ggml-medium.bin"
OLLAMA_URL = "http://localhost:11434/api/chat"
LLM_MODEL = "mistral"

SYSTEM_CR = """Tu es un assistant qui produit des comptes-rendus de
réunion en français à partir d'une transcription brute.

FORMAT DE SORTIE (Markdown) :
# Compte-rendu
## Participants identifiables
## Sujets abordés (1 paragraphe par sujet)
## Décisions prises
## Actions à mener (avec porteur si mentionné)
## Points en suspens

RÈGLES :
- N'invente AUCUN nom, AUCUNE décision, AUCUNE action.
- Si une info manque, écris \"Non précisé\".
- Sois concis : un compte-rendu se lit en 2 minutes.
"""

def to_wav(src: pathlib.Path) -> pathlib.Path:
    dst = src.with_suffix(".wav")
    subprocess.run([
        "ffmpeg", "-y", "-i", str(src),
        "-ar", "16000", "-ac", "1", "-c:a", "pcm_s16le",
        str(dst),
    ], check=True)
    return dst

def transcribe(wav: pathlib.Path) -> str:
    prefix = wav.with_suffix("")
    subprocess.run([
        WHISPER_BIN, "-m", WHISPER_MODEL, "-f", str(wav),
        "-l", "fr", "-otxt", "-of", str(prefix),
        "--print-progress",
    ], check=True)
    return prefix.with_suffix(".txt").read_text(encoding="utf-8")

def summarize(transcription: str) -> str:
    r = requests.post(OLLAMA_URL, json={
        "model": LLM_MODEL,
        "stream": False,
        "options": {"temperature": 0.2, "num_ctx": 16384},
        "messages": [
            {"role": "system", "content": SYSTEM_CR},
            {"role": "user",   "content": transcription},
        ],
    }, timeout=600)
    r.raise_for_status()
    return r.json()["message"]["content"]

if __name__ == "__main__":
    src = pathlib.Path(sys.argv[1])
    wav = to_wav(src)
    print(f"[1/3] Audio converti -> {wav}")
    texte = transcribe(wav)
    print(f"[2/3] Transcription : {len(texte)} caractères")
    cr = summarize(texte)
    out = src.with_name(src.stem + "_compte-rendu.md")
    out.write_text(cr, encoding="utf-8")
    print(f"[3/3] Compte-rendu : {out}")
Lancement
python pipeline_reunion.py reunion.m4a

Sur une réunion d'1h avec une RTX 3060 12 Go et le modèle medium : ~3 minutes pour la transcription, ~30 secondes pour le résumé Mistral. Total : moins de 4 minutes, zéro requête réseau. Sur un MacBook M2 16 Go en CPU + Metal : ~6 minutes total.

Réunions très longues
Au-delà de 90 minutes ou 30 000 tokens de transcription, scindez le texte en blocs de 10 000 tokens, résumez chaque bloc, puis demandez au LLM de fusionner les résumés. C'est le pattern classique map-reduce. Sinon la qualité du résumé s'écroule, même si num_ctx accepte.

#Astuces et dépannage

Transcription qui hallucine en silences
Whisper invente parfois des phrases dans les longs silences ("Sous-titrage par...", "Merci d'avoir regardé"). Activez le VAD : --vad --vad-model models/ggml-silero-v5.1.2.bin (à télécharger via le même script).
Noms propres déformés
Whisper ne connaît pas les noms de vos collègues. Passez-les en prompt initial via --prompt "Marie, Julien, Samir, ACME Corp, ProjetX". Ils seront orthographiés correctement.
Audio compressé (Zoom, Teams)
Les enregistrements Zoom MP4 contiennent souvent un audio mono de mauvaise qualité. Préférez l'export Zoom "audio seul" (M4A) ou enregistrez en parallèle avec OBS si la qualité prime.
Erreur ggml_metal_init sur Mac
Vous avez compilé sans Metal ou whisper.cpp ne trouve pas les ressources. Recompilez depuis zéro : rm -rf build && cmake -B build && cmake --build build --config Release -j.
Ollama timeout sur gros contexte
Le client HTTP coupe avant la fin. Augmentez timeout=600 (10 min) côté requests. Côté serveur, OLLAMA_KEEP_ALIVE=30m garde le modèle chaud.
Transcription tronquée
Si le résumé semble couper l'audio en cours de route, c'est que num_ctx est trop bas. Vérifiez le nombre de tokens (wc -w sur le .txt × 1.3 ≈ tokens) et alignez num_ctx au double.
Diarisation (qui parle)
whisper.cpp ne fait pas la diarisation. Pour distinguer les locuteurs, ajoutez pyannote.audio dans le pipeline avant la transcription, puis annotez chaque segment. C'est une autre couche, hors scope ici.
i
Coût matériel concret
Pour un usage quotidien — 2 à 3 réunions transcrites par jour — un Mac mini M4 16 Go (~700 €) ou un mini-PC avec RTX 3060 12 Go (~600 € d'occasion) suffit largement. C'est un investissement unique vs ~15 €/mois/utilisateur chez les SaaS de transcription, qui s'amortit en moins d'un an pour une équipe de 5 personnes.

#Pour aller plus loin

Votre pipeline transcrit et résume en local. Trois directions logiques selon votre besoin :

Compte-rendu médical avec faster-whisper
Le guide transcription des consultations utilise faster-whisper (port Python optimisé) avec un focus secret médical, diarisation pyannote, et conformité RGPD santé. Variante intéressante du même pattern.
Choisir le bon LLM de résumé
Le résumé est le maillon où la qualité varie le plus. Le guide choisir sa quantification compare Q4_K_M, Q5_K_M et Q8_0 — différence audible sur du texte long avec des nuances.
Automatiser le pipeline avec n8n
Pour déclencher la chaîne dès qu'un fichier audio arrive (dossier surveillé, mail, Slack), le guide automatisation n8n + Ollama montre comment construire le workflow sans code.
Ce guide vous a aidé ?

Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.