Retrato de Santiago Fernández

CubeLabs

IA · Fintech · Agentes · Automatización
🧠 IA

Speech-to-Speech: Agentes de Voz con IA

Construye agentes conversacionales locales con el pipeline VAD → STT → LLM → TTS de Hugging Face

⏱ 35 min 📊 Intermedio 📝 10 lecciones

Aprende a construir agentes de voz completos usando el framework speech-to-speech de Hugging Face. Este curso cubre el pipeline completo: detección de actividad de voz (VAD), transcripción a texto (STT), generación de respuestas con modelos de lenguaje (LLM), y síntesis de voz (TTS), todo con modelos open-source y ejecutable en local.

Speech-to-Speech Logo - Hugging Face

Contenido

  1. Introducción a los Agentes de Voz
  2. Arquitectura del Pipeline Speech-to-Speech
  3. Instalación y Primeros Pasos
  4. Voice Activity Detection (VAD) con Silero
  5. Speech-to-Text (STT): Parakeet, Whisper y alternativas
  6. Modelos de Lenguaje (LLM) para Respuestas
  7. Text-to-Speech (TTS) con Qwen3-TTS y alternativas
  8. Modo Realtime Server con API OpenAI
  9. Modo Local y Conexión por Socket
  10. Despliegue con Docker y Casos de Uso Reales

1. Introducción a los Agentes de Voz

Los agentes de voz son sistemas capaces de mantener conversaciones habladas con humanos. A diferencia de los chatbots tradicionales, procesan audio directamente: escuchan, entienden, razonan y responden con voz. Ejemplos conocidos incluyen Alexa, Siri y Google Assistant, pero hasta hace poco construir uno propio requería APIs cerradas y costosas.

El proyecto speech-to-speech de Hugging Face cambia eso: ofrece un pipeline open-source, modular y extensible que puedes ejecutar en tu propio hardware. Está compuesto por cuatro etapas encadenadas:

EtapaFunciónTecnología por defecto
VADDetectar cuándo el usuario hablaSilero VAD v5
STTConvertir audio a textoParakeet TDT / Whisper
LLMGenerar respuesta textualOpenAI-compatible / Transformers
TTSConvertir texto a vozQwen3-TTS / Kokoro

El pipeline se usa en producción dando voz a miles de robots Reachy Mini en Hugging Face. En este curso aprenderás a montarlo, configurarlo y desplegarlo paso a paso.

💡 Tip

Todo el stack es open-source. Puedes ejecutar el pipeline 100% local sin depender de ninguna API externa si tienes suficiente hardware (GPU recomendada).

2. Arquitectura del Pipeline Speech-to-Speech

El pipeline es una cascada de cuatro componentes que se ejecutan en hilos independientes comunicados por colas. Cada componente es completamente intercambiable mediante flags de línea de comandos.

Flujo de datos

[Micrófono] → [VAD] → [STT] → [LLM] → [TTS] → [Altavoz]
                 ↑                           ↓
            Buffer de audio           Buffer de audio

Detalle del flujo:

  1. VAD recibe chunks de audio en tiempo real y detecta los límites de las intervenciones del usuario (cuándo empieza y termina de hablar).
  2. STT toma el segmento de audio completo y lo transcribe a texto, con soporte para transcripciones parciales en vivo.
  3. LLM recibe el texto transcrito y genera una respuesta, que puede incluir llamadas a herramientas (tool calls).
  4. TTS sintetiza la respuesta textual en audio y lo envía al cliente.

Modos de ejecución

ModoTransporteCuándo usarlo
realtimeWebSocket (protocolo OpenAI Realtime)Construir apps o dispositivos contra una API de voz estándar
localMicrófono y altavoces del equipoHablar directamente con el pipeline, sin cliente adicional
websocketPCM raw sobre WebSocketCliente personalizado mínimo sin protocolo Realtime
socketPCM raw sobre TCPModelos en servidor remoto con cliente ligero
💡 Tip

El modo realtime es el más potente: sigue el protocolo OpenAI Realtime, lo que significa que cualquier cliente que hable ese protocolo puede conectarse a tu servidor self-hosted.

3. Instalación y Primeros Pasos

El framework requiere Python 3.10+ y se instala con un solo comando pip. Vamos a ponerlo en marcha:

