chore: import upstream snapshot with attribution
Create PR to main with cherry-pick from release / cherry-pick (push) Failing after 0s
CICD NeMo / pre-flight (push) Failing after 0s
CICD NeMo / configure (push) Has been skipped
Build, validate, and release Neural Modules / pre-flight (push) Failing after 1s
CICD NeMo / code-linting (push) Has been skipped
Build, validate, and release Neural Modules / release (push) Has been skipped
Build, validate, and release Neural Modules / release-summary (push) Has been cancelled
CICD NeMo / cicd-test-container-build (push) Has been cancelled
CICD NeMo / cicd-import-tests (push) Has been cancelled
CICD NeMo / L0_Setup_Test_Data_And_Models (push) Has been cancelled
CICD NeMo / cicd-main-unit-tests (push) Has been cancelled
CICD NeMo / cicd-main-speech (push) Has been cancelled
CICD NeMo / Nemo_CICD_Test (push) Has been cancelled
CICD NeMo / Coverage (e2e) (push) Has been cancelled
CICD NeMo / Coverage (unit-test) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
CICD NeMo / cicd-wait-in-queue (push) Has been cancelled
Create PR to main with cherry-pick from release / cherry-pick (push) Failing after 0s
CICD NeMo / pre-flight (push) Failing after 0s
CICD NeMo / configure (push) Has been skipped
Build, validate, and release Neural Modules / pre-flight (push) Failing after 1s
CICD NeMo / code-linting (push) Has been skipped
Build, validate, and release Neural Modules / release (push) Has been skipped
Build, validate, and release Neural Modules / release-summary (push) Has been cancelled
CICD NeMo / cicd-test-container-build (push) Has been cancelled
CICD NeMo / cicd-import-tests (push) Has been cancelled
CICD NeMo / L0_Setup_Test_Data_And_Models (push) Has been cancelled
CICD NeMo / cicd-main-unit-tests (push) Has been cancelled
CICD NeMo / cicd-main-speech (push) Has been cancelled
CICD NeMo / Nemo_CICD_Test (push) Has been cancelled
CICD NeMo / Coverage (e2e) (push) Has been cancelled
CICD NeMo / Coverage (unit-test) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
CICD NeMo / cicd-wait-in-queue (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# Overview
|
||||
This PR introduces frame-stacking implementation in Magpie-TTS. Frame-stacking is disabled by default. It can be enabled by setting a `frame_stacking_factor` > 1 in the YAML config.
|
||||
|
||||
# Frame-stacking
|
||||
|
||||
## Overview
|
||||
Frame-stacking is a technique that allows the Magpie-TTS **base decoder** (also known as the "main" for "first stage" decoder) to **process multiple consecutive audio frames in a single forward pass**, leaving the job of generating individual frames and codebooks to a second, smaller, "Local Transformer" ("LT") decoder. The goal is to accelerate inference by reducing the number of generation steps of the base decoder. In this two-stage approach:
|
||||
|
||||
1. The base decoder processes multiple frames at once, producing a single latent representation for each group (stack) of frames
|
||||
2. The Local Transformer then generates the individual `frames * codebooks` tokens.
|
||||
|
||||
The Local Transformer is much faster than the base decoder, making this two-stage approach significantly faster than generating each frame with the base decoder. The speed improvement comes from two factors:
|
||||
* **Fewer parameters**: The LT decoder is lightweight compared to the base decoder
|
||||
* **Shorter sequences**: The LT decoder only attends to the current frame stack and the latent, not the entire frame sequence
|
||||
|
||||
The base decoder can also generate audio codes directly without a LT, but when frame-stacking is enabled using the LT decoder is typically necessary to achieve high-quality synthesis.
|
||||
|
||||
## Design and Implementation
|
||||
* The `frame_stacking_factor` is the parameter that controls the number of frames to stack. The default is 1, which means no frame-stacking. We have tested values up to `4`.
|
||||
* For each codebooks, we keep a separate embedding table for at each frame within the stack. At the input to the decoder, the embeddings are averages across codebooks (as usual) and also frames within the stack. The embedding tables are shared between the base and LT decoders.
|
||||
|
||||
## Limitations
|
||||
This is still WIP with more work to be done. Specifically, the following are not yet implemented / tested:
|
||||
* Online code extraction combined with frame-stacking.
|
||||
* Alignment encoder with frame-stacking.
|
||||
* CTC loss with frame-stacking.
|
||||
@@ -0,0 +1,95 @@
|
||||
# Background
|
||||
Magpie-TTS uses special tokens like AUDIO_BOS and AUDIO_EOS for its operation. The indices of these tokens are after the audio codec tokens, at the end of the embedding table.
|
||||
|
||||
In April 2025 we changed the layout of the embedding table in a non-backwards compatible way:
|
||||
|
||||
## Old Layout (until April 16)
|
||||
With the most common codec configuration (2016 codes), the layout used to look like this:
|
||||
```
|
||||
| Index | Token Description | Comments |
|
||||
|---------|----------------------|-----------------------------------------------------------------------------------------------------------|
|
||||
| [0] | Codec Token 0 | |
|
||||
| [1] | Codec Token 1 | |
|
||||
| [2] | Codec Token 2 | |
|
||||
| ... | ... | |
|
||||
| [2015] | Codec Token 2015 | |
|
||||
| [2016] | <Unused> | |
|
||||
| [2017] | <Unused> | |
|
||||
| [2018] | <Unused> | |
|
||||
| ... | | |
|
||||
| [2044] | Context Audio BOS | if model_type == `decoder_context_tts` |
|
||||
| [2045] | Context Audio EOS | if model_type == `decoder_context_tts` |
|
||||
| [2046] | Audio BOS | also used for Context Audio BOS if model_type == `multi_encoder_context_tts` or `single_encoder_sv_tts` |
|
||||
| [2047] | Audio EOS | also used for Context Audio EOS if model_type == `multi_encoder_context_tts` or `single_encoder_sv_tts` |
|
||||
```
|
||||
|
||||
## New Layout```
|
||||
The new layout for the same codec configuration is:
|
||||
```
|
||||
| Index | Token Description | Comments |
|
||||
---------------------------------------------|
|
||||
| [0] | Codec Token 0 | |
|
||||
| [1] | Codec Token 1 | |
|
||||
| [2] | Codec Token 2 | |
|
||||
| ... | ... | |
|
||||
| [2015] | Codec Token 2015 | |
|
||||
| [2016] | Audio BOS | |
|
||||
| [2017] | Audio EOS | |
|
||||
| [2018] | Context Audio BOS | |
|
||||
| [2019] | Context Audio EOS | |
|
||||
| [2020] | MASK token (MaskGit) | |
|
||||
| [2021] | RESERVED_1 | |
|
||||
| [2022] | RESERVED_2 | |
|
||||
| [2023] | RESERVED_3 | |
|
||||
```
|
||||
|
||||
# How to Train and Load a New Checkpoint
|
||||
For new trainings and inference all configuration is automatic:
|
||||
* The number of codebooks, codec codebooks size, and codec downsampling rate are all read from the codec checkpoint rather than configured in Magpie.
|
||||
* The embedding table size is automatically set to codec_codebook_size + number_of_special_tokens (currently 2016+8=2024). There is no risk of accidentally stepping on codec tokens since the table sizes gets automatically sized with enough room for the special tokens.
|
||||
|
||||
# How to Load Old Checkpoints
|
||||
For checkpoints created before the change you can force legacy codebook layout in one of these ways:
|
||||
|
||||
## If using `infer_and_evaluate.py`
|
||||
Just set the `--legacy_codebooks` command line option. No need to update your YAML file – The script will automatically add the overrides.
|
||||
|
||||
## If using a Hydra command line
|
||||
This scenario would happen when either finetuning with an old checkpoint or doing data generation with an old checkpoint.
|
||||
|
||||
You have two options:
|
||||
### Add these to your command line
|
||||
```
|
||||
# decoder context model
|
||||
+model.forced_num_all_tokens_per_codebook=2048 +model.forced_audio_eos_id=2047 +model.forced_audio_bos_id=2046 +model.forced_context_audio_eos_id=2045 +model.forced_context_audio_bos_id=2044
|
||||
|
||||
# multi encoder context and any other model type
|
||||
+model.forced_num_all_tokens_per_codebook=2048 +model.forced_audio_eos_id=2047 +model.forced_audio_bos_id=2046 +model.forced_context_audio_eos_id=2047 +model.forced_context_audio_bos_id=2046
|
||||
```
|
||||
# Or, add these overrides to your YAML file
|
||||
```
|
||||
forced_num_all_tokens_per_codebook: 2048
|
||||
forced_audio_eos_id: ${sum:${model.forced_num_all_tokens_per_codebook}, -1} # 2047
|
||||
forced_audio_bos_id: ${sum:${model.forced_num_all_tokens_per_codebook}, -2} # 2046
|
||||
|
||||
# Depending on the old model type, the context_audio_bos_id and context_audio_eos_id will be different (choose one of the pairs below)
|
||||
|
||||
# For `multi_encoder_context_tts`, `single_encoder_sv_tts`:
|
||||
#forced_context_audio_eos_id: ${sum:${model.forced_num_all_tokens_per_codebook}, -1} # 2047
|
||||
#forced_context_audio_bos_id: ${sum:${model.forced_num_all_tokens_per_codebook}, -2} # 2046
|
||||
|
||||
# For `decoder_context_tts` models:
|
||||
#forced_context_audio_eos_id: ${sum:${model.forced_num_all_tokens_per_codebook}, -3} # 2045
|
||||
#forced_context_audio_bos_id: ${sum:${model.forced_num_all_tokens_per_codebook}, -4} # 2044
|
||||
```
|
||||
|
||||
# Additional Details
|
||||
Over the last few weeks we have gone through a few embedding table layouts. When using an old checkpoint it's important to know which layout your checkpoint was trained with and configuring the system accordingly.
|
||||
|
||||
* Layout 1: used until April 16 (described in the table above). Add `--legacy-codebooks` to the `infer_and_evaluate.py` command line to inference using this layout.
|
||||
|
||||
* Layout 2: after the [config changes](https://github.com/blisc/NeMo/commit/7e2cdca74a866ecefdbe01c0076ad9b5d140ac61): 2018 tokens with special tokens at the end 2017, 2016, 2015, 2014 (the last two being overwrites of codec tokens). This is an invalid layout and these checkpoints should not be used.
|
||||
|
||||
* Layout 3: after the [bugfix](https://github.com/blisc/NeMo/commit/23e299a0bd14b666543b4bbcc7783f783acb0bd3) but before the [refactoring](https://github.com/blisc/NeMo/commit/8ba55061a0ebb161abff4b329e402d5307f4af98): 2024 tokens with special tokens at the end (2023, 2022, 2021, 2020). There are no automatic options provided for using this layout but it can be manually configured by updating the `hparams.yaml` file with the `forced_*` options. Set `forced_num_all_tokens_per_codebook` to `2024` and set the rest of the overrides as defined under section `# Or, add these overrides to your YAML file` above.
|
||||
|
||||
* Layout 4: The new layout, [from this commit onwards](https://github.com/blisc/NeMo/commit/8ba55061a0ebb161abff4b329e402d5307f4af98): 2024 tokens but with special tokens immediately after codec tokens (2016, 2017, 2018, 2019). Training and inference with the latest version of the code automatically use this layout.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
|
||||
from nemo.collections.common.callbacks import LogEpochTimeCallback
|
||||
from nemo.collections.tts.models import AlignerModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path='conf', config_name='aligner')
|
||||
def main(cfg):
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get('exp_manager', None))
|
||||
model = AlignerModel(cfg=cfg.model, trainer=trainer)
|
||||
trainer.callbacks.extend([pl.callbacks.LearningRateMonitor(), LogEpochTimeCallback()]) # noqa
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,314 @@
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
import librosa
|
||||
import soundfile as sf
|
||||
import torch
|
||||
|
||||
from nemo.collections.tts.models import AlignerModel
|
||||
from nemo.collections.tts.parts.utils.tts_dataset_utils import general_padding
|
||||
|
||||
|
||||
"""
|
||||
G2P disambiguation using an Aligner model's input embedding distances.
|
||||
|
||||
Does not handle OOV and leaves them as graphemes.
|
||||
|
||||
The output will have each token's phonemes (or graphemes) bracketed, e.g.
|
||||
<\"><M AH1 L ER0><, ><M AH1 L ER0><, ><HH IY1 Z>< ><DH AH0>< ><M AE1 N><.\">
|
||||
|
||||
Example:
|
||||
python aligner_heteronym_disambiguation.py \
|
||||
--model=<model_path> \
|
||||
--manifest=<manifest_path> \
|
||||
--out=<output_json_path> \
|
||||
--confidence=0.02 \
|
||||
--verbose
|
||||
"""
|
||||
|
||||
|
||||
def get_args():
|
||||
"""Retrieve arguments for disambiguation."""
|
||||
parser = argparse.ArgumentParser("G2P disambiguation using Aligner input embedding distances.")
|
||||
# TODO(jocelynh): Make this required=False with default download from NGC once ckpt uploaded
|
||||
parser.add_argument('--model', required=True, type=str, help="Path to Aligner model checkpoint (.nemo file).")
|
||||
parser.add_argument(
|
||||
'--manifest',
|
||||
required=True,
|
||||
type=str,
|
||||
help="Path to data manifest. Each entry should contain the path to the audio file as well as the text in graphemes.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--out', required=True, type=str, help="Path to output file where disambiguations will be written."
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sr',
|
||||
required=False,
|
||||
default=22050,
|
||||
type=int,
|
||||
help="Target sample rate to load the dataset. Should match what the model was trained on.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--heteronyms',
|
||||
required=False,
|
||||
type=str,
|
||||
default='../../scripts/tts_dataset_files/heteronyms-052722',
|
||||
help="Heteronyms file to specify which words should be disambiguated. All others will use default pron.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--confidence', required=False, type=float, default=0.0, help="Confidence threshold to keep a disambiguation."
|
||||
)
|
||||
parser.add_argument(
|
||||
'--verbose',
|
||||
action='store_true',
|
||||
help="If set to True, logs scores for each disambiguated word in disambiguation_logs.txt.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def load_and_prepare_audio(aligner, audio_path, target_sr, device):
|
||||
"""Loads and resamples audio to target sample rate (if necessary), and preprocesses for Aligner input."""
|
||||
# Load audio and get length for preprocessing
|
||||
audio_data, orig_sr = sf.read(audio_path)
|
||||
if orig_sr != target_sr:
|
||||
audio_data = librosa.core.resample(audio_data, orig_sr=orig_sr, target_sr=target_sr)
|
||||
|
||||
audio = torch.tensor(audio_data, dtype=torch.float, device=device).unsqueeze(0)
|
||||
audio_len = torch.tensor(audio_data.shape[0], device=device).long().unsqueeze(0)
|
||||
|
||||
# Generate spectrogram
|
||||
spec, spec_len = aligner.preprocessor(input_signal=audio, length=audio_len)
|
||||
|
||||
return spec, spec_len
|
||||
|
||||
|
||||
def disambiguate_candidates(aligner, text, spec, spec_len, confidence, device, heteronyms, log_file=None):
|
||||
"""Retrieves and disambiguate all candidate sentences for disambiguation of a given some text.
|
||||
|
||||
Assumes that the max number of candidates per word is a reasonable batch size.
|
||||
|
||||
Note: This could be sped up if multiple words' candidates were batched, but this is conceptually easier.
|
||||
"""
|
||||
# Grab original G2P result
|
||||
aligner_g2p = aligner.tokenizer.g2p
|
||||
base_g2p = aligner_g2p(text)
|
||||
|
||||
# Tokenize text
|
||||
words = [word for word, _ in aligner_g2p.word_tokenize_func(text)]
|
||||
|
||||
### Loop Through Words ###
|
||||
result_g2p = []
|
||||
word_start_idx = 0
|
||||
|
||||
has_heteronym = False
|
||||
|
||||
for word in words:
|
||||
# Retrieve the length of the word in the default G2P conversion
|
||||
g2p_default_len = len(aligner_g2p(word))
|
||||
|
||||
# Check if word needs to be disambiguated
|
||||
if word in heteronyms:
|
||||
has_heteronym = True
|
||||
|
||||
# Add candidate for each ambiguous pronunciation
|
||||
word_candidates = []
|
||||
candidate_prons_and_lengths = []
|
||||
|
||||
for pron in aligner_g2p.phoneme_dict[word]:
|
||||
# Replace graphemes in the base G2P result with the current variant
|
||||
candidate = base_g2p[:word_start_idx] + pron + base_g2p[word_start_idx + g2p_default_len :]
|
||||
candidate_tokens = aligner.tokenizer.encode_from_g2p(candidate)
|
||||
|
||||
word_candidates.append(candidate_tokens)
|
||||
candidate_prons_and_lengths.append((pron, len(pron)))
|
||||
|
||||
### Inference ###
|
||||
num_candidates = len(word_candidates)
|
||||
|
||||
# If only one candidate, just convert and continue
|
||||
if num_candidates == 1:
|
||||
has_heteronym = False
|
||||
result_g2p.append(f"<{' '.join(candidate_prons_and_lengths[0][0])}>")
|
||||
word_start_idx += g2p_default_len
|
||||
continue
|
||||
|
||||
text_len = [len(toks) for toks in word_candidates]
|
||||
text_len_in = torch.tensor(text_len, device=device).long()
|
||||
|
||||
# Have to pad text tokens in case different pronunciations have different lengths
|
||||
max_text_len = max(text_len)
|
||||
text_stack = []
|
||||
for i in range(num_candidates):
|
||||
padded_tokens = general_padding(
|
||||
torch.tensor(word_candidates[i], device=device).long(), text_len[i], max_text_len
|
||||
)
|
||||
text_stack.append(padded_tokens)
|
||||
text_in = torch.stack(text_stack)
|
||||
|
||||
# Repeat spectrogram and spec_len tensors to match batch size
|
||||
spec_in = spec.repeat([num_candidates, 1, 1])
|
||||
spec_len_in = spec_len.repeat([num_candidates])
|
||||
|
||||
with torch.no_grad():
|
||||
soft_attn, _ = aligner(spec=spec_in, spec_len=spec_len_in, text=text_in, text_len=text_len_in)
|
||||
|
||||
# Need embedding distances and duration preds to calculate mean distance for just the one word
|
||||
text_embeddings = aligner.embed(text_in).transpose(1, 2)
|
||||
l2_dists = aligner.alignment_encoder.get_dist(keys=text_embeddings, queries=spec_in).sqrt()
|
||||
|
||||
durations = aligner.alignment_encoder.get_durations(soft_attn, text_len_in, spec_len_in).int()
|
||||
|
||||
# Retrieve average embedding distances
|
||||
min_dist = float('inf')
|
||||
max_dist = 0.0
|
||||
best_candidate = None
|
||||
for i in range(num_candidates):
|
||||
candidate_mean_dist = aligner.alignment_encoder.get_mean_distance_for_word(
|
||||
l2_dists=l2_dists[i],
|
||||
durs=durations[i],
|
||||
start_token=word_start_idx + (1 if aligner.tokenizer.pad_with_space else 0),
|
||||
num_tokens=candidate_prons_and_lengths[i][1],
|
||||
)
|
||||
if log_file:
|
||||
log_file.write(f"{candidate_prons_and_lengths[i][0]} -- {candidate_mean_dist}\n")
|
||||
|
||||
if candidate_mean_dist < min_dist:
|
||||
min_dist = candidate_mean_dist
|
||||
best_candidate = candidate_prons_and_lengths[i][0]
|
||||
if candidate_mean_dist > max_dist:
|
||||
max_dist = candidate_mean_dist
|
||||
|
||||
# Calculate confidence score. If below threshold, skip and use graphemes.
|
||||
disamb_conf = (max_dist - min_dist) / ((max_dist + min_dist) / 2.0)
|
||||
if disamb_conf < confidence:
|
||||
if log_file:
|
||||
log_file.write(f"Below confidence threshold: {best_candidate} ({disamb_conf})\n")
|
||||
|
||||
has_heteronym = False
|
||||
result_g2p.append(f"<{' '.join(aligner_g2p(word))}>")
|
||||
word_start_idx += g2p_default_len
|
||||
continue
|
||||
|
||||
# Otherwise, can write disambiguated word
|
||||
if log_file:
|
||||
log_file.write(f"best candidate: {best_candidate} (confidence: {disamb_conf})\n")
|
||||
|
||||
result_g2p.append(f"<{' '.join(best_candidate)}>")
|
||||
else:
|
||||
if re.search("[a-zA-Z]", word) is None:
|
||||
# Punctuation or space
|
||||
result_g2p.append(f"<{word}>")
|
||||
elif word in aligner_g2p.phoneme_dict:
|
||||
# Take default pronunciation for everything else in the dictionary
|
||||
result_g2p.append(f"<{' '.join(aligner_g2p.phoneme_dict[word][0])}>")
|
||||
else:
|
||||
# OOV
|
||||
result_g2p.append(f"<{' '.join(aligner_g2p(word))}>")
|
||||
|
||||
# Advance to phoneme index of next word
|
||||
word_start_idx += g2p_default_len
|
||||
|
||||
if log_file and has_heteronym:
|
||||
log_file.write(f"{text}\n")
|
||||
log_file.write(f"===\n{''.join(result_g2p)}\n===\n")
|
||||
log_file.write(f"===============================\n")
|
||||
|
||||
return result_g2p, has_heteronym
|
||||
|
||||
|
||||
def disambiguate_dataset(
|
||||
aligner, manifest_path, out_path, sr, heteronyms, confidence, device, verbose, heteronyms_only=True
|
||||
):
|
||||
"""Disambiguates the phonemes for all words with ambiguous pronunciations in the given manifest."""
|
||||
log_file = open('disambiguation_logs.txt', 'w') if verbose else None
|
||||
|
||||
with open(out_path, 'w') as f_out:
|
||||
with open(manifest_path, 'r') as f_in:
|
||||
count = 0
|
||||
|
||||
for line in f_in:
|
||||
# Retrieve entry and base G2P conversion for full text
|
||||
entry = json.loads(line)
|
||||
# Set punct_post_process=True in order to preserve words with apostrophes
|
||||
text = aligner.normalizer.normalize(entry['text'], punct_post_process=True)
|
||||
text = aligner.tokenizer.text_preprocessing_func(text)
|
||||
|
||||
# Load and preprocess audio
|
||||
audio_path = entry['audio_filepath']
|
||||
spec, spec_len = load_and_prepare_audio(aligner, audio_path, sr, device)
|
||||
|
||||
# Get pronunciation candidates and disambiguate
|
||||
disambiguated_text, has_heteronym = disambiguate_candidates(
|
||||
aligner, text, spec, spec_len, confidence, device, heteronyms, log_file
|
||||
)
|
||||
|
||||
# Skip writing entry if user only wants samples with heteronyms
|
||||
if heteronyms_only and not has_heteronym:
|
||||
continue
|
||||
|
||||
# Save entry with disambiguation
|
||||
entry['disambiguated_text'] = ''.join(disambiguated_text)
|
||||
f_out.write(f"{json.dumps(entry)}\n")
|
||||
|
||||
count += 1
|
||||
if count % 100 == 0:
|
||||
print(f"Finished {count} entries.")
|
||||
|
||||
print(f"Finished all entries, with a total of {count}.")
|
||||
if log_file:
|
||||
log_file.close()
|
||||
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
|
||||
# Check file paths from arguments
|
||||
if not os.path.exists(args.model):
|
||||
print("Could not find model checkpoint file: ", args.model)
|
||||
if not os.path.exists(args.manifest):
|
||||
print("Could not find data manifest file: ", args.manifest)
|
||||
if os.path.exists(args.out):
|
||||
print("Output file already exists: ", args.out)
|
||||
overwrite = input("Is it okay to overwrite it? (Y/N): ")
|
||||
if overwrite.lower() != 'y':
|
||||
print("Not overwriting output file, quitting.")
|
||||
quit()
|
||||
if not os.path.exists(args.heteronyms):
|
||||
print("Could not find heteronyms list: ", args.heteronyms)
|
||||
|
||||
# Read heteronyms list, one per line
|
||||
heteronyms = set()
|
||||
with open(args.heteronyms, 'r') as f_het:
|
||||
for line in f_het:
|
||||
heteronyms.add(line.strip().lower())
|
||||
|
||||
# Load model
|
||||
print("Restoring Aligner model from checkpoint...")
|
||||
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||
aligner = AlignerModel.restore_from(args.model, map_location=device)
|
||||
|
||||
# Disambiguation
|
||||
print("Beginning disambiguation...")
|
||||
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
||||
disambiguate_dataset(aligner, args.manifest, args.out, args.sr, heteronyms, args.confidence, device, args.verbose)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,35 @@
|
||||
# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
from omegaconf import OmegaConf
|
||||
|
||||
from nemo.collections.tts.models import AudioCodecModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils import logging
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf/audio_codec", config_name="audio_codec")
|
||||
def main(cfg):
|
||||
logging.info('\nConfig Params:\n%s', OmegaConf.to_yaml(cfg, resolve=True))
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
model = AudioCodecModel(cfg=cfg.model, trainer=trainer)
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,181 @@
|
||||
# This config contains the default values for training Aligner model on LJSpeech dataset.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: Aligner
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix" ]
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: 8000
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/cmudict-0.7b_nv22.10"
|
||||
heteronyms_path: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
|
||||
model:
|
||||
symbols_embedding_dim: 384
|
||||
bin_loss_start_ratio: 0.2
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: en
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.EnglishPhonemesTokenizer
|
||||
punct: true
|
||||
stresses: true
|
||||
chars: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.en_us_arpabet.EnglishG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 64
|
||||
num_workers: 4
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 64
|
||||
num_workers: 1
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: -11.52
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: clamp
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
alignment_encoder:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_mel_channels: ${model.n_mel_channels}
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
n_att_channels: ${model.n_mel_channels}
|
||||
|
||||
optim:
|
||||
name: adam
|
||||
lr: 1e-3
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: CosineAnnealing
|
||||
min_lr: 5e-5
|
||||
warmup_ratio: 0.35
|
||||
|
||||
trainer:
|
||||
devices: 1
|
||||
num_nodes: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 32
|
||||
max_epochs: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 1
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_forward_sum_loss
|
||||
mode: min
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
entity: null
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,193 @@
|
||||
name: AudioCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
semantic_codec_path: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 16000
|
||||
samples_per_frame: 640
|
||||
train_n_samples: 12800
|
||||
# The product of the down_sample_rates and up_sample_rates should match the samples_per_frame.
|
||||
# For example 2 * 5 * 8 * 8 = 640.
|
||||
down_sample_rates: [2, 5, 8, 8]
|
||||
up_sample_rates: [8, 8, 5, 2]
|
||||
|
||||
num_codebooks: 8
|
||||
encoder_out_dim: 42
|
||||
decoder_input_dim: 48
|
||||
|
||||
model:
|
||||
|
||||
semantic_codec_path: ${semantic_codec_path}
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${samples_per_frame}
|
||||
|
||||
mel_loss_l1_scale: 10.0
|
||||
mel_loss_l2_scale: 0.0
|
||||
stft_loss_scale: 10.0
|
||||
time_domain_loss_scale: 0.0
|
||||
commit_loss_scale: 0.0
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 1/2 times (1 update for every 2 batches)
|
||||
disc_updates_per_period: 1
|
||||
disc_update_period: 2
|
||||
|
||||
# All resolutions for mel reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024]
|
||||
]
|
||||
mel_loss_dims: [5, 10, 20, 40, 80, 160]
|
||||
mel_loss_log_guard: 1.0
|
||||
stft_loss_log_guard: 1.0
|
||||
feature_loss_type: absolute
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4 # seconds
|
||||
max_duration: null
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only log the first 10 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANEncoder
|
||||
down_sample_rates: ${down_sample_rates}
|
||||
encoded_dim: ${encoder_out_dim}
|
||||
base_channels: 48
|
||||
activation: "lrelu"
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
input_dim: ${decoder_input_dim}
|
||||
base_channels: 768
|
||||
activation: "half_snake"
|
||||
output_activation: "clamp"
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.GroupFiniteScalarQuantizer
|
||||
num_groups: ${num_codebooks}
|
||||
num_levels_per_group: [4, 4, 4, 4, 4, 4]
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.Discriminator
|
||||
discriminators:
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiPeriodDiscriminator
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[512, 128, 512], [1024, 256, 1024]]
|
||||
stft_bands: [[0.0, 0.1], [0.1, 0.25], [0.25, 0.5], [0.5, 0.75], [0.75, 1.0]]
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: false
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,174 @@
|
||||
# This config contains the default values for training 16kHz NeMo Audio Codec model
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: AudioCodec
|
||||
|
||||
max_epochs: ???
|
||||
max_steps: 200000
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 32
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 16000
|
||||
train_n_samples: 16000
|
||||
down_sample_rates: [2, 4, 5, 5]
|
||||
up_sample_rates: [5, 5, 4, 2]
|
||||
# The number of samples per encoded audio frame. Should be the product of the down_sample_rates.
|
||||
# For example 2 * 4 * 5 * 5 = 200. => frame_rate = 16000/200 = 80
|
||||
samples_per_frame: 200
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
max_steps: ${max_steps}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${samples_per_frame}
|
||||
|
||||
mel_loss_l1_scale: 1.0
|
||||
mel_loss_l2_scale: 1.0
|
||||
stft_loss_scale: 0.0
|
||||
time_domain_loss_scale: 0.1
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 2/3 times (2 updates for every 3 batches)
|
||||
disc_updates_per_period: 2
|
||||
disc_update_period: 3
|
||||
|
||||
# All resolutions for reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]
|
||||
]
|
||||
mel_loss_dims: [64, 64, 64, 64, 64, 64, 64]
|
||||
mel_loss_log_guard: 1E-5
|
||||
stft_loss_log_guard: 1.0
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 1.01
|
||||
max_duration: null
|
||||
dataset_meta: ${train_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 8
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [1, 2, 3, 4, 5, 6]
|
||||
epoch_frequency: 1
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 15.0 # Only log the first 15 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.SEANetEncoder
|
||||
down_sample_rates: ${down_sample_rates}
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.SEANetDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.ResidualVectorQuantizer
|
||||
num_codebooks: 8
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]]
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 1e-4
|
||||
betas: [0.8, 0.9]
|
||||
|
||||
sched:
|
||||
name: StepLR
|
||||
gamma: 0.999996
|
||||
step_size: 1
|
||||
|
||||
# Parameters above are tuned based on 8 GPUs with bs 32 for librilight dataset, based on number of GPUs, those parameters need to be updated accordingly
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32 # Vector quantization only works with 32-bit precision.
|
||||
max_steps: ${max_steps}
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 1
|
||||
benchmark: false
|
||||
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
create_wandb_logger: false
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,193 @@
|
||||
# This config contains the default values for training 22.05kHz NeMo Audio Codec model.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: AudioCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 22050
|
||||
win_length: 1024
|
||||
hop_length: 256
|
||||
train_n_samples: 8192 # ~0.37 seconds
|
||||
# The product of the down_sample_rates and up_sample_rates should match the hop_length.
|
||||
# For example 2 * 2 * 8 * 8 = 256.
|
||||
down_sample_rates: [2, 2, 8, 8]
|
||||
up_sample_rates: [8, 8, 2, 2]
|
||||
|
||||
num_codebooks: 8
|
||||
encoder_out_dim: 32
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${hop_length}
|
||||
|
||||
mel_loss_l1_scale: 10.0
|
||||
mel_loss_l2_scale: 0.0
|
||||
stft_loss_scale: 10.0
|
||||
time_domain_loss_scale: 0.0
|
||||
commit_loss_scale: 0.0
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 1/2 times (1 update for every 2 batches)
|
||||
disc_updates_per_period: 1
|
||||
disc_update_period: 2
|
||||
|
||||
# All resolutions for mel reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024]
|
||||
]
|
||||
mel_loss_dims: [5, 10, 20, 40, 80, 160]
|
||||
mel_loss_log_guard: 1.0
|
||||
stft_loss_log_guard: 1.0
|
||||
feature_loss_type: absolute
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4 # seconds
|
||||
max_duration: null
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only log the first 10 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANEncoder
|
||||
down_sample_rates: ${down_sample_rates}
|
||||
encoded_dim: ${encoder_out_dim}
|
||||
base_channels: 48
|
||||
activation: "lrelu"
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
input_dim: ${encoder_out_dim}
|
||||
base_channels: 768
|
||||
activation: "half_snake"
|
||||
output_activation: "clamp"
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.GroupFiniteScalarQuantizer
|
||||
num_groups: ${num_codebooks}
|
||||
num_levels_per_group: [8, 5, 5, 5]
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.Discriminator
|
||||
discriminators:
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiPeriodDiscriminator
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[512, 128, 512], [1024, 256, 1024]]
|
||||
stft_bands: [[0.0, 0.1], [0.1, 0.25], [0.25, 0.5], [0.5, 0.75], [0.75, 1.0]]
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: false
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,175 @@
|
||||
# This config contains the default values for training 24khz audio codec model
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: AudioCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 24000
|
||||
train_n_samples: 24000
|
||||
down_sample_rates: [2, 4, 5, 8]
|
||||
up_sample_rates: [8, 5, 4, 2]
|
||||
# The number of samples per encoded audio frame. Should be the product of the down_sample_rates.
|
||||
# For example 2 * 4 * 5 * 8 = 320.
|
||||
samples_per_frame: 320
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${samples_per_frame}
|
||||
|
||||
mel_loss_l1_scale: 15.0
|
||||
mel_loss_l2_scale: 0.0
|
||||
stft_loss_scale: 15.0
|
||||
time_domain_loss_scale: 0.0
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 2/3 times (2 updates for every 3 batches)
|
||||
disc_updates_per_period: 2
|
||||
disc_update_period: 3
|
||||
|
||||
# All resolutions for reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]
|
||||
]
|
||||
mel_loss_dims: [5, 10, 20, 40, 80, 160, 320]
|
||||
mel_loss_log_guard: 1.0
|
||||
stft_loss_log_guard: 1.0
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 1.01
|
||||
max_duration: null
|
||||
dataset_meta: ${train_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 8
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50, 100, 150, 200]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 15.0 # Only log the first 15 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.SEANetEncoder
|
||||
down_sample_rates: ${down_sample_rates}
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.SEANetDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.ResidualVectorQuantizer
|
||||
num_codebooks: 8
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]]
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 3e-4
|
||||
betas: [0.5, 0.9]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32 # Vector quantization only works with 32-bit precision.
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: false
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,193 @@
|
||||
# This config contains the default values for training 44.1kHz NeMo Audio Codec model.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: AudioCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 44100
|
||||
win_length: 2048
|
||||
hop_length: 512
|
||||
train_n_samples: 16384 # ~0.37 seconds
|
||||
# The product of the down_sample_rates and up_sample_rates should match the hop_length.
|
||||
# For example 2 * 4 * 8 * 8 = 512.
|
||||
down_sample_rates: [2, 4, 8, 8]
|
||||
up_sample_rates: [8, 8, 4, 2]
|
||||
|
||||
num_codebooks: 8
|
||||
encoder_out_dim: 32
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${hop_length}
|
||||
|
||||
mel_loss_l1_scale: 10.0
|
||||
mel_loss_l2_scale: 0.0
|
||||
stft_loss_scale: 10.0
|
||||
time_domain_loss_scale: 0.0
|
||||
commit_loss_scale: 0.0
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 1/2 times (1 update for every 2 batches)
|
||||
disc_updates_per_period: 1
|
||||
disc_update_period: 2
|
||||
|
||||
# All resolutions for mel reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]
|
||||
]
|
||||
mel_loss_dims: [5, 10, 20, 40, 80, 160, 320]
|
||||
mel_loss_log_guard: 1.0
|
||||
stft_loss_log_guard: 1.0
|
||||
feature_loss_type: absolute
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4 # seconds
|
||||
max_duration: null
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only log the first 10 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANEncoder
|
||||
down_sample_rates: ${down_sample_rates}
|
||||
encoded_dim: ${encoder_out_dim}
|
||||
base_channels: 48
|
||||
activation: "lrelu"
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
input_dim: ${encoder_out_dim}
|
||||
base_channels: 768
|
||||
activation: "half_snake"
|
||||
output_activation: "clamp"
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.GroupFiniteScalarQuantizer
|
||||
num_groups: ${num_codebooks}
|
||||
num_levels_per_group: [8, 5, 5, 5]
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.Discriminator
|
||||
discriminators:
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiPeriodDiscriminator
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]]
|
||||
stft_bands: [[0.0, 0.1], [0.1, 0.25], [0.25, 0.5], [0.5, 0.75], [0.75, 1.0]]
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: false
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,203 @@
|
||||
# This config contains the default values for training 22.05kHz Low-frame rate Speech Codec model.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: AudioCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 22050
|
||||
samples_per_frame: 1024
|
||||
train_n_samples: 24576 # ~1.11 seconds
|
||||
# The product of the down_sample_rates and up_sample_rates should match the samples_per_frame.
|
||||
# For example 8 * 8 * 4 * 2 * 2 = 1024.
|
||||
up_sample_rates: [8, 8, 4, 2, 2]
|
||||
down_sample_rates: [2, 2, 4, 8, 8]
|
||||
|
||||
num_codebooks: 8
|
||||
encoder_out_dim: 32
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${samples_per_frame}
|
||||
|
||||
mel_loss_l1_scale: 1.0
|
||||
mel_loss_l2_scale: 0.0
|
||||
stft_loss_scale: 20.0
|
||||
time_domain_loss_scale: 0.0
|
||||
codebook_loss_scale: 0.0
|
||||
commit_loss_scale: 0.0
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 1/2 times (1 update for every 2 batches)
|
||||
disc_updates_per_period: 1
|
||||
disc_update_period: 2
|
||||
|
||||
# All resolutions for mel reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]
|
||||
]
|
||||
mel_loss_dims: [5, 10, 20, 40, 80, 160, 320]
|
||||
mel_loss_log_guard: 1.0
|
||||
stft_loss_log_guard: 1.0
|
||||
feature_loss_type: absolute
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4 # seconds
|
||||
max_duration: null
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [1, 5, 7]
|
||||
epoch_frequency: 4
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only log the first 10 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANEncoder
|
||||
down_sample_rates: ${down_sample_rates}
|
||||
encoded_dim: ${encoder_out_dim}
|
||||
base_channels: 48
|
||||
activation: "lrelu"
|
||||
resblock_dilation_sizes: [1,]
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
input_dim: ${encoder_out_dim}
|
||||
base_channels: 1024
|
||||
activation: "lrelu"
|
||||
output_activation: "tanh"
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.GroupFiniteScalarQuantizer
|
||||
num_groups: ${num_codebooks}
|
||||
num_levels_per_group: [8, 7, 6, 6] # 2k codes
|
||||
# num_levels: [9, 8, 8, 7] # 4k codes
|
||||
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.Discriminator
|
||||
discriminators:
|
||||
- _target_: nemo.collections.tts.modules.encodec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]]
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiPeriodDiscriminator
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.SLMDiscriminator
|
||||
slm_model_name: "microsoft/wavlm-base-plus"
|
||||
slm_sr: 16000
|
||||
input_sr: ${sample_rate}
|
||||
slm_hidden: 768
|
||||
slm_layers: 13
|
||||
initial_channel: 64
|
||||
use_spectral_norm: false
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 2
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 3
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: true
|
||||
resume_ignore_no_checkpoint: true
|
||||
@@ -0,0 +1,177 @@
|
||||
# This config contains the default values for training 24khz EnCodec model
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: EnCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 24000
|
||||
train_n_samples: 24000
|
||||
down_sample_rates: [2, 4, 5, 8]
|
||||
up_sample_rates: [8, 5, 4, 2]
|
||||
# The number of samples per encoded audio frame. Should be the product of the down_sample_rates.
|
||||
# For example 2 * 4 * 5 * 8 = 320.
|
||||
samples_per_frame: 320
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${samples_per_frame}
|
||||
|
||||
mel_loss_l1_scale: 1.0
|
||||
mel_loss_l2_scale: 1.0
|
||||
stft_loss_scale: 0.0
|
||||
time_domain_loss_scale: 0.1
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 2/3 times (2 updates for every 3 batches)
|
||||
disc_updates_per_period: 2
|
||||
disc_update_period: 3
|
||||
|
||||
# All resolutions for reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]
|
||||
]
|
||||
mel_loss_dims: [64, 64, 64, 64, 64, 64, 64]
|
||||
mel_loss_log_guard: 1E-5
|
||||
stft_loss_log_guard: 1.0
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 1.01
|
||||
max_duration: null
|
||||
dataset_meta: ${train_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 8
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50, 100, 150, 200]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 15.0 # Only log the first 15 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.SEANetEncoder
|
||||
down_sample_rates: ${down_sample_rates}
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.SEANetDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.ResidualVectorQuantizer
|
||||
num_codebooks: 8
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.encodec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]]
|
||||
|
||||
# The original EnCodec uses hinged loss, but squared-GAN loss is more stable
|
||||
# and reduces the need to tune the loss weights or use a gradient balancer.
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 3e-4
|
||||
betas: [0.5, 0.9]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.999
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32 # Vector quantization only works with 32-bit precision.
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: false
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,194 @@
|
||||
# This config contains the default values for training 22.05kHz audio codec model which encodes mel spectrogram
|
||||
# instead of raw audio.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: MelCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 22050
|
||||
win_length: 1024
|
||||
hop_length: 256
|
||||
train_n_samples: 8192 # ~0.37 seconds
|
||||
# The product of the up_sample_rates should match the hop_length.
|
||||
# For example 8 * 8 * 2 * 2 = 256.
|
||||
up_sample_rates: [8, 8, 2, 2]
|
||||
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${hop_length}
|
||||
|
||||
mel_loss_l1_scale: 1.0
|
||||
mel_loss_l2_scale: 0.0
|
||||
stft_loss_scale: 20.0
|
||||
time_domain_loss_scale: 0.0
|
||||
commit_loss_scale: 0.0
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 1/2 times (1 update for every 2 batches)
|
||||
disc_updates_per_period: 1
|
||||
disc_update_period: 2
|
||||
|
||||
# All resolutions for mel reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]
|
||||
]
|
||||
mel_loss_dims: [5, 10, 20, 40, 80, 160, 320]
|
||||
mel_loss_log_guard: 1.0
|
||||
stft_loss_log_guard: 1.0
|
||||
feature_loss_type: absolute
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4
|
||||
max_duration: null
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50, 100, 150, 200]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only log the first 10 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.MultiBandMelEncoder
|
||||
mel_bands: [[0, 10], [10, 20], [20, 30], [30, 40], [40, 50], [50, 60], [60, 70], [70, 80]]
|
||||
out_channels: 4 # The dimension of each codebook
|
||||
hidden_channels: 128
|
||||
filters: 256
|
||||
mel_processor:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.MelSpectrogramProcessor
|
||||
mel_dim: 80
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
input_dim: 32 # Should be equal to len(audio_encoder.mel_bands) * audio_encoder.out_channels
|
||||
base_channels: 1024 # This is double the base channels of HiFi-GAN V1, making it approximately 4x larger.
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.GroupFiniteScalarQuantizer
|
||||
num_groups: 8 # Should equal len(audio_encoder.mel_bands)
|
||||
num_levels_per_group: [8, 5, 5, 5] # 8 * 5 * 5 * 5 = 1000 entries per codebook
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.Discriminator
|
||||
discriminators:
|
||||
- _target_: nemo.collections.tts.modules.encodec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]]
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiPeriodDiscriminator
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: false
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,194 @@
|
||||
# This config contains the default values for training 44.1kHz audio codec model which encodes mel spectrogram
|
||||
# instead of raw audio.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: MelCodec
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# https://github.com/NVIDIA/NeMo/blob/main/nemo/collections/tts/data/vocoder_dataset.py#L39-L41
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
log_ds_meta: ???
|
||||
log_dir: ???
|
||||
|
||||
# Modify these values based on your sample rate
|
||||
sample_rate: 44100
|
||||
win_length: 2048
|
||||
hop_length: 512
|
||||
train_n_samples: 16384 # ~0.37 seconds
|
||||
# The product of the up_sample_rates should match the hop_length.
|
||||
# For example 8 * 8 * 4 * 2 = 512.
|
||||
up_sample_rates: [8, 8, 4, 2]
|
||||
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
samples_per_frame: ${hop_length}
|
||||
|
||||
mel_loss_l1_scale: 1.0
|
||||
mel_loss_l2_scale: 0.0
|
||||
stft_loss_scale: 20.0
|
||||
time_domain_loss_scale: 0.0
|
||||
commit_loss_scale: 0.0
|
||||
|
||||
# Probability of updating the discriminator during each training step
|
||||
# For example, update the discriminator 1/2 times (1 update for every 2 batches)
|
||||
disc_updates_per_period: 1
|
||||
disc_update_period: 2
|
||||
|
||||
# All resolutions for mel reconstruction loss, ordered [num_fft, hop_length, window_length]
|
||||
loss_resolutions: [
|
||||
[32, 8, 32], [64, 16, 64], [128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]
|
||||
]
|
||||
mel_loss_dims: [5, 10, 20, 40, 80, 160, 320]
|
||||
mel_loss_log_guard: 1.0
|
||||
stft_loss_log_guard: 1.0
|
||||
feature_loss_type: absolute
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4
|
||||
max_duration: null
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
drop_last: true
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only use the first 10 seconds of audio for computing validation loss
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
# Configures how audio samples are generated and saved during training.
|
||||
# Remove this section to disable logging.
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50, 100, 150, 200]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.AudioCodecArtifactGenerator
|
||||
log_audio: true
|
||||
log_encoding: false
|
||||
log_dequantized: false
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 10.0 # Only log the first 10 seconds of generated audio.
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
audio_encoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.MultiBandMelEncoder
|
||||
mel_bands: [[0, 10], [10, 20], [20, 30], [30, 40], [40, 50], [50, 60], [60, 70], [70, 80]]
|
||||
out_channels: 4 # The dimension of each codebook
|
||||
hidden_channels: 128
|
||||
filters: 256
|
||||
mel_processor:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.MelSpectrogramProcessor
|
||||
mel_dim: 80
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
|
||||
audio_decoder:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.HiFiGANDecoder
|
||||
up_sample_rates: ${up_sample_rates}
|
||||
input_dim: 32 # Should be equal to len(audio_encoder.mel_bands) * audio_encoder.out_channels
|
||||
base_channels: 1024 # This is double the base channels of HiFi-GAN V1, making it approximately 4x larger.
|
||||
|
||||
vector_quantizer:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.GroupFiniteScalarQuantizer
|
||||
num_groups: 8 # Should equal len(audio_encoder.mel_bands)
|
||||
num_levels_per_group: [8, 5, 5, 5] # 8 * 5 * 5 * 5 = 1000 entries per codebook
|
||||
|
||||
discriminator:
|
||||
_target_: nemo.collections.tts.modules.audio_codec_modules.Discriminator
|
||||
discriminators:
|
||||
- _target_: nemo.collections.tts.modules.encodec_modules.MultiResolutionDiscriminatorSTFT
|
||||
resolutions: [[128, 32, 128], [256, 64, 256], [512, 128, 512], [1024, 256, 1024], [2048, 512, 2048]]
|
||||
- _target_: nemo.collections.tts.modules.audio_codec_modules.MultiPeriodDiscriminator
|
||||
|
||||
generator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.GeneratorSquaredLoss
|
||||
|
||||
discriminator_loss:
|
||||
_target_: nemo.collections.tts.losses.audio_codec_loss.DiscriminatorSquaredLoss
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: false
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,242 @@
|
||||
# This config contains the default values for training FastPitch model with aligner using 22KHz sampling
|
||||
# rate. If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 132.524658203125 for https://zenodo.org/record/5525342/files/thorsten-neutral_v03.tgz?download=1
|
||||
pitch_std: ??? # e.g. 37.389366149902 for https://zenodo.org/record/5525342/files/thorsten-neutral_v03.tgz?download=1
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: de
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.GermanCharsTokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [ 0.9, 0.999 ]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # specify all GPUs regardless of its availability
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1500
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,257 @@
|
||||
# This config contains the default values for training FastPitch model with aligner using 22KHz sampling
|
||||
# rate. If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 132.524658203125 for https://zenodo.org/record/5525342/files/thorsten-neutral_v03.tgz?download=1
|
||||
pitch_std: ??? # e.g. 37.389366149902 for https://zenodo.org/record/5525342/files/thorsten-neutral_v03.tgz?download=1
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/de/de_nv230119.dict"
|
||||
heteronyms_path: "scripts/tts_dataset_files/de/de_nv230119.heteronyms"
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: de
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
locale: 'de-DE'
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
locale: 'de-DE'
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.8
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
grapheme_case: mixed
|
||||
grapheme_prefix: '#'
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [ 0.9, 0.999 ]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # specify all GPUs regardless of its availability
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1500
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,242 @@
|
||||
# This config contains the default values for training FastPitch model with aligner using 44.1KHz sampling
|
||||
# rate. If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch", "speaker_id" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 151.9578857421875 for top-5 speakers in https://github.com/iisys-hof/HUI-Audio-Corpus-German
|
||||
pitch_std: ??? # e.g. 87.1997680664063 for top-5 speakers in https://github.com/iisys-hof/HUI-Audio-Corpus-German
|
||||
|
||||
# Default values for dataset with sample_rate=44100
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 119 # change to the number of speakers in your dataset. Make sure it is at least the largest speaker_id + 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: de
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.GermanCharsTokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [ 0.9, 0.999 ]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # specify all GPUs regardless of its availability
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1500
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,237 @@
|
||||
# This config contains the default values for training FastPitch model with aligner using 44.1KHz sampling
|
||||
# rate. If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch", "speaker_id" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 151.9578857421875 for top-5 speakers in https://github.com/iisys-hof/HUI-Audio-Corpus-German
|
||||
pitch_std: ??? # e.g. 87.1997680664063 for top-5 speakers in https://github.com/iisys-hof/HUI-Audio-Corpus-German
|
||||
|
||||
# Default values for dataset with sample_rate=44100
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 119 # change to the number of speakers in your dataset. Make sure it is at least the largest speaker_id + 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: de
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.GermanPhonemesTokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: false
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15 # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: false
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [ 0.9, 0.999 ]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # specify all GPUs regardless of its availability
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1500
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,223 @@
|
||||
# This config contains the default values for training grapheme Spanish FastPitch model with aligner using
|
||||
# 44.1KHz sampling rate. If you want to train model on other dataset, you can change config values according
|
||||
# to your dataset. Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: ["align_prior_matrix", "pitch"]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 178.86880493164062 for 174 speakers in https://research.google/pubs/pub49150/
|
||||
pitch_std: ??? # e.g. 60.64979553222656 for 174 speakers in https://research.google/pubs/pub49150/
|
||||
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.SpanishCharsTokenizer
|
||||
pad_with_space: true
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # number of gpus
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_steps: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,236 @@
|
||||
# This config contains the default values for training IPA Spanish FastPitch model with aligner using
|
||||
# 44.1KHz sampling rate. If you want to train model on other dataset, you can change config values according
|
||||
# to your dataset. Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: ["align_prior_matrix", "pitch"]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 178.86880493164062 for 174 speakers in https://research.google/pubs/pub49150/
|
||||
pitch_std: ??? # e.g. 60.64979553222656 for 174 speakers in https://research.google/pubs/pub49150/
|
||||
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: ???
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
locale: es-ES
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
locale: es-ES
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
phoneme_probability: 0.5
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # number of gpus
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_steps: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,231 @@
|
||||
# This config contains the default values for training multi-speaker IPA Spanish FastPitch model with aligner using
|
||||
# 44.1KHz sampling rate. If you want to train model on other dataset, you can change config values according
|
||||
# to your dataset. Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: ["align_prior_matrix", "pitch", "speaker_id"]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# See "scripts/tts_dataset_files/openslr_es/pitch_stats.json" for format example
|
||||
pitch_stats_path: ???
|
||||
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: ???
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: ???
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
speaker_emb_condition_prosody: true
|
||||
speaker_emb_condition_aligner: true
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
locale: es-ES
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
locale: es-ES
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
phoneme_probability: 0.5
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_stats_path: ${pitch_stats_path}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: 15
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_stats_path: ${pitch_stats_path}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # number of gpus
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_steps: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,286 @@
|
||||
# This config contains the default values for training an English 22.05kHz FastPitch model.
|
||||
# If you want to train a model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
max_epochs: ???
|
||||
batch_size: 32
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
n_speakers: ???
|
||||
speaker_path: null
|
||||
feature_stats_path: null
|
||||
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
log_ds_meta: ???
|
||||
|
||||
phoneme_dict_path: ???
|
||||
heteronyms_path: ???
|
||||
|
||||
log_dir: ???
|
||||
vocoder_type: ???
|
||||
vocoder_name: null
|
||||
vocoder_checkpoint_path: null
|
||||
|
||||
# The below feature config should match the feature.yaml config used during preprocessing.
|
||||
sample_rate: 22050
|
||||
win_length: 1024
|
||||
hop_length: 256
|
||||
|
||||
mel_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.MelSpectrogramFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
mel_dim: 80
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
|
||||
pitch_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.PitchFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
pitch_fmin: 60
|
||||
pitch_fmax: 640
|
||||
|
||||
energy_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.EnergyFeaturizer
|
||||
spec_featurizer: ${mel_feature}
|
||||
|
||||
featurizers:
|
||||
pitch: ${pitch_feature}
|
||||
energy: ${energy_feature}
|
||||
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: ${n_speakers}
|
||||
n_mel_channels: ${mel_feature.mel_dim}
|
||||
min_token_duration: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
energy_embedding_kernel_size: 3
|
||||
speaker_emb_condition_prosody: true
|
||||
speaker_emb_condition_aligner: true
|
||||
use_log_energy: false
|
||||
dur_loss_scale: 0.1
|
||||
pitch_loss_scale: 0.1
|
||||
energy_loss_scale: 0.1
|
||||
aligner_loss_scale: 0.1
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${mel_feature.mel_dim}
|
||||
lowfreq: ${mel_feature.lowfreq}
|
||||
highfreq: ${mel_feature.highfreq}
|
||||
n_fft: ${win_length}
|
||||
n_window_size: ${win_length}
|
||||
window_size: false
|
||||
n_window_stride: ${hop_length}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${sample_rate}
|
||||
window: hann
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1.0
|
||||
mag_power: 1.0
|
||||
mel_norm: null
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.8
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
|
||||
pitch_processor:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.feature_processors.MeanVarianceSpeakerNormalization
|
||||
field: pitch
|
||||
stats_path: ${feature_stats_path}
|
||||
|
||||
energy_processor:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.feature_processors.MeanVarianceSpeakerNormalization
|
||||
field: energy
|
||||
stats_path: ${feature_stats_path}
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.TextToSpeechDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
speaker_path: ${speaker_path}
|
||||
align_prior_hop_length: ${hop_length}
|
||||
featurizers: ${featurizers}
|
||||
feature_processors:
|
||||
pitch: ${model.pitch_processor}
|
||||
energy: ${model.energy_processor}
|
||||
min_duration: 0.1
|
||||
max_duration: 10.0
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.TextToSpeechDataset
|
||||
dataset_meta: ${val_ds_meta}
|
||||
sample_rate: ${sample_rate}
|
||||
speaker_path: ${speaker_path}
|
||||
align_prior_hop_length: ${hop_length}
|
||||
featurizers: ${featurizers}
|
||||
feature_processors:
|
||||
pitch: ${model.pitch_processor}
|
||||
energy: ${model.energy_processor}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 2
|
||||
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.FastPitchArtifactGenerator
|
||||
log_spectrogram: true
|
||||
log_alignment: true
|
||||
audio_params:
|
||||
_target_: nemo.collections.tts.parts.utils.callbacks.LogAudioParams
|
||||
log_audio_gta: true
|
||||
vocoder_type: ${vocoder_type}
|
||||
vocoder_name: ${vocoder_name}
|
||||
vocoder_checkpoint_path: ${vocoder_checkpoint_path}
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.TextToSpeechDataset
|
||||
text_tokenizer: ${model.text_tokenizer}
|
||||
sample_rate: ${sample_rate}
|
||||
speaker_path: ${speaker_path}
|
||||
align_prior_hop_length: ${hop_length}
|
||||
featurizers: ${featurizers}
|
||||
|
||||
feature_processors:
|
||||
pitch: ${model.pitch_processor}
|
||||
energy: ${model.energy_processor}
|
||||
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 8
|
||||
num_workers: 2
|
||||
|
||||
input_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 2
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
dist_type: cosine
|
||||
temperature: 15.0
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
energy_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 10.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,286 @@
|
||||
# This config contains the default values for training an English 44.1kHz FastPitch model.
|
||||
# If you want to train a model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
max_epochs: ???
|
||||
batch_size: 32
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
n_speakers: ???
|
||||
speaker_path: null
|
||||
feature_stats_path: null
|
||||
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
log_ds_meta: ???
|
||||
|
||||
phoneme_dict_path: ???
|
||||
heteronyms_path: ???
|
||||
|
||||
log_dir: ???
|
||||
vocoder_type: ???
|
||||
vocoder_name: null
|
||||
vocoder_checkpoint_path: null
|
||||
|
||||
# The below feature config should match the feature.yaml config used during preprocessing.
|
||||
sample_rate: 44100
|
||||
win_length: 2048
|
||||
hop_length: 512
|
||||
|
||||
mel_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.MelSpectrogramFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
mel_dim: 80
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
|
||||
pitch_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.PitchFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
pitch_fmin: 60
|
||||
pitch_fmax: 640
|
||||
|
||||
energy_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.EnergyFeaturizer
|
||||
spec_featurizer: ${mel_feature}
|
||||
|
||||
featurizers:
|
||||
pitch: ${pitch_feature}
|
||||
energy: ${energy_feature}
|
||||
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: ${n_speakers}
|
||||
n_mel_channels: ${mel_feature.mel_dim}
|
||||
min_token_duration: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
energy_embedding_kernel_size: 3
|
||||
speaker_emb_condition_prosody: true
|
||||
speaker_emb_condition_aligner: true
|
||||
use_log_energy: false
|
||||
dur_loss_scale: 0.1
|
||||
pitch_loss_scale: 0.1
|
||||
energy_loss_scale: 0.1
|
||||
aligner_loss_scale: 0.1
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${mel_feature.mel_dim}
|
||||
lowfreq: ${mel_feature.lowfreq}
|
||||
highfreq: ${mel_feature.highfreq}
|
||||
n_fft: ${win_length}
|
||||
n_window_size: ${win_length}
|
||||
window_size: false
|
||||
n_window_stride: ${hop_length}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${sample_rate}
|
||||
window: hann
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1.0
|
||||
mag_power: 1.0
|
||||
mel_norm: null
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.8
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
|
||||
pitch_processor:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.feature_processors.MeanVarianceSpeakerNormalization
|
||||
field: pitch
|
||||
stats_path: ${feature_stats_path}
|
||||
|
||||
energy_processor:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.feature_processors.MeanVarianceSpeakerNormalization
|
||||
field: energy
|
||||
stats_path: ${feature_stats_path}
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.TextToSpeechDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
speaker_path: ${speaker_path}
|
||||
align_prior_hop_length: ${hop_length}
|
||||
featurizers: ${featurizers}
|
||||
feature_processors:
|
||||
pitch: ${model.pitch_processor}
|
||||
energy: ${model.energy_processor}
|
||||
min_duration: 0.1
|
||||
max_duration: 10.0
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.TextToSpeechDataset
|
||||
dataset_meta: ${val_ds_meta}
|
||||
sample_rate: ${sample_rate}
|
||||
speaker_path: ${speaker_path}
|
||||
align_prior_hop_length: ${hop_length}
|
||||
featurizers: ${featurizers}
|
||||
feature_processors:
|
||||
pitch: ${model.pitch_processor}
|
||||
energy: ${model.energy_processor}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 2
|
||||
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.FastPitchArtifactGenerator
|
||||
log_spectrogram: true
|
||||
log_alignment: true
|
||||
audio_params:
|
||||
_target_: nemo.collections.tts.parts.utils.callbacks.LogAudioParams
|
||||
log_audio_gta: true
|
||||
vocoder_type: ${vocoder_type}
|
||||
vocoder_name: ${vocoder_name}
|
||||
vocoder_checkpoint_path: ${vocoder_checkpoint_path}
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.TextToSpeechDataset
|
||||
text_tokenizer: ${model.text_tokenizer}
|
||||
sample_rate: ${sample_rate}
|
||||
speaker_path: ${speaker_path}
|
||||
align_prior_hop_length: ${hop_length}
|
||||
featurizers: ${featurizers}
|
||||
|
||||
feature_processors:
|
||||
pitch: ${model.pitch_processor}
|
||||
energy: ${model.energy_processor}
|
||||
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 8
|
||||
num_workers: 2
|
||||
|
||||
input_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 2
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
dist_type: cosine
|
||||
temperature: 15.0
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
energy_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 10.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,248 @@
|
||||
# This config contains the default values for training FastPitch model with aligner using 44.1KHz sampling
|
||||
# rate. If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 212.35873413085938 for LJSpeech
|
||||
pitch_std: ??? # e.g. 68.52806091308594 for LJSpeech
|
||||
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/cmudict-0.7b_nv22.10"
|
||||
heteronyms_path: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: en
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.EnglishPhonemesTokenizer
|
||||
punct: true
|
||||
stresses: true
|
||||
chars: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.en_us_arpabet.EnglishG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.5
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: null
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # number of gpus
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1500
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: False # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: True
|
||||
create_checkpoint_callback: True
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
# This config contains the default values for training FastPitch speaker adaptation
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch", "speaker_id", "reference_audio"]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 212.35873413085938 for LJSpeech
|
||||
pitch_std: ??? # e.g. 68.52806091308594 for LJSpeech
|
||||
|
||||
# Default values for dataset with sample_rate=44100
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: 8000
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/cmudict-0.7b_nv22.10"
|
||||
heteronyms_path: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
|
||||
reference_audio_type: "same-speaker" # options: ["same-speaker", "ground-truth"]
|
||||
|
||||
model:
|
||||
unfreeze_aligner: false
|
||||
unfreeze_duration_predictor: false
|
||||
unfreeze_pitch_predictor: false
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: en
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.EnglishPhonemesTokenizer
|
||||
punct: true
|
||||
stresses: true
|
||||
chars: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.modules.EnglishG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.5
|
||||
|
||||
adapter:
|
||||
# Config of the adapter training/eval script.
|
||||
adapter_name: "adapter" # Name of the adapter, used by the script
|
||||
adapter_module_name: "encoder+decoder+duration_predictor+pitch_predictor+aligner" # Name of the adapter module. Combine multiple modules with '+' between module names.
|
||||
adapter_state_dict_name: "adapters.pt" # If the individual adapters must be saved, a file name can be provided here. null disables this.
|
||||
|
||||
# Config of the adapter module itself
|
||||
_target_: nemo.collections.common.parts.adapter_modules.LinearAdapter
|
||||
in_features: ${model.symbols_embedding_dim} # User must provide the output dimension of the layers of the model, which is the input dimension of this adapter.
|
||||
dim: 256 # The hidden dimension of the adapter, as chosen by user, but small values are preferred to reduce param count.
|
||||
activation: swish
|
||||
norm_position: 'pre' # Can be `pre` or `post`
|
||||
dropout: 0.0 # float, dropout for the adapter
|
||||
|
||||
# Adapter strategy config
|
||||
adapter_strategy:
|
||||
_target_: nemo.core.classes.mixins.adapter_mixin_strategies.ResidualAddAdapterStrategy
|
||||
stochastic_depth: 0.0 # float, setting to > 0 will enable stochastic depth for each adapter block.
|
||||
l2_lambda: 0.0 # float, setting to > 0 will enable l2 norm auxiliary loss for each adapter's output.
|
||||
|
||||
# Optional global config available to all adapters at a global level.
|
||||
# A global config is shared across every layer of the adapters, defining global properties rather
|
||||
# than properties local to the adapter (as defined above).
|
||||
# This can be useful in order to select *which type of adapter* is added, *what adapters to enable*,
|
||||
# and further global operations that can decide dynamically how to support the requested adapter.
|
||||
global_cfg:
|
||||
check_encoder_adapter: True # determines whether to check if encoder adapter modules is supported
|
||||
check_decoder_adapter: True # determines whether to check if decoder adapter modules is supported
|
||||
check_duration_predictor_adapter: True # determines whether to check if duration_predictor adapter modules is supported
|
||||
check_pitch_predictor_adapter: True # determines whether to check if pitch_predictor adapter modules is supported
|
||||
check_aligner_adapter: True # determines whether to check if aligner adapter modules is supported
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
reference_audio_type: ${reference_audio_type}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
reference_audio_type: ${reference_audio_type}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
condition_types: [ "add" ] # options: [ "add", "concat" ]
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
speaker_encoder:
|
||||
_target_: nemo.collections.tts.modules.submodules.SpeakerEncoder
|
||||
precomputed_embedding_dim: null
|
||||
lookup_module:
|
||||
_target_: nemo.collections.tts.modules.submodules.SpeakerLookupTable
|
||||
n_speakers: ???
|
||||
embedding_dim: ${model.symbols_embedding_dim}
|
||||
gst_module:
|
||||
_target_: nemo.collections.tts.modules.submodules.GlobalStyleToken
|
||||
gst_size: ${model.symbols_embedding_dim}
|
||||
n_style_token: 10
|
||||
n_style_attn_head: 4
|
||||
reference_encoder:
|
||||
_target_: nemo.collections.tts.modules.submodules.ReferenceEncoder
|
||||
n_mels: ${model.n_mel_channels}
|
||||
cnn_filters: [32, 32, 64, 64, 128, 128]
|
||||
dropout: 0.2
|
||||
gru_hidden: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
stride: 2
|
||||
padding: 1
|
||||
bias: true
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 1
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,247 @@
|
||||
# This config contains the default values for training a FastPitch model with aligner.
|
||||
# If you want to train a model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 212.35873413085938 for LJSpeech
|
||||
pitch_std: ??? # e.g. 68.52806091308594 for LJSpeech
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: 8000
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms_path: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: en
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.8
|
||||
# Relies on the heteronyms list for anything that needs to be disambiguated
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: null
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 32
|
||||
max_epochs: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,328 @@
|
||||
# This config contains the default values for training FastPitch speaker adaptation
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch", "speaker_id", "reference_audio"]
|
||||
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 212.35873413085938 for LJSpeech
|
||||
pitch_std: ??? # e.g. 68.52806091308594 for LJSpeech
|
||||
|
||||
# Default values for dataset with sample_rate=44100
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: 8000
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms_path: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
|
||||
reference_audio_type: "same-speaker" # options: ["same-speaker", "ground-truth"]
|
||||
|
||||
model:
|
||||
unfreeze_aligner: false
|
||||
unfreeze_duration_predictor: false
|
||||
unfreeze_pitch_predictor: false
|
||||
unfreeze_energy_predictor: false
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
energy_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: en
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.modules.IPAG2P
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.8
|
||||
# Relies on the heteronyms list for anything that needs to be disambiguated
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
|
||||
adapter:
|
||||
# Config of the adapter training/eval script.
|
||||
adapter_name: "adapter" # Name of the adapter, used by the script
|
||||
adapter_module_name: "encoder+decoder+duration_predictor+pitch_predictor+aligner" # Name of the adapter module. Combine multiple modules with '+' between module names.
|
||||
adapter_state_dict_name: "adapters.pt" # If the individual adapters must be saved, a file name can be provided here. null disables this.
|
||||
|
||||
# Config of the adapter module itself
|
||||
_target_: nemo.collections.common.parts.adapter_modules.LinearAdapter
|
||||
in_features: ${model.symbols_embedding_dim} # User must provide the output dimension of the layers of the model, which is the input dimension of this adapter.
|
||||
dim: 256 # The hidden dimension of the adapter, as chosen by user, but small values are preferred to reduce param count.
|
||||
activation: swish
|
||||
norm_position: 'pre' # Can be `pre` or `post`
|
||||
dropout: 0.0 # float, dropout for the adapter
|
||||
|
||||
# Adapter strategy config
|
||||
adapter_strategy:
|
||||
_target_: nemo.core.classes.mixins.adapter_mixin_strategies.ResidualAddAdapterStrategy
|
||||
stochastic_depth: 0.0 # float, setting to > 0 will enable stochastic depth for each adapter block.
|
||||
l2_lambda: 0.0 # float, setting to > 0 will enable l2 norm auxiliary loss for each adapter's output.
|
||||
|
||||
# Optional global config available to all adapters at a global level.
|
||||
# A global config is shared across every layer of the adapters, defining global properties rather
|
||||
# than properties local to the adapter (as defined above).
|
||||
# This can be useful in order to select *which type of adapter* is added, *what adapters to enable*,
|
||||
# and further global operations that can decide dynamically how to support the requested adapter.
|
||||
global_cfg:
|
||||
check_encoder_adapter: True # determines whether to check if encoder adapter modules is supported
|
||||
check_decoder_adapter: True # determines whether to check if decoder adapter modules is supported
|
||||
check_duration_predictor_adapter: True # determines whether to check if duration_predictor adapter modules is supported
|
||||
check_pitch_predictor_adapter: True # determines whether to check if pitch_predictor adapter modules is supported
|
||||
check_aligner_adapter: True # determines whether to check if aligner adapter modules is supported
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
reference_audio_type: ${reference_audio_type}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
reference_audio_type: ${reference_audio_type}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
condition_types: [ "add" ] # options: [ "add", "concat" ]
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
energy_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
condition_types: [ "add", "layernorm" ] # options: [ "add", "concat", "layernorm" ]
|
||||
|
||||
speaker_encoder:
|
||||
_target_: nemo.collections.tts.modules.submodules.SpeakerEncoder
|
||||
precomputed_embedding_dim: null
|
||||
lookup_module:
|
||||
_target_: nemo.collections.tts.modules.submodules.SpeakerLookupTable
|
||||
n_speakers: ???
|
||||
embedding_dim: ${model.symbols_embedding_dim}
|
||||
gst_module:
|
||||
_target_: nemo.collections.tts.modules.submodules.GlobalStyleToken
|
||||
gst_size: ${model.symbols_embedding_dim}
|
||||
n_style_token: 10
|
||||
n_style_attn_head: 4
|
||||
reference_encoder:
|
||||
_target_: nemo.collections.tts.modules.submodules.ReferenceEncoder
|
||||
n_mels: ${model.n_mel_channels}
|
||||
cnn_filters: [32, 32, 64, 64, 128, 128]
|
||||
dropout: 0.2
|
||||
gru_hidden: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
stride: 2
|
||||
padding: 1
|
||||
bias: true
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 1
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,248 @@
|
||||
# This config contains the default values for training FastPitch model with aligner on LJSpeech dataset.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 2093.004522404789
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 212.35873413085938 for LJSpeech
|
||||
pitch_std: ??? # e.g. 68.52806091308594 for LJSpeech
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: 8000
|
||||
window: hann
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/cmudict-0.7b_nv22.10"
|
||||
heteronyms_path: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: en
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.EnglishPhonemesTokenizer
|
||||
punct: true
|
||||
stresses: true
|
||||
chars: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.en_us_arpabet.EnglishG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
heteronyms: ${heteronyms_path}
|
||||
phoneme_probability: 0.5
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null
|
||||
min_duration: null
|
||||
ignore_file: null
|
||||
trim: false
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
use_beta_binomial_interpolator: true
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,184 @@
|
||||
# This config contains the default values for training FastPitch model with aligner on LJSpeech dataset.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
ssl_model_ckpt_path: ???
|
||||
hifi_ckpt_path: ???
|
||||
sup_data_dir: null
|
||||
|
||||
# LJSpeech stats (per frame)
|
||||
# ignored if pitch_normalization: speaker_wise
|
||||
pitch_mean: ??? #212.35873413085938
|
||||
pitch_std: ??? #68.52806091308594
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: 8000
|
||||
window: hann
|
||||
|
||||
|
||||
ssl_content_emb_type: "embedding_and_probs"
|
||||
speaker_stats_pitch_fp: null
|
||||
pitch_normalization: speaker_wise
|
||||
use_unique_tokens: true
|
||||
speaker_conditioning_type: per_sample
|
||||
segment_speaker_embedding: true
|
||||
ssl_downsampling_factor: 4 # How many mel-spectrogram frames map to one content embedding in the SSL model
|
||||
|
||||
model:
|
||||
ssl_model_ckpt_path: ${ssl_model_ckpt_path}
|
||||
ssl_downsampling_factor: ${ssl_downsampling_factor}
|
||||
use_encoder: true
|
||||
use_duration_predictor: ${use_unique_tokens}
|
||||
pitch_conditioning: true
|
||||
pitch_loss_scale: 1.0
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
n_datasets: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
content_emb_indim: 174
|
||||
speaker_emb_indim: 256
|
||||
content_emb_outdim: 192
|
||||
speaker_emb_outdim: 192
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.FastPitchSSLDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
ssl_content_emb_type: ${ssl_content_emb_type}
|
||||
pitch_conditioning: true
|
||||
pitch_normalization: ${pitch_normalization}
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
speaker_stats_pitch_fp: ${speaker_stats_pitch_fp}
|
||||
min_duration: 0.5
|
||||
max_duration: 16.0
|
||||
pad_multiple: 1024
|
||||
speaker_conditioning_type: ${speaker_conditioning_type}
|
||||
sup_data_dir: ${sup_data_dir}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 2
|
||||
num_workers: 8
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.FastPitchSSLDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
ssl_content_emb_type: ${ssl_content_emb_type}
|
||||
pitch_conditioning: true
|
||||
pitch_normalization: ${pitch_normalization}
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
speaker_stats_pitch_fp: ${speaker_stats_pitch_fp}
|
||||
min_duration: 0.5
|
||||
max_duration: 16.0
|
||||
pad_multiple: 1024
|
||||
speaker_conditioning_type: ${speaker_conditioning_type}
|
||||
sup_data_dir: ${sup_data_dir}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 2
|
||||
num_workers: 0
|
||||
pin_memory: true
|
||||
|
||||
# both encoder and decoder have same architecture, FFTransformerDecoder
|
||||
encoder: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 0.0002
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 32
|
||||
max_epochs: 1000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: v_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,28 @@
|
||||
sample_rate: 22050
|
||||
win_length: 1024
|
||||
hop_length: 256
|
||||
|
||||
mel_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.MelSpectrogramFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
mel_dim: 80
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
|
||||
pitch_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.PitchFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
pitch_fmin: 60
|
||||
pitch_fmax: 640
|
||||
|
||||
energy_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.EnergyFeaturizer
|
||||
spec_featurizer: ${mel_feature}
|
||||
|
||||
featurizers:
|
||||
pitch: ${pitch_feature}
|
||||
energy: ${energy_feature}
|
||||
@@ -0,0 +1,28 @@
|
||||
sample_rate: 44100
|
||||
win_length: 2048
|
||||
hop_length: 512
|
||||
|
||||
mel_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.MelSpectrogramFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
mel_dim: 80
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
|
||||
pitch_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.PitchFeaturizer
|
||||
sample_rate: ${sample_rate}
|
||||
win_length: ${win_length}
|
||||
hop_length: ${hop_length}
|
||||
pitch_fmin: 60
|
||||
pitch_fmax: 640
|
||||
|
||||
energy_feature:
|
||||
_target_: nemo.collections.tts.parts.preprocessing.features.EnergyFeaturizer
|
||||
spec_featurizer: ${mel_feature}
|
||||
|
||||
featurizers:
|
||||
pitch: ${pitch_feature}
|
||||
energy: ${energy_feature}
|
||||
@@ -0,0 +1,99 @@
|
||||
# This config contains the default values for training HiFi-GAN model on LJSpeech dataset.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: "HifiGan"
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: 8000
|
||||
window: hann
|
||||
|
||||
train_n_segments: 8192
|
||||
train_max_duration: null
|
||||
train_min_duration: 0.75
|
||||
|
||||
val_n_segments: 66048
|
||||
val_max_duration: null
|
||||
val_min_duration: 3
|
||||
|
||||
defaults:
|
||||
- model/generator: v1
|
||||
- model/train_ds: train_ds
|
||||
- model/validation_ds: val_ds
|
||||
|
||||
model:
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.parts.preprocessing.features.FilterbankFeatures
|
||||
nfilt: ${n_mel_channels}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
n_fft: ${n_fft}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
pad_to: 0
|
||||
pad_value: -11.52
|
||||
sample_rate: ${sample_rate}
|
||||
window: ${window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: clamp
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
use_grads: false
|
||||
exact_pad: true
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 0.0002
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: CosineAnnealing
|
||||
min_lr: 1e-5
|
||||
warmup_ratio: 0.02
|
||||
|
||||
max_steps: 2500000
|
||||
l1_loss_factor: 45
|
||||
denoise_strength: 0.0025
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32
|
||||
max_steps: ${model.max_steps}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
entity: null
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,99 @@
|
||||
# This config contains the default values for training HiFi-GAN model on HiFi-TTS dataset.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: "HifiGan"
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
|
||||
# Default values for dataset with sample_rate=44100
|
||||
sample_rate: 44100
|
||||
n_mel_channels: 80
|
||||
n_window_size: 2048
|
||||
n_window_stride: 512
|
||||
n_fft: 2048
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
train_n_segments: 16384
|
||||
train_max_duration: null # change to null to include longer audios.
|
||||
train_min_duration: 0.75
|
||||
|
||||
val_n_segments: 131072
|
||||
val_max_duration: null
|
||||
val_min_duration: 3
|
||||
|
||||
defaults:
|
||||
- model/generator: v1_44100
|
||||
- model/train_ds: train_ds
|
||||
- model/validation_ds: val_ds
|
||||
|
||||
model:
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.parts.preprocessing.features.FilterbankFeatures
|
||||
nfilt: ${n_mel_channels}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
n_fft: ${n_fft}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
pad_to: 0
|
||||
pad_value: -11.52
|
||||
sample_rate: ${sample_rate}
|
||||
window: ${window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: clamp
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
use_grads: false
|
||||
exact_pad: true
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 0.0002
|
||||
betas: [0.8, 0.99]
|
||||
|
||||
sched:
|
||||
name: CosineAnnealing
|
||||
min_lr: 1e-5
|
||||
warmup_ratio: 0.02
|
||||
|
||||
max_steps: 2500000
|
||||
l1_loss_factor: 45
|
||||
denoise_strength: 0.0025
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_steps: ${model.max_steps}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
entity: null
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,7 @@
|
||||
_target_: nemo.collections.tts.modules.hifigan_modules.Generator
|
||||
resblock: 1
|
||||
upsample_rates: [8,8,2,2]
|
||||
upsample_kernel_sizes: [16,16,4,4]
|
||||
upsample_initial_channel: 512
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
@@ -0,0 +1,7 @@
|
||||
_target_: nemo.collections.tts.modules.hifigan_modules.Generator
|
||||
resblock: 1
|
||||
upsample_rates: [8,8,4,2]
|
||||
upsample_kernel_sizes: [16,16,4,4]
|
||||
upsample_initial_channel: 512
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
@@ -0,0 +1,7 @@
|
||||
_target_: nemo.collections.tts.modules.hifigan_modules.Generator
|
||||
resblock: 1
|
||||
upsample_rates: [8,8,2,2]
|
||||
upsample_kernel_sizes: [16,16,4,4]
|
||||
upsample_initial_channel: 128
|
||||
resblock_kernel_sizes: [3,7,11]
|
||||
resblock_dilation_sizes: [[1,3,5], [1,3,5], [1,3,5]]
|
||||
@@ -0,0 +1,7 @@
|
||||
_target_: nemo.collections.tts.modules.hifigan_modules.Generator
|
||||
resblock: 2
|
||||
upsample_rates: [8,8,4]
|
||||
upsample_kernel_sizes: [16,16,8]
|
||||
upsample_initial_channel: 256
|
||||
resblock_kernel_sizes: [3,5,7]
|
||||
resblock_dilation_sizes: [[1,2], [2,6], [3,12]]
|
||||
@@ -0,0 +1,13 @@
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.data.dataset.VocoderDataset"
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${sample_rate}
|
||||
n_segments: ${train_n_segments}
|
||||
max_duration: ${train_max_duration}
|
||||
min_duration: ${train_min_duration}
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 16
|
||||
num_workers: 4
|
||||
pin_memory: true
|
||||
@@ -0,0 +1,15 @@
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.data.dataset.VocoderDataset"
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${sample_rate}
|
||||
n_segments: ${train_n_segments}
|
||||
max_duration: ${train_max_duration}
|
||||
min_duration: ${train_min_duration}
|
||||
load_precomputed_mel: true
|
||||
hop_length: ${n_window_stride}
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 16
|
||||
num_workers: 4
|
||||
pin_memory: true
|
||||
@@ -0,0 +1,13 @@
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.data.dataset.VocoderDataset"
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${sample_rate}
|
||||
n_segments: ${val_n_segments}
|
||||
max_duration: ${val_max_duration}
|
||||
min_duration: ${val_min_duration}
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 16
|
||||
num_workers: 1
|
||||
pin_memory: true
|
||||
@@ -0,0 +1,15 @@
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.data.dataset.VocoderDataset"
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${sample_rate}
|
||||
n_segments: ${val_n_segments}
|
||||
max_duration: ${val_max_duration}
|
||||
min_duration: ${val_min_duration}
|
||||
load_precomputed_mel: true
|
||||
hop_length: ${n_window_stride}
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 16
|
||||
num_workers: 4
|
||||
pin_memory: true
|
||||
@@ -0,0 +1,151 @@
|
||||
# This config contains the default values for training a 22.05kHz HiFi-GAN model.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: "HifiGan"
|
||||
|
||||
max_epochs: ???
|
||||
batch_size: 16
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
log_ds_meta: ???
|
||||
|
||||
log_dir: ???
|
||||
|
||||
mel_dim: 80
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
|
||||
# Change these values depending on your sampling rate.
|
||||
sample_rate: 22050
|
||||
win_length: 1024
|
||||
hop_length: 256
|
||||
upsample_rates: [8, 8, 2, 2]
|
||||
train_n_samples: 8192
|
||||
val_min_duration_seconds: 3.0
|
||||
val_n_samples: 66048
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
l1_loss_factor: 60
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.parts.preprocessing.features.FilterbankFeatures
|
||||
nfilt: ${mel_dim}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
n_fft: ${win_length}
|
||||
n_window_size: ${win_length}
|
||||
n_window_stride: ${hop_length}
|
||||
pad_to: 0
|
||||
pad_value: 0
|
||||
exact_pad: true
|
||||
sample_rate: ${sample_rate}
|
||||
window: hann
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1.0
|
||||
mag_power: 1.0
|
||||
mel_norm: null
|
||||
use_grads: false
|
||||
|
||||
generator:
|
||||
_target_: nemo.collections.tts.modules.hifigan_modules.Generator
|
||||
resblock: 1
|
||||
upsample_rates: ${upsample_rates}
|
||||
upsample_kernel_sizes: [16, 16, 4, 4]
|
||||
upsample_initial_channel: 512
|
||||
resblock_kernel_sizes: [3, 7, 11]
|
||||
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4
|
||||
max_duration: null
|
||||
dataset_meta: ${train_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${val_n_samples}
|
||||
min_duration: ${val_min_duration_seconds}
|
||||
max_duration: null
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 2
|
||||
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.VocoderArtifactGenerator
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 15.0
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
weight_decay: 1e-6
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.999
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
create_wandb_logger: false
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,151 @@
|
||||
# This config contains the default values for training a 44.1kHz HiFi-GAN model.
|
||||
# If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: "HifiGan"
|
||||
|
||||
max_epochs: ???
|
||||
batch_size: 16
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
log_ds_meta: ???
|
||||
|
||||
log_dir: ???
|
||||
|
||||
mel_dim: 80
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
|
||||
# Change these values depending on your sampling rate.
|
||||
sample_rate: 44100
|
||||
win_length: 2048
|
||||
hop_length: 512
|
||||
upsample_rates: [8, 8, 4, 2]
|
||||
train_n_samples: 16384
|
||||
val_min_duration_seconds: 3.0
|
||||
val_n_samples: 131072
|
||||
|
||||
model:
|
||||
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
l1_loss_factor: 60
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.parts.preprocessing.features.FilterbankFeatures
|
||||
nfilt: ${mel_dim}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
n_fft: ${win_length}
|
||||
n_window_size: ${win_length}
|
||||
n_window_stride: ${hop_length}
|
||||
pad_to: 0
|
||||
pad_value: 0
|
||||
exact_pad: true
|
||||
sample_rate: ${sample_rate}
|
||||
window: hann
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1.0
|
||||
mag_power: 1.0
|
||||
mel_norm: null
|
||||
use_grads: false
|
||||
|
||||
generator:
|
||||
_target_: nemo.collections.tts.modules.hifigan_modules.Generator
|
||||
resblock: 1
|
||||
upsample_rates: ${upsample_rates}
|
||||
upsample_kernel_sizes: [16, 16, 4, 4]
|
||||
upsample_initial_channel: 512
|
||||
resblock_kernel_sizes: [3, 7, 11]
|
||||
resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]]
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${train_n_samples}
|
||||
min_duration: 0.4
|
||||
max_duration: null
|
||||
dataset_meta: ${train_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: ${val_n_samples}
|
||||
min_duration: ${val_min_duration_seconds}
|
||||
max_duration: null
|
||||
dataset_meta: ${val_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 2
|
||||
|
||||
log_config:
|
||||
log_dir: ${log_dir}
|
||||
log_epochs: [10, 50]
|
||||
epoch_frequency: 100
|
||||
log_tensorboard: false
|
||||
log_wandb: false
|
||||
|
||||
generators:
|
||||
- _target_: nemo.collections.tts.parts.utils.callbacks.VocoderArtifactGenerator
|
||||
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.vocoder_dataset.VocoderDataset
|
||||
sample_rate: ${sample_rate}
|
||||
n_samples: null
|
||||
min_duration: null
|
||||
max_duration: null
|
||||
trunc_duration: 15.0
|
||||
dataset_meta: ${log_ds_meta}
|
||||
|
||||
dataloader_params:
|
||||
batch_size: 4
|
||||
num_workers: 2
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 2e-4
|
||||
betas: [0.8, 0.99]
|
||||
weight_decay: 1e-6
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.999
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 16
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 10
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
create_wandb_logger: false
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,198 @@
|
||||
name: Magpie-TTS-DecoderOnly-EN
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 2
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
model:
|
||||
# Decoder backend selection
|
||||
# Options: "huggingface" (default), "nemotron_h"
|
||||
decoder_type: "huggingface"
|
||||
disable_lm_text_head: false
|
||||
disable_subword_embedding: false
|
||||
use_bpe_char_tokenizer: true
|
||||
|
||||
# HuggingFace backend config (used when decoder_type: "huggingface")
|
||||
transformer_hf_backend: "Qwen/Qwen2.5-1.5B"
|
||||
|
||||
# NemotronH config (used when decoder_type: "nemotron_h")
|
||||
# Hybrid Mamba2/MoE/Attention model (~3B total, ~600-800M active). Layer types via hybrid_override_pattern:
|
||||
# 'M' = Mamba2 layer, '*' = Attention layer, '-' = MLP layer, 'E' = MoE layer
|
||||
nemotron_h_config:
|
||||
hidden_size: 1536 # Should match embedding_dim
|
||||
num_hidden_layers: 48
|
||||
vocab_size: 131072
|
||||
# Attention config
|
||||
num_attention_heads: 12
|
||||
num_key_value_heads: 4
|
||||
attention_dropout: 0.0
|
||||
attention_bias: false
|
||||
max_position_embeddings: 8192
|
||||
# Mamba config
|
||||
mamba_num_heads: 64
|
||||
mamba_head_dim: 24
|
||||
ssm_state_size: 128
|
||||
conv_kernel: 4
|
||||
n_groups: 8
|
||||
chunk_size: 256
|
||||
mamba_hidden_act: "silu"
|
||||
use_conv_bias: true
|
||||
use_bias: false
|
||||
# MLP config
|
||||
intermediate_size: 4096
|
||||
mlp_hidden_act: "silu"
|
||||
mlp_bias: false
|
||||
# MoE config (scaled from Nemotron-3-Nano-30B-A3B)
|
||||
n_routed_experts: 48
|
||||
num_experts_per_tok: 6
|
||||
moe_intermediate_size: 1024
|
||||
moe_shared_expert_intermediate_size: 2048
|
||||
n_group: 1
|
||||
topk_group: 1
|
||||
routed_scaling_factor: 2.5
|
||||
norm_topk_prob: true
|
||||
# Layer pattern: (M E M E M *) x 8 => 16 Mamba, 16 MoE, 8 Attention
|
||||
hybrid_override_pattern: "MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*"
|
||||
# Normalization
|
||||
layer_norm_epsilon: 1e-5
|
||||
residual_in_fp32: true
|
||||
|
||||
use_text_conditioning_encoder: true # If true, distilbert will be used to encode context_text if provided.
|
||||
context_duration_min: 5.0
|
||||
context_duration_max: 5.0
|
||||
load_cached_codes_if_available: true
|
||||
|
||||
embedding_dim: 1536
|
||||
hidden_dim: 1536
|
||||
audio_embedding_dim: 1536 # Can set a smaller dimension for audio embeddings to reduce parameters. Set equal to hidden_dim for no projection.
|
||||
codecmodel_path: ???
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
# Local transformer parameters for autoregressive codebook prediction within a frame
|
||||
local_transformer_type: "autoregressive" # "none", "autoregressive"
|
||||
# Below args are only relevant if use_local_transformer is autoregressive
|
||||
local_transformer_loss_scale: 1.0
|
||||
phoneme_loss_weight: 1.0
|
||||
local_transformer_n_layers: 3
|
||||
local_transformer_n_heads: 12
|
||||
local_transformer_hidden_dim: 1536
|
||||
|
||||
cfg_unconditional_prob: 0.05
|
||||
# To get special_tokens of the tokenzer, you can do:
|
||||
# model.tokenizer.first_tokenizer.additional_special_tokens
|
||||
|
||||
# Multi-mode training configuration
|
||||
training_modes:
|
||||
- text_input_mode: "streaming" # Options: "full", "streaming"
|
||||
streaming_phonemes_delay: 0
|
||||
streaming_speech_delay: 1
|
||||
|
||||
frame_stacking_factor: 2
|
||||
phoneme_stacking_factor: 1
|
||||
phoneme_confidence_unk_threshold: 0.0 # If max phoneme probability is below this threshold at inference-time, replace the predicted timestep with UNK to reduce error propagation.
|
||||
dropout_text_input_prob: 0.1
|
||||
phoneme_corruption_batch_prob: 0.1
|
||||
phoneme_corruption_timestep_ratio: 0.15
|
||||
phoneme_corruption_unk_mode_prob: 0.5
|
||||
phoneme_corruption_type: "repeat_skip_unk" # "repeat_skip_unk" or "complete_channel"
|
||||
phoneme_as_text_prob: 0.0 # Probability of replacing training text with pronunciation-control G2P output.
|
||||
ignore_phoneme_languages: [] # Languages for which missing IPA phoneme fields are allowed during training.
|
||||
add_language_to_context_text: false # Prefix context text with language metadata for multilingual conditioning.
|
||||
|
||||
pronunciation_control_g2p:
|
||||
en:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
phoneme_probability: 0.3
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
grapheme_case: mixed
|
||||
|
||||
phoneme_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPABPETokenizer
|
||||
tokenizer_path: ???
|
||||
|
||||
text_tokenizers:
|
||||
nemotron_nano_30b:
|
||||
_target_: AutoTokenizer
|
||||
pretrained_model: "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16"
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.MagpieTTSDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
drop_last: true
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.MagpieTTSDataset
|
||||
dataset_meta: ${val_ds_meta}
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
pin_memory: true
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 1e-4
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: bf16-mixed
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 1
|
||||
num_sanity_val_steps: 0
|
||||
benchmark: false
|
||||
gradient_clip_val: 2.5
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
entity: null
|
||||
name: ${name}
|
||||
project: null
|
||||
group: null
|
||||
resume: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
resume_if_exists: true
|
||||
resume_ignore_no_checkpoint: true
|
||||
@@ -0,0 +1,227 @@
|
||||
name: Magpie-TTS-DecoderOnly-EN
|
||||
|
||||
quadratic_duration: 20
|
||||
|
||||
# Adjust batch size based on GPU memory
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
|
||||
model:
|
||||
use_lhotse: true
|
||||
|
||||
# Decoder backend selection
|
||||
# Options: "huggingface" (default), "nemotron_h"
|
||||
decoder_type: "huggingface"
|
||||
disable_lm_text_head: false
|
||||
disable_subword_embedding: false
|
||||
use_bpe_char_tokenizer: true
|
||||
|
||||
# HuggingFace backend config (used when decoder_type: "huggingface")
|
||||
transformer_hf_backend: "Qwen/Qwen2.5-1.5B"
|
||||
|
||||
# NemotronH config (used when decoder_type: "nemotron_h")
|
||||
# Hybrid Mamba2/MoE/Attention model (~3B total, ~600-800M active). Layer types via hybrid_override_pattern:
|
||||
# 'M' = Mamba2 layer, '*' = Attention layer, '-' = MLP layer, 'E' = MoE layer
|
||||
nemotron_h_config:
|
||||
hidden_size: 1536 # Should match embedding_dim
|
||||
num_hidden_layers: 48
|
||||
vocab_size: 131072
|
||||
# Attention config
|
||||
num_attention_heads: 12
|
||||
num_key_value_heads: 4
|
||||
attention_dropout: 0.0
|
||||
attention_bias: false
|
||||
max_position_embeddings: 8192
|
||||
# Mamba config
|
||||
mamba_num_heads: 64
|
||||
mamba_head_dim: 24
|
||||
ssm_state_size: 128
|
||||
conv_kernel: 4
|
||||
n_groups: 8
|
||||
chunk_size: 256
|
||||
mamba_hidden_act: "silu"
|
||||
use_conv_bias: true
|
||||
use_bias: false
|
||||
# MLP config
|
||||
intermediate_size: 4096
|
||||
mlp_hidden_act: "silu"
|
||||
mlp_bias: false
|
||||
# MoE config (scaled from Nemotron-3-Nano-30B-A3B)
|
||||
n_routed_experts: 48
|
||||
num_experts_per_tok: 6
|
||||
moe_intermediate_size: 1024
|
||||
moe_shared_expert_intermediate_size: 2048
|
||||
n_group: 1
|
||||
topk_group: 1
|
||||
routed_scaling_factor: 2.5
|
||||
norm_topk_prob: true
|
||||
# Layer pattern: (M E M E M *) x 8 => 16 Mamba, 16 MoE, 8 Attention
|
||||
hybrid_override_pattern: "MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*MEMEM*"
|
||||
# Normalization
|
||||
layer_norm_epsilon: 1e-5
|
||||
residual_in_fp32: true
|
||||
|
||||
use_text_conditioning_encoder: true # If true, distilbert will be used to encode context_text if provided.
|
||||
context_duration_min: 5.0
|
||||
context_duration_max: 5.0
|
||||
load_cached_codes_if_available: true
|
||||
|
||||
embedding_dim: 1536
|
||||
hidden_dim: 1536
|
||||
audio_embedding_dim: 1536 # Can set a smaller dimension for audio embeddings to reduce parameters. Set equal to hidden_dim for no projection.
|
||||
codecmodel_path: ???
|
||||
|
||||
# Local transformer parameters for autoregressive codebook prediction within a frame
|
||||
local_transformer_type: "autoregressive" # "none", "autoregressive"
|
||||
# Below args are only relevant if use_local_transformer is autoregressive
|
||||
local_transformer_loss_scale: 1.0
|
||||
phoneme_loss_weight: 1.0
|
||||
local_transformer_n_layers: 3
|
||||
local_transformer_n_heads: 12
|
||||
local_transformer_hidden_dim: 1536
|
||||
|
||||
cfg_unconditional_prob: 0.05
|
||||
|
||||
# Multi-mode training configuration
|
||||
training_modes:
|
||||
- text_input_mode: "streaming" # Options: "full", "streaming"
|
||||
streaming_phonemes_delay: 0
|
||||
streaming_speech_delay: 1
|
||||
|
||||
frame_stacking_factor: 2
|
||||
phoneme_stacking_factor: 1
|
||||
phoneme_confidence_unk_threshold: 0.0 # If max phoneme probability is below this threshold at inference-time, replace the predicted timestep with UNK to reduce error propagation.
|
||||
dropout_text_input_prob: 0.1
|
||||
phoneme_corruption_batch_prob: 0.1
|
||||
phoneme_corruption_timestep_ratio: 0.15
|
||||
phoneme_corruption_unk_mode_prob: 0.5
|
||||
phoneme_corruption_type: "repeat_skip_unk" # "repeat_skip_unk" or "complete_channel"
|
||||
phoneme_as_text_prob: 0.0 # Probability of replacing training text with pronunciation-control G2P output.
|
||||
ignore_phoneme_languages: [] # Languages for which missing IPA phoneme fields are allowed during training.
|
||||
add_language_to_context_text: false # Prefix context text with language metadata for multilingual conditioning.
|
||||
|
||||
pronunciation_control_g2p:
|
||||
en:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
phoneme_probability: 0.3
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
grapheme_case: mixed
|
||||
|
||||
phoneme_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPABPETokenizer
|
||||
tokenizer_path: ???
|
||||
|
||||
text_tokenizers:
|
||||
nemotron_nano_30b:
|
||||
_target_: AutoTokenizer
|
||||
pretrained_model: "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16"
|
||||
|
||||
train_ds:
|
||||
use_lhotse: ${model.use_lhotse}
|
||||
volume_norm: true
|
||||
|
||||
dataset:
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
min_context_speaker_similarity: 0.6
|
||||
max_cer: 0.03
|
||||
batch_duration : ??? # in seconds. Adjust based on your GPU memory.
|
||||
quadratic_duration: ${quadratic_duration}
|
||||
use_bucketing: true
|
||||
num_buckets: 20
|
||||
bucket_buffer_size: 20_000
|
||||
shuffle_buffer_size: 20_000
|
||||
num_cuts_for_bins_estimate: 20_000
|
||||
shard_seed: "trng"
|
||||
drop_last: true
|
||||
shuffle: true
|
||||
num_workers: 6
|
||||
pin_memory: true
|
||||
|
||||
input_cfg:
|
||||
- type: lhotse_shar
|
||||
shar_path: ???
|
||||
weight: 1.0
|
||||
tags:
|
||||
tokenizer_names: ["english_phoneme"]
|
||||
|
||||
|
||||
validation_ds:
|
||||
use_lhotse: ${model.use_lhotse}
|
||||
volume_norm: true
|
||||
|
||||
dataset:
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
min_context_speaker_similarity: 0.6
|
||||
max_cer: 0.03
|
||||
batch_duration: ??? # recommend to use smaller batch_duration for validation dataset than training dataset.
|
||||
quadratic_duration: ${quadratic_duration}
|
||||
use_bucketing: false
|
||||
force_finite: true
|
||||
force_map_dataset: true
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
num_workers: 2
|
||||
pin_memory: true
|
||||
seed: 42
|
||||
shard_seed: "randomized"
|
||||
|
||||
input_cfg:
|
||||
- type: lhotse_shar
|
||||
shar_path: ???
|
||||
weight: 1.0
|
||||
tags:
|
||||
tokenizer_names: ["english_phoneme"]
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 1e-4
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: bf16-mixed
|
||||
max_steps: ???
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
limit_train_batches: 1_000
|
||||
val_check_interval: 1_000
|
||||
num_sanity_val_steps: 0
|
||||
benchmark: false
|
||||
use_distributed_sampler: false # required because Lhotse has its own handling
|
||||
gradient_clip_val: 2.5
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
entity: null
|
||||
name: ${name}
|
||||
project: null
|
||||
group: null
|
||||
resume: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
filename: '${name}--{${exp_manager.checkpoint_callback_params.monitor}:.4f}-{step}-{epoch}'
|
||||
resume_if_exists: true
|
||||
resume_ignore_no_checkpoint: true
|
||||
@@ -0,0 +1,202 @@
|
||||
name: Magpie-TTS
|
||||
|
||||
max_epochs: ???
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# See DatasetMeta in https://github.com/NVIDIA-NeMo/NeMo/blob/main/nemo/collections/tts/data/text_to_speech_dataset.py
|
||||
train_ds_meta: ???
|
||||
val_ds_meta: ???
|
||||
|
||||
model:
|
||||
model_type: "decoder_ce" # decoder_context_tts or decoder_ce
|
||||
use_text_conditioning_encoder: true # Enable or disable text context. Audio context is always enabled
|
||||
text_conditioning_tokenizer_name: text_ce_tokenizer # The tokenizer to be used for text contexts
|
||||
context_duration_min: 5.0
|
||||
context_duration_max: 5.0
|
||||
load_cached_codes_if_available: true
|
||||
prior_scaling_factor: 0.5
|
||||
prior_end_step: 12000
|
||||
prior_scaledown_start_step: 8000
|
||||
indefinite_prior_prob: 0.0 # If > 0, then prior will be applied after prior_end_step with this probability.
|
||||
alignment_loss_scale: 0.002
|
||||
embedding_dim: 768
|
||||
codecmodel_path: ???
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
cfg_unconditional_prob: 0.1
|
||||
|
||||
# Alignment encoder parameters, to binarize the prior
|
||||
# This is used for attention-constrained training and inference
|
||||
use_alignment_encoder: false
|
||||
# Below args are only relevant if use_alignment_encoder is true
|
||||
use_prior_for_aligner: true # Whether to use the beta-binomial prior to train the alignment encoder
|
||||
alignment_encoder_loss_scale: 1.0
|
||||
binarize_prior_after_step: 10000 # Switch from beta-binomial prior to binarized prior after this step.
|
||||
binarize_attn_method: "nemo_binarize" # nemo_binarize or argmax.
|
||||
prior_future_context: 2 # Future window of the binarized prior.
|
||||
prior_past_context: 2 # Past window of the binarized prior.
|
||||
prior_future_decay: 0.8 # Decay factor for future context
|
||||
prior_past_decay: 0.5 # Decay factor for past context
|
||||
binarize_repeat_audio_factor: 2 # Temporally increase audio timesteps, for nemo_binarize to work better. Increase this for low frame rate codecs
|
||||
binarized_prior_epsilon: 0.0
|
||||
aligner_encoder_train_steps: 50000
|
||||
|
||||
# Local transformer parameters for autoregressive codebook prediction within a frame
|
||||
local_transformer_type: "autoregressive" # "none", "autoregressive", "maskgit"
|
||||
# Below args are only relevant if use_local_transformer is true
|
||||
local_transformer_loss_scale: 1.0
|
||||
local_transformer_n_layers: 1
|
||||
local_transformer_n_heads: 1
|
||||
local_transformer_hidden_dim: 256
|
||||
|
||||
text_context_remapping_json: null # JSON file defining mapping of multiple text contexts to a single text context. Does not need to cover all text contexts.
|
||||
text_context_remapping_prob: 0.0 # Probability of remapping the original text context to a remapped text context.
|
||||
|
||||
text_tokenizers:
|
||||
english_phoneme:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: false
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
phoneme_probability: 0.8
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
text_ce_tokenizer: # Used for text context
|
||||
_target_: AutoTokenizer
|
||||
pretrained_model: "google/byt5-small"
|
||||
### For additional languages, consider adding a generic byt5 tokenizer like the one below
|
||||
# french_chartokenizer: # Used for text context
|
||||
# _target_: AutoTokenizer
|
||||
# pretrained_model: "google/byt5-small"
|
||||
|
||||
train_ds:
|
||||
datasets:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.MagpieTTSDataset
|
||||
dataset_meta: ${train_ds_meta}
|
||||
weighted_sampling_steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
drop_last: true
|
||||
pin_memory: true
|
||||
|
||||
# Non-lhotse validation uses a single dataloader. All dataset_meta entries are mixed
|
||||
# together, so validation metrics are logged jointly. For per-dataset validation
|
||||
# metrics, use the lhotse config (magpietts_lhotse.yaml) with separate datasets entries.
|
||||
validation_ds:
|
||||
datasets:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.MagpieTTSDataset
|
||||
dataset_meta: ${val_ds_meta}
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 4
|
||||
pin_memory: true
|
||||
|
||||
encoder:
|
||||
n_layers: 6
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
context_encoder: # Only used for decoder_ce (and multi_encoder_context_tts), ignored otherwise
|
||||
n_layers: 1
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: false
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
decoder:
|
||||
n_layers: 12
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 1
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: true
|
||||
xa_d_head: 128
|
||||
xa_d_memory: 768
|
||||
xa_n_heads: 1
|
||||
is_causal: true
|
||||
apply_norm_to_cond: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
make_prior_window_strict: true
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 2e-4
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 1
|
||||
num_sanity_val_steps: 0
|
||||
benchmark: false
|
||||
gradient_clip_val: 2.5
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
entity: null
|
||||
project: null
|
||||
group: null
|
||||
name: ${name}
|
||||
resume: true # enable resume to ensure continuous training log metrics merged on the previous run id.
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
filename: '${name}--{${exp_manager.checkpoint_callback_params.monitor}:.4f}-{step}'
|
||||
resume_if_exists: true
|
||||
resume_ignore_no_checkpoint: true
|
||||
@@ -0,0 +1,225 @@
|
||||
name: Magpie-TTS
|
||||
|
||||
quadratic_duration: 20 # both training and validation datasets can apply same quadratic_duration.
|
||||
|
||||
model:
|
||||
use_lhotse: true
|
||||
model_type: "decoder_ce" # decoder_context_tts or decoder_ce
|
||||
use_text_conditioning_encoder: true # Enable or disable text context. Audio context is always enabled
|
||||
text_conditioning_tokenizer_name: text_ce_tokenizer # The tokenizer to be used for text contexts
|
||||
context_duration_min: 5.0
|
||||
context_duration_max: 5.0
|
||||
load_cached_codes_if_available: true
|
||||
prior_scaling_factor: 0.5
|
||||
prior_end_step: 12000
|
||||
prior_scaledown_start_step: 8000
|
||||
indefinite_prior_prob: 0. # If > 0, then prior will be applied after prior_end_step with this probability.
|
||||
alignment_loss_scale: 0.002
|
||||
embedding_dim: 768
|
||||
codecmodel_path: ???
|
||||
cfg_unconditional_prob: 0.1 # enable classifier-free guidance during traing by dropping out conditionals with this probability
|
||||
|
||||
# Alignment encoder parameters, to binarize the prior
|
||||
# This is used for attention-constrained training and inference
|
||||
use_alignment_encoder: false
|
||||
# Below args are only relevant if use_alignment_encoder is true
|
||||
use_prior_for_aligner: true # Whether to use the beta-binomial prior to train the alignment encoder
|
||||
alignment_encoder_loss_scale: 1.0
|
||||
binarize_prior_after_step: 10000 # Switch from beta-binomial prior to binarized prior after this step.
|
||||
binarize_attn_method: "nemo_binarize" # nemo_binarize or argmax.
|
||||
prior_future_context: 2 # Future window of the binarized prior.
|
||||
prior_past_context: 2 # Past window of the binarized prior.
|
||||
prior_future_decay: 0.8 # Decay factor for future context
|
||||
prior_past_decay: 0.5 # Decay factor for past context
|
||||
binarize_repeat_audio_factor: 2 # Temporally increase audio timesteps, for nemo_binarize to work better. Increase this for low frame rate codecs
|
||||
binarized_prior_epsilon: 0.0
|
||||
aligner_encoder_train_steps: 50000
|
||||
|
||||
# Local transformer parameters for autoregressive codebook prediction within a frame
|
||||
local_transformer_type: "autoregressive" # "none", "autoregressive", "maskgit"
|
||||
# Below args are only relevant if use_local_transformer is true
|
||||
local_transformer_loss_scale: 1.0
|
||||
local_transformer_n_layers: 1
|
||||
local_transformer_n_heads: 1
|
||||
local_transformer_hidden_dim: 256
|
||||
|
||||
text_context_remapping_json: null # JSON file defining mapping of multiple text contexts to a single text context. Does not need to cover all text contexts.
|
||||
text_context_remapping_prob: 0.0 # Probability of remapping the original text context to a remapped text context.
|
||||
|
||||
text_tokenizers:
|
||||
english_phoneme:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: false
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
phoneme_probability: 0.8
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
text_ce_tokenizer: # Used for text context
|
||||
_target_: AutoTokenizer
|
||||
pretrained_model: "google/byt5-small"
|
||||
### For additional languages, consider adding a generic byt5 tokenizer like the one below
|
||||
# french_chartokenizer: # Used for text context
|
||||
# _target_: AutoTokenizer
|
||||
# pretrained_model: "google/byt5-small"
|
||||
|
||||
train_ds:
|
||||
use_lhotse: ${model.use_lhotse}
|
||||
volume_norm: true
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
min_context_speaker_similarity: 0.6
|
||||
max_cer: 0.03
|
||||
batch_duration: ??? # in seconds. Adjust based on your GPU memory.
|
||||
quadratic_duration: ${quadratic_duration}
|
||||
use_bucketing: true
|
||||
num_buckets: 20
|
||||
bucket_buffer_size: 20_000
|
||||
shuffle_buffer_size: 20_000
|
||||
num_cuts_for_bins_estimate: 20_000
|
||||
shard_seed: "trng"
|
||||
drop_last: true
|
||||
shuffle: true
|
||||
num_workers: 6
|
||||
pin_memory: true
|
||||
reweight_temperature: 1.0 # Scalar broadcasts to all levels. Use a list for per-level control, e.g. [1.0, 0.0].
|
||||
|
||||
input_cfg:
|
||||
- type: lhotse_shar
|
||||
shar_path: ???
|
||||
weight: 1.0
|
||||
tags:
|
||||
tokenizer_names: ["english_phoneme"]
|
||||
|
||||
validation_ds:
|
||||
# the entries under 'datasets' are a list of separate dataloaders.
|
||||
# The structure is:
|
||||
# - name: '<dataset-name>'
|
||||
# <dataloader-dict-config>
|
||||
# They inherit all settings from validation_ds, but can individually override them.
|
||||
use_lhotse: ${model.use_lhotse}
|
||||
volume_norm: true
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
min_context_speaker_similarity: 0.6
|
||||
max_cer: 0.03
|
||||
batch_duration: ??? # recommend to use smaller batch_duration for validation dataset than training dataset.
|
||||
quadratic_duration: ${quadratic_duration}
|
||||
use_bucketing: false
|
||||
force_finite: true
|
||||
force_map_dataset: true
|
||||
seed: 42
|
||||
shard_seed: "randomized"
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
num_workers: 2
|
||||
pin_memory: true
|
||||
|
||||
datasets:
|
||||
- name: "val_set_0" # rename to your dataset name, add more as needed
|
||||
input_cfg:
|
||||
- type: lhotse_shar
|
||||
shar_path: ???
|
||||
weight: 1.0
|
||||
tags:
|
||||
tokenizer_names: ["english_phoneme"]
|
||||
|
||||
encoder:
|
||||
n_layers: 6
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
context_encoder: # Only used for decoder_ce (and multi_encoder_context_tts), ignored otherwise
|
||||
n_layers: 1
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: false
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
decoder:
|
||||
n_layers: 12
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 1
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: true
|
||||
xa_d_head: 128
|
||||
xa_d_memory: 768
|
||||
xa_n_heads: 1
|
||||
is_causal: true
|
||||
apply_norm_to_cond: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
make_prior_window_strict: false
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 2e-4
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32
|
||||
max_steps: ???
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
limit_train_batches: 1_000
|
||||
val_check_interval: 1_000
|
||||
num_sanity_val_steps: 0
|
||||
benchmark: false
|
||||
use_distributed_sampler: false # required because Lhotse has its own handling
|
||||
gradient_clip_val: 2.5
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
entity: null
|
||||
project: null
|
||||
group: null
|
||||
name: ${name}
|
||||
resume: true # enable resume to ensure continuous training log metrics merged on the previous run id.
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
filename: '${name}--{${exp_manager.checkpoint_callback_params.monitor}:.4f}-{step}'
|
||||
resume_if_exists: true
|
||||
resume_ignore_no_checkpoint: true
|
||||
@@ -0,0 +1,245 @@
|
||||
name: MagpieTTS-MoE
|
||||
|
||||
quadratic_duration: 20 # both training and validation datasets can apply same quadratic_duration.
|
||||
|
||||
model:
|
||||
use_lhotse: true
|
||||
use_moe: true # Enable Mixture-of-Experts in decoder (MoE is only supported in decoder)
|
||||
router_load_balancing_loss_coeff: 0.01 # Encourages uniform token distribution across experts (set 0.001 to 0.01 for top_k, 0.0 for sinkhorn)
|
||||
router_z_loss_coeff: 0.001 # Encourages smaller router logits for numerical stability (set 0.0001 to 0.001)
|
||||
model_type: "decoder_ce" # decoder_context_tts or decoder_ce
|
||||
use_text_conditioning_encoder: true # Enable or disable text context. Audio context is always enabled
|
||||
text_conditioning_tokenizer_name: text_ce_tokenizer # The tokenizer to be used for text contexts
|
||||
context_duration_min: 5.0
|
||||
context_duration_max: 5.0
|
||||
load_cached_codes_if_available: true
|
||||
prior_scaling_factor: 0.5
|
||||
prior_end_step: 12000
|
||||
prior_scaledown_start_step: 8000
|
||||
indefinite_prior_prob: 0. # If > 0, then prior will be applied after prior_end_step with this probability.
|
||||
alignment_loss_scale: 0.002
|
||||
embedding_dim: 768
|
||||
codecmodel_path: ???
|
||||
cfg_unconditional_prob: 0.1 # enable classifier-free guidance during traing by dropping out conditionals with this probability
|
||||
|
||||
# Alignment encoder parameters, to binarize the prior
|
||||
# This is used for attention-constrained training and inference
|
||||
use_alignment_encoder: false
|
||||
# Below args are only relevant if use_alignment_encoder is true
|
||||
use_prior_for_aligner: true # Whether to use the beta-binomial prior to train the alignment encoder
|
||||
alignment_encoder_loss_scale: 1.0
|
||||
binarize_prior_after_step: 10000 # Switch from beta-binomial prior to binarized prior after this step.
|
||||
binarize_attn_method: "nemo_binarize" # nemo_binarize or argmax.
|
||||
prior_future_context: 2 # Future window of the binarized prior.
|
||||
prior_past_context: 2 # Past window of the binarized prior.
|
||||
prior_future_decay: 0.8 # Decay factor for future context
|
||||
prior_past_decay: 0.5 # Decay factor for past context
|
||||
binarize_repeat_audio_factor: 2 # Temporally increase audio timesteps, for nemo_binarize to work better. Increase this for low frame rate codecs
|
||||
binarized_prior_epsilon: 0.0
|
||||
aligner_encoder_train_steps: 50000
|
||||
|
||||
# Local transformer parameters for autoregressive codebook prediction within a frame
|
||||
local_transformer_type: "autoregressive" # "none", "autoregressive", "maskgit"
|
||||
# Below args are only relevant if use_local_transformer is true
|
||||
local_transformer_loss_scale: 1.0
|
||||
local_transformer_n_layers: 1
|
||||
local_transformer_n_heads: 1
|
||||
local_transformer_hidden_dim: 256
|
||||
|
||||
text_context_remapping_json: null # JSON file defining mapping of multiple text contexts to a single text context. Does not need to cover all text contexts.
|
||||
text_context_remapping_prob: 0.0 # Probability of remapping the original text context to a remapped text context.
|
||||
|
||||
text_tokenizers:
|
||||
english_phoneme:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: false
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
phoneme_probability: 0.8
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
text_ce_tokenizer: # Used for text context
|
||||
_target_: AutoTokenizer
|
||||
pretrained_model: "google/byt5-small"
|
||||
### For additional languages, consider adding a generic byt5 tokenizer like the one below
|
||||
# french_chartokenizer: # Used for text context
|
||||
# _target_: AutoTokenizer
|
||||
# pretrained_model: "google/byt5-small"
|
||||
|
||||
train_ds:
|
||||
use_lhotse: ${model.use_lhotse}
|
||||
volume_norm: true
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
min_context_speaker_similarity: 0.6
|
||||
max_cer: 0.03
|
||||
batch_duration: ??? # in seconds. Adjust based on your GPU memory.
|
||||
quadratic_duration: ${quadratic_duration}
|
||||
use_bucketing: true
|
||||
num_buckets: 20
|
||||
bucket_buffer_size: 20_000
|
||||
shuffle_buffer_size: 20_000
|
||||
num_cuts_for_bins_estimate: 20_000
|
||||
shard_seed: "trng"
|
||||
drop_last: true
|
||||
shuffle: true
|
||||
num_workers: 6
|
||||
pin_memory: true
|
||||
reweight_temperature: 1.0 # Scalar broadcasts to all levels. Use a list for per-level control, e.g. [1.0, 0.0].
|
||||
|
||||
input_cfg:
|
||||
- type: lhotse_shar
|
||||
shar_path: ???
|
||||
weight: 1.0
|
||||
tags:
|
||||
tokenizer_names: ["english_phoneme"]
|
||||
|
||||
validation_ds:
|
||||
# the entries under 'datasets' are a list of separate dataloaders.
|
||||
# The structure is:
|
||||
# - name: '<dataset-name>'
|
||||
# <dataloader-dict-config>
|
||||
# They inherit all settings from validation_ds, but can individually override them.
|
||||
use_lhotse: ${model.use_lhotse}
|
||||
volume_norm: true
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
min_context_speaker_similarity: 0.6
|
||||
max_cer: 0.03
|
||||
batch_duration: ??? # recommend to use smaller batch_duration for validation dataset than training dataset.
|
||||
quadratic_duration: ${quadratic_duration}
|
||||
use_bucketing: false
|
||||
force_finite: true
|
||||
force_map_dataset: true
|
||||
seed: 42
|
||||
shard_seed: "randomized"
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
num_workers: 2
|
||||
pin_memory: true
|
||||
|
||||
datasets:
|
||||
- name: "val_set_0" # rename to your dataset name, add more as needed
|
||||
input_cfg:
|
||||
- type: lhotse_shar
|
||||
shar_path: ???
|
||||
weight: 1.0
|
||||
tags:
|
||||
tokenizer_names: ["english_phoneme"]
|
||||
|
||||
encoder:
|
||||
n_layers: 6
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
context_encoder: # Only used for decoder_ce (and multi_encoder_context_tts), ignored otherwise
|
||||
n_layers: 1
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: false
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
decoder:
|
||||
use_moe: ${model.use_moe}
|
||||
n_layers: 12
|
||||
d_model: 768
|
||||
d_ffn: 1536 # Per-expert FFN hidden dimension. Set to 1536 (=3072/top_k) for FLOPs-matched MoE, or 3072 for full-capacity experts (2x inference FLOPs vs dense).
|
||||
sa_n_heads: 12
|
||||
kernel_size: 1
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: true
|
||||
xa_d_head: 128
|
||||
xa_d_memory: 768
|
||||
xa_n_heads: 1
|
||||
is_causal: true
|
||||
apply_norm_to_cond: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
make_prior_window_strict: false
|
||||
num_experts: 8 # num of expert networks in each MoE layer
|
||||
|
||||
# Number of experts to activate per token (top-k routing)
|
||||
# top_k=1: Switch Transformer (fastest, most efficient)
|
||||
# top_k=2: Better quality, slightly slower
|
||||
top_k_experts: 2
|
||||
|
||||
# Routing strategy: "top_k" or "sinkhorn"
|
||||
# - "top_k": Standard softmax routing with top-k selection
|
||||
# - "sinkhorn": Balanced routing
|
||||
routing_strategy: "top_k"
|
||||
|
||||
# Router jitter noise for exploration during training
|
||||
# Adds noise to router logits to encourage exploration
|
||||
# Recommended: 0.0 to 0.01
|
||||
router_jitter_noise: 0.01
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 2e-4
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32
|
||||
max_steps: ???
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
limit_train_batches: 1_000
|
||||
val_check_interval: 1_000
|
||||
num_sanity_val_steps: 0
|
||||
benchmark: false
|
||||
use_distributed_sampler: false # required because Lhotse has its own handling
|
||||
gradient_clip_val: 2.5
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
entity: null
|
||||
project: null
|
||||
group: null
|
||||
name: ${name}
|
||||
resume: true # enable resume to ensure continuous training log metrics merged on the previous run id.
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
filename: '${name}--{${exp_manager.checkpoint_callback_params.monitor}:.4f}-{step}'
|
||||
resume_if_exists: true
|
||||
resume_ignore_no_checkpoint: true
|
||||
@@ -0,0 +1,191 @@
|
||||
name: MagpieTTS-PO-Infer
|
||||
mode: test
|
||||
init_from_ptl_ckpt: ???
|
||||
max_epochs: 1
|
||||
# Adjust batch size based on GPU memory
|
||||
batch_size: 16
|
||||
# When doing weighted sampling with multiple manifests, this defines how many training steps are in an epoch.
|
||||
# If null, then weighted sampling is disabled.
|
||||
weighted_sampling_steps_per_epoch: null
|
||||
|
||||
# Dataset metadata for each manifest
|
||||
# See DatasetMeta in https://github.com/NVIDIA-NeMo/NeMo/blob/main/nemo/collections/tts/data/text_to_speech_dataset.py
|
||||
test_ds_meta: ???
|
||||
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms_path: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
model:
|
||||
# Inference hyperparameters
|
||||
use_kv_cache_for_inference: true
|
||||
inference_temperature: 0.7
|
||||
inference_topk: 80
|
||||
inference_use_cfg: false
|
||||
inference_cfg_scale: 1.0
|
||||
max_decoder_steps: 500
|
||||
|
||||
model_type: "decoder_ce" # decoder_context_tts or decoder_ce
|
||||
use_text_conditioning_encoder: true # Enable or disable text context. Audio context is always enabled
|
||||
text_conditioning_tokenizer_name: text_ce_tokenizer # The tokenizer to be used for text contexts
|
||||
context_duration_min: 5.0
|
||||
context_duration_max: 5.0
|
||||
load_cached_codes_if_available: true
|
||||
prior_scaling_factor: null
|
||||
prior_end_step: 0
|
||||
prior_scaledown_start_step: 0
|
||||
alignment_loss_scale: 0.0
|
||||
embedding_dim: 768
|
||||
codecmodel_path: ???
|
||||
max_epochs: ${max_epochs}
|
||||
steps_per_epoch: ${weighted_sampling_steps_per_epoch}
|
||||
|
||||
# Alignment encoder parameters, to binarize the prior
|
||||
# This is used for attention-constrained training and inference
|
||||
use_alignment_encoder: false
|
||||
# Below args are only relevant if use_alignment_encoder is true
|
||||
use_prior_for_aligner: true # Whether to use the beta-binomial prior to train the alignment encoder
|
||||
alignment_encoder_loss_scale: 1.0
|
||||
binarize_prior_after_step: 10000 # Switch from beta-binomial prior to binarized prior after this step.
|
||||
binarize_attn_method: "nemo_binarize" # nemo_binarize or argmax.
|
||||
prior_future_context: 2 # Future window of the binarized prior.
|
||||
prior_past_context: 2 # Past window of the binarized prior.
|
||||
prior_future_decay: 0.8 # Decay factor for future context
|
||||
prior_past_decay: 0.5 # Decay factor for past context
|
||||
binarize_repeat_audio_factor: 2 # Temporally increase audio timesteps, for nemo_binarize to work better. Increase this for low frame rate codecs
|
||||
binarized_prior_epsilon: 0.0
|
||||
aligner_encoder_train_steps: 50000
|
||||
|
||||
# Local transformer parameters for autoregressive codebook prediction within a frame
|
||||
local_transformer_type: "autoregressive" # "none", "autoregressive", "maskgit"
|
||||
# Below args are only relevant if use_local_transformer is true
|
||||
local_transformer_loss_scale: 1.0
|
||||
local_transformer_n_layers: 1
|
||||
local_transformer_n_heads: 1
|
||||
local_transformer_hidden_dim: 256
|
||||
|
||||
text_context_remapping_json: null # JSON file defining mapping of multiple text contexts to a single text context. Does not need to cover all text contexts.
|
||||
text_context_remapping_prob: 0.0 # Probability of remapping the original text context to a remapped text context.
|
||||
|
||||
text_tokenizers:
|
||||
english_phoneme:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.IPATokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: false
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.i18n_ipa.IpaG2p
|
||||
phoneme_dict: "scripts/tts_dataset_files/ipa_cmudict-0.7b_nv23.01.txt"
|
||||
heteronyms: "scripts/tts_dataset_files/heteronyms-052722"
|
||||
phoneme_probability: 0.8
|
||||
ignore_ambiguous_words: false
|
||||
use_chars: true
|
||||
use_stresses: true
|
||||
text_ce_tokenizer: # Used for text context
|
||||
_target_: AutoTokenizer
|
||||
pretrained_model: "google/byt5-small"
|
||||
### For additional languages, consider adding a generic byt5 tokenizer like the one below
|
||||
# french_chartokenizer: # Used for text context
|
||||
# _target_: AutoTokenizer
|
||||
# pretrained_model: "google/byt5-small"
|
||||
|
||||
test_ds:
|
||||
datasets:
|
||||
_target_: nemo.collections.tts.data.text_to_speech_dataset.MagpieTTSDataset
|
||||
dataset_meta: ${test_ds_meta}
|
||||
min_duration: 0.2
|
||||
max_duration: 20.0
|
||||
|
||||
dataloader_params:
|
||||
batch_size: ${batch_size}
|
||||
num_workers: 2
|
||||
|
||||
encoder:
|
||||
n_layers: 6
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
context_encoder: # Only used for decoder_ce (and multi_encoder_context_tts), ignored otherwise
|
||||
n_layers: 1
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 3
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: false
|
||||
is_causal: false
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
|
||||
decoder:
|
||||
n_layers: 12
|
||||
d_model: 768
|
||||
d_ffn: 3072
|
||||
sa_n_heads: 12
|
||||
kernel_size: 1
|
||||
p_dropout: 0.1
|
||||
p_dropout_out: 0.0
|
||||
has_xattn: true
|
||||
xa_d_head: 128
|
||||
xa_d_memory: 768
|
||||
xa_n_heads: 1
|
||||
is_causal: true
|
||||
apply_norm_to_cond: true
|
||||
apply_norm_out: true
|
||||
max_length_causal_mask: 2048
|
||||
use_learnable_pos_emb: true
|
||||
make_prior_window_strict: true
|
||||
|
||||
optim:
|
||||
_target_: torch.optim.AdamW
|
||||
lr: 2e-4
|
||||
|
||||
sched:
|
||||
name: ExponentialLR
|
||||
gamma: 0.998
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1
|
||||
accelerator: gpu
|
||||
strategy: ddp_find_unused_parameters_true
|
||||
precision: 32
|
||||
max_epochs: ${max_epochs}
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
val_check_interval: 500
|
||||
benchmark: false
|
||||
gradient_clip_val: 2.5
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
entity: null
|
||||
project: null
|
||||
group: null
|
||||
name: ${name}
|
||||
resume: true # enable resume to ensure continuous training log metrics merged on the previous run id.
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
mode: min
|
||||
save_top_k: 5
|
||||
save_best_model: true
|
||||
always_save_nemo: true
|
||||
filename: '${name}--{${exp_manager.checkpoint_callback_params.monitor}:.4f}-{step}'
|
||||
resume_if_exists: true
|
||||
resume_ignore_no_checkpoint: true
|
||||
@@ -0,0 +1,191 @@
|
||||
# This config contains the default values for self-supervised pre-training of a Conformer ASR model, large size (~120M).
|
||||
|
||||
# Architecture and training config:
|
||||
# Default learning parameters in this config are set for effective batch size of 2K. To train it with smaller effective
|
||||
# batch sizes, you may need to re-tune the learning parameters or use higher accumulate_grad_batches.
|
||||
# Here are the recommended configs for different variants of Conformer-CTC, other parameters are the same as in this config file.
|
||||
# One extra layer (compared to original paper) is added to the medium and large variants to compensate for replacing the LSTM decoder with a linear one.
|
||||
#
|
||||
# +-------------+---------+---------+----------+------------+-----+
|
||||
# | Model | d_model | n_heads | n_layers | time_masks | lr |
|
||||
# +=============+=========+========+===========+============+=====+
|
||||
# | Small (13M)| 176 | 4 | 16 | 5 | 5.0 |
|
||||
# +-------------+---------+--------+-----------+------------+-----+
|
||||
# | Medium (30M)| 256 | 4 | 18 | 5 | 5.0 |
|
||||
# +-------------+---------+--------+-----------+------------+-----+
|
||||
# | Large (121M)| 512 | 8 | 18 | 10 | 2.0 |
|
||||
# +---------------------------------------------------------------+
|
||||
#
|
||||
# If you do not want to train with AMP, you may use weight decay of 0.0 or reduce the number of time maskings to 2
|
||||
# with time_width=100. It may help when you want to train for fewer epochs and need faster convergence.
|
||||
# With weight_decay=0.0, learning rate may need to get reduced to 2.0.
|
||||
|
||||
name: "Conformer-SSL"
|
||||
init_from_pretrained_model: "ssl_en_conformer_large"
|
||||
|
||||
model:
|
||||
sample_rate: 22050
|
||||
combined_loss: true
|
||||
pitch_augment: true
|
||||
augment_sim_alpha: 1.0
|
||||
stop_gradient: false
|
||||
augment_ctc: true
|
||||
aug_loss_type: "cosine"
|
||||
pad_multiple: 1
|
||||
train_ds:
|
||||
manifest_speaker_verification_fp: ???
|
||||
manifest_content_fp: ???
|
||||
sample_rate: ${model.sample_rate}
|
||||
batch_size_content: 8 # you may increase batch_size if your memory allows
|
||||
batch_size_sv: 20
|
||||
shuffle: true
|
||||
num_workers_sv: 4
|
||||
num_workers_content: 6
|
||||
pin_memory: false
|
||||
max_duration_content: 16.7
|
||||
min_duration_content: 8.0
|
||||
segment_max_duration: 2
|
||||
sup_data_path: ???
|
||||
pitch_augment: ${model.pitch_augment}
|
||||
cache_pitch_augment: true
|
||||
pad_multiple: ${model.pad_multiple}
|
||||
|
||||
validation_ds:
|
||||
manifest_speaker_verification_fp: ???
|
||||
manifest_content_fp: ???
|
||||
sample_rate: ${model.sample_rate}
|
||||
batch_size_content: 4 # you may increase batch_size if your memory allows
|
||||
batch_size_sv: 8
|
||||
shuffle: false
|
||||
num_workers_sv: 0
|
||||
num_workers_content: 0
|
||||
pin_memory: true
|
||||
use_start_end_token: false
|
||||
max_duration_content: 16.7
|
||||
min_duration_content: 8.0
|
||||
segment_max_duration: 2
|
||||
sup_data_path: ???
|
||||
pitch_augment: ${model.pitch_augment}
|
||||
cache_pitch_augment: true
|
||||
pad_multiple: ${model.pad_multiple}
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
sample_rate: ${model.sample_rate}
|
||||
normalize: "per_feature"
|
||||
window_size: null
|
||||
window_stride: null
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
window: "hann"
|
||||
features: 80
|
||||
n_fft: 1024
|
||||
log: true
|
||||
frame_splicing: 1
|
||||
dither: 0.00001
|
||||
pad_to: 16
|
||||
pad_value: 0.0
|
||||
|
||||
spec_augment:
|
||||
_target_: nemo.collections.asr.modules.MaskedPatchAugmentation
|
||||
freq_masks: 3
|
||||
freq_width: 20
|
||||
patch_size: 48
|
||||
mask_patches: 0.5
|
||||
|
||||
downstream_heads:
|
||||
task_names: ['speaker_verification', 'content']
|
||||
speaker_embed_size: 256
|
||||
num_speakers: 5994
|
||||
content_embed_size: 128
|
||||
|
||||
encoder:
|
||||
_target_: nemo.collections.asr.modules.ConformerEncoder
|
||||
feat_in: ${model.preprocessor.features}
|
||||
feat_out: -1 # you may set it if you need different output size other than the default d_model
|
||||
n_layers: 18
|
||||
d_model: 512
|
||||
|
||||
# Sub-sampling params
|
||||
subsampling: striding # vggnet or striding, vggnet may give better results but needs more memory
|
||||
subsampling_factor: 4 # must be power of 2
|
||||
subsampling_conv_channels: -1 # -1 sets it to d_model
|
||||
|
||||
# Feed forward module's params
|
||||
ff_expansion_factor: 4
|
||||
|
||||
# Multi-headed Attention Module's params
|
||||
self_attention_model: rel_pos # rel_pos or abs_pos
|
||||
n_heads: 8 # may need to be lower for smaller d_models
|
||||
# [left, right] specifies the number of steps to be seen from left and right of each step in self-attention
|
||||
att_context_size: [-1, -1] # -1 means unlimited context
|
||||
xscaling: true # scales up the input embeddings by sqrt(d_model)
|
||||
untie_biases: true # unties the biases of the TransformerXL layers
|
||||
pos_emb_max_len: 5000
|
||||
|
||||
# Convolution module's params
|
||||
conv_kernel_size: 31
|
||||
conv_norm_type: 'batch_norm' # batch_norm or layer_norm
|
||||
|
||||
### regularization
|
||||
dropout: 0.1 # The dropout used in most of the Conformer Modules
|
||||
dropout_emb: 0.0 # The dropout used for embeddings
|
||||
dropout_att: 0.1 # The dropout for multi-headed attention modules
|
||||
|
||||
decoder_out: 128
|
||||
|
||||
|
||||
optim_backbone:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 5e-5
|
||||
sched:
|
||||
min_lr: 1e-6
|
||||
warmup_steps: 2000
|
||||
|
||||
optim_downstream:
|
||||
_target_: torch.optim.Adam
|
||||
lr: 1e-4
|
||||
sched:
|
||||
min_lr: 1e-6
|
||||
warmup_steps: 1000
|
||||
|
||||
|
||||
trainer:
|
||||
devices: -1 # number of GPUs, -1 would use all available GPUs
|
||||
num_nodes: 1
|
||||
max_epochs: 1000
|
||||
max_steps: 500000 # computed at runtime if not set
|
||||
val_check_interval: 1.0 # Set to 0.25 to check 4 times per epoch, or an int for number of iterations
|
||||
accelerator: auto
|
||||
strategy: ddp
|
||||
accumulate_grad_batches: 1
|
||||
precision: 32 # Should be set to 16 for O1 and O2 to enable the AMP.
|
||||
log_every_n_steps: 10 # Interval of logging.
|
||||
num_sanity_val_steps: 0 # number of steps to perform validation steps for sanity check the validation process before starting the training, setting to 0 disables it
|
||||
check_val_every_n_epoch: 1 # number of evaluations on validation every n epochs
|
||||
sync_batchnorm: true
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
benchmark: false # needs to be false for models with variable-length speech input as it slows down training
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
# in case of multiple validation sets, first one is used
|
||||
monitor: "val_loss"
|
||||
mode: "min"
|
||||
save_top_k: 5
|
||||
|
||||
resume_from_checkpoint: null # The path to a checkpoint file to continue the training, restores the whole state including the epoch, step, LR schedulers, apex, etc.
|
||||
# you need to set these two to True to continue the training
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
|
||||
# You may use this section to create a W&B logger
|
||||
create_wandb_logger: false
|
||||
wandb_logger_kwargs:
|
||||
name: null
|
||||
project: null
|
||||
@@ -0,0 +1,3 @@
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: en
|
||||
input_case: cased
|
||||
@@ -0,0 +1,7 @@
|
||||
_target_: nemo.collections.tts.parts.preprocessing.audio_trimming.EnergyAudioTrimmer
|
||||
|
||||
db_threshold: 50.0
|
||||
speech_frame_threshold: 3
|
||||
trim_win_length: 4096
|
||||
trim_hop_length: 1024
|
||||
pad_seconds: 0.2
|
||||
@@ -0,0 +1,10 @@
|
||||
_target_: nemo.collections.tts.parts.preprocessing.audio_trimming.VadAudioTrimmer
|
||||
|
||||
model_name: "vad_multilingual_marblenet"
|
||||
vad_sample_rate: 16000
|
||||
vad_threshold: 0.5
|
||||
device: "cpu"
|
||||
speech_frame_threshold: 3
|
||||
trim_win_length: 4096
|
||||
trim_hop_length: 1024
|
||||
pad_seconds: 0.2
|
||||
@@ -0,0 +1,259 @@
|
||||
# This config contains the default values for training FastPitch model with aligner using 22KHz sampling
|
||||
# rate. If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch" ]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 1986.977294921875
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 221.4948272705078 for SFbilingual dataset.
|
||||
pitch_std: ??? # e.g. 64.6528930664063 for SFbilingual dataset.
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
# There are four candidates of `phoneme_dict_path` provided for Chinese as shown below,
|
||||
# 1) 24-final Pinyin: "scripts/tts_dataset_files/zh/24finals/pinyin_dict_nv_22.10.txt",
|
||||
# 2) IPA converted from 24-final Pinyin: "scripts/tts_dataset_files/zh/24finals/ipa_dict_nv23.05.txt",
|
||||
# 3) 36-final Pinyin: "scripts/tts_dataset_files/zh/36finals/pinyin_dict_nv23.05.txt",
|
||||
# 4) (default) IPA converted from 36-final Pinyin: "scripts/tts_dataset_files/zh/36finals/ipa_dict_nv23.05.txt"
|
||||
# Suggest to choose IPA symbol set converted from 36-final Pinyin because better audio quality were observed.
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/zh/36finals/ipa_dict_nv23.05.txt"
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 1
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: zh
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.ChinesePhonemesTokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.zh_cn_pinyin.ChineseG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
word_segmenter: jieba # Only jieba is supported now.
|
||||
phoneme_prefix: ""
|
||||
phoneme_case: lower
|
||||
tone_prefix: "#"
|
||||
ascii_letter_prefix: ""
|
||||
ascii_letter_case: upper
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 2
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # number of gpus
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 5000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,261 @@
|
||||
# This config contains the default values for training FastPitch model with aligner using 22KHz sampling
|
||||
# rate. If you want to train model on other dataset, you can change config values according to your dataset.
|
||||
# Most dataset-specific arguments are in the head of the config file, see below.
|
||||
|
||||
name: FastPitch
|
||||
|
||||
train_dataset: ???
|
||||
validation_datasets: ???
|
||||
sup_data_path: ???
|
||||
sup_data_types: [ "align_prior_matrix", "pitch", "speaker_id"]
|
||||
|
||||
# Default values from librosa.pyin
|
||||
pitch_fmin: 65.40639132514966
|
||||
pitch_fmax: 1986.977294921875
|
||||
|
||||
# these frame-wise values depend on pitch_fmin and pitch_fmax, you can get values
|
||||
# by running `scripts/dataset_processing/tts/extract_sup_data.py`
|
||||
pitch_mean: ??? # e.g. 221.4948272705078 for SFbilingual dataset.
|
||||
pitch_std: ??? # e.g. 64.6528930664063 for SFbilingual dataset.
|
||||
|
||||
# Default values for dataset with sample_rate=22050
|
||||
sample_rate: 22050
|
||||
n_mel_channels: 80
|
||||
n_window_size: 1024
|
||||
n_window_stride: 256
|
||||
n_fft: 1024
|
||||
lowfreq: 0
|
||||
highfreq: null
|
||||
window: hann
|
||||
|
||||
# There are four candidates of `phoneme_dict_path` provided for Chinese as shown below,
|
||||
# 1) 24-final Pinyin: "scripts/tts_dataset_files/zh/24finals/pinyin_dict_nv_22.10.txt",
|
||||
# 2) IPA converted from 24-final Pinyin: "scripts/tts_dataset_files/zh/24finals/ipa_dict_nv23.05.txt",
|
||||
# 3) 36-final Pinyin: "scripts/tts_dataset_files/zh/36finals/pinyin_dict_nv23.05.txt",
|
||||
# 4) (default) IPA converted from 36-final Pinyin: "scripts/tts_dataset_files/zh/36finals/ipa_dict_nv23.05.txt"
|
||||
# Suggest to choose IPA symbol set converted from 36-final Pinyin because better audio quality were observed.
|
||||
phoneme_dict_path: "scripts/tts_dataset_files/zh/36finals/ipa_dict_nv23.05.txt"
|
||||
|
||||
model:
|
||||
learn_alignment: true
|
||||
bin_loss_warmup_epochs: 100
|
||||
|
||||
n_speakers: 175
|
||||
max_token_duration: 75
|
||||
symbols_embedding_dim: 384
|
||||
pitch_embedding_kernel_size: 3
|
||||
speaker_emb_condition_prosody: true
|
||||
speaker_emb_condition_aligner: true
|
||||
|
||||
pitch_fmin: ${pitch_fmin}
|
||||
pitch_fmax: ${pitch_fmax}
|
||||
|
||||
pitch_mean: ${pitch_mean}
|
||||
pitch_std: ${pitch_std}
|
||||
|
||||
sample_rate: ${sample_rate}
|
||||
n_mel_channels: ${n_mel_channels}
|
||||
n_window_size: ${n_window_size}
|
||||
n_window_stride: ${n_window_stride}
|
||||
n_fft: ${n_fft}
|
||||
lowfreq: ${lowfreq}
|
||||
highfreq: ${highfreq}
|
||||
window: ${window}
|
||||
|
||||
text_normalizer:
|
||||
_target_: nemo_text_processing.text_normalization.normalize.Normalizer
|
||||
lang: zh
|
||||
input_case: cased
|
||||
|
||||
text_normalizer_call_kwargs:
|
||||
verbose: false
|
||||
punct_pre_process: true
|
||||
punct_post_process: true
|
||||
|
||||
text_tokenizer:
|
||||
_target_: nemo.collections.common.tokenizers.text_to_speech.tts_tokenizers.ChinesePhonemesTokenizer
|
||||
punct: true
|
||||
apostrophe: true
|
||||
pad_with_space: true
|
||||
g2p:
|
||||
_target_: nemo.collections.tts.g2p.models.zh_cn_pinyin.ChineseG2p
|
||||
phoneme_dict: ${phoneme_dict_path}
|
||||
word_segmenter: jieba # Only jieba is supported now.
|
||||
phoneme_prefix: ""
|
||||
phoneme_case: lower
|
||||
tone_prefix: "#"
|
||||
ascii_letter_prefix: ""
|
||||
ascii_letter_case: upper
|
||||
|
||||
train_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${train_dataset}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 12
|
||||
pin_memory: true
|
||||
|
||||
validation_ds:
|
||||
dataset:
|
||||
_target_: nemo.collections.tts.data.dataset.TTSDataset
|
||||
manifest_filepath: ${validation_datasets}
|
||||
sample_rate: ${model.sample_rate}
|
||||
sup_data_path: ${sup_data_path}
|
||||
sup_data_types: ${sup_data_types}
|
||||
n_fft: ${model.n_fft}
|
||||
win_length: ${model.n_window_size}
|
||||
hop_length: ${model.n_window_stride}
|
||||
window: ${model.window}
|
||||
n_mels: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
max_duration: null # change to null to include longer audios.
|
||||
min_duration: 0.1
|
||||
ignore_file: null
|
||||
trim: true
|
||||
trim_top_db: 50
|
||||
trim_frame_length: ${model.n_window_size}
|
||||
trim_hop_length: ${model.n_window_stride}
|
||||
pitch_fmin: ${model.pitch_fmin}
|
||||
pitch_fmax: ${model.pitch_fmax}
|
||||
pitch_norm: true
|
||||
pitch_mean: ${model.pitch_mean}
|
||||
pitch_std: ${model.pitch_std}
|
||||
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 2
|
||||
pin_memory: true
|
||||
|
||||
preprocessor:
|
||||
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
|
||||
features: ${model.n_mel_channels}
|
||||
lowfreq: ${model.lowfreq}
|
||||
highfreq: ${model.highfreq}
|
||||
n_fft: ${model.n_fft}
|
||||
n_window_size: ${model.n_window_size}
|
||||
window_size: false
|
||||
n_window_stride: ${model.n_window_stride}
|
||||
window_stride: false
|
||||
pad_to: 1
|
||||
pad_value: 0
|
||||
sample_rate: ${model.sample_rate}
|
||||
window: ${model.window}
|
||||
normalize: null
|
||||
preemph: null
|
||||
dither: 0.0
|
||||
frame_splicing: 1
|
||||
log: true
|
||||
log_zero_guard_type: add
|
||||
log_zero_guard_value: 1e-05
|
||||
mag_power: 1.0
|
||||
|
||||
input_fft: #n_embed and padding_idx are added by the model
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerEncoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
d_embed: ${model.symbols_embedding_dim}
|
||||
|
||||
output_fft:
|
||||
_target_: nemo.collections.tts.modules.transformer.FFTransformerDecoder
|
||||
n_layer: 6
|
||||
n_head: 1
|
||||
d_model: ${model.symbols_embedding_dim}
|
||||
d_head: 64
|
||||
d_inner: 1536
|
||||
kernel_size: 3
|
||||
dropout: 0.1
|
||||
dropatt: 0.1
|
||||
dropemb: 0.0
|
||||
|
||||
alignment_module:
|
||||
_target_: nemo.collections.tts.modules.aligner.AlignmentEncoder
|
||||
n_text_channels: ${model.symbols_embedding_dim}
|
||||
|
||||
duration_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
pitch_predictor:
|
||||
_target_: nemo.collections.tts.modules.fastpitch.TemporalPredictor
|
||||
input_size: ${model.symbols_embedding_dim}
|
||||
kernel_size: 3
|
||||
filter_size: 256
|
||||
dropout: 0.1
|
||||
n_layers: 2
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 1e-3
|
||||
betas: [0.9, 0.999]
|
||||
weight_decay: 1e-6
|
||||
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
warmup_steps: 1000
|
||||
last_epoch: -1
|
||||
d_model: 1 # Disable scaling based on model dim
|
||||
|
||||
trainer:
|
||||
num_nodes: 1
|
||||
devices: -1 # number of gpus
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
precision: 16
|
||||
max_epochs: 5000
|
||||
accumulate_grad_batches: 1
|
||||
gradient_clip_val: 1000.0
|
||||
enable_checkpointing: false # Provided by exp_manager
|
||||
logger: false # Provided by exp_manager
|
||||
log_every_n_steps: 100
|
||||
check_val_every_n_epoch: 5
|
||||
benchmark: false
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: true
|
||||
create_checkpoint_callback: true
|
||||
checkpoint_callback_params:
|
||||
monitor: val_loss
|
||||
resume_if_exists: false
|
||||
resume_ignore_no_checkpoint: false
|
||||
@@ -0,0 +1,67 @@
|
||||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
import torch.multiprocessing as mp
|
||||
from omegaconf import OmegaConf, open_dict
|
||||
|
||||
from nemo.collections.tts.models import EasyMagpieTTSModel, EasyMagpieTTSModelOnlinePO
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils import logging
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf/magpietts", config_name="easy_magpietts")
|
||||
def main(cfg):
|
||||
logging.info('\nConfig Params:\n%s', OmegaConf.to_yaml(cfg, resolve=True))
|
||||
|
||||
# forcing "spawn" method for multiprocessing over "fork" when choosing multiple
|
||||
# worker processes for dataloaders. By default, multiprocessing uses "fork" to create
|
||||
# worker processes, which inherit the memory state of the main process, including its
|
||||
# already initialized CUDA state. When the worker processes trieds to use
|
||||
# CUDA, it runs into conflicts with the inherited, now potentially invalid,
|
||||
# CUDA context, resuling in the CUDA initialization error. When
|
||||
# num_workers=0, all dataloading happens in the main process, so there is no
|
||||
# process forking and no CUDA context conflict. When num_workers>0, the standard way
|
||||
# to fix this is to use "spawn" to create a completely new and clean python process for
|
||||
# each worker, avoding the problematic CUDA state inheritance.
|
||||
mp.set_start_method("spawn", force=True)
|
||||
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
trainer.callbacks.append(pl.callbacks.LearningRateMonitor(logging_interval='step', log_weight_decay=True))
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
|
||||
mode = cfg.get('mode', 'train')
|
||||
if mode == 'train':
|
||||
model = EasyMagpieTTSModel(cfg=cfg.model, trainer=trainer)
|
||||
elif mode == 'onlinepo_train':
|
||||
model_cfg = cfg.model
|
||||
with open_dict(model_cfg):
|
||||
model_cfg.reference_model_ckpt_path = cfg.init_from_ptl_ckpt
|
||||
model = EasyMagpieTTSModelOnlinePO(cfg=model_cfg, trainer=trainer)
|
||||
elif mode == 'test':
|
||||
model = EasyMagpieTTSModel(cfg=cfg.model, trainer=trainer)
|
||||
else:
|
||||
raise NotImplementedError(f"Only train, onlinepo_train and test modes are supported. Got {mode}")
|
||||
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
|
||||
if mode in ['train', 'onlinepo_train']:
|
||||
trainer.fit(model)
|
||||
elif mode == 'test':
|
||||
trainer.test(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"an4_val_ci": {
|
||||
"manifest_path": "/home/TestData/an4_dataset/an4_val_context_v1.json",
|
||||
"audio_dir": "/",
|
||||
"feature_dir": null
|
||||
},
|
||||
"an4_val_tiny_ci": {
|
||||
"manifest_path": "/home/TestData/an4_dataset/an4_val_context_v1_tiny.json",
|
||||
"audio_dir": "/",
|
||||
"feature_dir": null
|
||||
},
|
||||
"an4_val_ci_longform_tiny": {
|
||||
"manifest_path": "/home/TestData/an4_dataset/an4_val_context_v1_longform_tiny_normalized.json",
|
||||
"audio_dir": "/",
|
||||
"feature_dir": null
|
||||
},
|
||||
"an4_val_ci_nemotronTokenizer": {
|
||||
"manifest_path": "/home/TestData/an4_dataset/an4_val_context_v1.json",
|
||||
"audio_dir": "/",
|
||||
"feature_dir": null,
|
||||
"tokenizer_names": ["nemotron_nano_30b"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
|
||||
from nemo.collections.common.callbacks import LogEpochTimeCallback
|
||||
from nemo.collections.tts.models import FastPitchModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf", config_name="fastpitch_align_v1.05")
|
||||
def main(cfg):
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
model = FastPitchModel(cfg=cfg.model, trainer=trainer)
|
||||
lr_logger = pl.callbacks.LearningRateMonitor()
|
||||
epoch_time_logger = LogEpochTimeCallback()
|
||||
trainer.callbacks.extend([lr_logger, epoch_time_logger])
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
|
||||
from nemo.collections.common.callbacks import LogEpochTimeCallback
|
||||
from nemo.collections.tts.models import FastPitchModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils import logging
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf", config_name="fastpitch_align_44100")
|
||||
def main(cfg):
|
||||
if hasattr(cfg.model.optim, 'sched'):
|
||||
logging.warning("You are using an optimizer scheduler while finetuning. Are you sure this is intended?")
|
||||
if cfg.model.optim.lr > 1e-3 or cfg.model.optim.lr < 1e-5:
|
||||
logging.warning("The recommended learning rate for finetuning is 2e-4")
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
model = FastPitchModel(cfg=cfg.model, trainer=trainer)
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
lr_logger = pl.callbacks.LearningRateMonitor()
|
||||
epoch_time_logger = LogEpochTimeCallback()
|
||||
trainer.callbacks.extend([lr_logger, epoch_time_logger])
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,153 @@
|
||||
# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
from dataclasses import is_dataclass
|
||||
|
||||
import lightning.pytorch as pl
|
||||
from omegaconf import DictConfig, OmegaConf, open_dict
|
||||
|
||||
from nemo.collections.common.callbacks import LogEpochTimeCallback
|
||||
from nemo.collections.tts.models import FastPitchModel
|
||||
from nemo.core import adapter_mixins
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils import logging
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
def update_model_config_to_support_adapter(config) -> DictConfig:
|
||||
with open_dict(config):
|
||||
enc_adapter_metadata = adapter_mixins.get_registered_adapter(config.input_fft._target_)
|
||||
if enc_adapter_metadata is not None:
|
||||
config.input_fft._target_ = enc_adapter_metadata.adapter_class_path
|
||||
|
||||
dec_adapter_metadata = adapter_mixins.get_registered_adapter(config.output_fft._target_)
|
||||
if dec_adapter_metadata is not None:
|
||||
config.output_fft._target_ = dec_adapter_metadata.adapter_class_path
|
||||
|
||||
pitch_predictor_adapter_metadata = adapter_mixins.get_registered_adapter(config.pitch_predictor._target_)
|
||||
if pitch_predictor_adapter_metadata is not None:
|
||||
config.pitch_predictor._target_ = pitch_predictor_adapter_metadata.adapter_class_path
|
||||
|
||||
duration_predictor_adapter_metadata = adapter_mixins.get_registered_adapter(config.duration_predictor._target_)
|
||||
if duration_predictor_adapter_metadata is not None:
|
||||
config.duration_predictor._target_ = duration_predictor_adapter_metadata.adapter_class_path
|
||||
|
||||
aligner_adapter_metadata = adapter_mixins.get_registered_adapter(config.alignment_module._target_)
|
||||
if aligner_adapter_metadata is not None:
|
||||
config.alignment_module._target_ = aligner_adapter_metadata.adapter_class_path
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def add_global_adapter_cfg(model, global_adapter_cfg):
|
||||
# Convert to DictConfig from dict or Dataclass
|
||||
if is_dataclass(global_adapter_cfg):
|
||||
global_adapter_cfg = OmegaConf.structured(global_adapter_cfg)
|
||||
|
||||
if not isinstance(global_adapter_cfg, DictConfig):
|
||||
global_adapter_cfg = DictConfig(global_adapter_cfg)
|
||||
|
||||
# Update the model.cfg with information about the new adapter global cfg
|
||||
with open_dict(global_adapter_cfg), open_dict(model.cfg):
|
||||
if 'adapters' not in model.cfg:
|
||||
model.cfg.adapters = OmegaConf.create({})
|
||||
|
||||
# Add the global config for adapters to the model's internal config
|
||||
model.cfg.adapters[model.adapter_global_cfg_key] = global_adapter_cfg
|
||||
|
||||
# Update all adapter modules (that already exist) with this global adapter config
|
||||
model.update_adapter_cfg(model.cfg.adapters)
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf", config_name="fastpitch_align_44100_adapter")
|
||||
def main(cfg):
|
||||
if hasattr(cfg.model.optim, 'sched'):
|
||||
logging.warning("You are using an optimizer scheduler while finetuning. Are you sure this is intended?")
|
||||
if cfg.model.optim.lr > 1e-3 or cfg.model.optim.lr < 1e-5:
|
||||
logging.warning("The recommended learning rate for finetuning is 2e-4")
|
||||
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_log_dir = exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
# Initialize FastPitchModel
|
||||
model = FastPitchModel(cfg=update_model_config_to_support_adapter(cfg.model), trainer=trainer)
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
|
||||
# Extract adapter parameters
|
||||
with open_dict(cfg.model.adapter):
|
||||
# Extract the name of the adapter (must be given for training)
|
||||
adapter_name = cfg.model.adapter.pop("adapter_name", "adapter")
|
||||
# Extract the name of the modules where adapters need to be added (must be given for training)
|
||||
adapter_module_name = cfg.model.adapter.pop("adapter_module_name", None)
|
||||
# Name of the adapter checkpoint which will be saved after training
|
||||
adapter_state_dict_name = cfg.model.adapter.pop("adapter_state_dict_name", None)
|
||||
|
||||
# augment adapter name with module name, if not provided by user
|
||||
if adapter_module_name is not None and ':' not in adapter_name:
|
||||
adapter_name = f'{adapter_module_name}:{adapter_name}'
|
||||
|
||||
# Extract the global adapter config, if provided
|
||||
adapter_global_cfg = cfg.model.adapter.pop(model.adapter_global_cfg_key, None)
|
||||
|
||||
# Freeze model
|
||||
model.freeze()
|
||||
|
||||
# Setup adapters
|
||||
if adapter_global_cfg is not None:
|
||||
add_global_adapter_cfg(model, adapter_global_cfg)
|
||||
|
||||
if cfg.model.get("unfreeze_aligner", False):
|
||||
for name, param in model.fastpitch.aligner.named_parameters():
|
||||
param.requires_grad = True
|
||||
|
||||
if cfg.model.get("unfreeze_duration_predictor", False):
|
||||
for name, param in model.fastpitch.duration_predictor.named_parameters():
|
||||
param.requires_grad = True
|
||||
|
||||
if cfg.model.get("unfreeze_pitch_predictor", False):
|
||||
for name, param in model.fastpitch.pitch_predictor.named_parameters():
|
||||
param.requires_grad = True
|
||||
|
||||
# Add adapters
|
||||
model.add_adapter(name=adapter_name, cfg=cfg.model.adapter)
|
||||
assert model.is_adapter_available()
|
||||
# enable adapters
|
||||
model.set_enabled_adapters(enabled=False)
|
||||
model.set_enabled_adapters(adapter_name, enabled=True)
|
||||
|
||||
# Set model to training mode.
|
||||
model = model.train()
|
||||
# Then, Unfreeze just the adapter weights that were enabled above (no part of model)
|
||||
model.unfreeze_enabled_adapters()
|
||||
# summarize the model
|
||||
model.summarize()
|
||||
|
||||
lr_logger = pl.callbacks.LearningRateMonitor()
|
||||
epoch_time_logger = LogEpochTimeCallback()
|
||||
trainer.callbacks.extend([lr_logger, epoch_time_logger])
|
||||
trainer.fit(model)
|
||||
|
||||
# Save the adapter state dict after training has completed
|
||||
if adapter_state_dict_name is not None:
|
||||
state_path = exp_log_dir if exp_log_dir is not None else os.getcwd()
|
||||
ckpt_path = os.path.join(state_path, "checkpoints")
|
||||
if os.path.exists(ckpt_path):
|
||||
state_path = ckpt_path
|
||||
|
||||
# Save the adapter modules in a seperate file
|
||||
model.save_adapters(os.path.join(state_path, adapter_state_dict_name))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
|
||||
from nemo.collections.common.callbacks import LogEpochTimeCallback
|
||||
from nemo.collections.tts.models import fastpitch_ssl, hifigan
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf", config_name="fastpitch_ssl")
|
||||
def main(cfg):
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
vocoder = hifigan.HifiGanModel.load_from_checkpoint(cfg.hifi_ckpt_path).cpu()
|
||||
vocoder.eval()
|
||||
model = fastpitch_ssl.FastPitchModel_SSL(cfg=cfg.model, trainer=trainer, vocoder=vocoder)
|
||||
if cfg.get("finetune", False):
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
lr_logger = pl.callbacks.LearningRateMonitor()
|
||||
epoch_time_logger = LogEpochTimeCallback()
|
||||
trainer.callbacks.extend([lr_logger, epoch_time_logger])
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,2 @@
|
||||
This directory contains grapheme-to-phoneme (G2P) related work.
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
name: G2P-Conformer-CTC
|
||||
|
||||
# Dataset info
|
||||
train_manifest: ???
|
||||
validation_manifest: ???
|
||||
test_manifest: null
|
||||
do_training: True
|
||||
do_testing: False
|
||||
pretrained_model: null # path to .nemo file or model name from list_available_models()
|
||||
|
||||
model:
|
||||
model_name: conformer_bpe
|
||||
max_source_len: 512
|
||||
|
||||
tokenizer_grapheme:
|
||||
dataset:
|
||||
_target_: nemo.collections.common.tokenizers.char_tokenizer.CharTokenizer
|
||||
unk_token: "҂" # in the data, T5 unk_token is still <unk>
|
||||
vocab_file: null # will be filled during training
|
||||
do_lower: true # whether to lower case graphemes
|
||||
add_punctuation: true # whether to add punctuation symbols
|
||||
|
||||
embedding:
|
||||
d_model: 300
|
||||
encoder:
|
||||
_target_: nemo.collections.asr.modules.ConformerEncoder
|
||||
feat_in: ${model.embedding.d_model}
|
||||
feat_out: -1 # you may set it if you need different output size other than the default d_model
|
||||
n_layers: 16
|
||||
d_model: 176
|
||||
|
||||
# Sub-sampling params
|
||||
subsampling: null # vggnet or striding, vggnet may give better results but needs more memory
|
||||
subsampling_factor: 1 # must be power of 2
|
||||
subsampling_conv_channels: -1 # set to -1 to make it equal to the d_model
|
||||
|
||||
# Feed forward module's params
|
||||
ff_expansion_factor: 4
|
||||
|
||||
# Multi-headed Attention Module's params
|
||||
self_attention_model: rel_pos # rel_pos or abs_pos
|
||||
n_heads: 4 # may need to be lower for smaller d_models
|
||||
# [left, right] specifies the number of steps to be seen from left and right of each step in self-attention
|
||||
att_context_size: [ -1, -1 ] # -1 means unlimited context
|
||||
xscaling: true # scales up the input embeddings by sqrt(d_model)
|
||||
untie_biases: true # unties the biases of the TransformerXL layers
|
||||
pos_emb_max_len: 5000
|
||||
|
||||
# Convolution module's params
|
||||
conv_kernel_size: 31
|
||||
conv_norm_type: 'batch_norm' # batch_norm or layer_norm
|
||||
|
||||
### regularization
|
||||
dropout: 0.1 # The dropout used in most of the Conformer Modules
|
||||
dropout_pre_encoder: 0.1 # The dropout used before the encoder
|
||||
dropout_emb: 0.0 # The dropout used for embeddings
|
||||
dropout_att: 0.1 # The dropout for multi-headed attention modules
|
||||
|
||||
decoder:
|
||||
_target_: nemo.collections.asr.modules.ConvASRDecoder
|
||||
feat_in: null # will be filled during training based on encoder model dim
|
||||
num_classes: -1
|
||||
vocabulary: null # will be filled during training
|
||||
|
||||
tokenizer:
|
||||
dir: null # path to directory which contains either tokenizer.model (bpe) or vocab.txt (wpe)
|
||||
type: bpe # Can be either bpe (SentencePiece tokenizer) or wpe (WordPiece tokenizer)
|
||||
|
||||
train_ds:
|
||||
manifest_filepath: ${train_manifest}
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.g2p.data.ctc.CTCG2PBPEDataset"
|
||||
phoneme_field: "text" # name of the field in manifest_filepath for ground truth phonemes
|
||||
grapheme_field: "text_graphemes" # name of the field in manifest_filepath for input grapheme text
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 32
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
manifest_filepath: ${validation_manifest}
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.g2p.data.ctc.CTCG2PBPEDataset"
|
||||
phoneme_field: "text" # name of the field in manifest_filepath for ground truth phonemes
|
||||
grapheme_field: "text_graphemes" # name of the field in manifest_filepath for input grapheme text
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 4
|
||||
|
||||
test_ds:
|
||||
manifest_filepath: ${test_manifest}
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.g2p.data.ctc.CTCG2PBPEDataset"
|
||||
phoneme_field: "text" # name of the field in manifest_filepath for ground truth phonemes
|
||||
grapheme_field: "text_graphemes" # name of the field in manifest_filepath for input grapheme text
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 32
|
||||
num_workers: 0
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 2.0
|
||||
# optimizer arguments
|
||||
betas: [ 0.9, 0.98 ]
|
||||
# less necessity for weight_decay as we already have large augmentations with SpecAug
|
||||
# you may need weight_decay for large models, stable AMP training, small datasets, or when lower augmentations are used
|
||||
# weight decay of 0.0 with lr of 2.0 also works fine
|
||||
weight_decay: 1e-3
|
||||
|
||||
# scheduler setup
|
||||
sched:
|
||||
name: NoamAnnealing
|
||||
d_model: ${model.encoder.d_model}
|
||||
# scheduler config override
|
||||
warmup_steps: 10000
|
||||
warmup_ratio: null
|
||||
min_lr: 1e-6
|
||||
|
||||
trainer:
|
||||
devices: 1 # number of gpus
|
||||
max_epochs: 5
|
||||
num_nodes: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: False # Provided by exp_manager
|
||||
log_every_n_steps: 200
|
||||
check_val_every_n_epoch: 1
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: True
|
||||
create_checkpoint_callback: True
|
||||
checkpoint_callback_params:
|
||||
save_top_k: 1
|
||||
monitor: "val_per"
|
||||
mode: "min"
|
||||
save_best_model: true
|
||||
@@ -0,0 +1,92 @@
|
||||
name: T5G2P
|
||||
|
||||
# Dataset info
|
||||
train_manifest: ???
|
||||
validation_manifest: ???
|
||||
test_manifest: null
|
||||
do_training: True
|
||||
do_testing: False
|
||||
pretrained_model: null # path to .nemo file or model name from list_available_models()
|
||||
|
||||
model:
|
||||
model_name: "google/byt5-small" # One of: google/byt5-small/base/large/xl or t5-small/base/large/3b/11b
|
||||
max_source_len: 256
|
||||
max_target_len: 512
|
||||
do_lower: false
|
||||
|
||||
train_ds:
|
||||
manifest_filepath: ${train_manifest}
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.g2p.data.t5.T5G2PDataset"
|
||||
phoneme_field: "text" # name of the field in manifest_filepath for ground truth phonemes
|
||||
grapheme_field: "text_graphemes" # name of the field in manifest_filepath for input grapheme text
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: true
|
||||
batch_size: 20
|
||||
num_workers: 4
|
||||
|
||||
validation_ds:
|
||||
manifest_filepath: ${validation_manifest}
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.g2p.data.t5.T5G2PDataset"
|
||||
phoneme_field: "text" # name of the field in manifest_filepath for ground truth phonemes
|
||||
grapheme_field: "text_graphemes" # name of the field in manifest_filepath for input grapheme text
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 20
|
||||
num_workers: 4
|
||||
|
||||
test_ds:
|
||||
manifest_filepath: ${test_manifest}
|
||||
dataset:
|
||||
_target_: "nemo.collections.tts.g2p.data.t5.T5G2PDataset"
|
||||
phoneme_field: "text" # name of the field in manifest_filepath for ground truth phonemes
|
||||
grapheme_field: "text_graphemes" # name of the field in manifest_filepath for input grapheme text
|
||||
dataloader_params:
|
||||
drop_last: false
|
||||
shuffle: false
|
||||
batch_size: 20
|
||||
num_workers: 4
|
||||
|
||||
optim:
|
||||
name: adamw
|
||||
lr: 2e-4
|
||||
weight_decay: 0.01
|
||||
# scheduler setup
|
||||
sched:
|
||||
name: WarmupAnnealing
|
||||
|
||||
# pytorch lightning args
|
||||
monitor: val_token_precision
|
||||
reduce_on_plateau: false
|
||||
|
||||
# scheduler config override
|
||||
warmup_steps: null
|
||||
warmup_ratio: 0.1
|
||||
last_epoch: -1
|
||||
|
||||
trainer:
|
||||
devices: 1 # number of gpus
|
||||
max_epochs: 5
|
||||
num_nodes: 1
|
||||
accelerator: gpu
|
||||
strategy: ddp
|
||||
accumulate_grad_batches: 1
|
||||
enable_checkpointing: False # Provided by exp_manager
|
||||
logger: False # Provided by exp_manager
|
||||
log_every_n_steps: 200
|
||||
check_val_every_n_epoch: 1
|
||||
|
||||
exp_manager:
|
||||
exp_dir: null
|
||||
name: ${name}
|
||||
create_tensorboard_logger: True
|
||||
create_checkpoint_callback: True
|
||||
checkpoint_callback_params:
|
||||
save_top_k: 1
|
||||
monitor: "val_per"
|
||||
mode: "min"
|
||||
save_best_model: true
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
from dataclasses import dataclass, is_dataclass
|
||||
from typing import Optional
|
||||
|
||||
import lightning.pytorch as pl
|
||||
import torch
|
||||
from omegaconf import OmegaConf
|
||||
from utils import get_metrics
|
||||
|
||||
from nemo.collections.tts.models.base import G2PModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils import logging
|
||||
|
||||
"""
|
||||
python g2p_inference.py \
|
||||
pretrained_model=<Path to .nemo file or pretrained model name for G2PModel from list_available_models()>" \
|
||||
manifest_filepath="<Path to .json manifest>" \
|
||||
output_file="<Path to .json manifest to save prediction>" \
|
||||
batch_size=32 \
|
||||
num_workers=4 \
|
||||
pred_field=pred_text
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class TranscriptionConfig:
|
||||
# Required configs
|
||||
pretrained_model: str # Path to a .nemo file or Name of a pretrained model
|
||||
manifest_filepath: str # Path to .json manifest file
|
||||
phoneme_field: Optional[str] = (
|
||||
None # name of the field in manifest_filepath for ground truth phonemes, default during training "text"
|
||||
)
|
||||
grapheme_field: Optional[str] = "text_graphemes" # name of the field in manifest_filepath for input grapheme text
|
||||
|
||||
# General configs
|
||||
output_file: Optional[str] = (
|
||||
None # Path to .json manifest file to save predictions, will be saved in "target_field"
|
||||
)
|
||||
pred_field: Optional[str] = "pred_text" # name of the field in the output_file to save predictions
|
||||
batch_size: int = 32 # Batch size to use for inference
|
||||
num_workers: int = 0 # Number of workers to use for DataLoader during inference
|
||||
|
||||
|
||||
@hydra_runner(config_name="TranscriptionConfig", schema=TranscriptionConfig)
|
||||
def main(cfg: TranscriptionConfig) -> TranscriptionConfig:
|
||||
logging.info(f'Hydra config: {OmegaConf.to_yaml(cfg)}')
|
||||
|
||||
if is_dataclass(cfg):
|
||||
cfg = OmegaConf.structured(cfg)
|
||||
|
||||
if not cfg.pretrained_model:
|
||||
raise ValueError(
|
||||
'To run evaluation and inference script a pre-trained model or .nemo file must be provided.'
|
||||
f'Choose from {G2PModel.list_available_models()} or "pretrained_model"="your_model.nemo"'
|
||||
)
|
||||
|
||||
logging.info(
|
||||
'During evaluation/testing, it is currently advisable to construct a new Trainer with single GPU and \
|
||||
no DDP to obtain accurate results'
|
||||
)
|
||||
|
||||
# setup GPU
|
||||
if torch.cuda.is_available():
|
||||
device = [0] # use 0th CUDA device
|
||||
accelerator = 'gpu'
|
||||
else:
|
||||
device = 1
|
||||
accelerator = 'cpu'
|
||||
|
||||
map_location = torch.device('cuda:{}'.format(device[0]) if accelerator == 'gpu' else 'cpu')
|
||||
trainer = pl.Trainer(devices=device, accelerator=accelerator, logger=False, enable_checkpointing=False)
|
||||
|
||||
if os.path.exists(cfg.pretrained_model):
|
||||
model = G2PModel.restore_from(cfg.pretrained_model, map_location=map_location)
|
||||
elif cfg.pretrained_model in G2PModel.get_available_model_names():
|
||||
model = G2PModel.from_pretrained(cfg.pretrained_model, map_location=map_location)
|
||||
else:
|
||||
raise ValueError(
|
||||
f'Provide path to the pre-trained .nemo checkpoint or choose from {G2PModel.list_available_models()}'
|
||||
)
|
||||
model._cfg.max_source_len = 512
|
||||
model.set_trainer(trainer)
|
||||
model = model.eval()
|
||||
|
||||
if cfg.output_file is None:
|
||||
cfg.output_file = cfg.manifest_filepath.replace(".json", "_phonemes.json")
|
||||
|
||||
with torch.no_grad():
|
||||
model.convert_graphemes_to_phonemes(
|
||||
manifest_filepath=cfg.manifest_filepath,
|
||||
output_manifest_filepath=cfg.output_file,
|
||||
grapheme_field=cfg.grapheme_field,
|
||||
batch_size=cfg.batch_size,
|
||||
num_workers=cfg.num_workers,
|
||||
pred_field=cfg.pred_field,
|
||||
)
|
||||
print(f"IPA predictions saved in {cfg.output_file}")
|
||||
|
||||
if cfg.phoneme_field is not None:
|
||||
get_metrics(cfg.output_file, phoneme_field=cfg.phoneme_field, grapheme_field=cfg.grapheme_field)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,121 @@
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
|
||||
import lightning.pytorch as pl
|
||||
import torch
|
||||
from utils import get_model
|
||||
|
||||
from nemo.collections.common.callbacks import LogEpochTimeCallback
|
||||
from nemo.collections.tts.models.base import G2PModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils import logging, model_utils
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
"""
|
||||
This script supports training of G2PModels
|
||||
(for T5G2PModel use g2p_t5.yaml, for CTCG2PModel use either g2p_conformer.yaml or g2p_t5_ctc.yaml)
|
||||
|
||||
# Training T5G2PModel and evaluation at the end of training:
|
||||
python examples/text_processing/g2p/g2p_train_and_evaluate.py \
|
||||
# (Optional: --config-path=<Path to dir of configs> --config-name=<name of config without .yaml>) \
|
||||
model.train_ds.manifest_filepath="<Path to manifest file>" \
|
||||
model.validation_ds.manifest_filepath="<Path to manifest file>" \
|
||||
model.test_ds.manifest_filepath="<Path to manifest file>" \
|
||||
trainer.devices=1 \
|
||||
do_training=True \
|
||||
do_testing=True
|
||||
|
||||
Example of the config file: NeMo/examples/tts/g2p/conf/g2p_t5.yaml
|
||||
|
||||
# Training Conformer-G2P Model and evaluation at the end of training:
|
||||
python examples/text_processing/g2p/g2p_train_and_evaluate.py \
|
||||
# (Optional: --config-path=<Path to dir of configs> --config-name=<name of config without .yaml>) \
|
||||
model.train_ds.manifest_filepath="<Path to manifest file>" \
|
||||
model.validation_ds.manifest_filepath="<Path to manifest file>" \
|
||||
model.test_ds.manifest_filepath="<Path to manifest file>" \
|
||||
model.tokenizer.dir=<Path to pretrained tokenizer> \
|
||||
trainer.devices=1 \
|
||||
do_training=True \
|
||||
do_testing=True
|
||||
|
||||
Example of the config file: NeMo/examples/text_processing/g2p/conf/g2p_conformer_ctc.yaml
|
||||
|
||||
# Run evaluation of the pretrained model:
|
||||
python examples/text_processing/g2p/g2p_train_and_evaluate.py \
|
||||
# (Optional: --config-path=<Path to dir of configs> --config-name=<name of config without .yaml>) \
|
||||
pretrained_model="<Path to .nemo file or pretrained model name from list_available_models()>" \
|
||||
model.test_ds.manifest_filepath="<Path to manifest file>" \
|
||||
trainer.devices=1 \
|
||||
do_training=False \
|
||||
do_testing=True
|
||||
"""
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf", config_name="g2p_t5")
|
||||
def main(cfg):
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
|
||||
g2p_model = None
|
||||
if cfg.do_training:
|
||||
g2p_model = get_model(cfg, trainer)
|
||||
lr_logger = pl.callbacks.LearningRateMonitor()
|
||||
epoch_time_logger = LogEpochTimeCallback()
|
||||
trainer.callbacks.extend([lr_logger, epoch_time_logger])
|
||||
trainer.fit(g2p_model)
|
||||
|
||||
if cfg.do_testing:
|
||||
logging.info(
|
||||
'During evaluation/testing, it is currently advisable to construct a new Trainer with single GPU and \
|
||||
no DDP to obtain accurate results'
|
||||
)
|
||||
# setup GPU
|
||||
if torch.cuda.is_available():
|
||||
device = [0] # use 0th CUDA device
|
||||
accelerator = 'gpu'
|
||||
else:
|
||||
device = 1
|
||||
accelerator = 'cpu'
|
||||
|
||||
map_location = torch.device('cuda:{}'.format(device[0]) if accelerator == 'gpu' else 'cpu')
|
||||
trainer = pl.Trainer(devices=device, accelerator=accelerator, logger=False, enable_checkpointing=False)
|
||||
|
||||
if g2p_model is None:
|
||||
if os.path.exists(cfg.pretrained_model):
|
||||
# restore g2p_model from .nemo file path
|
||||
model_cfg = G2PModel.restore_from(restore_path=cfg.pretrained_model, return_config=True)
|
||||
classpath = model_cfg.target # original class path
|
||||
imported_class = model_utils.import_class_by_path(classpath)
|
||||
logging.info(f"Restoring g2p_model : {imported_class.__name__}")
|
||||
g2p_model = imported_class.restore_from(restore_path=cfg.pretrained_model, map_location=map_location)
|
||||
model_name = os.path.splitext(os.path.basename(cfg.pretrained_model))[0]
|
||||
logging.info(f"Restored {model_name} g2p_model from {cfg.pretrained_model}.")
|
||||
elif cfg.pretrained_model in G2PModel.get_available_model_names():
|
||||
# restore g2p_model by name
|
||||
g2p_model = G2PModel.from_pretrained(cfg.pretrained_model, map_location=map_location)
|
||||
else:
|
||||
raise ValueError(
|
||||
f'Provide path to the pre-trained .nemo checkpoint or choose from {G2PModel.list_available_models()}'
|
||||
)
|
||||
|
||||
if hasattr(cfg.model, "test_ds") and cfg.model.test_ds.manifest_filepath is not None:
|
||||
g2p_model.setup_multiple_test_data(cfg.model.test_ds)
|
||||
if g2p_model.prepare_test(trainer):
|
||||
trainer.test(g2p_model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,93 @@
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
|
||||
from nemo.collections.asr.metrics.wer import word_error_rate
|
||||
from nemo.collections.tts.g2p.models.ctc import CTCG2PModel
|
||||
from nemo.collections.tts.g2p.models.t5 import T5G2PModel
|
||||
from nemo.utils import logging
|
||||
|
||||
|
||||
def get_model(cfg, trainer):
|
||||
"""
|
||||
Get model instance
|
||||
|
||||
Args:
|
||||
cfg: model's config file
|
||||
trainer: trainer
|
||||
Return:
|
||||
G2PModel instance
|
||||
"""
|
||||
if "CTC" in cfg.name:
|
||||
model = CTCG2PModel(cfg=cfg.model, trainer=trainer)
|
||||
elif cfg.name == "T5G2P":
|
||||
model = T5G2PModel(cfg=cfg.model, trainer=trainer)
|
||||
else:
|
||||
raise ValueError(f"{cfg.name} is not supported. Choose from [G2P-Conformer-CTC, T5G2P]")
|
||||
return model
|
||||
|
||||
|
||||
def get_metrics(manifest: str, pred_field="pred_text", phoneme_field="text", grapheme_field="text_graphemes"):
|
||||
"""
|
||||
Calculates WER and PER metrics (for duplicated grapheme entries with multiple reference values,
|
||||
the best matching prediction will be used for evaluation.)
|
||||
|
||||
Args:
|
||||
manifest: Path to .json manifest file
|
||||
pred_field: name of the field in the output_file to save predictions
|
||||
phoneme_field: name of the field in manifest_filepath for ground truth phonemes
|
||||
grapheme_field: name of the field in manifest_filepath for input grapheme text
|
||||
|
||||
Returns: WER and PER values
|
||||
"""
|
||||
all_preds = []
|
||||
all_references = []
|
||||
all_graphemes = {}
|
||||
with open(manifest, "r") as f:
|
||||
for i, line in enumerate(f):
|
||||
line = json.loads(line)
|
||||
all_preds.append(line[pred_field])
|
||||
all_references.append(line[phoneme_field])
|
||||
|
||||
if line[grapheme_field] not in all_graphemes:
|
||||
all_graphemes[line[grapheme_field]] = []
|
||||
all_graphemes[line[grapheme_field]].append(i)
|
||||
|
||||
# collect all examples with multiple phoneme options and same grapheme form, choose the one with min PER
|
||||
all_graphemes = {k: v for k, v in all_graphemes.items() if len(v) > 1}
|
||||
lines_to_drop = []
|
||||
for phon_amb_indices in all_graphemes.values():
|
||||
refs, preds = [], []
|
||||
for phon_amb_indices_ in phon_amb_indices:
|
||||
refs.append(all_references[phon_amb_indices_])
|
||||
preds.append(all_preds[phon_amb_indices_])
|
||||
pers = []
|
||||
for ref_, pred_ in zip(refs, preds):
|
||||
pers.append(word_error_rate(hypotheses=[pred_], references=[ref_], use_cer=True))
|
||||
|
||||
min_idx = pers.index(min(pers))
|
||||
|
||||
phon_amb_indices.pop(min_idx)
|
||||
lines_to_drop.extend(phon_amb_indices)
|
||||
|
||||
# drop duplicated examples, only keep with min PER
|
||||
all_preds = [x for i, x in enumerate(all_preds) if i not in lines_to_drop]
|
||||
all_references = [x for i, x in enumerate(all_references) if i not in lines_to_drop]
|
||||
|
||||
wer = word_error_rate(hypotheses=all_preds, references=all_references)
|
||||
per = word_error_rate(hypotheses=all_preds, references=all_references, use_cer=True)
|
||||
|
||||
logging.info(f"{manifest}: PER: {per * 100:.2f}%, WER: {wer * 100:.2f}%, lines: {len(all_references)}")
|
||||
return wer, per
|
||||
@@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
|
||||
from nemo.collections.tts.models import HifiGanModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf/hifigan", config_name="hifigan")
|
||||
def main(cfg):
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
model = HifiGanModel(cfg=cfg.model, trainer=trainer)
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
|
||||
from nemo.collections.tts.models import HifiGanModel
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf/hifigan", config_name="hifigan_44100")
|
||||
def main(cfg):
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
model = HifiGanModel(cfg=cfg.model, trainer=trainer)
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,113 @@
|
||||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
import torch.multiprocessing as mp
|
||||
from omegaconf import OmegaConf, open_dict
|
||||
|
||||
from nemo.collections.tts.models import (
|
||||
MagpieTTSModel,
|
||||
MagpieTTSModelOfflinePO,
|
||||
MagpieTTSModelOfflinePODataGen,
|
||||
MagpieTTSModelOnlinePO,
|
||||
OnlineCFGDistillation,
|
||||
)
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils import logging
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
_TRAIN_MODES: list[str] = [
|
||||
"train",
|
||||
"online_cfg_distillation_train",
|
||||
"dpo_train",
|
||||
"onlinepo_train",
|
||||
]
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf/magpietts", config_name="magpietts_lhotse")
|
||||
def main(cfg):
|
||||
logging.info('\nConfig Params:\n%s', OmegaConf.to_yaml(cfg, resolve=True))
|
||||
|
||||
# forcing "spawn" method for multiprocessing over "fork" when choosing multiple
|
||||
# worker processes for dataloaders. By default, multiprocessing uses "fork" to create
|
||||
# worker processes, which inherit the memory state of the main process, including its
|
||||
# already initialized CUDA state. When the worker processes trieds to use
|
||||
# CUDA, it runs into conflicts with the inherited, now potentially invalid,
|
||||
# CUDA context, resuling in the CUDA initialization error. When
|
||||
# num_workers=0, all dataloading happens in the main process, so there is no
|
||||
# process forking and no CUDA context conflict. When num_workers>0, the standard way
|
||||
# to fix this is to use "spawn" to create a completely new and clean python process for
|
||||
# each worker, avoding the problematic CUDA state inheritance.
|
||||
mp.set_start_method("spawn", force=True)
|
||||
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
trainer.callbacks.append(pl.callbacks.LearningRateMonitor(logging_interval='step', log_weight_decay=True))
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
|
||||
seed = cfg.get('seed', None)
|
||||
if seed is not None:
|
||||
# Option to seed for debugging
|
||||
logging.info(f"Setting seed to {seed}")
|
||||
pl.seed_everything(seed, workers=True)
|
||||
|
||||
mode = cfg.get('mode', 'train')
|
||||
train_modes_msg = ", ".join(_TRAIN_MODES)
|
||||
|
||||
if mode == 'train':
|
||||
model = MagpieTTSModel(cfg=cfg.model, trainer=trainer)
|
||||
elif mode == 'online_cfg_distillation_train':
|
||||
model = OnlineCFGDistillation(cfg=cfg.model, trainer=trainer)
|
||||
elif mode == 'dpo_train':
|
||||
model_cfg = cfg.model
|
||||
with open_dict(model_cfg):
|
||||
model_cfg.reference_model_ckpt_path = cfg.init_from_ptl_ckpt
|
||||
model = MagpieTTSModelOfflinePO(cfg=model_cfg, trainer=trainer)
|
||||
elif mode == 'onlinepo_train':
|
||||
model_cfg = cfg.model
|
||||
with open_dict(model_cfg):
|
||||
model_cfg.reference_model_ckpt_path = cfg.init_from_ptl_ckpt
|
||||
model = MagpieTTSModelOnlinePO(cfg=model_cfg, trainer=trainer)
|
||||
elif mode == 'test':
|
||||
model = MagpieTTSModelOfflinePODataGen(cfg=cfg.model, trainer=trainer)
|
||||
else:
|
||||
raise NotImplementedError(f"Only {train_modes_msg} and test modes are supported. Got {mode}")
|
||||
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
|
||||
try:
|
||||
if mode in _TRAIN_MODES:
|
||||
logging.info("Starting training...")
|
||||
trainer.fit(model)
|
||||
elif mode == 'test':
|
||||
logging.info("Starting testing...")
|
||||
trainer.test(model)
|
||||
else:
|
||||
raise NotImplementedError(f"Only {train_modes_msg} and test modes are supported. Got {mode}")
|
||||
logging.info("Training/testing completed successfully.")
|
||||
finally:
|
||||
# Ensure WandB completes all uploads before Python thread shutdown
|
||||
# Critical when num_workers=0 during debugging - the main process can become
|
||||
# overwhelmed and fail to properly coordinate with WandB's background threads
|
||||
try:
|
||||
import wandb
|
||||
|
||||
if wandb.run is not None:
|
||||
logging.info("Finishing WandB run to prevent threading shutdown hang...")
|
||||
wandb.finish()
|
||||
except Exception as e:
|
||||
logging.warning(f"Error finishing WandB: {e}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
@@ -0,0 +1,848 @@
|
||||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""
|
||||
TTS Inference and Evaluation Script.
|
||||
|
||||
Supports both encoder-decoder MagpieTTS and decoder-only EasyMagpieTTS models
|
||||
with:
|
||||
- Automatic MoE detection and FLOPs calculation
|
||||
- Comprehensive evaluation metrics (RTF, FLOPs, CER, SSIM, etc.)
|
||||
|
||||
This script provides a clean CLI for running TTS inference with optional
|
||||
evaluation. Model-specific behaviour (dataset creation, inference loop, CLI
|
||||
arguments) is handled by separate runner classes so there is no scattered
|
||||
if/else branching.
|
||||
|
||||
Example usage:
|
||||
# MagpieTTS inference (encoder-decoder, default)
|
||||
python examples/tts/magpietts_inference.py \\
|
||||
--model_type magpie \\
|
||||
--nemo_files /path/to/model.nemo \\
|
||||
--datasets_json_path /path/to/evalset_config.json \\
|
||||
--out_dir /path/to/output \\
|
||||
--codecmodel_path /path/to/codec.nemo
|
||||
|
||||
# EasyMagpieTTS inference (decoder-only)
|
||||
python examples/tts/magpietts_inference.py \\
|
||||
--model_type easy_magpie \\
|
||||
--nemo_files /path/to/model.nemo \\
|
||||
--datasets_json_path /path/to/evalset_config.json \\
|
||||
--out_dir /path/to/output \\
|
||||
--codecmodel_path /path/to/codec.nemo
|
||||
|
||||
# With evaluation
|
||||
python examples/tts/magpietts_inference.py \\
|
||||
--model_type magpie \\
|
||||
--hparams_files /path/to/hparams.yaml \\
|
||||
--checkpoint_files /path/to/model.ckpt \\
|
||||
--datasets_json_path /path/to/evalset_config.json \\
|
||||
--out_dir /path/to/output \\
|
||||
--codecmodel_path /path/to/codec.nemo \\
|
||||
--run_evaluation \\
|
||||
--num_repeats 3
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
from dataclasses import fields
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from nemo.collections.asr.parts.utils.manifest_utils import read_manifest
|
||||
from nemo.collections.tts.models.easy_magpietts_inference import EasyModelInferenceParameters
|
||||
from nemo.collections.tts.models.magpietts import ModelInferenceParameters
|
||||
from nemo.collections.tts.modules.magpietts_inference.evaluate_generated_audio import load_evalset_config
|
||||
from nemo.collections.tts.modules.magpietts_inference.evaluation import (
|
||||
DEFAULT_VIOLIN_METRICS,
|
||||
EvaluationConfig,
|
||||
compute_mean_with_confidence_interval,
|
||||
evaluate_generated_audio_dir,
|
||||
)
|
||||
from nemo.collections.tts.modules.magpietts_inference.inference import (
|
||||
BaseInferenceConfig,
|
||||
BaseInferenceRunner,
|
||||
EasyMagpieInferenceConfig,
|
||||
EasyMagpieInferenceRunner,
|
||||
MagpieInferenceConfig,
|
||||
MagpieInferenceRunner,
|
||||
)
|
||||
from nemo.collections.tts.modules.magpietts_inference.utils import (
|
||||
ModelLoadConfig,
|
||||
get_experiment_name_from_checkpoint_path,
|
||||
load_easy_magpie_model,
|
||||
load_magpie_model,
|
||||
log_model_architecture_summary,
|
||||
)
|
||||
from nemo.collections.tts.modules.magpietts_inference.visualization import create_combined_box_plot, create_violin_plot
|
||||
from nemo.collections.tts.modules.magpietts_modules import EOSDetectionMethod
|
||||
from nemo.utils import logging
|
||||
|
||||
|
||||
def parse_layer_list(layer_str: Optional[str]) -> Optional[List[int]]:
|
||||
"""Parse a comma-separated list of layer indices."""
|
||||
if layer_str is None:
|
||||
return None
|
||||
return [int(l.strip()) for l in layer_str.split(",")]
|
||||
|
||||
|
||||
def write_csv_header_if_needed(csv_path: str, header: str) -> None:
|
||||
"""Write CSV header if file doesn't exist."""
|
||||
if not os.path.exists(csv_path):
|
||||
with open(csv_path, "w") as f:
|
||||
f.write(header + "\n")
|
||||
|
||||
|
||||
def append_metrics_to_csv(csv_path: str, checkpoint_name: str, dataset: str, metrics: dict) -> None:
|
||||
"""Append metrics to a CSV file."""
|
||||
values = [
|
||||
checkpoint_name,
|
||||
dataset,
|
||||
metrics.get('cer_filewise_avg', ''),
|
||||
metrics.get('wer_filewise_avg', ''),
|
||||
metrics.get('cer_cumulative', ''),
|
||||
metrics.get('wer_cumulative', ''),
|
||||
metrics.get('ssim_pred_gt_avg', ''),
|
||||
metrics.get('ssim_pred_context_avg', ''),
|
||||
metrics.get('ssim_gt_context_avg', ''),
|
||||
metrics.get('ssim_pred_gt_avg_alternate', ''),
|
||||
metrics.get('ssim_pred_context_avg_alternate', ''),
|
||||
metrics.get('ssim_gt_context_avg_alternate', ''),
|
||||
metrics.get('cer_gt_audio_cumulative', ''),
|
||||
metrics.get('wer_gt_audio_cumulative', ''),
|
||||
metrics.get('utmosv2_avg', ''),
|
||||
metrics.get('total_gen_audio_seconds', ''),
|
||||
metrics.get('frechet_codec_distance', ''),
|
||||
metrics.get('eou_cutoff_rate', ''),
|
||||
metrics.get('eou_silence_rate', ''),
|
||||
metrics.get('eou_noise_rate', ''),
|
||||
metrics.get('eou_error_rate', ''),
|
||||
]
|
||||
with open(csv_path, "a") as f:
|
||||
f.write(",".join(str(v) for v in values) + "\n")
|
||||
logging.info(f"Metrics appended to: {csv_path}")
|
||||
|
||||
|
||||
def create_formatted_metrics_mean_ci(metrics_mean_ci: dict) -> dict:
|
||||
"""Create formatted metrics mean CI."""
|
||||
for k, v in metrics_mean_ci.items():
|
||||
if isinstance(v, list):
|
||||
mean, ci = float(v[0]), float(v[1])
|
||||
logging.info(f"Metric {k}: {mean:.4f} ± {ci:.4f}")
|
||||
metrics_mean_ci[k] = f"{mean:.4f} ± {ci:.4f}"
|
||||
return metrics_mean_ci
|
||||
|
||||
|
||||
def filter_datasets(
|
||||
dataset_meta_info: dict,
|
||||
datasets: Optional[List[str]],
|
||||
) -> List[str]:
|
||||
"""Select datasets from the dataset meta info."""
|
||||
if datasets is None:
|
||||
# Dataset filtering not specified, return all datasets.
|
||||
return list(dataset_meta_info.keys())
|
||||
else:
|
||||
datasets = datasets.split(",")
|
||||
# Check if requested datasets are valid.
|
||||
for dataset in datasets:
|
||||
if dataset not in dataset_meta_info:
|
||||
raise ValueError(f"Dataset {dataset} not found in dataset meta info")
|
||||
# Return all requested datasets.
|
||||
return datasets
|
||||
|
||||
|
||||
def run_inference_and_evaluation(
|
||||
runner: BaseInferenceRunner,
|
||||
checkpoint_name: str,
|
||||
inference_config: BaseInferenceConfig,
|
||||
eval_config: EvaluationConfig,
|
||||
dataset_meta_info: dict,
|
||||
datasets: List[str],
|
||||
out_dir: str,
|
||||
flops_per_component: dict,
|
||||
moe_info: str,
|
||||
num_repeats: int = 1,
|
||||
confidence_level: float = 0.95,
|
||||
violin_plot_metrics: Optional[List[str]] = None,
|
||||
clean_up_disk: bool = False,
|
||||
skip_evaluation: bool = False,
|
||||
) -> Tuple[Optional[float], Optional[float]]:
|
||||
"""Run inference and optional evaluation on specified datasets.
|
||||
|
||||
This function is model-type agnostic -- it delegates dataset creation
|
||||
and batch inference to the provided ``runner``.
|
||||
|
||||
Args:
|
||||
runner: Concrete inference runner (MagpieInferenceRunner or EasyMagpieInferenceRunner).
|
||||
checkpoint_name: Human-readable checkpoint identifier for output naming.
|
||||
inference_config: Configuration for inference.
|
||||
eval_config: Configuration for evaluation.
|
||||
dataset_meta_info: Dictionary containing dataset metadata.
|
||||
datasets: List of dataset names to process.
|
||||
out_dir: Output directory for results.
|
||||
flops_per_component: FLOPs info dict from log_model_architecture_summary.
|
||||
moe_info: MoE identifier string from log_model_architecture_summary.
|
||||
num_repeats: Number of times to repeat inference (for CI estimation).
|
||||
confidence_level: Confidence level for CI calculation.
|
||||
violin_plot_metrics: Metrics to include in violin plots.
|
||||
clean_up_disk: Whether to clean up output directory after completion.
|
||||
skip_evaluation: Whether to skip evaluation (inference only mode).
|
||||
|
||||
Returns:
|
||||
Tuple of (mean CER across datasets, mean SSIM across datasets).
|
||||
"""
|
||||
if violin_plot_metrics is None:
|
||||
violin_plot_metrics = list(DEFAULT_VIOLIN_METRICS)
|
||||
|
||||
# Remove UTMOSv2 from plots if disabled
|
||||
if not eval_config.with_utmosv2 and 'utmosv2' in violin_plot_metrics:
|
||||
violin_plot_metrics.remove('utmosv2')
|
||||
|
||||
# Build full checkpoint identifier (include MoE info if present)
|
||||
full_checkpoint_name = f"{checkpoint_name}_{moe_info}{inference_config.build_identifier()}_SV_{eval_config.sv_model}_{eval_config.language}"
|
||||
|
||||
# Tracking metrics across datasets
|
||||
ssim_per_dataset = []
|
||||
cer_per_dataset = []
|
||||
all_datasets_filewise_metrics = {}
|
||||
|
||||
# CSV headers
|
||||
csv_header = (
|
||||
"checkpoint_name,dataset,cer_filewise_avg,wer_filewise_avg,cer_cumulative,"
|
||||
"wer_cumulative,ssim_pred_gt_avg,ssim_pred_context_avg,ssim_gt_context_avg,"
|
||||
"ssim_pred_gt_avg_alternate,ssim_pred_context_avg_alternate,"
|
||||
"ssim_gt_context_avg_alternate,cer_gt_audio_cumulative,wer_gt_audio_cumulative,"
|
||||
"utmosv2_avg,total_gen_audio_seconds,frechet_codec_distance,"
|
||||
"eou_cutoff_rate,eou_silence_rate,eou_noise_rate,eou_error_rate"
|
||||
)
|
||||
|
||||
for dataset in datasets:
|
||||
logging.info(f"Processing dataset: {dataset}")
|
||||
|
||||
meta = dataset_meta_info[dataset]
|
||||
manifest_records = read_manifest(meta['manifest_path'])
|
||||
|
||||
if 'asr_model' in meta:
|
||||
asr_model_name = meta['asr_model']['name']
|
||||
asr_model_type = meta['asr_model']['type']
|
||||
else:
|
||||
asr_model_name = eval_config.asr_model_name
|
||||
asr_model_type = eval_config.asr_model_type
|
||||
|
||||
if 'language' in meta:
|
||||
language = meta.get('language')
|
||||
else:
|
||||
language = eval_config.language
|
||||
|
||||
tokenizer_names = meta.get('tokenizer_names', None)
|
||||
|
||||
dataset_meta_for_dl = {
|
||||
"manifest_path": meta["manifest_path"],
|
||||
"audio_dir": meta["audio_dir"],
|
||||
"language": language,
|
||||
"tokenizer_names": tokenizer_names,
|
||||
}
|
||||
|
||||
# Setup output directories
|
||||
eval_dir = os.path.join(out_dir, f"{full_checkpoint_name}_{dataset}")
|
||||
audio_dir = os.path.join(eval_dir, "audio")
|
||||
os.makedirs(eval_dir, exist_ok=True)
|
||||
|
||||
# Setup CSV files
|
||||
per_run_csv = os.path.join(eval_dir, "all_experiment_metrics.csv")
|
||||
write_csv_header_if_needed(per_run_csv, csv_header)
|
||||
|
||||
metrics_all_repeats = []
|
||||
filewise_metrics_all_repeats = []
|
||||
|
||||
for repeat_idx in range(num_repeats):
|
||||
logging.info(f"Repeat {repeat_idx + 1}/{num_repeats} for dataset {dataset}")
|
||||
|
||||
repeat_audio_dir = os.path.join(audio_dir, f"repeat_{repeat_idx}")
|
||||
os.makedirs(repeat_audio_dir, exist_ok=True)
|
||||
|
||||
# Create dataset and run inference
|
||||
test_dataset = runner.create_dataset({dataset: dataset_meta_for_dl})
|
||||
|
||||
if len(test_dataset) != len(manifest_records):
|
||||
raise ValueError(
|
||||
f"Dataset length mismatch: {len(test_dataset)} vs {len(manifest_records)} manifest records"
|
||||
)
|
||||
|
||||
rtf_metrics_list, _, codec_file_paths = runner.run_inference_on_dataset(
|
||||
dataset=test_dataset,
|
||||
output_dir=repeat_audio_dir,
|
||||
manifest_records=manifest_records,
|
||||
audio_base_dir=meta['audio_dir'],
|
||||
save_cross_attention_maps=True,
|
||||
save_context_audio=(repeat_idx == 0), # Only save context audio once
|
||||
save_predicted_codes=eval_config.with_fcd, # Code files are only needed for FCD computation
|
||||
)
|
||||
|
||||
# Compute mean RTF metrics
|
||||
mean_rtf = runner.compute_mean_rtf_metrics(rtf_metrics_list)
|
||||
|
||||
# Add FLOPs metrics per component
|
||||
for component_name, component_flops in flops_per_component.items():
|
||||
for key, value in component_flops.items():
|
||||
mean_rtf[f"{component_name}_{key}"] = value
|
||||
logging.info(f"{component_name} FLOPs per token: {component_flops['total_flops_per_token']:,}")
|
||||
|
||||
with open(os.path.join(eval_dir, f"{dataset}_rtf_metrics_{repeat_idx}.json"), "w") as f:
|
||||
json.dump(mean_rtf, f, indent=4)
|
||||
|
||||
if skip_evaluation:
|
||||
logging.info("Skipping evaluation as requested.")
|
||||
continue
|
||||
|
||||
# Run evaluation
|
||||
eval_config_for_dataset = EvaluationConfig(
|
||||
sv_model=eval_config.sv_model,
|
||||
asr_model_name=asr_model_name,
|
||||
asr_model_type=asr_model_type,
|
||||
eou_model_name=eval_config.eou_model_name,
|
||||
language=language,
|
||||
with_utmosv2=eval_config.with_utmosv2,
|
||||
with_fcd=eval_config.with_fcd,
|
||||
codec_model_path=eval_config.codec_model_path,
|
||||
device=eval_config.device,
|
||||
)
|
||||
|
||||
metrics, filewise_metrics = evaluate_generated_audio_dir(
|
||||
manifest_path=meta['manifest_path'],
|
||||
audio_dir=meta['audio_dir'],
|
||||
generated_audio_dir=repeat_audio_dir,
|
||||
config=eval_config_for_dataset,
|
||||
)
|
||||
|
||||
metrics_all_repeats.append(metrics)
|
||||
filewise_metrics_all_repeats.extend(filewise_metrics)
|
||||
|
||||
# Save metrics
|
||||
with open(os.path.join(eval_dir, f"{dataset}_metrics_{repeat_idx}.json"), "w") as f:
|
||||
json.dump(metrics, f, indent=4)
|
||||
|
||||
sorted_filewise = sorted(filewise_metrics, key=lambda x: x.get('cer', 0), reverse=True)
|
||||
with open(os.path.join(eval_dir, f"{dataset}_filewise_metrics_{repeat_idx}.json"), "w") as f:
|
||||
json.dump(sorted_filewise, f, indent=4)
|
||||
|
||||
# Append to per-run CSV
|
||||
append_metrics_to_csv(per_run_csv, full_checkpoint_name, dataset, metrics)
|
||||
|
||||
# Create violin plot for this repeat
|
||||
violin_path = Path(eval_dir) / f"{dataset}_violin_{repeat_idx}.png"
|
||||
create_violin_plot(filewise_metrics, violin_plot_metrics, violin_path)
|
||||
|
||||
# Delete temporary predicted codes files
|
||||
for codec_file_path in codec_file_paths:
|
||||
os.remove(codec_file_path)
|
||||
|
||||
if skip_evaluation or not metrics_all_repeats:
|
||||
continue
|
||||
|
||||
# Store for combined plot
|
||||
all_datasets_filewise_metrics[dataset] = filewise_metrics_all_repeats
|
||||
|
||||
# Compute mean with confidence interval across repeats
|
||||
metrics_mean_ci = compute_mean_with_confidence_interval(
|
||||
metrics_all_repeats,
|
||||
confidence=confidence_level,
|
||||
)
|
||||
|
||||
formatted_metrics_mean_ci = create_formatted_metrics_mean_ci(metrics_mean_ci)
|
||||
|
||||
# Write to aggregated CSV
|
||||
ci_csv = os.path.join(out_dir, "all_experiment_metrics_with_ci.csv")
|
||||
write_csv_header_if_needed(ci_csv, csv_header)
|
||||
append_metrics_to_csv(ci_csv, full_checkpoint_name, dataset, formatted_metrics_mean_ci)
|
||||
|
||||
# Track per-dataset means
|
||||
ssim_values = [m['ssim_pred_context_avg'] for m in metrics_all_repeats]
|
||||
cer_values = [m['cer_cumulative'] for m in metrics_all_repeats]
|
||||
ssim_per_dataset.append(np.mean(ssim_values))
|
||||
cer_per_dataset.append(np.mean(cer_values))
|
||||
|
||||
# Create combined plot if we have multiple datasets
|
||||
if len(all_datasets_filewise_metrics) > 1:
|
||||
combined_plot_path = os.path.join(out_dir, f"{full_checkpoint_name}_combined_violin_plot.png")
|
||||
create_combined_box_plot(all_datasets_filewise_metrics, violin_plot_metrics, combined_plot_path)
|
||||
|
||||
# Clean up if requested
|
||||
if clean_up_disk:
|
||||
logging.info(f"Cleaning up output directory: {out_dir}")
|
||||
shutil.rmtree(out_dir)
|
||||
|
||||
# Return averaged metrics
|
||||
if ssim_per_dataset and cer_per_dataset:
|
||||
return np.mean(cer_per_dataset), np.mean(ssim_per_dataset)
|
||||
return None, None
|
||||
|
||||
|
||||
def _get_shared_inference_param_names() -> set:
|
||||
"""Return the field names shared by ModelInferenceParameters and EasyModelInferenceParameters."""
|
||||
magpie_fields = {f.name for f in fields(ModelInferenceParameters)}
|
||||
easy_fields = {f.name for f in fields(EasyModelInferenceParameters)}
|
||||
return magpie_fields & easy_fields
|
||||
|
||||
|
||||
def _add_inference_param_fields(
|
||||
group: argparse._ArgumentGroup,
|
||||
param_cls: type,
|
||||
skip_fields: Optional[set] = None,
|
||||
only_fields: Optional[set] = None,
|
||||
) -> None:
|
||||
"""Auto-generate argparse arguments from fields of a dataclass.
|
||||
|
||||
Args:
|
||||
group: The argparse argument group to add arguments to.
|
||||
param_cls: The dataclass whose fields to add.
|
||||
skip_fields: Field names to skip (already added by another group).
|
||||
only_fields: If provided, only add fields whose names are in this set.
|
||||
"""
|
||||
if skip_fields is None:
|
||||
skip_fields = set()
|
||||
for f in fields(param_cls):
|
||||
if f.name in skip_fields:
|
||||
continue
|
||||
if only_fields is not None and f.name not in only_fields:
|
||||
continue
|
||||
extra_args: dict = {"type": f.type}
|
||||
if f.type == bool:
|
||||
extra_args = {"action": "store_true"}
|
||||
if f.name in ("estimate_alignment_from_layers", "apply_prior_to_layers"):
|
||||
extra_args = {
|
||||
"help": "Must be a comma separate string. Not enclosed in brackets",
|
||||
"type": str,
|
||||
}
|
||||
elif f.name == "eos_detection_method":
|
||||
extra_args["choices"] = [m.value for m in EOSDetectionMethod]
|
||||
group.add_argument(f"--{f.name}", **extra_args)
|
||||
|
||||
|
||||
def _add_common_args(parser: argparse.ArgumentParser) -> None:
|
||||
"""Add arguments shared by all model types."""
|
||||
|
||||
parser.add_argument(
|
||||
'--model_type',
|
||||
type=str,
|
||||
default='magpie',
|
||||
choices=['magpie', 'easy_magpie'],
|
||||
help='Model type: "magpie" for encoder-decoder MagpieTTSModel, '
|
||||
'"easy_magpie" for decoder-only EasyMagpieTTSInferenceModel',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--deterministic',
|
||||
action='store_true',
|
||||
help='Attempts to make results deterministic to the best that can be done. Used for testing',
|
||||
)
|
||||
|
||||
# Model loading
|
||||
model_group = parser.add_argument_group('Model Loading')
|
||||
model_group.add_argument(
|
||||
'--hparams_files',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Comma-separated paths to hparams.yaml files (use with --checkpoint_files)',
|
||||
)
|
||||
model_group.add_argument(
|
||||
'--checkpoint_files',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Comma-separated paths to .ckpt files (use with --hparams_files)',
|
||||
)
|
||||
model_group.add_argument(
|
||||
'--nemo_files',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Comma-separated paths to .nemo files (alternative to hparams + checkpoint)',
|
||||
)
|
||||
model_group.add_argument(
|
||||
'--codecmodel_path',
|
||||
type=str,
|
||||
required=True,
|
||||
help='Path to the audio codec model',
|
||||
)
|
||||
model_group.add_argument(
|
||||
'--hparams_file_from_wandb',
|
||||
action='store_true',
|
||||
help='Set if hparams file was exported from wandb',
|
||||
)
|
||||
model_group.add_argument(
|
||||
'--legacy_codebooks',
|
||||
action='store_true',
|
||||
help='Use legacy codebook indices (for old checkpoints)',
|
||||
)
|
||||
model_group.add_argument(
|
||||
'--legacy_text_conditioning',
|
||||
action='store_true',
|
||||
help='Use legacy text conditioning (for old checkpoints)',
|
||||
)
|
||||
|
||||
# Dataset and output
|
||||
data_group = parser.add_argument_group('Dataset and Output')
|
||||
data_group.add_argument(
|
||||
'--datasets_json_path',
|
||||
type=str,
|
||||
required=True,
|
||||
default=None,
|
||||
help='Path to dataset configuration JSON file',
|
||||
)
|
||||
data_group.add_argument(
|
||||
'--datasets_base_path',
|
||||
type=Path,
|
||||
default=None,
|
||||
help='Optional base path that paths in the "datasets_json_path" file are relative to',
|
||||
)
|
||||
data_group.add_argument(
|
||||
'--datasets',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Comma-separated list of dataset names to process',
|
||||
)
|
||||
data_group.add_argument(
|
||||
'--tokenizer_name',
|
||||
type=str,
|
||||
default="english_phoneme",
|
||||
help='Default tokenizer to use when a language or dataset specific tokenizer is not provided.',
|
||||
)
|
||||
data_group.add_argument('--out_dir', type=str, required=True, help='Output directory')
|
||||
data_group.add_argument('--log_exp_name', action='store_true')
|
||||
data_group.add_argument('--clean_up_disk', action='store_true')
|
||||
|
||||
# Common inference parameters
|
||||
infer_group = parser.add_argument_group('Common Inference Parameters')
|
||||
infer_group.add_argument('--batch_size', type=int, default=32)
|
||||
infer_group.add_argument('--use_cfg', action='store_true', help='Enable classifier-free guidance')
|
||||
infer_group.add_argument('--use_local_transformer', action='store_true')
|
||||
|
||||
# Model inference parameters shared by both MagpieTTS and EasyMagpieTTS
|
||||
shared_param_names = _get_shared_inference_param_names()
|
||||
_add_inference_param_fields(infer_group, ModelInferenceParameters, only_fields=shared_param_names)
|
||||
|
||||
# Evaluation
|
||||
eval_group = parser.add_argument_group('Evaluation')
|
||||
eval_group.add_argument('--run_evaluation', action='store_true', help='Run evaluation after inference')
|
||||
eval_group.add_argument('--sv_model', type=str, default="titanet", choices=["titanet", "wavlm"])
|
||||
eval_group.add_argument(
|
||||
'--asr_model_name',
|
||||
type=str,
|
||||
default='nvidia/parakeet-tdt-1.1b',
|
||||
help="ASR model to use for WER calculation, when not provided in dataset config",
|
||||
)
|
||||
eval_group.add_argument(
|
||||
'--asr_model_type',
|
||||
type=str,
|
||||
default='nemo',
|
||||
choices=['nemo', 'nemo_with_prompt', 'whisper'],
|
||||
help="Type of ASR model provided in 'asr_model_name'",
|
||||
)
|
||||
eval_group.add_argument(
|
||||
'--language', type=str, default="en", help='Language to use, when not provided in dataset config'
|
||||
)
|
||||
eval_group.add_argument(
|
||||
'--eou_model_name',
|
||||
type=str,
|
||||
default="facebook/wav2vec2-base-960h",
|
||||
help=(
|
||||
'Hugging Face model id or local path to the EoU wav2vec2 model directory. '
|
||||
'For offline use, download the model locally and pass the directory path here.'
|
||||
),
|
||||
)
|
||||
eval_group.add_argument('--num_repeats', type=int, default=1)
|
||||
eval_group.add_argument('--confidence_level', type=float, default=0.95)
|
||||
eval_group.add_argument('--disable_utmosv2', action='store_true')
|
||||
eval_group.add_argument(
|
||||
'--violin_plot_metrics',
|
||||
type=str,
|
||||
nargs='*',
|
||||
default=['cer', 'pred_context_ssim', 'utmosv2'],
|
||||
)
|
||||
eval_group.add_argument('--disable_fcd', action='store_true')
|
||||
|
||||
# Quality targets
|
||||
target_group = parser.add_argument_group('Quality Targets')
|
||||
target_group.add_argument('--cer_target', type=float, default=None)
|
||||
target_group.add_argument('--ssim_target', type=float, default=None)
|
||||
|
||||
|
||||
def seed_all(seed: int):
|
||||
"""
|
||||
Attempts to make script deterministic
|
||||
"""
|
||||
torch.manual_seed(seed)
|
||||
random.seed(seed)
|
||||
np.random.seed(seed)
|
||||
torch.backends.cudnn.benchmark = False
|
||||
torch.use_deterministic_algorithms(True)
|
||||
|
||||
|
||||
def _add_magpie_args(parser: argparse.ArgumentParser) -> None:
|
||||
"""Add arguments specific to encoder-decoder MagpieTTSModel."""
|
||||
group = parser.add_argument_group('MagpieTTS-specific Parameters')
|
||||
|
||||
# MagpieTTS-specific model inference parameters (attention prior, EOS, etc.)
|
||||
shared_param_names = _get_shared_inference_param_names()
|
||||
_add_inference_param_fields(group, ModelInferenceParameters, skip_fields=shared_param_names)
|
||||
|
||||
group.add_argument('--maskgit_n_steps', type=int, default=3)
|
||||
group.add_argument('--maskgit_noise_scale', type=float, default=0.0)
|
||||
group.add_argument('--maskgit_fixed_schedule', type=int, nargs='+', default=None)
|
||||
group.add_argument(
|
||||
'--maskgit_sampling_type',
|
||||
default=None,
|
||||
choices=["default", "causal", "purity_causal", "purity_default"],
|
||||
)
|
||||
|
||||
|
||||
def _add_easy_magpie_args(parser: argparse.ArgumentParser) -> None:
|
||||
"""Add arguments specific to decoder-only EasyMagpieTTSInferenceModel."""
|
||||
group = parser.add_argument_group('EasyMagpieTTS-specific Parameters')
|
||||
group.add_argument(
|
||||
'--phoneme_input_type',
|
||||
type=str,
|
||||
default='gt',
|
||||
choices=['gt', 'predicted'],
|
||||
help='Source of phoneme input for decoder-only model',
|
||||
)
|
||||
group.add_argument(
|
||||
'--phoneme_sampling_method',
|
||||
type=str,
|
||||
default='argmax',
|
||||
choices=['argmax', 'multinomial'],
|
||||
help='Sampling method for phoneme prediction',
|
||||
)
|
||||
group.add_argument('--dropout_text_input', action='store_true', help='Force dropout on text input')
|
||||
group.add_argument(
|
||||
'--phoneme_tokenizer_path',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Override path to the phoneme tokenizer file (overrides the path stored in the checkpoint config)',
|
||||
)
|
||||
group.add_argument(
|
||||
'--disable_cas_for_context_text',
|
||||
action='store_true',
|
||||
help='Skip CAS embeddings for context text when loading legacy EasyMagpieTTS models',
|
||||
)
|
||||
|
||||
|
||||
def create_argument_parser() -> argparse.ArgumentParser:
|
||||
"""Create the CLI argument parser with all argument groups."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description='TTS Inference and Evaluation (MagpieTTS & EasyMagpieTTS)',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=__doc__,
|
||||
)
|
||||
_add_common_args(parser)
|
||||
_add_magpie_args(parser)
|
||||
_add_easy_magpie_args(parser)
|
||||
return parser
|
||||
|
||||
|
||||
def _build_inference_params_from_args(param_cls: type, args):
|
||||
"""Extract inference parameters from parsed CLI args for the given dataclass."""
|
||||
params = {}
|
||||
for f in fields(param_cls):
|
||||
arg_val = vars(args).get(f.name)
|
||||
if arg_val is not None:
|
||||
if f.name in ("estimate_alignment_from_layers", "apply_prior_to_layers"):
|
||||
params[f.name] = parse_layer_list(arg_val)
|
||||
else:
|
||||
params[f.name] = arg_val
|
||||
return param_cls.from_dict(params)
|
||||
|
||||
|
||||
def _build_magpie_config(args) -> MagpieInferenceConfig:
|
||||
return MagpieInferenceConfig(
|
||||
model_inference_parameters=_build_inference_params_from_args(ModelInferenceParameters, args),
|
||||
batch_size=args.batch_size,
|
||||
use_cfg=args.use_cfg,
|
||||
apply_attention_prior=args.apply_attention_prior,
|
||||
use_local_transformer=args.use_local_transformer,
|
||||
maskgit_n_steps=args.maskgit_n_steps,
|
||||
maskgit_noise_scale=args.maskgit_noise_scale,
|
||||
maskgit_fixed_schedule=args.maskgit_fixed_schedule,
|
||||
maskgit_sampling_type=args.maskgit_sampling_type,
|
||||
default_tokenizer_name=args.tokenizer_name,
|
||||
)
|
||||
|
||||
|
||||
def _build_easy_magpie_config(args) -> EasyMagpieInferenceConfig:
|
||||
return EasyMagpieInferenceConfig(
|
||||
model_inference_parameters=_build_inference_params_from_args(EasyModelInferenceParameters, args),
|
||||
batch_size=args.batch_size,
|
||||
use_cfg=args.use_cfg,
|
||||
use_local_transformer=args.use_local_transformer,
|
||||
phoneme_input_type=args.phoneme_input_type,
|
||||
phoneme_sampling_method=args.phoneme_sampling_method,
|
||||
dropout_text_input=args.dropout_text_input,
|
||||
default_tokenizer_name=args.tokenizer_name,
|
||||
)
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
"""Entry point for TTS inference and evaluation."""
|
||||
parser = create_argument_parser()
|
||||
args = parser.parse_args(argv)
|
||||
if args.deterministic:
|
||||
seed_all(seed=9)
|
||||
|
||||
dataset_meta_info = load_evalset_config(
|
||||
config_path=args.datasets_json_path, dataset_base_path=args.datasets_base_path
|
||||
)
|
||||
datasets = filter_datasets(dataset_meta_info, args.datasets)
|
||||
logging.info(f"Loaded {len(datasets)} datasets: {', '.join(datasets)}")
|
||||
|
||||
# Validate model loading args
|
||||
has_checkpoint_mode = (
|
||||
args.hparams_files is not None
|
||||
and args.checkpoint_files is not None
|
||||
and args.hparams_files != "null"
|
||||
and args.checkpoint_files != "null"
|
||||
)
|
||||
has_nemo_mode = args.nemo_files is not None and args.nemo_files != "null"
|
||||
|
||||
if not has_checkpoint_mode and not has_nemo_mode:
|
||||
parser.error("You must provide either:\n 1. --hparams_files and --checkpoint_files\n 2. --nemo_files")
|
||||
|
||||
# Select model loader and config builder based on --model_type
|
||||
is_easy_magpie = args.model_type == 'easy_magpie'
|
||||
load_fn = load_easy_magpie_model if is_easy_magpie else load_magpie_model
|
||||
inference_config = _build_easy_magpie_config(args) if is_easy_magpie else _build_magpie_config(args)
|
||||
runner_cls = EasyMagpieInferenceRunner if is_easy_magpie else MagpieInferenceRunner
|
||||
|
||||
eval_config = EvaluationConfig(
|
||||
sv_model=args.sv_model,
|
||||
asr_model_name=args.asr_model_name,
|
||||
asr_model_type=args.asr_model_type,
|
||||
eou_model_name=args.eou_model_name,
|
||||
language=args.language,
|
||||
with_utmosv2=not args.disable_utmosv2,
|
||||
with_fcd=not args.disable_fcd,
|
||||
codec_model_path=args.codecmodel_path if not args.disable_fcd else None,
|
||||
)
|
||||
|
||||
cer, ssim = None, None
|
||||
|
||||
# Iterate over model files (checkpoint or nemo)
|
||||
if has_checkpoint_mode:
|
||||
hparam_files = args.hparams_files.split(",")
|
||||
checkpoint_files = args.checkpoint_files.split(",")
|
||||
|
||||
if len(hparam_files) != len(checkpoint_files):
|
||||
parser.error("Number of hparams_files must match number of checkpoint_files")
|
||||
|
||||
for hparams_file, checkpoint_file in zip(hparam_files, checkpoint_files):
|
||||
logging.info(f"Processing checkpoint: {checkpoint_file}")
|
||||
|
||||
model_config = ModelLoadConfig(
|
||||
hparams_file=hparams_file,
|
||||
checkpoint_file=checkpoint_file,
|
||||
codecmodel_path=args.codecmodel_path,
|
||||
legacy_codebooks=args.legacy_codebooks,
|
||||
legacy_text_conditioning=args.legacy_text_conditioning,
|
||||
hparams_from_wandb=args.hparams_file_from_wandb,
|
||||
phoneme_tokenizer_path=getattr(args, 'phoneme_tokenizer_path', None),
|
||||
disable_cas_for_context_text=args.disable_cas_for_context_text,
|
||||
)
|
||||
|
||||
# Load model
|
||||
model, checkpoint_name = load_fn(model_config)
|
||||
# Log architecture summary and get MoE info + FLOPs metrics
|
||||
moe_info, flops_per_component = log_model_architecture_summary(model)
|
||||
|
||||
# Add experiment name prefix if requested
|
||||
if args.log_exp_name and model_config.checkpoint_file:
|
||||
exp_name = get_experiment_name_from_checkpoint_path(model_config.checkpoint_file)
|
||||
checkpoint_name = f"{exp_name}__{checkpoint_name}"
|
||||
|
||||
# Create inference runner
|
||||
runner = runner_cls(model, inference_config)
|
||||
|
||||
cer, ssim = run_inference_and_evaluation(
|
||||
runner=runner,
|
||||
checkpoint_name=checkpoint_name,
|
||||
inference_config=inference_config,
|
||||
eval_config=eval_config,
|
||||
dataset_meta_info=dataset_meta_info,
|
||||
datasets=datasets,
|
||||
out_dir=args.out_dir,
|
||||
flops_per_component=flops_per_component,
|
||||
moe_info=moe_info,
|
||||
num_repeats=args.num_repeats,
|
||||
confidence_level=args.confidence_level,
|
||||
violin_plot_metrics=args.violin_plot_metrics,
|
||||
clean_up_disk=args.clean_up_disk,
|
||||
skip_evaluation=not args.run_evaluation,
|
||||
)
|
||||
|
||||
else: # nemo mode
|
||||
for nemo_file in args.nemo_files.split(","):
|
||||
logging.info(f"Processing NeMo file: {nemo_file}")
|
||||
|
||||
model_config = ModelLoadConfig(
|
||||
nemo_file=nemo_file,
|
||||
codecmodel_path=args.codecmodel_path,
|
||||
legacy_codebooks=args.legacy_codebooks,
|
||||
legacy_text_conditioning=args.legacy_text_conditioning,
|
||||
phoneme_tokenizer_path=getattr(args, 'phoneme_tokenizer_path', None),
|
||||
disable_cas_for_context_text=args.disable_cas_for_context_text,
|
||||
)
|
||||
|
||||
# Load model
|
||||
model, checkpoint_name = load_fn(model_config)
|
||||
# Log architecture summary and get MoE info + FLOPs metrics
|
||||
moe_info, flops_per_component = log_model_architecture_summary(model)
|
||||
|
||||
# Create inference runner
|
||||
runner = runner_cls(model, inference_config)
|
||||
|
||||
cer, ssim = run_inference_and_evaluation(
|
||||
runner=runner,
|
||||
checkpoint_name=checkpoint_name,
|
||||
inference_config=inference_config,
|
||||
eval_config=eval_config,
|
||||
dataset_meta_info=dataset_meta_info,
|
||||
datasets=datasets,
|
||||
out_dir=args.out_dir,
|
||||
flops_per_component=flops_per_component,
|
||||
moe_info=moe_info,
|
||||
num_repeats=args.num_repeats,
|
||||
confidence_level=args.confidence_level,
|
||||
violin_plot_metrics=args.violin_plot_metrics,
|
||||
clean_up_disk=args.clean_up_disk,
|
||||
skip_evaluation=not args.run_evaluation,
|
||||
)
|
||||
|
||||
# Check quality targets
|
||||
if cer is not None and args.cer_target is not None:
|
||||
if cer > args.cer_target:
|
||||
raise ValueError(f"CER {cer:.4f} exceeds target {args.cer_target:.4f}")
|
||||
logging.info(f"CER {cer:.4f} meets target {args.cer_target:.4f}")
|
||||
|
||||
if ssim is not None and args.ssim_target is not None:
|
||||
if ssim < args.ssim_target:
|
||||
raise ValueError(f"SSIM {ssim:.4f} below target {args.ssim_target:.4f}")
|
||||
logging.info(f"SSIM {ssim:.4f} meets target {args.ssim_target:.4f}")
|
||||
|
||||
logging.info("Inference and evaluation completed successfully.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,36 @@
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import lightning.pytorch as pl
|
||||
|
||||
from nemo.collections.common.callbacks import LogEpochTimeCallback
|
||||
from nemo.collections.tts.models import ssl_tts
|
||||
from nemo.core.config import hydra_runner
|
||||
from nemo.utils.exp_manager import exp_manager
|
||||
|
||||
|
||||
@hydra_runner(config_path="conf", config_name="ssl_tts_22050")
|
||||
def main(cfg):
|
||||
trainer = pl.Trainer(**cfg.trainer)
|
||||
exp_manager(trainer, cfg.get("exp_manager", None))
|
||||
model = ssl_tts.SSLDisentangler(cfg=cfg.model, trainer=trainer)
|
||||
model.maybe_init_from_pretrained_checkpoint(cfg=cfg)
|
||||
lr_logger = pl.callbacks.LearningRateMonitor()
|
||||
epoch_time_logger = LogEpochTimeCallback()
|
||||
trainer.callbacks.extend([lr_logger, epoch_time_logger])
|
||||
trainer.fit(model)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # noqa pylint: disable=no-value-for-parameter
|
||||
Reference in New Issue
Block a user