2P by GN⁺ 7시간전 | ★ favorite | 댓글 1개
  • OpenAI는 9억 명 이상 주간 활성 사용자에게 자연스러운 음성 대화를 제공하기 위해 표준 WebRTC 동작을 유지하면서 내부 패킷 라우팅을 relay + transceiver 구조로 재설계함
  • WebRTC는 ICE, DTLS/SRTP, 코덱 협상, RTCP 품질 제어, 에코 제거와 지터 버퍼링을 표준화해 브라우저·모바일 앱·서버 사이의 저지연 연속 오디오 스트림 처리에 적합함
  • OpenAI의 대부분 세션은 사용자 1명과 모델 1개 또는 애플리케이션 1개와 실시간 에이전트 1개가 대화하는 1:1 세션이어서, 다자간 통화에 맞는 SFU보다 transceiver 모델이 지연과 확장성에 더 적합했음
  • Kubernetes에서 세션당 UDP 포트 1개를 노출하는 WebRTC 모델은 큰 공개 포트 범위, 로드밸런서 설정, 헬스체크, 방화벽 정책, 롤아웃 안전성을 복잡하게 만들어 작고 고정된 UDP 표면이 필요했음
  • relay는 첫 STUN 패킷의 ICE ufrag에 담긴 라우팅 힌트로 소유 transceiver를 찾아 전달하고, transceiver가 ICE·DTLS·SRTP·세션 수명주기를 소유해 표준 WebRTC 호환성과 전 세계 가까운 ingress 경로를 함께 유지함

저지연 음성 AI의 요구사항

  • 음성 AI는 대화가 말의 속도로 움직일 때 자연스럽게 느껴지며, 네트워크 지연은 어색한 침묵, 잘린 끼어들기, 늦은 끼어들기 반응으로 바로 드러남
  • OpenAI 규모에서는 9억 명 이상 주간 활성 사용자를 위한 전 세계 도달성, 세션 시작 직후 말할 수 있는 빠른 연결 설정, 낮고 안정적인 미디어 왕복 시간, 낮은 지터와 패킷 손실이 필요함
  • ChatGPT voice, Realtime API, 대화형 워크플로의 에이전트, 사용자가 말하는 동안 오디오를 처리해야 하는 모델 모두 이 지연 특성에 영향을 받음
  • OpenAI는 클라이언트의 표준 WebRTC 동작을 유지하면서 내부 패킷 라우팅을 바꾸기 위해 relay + transceiver 분리 구조로 WebRTC 스택을 재설계함

WebRTC를 선택한 이유

  • WebRTC는 브라우저, 모바일 앱, 서버 사이에서 저지연 오디오·비디오·데이터를 보내기 위한 공개 표준이며, 클라이언트-서버 실시간 시스템의 기반으로도 적합함
  • WebRTC는 ICE를 통한 연결 설정과 NAT 통과, DTLS/SRTP 암호화 전송, 코덱 협상, RTCP 품질 제어, 에코 제거와 지터 버퍼링 같은 클라이언트 기능을 표준화함
  • WebRTC가 없으면 각 클라이언트가 NAT 환경에서의 연결 수립, 미디어 암호화, 코덱 협상, 네트워크 변화 대응을 따로 해결해야 함
  • AI 제품에서 중요한 특성은 오디오가 연속 스트림으로 도착한다는 점이며, 사용자의 전체 업로드가 끝날 때까지 기다리지 않고 전사, 추론, 도구 호출, 음성 생성을 시작할 수 있음
  • 이 차이가 대화형으로 느껴지는 시스템과 push-to-talk처럼 느껴지는 시스템을 가름함
  • OpenAI는 성숙한 오픈소스 구현과 표준화 작업을 포함한 WebRTC 생태계를 기반으로 삼으며, Justin Uberti와 Sean DuBois의 기반 작업 덕분에 저수준 전송, 암호화, 혼잡 제어를 새로 만들지 않고 검증된 미디어 인프라 위에 구축할 수 있었음

