Communitygithub.com

TTS Local

Genera voz con sonido humano localmente en tu propia GPU (o CPU) sin coste de API — locuciones, narración para vídeos explicativos, lectura de texto en voz alta, clips de audio a partir de texto — además de subtítulos .srt sincronizados a partir de las marcas de tiempo conocidas de cada línea.

¿Qué es TTS Local?

La habilidad **Local TTS** permite generar voz de alta calidad de forma completamente local, utilizando el modelo **Qwen3-TTS 1.7B** en formato GGUF de 8 bits a través de `qwentts.cpp`, sin necesidad de conexión a internet ni costes de API. Está diseñada para casos de uso como locuciones para vídeos explicativos, narración de tutoriales, lectura en voz alta de documentos o generación de clips de audio para proyectos multimedia (HyperFrames, fframes, Remotion, etc.). La voz por defecto, llamada `aiden`, ha ganado pruebas ciegas de escucha frente a otros modelos como Kokoro, Chatterbox o VoxCPM2, y ofrece una velocidad de generación de ~4x tiempo real en una GPU de 8 GB. Además, la habilidad incluye generación automática de subtítulos .srt sincronizados con el audio, soporta múltiples opciones de configuración (altavoz, estilo, semilla, silencios) y ofrece un proceso de actualización continua para buscar y probar modelos TTS locales más nuevos y mejores. Funciona en Linux, macOS y Windows (con soporte CUDA, Vulkan o CPU), y requiere unos 2.5 GB de disco para los pesos del modelo. Es ideal para cualquier tarea que necesite voz sintética antes de recurrir a APIs de pago o a voces de baja calidad integradas.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Ayushmaniar/claude-explainer-skills/tree/HEAD/plugins/explainer-skills/skills/local-tts

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace TTS Local?

La voz por defecto: Qwen3-TTS 1.7B CustomVoice, altavoz aiden, 8-bit GGUF (Q8_0), ejecutado por qwentts.cpp (C++/ggml, MIT) con esta instrucción de estilo:

Cálida, clara y curiosa, como un narrador amigable de vídeos explicativos de tecnología. Ritmo relajado y constante.

Ganó una prueba de escucha ciega contra Kokoro, Chatterbox, PyTorch Qwen3-TTS, VoxCPM2 y Phonon (consulta references/benchmarks.md). En una GPU de portátil RTX 4070 de 8 GB funciona a ~4x tiempo real incluyendo la carga del modelo: una narración de 18 minutos tarda ~4.5 minutos.

Configuración (una vez por máquina)

Ejecuta python -I <skill>/scripts/say.py --check primero. Si imprime OK, omite esta sección. De lo contrario, configura el motor, o pide al usuario que lo haga. Tarda entre 10 y 20 minutos y requiere ~2.5 GB de disco.

  1. Compilar qwentts.cpp. No existe un binario precompilado para Windows, así que compílalo desde el código fuente:
    git clone --recurse-submodules https://github.com/ServeurpersoCom/qwentts.cpp ~/tools/qwentts.cpp
    cd ~/tools/qwentts.cpp
    ./buildcuda.sh       # NVIDIA (Linux); ./buildvulkan.sh para AMD/Intel; ./buildcpu.sh solo CPU (p. ej. macOS)
    
    En Windows, instala las Herramientas de compilación de VS 2022 (o superior) con la carga de trabajo de C++, CMake, Ninja y el CUDA Toolkit, luego ejecuta buildcuda.cmd desde el repositorio. Si vcvars64.bat está en otra ubicación, edita la ruta al inicio de ese script. Para apuntar solo a una GPU, añade -DCMAKE_CUDA_ARCHITECTURES=89 (RTX 40xx; 86 = RTX 30xx, 120 = RTX 50xx) a la línea de cmake.
  2. Descargar los pesos (~2 GB) desde Hugging Face Serveurperso/Qwen3-TTS-GGUF:
    pip install -U huggingface_hub
    hf download Serveurperso/Qwen3-TTS-GGUF qwen-talker-1.7b-customvoice-Q8_0.gguf qwen-tokenizer-12hz-Q8_0.gguf --local-dir ~/tools/qwen-gguf
    
  3. Apuntar say.py a ellos si usaste otras carpetas: configura QWEN_TTS_HOME (el checkout), QWEN_TTS_EXE (el binario) o QWEN_TTS_MODELS (la carpeta .gguf). En Windows, say.py añade %CUDA_PATH%\bin\x64 al PATH por ti (sobrescribe con CUDA_BIN).
  4. say.py --check de nuevo, luego genera una línea de prueba.

