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:04] – [Entrenar COQUI TTS] jose | informatica:inteligencia_artificial:tts [2026/06/26 18:55] (current) – jose | ||
|---|---|---|---|
| Line 179: | Line 179: | ||
| tts | tts | ||
| - | ====== Entrenar COQUI TTS ====== | + | ====== Entrenar COQUI TTS con XTTS====== |
| - | Para entrenar a COQUI hay que hacerlo con el modelo de fine-tunning xtts_v2 | + | Para entrenar a COQUI hay que hacerlo con el modelo de fine-tunning xtts_v2 |
| Tenemos que instalarlo con estable: | Tenemos que instalarlo con estable: | ||
| Line 261: | Line 261: | ||
| </ | </ | ||
| + | Grabamos ficheros wav con nuestra voz en el directorio mis_audios | ||
| + | |||
| + | python calcular_voz.py | ||
| + | < | ||
| + | -> Cargando modelo XTTS v2 desde: .cache/ | ||
| + | |||
| + | Procesando 1 archivos para crear tu huella de voz... | ||
| + | |||
| + | [OK] ¡Listo! Tu voz se ha promediado y guardado con éxito en ' | ||
| + | </ | ||
| + | |||
| + | Luego ejecutamos el fichero hablar.py | ||
| + | |||
| + | hablar.py | ||
| + | |||
| + | < | ||
| + | import os | ||
| + | import torch | ||
| + | import torchaudio | ||
| + | from TTS.tts.configs.xtts_config import XttsConfig | ||
| + | from TTS.tts.models.xtts import Xtts | ||
| + | |||
| + | # 1. Texto a sintetizar y salida | ||
| + | texto_a_decir = "Hola, ahora estoy generando voz al vuelo de forma mucho más rápida y directa." | ||
| + | archivo_salida = " | ||
| + | |||
| + | # 2. Rutas del modelo base | ||
| + | checkpoint_dir = os.path.expanduser(" | ||
| + | config_file = os.path.join(checkpoint_dir, | ||
| + | |||
| + | # 3. Cargamos configuración y modelo | ||
| + | config = XttsConfig() | ||
| + | config.load_json(config_file) | ||
| + | model = Xtts(config) | ||
| + | model.load_checkpoint(config, | ||
| + | |||
| + | # 4. Cargamos tu huella de voz precalculada (.pth) | ||
| + | print(" | ||
| + | voice_data = torch.load(" | ||
| + | |||
| + | # Mapeamos los nombres a lo que exige el método interno .inference() | ||
| + | gpt_cond_latent = voice_data[" | ||
| + | speaker_embedding = voice_data[" | ||
| + | |||
| + | # 5. Inferencia con los nombres de variables exactos del código de Coqui | ||
| + | print(" | ||
| + | outputs = model.inference( | ||
| + | text=texto_a_decir, | ||
| + | language=" | ||
| + | gpt_cond_latent=gpt_cond_latent, | ||
| + | speaker_embedding=speaker_embedding, | ||
| + | temperature=config.temperature, | ||
| + | length_penalty=config.length_penalty, | ||
| + | repetition_penalty=config.repetition_penalty, | ||
| + | top_k=config.top_k, | ||
| + | top_p=config.top_p, | ||
| + | ) | ||
| + | |||
| + | # 6. Guardamos el resultado en un archivo .wav | ||
| + | audio_tensor = torch.tensor(outputs[" | ||
| + | torchaudio.save(archivo_salida, | ||
| + | |||
| + | print(f" | ||
| + | </ | ||
| + | |||
| + | ====== 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.1782468243.txt.gz · Last modified: by jose
