| | import os |
| | from typing import Any, Dict, List |
| |
|
| | import fsspec |
| | import numpy as np |
| | import torch |
| | from coqpit import Coqpit |
| |
|
| | from TTS.config import check_config_and_model_args |
| | from TTS.tts.utils.managers import BaseIDManager |
| |
|
| |
|
| | class LanguageManager(BaseIDManager): |
| | """Manage the languages for multi-lingual 🐸TTS models. Load a datafile and parse the information |
| | in a way that can be queried by language. |
| | |
| | Args: |
| | language_ids_file_path (str, optional): Path to the metafile that maps language names to ids used by |
| | TTS models. Defaults to "". |
| | config (Coqpit, optional): Coqpit config that contains the language information in the datasets filed. |
| | Defaults to None. |
| | |
| | Examples: |
| | >>> manager = LanguageManager(language_ids_file_path=language_ids_file_path) |
| | >>> language_id_mapper = manager.language_ids |
| | """ |
| |
|
| | def __init__( |
| | self, |
| | language_ids_file_path: str = "", |
| | config: Coqpit = None, |
| | ): |
| | super().__init__(id_file_path=language_ids_file_path) |
| |
|
| | if config: |
| | self.set_language_ids_from_config(config) |
| |
|
| | @property |
| | def num_languages(self) -> int: |
| | return len(list(self.name_to_id.keys())) |
| |
|
| | @property |
| | def language_names(self) -> List: |
| | return list(self.name_to_id.keys()) |
| |
|
| | @staticmethod |
| | def parse_language_ids_from_config(c: Coqpit) -> Dict: |
| | """Set language id from config. |
| | |
| | Args: |
| | c (Coqpit): Config |
| | |
| | Returns: |
| | Tuple[Dict, int]: Language ID mapping and the number of languages. |
| | """ |
| | languages = set({}) |
| | for dataset in c.datasets: |
| | if "language" in dataset: |
| | languages.add(dataset["language"]) |
| | else: |
| | raise ValueError(f"Dataset {dataset['name']} has no language specified.") |
| | return {name: i for i, name in enumerate(sorted(list(languages)))} |
| |
|
| | def set_language_ids_from_config(self, c: Coqpit) -> None: |
| | """Set language IDs from config samples. |
| | |
| | Args: |
| | c (Coqpit): Config. |
| | """ |
| | self.name_to_id = self.parse_language_ids_from_config(c) |
| |
|
| | @staticmethod |
| | def parse_ids_from_data(items: List, parse_key: str) -> Any: |
| | raise NotImplementedError |
| |
|
| | def set_ids_from_data(self, items: List, parse_key: str) -> Any: |
| | raise NotImplementedError |
| |
|
| | def save_ids_to_file(self, file_path: str) -> None: |
| | """Save language IDs to a json file. |
| | |
| | Args: |
| | file_path (str): Path to the output file. |
| | """ |
| | self._save_json(file_path, self.name_to_id) |
| |
|
| | @staticmethod |
| | def init_from_config(config: Coqpit) -> "LanguageManager": |
| | """Initialize the language manager from a Coqpit config. |
| | |
| | Args: |
| | config (Coqpit): Coqpit config. |
| | """ |
| | language_manager = None |
| | if check_config_and_model_args(config, "use_language_embedding", True): |
| | if config.get("language_ids_file", None): |
| | language_manager = LanguageManager(language_ids_file_path=config.language_ids_file) |
| | language_manager = LanguageManager(config=config) |
| | return language_manager |
| |
|
| |
|
| | def _set_file_path(path): |
| | """Find the language_ids.json under the given path or the above it. |
| | Intended to band aid the different paths returned in restored and continued training.""" |
| | path_restore = os.path.join(os.path.dirname(path), "language_ids.json") |
| | path_continue = os.path.join(path, "language_ids.json") |
| | fs = fsspec.get_mapper(path).fs |
| | if fs.exists(path_restore): |
| | return path_restore |
| | if fs.exists(path_continue): |
| | return path_continue |
| | return None |
| |
|
| |
|
| | def get_language_balancer_weights(items: list): |
| | language_names = np.array([item["language"] for item in items]) |
| | unique_language_names = np.unique(language_names).tolist() |
| | language_ids = [unique_language_names.index(l) for l in language_names] |
| | language_count = np.array([len(np.where(language_names == l)[0]) for l in unique_language_names]) |
| | weight_language = 1.0 / language_count |
| | |
| | dataset_samples_weight = np.array([weight_language[l] for l in language_ids]) |
| | |
| | dataset_samples_weight = dataset_samples_weight / np.linalg.norm(dataset_samples_weight) |
| | return torch.from_numpy(dataset_samples_weight).float() |
| |
|