Streaming de la voix

Le streaming envoie l'audio d'une requête de synthèse vocale par fragments pendant que la génération se poursuit. L'auditeur entend ainsi les premiers mots plus tôt. Cette page explique comment envoyer une requête en streaming, lire l'audio à mesure qu'il arrive et mesurer le temps d'attente de l'auditeur.

i
Information

Pour obtenir un fichier complet à la place, consultez Génération de Speech. Pour comprendre ce qui fait attendre l'auditeur et comment se répartit ce délai, consultez Latence.

Fonctionnement du streaming

Fonctionnement du streaming

Une requête en streaming est une requête de synthèse vocale dont le paramètre stream est défini sur true. Vous envoyez toujours le texte complet en une seule requête : seul l'audio est renvoyé par fragments, sous forme de server-sent events.

ÉvénementChampsAction de votre application
speech.audio.deltaaudio_data : un fragment audio encodé en base64Décodez le fragment et transmettez-le à votre lecteur, ou ajoutez-le au fichier que vous écrivez.
speech.audio.doneusageArrêtez de lire la réponse : l'audio est complet.

Les fragments arrivent dans l'ordre. Une fois assemblés, ils forment un fichier audio au format response_format demandé, identique au fichier obtenu avec une requête sans streaming.

Note
Envoyer une requête en streaming

Envoyer une requête en streaming

Le script suivant envoie une requête en streaming, enregistre l'instant où le premier fragment arrive et sauvegarde tous les fragments dans un seul fichier MP3 :

import base64
import os
import time
from pathlib import Path

from mistralai.client import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

chunks = []
first_audio = None
start = time.perf_counter()

with client.audio.speech.complete(
    model="voxtral-mini-tts-3-0",
    input=(
        "Thanks for calling. Your order shipped this morning and should arrive on Thursday. "
        "You'll get a tracking link by email within the hour."
    ),
    voice_id="gb_jane_neutral",
    response_format="mp3",
    stream=True,
) as stream:
    for event in stream:
        if event.event == "speech.audio.delta":
            if first_audio is None:
                first_audio = time.perf_counter() - start
            chunks.append(base64.b64decode(event.data.audio_data))
        elif event.event == "speech.audio.done":
            print(f"Usage: {event.data.usage}")

output = Path("streamed.mp3")
output.write_bytes(b"".join(chunks))
print(f"First audio after {first_audio:.2f} s, {len(chunks)} chunks, total {time.perf_counter() - start:.2f} s")
print(f"Saved {output.resolve()}")
Lire l'audio à mesure qu'il arrive

Lire l'audio à mesure qu'il arrive

Pour démarrer la lecture avant que le fichier complet soit prêt, décodez chaque speech.audio.delta et transmettez les octets à un lecteur qui accepte un flux, dans leur ordre d'arrivée.

La plupart des lecteurs conservent une petite quantité d'audio dans une mémoire tampon avant de démarrer. La taille de cette mémoire tampon impose un compromis :

Mémoire tampon du lecteurRésultat pour l'auditeurRisque
Plus petiteLe premier son arrive plus tôtDes coupures pendant la lecture si le fragment suivant arrive en retard
Plus grandeUne lecture fluideUne attente plus longue avant le premier son
Astuce

Commencez avec la mémoire tampon par défaut de votre lecteur et réduisez-la uniquement si le premier son arrive trop tard. Testez avec les conditions réseau de vos utilisateurs, pas seulement avec une connexion rapide.

Mesurer le délai avant le premier son

Mesurer le délai avant le premier son

Le délai avant le premier son correspond au temps d'attente de l'auditeur. Mesurez-le à deux niveaux :

  1. De l'envoi de la requête au premier speech.audio.delta, comme dans l'exemple. Ce délai correspond à l'attente liée à l'API et au réseau.
  2. De l'envoi de la requête au premier son émis par votre lecteur. Ce délai inclut la mémoire tampon du lecteur et correspond à l'attente perçue par l'auditeur.

. Mesurez-le donc sur de nombreuses requêtes et surveillez les plus lentes, pas seulement la moyenne. Pour la méthode complète, consultez Latence.

Envoyer le texte en streaming pendant son écriture

Envoyer le texte en streaming pendant son écriture

Problèmes courants

Problèmes courants

Ces problèmes sont propres au streaming. Pour les erreurs liées à la requête elle-même, comme une voix inconnue ou un format invalide, consultez Dépannage.

SymptômeCauseSolution
La lecture ne démarre qu'une fois l'audio complet disponibleVotre client lit la réponse complète avant de la transmettreLisez les événements à mesure qu'ils arrivent et transmettez immédiatement chaque fragment au lecteur.
Coupures ou saccades pendant la lectureLa mémoire tampon du lecteur se vide avant l'arrivée du fragment suivantAugmentez la mémoire tampon du lecteur ou vérifiez le réseau entre votre application et l'API.
Le fichier sauvegardé ne peut pas être luLes fragments ont été sauvegardés dans le désordre, ou l'un d'eux a été perduDécodez chaque speech.audio.delta et écrivez les fragments dans leur ordre d'arrivée.
Aller plus loin

Aller plus loin