Instalación básica

pip install speech-to-speech

Esto instala el pipeline con los backends por defecto:

Primer arranque (con API key de OpenAI)

export OPENAI_API_KEY="sk-..."
speech-to-speech

Esto inicia un servidor Realtime en ws://localhost:8765/v1/realtime usando Parakeet TDT para STT local, un LLM compatible con OpenAI y Qwen3-TTS para la salida de voz.

Hablar con el pipeline

Desde una segunda terminal, ejecuta el cliente integrado:

python scripts/listen_and_play_realtime.py --host 127.0.0.1 --port 8765
⚠️ Requisitos de hardware

Para una experiencia fluida necesitas al menos 8 GB de RAM y preferiblemente una GPU NVIDIA con CUDA 12+. En Apple Silicon (M1+) funciona muy bien con MLX. Sin GPU, el pipeline funcionará pero con mayor latencia.

Instalación desde fuente

git clone https://github.com/huggingface/speech-to-speech.git
cd speech-to-speech
uv sync

4. Voice Activity Detection (VAD) con Silero

El VAD es el primer componente del pipeline. Su trabajo es detectar cuándo una persona está hablando, determinar los límites de cada intervención y gestionar el turn-taking (quién habla en cada momento).

Silero VAD v5

El VAD por defecto es Silero VAD v5, un modelo pre-entrenado de alta calidad que funciona en CPU y GPU. Procesa el audio en chunks y devuelve una probabilidad de actividad de voz para cada uno.

Parámetros clave del VAD

ParámetroPor defectoDescripción
--thresh0.6Umbral de probabilidad para activar detección de voz
--min_speech_ms384Duración mínima de voz para considerarla intervención válida
--min_silence_ms64Silencio mínimo para segmentar intervenciones
--min_speech_continuation_ms192Histeresis para reabrir un turno que terminó hace poco
--unanswered_reopen_ms2000Tiempo máximo para reabrir un turno sin respuesta del asistente

Ajuste fino del VAD

speech-to-speech \
    --thresh 0.5 \
    --min_speech_ms 500 \
    --min_silence_ms 100 \
    --mode realtime
💡 Tip

Si el asistente interrumpe demasiado pronto, sube --thresh y --min_speech_ms. Si no detecta bien el final de tus frases, baja --min_silence_ms.

5. Speech-to-Text (STT): Parakeet, Whisper y alternativas

El STT convierte el audio segmentado por el VAD en texto. Es el puente entre el mundo del audio y el del lenguaje escrito.

Backends disponibles

BackendPlataformasIdiomasInstalación
Parakeet TDT (por defecto)CUDA / CPU (nano-parakeet), Apple Silicon (MLX)25 lenguas europeasBuilt-in
Whisper (Transformers)CUDA / CPUMultilingüeBuilt-in
Faster WhisperCUDA / CPUMultilingüe[faster-whisper]
Whisper MLXApple SiliconMultilingüe[whisper-mlx]
Paraformer (FunASR)CUDA / CPUChino[paraformer]

Usar Whisper como STT

speech-to-speech \
    --stt whisper \
    --stt_model_name openai/whisper-medium \
    --mode realtime

Transcripción en vivo

El pipeline soporta transcripciones parciales que se envían al cliente mientras el usuario sigue hablando. Se activa con el flag:

--enable_live_transcription
💡 Tip

Parakeet TDT es el backend más rápido en GPU. Si necesitas más precisión multilingüe, usa Whisper large-v3. Para Apple Silicon, Whisper MLX ofrece el mejor rendimiento.

6. Modelos de Lenguaje (LLM) para Respuestas

El LLM es el cerebro del pipeline: recibe el texto transcrito y genera una respuesta natural, incluyendo llamadas a herramientas si es necesario. Es el componente más intensivo en cómputo.

Backends de LLM

BackendUsoEjemplo
responses-apiAPI compatible con OpenAI Responses APIOpenAI, HF Inference Providers, vLLM
chat-completionsAPI /v1/chat/completionsvLLM, llama.cpp, OpenRouter
transformersInferencia local con TransformersModelos de Hugging Face Hub
mlx-lmInferencia local en Apple SiliconModelos cuantizados MLX

