User Tools

Site Tools


informatica:inteligencia_artificial:tts

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
informatica:inteligencia_artificial:tts [2026/06/26 10:41] – [Entrenar COQUI TTS con XTTS] joseinformatica:inteligencia_artificial:tts [2026/06/26 18:55] (current) jose
Line 326: Line 326:
 </code> </code>
  
-====== 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 350: Line 350:
 <code> <code>
 import os import os
 +from unicodedata import normalize
 +
 from trainer import Trainer, TrainerArgs from trainer import Trainer, TrainerArgs
 +
 +from TTS.config import BaseAudioConfig
 from TTS.tts.configs.shared_configs import BaseDatasetConfig from TTS.tts.configs.shared_configs import BaseDatasetConfig
 from TTS.tts.configs.vits_config import VitsConfig from TTS.tts.configs.vits_config import VitsConfig
-from TTS.tts.datasets import load_tts_samples +from TTS.tts.models.vits import CharactersConfig, Vits
-from TTS.tts.models.vits import Vits+
  
 # 1. Rutas de carpetas # 1. Rutas de carpetas
-PATH_DATASET = "/Users/T054810/Personal/IA/coqui-ai-TTS/mi_dataset_vits" +PATH_DATASET = "/Users/T054810/Personal/IA/coqui-ai-TTS_beta/mi_dataset_vits" 
-PATH_SALIDA = "/Users/T054810/Personal/IA/coqui-ai-TTS/resultado_entrenamiento"+PATH_SALIDA = "/Users/T054810/Personal/IA/coqui-ai-TTS_beta/resultado_entrenamiento
 +SPANISH_PUNCTUATIONS = "!'(),-.:;? ¡¿"
  
