informatica:inteligencia_artificial:tts
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| informatica:inteligencia_artificial:tts [2026/06/26 10:40] – [Entrenar COQUI TTS con XTTS] jose | informatica:inteligencia_artificial:tts [2026/07/04 00:03] (current) – jose | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Herramientas ====== | ||
| + | Para grabar voz mimic:\\ | ||
| + | https:// | ||
| + | |||
| + | Este es mas moderno: | ||
| + | https:// | ||
| + | |||
| + | docker run -it -p 8000:8000 -v " | ||
| + | |||
| + | Videos Youtube:\\ | ||
| + | https:// | ||
| + | |||
| + | |||
| ====== Español en Mac ====== | ====== Español en Mac ====== | ||
| git clone https:// | git clone https:// | ||
| Line 131: | Line 144: | ||
| python generar_voz.py entrada.txt salida.mp3 | python generar_voz.py entrada.txt salida.mp3 | ||
| | | ||
| + | |||
| + | ====== Piper TTS ====== | ||
| + | El proyecto en el 2026 se ha movido a:\\ | ||
| + | https:// | ||
| + | |||
| + | Seguimos README.md | ||
| + | git clone https:// | ||
| + | cd piper1-gpl | ||
| + | python -m venv venv | ||
| + | pip install piper-tts | ||
| + | Listamos voces | ||
| + | python3 -m piper.download_voices | ||
| + | Descargamos castellano | ||
| + | mkdir ES && cd ES | ||
| + | python3 -m piper.download_voices es_ES-sharvard-medium | ||
| + | Descarga dos ficheros, un json con la configuración y el de la voz que ocupa 74Mb | ||
| + | 74M es_ES-sharvard-medium.onnx | ||
| + | 4.8K es_ES-sharvard-medium.onnx.json | ||
| + | Creamos un fichero con esa voz que es casi inmediato: | ||
| + | time python3 -m piper -m es_ES-sharvard-medium -f test.wav -- 'Esto es una pequeña prueba' | ||
| + | real 1.554s | ||
| + | user 2.740s | ||
| + | |||
| + | Con una frase mas larga tarda mas o menos lo mismo | ||
| + | time python3 -m piper -m es_ES-sharvard-medium -f test.wav -- 'Esto es una pequeña prueba para ver cuanto puede tardar este programa en reproducir texto a voz.' | ||
| + | real 1.771s | ||
| + | user 3.596s | ||
| + | |||
| + | |||
| | | ||
| ====== COQUI TTS ====== | ====== COQUI TTS ====== | ||
| Line 326: | Line 368: | ||
| </ | </ | ||
| - | ====== Entrenar COQUI TTS con XTTS ====== | + | ====== Entrenar COQUI TTS con VITS ====== |
| Necesitamos muchísimas horas de audio y preparar un dataset | Necesitamos muchísimas horas de audio y preparar un dataset | ||
| Line 338: | Line 380: | ||
| └── metadata.csv | └── metadata.csv | ||
| </ | </ | ||
| + | |||
| + | El archivo metadata.csv tiene que tener el formato: | ||
| + | 00001|Hola, esta es la primera frase que grabé para mi modelo. | ||
| + | 00002|El entrenamiento de inteligencia artificial requiere paciencia. | ||
| + | 00003|Generar voz al vuelo ahora será inmediato. | ||
| + | |||
| + | Script entrenamiento | ||
| + | |||
| + | entrenar_vits.py | ||
| + | |||
| + | < | ||
| + | import os | ||
| + | from unicodedata import normalize | ||
| + | |||
| + | from trainer import Trainer, TrainerArgs | ||
| + | |||
| + | from TTS.config import BaseAudioConfig | ||
| + | from TTS.tts.configs.shared_configs import BaseDatasetConfig | ||
| + | from TTS.tts.configs.vits_config import VitsConfig | ||
| + | from TTS.tts.models.vits import CharactersConfig, | ||
| + | |||
| + | # 1. Rutas de carpetas | ||
| + | PATH_DATASET = "/ | ||
| + | PATH_SALIDA = "/ | ||
| + | SPANISH_PUNCTUATIONS = " | ||
| + | |||
| + | # Incluimos el alfabeto base del español y completamos con cualquier carácter extra presente en el dataset. | ||
| + | BASE_SPANISH_CHARACTERS = " | ||
| + | |||
| + | |||
| + | def build_characters_config(texts: | ||
| + | normalized_text = normalize(" | ||
| + | discovered_characters = sorted( | ||
| + | { | ||
| + | char | ||
| + | for char in normalized_text | ||
| + | if not char.isspace() and char not in SPANISH_PUNCTUATIONS | ||
| + | } | ||
| + | ) | ||
| + | characters = "" | ||
| + | |||
| + | return CharactersConfig( | ||
| + | characters_class=" | ||
| + | pad="< | ||
| + | eos=None, | ||
| + | bos=None, | ||
| + | blank="< | ||
| + | characters=characters, | ||
| + | punctuations=SPANISH_PUNCTUATIONS, | ||
| + | phonemes=None, | ||
| + | is_unique=False, | ||
| + | is_sorted=True, | ||
| + | ) | ||
| + | |||
| + | |||
| + | def load_samples(dataset_path: | ||
| + | samples = [] | ||
| + | csv_path = os.path.join(dataset_path, | ||
| + | |||
| + | with open(csv_path, | ||
| + | for line in file_handle: | ||
| + | parts = line.strip().split(" | ||
| + | if len(parts) < 2: | ||
| + | continue | ||
| + | |||
| + | audio_id, text = parts[0], parts[1] | ||
| + | samples.append( | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | ) | ||
| + | |||
| + | return samples | ||
| + | |||
| + | |||
| + | def main(): | ||
| + | samples = load_samples(PATH_DATASET) | ||
| + | if not samples: | ||
| + | raise RuntimeError(f" | ||
| + | |||
| + | characters_config = build_characters_config([sample[" | ||
| + | |||
| + | # 2. Configurar el Dataset Base | ||
| + | dataset_config = BaseDatasetConfig( | ||
| + | formatter=" | ||
| + | path=PATH_DATASET, | ||
| + | language=" | ||
| + | ) | ||
| + | |||
| + | # Configuración estándar de audio para VITS | ||
| + | audio_config = BaseAudioConfig( | ||
| + | sample_rate=22050, | ||
| + | resample=True, | ||
| + | ) | ||
| + | |||
| + | # 3. Configurar la arquitectura VITS | ||
| + | # 3. Configurar la arquitectura VITS (Modo caracteres puros, sin fonemas externos) | ||
| + | config = VitsConfig( | ||
| + | audio=audio_config, | ||
| + | run_name=" | ||
| + | batch_size=16, | ||
| + | eval_batch_size=8, | ||
| + | num_loader_workers=0, | ||
| + | num_eval_loader_workers=0, | ||
| + | run_eval=True, | ||
| + | test_delay_epochs=5, | ||
| + | epochs=100, | ||
| + | text_cleaner=" | ||
| + | use_phonemes=False, | ||
| + | datasets=[dataset_config], | ||
| + | characters=characters_config, | ||
| + | output_path=PATH_SALIDA, | ||
| + | ) | ||
| + | |||
| + | # Fuerza la serialización de `characters` para que el tokenizer use este vocabulario desde el config. | ||
| + | config.from_dict(config.to_dict()) | ||
| + | |||
| + | train_samples = samples | ||
| + | eval_samples = samples[:1] | ||
| + | |||
| + | model = Vits(config) | ||
| + | |||
| + | trainer = Trainer( | ||
| + | TrainerArgs(), | ||
| + | config, | ||
| + | output_path=PATH_SALIDA, | ||
| + | model=model, | ||
| + | train_samples=train_samples, | ||
| + | eval_samples=eval_samples, | ||
| + | ) | ||
| + | |||
| + | print(f" | ||
| + | print(f" | ||
| + | print(" | ||
| + | trainer.fit() | ||
| + | |||
| + | |||
| + | if __name__ == " | ||
| + | main() | ||
| + | </ | ||
| + | |||
| + | Luego lo ejecutamos con (cambiar directorio de entreno): | ||
| + | python entrenar_vits.py --device mps --continue_path resultado_entrenamiento/ | ||
| + | |||
| + | En mi caso: | ||
| + | python entrenar_vits.py --device mps --continue_path resultado_entrenamiento/ | ||
| + | |||
| + | MAC: | ||
| + | |||
| + | Las notas de audio están en | ||
| + | open ~/ | ||
| + | |||
| + | |||
| + | |||
| + | ====== Gráficas de rendimiento ====== | ||
| + | Levantamos servidor tensor con: | ||
| + | tensorboard --logdir=/ | ||
| + | |||
| + | Entramos en: http:// | ||
| + | |||
| + | Sacado de chatGPT: | ||
| + | < | ||
| + | oss_disc y loss_gen: Son las gráficas de rendimiento del Discriminador y el Generador de VITS. Verás curvas que van bajando. Cuanto más abajo y estables estén, mejor y más limpia sonará tu voz. | ||
| + | |||
| + | loss_mel: Te indica cómo de bien está aprendiendo el modelo a imitar las frecuencias exactas de tu tono de voz. | ||
| + | |||
| + | Rendimiento de tiempo: Te muestra cuántos segundos tarda por cada paso de entrenamiento. | ||
| + | </ | ||
| + | |||
informatica/inteligencia_artificial/tts.1782470410.txt.gz · Last modified: by jose
