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:36] – [Entrenar COQUI TTS] jose | informatica:inteligencia_artificial:tts [2026/06/26 18:55] (current) – jose | ||
|---|---|---|---|
| Line 326: | Line 326: | ||
| </ | </ | ||
| + | ====== Entrenar COQUI TTS con VITS ====== | ||
| + | Necesitamos muchísimas horas de audio y preparar un dataset | ||
| + | |||
| + | Creamos la siguiente estructura de ficheros | ||
| + | < | ||
| + | mi_dataset_vits/ | ||
| + | ├── wavs/ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | └── 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.1782470181.txt.gz · Last modified: by jose
