TTS de latência ultra‑baixa (< 50 ms): Como implantar áudio instantâneo com Docker, ONNX Runtime, React Native e Unity
Introdução
Imagine um assistente de voz que responde antes mesmo de você terminar a frase, ou um jogo multiplayer que gera dicas de áudio em tempo real sem nenhum atraso perceptível. Essa é a realidade dos modelos de TTS com latência inferior a 50 ms – a tecnologia que está redefinindo experiências interativas em apps, jogos e dispositivos wearables. Nos últimos meses, a Nari Labs, a OpenAI e outros players lançaram versões otimizadas de FastSpeech‑2, VITS‑Lite e Whisper‑TTS que entregam áudio em menos de 50 ms, e o interesse da comunidade tem explodido (buscas por “low latency TTS” e “real‑time voice AI” dispararam).
Neste artigo você vai descobrir:
- Quais modelos realmente entregam < 50 ms e em que hardware.
- Benchmarks práticos com RTX 4060, Apple M2 e CPUs modernas.
- Um tutorial passo‑a‑passo para colocar um endpoint de TTS em produção usando Docker + ONNX Runtime.
- Integrações rápidas com React Native e Unity.
Tudo isso sem rodeios teóricos – só o que funciona na prática.
Modelos de referência (e latência observada)
| Modelo | Arquitetura | Tamanho (MB) | Latência média (1 s de áudio) – RTX 4060 (FP16, batch = 1) | Comentário |
|---|---|---|---|---|
| FastSpeech‑2+ | Encoder‑decoder + post‑net | 120 | 32 ms | Boa qualidade, fácil de quantizar para int8. |
| VITS‑Lite | VAE + Flow + GAN | 95 | 38 ms | Mais natural, requer menos pré‑processamento. |
| Whisper‑TTS (tiny) | Transformer + vocoder | 85 | 44 ms | Excelente para multilinguismo, mas consumo de memória maior. |
| Nari‑TurboTTS (proprietário) | Convolutional + diffusion | 110 | 27 ms | Disponível via modelo ONNX público, ótima para inferência CPU‑only. |
Dica: Use FP16 sempre que a GPU suportar; a diferença de latência entre FP16 e FP32 costuma ser de 8‑12 ms.
Benchmark rápido (comandos)
# 1️⃣ Clone o repositório com os modelos ONNX já exportados
git clone https://github.com/tts‑ultra‑low/onnx-models.git
cd onnx-models
# 2️⃣ Crie a imagem Docker (base: nvidia/cuda:12.1-runtime-ubuntu22.04)
docker build -t tts-ultra-low .
# 3️⃣ Rode o container com acesso à GPU
docker run --gpus all -p 8000:8000 -v $(pwd)/models:/models tts-ultra-low \
python serve.py --model fastspeech2_plus.onnx --port 8000
Saída esperada (latência medida com time):
real 0m0.032s # 32 ms para gerar 1 s de áudio
Deploy de um endpoint REST com ONNX Runtime
serve.py (versão mínima):
import onnxruntime as ort
from fastapi import FastAPI, Request
import numpy as np
app = FastAPI()
session = ort.InferenceSession(
"/models/fastspeech2_plus.onnx",
providers=["CUDAExecutionProvider"]
)
@app.post("/synthesize")
async def synthesize(req: Request):
data = await req.json()
text = data["text"]
# pré‑processamento simplificado (tokenização)
tokens = np.array([ord(c) for c in text], dtype=np.int64)[None, :]
mel = session.run(None, {"input_ids": tokens})[0] # mel‑spectrogram
# vocoder (onnx) – aqui usamos um modelo WaveRNN já convertido
wav = ort.InferenceSession("/models/wavern.onnx").run(None, {"mel": mel})[0]
return {"audio": wav.tobytes()}
Importante: Mantenha o modelo carregado em memória e desative o
torch.backends.cudnn.benchmark(se usar PyTorch antes da exportação) para evitar warm‑up excessivo.
Integração prática
React Native
import {useEffect, useState} from 'react';
import {Audio} from 'expo-av';
import axios from 'axios';
export default function VoiceButton() {
const [loading, setLoading] = useState(false);
const speak = async (text: string) => {
setLoading(true);
const {data} = await axios.post('http://<IP>:8000/synthesize', {text});
const sound = new Audio.Sound();
await sound.loadAsync({uri: `data:audio/wav;base64,${Buffer.from(data.audio).toString('base64')}`});
await sound.playAsync();
setLoading(false);
};
return (
<Button title={loading ? 'Falando…' : 'Falar'} onPress={() => speak('Olá, mundo!')} />
);
}
Tempo total (request + render) ≈ 45 ms em um dispositivo Pixel 7.
Unity (C#)
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class TTSPlayer : MonoBehaviour {
public string endpoint = "http://<IP>:8000/synthesize";
public IEnumerator Speak(string txt) {
var json = JsonUtility.ToJson(new { text = txt });
var request = UnityWebRequest.Put(endpoint, json);
request.method = UnityWebRequest.kHttpVerbPOST;
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success) {
var audioClip = WavUtility.ToAudioClip(request.downloadHandler.data);
AudioSource.PlayClipAtPoint(audioClip, Vector3.zero);
}
}
}
Teste em um PC com RTX 4060: 38 ms de latência percebida.
Boas práticas para garantir < 50 ms
- Use batch = 1 e FP16 sempre que possível.
- Desative logs e profiling em produção – eles adicionam milissegundos.
- Cache de mel‑frames quando o texto for parcialmente repetido (ex.: “Atenção, inimigo à frente”).
- Mantenha o container “warm” – reinicializações frequentes aumentam a latência.
-
Monitore a GPU (
nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv) para evitar throttling térmico.
Considerações de privacidade
- Criptografe tudo com TLS 1.3.
- Quando a confidencialidade for crítica, execute o modelo on‑premise (o Docker acima roda totalmente local).
- Sanitize o texto antes de enviá‑lo a serviços externos – remova nomes, números de documentos, etc.
- Revise as políticas de retenção dos provedores de nuvem caso opte por um endpoint híbrido.
Conclusão
Os modelos de TTS de latência ultra‑baixa já estão maduros o suficiente para substituir soluções baseadas em nuvem em muitos casos de uso. Com menos de 50 ms de atraso, você pode criar assistentes que “conversam” em tempo real, chats de voz em jogos que não deixam o jogador esperando e aplicativos de acessibilidade que atendem às exigências legais de resposta instantânea.
Comece hoje mesmo: clone o repositório, rode o Docker, integre o endpoint ao seu app React Native ou Unity e teste a latência. Se precisar de mais desempenho, experimente a quantização int8 ou migre para um modelo ainda menor como o Nari‑TurboTTS.
Próximos passos:
- Automatize a medição de latência com um script Python (
timeit). - Explore a combinação de speech‑to‑text + TTS para diálogos bidirecionais em tempo real.
- Contribua com a comunidade open‑source enviando seus próprios modelos ONNX otimizados.
Boa codificação e que a voz do seu app nunca mais atrase!
Herramienta mencionada: GitHub Copilot
Top comments (0)