Met de AWS-opzet kan Kokoro-82M al beginnen met spraak maken terwijl een AI-agent de rest van zijn antwoord nog genereert. De client stuurt elke voltooide zin naar een realtime endpoint in Amazon SageMaker AI. De endpoint verwerkt de syntheseberichten wel één voor één: de eerste zin begint eerder, maar meerdere zinnen worden niet gelijktijdig uitgesproken.

Hoe de opzet is opgebouwd

Kokoro-82M, een tekst-naar-spraakmodel met 82 miljoen parameters, draait in een aangepaste container op een SageMaker AI-endpoint. AWS gebruikt daarvoor een ml.g5.xlarge-instantie. Een Strands-agent draait in de voorbeeldopzet binnen Amazon Bedrock AgentCore en vraagt tekst op via Amazon Bedrock.

De container biedt drie routes: GET /ping voor een gezondheidscontrole, POST /invocations voor een responsstream en WS /invocations-bidirectional-stream voor een blijvende verbinding in twee richtingen. Die WebSocket-verbinding kan achtereenvolgens meerdere syntheseberichten vervoeren.

Wat je nodig hebt en in welke volgorde je uitrolt

Voor de voorbeeldopzet heb je een AWS-account met de benodigde machtigingen nodig. Verder vermeldt AWS een vooraf geïnitialiseerde AWS CDK v2-omgeving, Python 3.12 of hoger, uv, Docker, een compatibele Boto3-versie en een containerlabel voor bidirectionele streaming. Ervaring met WebSockets en Starlette of ASGI helpt om de endpoint-handler te begrijpen.

  1. Bouw en rol eerst het Kokoro-endpoint uit. De agent moet audio kunnen aanvragen bij de SageMaker AI-endpoint voordat je de volledige route vanaf de agent kunt testen.
  2. Rol daarna de Strands-agent uit naar Bedrock AgentCore. Daarmee kan de agent tekst genereren en die tijdens het genereren naar Kokoro doorsturen.
  3. Controleer de endpoint en test vervolgens de bidirectionele route. GET /ping controleert de gezondheidsroute. Test daarnaast daadwerkelijk een WebSocket-bericht, omdat een endpoint met de status InService nog steeds kan falen op de manier waarop de handler frames verwerkt.

De AWS-container gebruikt een oudere versie van PyTorch die verband houdt met beveiligingsadvies PYSEC-2026-2286. AWS vermeldt dat dit advies is verholpen in PyTorch 2.10.0. Beoordeel de vastgepinde versie voordat je het voorbeeld buiten een proof of value gebruikt.

Verwerk WebSocket-frames als bytes en houd de sessie open

SageMaker levert berichten via de bidirectionele verbinding als binaire WebSocket-frames. Een Starlette-handler die alleen receive_text() gebruikt, kan daardoor KeyError('text') geven terwijl de endpoint-status InService blijft. De handler moet binaire frames kunnen accepteren en de inhoud waar nodig als UTF-8 decoderen.

Houd dezelfde sessie open voor opeenvolgende syntheseverzoeken. Per verzoek stuurt de endpoint besturingsinformatie en audio terug; sluit de verbinding pas wanneer de client expliciet een afsluitbericht stuurt. De voorbeeldstroom bevat per verzoek een synthesis_start-bericht, binaire PCM-audio en een synthesis_complete-bericht. Zo kan één verbinding meerdere zinnen afhandelen zonder telkens opnieuw te verbinden.

Stuur zinnen door zodra ze af zijn

De client verzamelt tekst terwijl de agent genereert en stuurt een zin naar Kokoro zodra die compleet is. Aan het einde van de generatie wordt ook de resterende tekst verstuurd, zelfs als die geen volledige zin vormt. Zo kan de synthese van de eerste zin beginnen voordat de agent zijn hele antwoord heeft afgemaakt.

De winst zit dus in het eerdere startmoment. De handler verwerkt syntheseverzoeken sequentieel; streaming betekent hier niet dat Kokoro meerdere zinnen tegelijk omzet in spraak.

Kies hoe je de audio bij de browser krijgt

Als je frontend al Server-Sent Events (SSE) gebruikt, kan audio als base64-tekst in die stroom passen. Base64 vergroot de payload in AWS’ meting met ongeveer een derde. Bovendien kan een transportblok midden in een audi frame eindigen. De ontvanger moet de binnenkomende data daarom bufferen en de audiogegevens weer samenvoegen.

Op de bidirectionele modelverbinding kan de opzet ruwe audio combineren met JSON-besturingsberichten. De browsergerichte verbinding via AgentCore gebruikt nog steeds base64, omdat de runtime JSON-serialiseerbare gegevens oplevert. AWS mat in een transporttest met 24 clips de volgende payloadgroottes:

AudioformaatRuwe bytesBytes in base64Bitsnelheid
Ruwe PCM2.396.4003.195.200384 kbps
MP3 48k308.304411.07249,5 kbps
AAC 32k fMP4258.039344.08441,6 kbps

De tabel laat zien wat de gekozen codering doet met de omvang van deze geteste audiopayloads. Voor een bestaande SSE-frontend is base64 een bruikbare route, mits je rekening houdt met de grotere payload en het opnieuw samenvoegen van gegevens. De bidirectionele modelroute kan ruwe audio gebruiken met afzonderlijke JSON-besturingsberichten.

Andere manieren om Kokoro te draaien

Trelis Research demonstreerde Kokoro-ONNX voor lokale inferentie op een CPU en Kokoro-FastAPI op een H100-server bij Runpod. In die serveropstelling rapporteerde Trelis Research onder gelijktijdige belasting een verwerking van ongeveer 55 tot 78 uur audio per uur rekentijd. Dat is een andere maatstaf en een andere omgeving dan de tijd tot de eerste audio in AWS’ tests.

Wat AWS’ latencycijfers meten

In een geïsoleerde test stuurde AWS dezelfde tekst van 267 tekens en vier zinnen naar een live endpoint. Over vijf tests per modus bedroeg de gemiddelde tijd tot de eerste audiobyte 329,3 ms in batchmodus en 156,7 ms wanneer de eerste zin eerder werd verstuurd. AWS rapporteerde daarvoor een relatieve afname van 52,4%.

Voor de end-to-endvergelijking rapporteerde AWS dat bidirectionele streaming lokaal 2,4 keer sneller tot de eerste audio leidde dan batchverwerking. Op de uitgerolde AgentCore-runtime was dat 3,5 keer sneller. AWS gebruikte daarbij dezelfde prompt, hetzelfde Bedrock-model en dezelfde endpoint; het moment waarop de synthese begon was de gewijzigde factor.

Ruim de AWS-resources op

Verwijder bij het opruimen eerst de agentruntime en daarna de SageMaker AI-endpoint. De opruimcommando’s uit het voorbeeld verwijderen niet automatisch de S3-bucket met de modelcache of de ECR-repository met de containerafbeelding. Als die resources blijven staan, kunnen ze opslagkosten blijven veroorzaken.