텍스트-음성 변환 모델을 50ms 미만 응답으로 만든 방법
Qwen3-TTS 1.7B CustomVoice를 단일 NVIDIA H100에서 서빙하여 초당 10건의 요청(RPS)을 처리하면서도 p95 첫 오디오 지연시간(TTFA) 50ms 미만을 달성한 오픈소스 구현을 소개한 글이다. 선행 무음 제거와 코덱 프레임 누적 튜닝을 통해 기존 vLLM-Omni, SGLang-Omni, VoxServe 등 대비 가장 낮은 지연시간을 확보했으며, 비용도 백만 자당 약 2달러로 ElevenLabs(100달러)나 Cartesia(49달러)보다 훨씬 저렴하다.
TL;DR: 저희의 Qwen3-TTS 1.7B CustomVoice 구현은 단일 NVIDIA H100 SXM에서 초당 10건의 요청(RPS)을 처리하면서 p95 첫 오디오까지의 시간(TTFA) 50ms 미만을 달성하고 실시간 재생을 유지합니다. 저희는 Poisson 개방형 루프 트래픽 환경에서 다섯 가지 구현체(저희 것, vLLM-Omni, SGLang-Omni△, VoxServe, M*)를 비교했습니다. 각 구현체를 저지연 스트리밍에 맞게 튜닝한 후, 저희 구현만이 유일하게 p95 TTFA 50ms 미만을 달성했습니다. 저희는 10 RPS까지 p95 TTFA 50ms 미만을 유지하며, 20 RPS에서도 100ms 이하를 유지합니다. 저희 시스템은 10 RPS에서 초당 약 630자를 생성합니다. 1× H100 SXM 인스턴스가 시간당 4.29달러이므로, full utilization 기준 백만 자당 약 2달러로 환산됩니다. 비교하자면 ElevenLabs V3는 백만 자당 100달러, Cartesia Sonic 3.5는 더 높은 TTFA에서 백만 자당 49달러입니다. 저희는 구현체와 벤치마크를 오픈소스로 공개합니다. 방법론은 아래에 설명합니다.
"실시간" TTS 정의하기 실시간 TTS 서버가 달성해야 할 것을 논의해 보겠습니다. 네 부분으로 구성된 문제라고 생각합니다:
- 낮은 가청 TTFA: 요청 전송부터 첫 가청 샘플까지의 시간이 짧아야 합니다.
- 언더런 없음: 재생이 시작되면 클라이언트의 버퍼가 소진되지 않아야 합니다.
- 용량: RPS가 증가해도 1과 2가 유지되어야 합니다.
- 정상 출력: 음성이 명확하게 이해 가능해야 합니다.
Qwen3-TTS CustomVoice 1.7B는 허용적인 라이선스를 가진 가장 인기 있는 TTS 모델 중 하나이기 때문에 선택했습니다. 위 정의에 따라 단일 NVIDIA H100 SXM에서 높은 RPS를 유지하면서 언더런 없이 낮은 p95 가청 TTFA를 목표로 했습니다. 모든 벤치마크는 Fireworks AI의 LLM 벤치마크를 따라 실제 워크로드에 근접하도록 Poisson 개방형 루프 트래픽에서 5분간 실행됩니다. 각 엔진은 전체 텍스트를 단일 HTTP 요청으로 받고, 오디오 출력은 스트리밍됩니다. 가청 TTFA를 감지하고, 수신된 PCM으로 재생을 재구성하며, 완성된 오디오를 Deepgram STT로 평가합니다.
다른 엔진들의 성능은? 아래 표는 각 엔진의 1 RPS에서 업스트림/기본 결과입니다. 이 실행에서는 호환성을 위한 변경만 적용했습니다.
| 엔진 | p95 가청 TTFA | p95 선행 무음 | 언더런 발생 요청 | | vLLM-Omni | 277.883 ms | 90 ms | 100% | | SGLang-Omni△ | 1,140.69 ms | 80 ms | 0% | | VoxServe | 315.064 ms | 30 ms | 0% | | M* | 1,159.956 ms | 90 ms | 0% |
이 기본값들은 개선 여지가 상당합니다. 저희는 각 서빙 엔진을 자체적인 지연시간, 연속성, 품질, 용량 요구사항에 맞게 튜닝했습니다.
선행 무음 제거 모델이 반환하는 첫 PCM에는 첫 지속 사운드 이전에 수십 밀리초의 무음이 포함될 수 있습니다. 이 간극은 가청 TTFA를 이만큼 뒤로 밀어냅니다. 저희는 동적 트림을 추가했습니다. 짧은 RMS 윈도우에서 지속 음성을 감지하고, 시작점 이전의 샘플을 제거한 뒤 나머지 오디오를 정상적으로 스트리밍합니다. 이 변경으로 TTFA가 약 80ms 개선되지만 모델 추론 자체를 빠르게 하지는 않습니다.
프레임 누적 튜닝 또한 디코딩 및 오디오 청크 릴리스 전에 수집할 코덱 프레임 수를 튜닝했습니다. 초기 청크가 작으면 TTFA는 줄지만 재생 여유 버퍼가 줄어들고 디코더 작업이 더 자주 발생합니다. 청크가 크면 배칭이 쉽고 연속 재생이 안전해지지만 첫 가청 출력이 지연됩니다. 따라서 유용한 구성은 작은 청크로 시작해 이후 출력에는 청크 크기를 늘리는 것입니다. 정확한 설정값은 엔진마다 다릅니다. vLLM-Omni는 codec_chunk_frames와 codec_chunk_ramp 같은 설정을 제공하며, 다른 엔진들도 동등한 청크 또는 스트라이드 제어를 제공합니다. 저희는 이 값들을 반복 탐색하며 낮은 p95 TTFA, 언더런 없음, 부하 증가 시 안정적 동작에 가장 부합하는 설정을 찾았습니다.
기존 서빙 엔진 튜닝 후 성능 다음 표는 선행 무음 및 프레임 누적 튜닝 후 각 엔진의 언더런 없는 프로파일 결과입니다.
| 엔진 | p95 TTFA (1 RPS) | p95 TTFA (6 RPS) | | vLLM-Omni | 56.815 ms | 93.451 ms | | SGLang-Omni△ | 120.879 ms | 273.700 ms | | VoxServe | 49.3 ms | 363.2 ms | | M* | 104.035 ms | 179.501 ms |
VoxServe는 1 RPS에서 p95 TTFA 50ms 미만을 달성하지만, 다른 엔진들은...