Ejemplo: LLM local con llama.cpp

Primero, sirve el modelo con llama.cpp:

llama-server -hf ggml-org/gemma-4-E4B-it-GGUF \
    -np 2 -c 65536 -fa on --swa-full

Luego, conecta el pipeline a ese servidor:

speech-to-speech \
    --model_name "ggml-org/gemma-4-E4B-it-GGUF" \
    --responses_api_base_url "http://127.0.0.1:8080/v1" \
    --responses_api_api_key "" \
    --responses_api_stream

Ejemplo: API de proveedor

speech-to-speech \
    --mode local \
    --llm_backend responses-api \
    --model_name "Qwen/Qwen3.5-9B:together" \
    --responses_api_base_url "https://router.huggingface.co/v1" \
    --responses_api_api_key "$HF_TOKEN" \
    --responses_api_stream \
    --enable_live_transcription
⚠️ Latencia

El LLM es el cuello de botella. Para baja latencia, usa modelos pequeños (gpt-4o-mini, Qwen3-4B) o servidores self-hosted con vLLM.

7. Text-to-Speech (TTS) con Qwen3-TTS y alternativas

El TTS convierte la respuesta textual del LLM en audio sintetizado. El pipeline ofrece múltiples backends de TTS, cada uno con diferentes perfiles de calidad, velocidad y requisitos de hardware.

Backends de TTS disponibles

BackendCalidadPlataformasInstalación
Qwen3-TTS (por defecto)⭐⭐⭐⭐⭐GGML/CUDA en Linux, MLX en macOSBuilt-in
Kokoro-82M⭐⭐⭐⭐CUDA/CPU, Apple Silicon[kokoro]
Pocket TTS⭐⭐⭐CPU/CUDA[pocket]
ChatTTS⭐⭐⭐⭐CUDA/CPU[chattts]
MMS TTS⭐⭐⭐CUDA/CPU[facebook-mms]

Usar Qwen3-TTS con parámetros personalizados

speech-to-speech \
    --tts qwen3 \
    --qwen3_tts_model_name Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice \
    --qwen3_tts_speaker Aiden \
    --qwen3_tts_language auto \
    --qwen3_tts_backend ggml \
    --qwen3_tts_non_streaming_mode True

Usar Kokoro-82M

pip install "speech-to-speech[kokoro]"
speech-to-speech --tts kokoro

Usar Pocket TTS con clonación de voz

speech-to-speech \
    --tts pocket \
    --pocket_tts_voice jean \
    --pocket_tts_device cpu
💡 Tip

Qwen3-TTS ofrece la mejor calidad con voces naturales y soporte multilingüe. Para clonación de voz, Pocket TTS es la mejor opción: acepta archivos de voz personalizados.

8. Modo Realtime Server con API OpenAI

El modo realtime expone el pipeline como un servidor WebSocket que implementa el protocolo OpenAI Realtime. Esto significa que cualquier cliente que hable ese protocolo — incluyendo el SDK oficial de OpenAI — puede conectarse a tu servidor self-hosted.

Arrancar el servidor Realtime

export OPENAI_API_KEY="sk-..."
speech-to-speech --mode realtime

Esto expone el endpoint ws://localhost:8765/v1/realtime.

Conectar con el SDK de OpenAI

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8765/v1",
    websocket_base_url="ws://localhost:8765/v1",
    api_key="not-needed",
)

with client.realtime.connect(model="local") as conn:
    conn.send({
        "type": "session.update",
        "session": {
            "type": "realtime",
            "instructions": "Eres un asistente de voz amigable y conciso."
        }
    })

    for event in conn:
        print(event.type)

Eventos del protocolo Realtime

El servidor implementa los eventos principales del protocolo:

DirecciónEventos
Cliente → Servidorinput_audio_buffer.append, session.update, conversation.item.create, response.create, response.cancel
Servidor → Clientespeech.start, speech.stop, transcripción parcial, audio.delta, tool_calls, response.done
💡 Tip

Este modo es ideal para integrar el agente de voz en aplicaciones web, robots o dispositivos IoT. Cualquier cliente OpenAI Realtime funciona sin modificaciones.

9. Modo Local y Conexión por Socket