SFU 대신 transceiver를 선택한 구조

  • SFU가 맞는 경우

    • SFU는 각 참여자의 WebRTC 스트림을 받아 다른 참여자에게 선택적으로 전달하는 미디어 서버임
    • SFU 모델에서는 각 참여자마다 별도 WebRTC 연결을 종료하고, AI도 세션의 또 다른 참여자로 합류함
    • 그룹 통화, 교실, 협업 회의처럼 본질적으로 다자간인 제품에는 SFU가 잘 맞을 수 있음
    • 오디오 코덱, RTCP 메시지, 데이터 채널, 녹화, 스트림별 정책을 한곳에 둘 수 있음
    • 클라이언트-대-AI 제품에서도 신호 처리, 미디어 라우팅, 녹화, 관측성, 사람에게 인계하거나 참여자를 추가하는 향후 확장을 한 시스템에서 재사용할 수 있어 기본 출발점이 되기 쉬움
  • OpenAI의 워크로드

    • OpenAI의 대부분 세션은 사용자 1명과 모델 1개, 또는 애플리케이션 1개와 실시간 에이전트 1개가 대화하는 1:1 세션
    • 이 트래픽 형태는 매 턴 지연에 민감하기 때문에 transceiver 모델을 선택함
    • transceiver 모델에서는 WebRTC edge 서비스가 클라이언트 연결을 종료한 뒤, 미디어와 이벤트를 모델 추론, 전사, 음성 생성, 도구 사용, 오케스트레이션을 위한 단순한 내부 프로토콜로 변환함
    • transceiver는 ICE 연결 검사, DTLS 핸드셰이크, SRTP 암호화 키, 세션 수명주기를 포함한 WebRTC 세션 상태를 소유하는 유일한 서비스임
    • 세션 상태를 한곳에 두면 세션 소유권을 이해하기 쉬워지고, 백엔드 서비스는 WebRTC 피어처럼 동작하지 않고 일반 서비스처럼 확장할 수 있음

초기 구현과 Kubernetes에서 부딪힌 제약

  • OpenAI의 첫 구현은 Pion 기반의 단일 Go 서비스였으며, 신호 처리와 미디어 종료를 모두 담당함
  • 이 transceiver 서비스는 ChatGPT voice, Realtime API의 WebRTC endpoint, 여러 연구 프로젝트를 구동함
  • 운영상 transceiver는 signaling에서 SDP 협상, 코덱 선택, ICE 자격 증명, 세션 설정을 처리함
  • media에서는 downstream WebRTC 연결을 종료하고, 추론과 오케스트레이션을 위한 backend 서비스와 upstream 연결을 유지함
  • OpenAI는 이 서비스를 수요 변화에 따라 확장·축소되고 호스트 사이를 이동할 수 있는 Kubernetes 위에서 운영하려 했음
  • 기존의 세션당 포트 1개 WebRTC 모델은 Kubernetes 환경과 맞지 않았으며, 큰 공개 UDP 포트 범위를 노출·보안·유지해야 했음
  • 높은 동시성에서 세션당 포트 1개는 매우 큰 UDP 포트 범위를 노출하고 관리해야 함
  • 클라우드 로드밸런서와 Kubernetes 서비스는 서비스당 수만 개의 공개 UDP 포트를 전제로 설계되지 않았고, 포트 범위가 늘어날수록 로드밸런서 설정, 헬스체크, 방화벽 정책, 롤아웃 안전성이 복잡해짐
  • 큰 UDP 포트 범위는 외부에서 도달 가능한 표면을 넓히고 네트워크 정책 감사를 어렵게 만들어 보안에도 불리함
  • Kubernetes에서는 pod가 계속 추가, 제거, 재스케줄링되므로 각 pod가 크고 안정적인 포트 범위를 예약·광고해야 하면 탄력성이 취약해짐

