Aller au contenu principal
Leçon 8 sur 14 · Voxtral TTS — Synthèse Vocale et Clonage

Génération de parole basique

Leçon 8 sur 14 Mis à jour le 3 novembre 2026 Développeur
Sur cette page
  1. Votre première génération vocale
  2. Ce que gouverne chaque paramètre
  3. Passer à l’échelle : un chapitre d’audiobook
  4. Quand la génération échoue
  5. Points clés à retenir

Cours mis à jour le 3 novembre 2026 pour Voxtral TTS 3, d’après le guide Migrate from Voxtral 2 et les pages Text to Speech de Mistral : voxtral-mini-tts-2603, déprécié le 31 octobre 2026 et retiré le 30 avril 2027, est remplacé dans les exemples par voxtral-mini-tts-3-0. Les voix prédéfinies de Voxtral 2 (gb_jane_neutral…) restent acceptées ; Voxtral 3 ajoute les balises [emotion=…] et [pace=…] dans le texte, le réglage expressiveness, la prononciation personnalisée (phoneme_hints) et 35 langues. Mistral conseille de remesurer la latence après la migration. Sources : Migrate from Voxtral 2 · Speech generation.

Votre première génération vocale

Vous savez maintenant créer une voix et la gérer via l’API Voices. Il reste à faire ce pour quoi tout ce travail a été mené : produire du son. L’API Speech de Mistral tient dans un seul appel, client.audio.speech.complete(), qui reçoit du texte et un identifiant de voix, et renvoie de l’audio encodé en base64. Cette leçon couvre la génération basique avec une voix sauvegardée ; le clonage à la volée et le streaming viendront juste après.

Le code ci-dessous suffit à transformer une phrase en fichier MP3 sur votre disque. Observez la dernière étape : la réponse ne contient pas des octets audio directement exploitables, mais une chaîne base64 qu’il faut décoder avant d’écrire le fichier. C’est l’erreur classique du premier essai — on sauvegarde la chaîne telle quelle et le lecteur audio refuse de l’ouvrir.

import base64
from pathlib import Path
from mistralai.client import Mistral

client = Mistral(api_key="votre-cle-api")

# Générer de la parole avec une voix sauvegardée
response = client.audio.speech.complete(
    model="voxtral-mini-tts-3-0",
    input="Bonjour et bienvenue dans cette formation sur Voxtral TTS.",
    voice_id="votre-voice-id",
    response_format="mp3",
)

# Décoder le base64 et sauvegarder en fichier
audio_bytes = base64.b64decode(response.audio_data)
Path("sortie.mp3").write_bytes(audio_bytes)
print(f"Audio généré : {len(audio_bytes)} octets")

Ce que gouverne chaque paramètre

Le paramètre model désigne le modèle de synthèse. À ce jour, voxtral-mini-tts-3-0 est le seul disponible, mais indiquez-le toujours explicitement : le jour où d’autres modèles apparaîtront, votre code continuera de produire exactement la même voix qu’aujourd’hui.

input reçoit le texte à prononcer, et c’est de loin le paramètre qui demande le plus d’attention. La documentation de Voxtral 2 conseillait de rester sous 300 mots par requête ; celle de Voxtral TTS 3 ne fixe plus de seuil, mais des requêtes d’un paragraphe restent plus faciles à contrôler et à rejouer. Bannissez les emojis, que le modèle ne sait pas interpréter, ainsi que le formatage complexe — Markdown, HTML, caractères spéciaux —, qui finit lu à voix haute tel quel. Écrivez enfin les chiffres et les abréviations en toutes lettres : « vingt-trois » plutôt que « 23 », « Société à Responsabilité Limitée » plutôt que « SARL ». Un agent vocal qui annonce un montant en butant sur les chiffres perd sa crédibilité en une phrase.

voice_id identifie la voix employée. Vous l’obtenez de trois façons : en créant une voix avec client.audio.voices.create() (voir leçon 5), en listant vos voix existantes avec client.audio.voices.list(), ou en reprenant l’identifiant d’une voix professionnelle Mistral. response_format, enfin, fixe le format de sortie parmi mp3, wav, pcm, flac et opus. Ce choix pèse sur la taille des fichiers comme sur la latence, et la leçon 12 lui est entièrement consacrée.

Passer à l’échelle : un chapitre d’audiobook

Pour un texte un peu long, découper reste la bonne pratique. Le principe est simple : vous préparez une liste de paragraphes, vous générez chacun d’eux séparément, puis vous accumulez les octets décodés dans un même tampon avant d’écrire le fichier final.

import base64
from pathlib import Path
from mistralai.client import Mistral

client = Mistral(api_key="votre-cle-api")
voice_id = "votre-voice-id"

# Texte découpé en paragraphes
paragraphes = [
    "Premier paragraphe du chapitre. Le narrateur introduit le contexte.",
    "Deuxième paragraphe. L'action commence à se développer.",
    "Troisième paragraphe. Le suspense monte progressivement.",
]

audio_complet = b""

for i, texte in enumerate(paragraphes):
    print(f"Génération du segment {i + 1}/{len(paragraphes)}...")
    response = client.audio.speech.complete(
        model="voxtral-mini-tts-3-0",
        input=texte,
        voice_id=voice_id,
        response_format="wav",
    )
    audio_complet += base64.b64decode(response.audio_data)

Path("chapitre-01.wav").write_bytes(audio_complet)
print("Chapitre audio généré avec succès !")

Ce script fonctionne parce qu’il produit du WAV, un format non compressé dont les segments se mettent bout à bout sans traitement particulier. Tentez la même chose avec du MP3 ou de l’Opus et le résultat sera inutilisable : ces formats compressés portent des en-têtes et un découpage en trames que la concaténation brute casse. Passez alors par une bibliothèque comme pydub, qui décode chaque segment avant de les fusionner proprement.

Quand la génération échoue

En production, l’appel doit être protégé. Un voice_id supprimé la veille par un collègue, un texte qui s’allonge discrètement parce qu’un champ a été concaténé, un quota API épuisé en fin de mois, un format de sortie mal orthographié : chacune de ces situations lève une exception, et sans garde-fou votre traitement par lots s’arrête au milieu du corpus.

try:
    response = client.audio.speech.complete(
        model="voxtral-mini-tts-3-0",
        input="Texte à convertir en parole.",
        voice_id=voice_id,
        response_format="mp3",
    )
    audio_bytes = base64.b64decode(response.audio_data)
    Path("sortie.mp3").write_bytes(audio_bytes)
except Exception as e:
    print(f"Erreur lors de la génération : {e}")

Prenez le temps de tester ce chemin d’erreur avant de partir en production : générez volontairement avec un voice_id fantaisiste et vérifiez que votre application le signale clairement plutôt que de produire un fichier vide.

Points clés à retenir

  • La génération utilise client.audio.speech.complete() avec le modèle voxtral-mini-tts-3-0
  • Découpez les textes longs en paragraphes et évitez les emojis et le formatage
  • Épelez les chiffres et les abréviations pour une prononciation correcte
  • L’audio retourné est en base64 — décodez-le avant de sauvegarder
  • Pour les textes longs, découpez en segments et concaténez les résultats