El pipeline ofrece modos alternativos para diferentes escenarios de uso, desde una conversación directa en tu máquina hasta despliegues remotos con cliente ligero.

Modo Local: hablar directamente

Usa el micrófono y los altavoces de tu máquina para una conversación natural:

speech-to-speech --mode local

En Mac con Apple Silicon, usa la configuración optimizada:

speech-to-speech --local_mac_optimal_settings

Esto activa automáticamente:

Modo WebSocket: cliente personalizado

speech-to-speech --mode websocket --ws_host 0.0.0.0 --ws_port 8765

Los clientes envían audio PCM raw a 16 kHz, int16, mono y reciben audio generado.

Modo Socket: servidor remoto

En el servidor:

speech-to-speech --mode socket --recv_host 0.0.0.0 --send_host 0.0.0.0

En el cliente:

python scripts/listen_and_play.py --host <IP-del-servidor>
⚠️ Diferencia clave

El modo socket es minimalista: transmite PCM raw sin las características completas del protocolo Realtime (sin manejo de interrupciones, transcripción en vivo ni tool calls).

10. Despliegue con Docker y Casos de Uso Reales

El pipeline incluye Docker Compose para despliegues reproducibles. Además, se usa en producción a gran escala: es el backend conversacional de miles de robots Reachy Mini de Hugging Face.

Despliegue con Docker

Instala el NVIDIA Container Toolkit y ejecuta:

docker compose up

El compose inicia:

Casos de uso reales

CasoDescripciónModo recomendado
Robots conversacionalesReachy Mini, asistentes en feriasRealtime server
Asistente de voz en casaControl por voz, preguntas y respuestasLocal
Call center / IVRAuto-attendant con IAWebSocket / Realtime
Traducción simultáneaSpeech-to-speech multilingüeRealtime + language=auto
Juegos / VRNPCs con voz en tiempo realSocket (baja latencia)

Ejemplo completo: stack 100% local

# Terminal 1: llama.cpp con Gemma 4
llama-server -hf ggml-org/gemma-4-E4B-it-GGUF \
    -np 2 -c 65536 -fa on --swa-full

# Terminal 2: Pipeline con Gemma 4 local
speech-to-speech \
    --mode realtime \
    --stt parakeet-tdt \
    --llm_backend responses-api \
    --tts qwen3 \
    --model_name "ggml-org/gemma-4-E4B-it-GGUF" \
    --responses_api_base_url "http://127.0.0.1:8080/v1" \
    --responses_api_api_key "" \
    --responses_api_stream \
    --enable_live_transcription

# Terminal 3: Cliente Python
python scripts/listen_and_play_realtime.py \
    --host 127.0.0.1 --port 8765
💡 Tip

Este stack 100% open-source y local es ideal para prototipado y producción. Todos los modelos (Gemma 4, Parakeet, Qwen3-TTS) son gratuitos y se ejecutan en tu hardware.

❓ FAQ

¿Necesito GPU para ejecutar el pipeline?

No es estrictamente necesario, pero la experiencia es mucho mejor con GPU. En CPU, el TTS y el LLM tendrán latencia alta. En Apple Silicon (M1+) funciona bien con MLX. Para GPU NVIDIA, se recomienda CUDA 12+ y al menos 8 GB de VRAM.

¿Puedo usar solo modelos open-source sin ninguna API?

Sí. Usa --llm_backend transformers o sirve un modelo con llama.cpp/vLLM apuntando con --responses_api_base_url a tu servidor local. Todo el stack es open-source.

¿Qué latencia tiene el pipeline?

Depende del hardware y la configuración. En una GPU moderna con modelos pequeños (Qwen3-4B, Parakeet TDT, Qwen3-TTS) la latencia puede ser de 1-3 segundos. El cuello de botella suele ser el LLM.

¿Soporta varios idiomas?

Sí. El pipeline detecta el idioma automáticamente con --language auto si el backend STT lo soporta. Parakeet TDT cubre 25 lenguas europeas; Whisper cubre muchas más. El TTS con Qwen3-TTS es multilingüe.

¿Puedo añadir herramientas/funciones al LLM?

Sí. El protocolo OpenAI Realtime soporta tool_calls. Puedes definir herramientas que el LLM invoque durante la conversación, como buscar información, controlar dispositivos o ejecutar código.