단일 포트와 세션 소유권 문제

  • 많은 WebRTC 시스템은 포트 수 문제를 줄이기 위해 서버당 단일 UDP 포트와 애플리케이션 수준 역다중화를 사용함
  • 서버당 단일 포트 설계는 포트 수를 줄이지만, fleet 전체에서 각 세션의 소유권을 보존해야 하는 두 번째 문제를 만듦
  • ICE와 DTLS는 상태가 있는 프로토콜이므로 세션을 만든 프로세스가 해당 세션의 패킷을 계속 받아야 연결 검사를 검증하고, DTLS 핸드셰이크를 완료하고, SRTP를 복호화하고, ICE restart 같은 이후 세션 변경을 처리할 수 있음
  • 같은 세션의 패킷이 다른 프로세스에 도착하면 설정이 실패하거나 미디어가 깨질 수 있음
  • OpenAI의 목표는 공개 인터넷에 작고 고정된 UDP 표면만 노출하면서도 모든 패킷을 해당 WebRTC 세션을 소유한 transceiver로 라우팅하는 것이었음
  • 검토한 접근

    • 세션별 고유 IP:port는 직접 클라이언트-서버 미디어 경로를 제공하고 데이터 경로에 포워딩 계층이 없지만, 세션당 공개 UDP 포트 1개가 필요하고 큰 포트 범위가 Kubernetes·클라우드 로드밸런서·보안에 맞지 않음
    • 서버별 고유 IP:port는 세션별 노출보다 공개 UDP footprint가 훨씬 작고 한 공유 소켓이 많은 세션을 역다중화할 수 있지만, 공유 로드밸런싱 fleet 전체에서는 첫 패킷이 잘못된 인스턴스에 도착할 수 있어 세션을 소유한 프로세스로 결정적으로 보내는 방법이 필요함
    • TURN relay는 클라이언트가 TURN relay 주소와 포트에만 도달하면 되고 edge에서 정책을 중앙화할 수 있지만, TURN allocation이 설정 왕복을 추가하고 TURN 서버 사이에서 allocation 이동이나 복구가 여전히 어려움
    • stateless forwarder + stateful terminator인 OpenAI의 relay + transceiver 구조는 작은 공개 UDP footprint를 유지하고 transceiver가 전체 WebRTC 세션을 소유하지만, 미디어가 소유 transceiver에 도달하기 전 forwarding hop이 하나 추가되고 relay와 transceiver 사이의 맞춤 조정이 필요함

relay + transceiver 아키텍처

  • OpenAI가 배포한 구조는 패킷 라우팅프로토콜 종료를 분리함
  • 신호 처리는 세션 설정을 위해 transceiver에 도달하고, 미디어는 먼저 relay로 들어감
  • relay는 작은 공개 footprint를 가진 경량 UDP forwarding 계층이며, transceiver는 그 뒤에 있는 상태 있는 WebRTC endpoint임
  • relay는 미디어를 복호화하지 않고, ICE 상태 머신을 실행하지 않으며, 코덱 협상에도 참여하지 않음
  • relay는 목적지를 고르기에 충분한 패킷 metadata만 읽고, 세션을 소유한 transceiver로 패킷을 전달함
  • transceiver는 여전히 정상적인 WebRTC 흐름을 보고 모든 프로토콜 상태를 소유함
  • 클라이언트 관점에서는 WebRTC 세션이 바뀌지 않음

첫 패킷 라우팅과 ICE ufrag 활용

  • 이 구조의 핵심은 relay가 패킷 경로 자체에서 첫 클라이언트 패킷을 라우팅하는 것임
  • WebRTC 세션에는 이미 프로토콜 네이티브 라우팅 훅이 있으며, 이것이 ICE username fragment, 즉 ufrag
  • ufrag는 세션 설정 중 교환되고 STUN 연결 검사에 다시 실리는 짧은 식별자임
  • OpenAI는 server-side ufrag에 relay가 목적지 cluster와 소유 transceiver를 추론할 수 있을 만큼의 라우팅 metadata를 담도록 생성함
  • signaling 중 transceiver는 세션 상태를 할당하고 SDP answer에 공유 relay VIP와 UDP port를 반환함
  • VIP는 relay fleet 앞단의 가상 IP 주소이며, port와 결합해 여러 relay 인스턴스 뒤에서도 클라이언트에 203.0.113.10:3478 같은 단일 안정 목적지를 제공함
  • 클라이언트의 첫 media-path 패킷은 보통 STUN binding request이며, ICE는 이를 사용해 광고된 주소에 패킷이 도달할 수 있는지 검증함
  • relay는 첫 STUN 패킷에서 server ufrag를 읽고, 라우팅 힌트를 해독하고, 세션을 소유한 transceiver로 패킷을 전달할 만큼만 파싱함
  • 각 transceiver는 세션당 소켓 하나가 아니라 내부 IP:port에 바인딩된 운영체제 endpoint인 공유 UDP 소켓에서 수신함
  • relay가 클라이언트 source IP:port에서 transceiver 목적지까지의 세션을 만들면, 이후 DTLS, RTP, RTCP 패킷은 ufrag를 다시 해독하지 않고 그 세션 안에서 흐름
  • relay의 세션은 packet forwarding을 위한 in-memory session, monitoring counter, session 만료와 정리를 위한 timer만 가진 최소 상태로 유지됨
  • relay가 재시작되어 세션을 잃어도 다음 STUN 패킷이 ufrag 라우팅 힌트로 세션을 다시 만듦
  • 경로가 설정되면 Redis cache가 <client IP + Port, transceiver IP + Port> mapping을 보관해 다음 STUN 패킷이 오기 전에도 더 이른 복구가 가능함