Hardware: 8 GB de VRAM son suficientes para Q8_0 (~3 GB en uso). Sin GPU, una compilación para CPU funciona aproximadamente a un cuarto de la velocidad. GGML_BACKEND=CPU fuerza una compilación para GPU a ejecutarse en la CPU.

Antes de generar

  1. ¿Hay algo más usando la GPU? Un juego u otra aplicación pesada de GPU hace la generación ~4x más lenta y hace que esa aplicación se entrecorte. Pregunta antes de comenzar un trabajo largo. Si el usuario nombra tales aplicaciones, establece TTS_BUSY_APPS=app1,app2 y say.py advierte cuando una está en ejecución.
  2. ¿Vale la pena comprobar un modelo más nuevo? Consulta "Sigue buscando mejores modelos" más abajo. Si la última comprobación tiene más de ~6 semanas y la tarea es una narración real (no una prueba de una línea), haz el escaneo rápido primero.
  3. ¿El texto suena humano? Una voz lee el lenguaje de IA con la misma entonación cada vez, por lo que el patrón resalta más que en una página. Para cualquier narración de más de unas pocas líneas, lee natural-narration.md de la habilidad whiteboard-explainer (mismo plugin, references/) y ejecuta su scripts/aispeak_scan.py, que acepta un script.py o un archivo de texto plano.

Generar

El script usa solo la biblioteca estándar, por lo que cualquier Python 3.10+ funciona. <skill> es la carpeta de esta habilidad.

python -I <skill>/scripts/say.py "Primera línea." "Segunda línea." -o salida.wav       # un WAV, espacios de 0.35 s
python -I <skill>/scripts/say.py --file lineas.txt -o clips/                    # 000.wav, 001.wav, ...

Opciones:

IndicadorQué hace
--speakeraiden (predeterminado); ryan es la otra voz nativa en inglés
--instructTexto de estilo, p. ej. "Emocionado, rápido" o "Tranquilo y serio"
--seed NDa una toma repetible
--gap SSegundos de silencio entre líneas en un archivo unido
--srt FTambién escribe subtítulos sincronizados con el WAV unido (consulta Subtítulos)
--quantQ8_0 (predeterminado, mejor) o Q4_K_M (más pequeño, un poco más plano; descárgalo primero)
--checkInforma del motor, modelos y carpetas CUDA encontrados

Cómo funciona:

  • Cada línea pasa por un solo proceso, por lo que el modelo se carga una vez (3–8 s). Pasa las líneas en bloque, no una llamada por línea.
  • La salida es WAV mono de 24 kHz, 16 bits.

Las tomas se muestrean, por lo que cada ejecución difiere:

  • Conserva los clips que te gusten. Caché por línea, clave por texto más configuración.
  • Vuelve a tomar una línea si su duración se aleja mucho de ~0.07 s por carácter. Eso significa que se omitieron o inventaron palabras.

Para una narración de vídeo, además:

  • Recorta el silencio de cada clip a ~50 ms de relleno, luego coloca las líneas en la línea de tiempo con tus propios espacios.
  • Normaliza el volumen de la pista final: ffmpeg -af loudnorm=I=-16:TP=-1.5:LRA=11.

Subtítulos (.srt): ofrécelos con cada vídeo narrado

Ya sabes cuándo comienza y termina cada línea, por lo que no hay nada que transcribir. Construye los subtítulos a partir de esas marcas de tiempo.

  • Con say.py: añade --srt narracion.srt (necesita un .wav con -o). Los subtítulos coinciden exactamente con la pista unida.
  • En tu propio pipeline: llama a scripts/srt.py, to_srt([(inicio_s, fin_s, texto), ...], display=[...]), con inicio/fin en tiempo de vídeo por línea hablada. O usa la CLI: python srt.py marcas.tsv -o video.srt.
  • Corrige las ortografías de voz. El texto de la narración suele estar escrito para la voz: "D I L", nombres reescritos fonéticamente, "punto HTML de ejecutor", números en palabras. Mapea de vuelta con display / --display display.tsv (habladoescrito). Toma las formas escritas de lo que se muestra en pantalla, y usa cifras para los números ("$232", "83%").
  • Verifica el resultado. Búscalo con grep en busca de mayúsculas espaciadas restantes ([A-Z] [A-Z]) y " punto ".
  • Reglas que aplica el módulo:
    • como máximo 2 líneas de 42 caracteres por subtítulo
    • divide en oración, luego cláusula, luego palabra
    • oraciones cortas fusionadas para que nada pase rápido
    • tiempo compartido en proporción a la duración
  • Nómbralo como el vídeo (Nombre del Video.srt junto a Nombre del Video.mp4) para que los reproductores lo carguen automáticamente. En VLC, --sub-file= fuerza un archivo.

