Voix Intermédiaire schedule 30 min

record_voice_over Synthèse vocale avec Kokoro TTS

Faire parler tes programmes Python avec Kokoro TTS — une voix naturelle, entièrement locale, sans API ni abonnement.

help_outline C'est quoi Kokoro TTS ? 01

Kokoro est un modèle de synthèse vocale (Text-to-Speech) open-source publié début 2025. Il est remarquable pour plusieurs raisons :

  • Qualité : voix très naturelles, difficiles à distinguer d'une vraie voix humaine
  • Léger : seulement 82 Mo — le rapport qualité/taille est exceptionnel
  • Rapide : génère de l'audio plus vite que le temps réel, même sur CPU
  • Local : tout se passe sur ta machine, zéro cloud
  • Multivoix : plusieurs voix disponibles (anglais principalement, français en développement)
info

Langue : Kokoro est principalement entraîné en anglais américain et britannique. Les voix françaises sont en cours de développement dans la communauté. Pour du français de haute qualité, Coqui TTS ou Bark sont des alternatives. On abordera les deux options dans ce tuto.

build_circle Installation de Kokoro 02

terminalTerminal
mkdir kokoro-tuto
cd kokoro-tuto

python -m venv venv
venv\Scripts\activate            # Windows
source venv/bin/activate         # macOS / Linux

# kokoro : la bibliothèque principale
# soundfile : pour sauvegarder l'audio
# sounddevice : pour jouer l'audio directement
pip install kokoro soundfile sounddevice
warning

Sur Windows, sounddevice peut nécessiter le Visual C++ Redistributable. Si tu as une erreur à l'import, installe-le et relance.

record_voice_over Première synthèse vocale 03

Crée tts.py :

codetts.py
from kokoro import KPipeline
import soundfile as sf
import sounddevice as sd
import numpy as np

# ── Initialiser Kokoro ────────────────────────────────────────────────────────
# lang_code :
#   "a" = anglais américain
#   "b" = anglais britannique
#   "f" = français (expérimental)
# Le modèle se télécharge automatiquement la première fois (~82 Mo).

print("Initialisation de Kokoro TTS...")
pipeline = KPipeline(lang_code="a")   # anglais américain


def synthetiser(texte: str, voix: str = "af_heart", vitesse: float = 1.0) -> np.ndarray:
    """
    Convertit du texte en audio.

    texte  : le texte à synthétiser
    voix   : identifiant de voix (voir liste ci-dessous)
    vitesse: 0.5 (lent) à 2.0 (rapide), 1.0 = normal

    Retourne un tableau numpy de samples audio (22050 Hz, mono).
    """
    # Le pipeline retourne un générateur de segments audio
    # Pour du texte court, on collecte tout en une fois
    audio_segments = []

    for _, _, audio in pipeline(texte, voice=voix, speed=vitesse):
        if audio is not None:
            audio_segments.append(audio)

    if not audio_segments:
        return np.array([])

    # Concaténer tous les segments
    return np.concatenate(audio_segments)


def jouer_audio(audio: np.ndarray, sample_rate: int = 22050):
    """Joue l'audio directement dans les haut-parleurs."""
    sd.play(audio, sample_rate)
    sd.wait()


def sauvegarder_audio(audio: np.ndarray, chemin: str, sample_rate: int = 22050):
    """Sauvegarde l'audio en fichier WAV."""
    sf.write(chemin, audio, sample_rate)
    print(f"Audio sauvegardé : {chemin}")


# ── Exemple d'utilisation ─────────────────────────────────────────────────────

# Voix disponibles (anglais) :
# af_heart   → voix féminine américaine, chaleureuse (recommandée)
# af_bella   → voix féminine américaine, claire
# am_adam    → voix masculine américaine
# am_michael → voix masculine américaine, grave
# bf_emma    → voix féminine britannique
# bm_george  → voix masculine britannique

texte = (
    "Hello! This is Kokoro TTS running entirely on your local machine. "
    "No cloud, no subscription, no data leaving your computer. "
    "Pretty neat for eighty two megabytes, right?"
)

print(f"Synthèse de : '{texte[:60]}...'")
audio = synthetiser(texte, voix="af_heart", vitesse=1.0)

# Jouer directement
print("Lecture...")
jouer_audio(audio)

# Sauvegarder aussi en WAV
sauvegarder_audio(audio, "output_tts.wav")
terminalTerminal
python tts.py

language Option française — Coqui TTS 04

Pour du français de qualité, Coqui TTS est la référence open-source avec d'excellents modèles français. Installation et utilisation :

terminalTerminal
# Installer Coqui TTS
pip install TTS

# Lister les modèles disponibles en français
tts --list_models | grep fr
codetts_francais.py
from TTS.api import TTS
import sounddevice as sd
import soundfile as sf
import numpy as np

# ── Charger le modèle français ────────────────────────────────────────────────
# "tts_models/fr/mai/tacotron2-DDC" est un bon modèle français
# Le téléchargement se fait automatiquement la première fois