Global Relay와 가까운 진입 경로

  • 공개 UDP 표면을 작고 안정적인 주소·포트 수로 줄인 뒤, OpenAI는 같은 relay 패턴을 전 세계에 배포할 수 있었음
  • Global Relay는 같은 packet-forwarding 동작을 구현하는 지리적으로 분산된 relay ingress point fleet임
  • 넓은 지리적 ingress는 사용자의 패킷이 먼 region까지 공용 인터넷을 먼저 가로지르지 않고, 지리와 네트워크 topology상 가까운 relay에서 OpenAI 네트워크로 들어오게 해 첫 client-to-OpenAI hop을 줄임
  • 이 방식은 트래픽이 backbone에 도달하기 전의 지연, 지터, 피할 수 있는 loss burst를 낮춤
  • OpenAI는 signaling에 Cloudflare geo와 proximity steering을 사용해 초기 HTTP 또는 WebSocket 요청이 가까운 transceiver cluster에 도달하게 함
  • 요청 context가 세션 위치와 클라이언트에 광고할 Global Relay ingress point를 결정함
  • SDP answer는 Global Relay 주소를 제공하고, ufrag는 Global Relay가 지정 cluster로 media를 라우팅하고 relay가 목적지 transceiver로 라우팅할 수 있는 충분한 정보를 담음
  • geo-steered signaling과 Global Relay를 함께 사용하면 setup과 media 모두 가까운 entry path에 놓이면서도 세션은 하나의 transceiver에 고정됨
  • 이 구조는 signaling과 첫 ICE 연결 검사의 왕복 시간을 줄여 사용자가 말하기 시작하기까지 기다리는 시간을 직접 줄임

relay 구현 방식

  • relay 서비스는 Go로 작성됐고, 의도적으로 구현 범위를 좁게 유지함
  • Linux에서는 kernel networking stack이 네트워크 인터페이스에서 UDP packet을 받아 socket으로 전달하고, relay는 userspace의 일반 Go process로 socket에서 packet header를 읽음
  • relay는 소량의 flow state를 업데이트하고 WebRTC를 종료하지 않은 채 패킷을 전달함
  • OpenAI는 userspace process가 더 높은 packet rate를 위해 network queue를 직접 polling하는 kernel-bypass framework를 사용하지 않았으며, 그 방식은 운영 복잡성을 추가할 수 있다고 판단함
  • 주요 설계 선택

    • 프로토콜 종료 없음: relay는 STUN header와 ufrag만 파싱하고, 이후 DTLS, RTP, RTCP에는 cached state를 사용해 packet을 opaque하게 유지함
    • 일시적 상태: flow state와 관측성을 위해 client address에서 transceiver destination으로 가는 작고 짧은 timeout의 in-memory map을 유지함
    • 수평 확장성: 여러 relay instance가 load balancer 뒤에서 병렬로 실행되며, relay state가 hard WebRTC state가 아니므로 재시작 시 traffic drop이 작고 flow recovery가 빠름
  • 효율화 조치

    • SO_REUSEPORT는 여러 relay worker가 같은 machine에서 같은 UDP port에 bind할 수 있게 하는 Linux socket option이며, kernel이 들어오는 packet을 worker들에 분배해 단일 read loop 병목을 피함
    • runtime.LockOSThread는 각 UDP-reading goroutine을 특정 OS thread에 고정함
    • SO_REUSEPORT와 thread pinning을 함께 쓰면 같은 flow의 packet이 같은 CPU core에 머무는 경향이 있어 cache locality가 좋아지고 context switching이 줄어듦
    • pre-allocated buffer와 최소 복사는 parsing과 allocation overhead를 낮춰 Go의 garbage collection을 피하는 데 도움을 줌
    • 이 구현은 비교적 작은 relay footprint로 OpenAI의 global real-time media traffic을 처리했기 때문에, OpenAI는 kernel bypass 경로를 택하지 않고 더 단순한 설계를 유지함

