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/07/04 00:03] (current) jose
Line 1: Line 1:
 +====== Herramientas ======
 +Para grabar voz mimic:\\
 +https://github.com/MycroftAI/mimic-recording-studio/
 +
 +Este es mas moderno:
 +https://github.com/rhasspy/piper-recording-studio/
 +
 +  docker run -it -p 8000:8000 -v "$PWD/output:/app/output" rhasspy/piper-recording-studio
 +
 +Videos Youtube:\\
 +https://www.youtube.com/@ThorstenMueller/
 +
 +
 ====== Español en Mac ====== ====== Español en Mac ======
   git clone https://github.com/jpgallegoar/Spanish-F5.git   git clone https://github.com/jpgallegoar/Spanish-F5.git
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://github.com/OHF-voice/piper1-gpl
 +
 +Seguimos README.md
 +  git clone https://github.com/OHF-voice/piper1-gpl
 +  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:
 </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 392:
 <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]
  
-# 6. Configurar el entrenador (Trainer) +    model Vits(config)
-trainer Trainer( +
-    TrainerArgs(), +
-    config+
-    output_path=PATH_SALIDA, +
-    model=model, +
-    train_samples=train_samples, +
-    eval_samples=eval_samples, +
-)+
  
-# 7¡FUEGO! Lanzar el entrenamiento +    trainer = Trainer( 
-print("Iniciando entrenamiento del modelo VITS con tu voz..."+        TrainerArgs(), 
-trainer.fit()+        config, 
 +        output_path=PATH_SALIDA, 
 +        model=model, 
 +        train_samples=train_samples, 
 +        eval_samples=eval_samples, 
 +    ) 
 + 
 +    print(f"Dataset cargado manualmente con éxitoMuestras 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> </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.
 +
 +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.
 +</code>
 +
 +
informatica/inteligencia_artificial/tts.1782470508.txt.gz · Last modified: by jose