개요
OpenAI는 대규모 저지연 음성 AI를 위해 WebRTC 스택을 재설계했고, 핵심은 relay + transceiver 분리 구조였습니다.
- 대부분의 세션은 1:1 대화라서 SFU보다 transceiver가 더 적합
- 공개 인터넷에는 작은 UDP 표면만 노출
- 세션 상태는 transceiver가 소유
- 전역 지연을 줄이기 위해 geo-steered signaling과 Global Relay를 사용
한 줄 요약
“클라이언트는 표준 WebRTC를 그대로 쓰고, OpenAI 내부에서만 패킷 라우팅과 세션 종료를 분리해 지연과 운영 복잡성을 동시에 낮췄다.”
왜 WebRTC인가
음성 AI는 말의 속도로 반응해야 하므로, 오디오가 연속 스트림으로 도착해야 합니다.
WebRTC는 다음을 표준화합니다.
- ICE를 통한 연결 수립과 NAT 통과
- DTLS/SRTP 암호화 전송
- 코덱 협상
- RTCP 품질 제어
- 에코 제거, 지터 버퍼링
즉, OpenAI는 저수준 미디어 스택을 새로 만들지 않고, 검증된 표준 위에 AI 인프라를 얹은 것입니다.
relay + transceiver
transceiver
- WebRTC 세션 상태를 소유
- ICE, DTLS, SRTP, 세션 수명주기까지 관리
- 모델 추론, 전사, 음성 생성, 도구 호출로 이어지는 내부 프로토콜을 담당
relay
- 경량 UDP 포워딩 계층
- 패킷을 해독하지 않음
- ICE 상태 머신도 돌리지 않음
- 목적지 transceiver로 첫 패킷을 라우팅하는 역할만 수행
이 구조의 목적은 작은 공개 포트 표면과 세션 소유권 유지를 동시에 만족시키는 것입니다.
핵심 라우팅 아이디어
OpenAI는 ICE username fragment, 즉 ufrag를 라우팅 힌트로 사용했습니다.
- 첫 STUN 패킷에서 ufrag를 읽음
- relay가 목적지 cluster와 transceiver를 판별
- 이후 패킷은 같은 세션 경로로 흐름
- relay가 죽어도 다음 STUN 패킷으로 세션 복구 가능
여기에 Redis cache와 Global Relay를 결합해, 가까운 진입 경로를 유지하면서도 세션은 하나의 transceiver에 고정했습니다.
Kubernetes 제약
기존의 세션당 UDP 포트 1개 방식은 Kubernetes와 잘 맞지 않았습니다.
- 너무 큰 공개 포트 범위가 필요함
- 로드밸런서, 헬스체크, 방화벽 정책이 복잡해짐
- pod 재스케줄링이 어려워짐
OpenAI는 그래서 서버별 단일 포트도 아닌 stateless relay + stateful terminator 조합을 선택했습니다.
의미
이 사례의 핵심은 음성 모델 자체보다 실시간 미디어를 대규모로 운영하는 방식입니다.
- 클라이언트 호환성은 유지
- 내부 라우팅만 재설계
- 작은 UDP 표면으로 보안과 운영성 개선
- 지연 민감 제품에 맞는 구조 선택