Sådan byggede vi på seks måneder et realtidssystem til stemme-AI med hurtig respons
Af Justin Uberti og Zahan Malkani, tekniske medarbejdere
For stemme-AI er det sværere, end det lyder, at vide, hvornår man skal tale. Mennesker skiftes ubesværet til at tale på en brøkdel af et sekund, men tidligere stemme-AI-systemer kunne ikke følge denne rytme. Deres turbaserede arkitektur var afhængig af små modeller kaldet turskiftedetektorer, som havde en utaknemmelig opgave: Gættede de for tidligt, blev brugeren afbrudt. Gættede de for sent, føltes svaret trægt. Først når detektoren havde truffet sin beslutning, kunne den langt større LLM gå i gang.
GPT‑Live, vores tredjegenerations stemmesystem, fjerner turskiftedetektoren fra lydstien. Stemmemodellen er fulddupleks, hvilket betyder, at den kan lytte og tale samtidig. Dermed er der ikke brug for en separat detektor, og samtalen føles mere umiddelbar og naturlig. Når der er behov for dybere ræsonnering eller brug af værktøjer, kan GPT‑Live også rådføre sig med vores banebrydende modeller, såsom GPT‑5.5, uden at afbryde samtalens flow. Tilsammen giver disse egenskaber GPT‑Live en hidtil uset kombination af hurtig respons i samtaler og intelligens.
At levere denne oplevelse i stor skala krævede en ny systemarkitektur optimeret til lav forsinkelse. I modsætning til typisk anmodnings- og svarbaseret inferens streamer vores system indgående lyd til stemmemodellen og udgående tale tilbage til brugeren, mens delegering håndteres via en separat asynkron sti. I løbet af de seneste seks måneder har vi omarbejdet modelinferens, kontekststyring og medietransport for at holde talen flydende fra ende til anden.
Arkitekturen skaber også en klar grænse mellem den centrale stemmesti og applikationslogikken. Det gør det nemt at tilpasse applikationens adfærd uden at påvirke svartiden. Dette fundament driver et voksende udvalg af funktioner i ChatGPT stemme, herunder den nyligt lancerede mulighed for at styre din computer og koordinere dine agenter i ChatGPTs computerapp.
I dette indlæg forklarer vi, hvorfor tidligere turbaserede systemer ikke kunne opfylde vores behov, og hvordan vi konstruerede det nye system med henblik på hurtig respons i alle lag. Vi gennemgår tilstandsbaseret inferens, dynamisk kontekststyring, asynkron delegering og optimering på protokolniveau – alt sammen teknologier, der får GPT‑Live til virkelig at føles live.
Tidligere stemmearkitekturer arvede de tekstbaserede LLM'ers turbaserede struktur, men hver tur blev repræsenteret som en separat lydblok i stedet for tekst. I kaskadesystemer blev tale-til-tekst, LLM'en og tekst-til-tale afviklet efter hinanden. Denne rækkefølge øgede forsinkelsen og overså signaler som tonefald og taletempo.
Tale-til-tale-modeller forbedrede denne tilgang ved at behandle lyd direkte. Ved at træne modellen til selv at forstå og generere tale kunne den bevare detaljer, der går tabt ved transskription, og svare hurtigere. Systemet var dog stadig afhængigt af, at turskiftedetektoren afgjorde, hvornår inferensen kunne begynde. Modellen håndterede en større del af interaktionen, men den var stadig turbaseret.
GPT‑Live giver stemmemodellen kontrollen over samtalen: Lyd strømmer ind og ud af modellen, mens dybere ræsonnering og brug af værktøjer foregår asynkront. Systemets vigtigste opgave er at opretholde et ubrudt mediekredsløb. Andet arbejde, såsom at kalde banebrydende modeller og gemme samtalen, foregår uden for livestien.
Det er ikke altid ligetil at holde dette mediekredsløb ubrudt. Enhver forsinkelse i transport, behandling eller inferens kan blive til en hørbar pause eller lydfejl. Et tidligere turbaseret system kunne tåle en vis variation i, hvornår en lydblok ankom. Et system med livemedier skal derimod levere hver eneste lydframe til tiden.
Vores tidligere arbejde med ChatGPT stemme og Realtime API gav os et vigtigt fundament. Vi havde allerede genopbygget vores stemmeinfrastruktur, så lyd og video kunne streames direkte ind og ud af vores systemer med lavere og mere forudsigelig forsinkelse. GPT‑Live videreudviklede dette design ved at streame medier hele vejen til modellen gennem et nyt tilstandsbaseret inferenssystem bygget til kontinuerlige samtaler.
Streaminginferens var dog kun en del af løsningen. For at få det til at fungere godt i produktion skulle vi også sikre pålidelig levering af lyd fra klienten til inferensstakken og håndtere udfordringerne ved at bevare tilstand.
En tidlig beslutning var at adskille medieflowet fra applikations- og forretningslogikken. Lyden bevæger sig mellem klienten og stemmemodellen via en dedikeret hurtig sti. Delegering, brug af værktøjer og andet applikationsarbejde foregår bag en asynkron RPC-grænse. Et langsomt værktøjskald eller en langsom backendtjeneste kan forsinke sit eget resultat, men ikke standse medieflowet.
Denne adskillelse giver også systemet en klar grænse for tilpasning. Applikationer kan ændre deres værktøjer, politikker og backendadfærd uden at påvirke den mediefrontend, der holder lyden i gang. Livestien forbliver lille, forudsigelig og fokuseret på det arbejde, der skal udføres i realtid.
Vi skrev mediefrontenden og inferenslogikken i Go og erstattede en tidligere Python-implementering med asyncio. Det gjorde leveringen af frames markant mere jævn, så det nye systems p95 svarede til det tidligere systems p50.
WebRTC udgør fundamentet for transporten. Det er designet til medier med lav forsinkelse og kan fortsætte driften trods pakketab, tidsafvigelser og ændringer i klientens forbindelse. Hvis pakker ankommer for sent, kan WebRTC strække lyden diskret for at undgå udfald og derefter kortvarigt øge afspilningshastigheden for at indhente realtid igen.
Ved at minimere buffering og blokering i hele systemet kan vi levere den svartid på under et sekund, som mennesker forventer af en samtale.
Tilstandsbaseret inferens har sine egne driftsmæssige afvejninger. En stemmesession kan være aktiv i lang tid, mens dens kontekst vokser konstant, og modelinstanser startes og lukkes efter behov.
For at håndtere disse udfordringer byggede vi en mekanisme til problemfri overdragelse mellem modelinstanser. Når et skift er nødvendigt, kan vi varme en ny modelinstans op ved siden af den eksisterende, forhåndsudfylde den med sessionens aktuelle kontekst, køre inferens på begge parallelt og skifte, når den nye instans er helt klar.
Den samme grundlæggende mekanisme understøtter også dynamisk komprimering af kontekst. Efterhånden som en samtale fortsætter, kan dens akkumulerede kontekst overskride modellens kontekstgrænse. Komprimering kan reducere kontekstens størrelse, så den holder sig inden for grænsen, men processen tager tid. Fordi den ændrer tidligere kontekst, ugyldiggør den også modellens key-value-cache (KV-cache), som gemmer attention-nøgler og -værdier fra tidligere behandlede tokens. Genopbygning af denne tilstand kræver en ny forhåndsudfyldning, som giver yderligere forsinkelse.
I stedet behandler vi komprimering som endnu et styret skift. Mens den oprindelige modelinstans fortsætter samtalen, komprimerer systemet konteksten og forbereder en ny modelinstans med den nye kontekst. Når denne instans er klar, kan vi skifte uden at afbryde medieflowet. Dermed kan systemet understøtte langvarige opkald og komprimere efter behov.
Det tunge arbejde holdes væk fra livestien, så samtalen fortsætter uden at miste rytmen, selv under en overdragelse.
GPT‑Lives evne til at kalde eksisterende banebrydende modeller giver systemet stor styrke og adskiller reelt det at »tale« fra dybere »tænkning«. Men for at få denne arkitektur med to modeller til at føles som ét system måtte vi løse to beslægtede tekniske problemer.
Delegering til dybere arbejde
GPT-Live leverer hurtige, naturlige svar, mens GPT-5.5 håndterer søgning i baggrunden
For det første skal resultaterne komme hurtigt nok tilbage til at være nyttige i den igangværende samtale. Derfor måtte vi minimere forsinkelsen gennem hele delegeringsstien – fra routing og behandling af prompts til inferens og værktøjskald. Samtidig har systemer andre steder i produktet stadig brug for separate beskeder, så vi måtte repræsentere den løbende samtale i en form, de kunne forstå.
Når en delegering sendes af sted, optimerer vi tiden, indtil den banebrydende model producerer noget, samtalen kan bruge. Stemmemodellen kan kortvarigt holde samtalen i gang, mens en banebrydende model ræsonnerer eller bruger værktøjer, men den kan ikke skjule en vilkårligt langsom svartid. Derfor regnede vi hele delegeringskredsløbet – routing, behandling af prompts, inferens og værktøjskald – med i budgettet for svartid.
Den første optimering består i at klargøre den banebrydende model og de værktøjer, den skal bruge, før der anmodes om delegering. Når en stemmesession starter, opretter applikationsserveren en inferenssession til den banebrydende model og forhåndsudfylder den med samtalens oprindelige kontekst. Det sikrer, at prompten er færdigbehandlet før den første delegerede anmodning.
Derefter holder vi inferenssessionen tilgængelig under hele stemmesamtalen og bruger stabil sessionstilknytning til efterfølgende anmodninger. Sammen med caching af prompts reducerer disse teknikker forsinkelsen, samtidig med at systemet nemt kan komme sig efter fejl i en worker.
Ræsonneringsindsats, outputgrænser, værktøjsskemaer og rundture mellem model og værktøj påvirker også, hvornår samtalen modtager et brugbart resultat. Vi justerede derfor disse parametre for at få hurtigere svar. Ved at minimere arbejdet i delegeringsstien gjorde vi det muligt for stemmemodellen hurtigt at indarbejde resultater fra vores banebrydende modeller.
Selvom stemmemodellen arbejder med kontinuerlige talestrømme, arbejder mange af systemerne omkring den stadig med brugerens og assistentens taleture. Det gælder blandt andet ChatGPTs samtalegrænseflade og dele af vores analyse- og sikkerhedsinfrastruktur. Applikationsserveren opdeler derfor den overlappende og til tider tvetydige samtale i separate beskeder.
Efterhånden som lyden ankommer, bruger serveren foreløbige transskriptioner og tidssignaler til at udlede, hvem der har ordet, og opbygge en beskedkø. Den nyeste besked forbliver foreløbig. Dens tekst, tidsangivelser og talertilknytning kan alle ændre sig, efterhånden som der kommer mere tale. Når en taler har haft ordet længe nok til, at tilskrivningen er pålidelig, færdiggør serveren den tilhørende besked.
Det bliver mere kompliceret, når talerne overlapper hinanden. En kort bekræftelse fra assistenten, mens brugeren taler, f.eks. »mm-hm« eller »okay«, bør ikke nødvendigvis blive til en selvstændig besked. Et indholdsmæssigt indskud fra assistenten bør derimod ofte. På samme måde prioriterer vi sammenhæng i assistentens viste svar, selv når brugeren taler midt i dem.
Enhver segmenteringspolitik afvejer aktualitet mod sikkerhed. Hvis beskeder fastlægges for tidligt, bliver historikken fragmenteret og rækkefølgen ustabil. Venter man for længe, forsinkes transskriptionerne og de funktioner, der afhænger af dem. Systemet vedligeholder derfor to beslægtede visninger af samtalen: en foreløbig visning af den aktuelle tilstand og en autoritativ registrering af, hvad der blev sagt. Samtalevisningen i applikationens brugergrænseflade kan håndtere opdateringer og bruger derfor den foreløbige visning. Logning til analysepipelinen kræver derimod en endelig transskription.
Det giver resten af ChatGPT et stabilt billede af samtalen uden at påtvinge livestien en turbaseret struktur.
Den hurtige respons begynder, så snart brugeren klikker på knappen. Med GPT‑Live skal systemet etablere mediestien og begynde at sende lyd gennem modellen, før samtalen kan begynde. Dermed bliver alle dele af opstartssekvensen kritiske for svartiden.
Som nævnt ovenfor udgør WebRTC et solidt fundament for realtid, men opstart af en almindelig WebRTC-session kræver overraskende mange protokolhandshakes og rundture på netværket. WebRTC er fra før det fokus på at minimere rundture, som formede senere protokoller som QUIC. Derfor gentager de underliggende protokoller undertiden arbejde, når de bruges sammen. Hver protokol havde eksempelvis sin egen mekanisme mod DoS-angreb, selv når den ikke var nødvendig i sammenhæng med hele WebRTC-stakken.
Vi analyserede stakken og udviklede WebRTC Abridged Roundtrip Protocol (WARP(åbner i et nyt vindue)), som reducerer opstarten af medier og data fra seks netværksrundture til blot én. WARP opnår dette med en række bagudkompatible protokolforbedringer: DTLS-handshaket sendes sammen med ICE (SPED(åbner i et nyt vindue)), det hurtigere DTLS 1.3(åbner i et nyt vindue)-handshake bruges, SCTP-handshaket forhåndsforhandles (SNAP(åbner i et nyt vindue)), og datakanaler forhåndsforhandles i stedet for at bruge DCEP(åbner i et nyt vindue).
Vi designede WARP som et sæt åbne specifikationer i samarbejde med bidragydere fra WebRTC-fællesskabet, så hele økosystemet kan få gavn af arbejdet. Vi arbejder på at føre forslagene videre gennem IETF's TSVWG-arbejdsgruppe, og understøttelse af WARP er allerede føjet til både libwebrtc og Pion, mens arbejdet fortsætter i andre WebRTC-implementeringer.
Efter optimeringen af mediehandshaket var der én resterende forsinkelse, som skilte sig ud: signaludvekslingen, der bruges til at dele SDP-parametre, før WebRTC kan oprette forbindelse. For at fjerne denne udveksling fra den kritiske sti udviklede vi det, vi kalder Instant Connect. Løsningen forhandler disse parametre på forhånd uden at reservere serverkapacitet og uden ændringer af eksisterende WebRTC-implementeringer.
Instant Connect kører parallelt med standardflowet for signalering. Hvis de forhåndsforhandlede parametre er gyldige, kan serveren oprette sessionen, når den første mediepakke ankommer. Hvis de er forældede eller ugyldige, er signaleringsflowet allerede i gang, så klienten kan falde tilbage til det uden yderligere forsinkelse.
Tilsammen reducerer Instant Connect og WARP markant tiden fra brugerens hensigt til et aktivt medieflow. Når SDP-udvekslingen er fjernet fra den kritiske sti, og WARP har komprimeret transporthandshaket, kan klienten nu starte en session med en enkelt UDP-pakke. Serveren kan svare med det samme, så resten af systemet kan begynde på det arbejde, brugeren faktisk er interesseret i: at lytte og svare.
Et system kan se hurtigt ud på papiret og alligevel gå i stå under virkelig stemmetrafik. Før vi lod GPT‑Live tale med brugerne, gennemførte vi en lydløs test, hvor en lille, gradvist stigende andel af produktionssessionerne i ChatGPT stemme blev sendt til både den eksisterende avancerede stemmetilstand og vores nye system. Den avancerede stemmetilstand betjente fortsat brugerne som normalt, mens skyggestien kørte inferens i skrivebeskyttet tilstand. Dermed blev systemet udsat for virkelige klienter, netværk, sessionslængder og geografisk fordeling, uden at det ændrede, hvad brugerne hørte.
En af de første erfaringer var, at kapacitet ikke blot kunne reduceres til GPU-gennemløb. Stemmesessioner forbliver åbne og sender kontinuerligt frames, så streamhandlere på CPU-siden, køer og netværksstier skal kunne skaleres i takt med inferensen. Under reel belastning nåede en understøttende komponent mætningspunktet tidligere end forventet ud fra vores belastningstest. Det fik inferensanmodninger til at hobe sig op og forsinkelsen til at vokse yderligere. Vi ændrede kapacitetsspørgsmålet fra »Hvor mange anmodninger kan en GPU håndtere?« til »Hvor mange samtidige sessioner kan systemet opretholde, mens hver frame leveres til tiden?«
Testen gjorde også geografi til en afgørende faktor. Hvis en session dirigeres til fjern kapacitet, kan det give forsinkelse flere steder under opstart og streaming. Vi begyndte at validere modeludrulninger sammen med regional kapacitet og konfigurationen af trafikstyringen og derefter opdele forsinkelsen efter geografisk oprindelse. Det hjalp at flytte inferensen tættere på brugerne, men understregede også en bredere erfaring: Svartiden fra ende til anden afhænger af samtlige tjenester i kæden, ikke kun modelserveren.
Andre fejl viste sig kun gennem realistiske sessionsforløb. Langvarige sessioner afslørede pres på hukommelse og persistens. Genoprettede forbindelser satte komprimering og gendannelse af tilstand på prøve. Almindelige afbrydelser fra klienter afslørede kapløbstilstande i nedlukningshandshaket. Disse problemer viste sig sjældent i korte belastningstest, fordi de afhang af tid, akkumuleret tilstand og adfærd på tværs af tjenestegrænser.
Endelig tvang produktionstesten os til at forbedre observerbarheden og styringen af udrulninger. Vi fandt målinger, der blandede forskellige kilder til forsinkelse sammen, dashboards, hvor aggregerede tal skjulte enkelte fejlbehæftede motorer, og konfigurationsafvigelser mellem de testede og udrullede systemer. Derfor tilføjede vi mere detaljeret telemetri, validering mod konfigurationer, der vides at fungere, trinvise opskaleringer samt mulighed for hurtigt at isolere eller deaktivere enkelte stier. Den lydløse test blev en tidlig generalprøve på lanceringen – ikke kun på, hvor meget trafik systemet kunne modtage, men også på, hvor hurtigt vi kunne opdage, inddæmme og rette op på fejl.
At bringe GPT‑Live op på ChatGPT‑skala krævede et helt nyt system bygget op omkring ét grundlæggende princip: Stemmen skal flyde. Streaminginferens forsyner løbende fulddupleksmodellen med lyd. En dedikeret mediesti sikrer pålidelig levering af frames. Asynkron delegering gør det muligt at foretage dybere tænkning parallelt. Optimeret transport sikrer hurtig respons hele vejen ud til brugeren.
Arkitekturen bag GPT‑Live er allerede ved at udvikle sig til en bredere platform for interaktion i realtid. Den driver ChatGPT stemme, efterhånden som produktet udvides fra samtale til koordinering mellem agenter, og den bliver fundamentet for den kommende GPT‑Live API. Med tiden vil den gøre det muligt at udbrede stemmeoplevelser til flere enheder, apps og modaliteter uden at miste den umiddelbarhed, der får stemmesamtaler til at føles levende.
Hvis det er den slags tekniske problemer, du gerne vil løse, kan du komme og arbejde sammen med os.

