� Speech-to-Speech Avatar Microservices Architecture
Arquitetura de microserviços para testar e medir latência em pipeline completo de conversação com avatar (Speech-to-Text → LLM → Text-to-Speech → Avatar Animation).
📋 Visão Geral
Este projeto implementa uma arquitetura de microserviços independentes para simular e testar um sistema completo de conversação com avatar digital. Cada serviço pode ser desenvolvido, testado e escalado independentemente.
Pipeline de Conversação:
Audio → Whisper (STT) → LLM → TTS → MuseTalk → Video
🏗️ Arquitetura
┌─────────────────────────────────────────────────────────┐
│ Gateway (Port 8080) │
│ Orchestrates all services & metrics │
└───────────┬─────────────────────────────────────────────┘
│
┌───────┴───────┬────────────┬────────────┐
│ │ │ │
┌───▼────┐ ┌────▼─────┐ ┌──▼───┐ ┌────▼──────┐
│Whisper │ │ LLM │ │ TTS │ │ MuseTalk │
│ (STT) │ │ │ │ │ │ (Avatar) │
│Port │ │Port 5002 │ │Port │ │Port 5004 │
│5001 │ │ │ │5003 │ │ │
└────────┘ └──────────┘ └──────┘ └───────────┘
📦 Microserviços
| Serviço | Porta | Função | Latência Mock |
|---|---|---|---|
| Gateway | 8080 | Orquestra pipeline, métricas | - |
| Whisper | 5001 | Speech-to-Text | ~75ms |
| LLM | 5002 | Geração de respostas | ~250ms |
| TTS | 5003 | Text-to-Speech | ~125ms |
| MuseTalk | 5004 | Avatar Animation | ~125ms |
Latência Total Esperada: ~575ms
🚀 Instalação e Execução
⚠️ Importante para VAST.ai, VST.ai e Cloud GPU
Se você está usando VAST.ai, RunPod, VST.ai ou qualquer plataforma cloud GPU, use APENAS a Opção 2 (Execução Local).
Por quê?
- ❌ Docker-in-Docker NÃO funciona nesses ambientes
- ✅ Scripts Python rodam DIRETAMENTE sem Docker
- ✅ Mais rápido e com menos overhead
Opção 1: Docker Compose (Para desenvolvimento local)
# 1. Clonar repositório
git clone <repo-url>
cd webrtc-latency-test
# 2. Iniciar todos os serviços
docker-compose up -d
# 3. Verificar status
docker-compose ps
# 4. Ver logs
docker-compose logs -f
# 5. Parar serviços
docker-compose down
Opção 2: Execução Local (Recomendado para VST.ai / Runpod)
# 1. Clonar repositório (se necessário)
cd webrtc-latency-test
# 2. Iniciar todos os serviços
./start-all.sh
# 3. Verificar serviços
curl http://localhost:8080/health
# 4. Parar serviços
./stop-all.sh
Vantagens da Execução Local:
- ✅ Funciona em ambientes containerizados (VST.ai, Runpod, etc.)
- ✅ Não requer Docker instalado
- ✅ Mais leve e rápido para desenvolvimento
- ✅ Cada serviço roda em seu próprio processo Python
- ✅ Logs individuais em
/tmp/*.log
🧪 Testando o Sistema
Teste de Conversação Completa
# Enviar audio para o pipeline completo
curl -X POST http://localhost:8080/conversation \
-H "Content-Type: application/json" \
-d '{
"audio_data": "base64_encoded_audio_here",
"user_id": "test_user_123"
}'
Resposta esperada:
{
"transcript": "Olá, como você está?",
"llm_response": "Estou muito bem, obrigado por perguntar!",
"audio_data": "base64_audio_data",
"video_data": "base64_video_data",
"latency_ms": {
"whisper": 75,
"llm": 250,
"tts": 125,
"musetalk": 125,
"total": 575
}
}
Teste de Latência Automatizado
# Executar 10 requisições e calcular estatísticas
python3 test_latency.py
# Resultados salvos em latency_results.json
cat latency_results.json
Exemplo de resultado:
{
"total_requests": 10,
"successful_requests": 10,
"failed_requests": 0,
"avg_latency_ms": 575.2,
"min_latency_ms": 571.8,
"max_latency_ms": 580.1,
"breakdown": {
"whisper_avg": 75.1,
"llm_avg": 250.3,
"tts_avg": 125.0,
"musetalk_avg": 124.8
}
}
Verificar Métricas
# Métricas de todos os serviços
curl http://localhost:8080/metrics
Testar Serviços Individualmente
# Whisper (STT)
curl -X POST http://localhost:5001/transcribe \
-H "Content-Type: application/json" \
-d '{"audio_data": "base64_audio"}'
# LLM
curl -X POST http://localhost:5002/generate \
-H "Content-Type: application/json" \
-d '{"text": "Olá"}'
# TTS
curl -X POST http://localhost:5003/synthesize \
-H "Content-Type: application/json" \
-d '{"text": "Olá, tudo bem?"}'
# MuseTalk
curl -X POST http://localhost:5004/generate \
-H "Content-Type: application/json" \
-d '{"audio_data": "base64_audio"}'
📁 Estrutura do Projeto
webrtc-latency-test/
├── README.md # Este arquivo
├── docker-compose.yml # Orquestração Docker
├── start-all.sh # Script para iniciar localmente
├── stop-all.sh # Script para parar serviços
├── test_latency.py # Teste automatizado de latência
│
├── gateway/ # Gateway Orchestrator
│ ├── main.py # API FastAPI
│ ├── requirements.txt # Dependências
│ └── Dockerfile # Container
│
├── services/ # Microserviços
│ ├── whisper/ # Speech-to-Text
│ │ ├── server.py # Mock Whisper
│ │ ├── requirements.txt
│ │ └── Dockerfile
│ │
│ ├── llm/ # Large Language Model
│ │ ├── server.py # Mock LLM
│ │ ├── requirements.txt
│ │ └── Dockerfile
│ │
│ ├── tts/ # Text-to-Speech
│ │ ├── server.py # Mock TTS
│ │ ├── requirements.txt
│ │ └── Dockerfile
│ │
│ └── musetalk/ # Avatar Animation
│ ├── server.py # Mock MuseTalk
│ ├── requirements.txt
│ └── Dockerfile
│
├── shared/ # Código compartilhado
│ └── proto/ # Protocol Buffers (futuro)
│ ├── whisper.proto
│ ├── llm.proto
│ ├── tts.proto
│ └── musetalk.proto
│
└── docs/
└── ARCHITECTURE.md # Documentação detalhada
🔄 Substituindo Mocks por Implementações Reais
Cada serviço mock pode ser substituído independentemente:
1. Whisper (Speech-to-Text)
# services/whisper/server.py
import whisper
model = whisper.load_model("base")
@app.post("/transcribe")
async def transcribe(request: TranscribeRequest):
# Decodificar audio
audio = decode_audio(request.audio_data)
# Transcrever com Whisper real
result = model.transcribe(audio)
return {"transcript": result["text"]}
2. LLM (Large Language Model)
# services/llm/server.py
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("gemma-2b")
tokenizer = AutoTokenizer.from_pretrained("gemma-2b")
@app.post("/generate")
async def generate(request: GenerateRequest):
inputs = tokenizer(request.text, return_tensors="pt")
outputs = model.generate(**inputs)
response = tokenizer.decode(outputs[0])
return {"response": response}
3. TTS (Text-to-Speech)
# services/tts/server.py
from fish_audio import FishAudioTTS
tts = FishAudioTTS()
@app.post("/synthesize")
async def synthesize(request: SynthesizeRequest):
audio = tts.generate(request.text)
audio_b64 = encode_audio(audio)
return {"audio_data": audio_b64}
4. MuseTalk (Avatar Animation)
# services/musetalk/server.py
from musetalk import MuseTalkPipeline
pipeline = MuseTalkPipeline()
@app.post("/generate")
async def generate(request: GenerateRequest):
audio = decode_audio(request.audio_data)
video = pipeline.generate(audio)
video_b64 = encode_video(video)
return {"video_data": video_b64}
� Benchmarks de Latência
Latências Esperadas (Implementação Real)
| Serviço | Mock | Real (GPU) | Real (CPU) |
|---|---|---|---|
| Whisper | 75ms | 50-150ms | 200-500ms |
| LLM | 250ms | 100-300ms | 500-2000ms |
| TTS | 125ms | 100-200ms | 300-800ms |
| MuseTalk | 125ms | 80-150ms | 500-1500ms |
| Total | ~575ms | 330-800ms | 1500-4800ms |
Otimizações para Reduzir Latência
- Streaming Pipeline: Processar em chunks ao invés de esperar resposta completa
- GPU Acceleration: Usar CUDA para Whisper, LLM, TTS e MuseTalk
- Model Optimization: Quantização, pruning, distillation
- Caching: Cache de respostas frequentes (LLM, TTS)
- Batch Processing: Processar múltiplas requisições juntas
- Edge Deployment: Deploy próximo ao usuário
�️ Desenvolvimento
Adicionar Novo Serviço
# 1. Criar diretório
mkdir -p services/novo-servico
# 2. Criar server.py
cat > services/novo-servico/server.py << 'EOF'
from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn
app = FastAPI()
class Request(BaseModel):
data: str
@app.post("/process")
async def process(request: Request):
# Sua lógica aqui
return {"result": "processed"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=5005)
EOF
# 3. Criar requirements.txt
echo "fastapi==0.104.1
uvicorn==0.24.0
pydantic==2.5.0" > services/novo-servico/requirements.txt
# 4. Criar Dockerfile
cat > services/novo-servico/Dockerfile << 'EOF'
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY server.py .
CMD ["python", "server.py"]
EOF
# 5. Adicionar ao docker-compose.yml
Logs e Debug
# Logs de serviço específico
docker-compose logs -f whisper
docker-compose logs -f gateway
# Logs locais
tail -f /tmp/whisper.log
tail -f /tmp/gateway.log
# Acessar container
docker-compose exec whisper /bin/bash
docker-compose exec gateway /bin/bash
� Segurança e Produção
Para deploy em produção, adicionar:
- Autenticação (JWT, API Keys)
- Rate limiting
- HTTPS/TLS
- Input validation robusta
- Logging estruturado
- Monitoring (Prometheus, Grafana)
- Health checks avançados
- Circuit breakers
- Retry policies
📈 Monitoramento
# Health check de todos os serviços
curl http://localhost:8080/health
# Métricas detalhadas
curl http://localhost:8080/metrics | jq
# Status individual
curl http://localhost:5001/health
curl http://localhost:5002/health
curl http://localhost:5003/health
curl http://localhost:5004/health
� Solução de Problemas
Serviço não inicia
# Verificar portas em uso
lsof -ti:5001 -ti:5002 -ti:5003 -ti:5004 -ti:8080
# Matar processos
pkill -f "python.*server.py"
# Reiniciar
./stop-all.sh
./start-all.sh
Docker não conecta serviços
# Verificar rede Docker
docker network ls
docker network inspect webrtc-latency-test_default
# Recriar containers
docker-compose down -v
docker-compose up -d --build
Latência muito alta
- Verificar logs de cada serviço
- Testar serviços individualmente
- Verificar recursos (CPU, RAM, GPU)
- Verificar rede entre containers
📚 Documentação Adicional
- Arquitetura Detalhada
- API Reference (em breve)
- Deployment Guide (em breve)
🎯 Próximos Passos
- Implementar streaming pipeline (chunks)
- Adicionar WebSocket para real-time
- Implementar Whisper real
- Integrar LLM (Gemma, LLaMA)
- Integrar Fish Audio TTS
- Integrar MuseTalk completo
- Adicionar frontend web
- Deploy em Kubernetes
- Adicionar monitoramento (Prometheus/Grafana)
📝 Licença
MIT License
🤝 Contribuições
Contribuições são bem-vindas! Abra uma issue ou pull request.
Desenvolvido para testar arquitetura de microserviços para conversação com avatar digital 🎯🤖