실시간 음성 상호작용을 서비스에 얹을 때 프로토타입과 실전은 완전히 다르다. API 비용은 예상보다 빨리 바닥을 치고, 로컬에서는 잘 돌던 음성 지연 문제가 서버에 올리면 터진다. 중소규모 스타트업 환경에서 무작정 API만 호출하면 배보다 배꼽이 더 커진다. 프로덕션 환경에서 인프라를 안정화하는 현실적인 방법을 정리했다.
불필요한 API 호출 차단하기
대화가 없는 묵음 구간에도 API가 돌면 토큰 비용은 계속 나간다. VAD(Voice Activity Detection) 엔진을 파이프라인 앞단에 붙여서 데이터 흐름을 끊어야 한다.
테스트 결과, TEN VAD는 메모리를 306KB만 점유하고 실시간 계수(RTF) 0.0150을 기록했다. Silero VAD는 무음 감지 과정에서 수백 밀리초 지연이 생겨 실시간 서비스에 부적합하다. 다음 과정을 따라해라.
- 파이프라인 최전단에 VAD를 배치하고 오디오 데이터를 160 샘플(10ms 프레임) 단위로 쪼개서 분석한다.
- 호출 패턴을 10분 단위로 로그에 남겨 묵음 구간 데이터 흐름을 강제로 차단한다.
- API 호출 비용이 설정한 임계치를 넘으면 서킷 브레이커가 작동해 호출을 멈추고 Slack으로 바로 알림을 보낸다.
이 구조를 잡으면 불필요한 재귀 호출이 줄어들어 운영 비용을 30%까지 아낄 수 있다.
컨테이너 네트워크 오버헤드 줄이기
초저지연 성능을 내려면 네트워크 통신 비용을 최소화해야 한다. 도커 컨테이너 기본 브리지 모드는 NAT 변환 과정에서 패킷당 15~50μs 지연을 일으킨다. 성능이 중요한 오디오 라우터 노드라면 무조건 호스트 네트워크 모드(--network host)를 써라.
프레임워크 내부 데이터 전송 비용은 아래 설정으로 깎아낸다.
- 통신 스키마를 manifest.json 파일에 박아넣어 동적 형식 검증 로직을 뺀다.
- 네트워크 품질에 맞춰 오디오 버퍼 크기를 20ms 단위로 슬라이딩한다.
- 지터 수준이 5ms 이하라면 샘플링 레이트를 48kHz로 올리고 버퍼를 10~20ms 사이로 유지한다.
이렇게 하면 불필요한 병목이 사라져 사용자가 느끼는 응답 속도를 200ms 줄일 수 있다.
세션 유지와 배포 전략
사용자가 늘어나면 대화 컨텍스트가 꼬이는 일이 흔하다. 개별 세션을 독립적인 그래프 인스턴스로 격리하고 데이터는 외부로 빼야 한다.
- 사용자별 대화 기록은 Redis 클러스터로 넘긴다.
- Redis 파이프라인으로 데이터를 저장하고 TTL(만료 시간)을 30분으로 걸어 메모리를 비운다.
- 사용자가 말을 가로채면 TEN Turn Detection이 버퍼에 쌓인 이전 답변을 즉시 지운다.
쿠버네티스로 넘길 때는 리소스 할당이 중요하다. 무중단 배포를 위해 Deployment 매니페스트에서 maxUnavailable을 0으로 둔다.
- 파드 하나당 최소 2 vCPU, 4Gi 메모리를 요청하고 최대 4 vCPU, 8Gi 메모리로 리미트를 걸어 CPU 쓰로틀링을 막는다.
- 파드 종료 시 preStop 훅에 45초를 걸어 통화 세션이 자연스럽게 끝나게 한다.
- terminationGracePeriodSeconds를 120초로 늘려 강제 세션 종료를 방지한다.
Datadog LLM Observability로 성능 저하를 실시간으로 찍어보면서 이 수치들을 미세 조정하면 된다.