결과와 교훈

  • 이 아키텍처는 수천 개 UDP 포트를 노출하지 않고 Kubernetes에서 WebRTC media를 실행할 수 있게 함
  • 작고 고정된 UDP 표면은 보안과 load balancing을 더 쉽게 만들고, 큰 공개 포트 범위를 예약하지 않고도 infrastructure가 확장될 수 있게 함
  • 이 설계는 client의 표준 WebRTC 동작을 보존하고, OpenAI 워크로드에서 SFU 없는 설계가 기본값으로 적절했음을 확인함
  • 대부분 세션은 point-to-point이고 지연에 민감하며, inference service가 WebRTC peer처럼 동작하지 않을 때 더 쉽게 확장됨
  • 복잡성은 모든 backend service나 custom client behavior가 아니라 얇은 routing layer에 두는 것이 더 적합했음
  • protocol-native field에 routing metadata를 encoding하면서 결정적 first-packet routing, 작은 공개 UDP footprint, 전 세계 사용자 가까이에 ingress를 둘 수 있는 유연성을 얻음
  • 특히 중요했던 선택

    • edge에서 protocol semantics 보존: client는 계속 표준 WebRTC를 사용하므로 browser와 mobile interoperability가 유지됨
    • 어려운 session state를 한곳에 유지: transceiver가 ICE, DTLS, SRTP, session lifecycle을 소유하고 relay는 packet만 전달함
    • setup에 이미 있는 정보로 routing: ICE ufrag가 hot-path lookup dependency 없이 first-packet routing hook을 제공함
    • kernel bypass보다 common case 최적화 우선: SO_REUSEPORT, thread pinning, low-allocation parsing을 신중히 사용한 좁은 Go 구현만으로 OpenAI 워크로드에 충분했음
    • 실시간 음성 AI는 infrastructure가 지연을 느껴지지 않게 만들 때 동작하며, OpenAI는 client가 WebRTC에 기대하는 동작을 바꾸지 않고 WebRTC 배포 형태를 바꾸는 방식을 택함