-2. Configurar el Dataset en formato LJSpeech +Incluimos el alfabeto base del español y completamos con cualquier carácter extra presente en el dataset. 
-dataset_config BaseDatasetConfig+BASE_SPANISH_CHARACTERS "abcdefghijklmnopqrstuvwxyzáéíóúüñ0123456789" 
-    formatter="ljspeech", + 
-    meta_file_name="metadata.csv", + 
-    path=PATH_DATASET +def build_characters_config(texts: list[str]) -> CharactersConfig: 
-)+    normalized_text normalize("NFC", " ".join(texts)).lower() 
 +    discovered_characters sorted( 
 +        { 
 +            char 
 +            for char in normalized_text 
 +            if not char.isspace() and char not in SPANISH_PUNCTUATIONS 
 +        } 
 +    ) 
 +    characters = "".join(dict.fromkeys(BASE_SPANISH_CHARACTERS + "".join(discovered_characters))) 
 + 
 +    return CharactersConfig( 
 +        characters_class="TTS.tts.models.vits.VitsCharacters", 
 +        pad="<PAD>", 
 +        eos=None, 
 +        bos=None, 
 +        blank="<BLNK>", 
 +        characters=characters, 
 +        punctuations=SPANISH_PUNCTUATIONS, 
 +        phonemes=None, 
 +        is_unique=False, 
 +        is_sorted=True, 
 +    ) 
 + 
 + 
 +def load_samples(dataset_path: str) -> list[dict]: 
 +    samples = [] 
 +    csv_path = os.path.join(dataset_path, "metadata.csv"
 + 
 +    with open(csv_path"r", encoding="utf-8") as file_handle: 
 +        for line in file_handle: 
 +            parts = line.strip().split("|"
 +            if len(parts) < 2: 
 +                continue 
 + 
 +            audio_id, text = parts[0], parts[1] 
 +            samples.append( 
 +                { 
 +                    "text": text, 
 +                    "audio_file": os.path.join(dataset_path, "wavs", f"{audio_id}.wav"), 
 +                    "speaker_name": "mi_voz", 
 +                    "language": "es", 
 +                    "audio_unique_name": audio_id, 
 +                } 
 +            ) 
 + 
 +    return samples 
 + 
 + 
 +def main(): 
 +    samples = load_samples(PATH_DATASET) 
 +    if not samples: 
 +        raise RuntimeError(f"No se encontraron muestras válidas en {PATH_DATASET}"
 + 
 +    characters_config = build_characters_config([sample["text"] for sample in samples]) 
 + 
 +# 2. Configurar el Dataset Base 
 +    dataset_config = BaseDatasetConfig( 
 +        formatter="ljspeech", 
 +        path=PATH_DATASET, 
 +        language="es", 
 +    ) 
 + 
 +# 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
-config = VitsConfig( +# 3. Configurar la arquitectura VITS (Modo caracteres puros, sin fonemas externos) 
-    audio=None # Coqui calculará los parámetros de audio automáticamente +    config = VitsConfig( 
-    run_name="mi_voz_vits_rapida", +        audio=audio_config
-    batch_size=16,       # Si te da error de memoria, bájalo a 8 o 4 +        run_name="mi_voz_vits_rapida", 
-    eval_batch_size=8, +        batch_size=16, 
-    num_loader_workers=2+        eval_batch_size=8, 
-    num_eval_loader_workers=2+        num_loader_workers=0
-    run_eval=True, +        num_eval_loader_workers=0
-    test_delay_epochs=5, +        run_eval=True, 
-    epochs=100,          # Puedes subirlo si quieres que aprenda más (ej. 500) +        test_delay_epochs=5, 
-    text_cleaner="multilingual_cleaners", +        epochs=100, 
-    language="es"      # Idioma español +        text_cleaner="multilingual_cleaners", 
-    phoneme_language="es", +        use_phonemes=False
-    phoneme_cache_path=os.path.join(PATH_SALIDA, "phoneme_cache"), +        datasets=[dataset_config], 
-    datasets=[dataset_config], +        characters=characters_config, 
-    output_path=PATH_SALIDA +        output_path=PATH_SALIDA, 
-)+    )
  
-4. Cargar muestras de audio y texto +    Fuerza la serialización de `characters` para que el tokenizer use este vocabulario desde el config. 
-train_samples, eval_samples = load_tts_samples(dataset_config, eval_split=True)+    config.from_dict(config.to_dict())
  
-# 5. Inicializar el modelo VITS +    train_samples = samples 
-model = Vits(config)+    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"Dataset cargado manualmente con éxito. Muestras encontradas: {len(samples)}"
 +    print(f"Vocabulario de texto preparado con {len(config.characters.characters)} caracteres."
 +    print("Iniciando entrenamiento del modelo VITS con tu voz..."
 +    trainer.fit() 
 + 
 + 
 +if __name__ == "__main__": 
 +    main() 
 +</code> 
 + 
 +Luego lo ejecutamos con (cambiar directorio de entreno): 
 +  python entrenar_vits.py --device mps --continue_path resultado_entrenamiento/mi_voz_vits_rapida-June-26-2026_05+24PM-ca2cf515 --epochs 200 
 + 
 +En mi caso: 
 +  python entrenar_vits.py --device mps --continue_path resultado_entrenamiento/entrenamiento1 --epochs 200 
 + 
 +MAC: 
 + 
 +Las notas de audio están en 
 +  open ~/Library/Group\ Containers/group.com.apple.VoiceMemos.shared 
 + 
 + 
 + 
 +====== Gráficas de rendimiento ====== 
 +Levantamos servidor tensor con: 
 +  tensorboard --logdir=/Users/T054810/Personal/IA/coqui-ai-TTS_beta/resultado_entrenamiento/ 
 + 
 +Entramos en: http://localhost:6006/ 
 + 
 +Sacado de chatGPT: 
 +<code> 
 +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.
  
-# 6. Configurar el entrenador (Trainer) +loss_mel: Te indica cómo de bien está aprendiendo el modelo a imitar las frecuencias exactas de tu tono de voz.
-trainer = Trainer( +
-    TrainerArgs(), +
-    config, +
-    output_path=PATH_SALIDA, +
-    model=model, +
-    train_samples=train_samples, +
-    eval_samples=eval_samples, +
-)+
  
-# 7. ¡FUEGO! Lanzar el entrenamiento +Rendimiento de tiempo: Te muestra cuántos segundos tarda por cada paso de entrenamiento.
-print("Iniciando entrenamiento del modelo VITS con tu voz..."+
-trainer.fit()+
 </code> </code>
informatica/inteligencia_artificial/tts.1782470508.txt.gz · Last modified: by jose