Kā sešos mēnešos izveidojām reāllaika sistēmu ātri reaģējošam balss MI
Autori: tehniskās komandas dalībnieki Justin Uberti un Zahan Malkani
Balss MI noteikt īsto brīdi, kad runāt, ir grūtāk, nekā šķiet. Cilvēki bez piepūles nodod vārdu cits citam sekundes daļā, taču iepriekšējās balss MI sistēmas nespēja turēt līdzi šim ritmam. To uz sarunas gājieniem balstītā arhitektūra paļāvās uz nelieliem modeļiem, ko sauc par gājiena detektoriem un kam bija nepateicīgs uzdevums: minot par agru, lietotājs tiek pārtraukts; minot par vēlu, atbilde šķiet gausa. Tikai pēc detektora lēmuma darbu varēja sākt daudz lielākais LVM Lielie valodu modeļi.
GPT‑Live, mūsu trešās paaudzes balss sistēma, izņem gājiena detektoru no audio ceļa. Tā balss modelis ir pilndupleksa, proti, tas spēj vienlaikus klausīties un runāt. Tādējādi nav vajadzīgs atsevišķs detektors un saruna šķiet tūlītīgāka un dabiskāka. Kad vajadzīga padziļināta spriestspēja vai rīku izmantošana, GPT‑Live var konsultēties arī ar mūsu robežšķirtnes modeļiem, piemēram, GPT‑5.5, nepārtraucot sarunas plūsmu. Kopā šīs iespējas nodrošina GPT‑Live vēl nepieredzētu sarunas reaģētspējas un intelekta apvienojumu.
Lai šo risinājumu nodrošinātu plašā mērogā, bija vajadzīga jauna sistēmas arhitektūra, kas optimizēta mazai aizkavei. Atšķirībā no ierastās pieprasījuma un atbildes inferenču pieejas mūsu sistēma straumē ienākošo audio balss modelī un tā runu atpakaļ lietotājam, bet deleģēšanu apstrādā pa atsevišķu asinhronu ceļu. Pēdējo sešu mēnešu laikā pārveidojām modeļa inferenci, konteksta pārvaldību un multivides datu pārraidi, lai nodrošinātu vienmērīgu runas plūsmu visā ceļā.
Arhitektūra arī skaidri nodala balss pamatceļu no lietotnes loģikas. Tādējādi lietotnes darbību var viegli pielāgot, neietekmējot reaģētspēju. Šis pamats nodrošina arvien plašākas ChatGPT Balss iespējas, tostarp nesen ieviesto iespēju vadīt datoru un koordinēt savus aģentus ChatGPT datora lietotnē.
Šajā rakstā izskaidrosim, kāpēc agrākās uz sarunas gājieniem balstītās sistēmas neatbilda mūsu vajadzībām un kā jauno sistēmu katrā slānī izstrādājām ātrai reakcijai. Aplūkosim inferenci ar stāvokli, dinamisku konteksta pārvaldību, asinhronu deleģēšanu un protokola līmeņa optimizāciju — tās visas darbojas kopā, lai GPT‑Live šķistu patiesi dzīvs.
Agrākās balss arhitektūras pārmantoja teksta LVM Lielie valodu modeļi uz sarunas gājieniem balstīto pieeju, taču katru gājienu attēloja kā atsevišķu audio datu bloku, nevis tekstu. Kaskādes sistēmās runas pārvēršana tekstā, LVM Lielie valodu modeļi un teksta pārvēršana runā tika izpildīta secīgi. Šī secīgā izpilde palielināja aizkavi un neņēma vērā tādas norādes kā tonis un runas temps.
Runas pārveidošanas runā modeļi uzlaboja šo pieeju, apstrādājot audio tieši. Apmācot modeli dabiski saprast un ģenerēt runu, tas varēja saglabāt atšifrējumā zudušās nianses un atbildēt ātrāk. Taču sistēma joprojām paļāvās uz gājiena detektoru, lai noteiktu, kad var sākt inferenci. Modelis pārvaldīja lielāku mijiedarbības daļu, taču tā joprojām bija balstīta uz sarunas gājieniem.
GPT‑Live nodod sarunas vadību balss modelim: audio ieplūst modelī un izplūst no tā, bet padziļināta spriestspēja un rīku izmantošana notiek asinhroni. Sistēmas galvenais uzdevums ir uzturēt nepārtrauktu multivides cilpu. Citi uzdevumi, piemēram, robežšķirtnes modeļu izsaukšana un sarunas pastāvīga saglabāšana, tiek veikti ārpus reāllaika ceļa.
Nodrošināt šīs multivides cilpas nepārtrauktu darbību ne vienmēr ir vienkārši. Jebkura datu pārraides, apstrādes vai inferenču aizkave var kļūt par dzirdamu pauzi vai kropļojumu. Iepriekšējā uz sarunas gājieniem balstītā sistēma varēja pieļaut zināmas audio datu bloka pienākšanas laika svārstības. Taču multivides sistēmai reāllaikā katrs audio kadrs jāpiegādā paredzētajā laikā.
Iepriekšējais darbs pie ChatGPT Balss un Realtime API nodrošināja mums svarīgu pamatu. Mēs jau bijām pārbūvējuši savu balss infrastruktūru, lai audio un video varētu tieši straumēt uz mūsu sistēmām un no tām ar mazāku un paredzamāku aizkavi. GPT‑Live šo risinājumu pilnveidoja, straumējot multividi līdz pašam modelim, izmantojot jaunu, nepārtrauktām sarunām paredzētu inferenču sistēmu ar stāvokli.
Tomēr straumēšanas inference bija tikai daļa no risinājuma. Lai sistēma labi darbotos produkcijas vidē, bija jānodrošina arī uzticama audio piegāde no klienta līdz inferenču stekam un jārisina ar stāvokļa uzturēšanu saistītās problēmas.
Viens no mūsu agrīnajiem lēmumiem bija skaidri nodalīt multivides plūsmu no lietotnes un biznesa loģikas. Audio starp klientu un balss modeli pārvietojas pa īpašu ātro ceļu. Deleģēšana, rīku izmantošana un citi lietotnes uzdevumi notiek aiz asinhronas RPC robežas. Lēns rīka izsaukums vai aizmugursistēmas pakalpojums var aizkavēt savu rezultātu, taču nevar apturēt multivides plūsmu.
Šis nodalījums sistēmā rada arī skaidru pielāgošanas robežu. Lietotnes var mainīt savus rīkus, politikas un aizmugursistēmas darbību, neietekmējot multivides priekšgalu, kas nodrošina nepārtrauktu audio plūsmu. Reāllaika ceļš paliek neliels, paredzams un vērsts uz darbu, kas jāveic reāllaikā.
Multivides priekšgalu un inferenču loģiku izstrādājām valodā Go, aizstājot iepriekšējo Python asyncio implementāciju. Tas būtiski uzlaboja kadru piegādes vienmērīgumu — jaunās sistēmas p95 rādītājs bija līdzvērtīgs iepriekšējās sistēmas p50 rādītājam.
WebRTC nodrošina datu pārraides pamatu. Tas ir paredzēts multividei ar mazu aizkavi un spēj turpināt darbību pakešu zuduma, pulksteņa nobīdes un klienta savienojuma izmaiņu gadījumā. Ja paketes pienāk novēloti, WebRTC var nemanāmi izstiept audio, lai novērstu pārrāvumus, un pēc tam īslaicīgi paātrināt atskaņošanu, atkal panākot reāllaiku.
Visā sistēmā mazinot buferizāciju un bloķēšanu, varam nodrošināt cilvēku sarunās gaidīto reakciju, kas ir ātrāka par sekundi.
Inferencei ar stāvokli ir savi darbības kompromisi. Balss sesija var būt aktīva ilgu laiku, taču tās konteksts nepārtraukti aug, bet modeļa instances tiek palaistas un apturētas atbilstoši pieprasījumam.
Lai risinātu šīs problēmas, izveidojām nemanāmas pārslēgšanas mehānismu starp modeļa instancēm. Kad nepieciešama pāreja, līdzās esošajai modeļa instancei varam iesildīt aizstājējinstanci, priekšielādēt tajā pašreizējās sesijas kontekstu, paralēli veikt inferenci abās instancēs un pārslēgties, kad jaunā instance ir pilnībā gatava.
Tas pats pamatmehānisms atbalsta arī dinamisku konteksta saspiešanu. Sarunai turpinoties, tās uzkrātais konteksts galu galā var pārsniegt modeļa konteksta ierobežojumu. Konteksta saspiešana var samazināt kontekstu, lai tas iekļautos ierobežojumā, taču šī darbība prasa laiku. Tā kā šī darbība maina iepriekšējo kontekstu, tā arī padara nederīgu modeļa atslēgu un vērtību (KV) kešatmiņu, kurā glabājas iepriekš apstrādāto marķieru uzmanības atslēgas un vērtības. Lai atjaunotu šo stāvokli, jāveic jauna priekšielāde, kas rada papildu aizkavi.
Tāpēc konteksta saspiešanu uzskatām par vēl vienu pārvaldītu pāreju. Kamēr sākotnējā modeļa instance turpina sarunu, sistēma saspiež kontekstu un sagatavo aizstājējinstanci ar jauno kontekstu. Kad šī instance ir gatava, varam uz to pārslēgties, nepārtraucot multivides plūsmu. Tas ļauj sistēmai atbalstīt ilgstošus zvanus, vajadzības gadījumā saspiežot kontekstu.
Resursietilpīgais darbs nenotiek reāllaika ceļā, tāpēc sarunas ritms nepārtrūkst pat pārslēgšanas laikā.
GPT‑Live spēja izsaukt esošos robežšķirtnes modeļus sniedz tam lielas iespējas, būtībā nodalot „runāšanu” no padziļinātas „domāšanas”. Taču, lai šī divu modeļu arhitektūra šķistu kā vienota sistēma, bija jāatrisina divas saistītas inženiertehniskas problēmas.
Deleģēšana plašākam darbam
GPT-Live nodrošina ātras, dabiskas atbildes, kamēr GPT-5.5 fonā veic meklēšanu
Pirmkārt, rezultātiem jāatgriežas pietiekami ātri, lai tie noderētu notiekošajā sarunā, tāpēc bija jāsamazina aizkave visā deleģēšanas ceļā — no maršrutēšanas un uzvednes apstrādes līdz inferencei un rīku izsaukumiem. Vienlaikus citām produkta sistēmām joprojām vajadzīgi atsevišķi ziņojumi, tāpēc notiekošā saruna bija jāatveido tām saprotamā veidā.
Nosūtot deleģētu uzdevumu, optimizējam laiku līdz brīdim, kad robežšķirtnes modelis rada sarunai noderīgu rezultātu. Balss modelis var īslaicīgi turpināt sarunu, kamēr robežšķirtnes modelis spriež vai izmanto rīkus, taču tas nevar noslēpt patvaļīgi lēnu atbildi. Tāpēc visu deleģēšanas ciklu — maršrutēšanu, uzvednes apstrādi, inferenci un rīku izsaukumus — iekļāvām reaģētspējas laika budžetā.
Pirmais optimizācijas solis ir sagatavot robežšķirtnes modeli un tam vajadzīgos rīkus vēl pirms deleģēšanas pieprasījuma. Sākoties balss sesijai, lietotnes serveris izveido inferenču sesiju robežšķirtnes modelim un priekšielādē tajā sākotnējo sarunas kontekstu, lai uzvedne būtu pilnībā apstrādāta pirms pirmā deleģētā pieprasījuma.
Pēc tam šo inferenču sesiju uzturam pieejamu visas balss sarunas laikā un secīgiem pieprasījumiem izmantojam stabilu sesijas piesaisti. Kopā ar uzvedņu kešošanu šie paņēmieni samazina aizkavi, vienlaikus ļaujot viegli atkopties pēc darbinprocesa kļūmes.
To, kad saruna saņem noderīgu rezultātu, ietekmē arī spriestspējas intensitāte, izvades ierobežojumi, rīku shēmas un modeļa un rīku saziņas cikli, tāpēc pielāgojām šos parametrus ātrāku atbilžu iegūšanai. Samazinot deleģēšanas ceļā veicamā darba apjomu, ļāvām balss modelim ātri izmantot mūsu robežšķirtnes modeļu rezultātus.
Lai gan balss modelis apstrādā nepārtrauktas runas plūsmas, daudzas apkārtējās sistēmas joprojām darbojas ar lietotāja un asistenta sarunas gājieniem, tostarp ChatGPT sarunas saskarne un daļa mūsu analītikas un drošības infrastruktūras. Tāpēc lietotnes serveris sadala pārklājošos un reizēm neviennozīmīgos sarunas fragmentus atsevišķos ziņojumos.
Audio pienākšanas laikā serveris izmanto daļējus atšifrējumus un laika signālus, lai noteiktu, kurš runātājs ir pārņēmis vārdu, un izveidotu ziņojumu rindu. Jaunākais ziņojums paliek provizorisks — saņemot vairāk runas, var mainīties tā teksts, laiks un runātāja attiecinājums. Kad runātājs ir pietiekami ilgi turpinājis runāt, lai attiecinājums būtu uzticams, serveris pabeidz attiecīgo ziņojumu.
Runātāju pārklāšanās šo procesu sarežģī. Īsam asistenta apstiprinājumam lietotāja runas laikā (piemēram, „mm hmm” vai „okay”) nav obligāti jākļūst par atsevišķu ziņojumu. Taču saturīgam asistenta iestarpinājumam bieži par tādu jākļūst. Tāpat mēs priekšroku dodam attēloto asistenta atbilžu saskaņotībai pat tad, ja lietotājs pa vidu ierunājas.
Katra segmentēšanas politika meklē līdzsvaru starp aktualitāti un noteiktību. Pārāk agrīna apstiprināšana rada sadrumstalotu vēsturi un nestabilu secību, savukārt pārāk ilga gaidīšana aizkavē atšifrējumus un no tiem atkarīgās funkcijas. Tāpēc sistēma uztur divus saistītus sarunas skatus: provizorisku pašreizējā stāvokļa skatu un autoritatīvu teiktā ierakstu. Sarunas skats lietotnes saskarnē spēj apstrādāt atjauninājumus, tāpēc tas izmanto provizorisko skatu. Taču reģistrēšanai analītikas konveijerā nepieciešams galīgais atšifrējums.
Tādējādi pārējā ChatGPT sistēma iegūst stabilu sarunas skatu, neuzspiežot sarunas gājienus reāllaika balss ceļam.
Ātra reakcija sākas jau brīdī, kad lietotājs noklikšķina uz pogas. Izmantojot GPT‑Live, sistēmai jāizveido multivides ceļš un jāsāk audio padeve modelim, pirms var sākties saruna. Tādējādi ikviena palaišanas secības daļa nonāk kritiskajā ceļā.
Kā minēts iepriekš, WebRTC nodrošina stabilu pamatu darbībai reāllaikā, taču standarta WebRTC sesijas sākšanai vajadzīgs pārsteidzoši daudz protokolu rokasspiedienu un tīkla turpceļu un atpakaļceļu. WebRTC radās pirms tam, kad uzmanība tika pievērsta tīkla turpceļu un atpakaļceļu samazināšanai, kas veidoja vēlākus protokolus, piemēram, QUIC. Tāpēc tā pamatā esošie protokoli, lietoti kopā, dažkārt atkārto vienu un to pašu darbu. Piemēram, katram protokolam bija savs aizsardzības mehānisms pret pakalpojumatteices uzbrukumiem, pat ja pilna WebRTC steka kontekstā tas nebija vajadzīgs.
Mēs analizējām steku un izstrādājām WebRTC saīsināto turpceļa un atpakaļceļa protokolu (WARP(atveras jaunā logā)), kas multivides un datu palaišanai nepieciešamos sešus tīkla turpceļus un atpakaļceļus samazina līdz vienam. WARP to panāk ar atpakaļsaderīgiem protokolu uzlabojumiem: DTLS rokasspiediena pievienošanu ICE plūsmai (SPED(atveras jaunā logā)), ātrākā DTLS 1.3(atveras jaunā logā) rokasspiediena izmantošanu, SCTP rokasspiediena iepriekšēju saskaņošanu (SNAP(atveras jaunā logā)) un datu kanālu iepriekšēju saskaņošanu, nevis DCEP(atveras jaunā logā) izmantošanu.
Sadarbojoties ar WebRTC kopienas pārstāvjiem, WARP izstrādājām kā atvērtu specifikāciju kopumu, lai šis darbs sniegtu labumu plašākai ekosistēmai. Priekšlikumus virzām IETF TSVWG darba grupā, un WARP atbalsts jau ir pievienots gan libwebrtc, gan Pion; darbs turpinās arī citās WebRTC implementācijās.
Pēc multivides rokasspiediena optimizēšanas izcēlās vēl viena atlikusī aizkave: signalizācijas apmaiņa, ko izmanto SDP parametru kopīgošanai, pirms WebRTC var izveidot savienojumu. Lai šo apmaiņu izņemtu no kritiskā ceļa, izstrādājām risinājumu, ko saucam par Instant Connect. Tas šos parametrus saskaņo iepriekš, nerezervējot servera jaudu un neveicot nekādas izmaiņas esošajās WebRTC implementācijās.
Instant Connect darbojas līdztekus standarta signalizācijas plūsmai. Ja iepriekš saskaņotie parametri ir derīgi, serveris var izveidot sesiju, kad pienāk pirmā multivides pakete. Ja tie ir novecojuši vai nederīgi, signalizācijas plūsma jau ir sākusies, tāpēc klients var pārslēgties uz rezerves risinājumu bez papildu aizkaves.
Instant Connect un WARP kopā ievērojami saīsina laiku no lietotāja nodoma līdz multivides plūsmai reāllaikā. Tā kā SDP apmaiņa vairs nav kritiskajā ceļā un WARP apvieno datu pārraides rokasspiedienus, klients tagad var sākt sesiju ar vienu UDP paketi. Serveris var atbildēt nekavējoties, ļaujot pārējai sistēmai sākt darbu, kas lietotājam patiesi rūp: klausīties un atbildēt.
Sistēma teorētiski var šķist ātra, taču reālā balss datplūsmā tik un tā iestrēgt. Pirms ļāvām GPT‑Live sarunāties ar lietotājiem, veicām kluso testu, pakāpeniski pieaugošu nelielu daļu produkcijas ChatGPT Balss sesiju novirzot gan uz esošo uzlabotā balss režīma risinājumu, gan uz mūsu jauno sistēmu. Uzlabotais balss režīms turpināja apkalpot lietotājus kā ierasts, bet ēnas plūsma veica inferenci tikai lasīšanas režīmā. Tādējādi sistēma tika pakļauta reāliem klientiem, tīkliem, sesiju ilgumiem un ģeogrāfiskajam sadalījumam, nemainot to, ko dzirdēja lietotāji.
Viena no pirmajām atziņām bija tāda, ka jaudu nevar vērtēt tikai pēc GPU caurlaidspējas. Balss sesijas paliek atvērtas un nepārtraukti sūta kadrus, tāpēc CPU puses straumju apstrādātājiem, rindām un tīkla ceļiem jāmērogojas līdztekus inferencei. Reālā slodzē viens palīgkomponents sasniedza piesātinājumu agrāk, nekā paredzēja slodzes testu aplēses, tāpēc inferenču pieprasījumi uzkrājās un aizkave turpināja pieaugt. Jautājumu par jaudu mainījām no „Cik pieprasījumu spēj apstrādāt GPU?” uz „Cik vienlaicīgu sesiju sistēma spēj uzturēt, ikvienu kadru apstrādājot laikā?”
Tests arī parādīja, ka ģeogrāfija ir viens no galvenajiem apsvērumiem. Sesijas novirzīšana uz attālu infrastruktūru var radīt aizkavi vairākos palaišanas un straumēšanas posmos. Sākām modeļu laidienus pārbaudīt kopā ar reģionālo jaudu un datplūsmas maršrutēšanas konfigurāciju, pēc tam analizējot aizkavi pēc izcelsmes reģiona. Inferenču pārvietošana tuvāk lietotājiem palīdzēja, taču nostiprināja arī plašāku atziņu: pilna ceļa reaģētspēja ir atkarīga no ikviena tajā iesaistītā pakalpojuma, ne tikai modeļa servera.
Citas kļūmes parādījās tikai reālistiskos sesiju dzīves ciklos. Ilgstošas sesijas atklāja atmiņas un pastāvīgās glabāšanas noslodzi. Atkārtota savienojuma izveide pārbaudīja konteksta saspiešanu un stāvokļa atjaunošanu. Parasta klientu atvienošanās atklāja sacensības noslēgšanas rokasspiedienā. Īsos slodzes testos šīs problēmas parādījās reti, jo tās bija atkarīgas no laika, uzkrātā stāvokļa un darbības pāri pakalpojumu robežām.
Visbeidzot, testēšana produkcijas vidē lika uzlabot novērojamību un laidienu kontroli. Atklājām metriku, kurā bija sajaukti dažādi aizkaves avoti, informācijas paneļus, kuru kopsavilkumi slēpa atsevišķus problemātiskus dzinējus, un konfigurāciju atšķirības starp testētajām un izvietotajām sistēmām. Tāpēc ieviesām detalizētāku telemetriju, pārbaudi pret zināmām drošām konfigurācijām, pakāpenisku slodzes palielināšanu un iespēju ātri izolēt vai atspējot atsevišķus ceļus. Klusais tests kļuva par agrīnu palaišanas mēģinājumu — ne tikai tam, cik lielu datplūsmu sistēma spēj uzņemt, bet arī tam, cik ātri spējam atklāt un ierobežot kļūmi un pēc tās atjaunoties.
Lai GPT‑Live darbotos ChatGPT mērogā, bija jāizveido pilnīgi jauna sistēma, kuras pamatā ir viens būtisks princips: balss plūsma nedrīkst apstāties. Straumēšanas inference nepārtraukti piegādā audio pilndupleksa modelim. Atsevišķs multivides ceļš nodrošina uzticamu kadru piegādi. Asinhrona deleģēšana ļauj padziļinātai domāšanai notikt paralēli. Optimizēta datu pārraide nodrošina ātru reakciju visā ceļā līdz lietotājam.
GPT‑Live pamatā esošā arhitektūra jau kļūst par plašāku reāllaika mijiedarbības platformu. Tā nodrošina ChatGPT Balss darbību, šim risinājumam pārejot no sarunām uz aģentu koordinēšanu, un būs gaidāmā GPT‑Live API pamatā. Laika gaitā tā ļaus balss risinājumiem aptvert vairāk ierīču, lietotņu un modalitāšu, nezaudējot tūlītīgumu, kas balss sarunai piešķir dzīvīgumu.
Ja vēlaties risināt šādas inženiertehniskas problēmas, pievienojieties mūsu komandai.

