Speech to Text en temps réel sous 200 ms : guide d’architecture
- Publié
ÉcouterÉcouter cet article
Le Speech to Text (STT) en temps réel transcrit l’audio au fur et à mesure que la personne parle, et restitue ses mots en texte en quelques centaines de millisecondes. Mais garder une faible latence STT est autant une question d’architecture que de modèle. Les ingénieurs doivent anticiper le transport, le découpage, la détection de fin de phrase et la capture, car chacun ajoute de la latence. Une inefficacité à l’un de ces niveaux peut faire exploser votre budget de 200 ms.
Ce guide propose un système concret pour construire des pipelines Speech to Text en temps réel, en partant de la couche transport. Nous allons nous appuyer sur Scribe v2 Realtime, qui produit des transcriptions partielles en environ 150 ms de latence modèle, prend en charge plus de 90 langues, accepte l’audio PCM (8kHz-48kHz) et mu-law, et propose la détection d’activité vocale ainsi qu’un contrôle manuel de validation pour finaliser les segments.
Nous allons suivre comment l’audio arrive au serveur, comment les hypothèses deviennent du texte validé, ce que coûtent les fonctionnalités en flux, et comment capturer et transmettre correctement l’audio.
Résumé
- Créer un système Speech to Text en temps réel demande d’ajuster l’architecture pour garder la latence basse sur tout le pipeline.
- WebSocket est le choix par défaut pour la plupart des pipelines, même si WebRTC offre certains avantages mais reste plus complexe.
- La détection d’activité vocale gère la segmentation mains libres, et le commit manuel permet à vos applications de valider la fin d’une prise de parole.
- Les transcriptions partielles sont provisoires et les finales sont validées : il faut donc les afficher différemment.
- De petits paquets PCM d’environ 100 ms minimisent la latence jusqu’à la première transcription partielle.
WebSocket ou WebRTC pour le Speech to Text en temps réel
Avant toute transcription, l’audio doit voyager de la source au moteur de reconnaissance. Le canal choisi fixe la latence minimale pour tout le reste. Deux options sont possibles pour transmettre l’audio à la couche de transcription.
WebSocket est un canal longue durée, ordonné, fiable et bidirectionnel sur TCP. On ouvre une connexion, on envoie des trames audio binaires, et on reçoit les événements de transcription. C’est simple côté client et serveur, ça traverse les proxies et pare-feux qui autorisent déjà HTTPS, et tous les navigateurs et serveurs le supportent.
La contrainte de WebSocket, c’est qu’il repose sur TCP. Si un paquet est perdu, TCP le retransmet et bloque les données suivantes jusqu’à ce que le trou soit comblé. En bonnes conditions réseau, c’est invisible. En cas de perte de paquets, cela crée un blocage temporaire où l’audio s’accumule puis arrive d’un coup.
WebRTC est conçu pour les médias en temps réel. Il fait passer l’audio sur UDP (via SRTP), donc un paquet perdu ne bloque pas le flux ; le pipeline continue. Il inclut un tampon de gigue pour absorber les variations d’arrivée des paquets, négocie la traversée NAT avec ICE/STUN/TURN pour connecter les pairs derrière des routeurs, et embarque ses propres outils de capture et d’encodage audio.
Il faut généralement des serveurs TURN pour les clients qui ne peuvent pas se connecter directement, et côté serveur il faut terminer un flux média plutôt que lire un flux d’octets.
Voici le résumé des avantages et inconvénients :
Pour la plupart des cas d’usage, WebSocket est la meilleure option. Utilisez-le si vos clients ont une bonne connexion et que vous contrôlez la capture : pipelines serveur à serveur, applications desktop, applications web sur le haut débit, et la plupart des backends de centres de contact où l’audio arrive déjà sur votre serveur.
Choisissez WebRTC si vous capturez directement depuis des appareils grand public sur des réseaux mobiles instables, si vous utilisez déjà une stack WebRTC pour l’audio bidirectionnel (par exemple un agent vocal qui répond), ou si le comportement temps réel sans perte est plus important que la simplicité de mise en œuvre.
La suite de ce guide utilise WebSocket pour la connexion au moteur de reconnaissance, car cela rend les étapes visibles et c’est le point de départ idéal pour la plupart des équipes. Rien n’est spécifique à WebSocket : vous pouvez ensuite ajouter une couche média WebRTC devant, décoder l’audio en PCM côté serveur, et transmettre les mêmes paquets dans le pipeline.
Partielles et finales : comprendre les résultats intermédiaires
Un moteur en temps réel n’attend pas la fin d’une phrase pour répondre. Il émet un flux continu d’hypothèses qui s’affinent au fil de l’audio, puis les valide. Comprendre la différence entre ces deux états, c’est ce qui distingue une transcription vivante d’une transcription bancale.
Une hypothèse partielle (intermédiaire) est la meilleure estimation du modèle à partir de l’audio reçu jusqu’ici. Les partielles sont instables par nature. À mesure que l’audio arrive, le modèle révise les mots précédents : « Je veux » peut devenir « Je veux deux billets » quand le contexte lève l’ambiguïté. Elles arrivent vite (c’est ce que décrit la latence d’environ 150 ms) et sont faites pour être écrasées.
Une hypothèse finale est un segment validé qui ne changera plus. Une fois le segment finalisé, le moteur passe à la suite, et les hypothèses suivantes concernent l’audio suivant. Les finales sont celles que vous conservez, envoyez à un LLM ou stockez comme transcription.
La distinction entre partielles et finales impacte trois points à ne pas négliger :
- Expérience utilisateur : Afficher les partielles rend la transcription vivante : l’utilisateur voit les mots apparaître au fur et à mesure, ce qui confirme que le micro fonctionne et que le système écoute.
- Détection de fin de phrase : Les partielles donnent un signal continu d’activité vocale. Combinées à la VAD, elles permettent de décider quand l’orateur s’est vraiment arrêté.
- Synchronisation en aval : Dans un pipeline d’agent vocal les étapes sont : audio entrant, puis Speech to Text, puis LLM, puis Text to Speech, puis audio sortant. Vous pouvez commencer à traiter les partielles et valider sur les finales, ce qui réduit le temps de réponse perçu au prix de parfois jeter du travail spéculatif.
Affichez les partielles et les finales différemment. Une méthode simple et efficace consiste à garder une « ligne courante » modifiable liée à la dernière partielle, puis à la valider dans la transcription dès qu’une finale arrive :
Visuellement, affichez les segments validés en texte normal et la ligne courante en style plus clair ou italique pour que l’utilisateur comprenne qu’elle peut encore changer.
Détection de fin de phrase et détection d’activité vocale (VAD)
Savoir ce qui a été dit n’est que la moitié du travail. Le moteur doit aussi savoir quand une idée est terminée. Cette décision détermine quand finaliser un segment et, pour un agent, quand le système commence à répondre.
La détection de fin de phrase consiste à décider qu’une prise de parole est terminée. Finaliser trop tôt coupe l’utilisateur en pleine phrase. Finaliser trop tard laisse un agent silencieux alors que l’utilisateur a fini.
Scribe v2 Realtime propose deux mécanismes complémentaires :
- La détection d’activité vocale segmente l’audio selon les silences : Le moteur détecte quand la parole laisse place à un silence prolongé et utilise cette limite pour finaliser automatiquement un segment. La VAD est le bon choix par défaut pour les interfaces conversationnelles, car elle s’adapte au rythme naturel de la parole sans avoir à gérer le timing manuellement.
- Contrôle manuel de validation : Le contrôle manuel de validation permet à votre application de décider quand finaliser le segment courant, indépendamment du silence. Vous envoyez un signal de commit, le moteur ferme le segment courant et émet une finale. C’est l’outil idéal quand votre application sait déjà que le tour est terminé : relâchement d’un bouton push-to-talk, action « envoyer » ou politique de prise de parole externe.
Les deux méthodes se complètent bien. Un agent vocal typique utilise la VAD pour le mode mains libres et propose le commit manuel en option, pour qu’un utilisateur qui fait une pause ne soit pas coupé, mais qu’un utilisateur qui appuie sur un bouton ait une validation immédiate.
Le seuil de silence est un vrai compromis sans valeur universelle :
- Un délai court de fin de parole (par exemple, validation après ~200-400 ms de silence) rend le système réactif. Mais il coupe aussi les utilisateurs qui font des pauses naturelles, divisant une idée en plusieurs segments et, pour un agent, déclenchant une réponse prématurée.
- Un délai long (par exemple ~800-1200 ms) tolère les pauses naturelles et garde les phrases intactes, au prix d’un léger décalage avant la réaction du système.
Il n’y a pas de valeur universelle ici ; ajustez le seuil selon l’interaction :
- La dictée et la prise de notes tolèrent des pauses plus longues, car l’utilisateur réfléchit en parlant. Privilégiez des délais plus longs et la VAD.
- Les agents de commande ou transactionnels bénéficient de délais plus courts et du commit manuel, car les tours sont courts et précis.
- Les locuteurs multilingues ou non natifs font plus de pauses, donc prévoyez plus de silence avant de finaliser.
Ces conseils vous aideront à construire un système de détection de fin de phrase efficace et à tendre vers le Speech to Text en temps réel.
Fonctionnalités en flux : détection de langue et diarisation des locuteurs
La reconnaissance en streaming peut faire plus que produire des mots. Mais chaque signal supplémentaire demandé impacte la latence et la stabilité. La règle : n’activez que ce qui est indispensable à l’expérience en direct, et gardez le reste pour un traitement différé.
La reconnaissance automatique de la langue permet à Scribe v2 Realtime d’identifier la langue parlée parmi plus de 90 langues prises en charge, sans avoir à la préciser à l’avance. Le modèle a besoin d’un court extrait audio pour être sûr, donc les premières partielles peuvent être moins stables le temps que la langue soit déterminée. Si vous connaissez déjà la langue, l’indiquer lève l’ambiguïté et stabilise les premiers résultats.
La diarisation attribue la parole à différents locuteurs, pour savoir qui parle. En transcription batch, c’est plus simple car le modèle voit tout le fichier. En streaming, c’est plus difficile : le moteur doit attribuer un label à partir de l’audio reçu, et ce label peut devoir être corrigé quand plus de voix est entendue. Traitez les labels de locuteur en streaming comme le texte partiel : provisoires jusqu’à la finalisation du segment.
Le timing au mot près et le contexte d’entité suivent la même logique. Plus vous demandez de métadonnées par jeton, plus le modèle et le réseau doivent transporter d’informations. Pour la plupart des interfaces en temps réel, vous n’avez besoin que du texte et des limites de segment en direct ; gardez les métadonnées détaillées pour un traitement différé avec Scribe v2.
Formats audio pour le streaming : PCM et mu-law
Le transport et la logique de reconnaissance attirent l’attention, mais beaucoup de bugs viennent d’un niveau en dessous : comment vous encodez et découpez l’audio. Bien choisir le format et la taille des paquets est le moyen le plus simple de gagner en latence.
Le PCM (linéaire, 16 bits signé, little-endian) est le format à privilégier si vous contrôlez la capture. Un taux d’échantillonnage plus élevé apporte plus de détails : 16 kHz est le minimum standard pour la reconnaissance vocale et suffit généralement ; 8 kHz est la qualité téléphonique et perd les hautes fréquences. Utilisez le taux qui correspond à votre source. Il n’y a aucun intérêt à suréchantillonner de l’audio 8 kHz en 48 kHz, car l’information n’existe pas.
Le mu-law à 8 kHz est le format téléphonique. Si vous récupérez des appels d’un fournisseur comme Twilio, l’audio arrive en mu-law 8 kHz : transmettez-le tel quel plutôt que de le transcoder deux fois. Respecter le format source évite les artefacts de rééchantillonnage et une conversion inutile.
La taille des paquets est le levier qui impacte le plus directement la latence perçue. Vous envoyez l’audio par paquets, et le moteur produit des partielles à chaque arrivée. Plus les paquets sont petits, plus les mises à jour sont fréquentes et la latence jusqu’à la première partielle est faible ; des paquets plus gros donnent moins de messages et un peu plus de contexte par inférence. Une plage pratique est de 20 à 250 ms d’audio par paquet. À titre d’exemple, en PCM mono 16 bits 16 kHz, une seconde d’audio fait 32 000 octets, donc un paquet de 100 ms fait environ 3 200 octets.
Capturer l’entrée micro dans le navigateur
Dans le navigateur, l’outil adapté est l’API Web Audio avec un AudioWorklet. Le worklet tourne sur le thread audio, reçoit l’audio en petits blocs et n’est pas affecté par les ralentissements du thread principal comme l’ancien ScriptProcessorNode. Son rôle est de convertir les échantillons float natifs du navigateur en PCM 16 bits et de les transmettre au thread principal, qui les envoie ensuite via WebSocket.
Le cœur du processeur worklet est la conversion float vers PCM :
Le pipeline en code
Le pipeline a trois éléments : un client navigateur qui capture le micro et envoie le PCM à votre serveur, un serveur Node qui relaie l’audio à Scribe v2 Realtime et renvoie les transcriptions, et un client scriptable qui envoie du PCM depuis un fichier ou un pont téléphonique.
Le serveur relaie au lieu d’exposer directement le moteur de reconnaissance au navigateur pour une raison essentielle : votre clé API ElevenLabs est confidentielle et ne doit jamais apparaître côté client. Le serveur garde la clé. Si vous devez parler directement au moteur depuis le navigateur, générez un jeton à usage unique côté serveur et transmettez-le au client à la place de la clé API.
Client navigateur
Le client ouvre un WebSocket vers votre serveur, capture le micro via le worklet ci-dessus, et transmet chaque trame PCM dès qu’elle est produite. Les événements reçus (déjà normalisés par le serveur en { type, text }) pilotent l’état partiel/final vu plus haut :
Relais serveur
Le serveur ouvre une connexion au moteur de reconnaissance par client, garde la clé API côté serveur, transmet le PCM binaire tel quel, et normalise les événements du moteur dans le format stable { type, text } que le client utilise :
Tout ce qui est spécifique à un endpoint est isolé dans les deux fonctions d’adaptation ci-dessous. Remplacez les noms de champs par ceux du guide Speech to Text ; le reste du pipeline ne change pas :
Client backend scriptable
Pour les pipelines backend et le benchmark ci-dessous, la même connexion au moteur fonctionne sans navigateur : lisez le PCM depuis n’importe quelle source, cadrez-le au rythme des paquets temps réel, et lisez les événements en retour. La clé API et l’URL viennent de l’environnement, comme côté serveur.
Mesurer la latence et le taux d’erreur du Speech to Text
La latence et le taux d’erreur varient selon l’orateur, la langue, les conditions acoustiques, la durée de l’audio, votre chemin réseau vers la région la plus proche de chaque fournisseur, et la charge du service à l’instant T.
Un résultat mesuré sur un ordinateur dans une ville ne se généralise pas à votre production ailleurs. Lancez le test sur une infrastructure proche de la production, avec de l’audio représentatif de vos usages, et rapportez des plages et des distributions plutôt qu’un chiffre unique.
Les seules mesures de latence et de précision qui comptent sont celles faites sur votre propre audio, depuis une infrastructure proche de la production. Voici un guide pour mesurer la latence du Speech to Text.
Que mesurer pour la latence Speech to Text
Voici les principaux indicateurs à suivre pour mesurer la latence du Speech to Text en temps réel :
- Temps jusqu’à la première partielle : Depuis l’envoi du premier paquet audio jusqu’à la réception de la première partielle non vide.
- Délai partielle-vers-finale : Depuis le dernier paquet audio d’une prise de parole jusqu’à l’hypothèse finale.
- Taux d’erreur sur les mots (WER) : WER sur la transcription finale comparée à une référence humaine, calculé de la même façon sur tous les systèmes.
- Instabilité des partielles : Combien de partielles sont réécrites avant la finalisation. Cela donne une idée de la stabilité de l’interface en direct.
Contrôles
Pour éviter des données peu fiables, mettez en place plusieurs contrôles pour garder l’expérience cohérente.
Voici les principaux contrôles à appliquer lors du benchmark de latence Speech to Text :
- Audio identique : Utilisez les mêmes fichiers, le même taux d’échantillonnage et le même encodage pour chaque système.
- Cadence identique : Diffusez chaque système à la même cadence de paquets temps réel (par exemple paquets de 100 ms).
- Répétez et rapportez les distributions : Lancez chaque fichier plusieurs fois dans la journée ; rapportez la médiane et les extrêmes (p50/p95).
- Références et scoring identiques : Normalisez le texte de la même façon (casse, ponctuation, chiffres) avant de calculer le WER.
- Indiquez la région et le réseau : Précisez où le test a été lancé et le chemin réseau vers chaque fournisseur.
En gardant tous ces éléments constants, vous obtiendrez des mesures plus précises.
Structure du test
Le cœur de la mesure prend un adaptateur fournisseur et enregistre le temps jusqu’à la première partielle, le délai de finalisation et l’instabilité des partielles :
Le taux d’erreur sur les mots est une distance de Levenshtein standard au niveau des tokens sur texte normalisé. Mettez en minuscules et retirez la ponctuation de la même façon sur la référence et l’hypothèse avant de calculer, sinon vous mesurerez votre normaliseur et non le modèle. Faites tourner la mesure en boucle sur chaque fichier ~10 fois par fournisseur et rapportez la médiane du temps jusqu’à la première partielle et du WER (p50/p95), car un seul échantillon est dominé par la variance réseau.
Pour lancer le test, il vous faut deux choses. D’abord, écrivez un adaptateur StreamFn par système. Le client scriptable ci-dessus en est déjà un, les autres suivent le même contrat (audioPath, onEvent, result) et définissent result.lastChunkSentAt quand le dernier paquet audio est envoyé. Ensuite, chargez vos fichiers audio et références et lancez les mesures dessus. Faites-le depuis une machine représentative de votre déploiement, sur de l’audio représentatif de vos utilisateurs, pour obtenir une comparaison reproductible.
Résumé : comment obtenir un Speech to Text en temps réel
Nous avons vu de nombreux changements architecturaux dans cet article, pour vous permettre d’améliorer votre système et d’atteindre le Speech to Text en temps réel.
Un système STT en temps réel en production repose sur quelques choix clés :
- Transport : Choisissez WebSocket pour la simplicité et les réseaux maîtrisés, et WebRTC si vous avez besoin de tolérance à la perte et capturez depuis des appareils grand public.
- Partielles et finales : Considérez les partielles comme provisoires et les finales comme validées, et affichez-les différemment pour que les utilisateurs aient confiance dans le texte en direct.
- Détection de fin de phrase : Utilisez la VAD pour la segmentation mains libres, le commit manuel en option, et ajustez le seuil de silence selon l’interaction plutôt qu’une valeur fixe.
- Fonctionnalités en flux : Activez les fonctionnalités en flux uniquement si l’expérience en direct l’exige, et gardez le reste pour un traitement différé avec Scribe v2.
- Format audio : Capturez en petits paquets PCM, envoyez des paquets d’environ 100 ms, et respectez le format source pour la téléphonie.
- Benchmark : Ajustez les paramètres précision/latence de façon empirique sur votre propre audio et vos métriques cibles.
- Sécurité de l’API : Gardez votre clé API sur le serveur, ou générez des jetons à usage unique pour les connexions directes client.
Si vous voulez voir comment optimiser la latence dans un agent vocal, nous avons aussi rédigé un guide pour vous.
Construisez des systèmes Speech to Text en temps réel avec Scribe v2 Realtime
Scribe v2 Realtime produit des partielles en environ 150 ms de latence modèle. Que vos utilisateurs ressentent ce chiffre ou plus dépend de l’architecture autour, qui est sous votre contrôle. En appliquant les stratégies de cet article, vous construirez un pipeline optimisé qui réduit la latence et améliore l’expérience client.
Pour aller plus loin, découvrez la présentation des capacités Speech to Text, consultez notre guide des modèles pour la liste complète des fonctionnalités et langues, et visitez les pages produits temps réel : API Speech to Text temps réel et Speech to Text temps réel.
Quand vous êtes prêt à vous lancer, créez un compte ElevenLabs gratuit et diffusez votre première transcription dès aujourd’hui.

.webp&w=3840&q=80)
.webp&w=3840&q=80)
