Files
TTS/notebooks/Tutorial_2_train_your_first_TTS_model.ipynb
prakharpbuf c1875f68df typos and minor fixes (#2508)
* Update tacotron1-2.md

* Update README.md

* Update Tutorial_2_train_your_first_TTS_model.ipynb

* Update synthesizer.py

There is no arg called --speaker_name

* Update formatting_your_dataset.md

* Update AnalyzeDataset.ipynb

* Update AnalyzeDataset.ipynb

* Update AnalyzeDataset.ipynb

* Update finetuning.md

* Update train_yourtts.py

* Update train_yourtts.py

* Update train_yourtts.py

* Update finetuning.md
2023-04-26 15:22:57 +02:00

14 KiB

Train your first 🐸 TTS model 💫

👋 Hello and welcome to Coqui (🐸) TTS

The goal of this notebook is to show you a typical workflow for training and testing a TTS model with 🐸.

Let's train a very small model on a very small amount of data so we can iterate quickly.

In this notebook, we will:

  1. Download data and format it for 🐸 TTS.
  2. Configure the training and testing runs.
  3. Train a new model.
  4. Test the model and display its performance.

So, let's jump right in!

In [ ]:
## Install Coqui TTS
! pip install -U pip
! pip install TTS

Data Preparation

First things first: we need some data.

We're training a Text-to-Speech model, so we need some text and we need some speech. Specificially, we want transcribed speech. The speech must be divided into audio clips and each clip needs transcription. More details about data requirements such as recording characteristics, background noise and vocabulary coverage can be found in the 🐸TTS documentation.

If you have a single audio file and you need to split it into clips. It is also important to use a lossless audio file format to prevent compression artifacts. We recommend using wav file format.

The data format we will be adopting for this tutorial is taken from the widely-used LJSpeech dataset, where waves are collected under a folder:

/wavs
 | - audio1.wav
 | - audio2.wav
 | - audio3.wav
...

and a metadata.csv file will have the audio file name in parallel to the transcript, delimited by |:

# metadata.csv
audio1|This is my sentence.
audio2|This is maybe my sentence.
audio3|This is certainly my sentence.
audio4|Let this be your sentence.
...

In the end, we should have the following folder structure:

/MyTTSDataset
 |
 | -> metadata.csv
 | -> /wavs
  | -> audio1.wav
  | -> audio2.wav
  | ...

🐸TTS already provides tooling for the LJSpeech. if you use the same format, you can start training your models right away.

After you collect and format your dataset, you need to check two things. Whether you need a formatter and a text_cleaner.
The formatter loads the text file (created above) as a list and the text_cleaner performs a sequence of text normalization operations that converts the raw text into the spoken representation (e.g. converting numbers to text, acronyms, and symbols to the spoken format).

If you use a different dataset format then the LJSpeech or the other public datasets that 🐸TTS supports, then you need to write your own formatter and text_cleaner.

️ Loading your dataset

Load one of the dataset supported by 🐸TTS.

We will start by defining dataset config and setting LJSpeech as our target dataset and define its path.

In [ ]:
import os

# BaseDatasetConfig: defines name, formatter and path of the dataset.
from TTS.tts.configs.shared_configs import BaseDatasetConfig

output_path = "tts_train_dir"
if not os.path.exists(output_path):
    os.makedirs(output_path)
    
In [ ]:
# Download and extract LJSpeech dataset.

!wget -O $output_path/LJSpeech-1.1.tar.bz2 https://data.keithito.com/data/speech/LJSpeech-1.1.tar.bz2 
!tar -xf $output_path/LJSpeech-1.1.tar.bz2 -C $output_path
In [ ]:
dataset_config = BaseDatasetConfig(
    formatter="ljspeech", meta_file_train="metadata.csv", path=os.path.join(output_path, "LJSpeech-1.1/")
)

Train a new model

Let's kick off a training run 🚀🚀🚀.

Deciding on the model architecture you'd want to use is based on your needs and available resources. Each model architecture has it's pros and cons that define the run-time efficiency and the voice quality. We have many recipes under TTS/recipes/ that provide a good starting point. For this tutorial, we will be using GlowTTS.

We will begin by initializing the model training configuration.

In [ ]:
# GlowTTSConfig: all model related values for training, validating and testing.
from TTS.tts.configs.glow_tts_config import GlowTTSConfig
config = GlowTTSConfig(
    batch_size=32,
    eval_batch_size=16,
    num_loader_workers=4,
    num_eval_loader_workers=4,
    run_eval=True,
    test_delay_epochs=-1,
    epochs=100,
    text_cleaner="phoneme_cleaners",
    use_phonemes=True,
    phoneme_language="en-us",
    phoneme_cache_path=os.path.join(output_path, "phoneme_cache"),
    print_step=25,
    print_eval=False,
    mixed_precision=True,
    output_path=output_path,
    datasets=[dataset_config],
    save_step=1000,
)

Next we will initialize the audio processor which is used for feature extraction and audio I/O.

In [ ]:
from TTS.utils.audio import AudioProcessor
ap = AudioProcessor.init_from_config(config)
# Modify sample rate if for a custom audio dataset:
# ap.sample_rate = 22050

Next we will initialize the tokenizer which is used to convert text to sequences of token IDs. If characters are not defined in the config, default characters are passed to the config.

In [ ]:
from TTS.tts.utils.text.tokenizer import TTSTokenizer
tokenizer, config = TTSTokenizer.init_from_config(config)

Next we will load data samples. Each sample is a list of [text, audio_file_path, speaker_name]. You can define your custom sample loader returning the list of samples.

In [ ]:
from TTS.tts.datasets import load_tts_samples
train_samples, eval_samples = load_tts_samples(
    dataset_config,
    eval_split=True,
    eval_split_max_size=config.eval_split_max_size,
    eval_split_size=config.eval_split_size,
)

Now we're ready to initialize the model.

Models take a config object and a speaker manager as input. Config defines the details of the model like the number of layers, the size of the embedding, etc. Speaker manager is used by multi-speaker models.

In [ ]:
from TTS.tts.models.glow_tts import GlowTTS
model = GlowTTS(config, ap, tokenizer, speaker_manager=None)

Trainer provides a generic API to train all the 🐸TTS models with all its perks like mixed-precision training, distributed training, etc.

In [ ]:
from trainer import Trainer, TrainerArgs
trainer = Trainer(
    TrainerArgs(), config, output_path, model=model, train_samples=train_samples, eval_samples=eval_samples
)

AND... 3,2,1... START TRAINING 🚀🚀🚀

In [ ]:
trainer.fit()

🚀 Run the Tensorboard. 🚀

On the notebook and Tensorboard, you can monitor the progress of your model. Also Tensorboard provides certain figures and sample outputs.

In [ ]:
!pip install tensorboard
!tensorboard --logdir=tts_train_dir

Test the model

We made it! 🙌

Let's kick off the testing run, which displays performance metrics.

We're committing the cardinal sin of ML 😈 (aka - testing on our training data) so you don't want to deploy this model into production. In this notebook we're focusing on the workflow itself, so it's forgivable 😇

You can see from the test output that our tiny model has overfit to the data, and basically memorized this one sentence.

When you start training your own models, make sure your testing data doesn't include your training data 😅

Let's get the latest saved checkpoint.

In [ ]:
import glob, os
output_path = "tts_train_dir"
ckpts = sorted([f for f in glob.glob(output_path+"/*/*.pth")])
configs = sorted([f for f in glob.glob(output_path+"/*/*.json")])
In [ ]:
 !tts --text "Text for TTS" \
      --model_path $test_ckpt \
      --config_path $test_config \
      --out_path out.wav

📣 Listen to the synthesized wave 📣

In [ ]:
import IPython
IPython.display.Audio("out.wav")

🎉 Congratulations! 🎉 You now have trained your first TTS model!

Follow up with the next tutorials to learn more advanced material.

In [ ]: