Carane OpenAI nyedhiyakake AI swara kanthi latensi rendah ing skala gedhé
Dening Yi Zhang lan William McDonald, Anggota Staf Teknis
AI swara mung krasa alami yen obrolan mlaku kanthi kacepetan wicara. Nalika jaringan ngganggu, wong-wong langsung krungu efeké minangka jeda kikuk, interupsi kepotong, utawa gangguan ketundha. Bab kuwi penting kanggo swara ChatGPT, kanggo pangembang sing mbangun nganggo Realtime API, kanggo agen sing makarya ing alur kerja interaktif, lan kanggo model sing kudu ngolah audio nalika pangguna isih ngomong.
Ing skala OpenAI, iku nerjemahake dadi telung syarat konkret:
- Jangkauan global sing nggayuh luwih saka 900 yuta pangguna aktif saben minggu
- Persiyapan sambungan sing cepet supaya pangguna bisa miwiti ngomong sanalika sesi diwiwiti
- Wektu wolak-walik media sing rendah lan stabil, kanthi jitter lan kelangan paket sing rendah, mula gantian ngomong krasa cepet lan cetha
Tim ing OpenAI sing tanggung jawab kanggo interaksi AI wektu nyata bubar ngrancang ulang arsitektur tumpukan WebRTC kanggo ngatasi telung watesan sing wiwit tabrakan ing skala gedhé: pemutusan media siji-port-saben-sesi ora cocog banget kanggo infrastruktur OpenAI, sesi ICE (Interactive Connectivity Establishment) lan DTLS (Datagram Transport Layer Security) sing nduwé status mbutuhake kepemilikan sing stabil, lan routing global kudu njaga latensi first-hop tetep rendah. Ing postingan iki, kita nerangake langkah demi langkah arsitektur relai plus transiver sing dipisah sing kita bangun kanggo njaga perilaku WebRTC standar kanggo klien, nalika ngowahi cara paket data dirutekake ing njero infrastruktur OpenAI.
WebRTC minangka standar terbuka kanggo ngirim audio, video, lan data kanthi latensi rendah antarane browser, aplikasi seluler, lan server. Iki asring digandhengaké karo panggilan peer-to-peer, nanging uga dadi pondasi praktis kanggo sistem wektu nyata klien-menyang-server amarga nyeragamake bagean angel saka media interaktif: ICE kanggo netepake konektivitas lan ngliwati NAT (Network Address Translation), DTLS lan SRTP (Secure Real-time Transport Protocol) kanggo transportasi sing dienkripsi, negosiasi codec kanggo ngompres lan ndékodhe audio, RTCP (Real-time Transport Control Protocol) kanggo kontrol kualitas, lan fitur ing sisi klien kaya pembatalan gema lan buffering jitter.
Standarisasi kuwi wigati kanggo produk AI. Tanpa WebRTC, saben klien bakal mbutuhake solusi sing beda kanggo cara mbangun konektivitas ngliwati NAT, ngenkripsi media, negosiasi codec (coder-decoder sing dipilih kanggo transmisi lan dekompresi), lan adaptasi karo kahanan jaringan sing owah-owahan. Kanthi WebRTC, kita bisa mbangun ing ndhuwur tumpukan protokol sing wis diimplementasikake ing saindhenging browser lan platform seluler, kanthi fokusake pakaryan kita dhewe marang infrastruktur sing nyambungake media wektu nyata menyang model.
Kita uga mbangun adhedhasar ekosistem WebRTC kuwi dhéwé, kalebu implementasi sumber mbukak sing wis mateng lan karya standar sing njaga browser, aplikasi seluler, lan server tetep bisa interoperasi. Pakaryan dhasar dening Justin Uberti (salah siji arsitek asli WebRTC) lan Sean DuBois (pangripta lan pangrumat Pion) ndadekake tim kaya kita bisa mbangun ing ndhuwur infrastruktur media sing wis kabukten tangguh ing kahanan nyata, tinimbang nggawe maneh prilaku transpor tingkat rendah, enkripsi, lan kontrol kemacetan saka wiwitan. Kita begja amarga Justin lan Sean loro-lorone saiki dadi kolega ing kene ing OpenAI, mbantu nuntun cara kita nggawa WebRTC lan AI wektu nyata luwih cedhak siji lan sijiné.
Kanggo AI, sipat sing paling penting yaiku audio teka minangka aliran sing terus-terusan. Agen lisan bisa miwiti nranskripsikake, nalar, nelpon alat, utawa ngasilake wicara nalika pangguna isih ngomong, tinimbang ngenteni unggahan lengkap. Kuwi bedané antarane sistem sing krasa kaya obrolan lan sistem sing krasa kaya push-to-talk.
Sawisé kita milih WebRTC, pitakonan sabanjuré yaiku ing endi kudu mungkasi sambungan WebRTC (ing endi kita bakal nampa lan ngelola sambungan WebRTC—contone, ing pinggiran jaringan) lan kepiye carane nyambungake sesi-sesi kasebut menyang backend inferensi. Mungkasi sambungan iku penting amarga iki nemtokaké kepiyé kita nangani kahanan sesi wektu nyata, transportasi media, routing, latensi, lan isolasi kegagalan.
SFU, utawa unit penerusan selektif, yaiku server media sing nampa siji stream WebRTC saka saben peserta lan kanthi selektif nerusake stream menyang peserta liyane. Ing model iki, SFU dadi titik terminasi kanggo sambungan WebRTC sing kapisah kanggo saben peserta, lan AI gabung minangka peserta liyane ing sesi kasebut. Iki bisa dadi pilihan sing pas kanggo produk sing pancen nglibatake akeh pihak, kayata telpon grup, kelas, utawa rapat kolaboratif. Iki nglumpukaké codec audio, pesen RTCP, saluran data, rekaman, lan kabijakan per-stream ing siji panggonan.1
Malah ing produk klien-menyang-AI, SFU asring dadi titik wiwitan standar amarga ngidini tim nggunakake maneh siji sistem sing wis kabukten kanggo pensinyalan, perutean media, perekaman, observabilitas, lan ekstensi mbesuk kayata pengalihan menyang manungsa utawa nambah peserta luwih akeh.
Beban kerja kita iku beda. Umume sesi iku 1:1—siji pangguna ngobrol karo siji model, utawa siji aplikasi ngobrol karo siji agen wektu nyata—kanthi peka marang latensi ing saben giliran. Kanggo pola lalu lintas kaya ngono, kami milih model transiver: layanan edge WebRTC nindakake terminasi koneksi klien banjur ngowahi media lan event dadi protokol internal sing luwih prasaja kanggo inferensi model, transkripsi, generasi wicara, panggunaan piranti, lan orkestrasi.
Ing rancangan iki, transiver iku siji-sijine layanan sing nduweni lan ngatur status sesi WebRTC, kalebu pamriksa konektivitas ICE, jabat tangan DTLS, kunci enkripsi SRTP, lan siklus urip sesi. “Terminasi” ing kene tegese transiver minangka endpoint sing ngrampungaké handshake kasebut lan ngenkripsi utawa ndekripsi media. Njaga state kasebut ing siji panggonan nggawe kepemilikan sesi luwih gampang dipahami lan dianalisis, lan nggawe layanan backend bisa diskalakake kaya layanan biasa tinimbang tumindak minangka peer WebRTC dhewe.
Sawisé milih model transiver, implementasi kapisan kita yaiku layanan Go tunggal sing dibangun ing Pion kanggo nangani signaling lan terminasi media. Iki nggerakaké fitur swara ChatGPT, endpoint WebRTC saka API wektu nyata, lan sawetara proyek panaliten.
Sacara operasional, layanan transiver nindakake rong tugas:
- Sinyalisasi: negosiasi SDP, pamilihan codec, kredensial ICE, lan persiapan sesi
- Media: Nindakake terminasi sambungan WebRTC hilir lan njaga sambungan hulu menyang layanan backend kanggo inferensi lan orkestrasi
Kita pengin layanan kasebut mlaku kaya infrastruktur liyane: ing Kubernetes, ing ngendi beban kerja bisa diskalakake munggah lan mudhun, lan pindhah antar-host nalika panjaluk owah. Nanging model WebRTC konvensional siji-port-saben-sesi ora cocog kanggo lingkungan kasebut, amarga gumantung marang rentang port UDP publik sing gedhé, sing angel di-ekspos, diamanake, lan dijaga nalika pods ditambah, dibusak, utawa dijadwal ulang.2
Masalah pisanan yaiku model siji port saben sesi kasebut. Nalika konkurensi dhuwur, iki tegesé mbukak lan ngatur rentang port UDP sing gedhé banget.
- Cloud load balancer lan layanan Kubernetes ora dirancang kanggo nangani puluhan ewu port UDP publik saben layanan. Saben rentang tambahan nambahake kerumitan operasional ing konfigurasi load balancer, pamriksan kesehatan, kabijakan firewall, lan keamanan orientasi.3
- Rentang port UDP sing gedhe angel diamanké amarga nggedhekake area permukaan sing bisa diakses saka njaba lan nggawe kabijakan jaringan luwih angel diaudit.
- Iku uga ora pas kanggo skala otomatis. Pod terus-terusan ditambahaké, dibusak, lan dijadwalaké maneh ing Kubernetes. Mbutuhake saben pod kanggo nyisihake lan ngumumake rentang port stabil sing gedhe nggawe elastisitas kasebut rapuh.4
Iki sebabe akeh sistem WebRTC ngarah menyang siji port UDP saben server, kanthi demultipleksing tingkat aplikasi ing mburi port kasebut.5
Rancangan siji-port-saben-server ngrampungake masalah cacah port, nanging nimbulake masalah kapindho: njaga hak kepemilikan saben sesi ing saindhenging armada.
ICE lan DTLS iku protokol sing duwe status. Proses sing nggawe sesi kudu tetep nampa paket saka sesi kasebut supaya bisa validasi pamriksan konektivitas, ngrampungake handshake DTLS, ndekripsi SRTP, lan ngolah owah-owahan sesi sabanjure kayata miwiti ulang ICE. Yen paket kanggo sesi sing padha tekan proses sing béda, penyiapan bisa gagal utawa media bisa pedhot.
Iki menehi target tartamtu marang kita: mbukak permukaan UDP sing cilik lan ajeg menyang internet publik, nalika isih ngarahake saben paket menyang transiver sing nduweni sesi WebRTC sing cocog.
Kita ngevaluasi sawetara cara kanggo nggayuh tujuan kasebut, kalebu TURN (Traversal Using Relays around NAT), ing ngendi relai edge mungkasi alokasi klien lan nerusake lalu lintas atas jenenge.2
Pendekatan | Kaluwihan | Kekurangan |
IP:port unik saben sesi (uga dikenal minangka UDP langsung asli) | Jalur media langsung saka klien menyang server Ora ana lapisan penerusan ing jalur data | Mbutuhake siji port UDP publik saben sesi Rentang port gedhé angel diekspos lan diamanake Ora pas kanggo Kubernetes lan penyeimbang beban awan |
IP:port unik saben server | Jejak UDP publik luwih cilik tinimbang paparan saben sesi Siji soket sing dienggo bareng saben server bisa misahake akeh sesi | Bisa mlaku kanthi lancar ing siji host, nanging ora ing saindhenging fleet bareng sing di-load-balance yen mung dhewe Demultipleksing sesi ing siji host mung migunani sawisé paket tekan host kasebut; nanging ing klaster sing di-load-balance, paket pisanan isih bisa tiba ing conto sing salah, mula njenengan isih mbutuhake cara deterministik kanggo ngarahaké saben sesi menyang proses sing nduwèni sesi kuwi |
Relai TURN (kang mungkasi protokol) | Klien mung perlu bisa ngakses alamat lan port relai TURN Bisa memusatake kabijakan ing pinggiran | Alokasi TURN nambah round trip persiapan Mindhah utawa mbalekake alokasi ing antarane server TURN isih angel. |
Forwarder tanpa status + terminator kanthi status (relai + transiver saka OpenAI) | Jejak UDP publik cilik Transiver isih nguwasani sesi WebRTC sakabèhé | Nambah siji hop penerusan sadurungé media tekan transiver pamiliké Mbutuhake koordinasi khusus antarane relai lan transiver |
Arsitektur sing kita rilis misahake routing paket saka terminasi protokol. Pensinyalan isih tekan transiver kanggo nyiyapake sesi, dene media mlebu liwat relai dhisik. Relai iku lapisan penerusan UDP sing entheng kanthi jejak publik sing cilik, lan transiver iku endpoint WebRTC sing nduwé state ing mburiné.
Relai ora ngdekripsi media, nglakokaké mesin status ICE, utawa melu negosiasi codec. Iki maca metadata paket sing cukup kanggo milih tujuan, banjur nerusake paket menyang transiver sing nduweni sesi kasebut. transiver isih ndeleng alur WebRTC sing normal lan isih nduweni kabeh status protokol. Saka perspektif klien, ora ana apa-apa babagan sesi WebRTC sing owah.
Perutean paket pisanan minangka langkah kunci ing setelan iki. Relai kudu ngrutekaké paket pisanan saka klien sadurungé ana sesi apa wae ing jalur paket kasebut dhéwé, tinimbang ngaso ing layanan lookup eksternal.
Saben sesi WebRTC wis nggawa kaitan routing bawaan protokol: fragmen jeneng pangguna ICE, utawa ufrag, yaiku pengenal cekak sing diijolake nalika persiyapan sesi lan diulang maneh ing pemeriksaan konektivitas STUN. Kita ngasilake ufrag sisih server supaya mung ngemot metadata perutean sing cukup kanggo relai nyimpulake klaster tujuan lan transiver sing dadi pamilik.
Sajrone proses sinyal, transiver ngalokasikake status sesi lan mbalekake VIP relai sing dienggo bareng lan port UDP ing jawaban SDP. VIP iku alamat IP virtual sing ana ing ngarep armada relai; yen digabungake karo port, iki menehi klien siji tujuan sing stabil, kayata `203.0.113.10:3478`, sanajan akeh conto relai ana ing mburine. Paket jalur media pisanan saka klien biasane minangka panjaluk njiret STUN (Session Traversal Utilities for NAT), sing digunakake ICE kanggo mesthekake yen paket bisa tekan alamat sing diumumake.
Relai mung nganalisis sacukupé saka paket STUN pisanan kanggo maca ufrag server, ngudhari pitunjuk routing, lan nerusaké paket kasebut menyang transiver sing dadi pamiliké. Saben transiver ngrungokake ing soket UDP bareng, tegese siji endpoint sistem operasi sing diiket menyang IP:port internal, dudu siji soket saben sesi. Sawisé relai nggawe sesi saka IP:port sumber klien menyang tujuan transiver kasebut, paket DTLS, RTP, lan RTCP sabanjuré mili ing njero sesi tanpa ndekode maneh ufrag.
Sesi relai sengaja digawe minimal, mung dumadi saka sesi ing memori kanggo menehi informasi marang penerusan paket, bareng karo counter sing dibutuhake kanggo monitoring lan timer kanggo kedaluwarsa sesi lan pambersihan. Pilihan desain iki njaga supaya perutean paket tetep langsung ana ing jalur paket. Yen relai diwiwiti maneh lan kelangan sesi, paket STUN sabanjure bakal mbangun maneh sesi saka pituduh routing ufrag. Kanggo nggawe luwih andal maneh, cache Redis digunakake kanggo nyimpen pemetaan <IP klien + Port, IP transiver + Port> sawisé rute wis ditetepake supaya bisa dipulihake luwih awal, sadurungé paket STUN sabanjuré teka.
Sawisé kita nyuda paparan UDP publik dadi mung sawetara alamat lan port sing stabil, kita bisa masang pola relai sing padha sacara global. Global Relay yaiku armada titik ingress relai kita sing disebarake sacara geografis lan kabeh ngetrapake prilaku nerusake paket sing padha.
Ingress geografis sing amba nyepetake hop pisanan saka klien menyang OpenAI amarga paket bisa mlebu jaringan kita ing relai sing cedhak karo pangguna, saka segi geografi lan topologi jaringan, tinimbang kudu nyabrang internet publik menyang wilayah sing adoh dhisik. Sacara praktis, kuwi tegesé latensi luwih endhek, jitter luwih sithik, lan lonjakan packet loss sing bisa dicegah luwih sithik sadurungé lalu lintas tekan backbone kita.6
Kita nggunakake geo lan kemudi jarak cedhak saka Cloudflare kanggo sinyal supaya panjaluk HTTP utawa WebSocket awal tekan klaster transiver sing cedhak. Konteks panjaluk nemtokake lokasi sesi lan titik ingress Global Relay sing diumumake marang klien. Wangsulan SDP nyedhiyakake alamat Global Relay, dene ufrag ngemot informasi sing cukup supaya Global Relay bisa ngerutekake media menyang klaster sing wis ditetepake lan relay bisa ngerutekake menyang transiver tujuan.
Bareng-bareng, pensinyalan sing diarahaké adhedhasar geo lan Global Relay nempataké panyiyapan lan media ing jalur mlebu sing cedhak, nalika tetep njangkaraké sesi menyang siji transiver. Kuwi nyuda wektu bolak-balik kanggo sinyalisasi lan kanggo pamriksa konektivitas ICE sing kapisan, sing kanthi langsung nyepetaké suwéné pangguna ngenteni sadurungé wicara bisa diwiwiti.
Kita nulis layanan relai nganggo Go lan kanthi sengaja njaga implementasine supaya tetep winates. Ing Linux, tumpukan jaringan kernel nampa paket UDP saka antarmuka jaringan mesin lan ngirimaké menyang soket, yaiku titik pungkasan sistem operasi sing diwaca déning proses sawisé ngiket IP:Port. Relai mlaku ing ruang pangguna, mula proses Go biasa maca header paket saka soket kasebut, nganyari sethithik status alur, lan nerusake paket tanpa mungkasi WebRTC. Kita ora mbutuhake kerangka kerja kernel-bypass apa wae, sing bakal ngidini proses ruang pangguna nindakake polling antrian jaringan kanthi langsung kanggo laju paket sing luwih dhuwur nanging uga nambah kerumitan operasional.
Pilihan desain utama:
- Ora ana terminasi protokol: Relai mung ngurai header STUN/ufrag; nggunakake status sing di-cache kanggo DTLS, RTP, lan RTCP sabanjuré, supaya paket tetep ora transparan.
- Kahanan sementara: Iki njaga peta cilik ing memori kanthi timeout cekak saka alamat klien menyang tujuan transiver kanggo kahanan alur lan observabilitas.
- Skalabilitas horisontal: Pirang-pirang conto relai mlaku kanthi paralel ing mburi load balancer. Kahanan dudu hard state WebRTC, mula restart nyebabake lalu lintas mudhun minimal lan pemulihan aliran kanthi cepet.
Langkah-langkah efisiensi:
SO_REUSEPORTyaiku opsi soket Linux sing ngidini pirang-pirang worker relai ing mesin sing padha ngiket port UDP sing padha. Kernel banjur mbagekake paket sing mlebu menyang worker-worker kasebut, saéngga ngindhari hambatan read-loop tunggal.runtime.LockOSThreadmengunci setiap goroutine yang membaca UDP ke thread OS tertentu. Yen digabungaké karoSO_REUSEPORT, iku cenderung njaga paket saka alur sing padha (IP:Port sumber lan tujuan plus protokol) tetep ana ing inti CPU sing padha, saéngga ningkataké lokalitas cache lan nyuda pangalihan konteks.- Buffer sing wis dialokasi sadurunge lan penyalinan minimal njaga overhead parsing lan alokasi tetep cilik supaya ora nyebabake pengumpulan sampah ing Go.
Implementasi iki nangani lalu lintas media wektu nyata global kita kanthi jejak relai sing relatif cilik, mula kita milih tetep nganggo desain sing luwih prasaja tinimbang nggunakake jalur kernel bypass.
Arsitektur iki ngidini kita nglakokaké media WebRTC ing Kubernetes tanpa mbukak ewonan port UDP. Iki penting amarga permukaan UDP sing luwih cilik lan tetep luwih gampang diamanké lan diimbangi bebané, lan iki ngidini infrastruktur ngembang skalane tanpa kudu nyisihaké rentang port publik sing gedhé. Kanthi dhukungan infrastruktur sing luwih apik saka Kubernetes lan keamanan sing luwih dhuwur amarga permukaan serangan sing luwih cilik, desain iki uga njaga prilaku WebRTC standar kanggo klien lan ngonfirmasi manawa desain tanpa SFU minangka pilihan bawaan sing pas kanggo beban kerja kita. Umume sesi kita iku point-to-point, sensitif marang latensi, lan luwih gampang diskalake nalika layanan inferensi ora perlu tumindak kaya peer WebRTC.
Piwulang sing luwih jembar yaiku panggonan paling apik kanggo nambah kompleksitas yaiku ing lapisan routing sing tipis, ora ing saben layanan backend, lan ora ing prilaku klien kustom. Ngode metadata routing menyang field bawaan protokol menehi kita routing paket pisanan sing deterministik, footprint UDP publik sing cilik, lan keluwesan sing cukup kanggo nyelehake ingress cedhak karo pangguna ing saindenging donya.
Sawetara pilihan utamané penting:
- Njaga semantik protokol ing tepi jaringan. Klien isih nggunakake WebRTC standar, sing njaga interoperabilitas antar browser lan piranti seluler tetep terjaga.
- Simpen status sesi sing angel ing siji panggonan. Transiver ngatur ICE, DTLS, SRTP, lan siklus urip sesi; relai mung nerusaké paket.
- Rutekake adhedhasar informasi sing wis ana ing setelan. ICE ufrag menehi kita hook routing paket kapisan tanpa nambah dependensi lookup ing hot-path.
- Ngoptimalake kanggo kasus umum sadurunge nggunakake kernel bypass. Implementasi Go sing khusus kanthi panggunaan
SO_REUSEPORTsing ngati-ati, pinning thread, lan parsing kanthi alokasi sithik wis cukup kanggo beban kerja kita.
AI swara wektu nyata mung bisa mlaku nalika infrastruktur nggawe latensi krasa ora ana. Kanggo kita, kuwi tegesé ngganti wujud penerapan WebRTC kita tanpa ngganti apa sing diarep-arep klien saka WebRTC kuwi dhewe.
Pangarang
Rujukan
2. GitHub - l7mp/stunner: A Kubernetes media gateway for WebRTC(mbukak ing jendhela anyar)
3. WebRTC Ports in a nutshell [Examples] - BlogGeek.me(mbukak ing jendhela anyar)
4. Deploy to Kubernetes - LiveKit docs(mbukak ing jendhela anyar)
6. Cloudflare Calls: millions of cascading trees all the way down(mbukak ing jendhela anyar)