print("Chargement du modèle français...")
tts = TTS(model_name="tts_models/fr/mai/tacotron2-DDC", progress_bar=True)
print("Modèle prêt.")


def synthetiser_fr(texte: str, chemin_sortie: str = "output_fr.wav"):
    """
    Synthétise du texte en français et sauvegarde en WAV.
    """
    print(f"Synthèse : '{texte[:80]}...'")

    # tts_to_file sauvegarde directement en WAV
    tts.tts_to_file(
        text=texte,
        file_path=chemin_sortie,
    )
    print(f"Audio sauvegardé : {chemin_sortie}")

    # Charger et jouer
    audio, sample_rate = sf.read(chemin_sortie)
    sd.play(audio, sample_rate)
    sd.wait()


# ── Exemple ───────────────────────────────────────────────────────────────────
texte_fr = (
    "Bonjour et bienvenue dans ce tutoriel sur la synthèse vocale. "
    "Ce texte est converti en audio directement sur votre machine, "
    "sans aucune connexion internet nécessaire."
)

synthetiser_fr(texte_fr)
lightbulb

Pour une voix française encore plus naturelle, explore le modèle tts_models/fr/css10/vits (VITS) — plus moderne que Tacotron2, avec une prosodie plus fluide. Lance tts --list_models | grep fr pour voir tous les modèles français disponibles.

integration_instructions Assembler STT + LLM + TTS — un assistant vocal complet 05

On a maintenant toutes les pièces. En combinant Whisper (STT) + Ollama (LLM) + Kokoro/Coqui (TTS), on peut construire un assistant vocal entièrement local :

codeassistant_vocal.py — architecture complète
"""
Assistant vocal local :
  Micro → Whisper (STT) → Ollama/gemma4 (LLM) → Coqui TTS → Haut-parleurs

Installation :
  pip install faster-whisper sounddevice soundfile numpy scipy TTS ollama
"""
import numpy as np
import sounddevice as sd
import soundfile as sf
import ollama
from faster_whisper import WhisperModel
from TTS.api import TTS

# ── Initialiser les modèles ───────────────────────────────────────────────────
SAMPLE_RATE  = 16000
DUREE_ECOUTE = 5        # secondes par tour de parole

print("Chargement Whisper STT...")
stt_model = WhisperModel("base", device="cpu", compute_type="int8")

print("Chargement Coqui TTS français...")
tts_model = TTS(model_name="tts_models/fr/mai/tacotron2-DDC", progress_bar=False)

print("Connexion à Ollama...")
# Test rapide de connexion
ollama.chat(model="gemma4:e2b", messages=[{"role": "user", "content": "test"}])

historique_llm = [
    {"role": "system", "content": "Tu es un assistant vocal en français. Réponds de façon concise, en 1 ou 2 phrases maximum, car ta réponse sera lue à voix haute."}
]

print("\n=== Assistant vocal prêt — parle maintenant (Ctrl+C pour quitter) ===\n")


def ecouter() -> str:
    """Enregistre et transcrit ce que dit l'utilisateur."""
    print("🎙 Écoute...", end=" ", flush=True)
    audio = sd.rec(int(DUREE_ECOUTE * SAMPLE_RATE), samplerate=SAMPLE_RATE, channels=1, dtype="float32")
    sd.wait()
    audio_flat = audio.flatten()

    segments, _ = stt_model.transcribe(audio_flat, language="fr", vad_filter=True)
    texte = " ".join(seg.text.strip() for seg in segments)
    print(f"Toi : {texte}" if texte else "(silence)")
    return texte


def reflechir(texte: str) -> str:
    """Envoie le texte au LLM et récupère la réponse."""
    historique_llm.append({"role": "user", "content": texte})
    reponse = ollama.chat(model="gemma4:e2b", messages=historique_llm)
    texte_reponse = reponse.message.content
    historique_llm.append({"role": "assistant", "content": texte_reponse})
    return texte_reponse


def parler(texte: str):
    """Synthétise et joue la réponse à voix haute."""
    print(f"Assistant : {texte}")
    tts_model.tts_to_file(text=texte, file_path="/tmp/response.wav")
    audio, sr = sf.read("/tmp/response.wav")
    sd.play(audio, sr)
    sd.wait()


# ── Boucle principale ─────────────────────────────────────────────────────────
try:
    while True:
        question = ecouter()
        if not question:
            continue
        if any(mot in question.lower() for mot in ["au revoir", "stop", "quitter"]):
            parler("Au revoir !")
            break
        reponse = reflechir(question)
        parler(reponse)
except KeyboardInterrupt:
    print("\nAssistant arrêté.")
info

Tu viens d'assembler un assistant vocal 100% local — pas de Google, pas d'OpenAI, pas d'Amazon. Tout tourne sur ta machine. C'est exactement le type de projet que je présente dans mes conférences pour montrer où en est l'IA open-source aujourd'hui.

Envie d'aller plus loin ? Tu peux connecter cet assistant à l'agent météo du tuto 06, lui donner accès à des fichiers locaux, ou le faire piloter des applications. Les outils sont là — à toi de construire.