El template/narration/build_vo.py de la habilidad whiteboard-explainer es un pipeline de trabajo completo: caché por línea, retomas, recorte de silencios, modelado de pausas, alineación de palabras, una tabla de señales y una envolvente de sincronización labial.

Problemas comunes

  • Los DLL de CUDA deben estar en PATH (Windows). CUDA 13 los mantiene en ...\CUDA\v13.x\bin\x64. Sin esa carpeta en PATH, qwen-tts.exe sale silenciosamente sin salida. say.py lo añade por ti.
  • --stream-by-line -o - escribe cabeceras WAV en streaming (tamaños 0x7fffffff), una por línea. Divide en RIFF....WAVEfmt y descarta cada cabecera de 44 bytes. No confíes en los campos de tamaño.
  • Aiden lee mal letras individuales y tokens extraños. Encontrado por una auditoría no solicitada de Whisper:
    • "h estrella" salió como "un hap" o "nuestra estrella", "y t" como "VT", "y" como "nosotros", y "arXiv" como "ArcSireFolk".
    • Estos funcionan: "H mayúscula estrella" / "bajo H", "por qué tee" / "por qué tilde", "archivo", y "verificación SMILES".
    • "aitch" es errático. Un nombre puede estar bien solo y distorsionado en medio de una oración: pruébalo dentro de toda la línea.
    • Una K al inicio de la oración puede caerse ("Kwenputer" → "When Pooter"): comienza esas líneas con "Y" o "Entonces".
    • Audita transcribiendo cada clip sin el guión como aviso inicial, luego compara con el guión. Un Whisper con aviso "oye" las palabras previstas y oculta los errores. Herramientas: whiteboard-explainer/template/narration/audit_vo.py y tts_try.py.
  • Pausas en dos puntos. Qwen pausa 0.6-0.8 s en un dos puntos y a veces en medio de una frase. En una narración, limita cada silencio por la puntuación anterior (shape() en el build_vo.py de la plantilla) y evita líneas fragmentadas por dos puntos ("Primero: ...").
  • Respaldo de CPU: Kokoro 82M (kokoro-onnx) es plano pero rápido en CPU, bueno para borradores mientras la GPU está ocupada.

Sigue buscando mejores modelos

El TTS local está mejorando rápidamente, y la elección actual será superada. Trátalo como el campeón actual, no la respuesta final. Busca modelos más nuevos y mejores, especialmente antes de un gran trabajo de narración, o cuando la última comprobación a continuación tenga más de ~6 semanas.

  1. Escanea. Busca en la web modelos TTS de pesos abiertos publicados o actualizados desde la última comprobación. Mira en:
    • TTS Arena / tablas de clasificación de voz de Artificial Analysis
    • Modelos de conversión de texto a voz en tendencia de Hugging Face
    • r/LocalLLaMA
    • Lanzamientos de GitHub de los motores a continuación
  2. Filtra. Mantén un candidato solo si:
    • se puede usar localmente de forma gratuita (pesos abiertos, licencia permisiva o de uso personal)
    • funciona en la memoria GPU y sistema operativo del usuario
    • habla el idioma necesario
    • supera al campeón en calidad, o lo iguala siendo mucho más rápido
  3. Prueba. Genera eval/lineas.txt con el candidato. Puntúalo contra el campeón con scripts/voice_metrics.py (pip install numpy librosa; las grabaciones del campeón y la línea base están en eval/):
    • Desviación estándar del tono ≥ ~5 semitonos y rango ≥ ~17 semitonos son necesarios para sonar natural.
    • Mide la velocidad como segundos de audio por segundo de generación.
  4. Escucha. Pide al usuario que elija de oído entre el candidato y eval/campeon_*.wav (ffplay -nodisp -autoexit archivo.wav). Las métricas solo preseleccionan candidatos; el oído decide.
  5. Registra. Actualiza la línea "Última comprobación" a continuación y references/benchmarks.md, tanto si algo cambió como si no. Si el campeón cambia, reemplaza eval/campeon_*.wav y actualiza say.py, y pregunta antes de eliminar el modelo antiguo.

Última comprobación: 2026-11-02 (encuesta web más pruebas locales de VoxCPM2 Q8 y Phonon 31m/Miles). Aiden fue preferido de oído sobre ambos. Aún no probados localmente: Phonon 40m, OmniVoice, Breeze TTS 2, Drama 3, Orpheus, Dia, Sesame CSM, Spark-TTS, IndexTTS-2, VibeVoice, Higgs Audio, Kyutai TTS y Fish/OpenAudio. Los detalles están en references/benchmarks.md.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills relacionados