Orpheus TTS - Benchmark com Continuous Batching
Data: 2024-12-25 GPU: NVIDIA RTX 4090 (24GB VRAM) Modelo: canopylabs/orpheus-3b-0.1-ft (3B parametros)
Resumo
Implementamos e testamos Continuous Batching com vLLM AsyncLLMEngine para o Orpheus TTS, conseguindo 12x mais capacidade comparado ao uso sequencial.
Resultados do Teste de Stress
| Requests Simultaneos | Taxa Sucesso | Tempo Wall-Clock | Audio Gerado | RTF | Usuarios Real-Time |
|---|---|---|---|---|---|
| 4 | 100% | 2.93s | 11.61s | 0.253 | 4.0 |
| 8 | 100% | 2.94s | 22.78s | 0.129 | 7.8 |
| 12 | 100% | 3.13s | 34.05s | 0.092 | 10.9 |
| 16 | 100% | 4.03s | 50.77s | 0.079 | 12.6 |
Comparacao
| Metodo | RTF | Usuarios Real-Time | Melhoria |
|---|---|---|---|
| Sequencial (orpheus_tts lib) | 0.85 | ~1 | baseline |
| Continuous Batching (4 req) | 0.253 | 4.0 | 4x |
| Continuous Batching (16 req) | 0.079 | 12.6 | 12x |
Otimizacoes Ativas (vLLM 0.13.0)
- Flash Attention 2
- Chunked Prefill
- Prefix Caching
- CUDA Graphs
- torch.compile
Configuracao do Engine
engine_args = AsyncEngineArgs(
model="canopylabs/orpheus-3b-0.1-ft",
dtype="bfloat16",
max_model_len=4096,
gpu_memory_utilization=0.9,
max_num_seqs=16, # Continuous batching
enable_chunked_prefill=True,
enable_prefix_caching=True,
enforce_eager=False,
)
Problema com a Biblioteca orpheus_tts
A biblioteca oficial orpheus_tts tem um bug onde o engine vLLM morre apos a primeira inferencia (EngineDeadError). A solucao e usar o AsyncLLMEngine do vLLM diretamente.
Formato do Prompt Orpheus
# Tokens especiais
START_TOKEN = 128259
END_TOKENS = [128009, 128260, 128261, 128257]
STOP_TOKEN = 128258
AUDIO_TOKEN_BASE = 128266
# Formato do prompt
prompt = f"{voice}: {text}"
# Depois adiciona os tokens especiais
Decodificacao de Audio (SNAC)
Os tokens de audio sao organizados em frames de 7 tokens:
- Layer 0: offset 0
- Layer 1: offset 4096 (2 tokens por frame)
- Layer 2: offset 8192, 12288, etc. (4 tokens por frame)
Latencia TTFT (Time-To-First-Token)
Medimos a latencia ate o primeiro chunk de audio ser gerado:
| Requisicoes Simultaneas | TTFT (min) | TTFT (max) | TTFF* (avg) |
|---|---|---|---|
| 1 (sequencial) | 12ms | 12ms | 63ms |
| 4 | 12ms | 28ms | 81ms |
| 8 | 12ms | 29ms | 82ms |
| 12 | 14ms | 32ms | 85ms |
| 16 | 16ms | 38ms | 93ms |
*TTFF = Time to First Frame (7 tokens = ~23ms de audio playable)
Conclusao: Mesmo com 16 requisicoes simultaneas, cada usuario recebe o primeiro chunk de audio em menos de 100ms - imperceptivel para o usuario!
Tecnicas de Otimizacao Utilizadas
1. Continuous Batching
Permite processar multiplas requisicoes simultaneamente na mesma GPU. Em vez de processar uma requisicao por vez (sequencial), o vLLM agrupa varias requisicoes e as processa em paralelo.
max_num_seqs=16 # Ate 16 requisicoes simultaneas
2. Chunked Prefill + Prefix Caching
- Chunked Prefill: Divide o processamento do prompt em chunks menores, permitindo intercalar prefill de novas requisicoes com a geracao de tokens de requisicoes existentes
- Prefix Caching: Reutiliza computacoes de prefixos comuns entre requisicoes (como tokens especiais do Orpheus)
enable_chunked_prefill=True
enable_prefix_caching=True
Teste de Limite Maximo (max_num_seqs=256)
Testamos ate onde a RTX 4090 aguenta com frases curtas identicas:
| Users | Sucesso | TTFF Max | RTF |
|---|---|---|---|
| 32 | 100% | 116ms | 0.154 |
| 64 | 100% | 136ms | 0.125 |
| 128 | 100% | 228ms | 0.091 |
| 200 | 100% | 335ms | 0.284 |
| 256 | 100% | 413ms | 0.244 |
Resultado: 256 usuarios simultaneos sem erros, TTFF < 500ms.
Teste Realista de Streaming (frases variadas)
Testamos com frases de tamanhos variados (curtas, medias, longas) para simular uso real:
| Users | Max Gap | RTF Max | Streaming com buffer 500ms |
|---|---|---|---|
| 32 | 86ms | 3.67 | OK |
| 64 | 105ms | 4.51 | OK |
| 100 | 139ms | 5.98 | OK |
| 128 | 160ms | 6.88 | OK |
| 200 | 232ms | 9.80 | OK |
| 256 | 375ms | 11.78 | OK |
Conclusao do teste realista:
- Com buffer de ~500ms no cliente: ate 256 usuarios funcionam sem travamento
- Sem buffer (streaming puro): ~12-16 usuarios com RTF < 1.0
- Para aulas de idiomas com avatar: recomendado usar buffer no cliente
Arquivos
scripts/orpheus_continuous_batching.py- Script de teste de continuous batchingscripts/orpheus_stress_test.py- Teste de stress com 4/8/12/16 usuariosscripts/orpheus_ttft_test.py- Teste de latencia TTFTscripts/orpheus_max_users_test.py- Teste de limite maximo de usuariosscripts/orpheus_streaming_test.py- Teste realista de streaming com frases variadas
Conclusao
Com Continuous Batching + Chunked Prefill + Prefix Caching, uma unica RTX 4090 pode suportar:
Streaming puro (sem buffer):
- ~12-16 usuarios com RTF < 1.0
- 12x melhoria sobre o metodo sequencial
- <100ms latencia para primeiro audio
Com buffer de 500ms no cliente:
- Ate 256 usuarios simultaneos sem travamento
- Max gap entre frames: 375ms (coberto pelo buffer)
- Ideal para aplicacoes de avatar interativo e aulas de idiomas
Recomendacao: Para aulas de idiomas, usar buffer de ~500ms no cliente para suportar mais usuarios.