Hacker News 의견들
  • OpenAI가 내가 작업하는 라이브러리 Pion 사용 사례를 공개해 줘서 매우 고마움
    WebRTC를 잘 모른다면 꽤 재미있는 분야이고, 작동 방식을 설명하는 책 WebRTC for the Curious도 작업 중임
    https://github.com/pion/webrtc
    https://webrtcforthecurious.com

    • Pion을 쓰고 있음. 그런데 OpenAI의 접근이 정말 필요했는지 궁금함
      음성 AI 구성에서 이미 빠른 축에 속하는 부분을 줄이려고 복잡도를 엄청 늘린 것처럼 보였음. 빠른 모델과 정확한 음성 활동 감지(VAD) 가 WebRTC 전송 시간을 미세 조정하는 것보다 훨씬 중요해 보임
    • 책 전체를 온라인에 올려줘서 고마움
      예전에 WebRTC 데이터 채널로 데이터베이스에서 브라우저 클라이언트로 CLI를 통해 데이터를 보내는 아이디어가 있어서 일부를 읽었는데, 내 용도에는 잘 맞지 않겠다는 걸 이해하게 됨. 결국 중앙화된 제어 평면과 WebSocket을 썼음
      그래도 WebRTC 데이터 채널 + 복사 없는 Apache Arrow ArrayBuffer + duckdb WASM 조합으로 뭔가 재미있는 걸 할 수 있을 것 같은데, 아직 뭘 할지는 못 찾았음
    • 약간 다른 얘기지만, 전체 코드베이스를 중첩된 src 폴더가 아니라 루트 디렉터리에 두는 이유가 뭔지 궁금함
      README로 가기가 훨씬 어려워짐
  • 낮은 지연 시간은 구현 방식상 장점이라기보다 고통에 가까움
    가볍게 대화하려고 하면 사람은 자연스럽게 잠깐 멈추는데, GPT는 그걸 “말이 끝났다”고 받아들이고 바로 떠들기 시작함
    나이가 들면서 원하는 단어를 찾는 데 시간이 더 걸리는데, 이런 빠른 음성 GPT는 도움보다 짜증이 더 큼. 말하기 전에 머릿속에서 문장 전체를 다 생각해 놓아야 해서 전혀 자연스럽지 않음

    • 여기에는 서로 다른 두 층위의 지연 시간이 섞여 있음
      글에서 말하는 지연은 오디오 스트림 자체의 전송 지연이고, 이 상황에서의 지연은 오디오 스트림 안에서 얼마나 빨리 응답을 시작하느냐에 가까움
    • 나도 겪어봤고 정말 성가심
      생각이 아직 끝나지 않았는데도 계속 말해야 한다는 압박이 생겨서 꽤 부자연스럽게 느껴짐. 적절한 단어를 찾는 중이라면 그걸 찾을 기회가 필요함
      해결책은 더 높은 지연 시간의 프로토콜이 아니라 멈춤을 더 똑똑하게 처리하는 쪽이라고 봄. 지연이 낮으면 사용자가 끼어들었을 때 봇이 즉시 말을 멈출 수 있음
    • 음성 대화에서는 특정 코드 워드를 쓰기 전까지는 아예 답하지 말거나 “알겠습니다”만 말하라고 시킴
      완벽하진 않지만 덜 끼어듦
    • 이건 글에서 말한 지연 시간보다 음성 활동 감지(VAD) 와 더 관련이 큼
    • 어려운 문제임. 봇이 떠들지 못하게 하려고 나도 모르게 필러 표현을 덧붙이게 됨
      또 대부분의 지능을 문제를 생각하는 데 쓰기보다 그럴듯하게 들리는 데 쓰는 것 같음. “네, 물론이죠. 왜 그렇게 원하시는지 이해합니다…” 같은 식임. 아마 시간 제한이 있고 음성 처리가 더 비싸서 그런 듯함. 텍스트 응답은 작업 자체에 더 많은 시간을 씀
  • “주간 활성 사용자 9억 명 이상”은 당연히 ChatGPT 전체 사용자 수를 말하는 것 같고, 그중 음성 기능을 쓰는 비율은 훨씬 작지 않을까 싶음
    이런 수치는 문제에 어느 정도의 하드웨어와 소프트웨어 최적화를 투입할지 같은 사업 판단에 영향을 줌

    • 맞음. 그래서 “reach”라는 표현을 쓴 듯함
      실제 사용 여부와 무관하게 기능에 노출될 수 있는 전체 사용자 수를 뜻함
  • 공유해 주는 건 정말 반갑지만, OpenAI의 실시간 오디오 모델은 아직 능력 면에서 4o 계열에 머물러 있다는 점을 기억해야 함
    그래도 여전히 매우 유용하고, 이 분야에 실질적인 경쟁자가 없다는 게 아쉬움. 실제 대화 같은 경험은 아이디어와 개념을 표현하는 데 큰 도움이 됐음
    출시 당시와 달리 지금은 최전선 모델이 아니라는 점은 염두에 둘 만함. Sam이 이걸 본다면 새 실시간 오디오 모델을 내줬으면 좋겠음

    • OpenAI의 realtime/voice mode에서 음성 부분은 훌륭하지만, 최신 모델에 비하면 꽤 멍청하고 종종 같은 말을 반복함
      Google의 Gemini flash live 3.1이 더 낫고, 특히 API로 쓰면 좋음. 도구 호출도 가능하고, 직접 구성하면 더 똑똑한 다른 LLM에도 연결할 수 있으며, 추론 수준도 설정 가능함. 높은 추론 수준도 실시간에 충분히 가깝고, Google 검색 기반으로 답변을 보강할 수 있음. 양방향 음성을 좋아한다면 지금은 아마 최고의 선택지이고, AI Studio에서 시험해 볼 수 있음
  • 이 분야에 들어오려는 사람이라면 pipecat이 좋은 오픈소스 저장소이자 커뮤니티임
    https://github.com/pipecat-ai/pipecat

  • 더 좋은 모델이 더 많이 생각한 뒤 답한다면 응답을 더 오래 기다려도 괜찮음
    다만 끼어들기를 잘 지원하고, 1초 멈췄다고 바로 답하기 시작하지 않으며, 내가 말을 끝냈는지 똑똑하게 판단해야 함

  • 이건 단순히 지연 시간만의 문제가 아닐 수도 있음
    사용자를 음성 대화에 머물게 하면 텍스트로는 절대 얻지 못할 학습 데이터를 얻을 수 있음. 그래서 SFU보다 트랜시버 방식을 택하고 다자간 대화를 대부분 무시해도 괜찮았던 걸까 싶음

  • OpenAI가 이제 WebRTC/오디오에 LiveKit을 쓰지 않는다는 뜻으로 읽어도 되는 건가?

    • 그렇게 보임
      이 아키텍처에는 LiveKit 서버가 딱히 원하는 형태가 아닐 것 같음. 글의 SFU 논의에서도 사실상 그렇게 말하고 있음. 다만 클라이언트 SDK에는 유용한 것들이 많음
  • 스트림 도중 트랜시버가 크래시하면 활성 세션은 어떻게 복구될까?
    시스템이 새 WebRTC 세션에서 컨텍스트를 자동으로 다시 수립하나?

  • 친구를 만들고 싶다면 어떤 형태로든 동호회나 모임에 들어가는 편이 더 낫다고 봄