Comment nous sommes passés sous les 700 ms en traduction en direct
Le budget est le vrai défi, pas le modèle
Tout le monde suppose que la latence de traduction vocale est un problème de modèle : choisir un moteur de reconnaissance plus rapide, un modèle de traduction plus rapide, une voix plus rapide, et le chiffre baisse. Sur FluenSync, notre produit de traduction vocale en temps réel sur le web, iOS et Android, changer de modèle a compté moins que prévu. Ce qui nous a fait passer sous les 700 millisecondes sur 14 langues ou plus, c'est l'architecture du pipeline autour des modèles.
Découper la parole avant qu'elle ne se termine
L'approche naïve attend une pause, envoie l'énoncé complet à la reconnaissance, puis à la traduction, puis à la synthèse. Chaque étape attend que la précédente se termine, et les pauses seules entament le budget avant même qu'un mot ait été traité. Nous envoyons plutôt des blocs audio de taille fixe vers la reconnaissance au fur et à mesure de leur arrivée, et la laissons émettre des transcriptions partielles en continu. La traduction démarre sur des segments stables que le moteur de reconnaissance ne révisera plus, sans attendre une transcription finale. C'est là que se récupère l'essentiel du budget, pas grâce à un modèle plus rapide en particulier.
Où vit la connexion
Les trois étapes reposent sur une seule connexion WebSocket par session plutôt que sur trois appels distincts. Une WebSocket évite le coût d'établissement d'une nouvelle connexion à chaque bloc, et permet de transmettre les résultats partiels au client dès qu'ils existent plutôt que d'attendre que le client interroge le serveur. Sur mobile, la même connexion transporte l'audio en amont et la parole synthétisée en aval, il n'y a donc qu'un seul aller-retour à budgétiser, pas plusieurs.
Le budget que nous suivons réellement
- Capture et découpage sur l'appareil : une tranche fixe et petite, pas l'énoncé entier.
- Réseau montant : une trame WebSocket, pas une nouvelle connexion par bloc.
- Reconnaissance sur un segment stable : renvoyer le résultat dès qu'il ne sera plus révisé.
- Traduction de ce segment : une entrée assez courte pour garder une latence de modèle prévisible.
- Synthèse : commencer à générer l'audio d'un segment avant que le suivant n'ait fini d'être traduit.
- Réseau descendant et lecture : diffusés en flux, pas livrés en un seul fichier à la fin.
Chaque étape a sa propre cible en millisecondes, et nous les mesurons séparément plutôt que de ne regarder que le chiffre de bout en bout, car une étape lente disparaît dans une moyenne mais reste très visible pour la personne qui attend.
Gérer le réseau, pas seulement le pipeline
Un pipeline rapide sur une connexion stable échoue quand même sur le terrain s'il suppose que le réseau ne connaît jamais de ratés. Les connexions mobiles perdent des trames, réordonnent des paquets et se bloquent en plein milieu d'une phrase. Nous faisons tourner un petit tampon de gigue côté client pour absorber les courtes coupures sans interrompre la lecture, et nous encodons l'audio avec un codec conçu pour le faible débit plutôt qu'un codec optimisé pour la taille du fichier. Quand la WebSocket se coupe en cours de session, le client se reconnecte et reprend la session au lieu de la recommencer, si bien qu'une interruption brève coûte un accroc, pas un redémarrage depuis le silence. Rien de tout cela n'apparaît dans un chiffre de latence mesuré sur un réseau de laboratoire, mais c'est ce qui décide si le budget de 700 millisecondes tient sur un téléphone dans un train en marche.
Ce que nous avons choisi de ne pas faire
Nous n'avons pas cherché le modèle le plus rapide dans l'absolu, car un modèle légèrement plus rapide qui attend un énoncé complet perd face à un modèle un peu plus lent capable de démarrer sur un segment partiel. Nous n'avons pas non plus essayé de prendre de l'avance en devinant des suites probables, car une mauvaise supposition coûte plus cher à corriger à voix haute que la latence qu'elle pourrait faire gagner. Les gains sont venus de la suppression des temps d'attente entre étapes, pas de l'accélération d'une étape isolée.
Ce que nous dirions à une équipe qui construit cela
Profilez le pipeline étape par étape avant d'optimiser un modèle en particulier. Diffusez en flux tout ce qui peut l'être. Traitez la connexion elle-même comme faisant partie du budget de latence, pas seulement les modèles qui se trouvent derrière. Sur un produit vocal en temps réel, ce que les utilisateurs remarquent n'est pas la vitesse d'une étape isolée. C'est la somme de chaque moment où une étape a attendu qu'une autre se termine complètement avant de démarrer.