Pour qu’un agent vocal commence à parler avant d’avoir terminé sa réponse, envoyez chaque phrase achevée à Kokoro-82M dès qu’elle est générée. Dans l’exemple d’AWS, un endpoint temps réel Amazon SageMaker AI synthétise les phrases l’une après l’autre pendant que l’agent poursuit la génération. Ce guide s’adresse aux développeurs qui veulent comprendre l’ordre de déploiement, les trames WebSocket et le transport audio de ce montage.
Comment le montage répartit la génération et la synthèse
L’agent, hébergé dans le runtime Amazon Bedrock AgentCore avec le framework Strands, reçoit du texte généré par Amazon Bedrock. Un client transmet les phrases complètes au modèle Kokoro-82M déployé dans un conteneur personnalisé sur un endpoint temps réel Amazon SageMaker AI. L’exemple utilise une instance GPU ml.g5.xlarge.
Le conteneur expose trois routes : GET /ping pour le contrôle de santé, POST /invocations pour un flux de réponse et WS /invocations-bidirectional-stream pour une session WebSocket bidirectionnelle. Cette dernière permet au client d’envoyer plusieurs messages de synthèse dans une même session.
Le découpage s’effectue à mesure que le texte arrive : le client émet une phrase dès qu’elle est complète, puis envoie le texte restant quand la génération prend fin. La synthèse des messages reste séquentielle. Le gain vient du démarrage plus précoce de la première phrase, pas de la synthèse simultanée de plusieurs phrases.
Préparer le déploiement dans le bon ordre
L’exemple demande un compte AWS et les autorisations nécessaires, AWS CDK v2 initialisé, Python 3.12 ou une version ultérieure, uv, Docker et une version compatible de Boto3. L’image du conteneur doit porter le label requis pour le streaming bidirectionnel de SageMaker. Il faut aussi être à l’aise avec les WebSocket et Starlette ou un framework ASGI, l’interface qui gère les connexions asynchrones.
Procédez dans cet ordre :
- Construisez et déployez le conteneur Kokoro sur SageMaker AI. L’endpoint doit être en place avant le runtime de l’agent, qui l’appellera pour produire l’audio.
- Faites accepter au gestionnaire WebSocket les trames binaires. SageMaker transmet les messages du client sous forme binaire dans le flux bidirectionnel. Un gestionnaire Starlette qui appelle seulement
receive_text()peut provoquerKeyError('text'), même si l’endpoint affiche l’étatInService. Le gestionnaire doit prendre en charge les octets et décoder leur contenu en UTF-8 lorsque le message contient du texte. - Gardez la connexion ouverte entre les messages de synthèse. Chaque message peut produire une trame de contrôle
synthesis_start, des données audio PCM brutes, puis une tramesynthesis_complete. Ne fermez la session qu’après réception du message de fermeture explicite du client. - Déployez ensuite l’agent Strands dans Amazon Bedrock AgentCore. Il peut alors envoyer les phrases achevées vers l’endpoint Kokoro au fil de la génération.
Le conteneur d’exemple épingle une ancienne version de PyTorch associée à l’avis PYSEC-2026-2286. AWS indique que la correction figure dans PyTorch 2.10.0 et recommande d’examiner cette version épinglée avant d’utiliser l’exemple au-delà d’une preuve de valeur.
Choisir le chemin audio vers le navigateur
Si votre interface utilise déjà les Server-Sent Events (SSE), un mécanisme qui transmet des événements du serveur au navigateur, l’audio encodé en base64 peut s’intégrer à ce flux. AWS mesure une hausse de taille d’environ un tiers avec cet encodage. Les segments SSE peuvent aussi couper une trame audio : le navigateur doit alors mettre les données en mémoire tampon et reconstituer les trames avant de les traiter.
Dans le trajet bidirectionnel vers Kokoro, l’exemple fait passer l’audio brut et les messages de contrôle JSON sur la même connexion. Le trajet entre AgentCore et le navigateur utilise encore le base64, car le runtime AgentCore transmet des dictionnaires compatibles avec JSON. Voici les tailles relevées par AWS sur 24 extraits audio :
| Format audio | Données brutes | Données en base64 | Débit binaire |
| PCM brut | 2 396 400 octets | 3 195 200 octets | 384 kbit/s |
| MP3 48k | 308 304 octets | 411 072 octets | 49,5 kbit/s |
| AAC 32k fMP4 | 258 039 octets | 344 084 octets | 41,6 kbit/s |
Sur le flux bidirectionnel, l’application doit aussi distinguer les messages de contrôle des données audio. L’exemple reconnaît un message de contrôle lorsque la trame entière peut être analysée comme un objet JSON. Une interface qui réutilise SSE doit, elle, assembler les segments audio plutôt que de supposer que chaque événement contient une trame complète.
D’autres façons d’exécuter Kokoro
Trelis Research a montré Kokoro-ONNX en inférence locale sur CPU, ainsi que Kokoro-FastAPI sur un serveur H100 hébergé par Runpod. Pour ce serveur sous concurrence, Trelis Research rapporte un débit de 55 à 78 heures d’audio traitées par heure réelle. Ce chiffre porte sur le débit du serveur dans cette configuration, tandis qu’AWS mesure le délai avant la première donnée audio dans son montage SageMaker et AgentCore.
Ce que mesurent les résultats de latence d’AWS
Dans son test de transport isolé, AWS a envoyé un texte de 267 caractères et quatre phrases à un endpoint actif, avec cinq essais par mode. Le délai moyen avant le premier octet audio était de 329,3 ms en mode batch, contre 156,7 ms lorsque seule la première phrase était envoyée au départ. AWS rapporte une réduction relative de 52,4 % pour ce test.
Dans sa comparaison de bout en bout, AWS rapporte que le mode bidirectionnel a atteint le premier audio 2,4 fois plus vite que le mode batch en test local et 3,5 fois plus vite sur le runtime AgentCore déployé. AWS indique avoir conservé le même prompt, le même modèle Bedrock et le même endpoint, en faisant varier le moment où la synthèse démarrait.
Vérifier le flux, puis nettoyer les ressources
Pour vérifier le comportement, envoyez plusieurs phrases dans une seule session et contrôlez que chaque message produit ses trames de début, audio et fin avant le message de fermeture explicite. Vérifiez aussi le cas des trames binaires : un endpoint InService ne suffit pas à garantir que le gestionnaire sait traiter le format reçu.
Les commandes de nettoyage d’AWS suppriment le runtime de l’agent et l’endpoint SageMaker. Le compartiment Amazon S3 utilisé pour mettre les poids du modèle en cache et le dépôt Amazon ECR qui conserve l’image du conteneur peuvent rester en place et continuer à générer des frais de stockage tant qu’ils ne sont pas supprimés séparément.