Repository: CMsmartvoice/One-Shot-Voice-Cloning Branch: master Commit: fe785f7755b0 Files: 74 Total size: 51.0 MB Directory structure: gitextract_aqw3mgq5/ ├── .gitignore ├── README-CN.md ├── README.md ├── TensorFlowTTS/ │ ├── LICENSE │ ├── README.md │ ├── setup.cfg │ ├── setup.py │ └── tensorflow_tts/ │ ├── __init__.py │ ├── audio_process/ │ │ ├── __init__.py │ │ ├── audio.py │ │ └── audio_spec.py │ ├── bin/ │ │ ├── __init__.py │ │ └── preprocess_unetts.py │ ├── configs/ │ │ ├── __init__.py │ │ ├── mb_melgan.py │ │ ├── melgan.py │ │ └── unetts.py │ ├── datasets/ │ │ ├── __init__.py │ │ ├── abstract_dataset.py │ │ ├── audio_dataset.py │ │ └── mel_dataset.py │ ├── inference/ │ │ ├── __init__.py │ │ ├── auto_config.py │ │ ├── auto_model.py │ │ └── auto_processor.py │ ├── losses/ │ │ ├── __init__.py │ │ ├── spectrogram.py │ │ └── stft.py │ ├── models/ │ │ ├── __init__.py │ │ ├── mb_melgan.py │ │ ├── melgan.py │ │ ├── moduls/ │ │ │ ├── __init__.py │ │ │ ├── adain_en_de_code.py │ │ │ ├── conditional.py │ │ │ ├── core.py │ │ │ └── core2.py │ │ └── unetts.py │ ├── optimizers/ │ │ ├── __init__.py │ │ └── adamweightdecay.py │ ├── processor/ │ │ ├── __init__.py │ │ ├── base_processor.py │ │ └── multispk_voiceclone.py │ ├── trainers/ │ │ ├── __init__.py │ │ └── base_trainer.py │ └── utils/ │ ├── __init__.py │ ├── cleaners.py │ ├── decoder.py │ ├── griffin_lim.py │ ├── group_conv.py │ ├── korean.py │ ├── number_norm.py │ ├── outliers.py │ ├── strategy.py │ ├── utils.py │ └── weight_norm.py ├── UnetTTS_syn.py ├── models/ │ ├── acous12k.h5 │ ├── duration4k.h5 │ ├── unetts_mapper.json │ └── vocoder800k.h5 ├── notebook/ │ └── OneShotVoiceClone_Inference.ipynb ├── test_wavs/ │ ├── angry_dur_stat.npy │ ├── happy_dur_stat.npy │ ├── neutral_dur_stat.npy │ ├── sad_dur_stat.npy │ └── surprise_dur_stat.npy └── train/ ├── configs/ │ ├── multiband_melgan.yaml │ ├── unetts_acous.yaml │ ├── unetts_duration.yaml │ └── unetts_preprocess.yaml ├── train_multiband_melgan.py ├── train_unetts_acous.py ├── train_unetts_duration.py └── unetts_dataset.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ **/**/__pycache__ **/.ipynb_checkpoints TensorFlowTTS/build TensorFlowTTS/TensorFlowTTS.egg-info TensorFlowTTS/.eggs egs ================================================ FILE: README-CN.md ================================================ ## Unet-TTS: Improving Unseen Speaker and Style Transfer in One-shot Voice Cloning [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://choosealicense.com/licenses/mit/) > 中文 | [English](README.md) :exclamation: 提供推理代码和预训练模型,你可以生成想要的文本语音。 :star: 模型只在正常情绪的语料上训练,没有使用其他任何强烈情感的语料。 :star: 受到训练语料的限制,一般的说话人编码或者非监督风格学习方法都很难模仿未见过的语音。训练数据分布范围外的风格迁移仍具有很大的挑战。 :star: 依赖Unet网络和AdaIN层,我们的方法在未见风格上有很强的迁移能力。 :sparkles:强烈推荐使用[在线notebook](https://colab.research.google.com/drive/1sEDvKTJCY7uosb7TvTqwyUdwNPiv3pBW#scrollTo=puzhCI99LY_a)进行推理。 [Demo results](https://cmsmartvoice.github.io/Unet-TTS/) [Paper link](https://arxiv.org/abs/2109.11115) ![](./pics/structure.png) --- :star: 现在只需要输入一条参考语音就可以进行克隆TTS,而不再需要手动输入参考语音的时长统计信息。 :smile: 我们正在准备基于aishell3数据的训练流程,敬请期待。 流程包括: - [x] 一句话语音克隆推理 - [x] 参考音频的时长统计信息可以有训练的Style_Encoder估计 - [ ] 基于说话人编码的多说话人TTS,它可以提供不错的Content Encoder - [ ] Unet-TTS训练 - [ ] C++推理 --- ### Install Requirements - 暂时只支持Linux系统 - Install the appropriate TensorFlow and tensorflow-addons versions according to CUDA version. - The default is TensorFlow 2.6 and tensorflow-addons 0.14.0. ```shell cd One-Shot-Voice-Cloning/TensorFlowTTS pip install . (or python setup.py install) ``` ### Usage 方法1: 在UnetTTS_syn.py文件中修改要克隆的参考语音. (更多细节参见此文件) ```shell cd One-Shot-Voice-Cloning CUDA_VISIBLE_DEVICES=0 python UnetTTS_syn.py ``` 方法2: Notebook **Note**: 请将One-Shot-Voice-Cloning目录添加到系统路径中,否则UnetTTS类无法从UnetTTS_syn.py文件中载入. ```python import sys sys.path.append("/One-Shot-Voice-Cloning") from UnetTTS_syn import UnetTTS from tensorflow_tts.audio_process import preprocess_wav """初始化模型""" models_and_params = {"duration_param": "train/configs/unetts_duration.yaml", "duration_model": "models/duration4k.h5", "acous_param": "train/configs/unetts_acous.yaml", "acous_model": "models/acous12k.h5", "vocoder_param": "train/configs/multiband_melgan.yaml", "vocoder_model": "models/vocoder800k.h5"} feats_yaml = "train/configs/unetts_preprocess.yaml" text2id_mapper = "models/unetts_mapper.json" Tts_handel = UnetTTS(models_and_params, text2id_mapper, feats_yaml) """根据目标语音,生成任意文本的克隆语音""" wav_fpath = "./reference_speech.wav" ref_audio = preprocess_wav(wav_fpath, source_sr=16000, normalize=True, trim_silence=True, is_sil_pad=True, vad_window_length=30, vad_moving_average_width=1, vad_max_silence_length=1) # 文本中插入#3标识,可以当作标点符号,合成语音中会产生停顿 text = "一句话#3风格迁移#3语音合成系统" syn_audio, _, _ = Tts_handel.one_shot_TTS(text, ref_audio) ``` ### Reference https://github.com/TensorSpeech/TensorFlowTTS https://github.com/CorentinJ/Real-Time-Voice-Cloning ================================================ FILE: README.md ================================================ ## Unet-TTS: Improving Unseen Speaker and Style Transfer in One-shot Voice Cloning [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://choosealicense.com/licenses/mit/) > English | [中文](README-CN.md) :exclamation: Now we provide inferencing code and pre-training models. You could generate any text sounds you want. :star: The model training only uses the corpus of neutral emotion, and does not use any strongly emotional speech. :star: There are still great challenges in out-of-domain style transfer. Limited by the training corpus, it is difficult for the speaker-embedding or unsupervised style learning (like GST) methods to imitate the unseen data. :star: With the help of Unet network and AdaIN layer, our proposed algorithm has powerful speaker and style transfer capabilities. [Demo results](https://cmsmartvoice.github.io/Unet-TTS/) [Paper link](https://arxiv.org/abs/2109.11115) :sparkles:[Colab notebook](https://colab.research.google.com/drive/1sEDvKTJCY7uosb7TvTqwyUdwNPiv3pBW?usp=sharing) is Highly Recommended for test. ![](./pics/structure.png) --- :star: Now, you only need to use the reference speech for one-shot voice cloning and no longer need to manually enter the duration statistics additionally. :smile: The authors are preparing simple, clear, and well-documented training process of Unet-TTS based on Aishell3. It contains: - [x] One-shot Voice cloning inference - [x] The duration statistics of the reference speech can be estimated Automatically using Style_Encoder. - [ ] Multi-speaker TTS with speaker_embedding-Instance-Normalization, and this model provides pre-training Content Encoder. - [ ] Unet-TTS training - [ ] C++ inference Stay tuned! --- ### Install Requirements - Only support Linux system - Install the appropriate TensorFlow and tensorflow-addons versions according to CUDA version. - The default is TensorFlow 2.6 and tensorflow-addons 0.14.0. ```shell cd One-Shot-Voice-Cloning/TensorFlowTTS pip install . (or python setup.py install) ``` ### Usage Option 1: Modify the reference audio file to be cloned in the UnetTTS_syn.py file. (See this file for more details) ```shell cd One-Shot-Voice-Cloning CUDA_VISIBLE_DEVICES=0 python UnetTTS_syn.py ``` Option 2: Notebook **Note**: Please add the One-Shot-Voice-Cloning path to the system path. Otherwise the required class UnetTTS cannot be imported from the UnetTTS_syn.py file. ```python import sys sys.path.append("/One-Shot-Voice-Cloning") from UnetTTS_syn import UnetTTS from tensorflow_tts.audio_process import preprocess_wav """Inint models""" models_and_params = {"duration_param": "train/configs/unetts_duration.yaml", "duration_model": "models/duration4k.h5", "acous_param": "train/configs/unetts_acous.yaml", "acous_model": "models/acous12k.h5", "vocoder_param": "train/configs/multiband_melgan.yaml", "vocoder_model": "models/vocoder800k.h5"} feats_yaml = "train/configs/unetts_preprocess.yaml" text2id_mapper = "models/unetts_mapper.json" Tts_handel = UnetTTS(models_and_params, text2id_mapper, feats_yaml) """Synthesize arbitrary text cloning voice using a reference speech""" wav_fpath = "./reference_speech.wav" ref_audio = preprocess_wav(wav_fpath, source_sr=16000, normalize=True, trim_silence=True, is_sil_pad=True, vad_window_length=30, vad_moving_average_width=1, vad_max_silence_length=1) # Inserting #3 marks into text is regarded as punctuation, and synthetic speech can produce pause. text = "一句话#3风格迁移#3语音合成系统" syn_audio, _, _ = Tts_handel.one_shot_TTS(text, ref_audio) ``` ### Reference https://github.com/TensorSpeech/TensorFlowTTS https://github.com/CorentinJ/Real-Time-Voice-Cloning ================================================ FILE: TensorFlowTTS/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: TensorFlowTTS/README.md ================================================

:yum: TensorFlowTTS

Build GitHub Colab

Real-Time State-of-the-art Speech Synthesis for Tensorflow 2

:zany_face: TensorFlowTTS provides real-time state-of-the-art speech synthesis architectures such as Tacotron-2, Melgan, Multiband-Melgan, FastSpeech, FastSpeech2 based-on TensorFlow 2. With Tensorflow 2, we can speed-up training/inference progress, optimizer further by using [fake-quantize aware](https://www.tensorflow.org/model_optimization/guide/quantization/training_comprehensive_guide) and [pruning](https://www.tensorflow.org/model_optimization/guide/pruning/pruning_with_keras), make TTS models can be run faster than real-time and be able to deploy on mobile devices or embedded systems. ## What's new - 2020/08/23 **(NEW!)** Add Parallel WaveGAN tensorflow implementation. See [here](https://github.com/TensorSpeech/TensorFlowTTS/tree/master/examples/parallel_wavegan) - 2020/08/23 **(NEW!)** Add MBMelGAN G + ParallelWaveGAN G example. See [here](https://github.com/TensorSpeech/TensorFlowTTS/tree/master/examples/multiband_pwgan) - 2020/08/20 **(NEW!)** Add C++ inference code. Thank [@ZDisket](https://github.com/ZDisket). See [here](https://github.com/TensorSpeech/TensorFlowTTS/tree/master/examples/cppwin) - 2020/08/18 **(NEW!)** Update [new base processor](https://github.com/TensorSpeech/TensorFlowTTS/blob/master/tensorflow_tts/processor/base_processor.py). Add [AutoProcessor](https://github.com/TensorSpeech/TensorFlowTTS/blob/master/tensorflow_tts/inference/auto_processor.py) and [pretrained processor](https://github.com/TensorSpeech/TensorFlowTTS/blob/master/tensorflow_tts/processor/pretrained/) json file. - 2020/08/14 **(NEW!)** Support Chinese TTS. Pls see the [colab](https://colab.research.google.com/drive/1YpSHRBRPBI7cnTkQn1UcVTWEQVbsUm1S?usp=sharing). Thank [@azraelkuan](https://github.com/azraelkuan). - 2020/08/05 **(NEW!)** Support Korean TTS. Pls see the [colab](https://colab.research.google.com/drive/1ybWwOS5tipgPFttNulp77P6DAB5MtiuN?usp=sharing). Thank [@crux153](https://github.com/crux153). - 2020/07/17 Support MultiGPU for all Trainer. - 2020/07/05 Support Convert Tacotron-2, FastSpeech to Tflite. Pls see the [colab](https://colab.research.google.com/drive/1HudLLpT9CQdh2k04c06bHUwLubhGTWxA?usp=sharing). Thank @jaeyoo from the TFlite team for his support. - 2020/06/20 [FastSpeech2](https://arxiv.org/abs/2006.04558) implementation with Tensorflow is supported. - 2020/06/07 [Multi-band MelGAN (MB MelGAN)](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/multiband_melgan/) implementation with Tensorflow is supported. ## Features - High performance on Speech Synthesis. - Be able to fine-tune on other languages. - Fast, Scalable, and Reliable. - Suitable for deployment. - Easy to implement a new model, based-on abstract class. - Mixed precision to speed-up training if possible. - Support both Single/Multi GPU in base trainer class. - TFlite conversion for all supported models. - Android example. - Support many languages (currently, we support Chinese, Korean, English.) - Support C++ inference. - Support Convert weight for some models from PyTorch to TensorFlow to accelerate speed. ## Requirements This repository is tested on Ubuntu 18.04 with: - Python 3.7+ - Cuda 10.1 - CuDNN 7.6.5 - Tensorflow 2.2/2.3 - [Tensorflow Addons](https://github.com/tensorflow/addons) >= 0.10.0 Different Tensorflow version should be working but not tested yet. This repo will try to work with the latest stable TensorFlow version. **We recommend you install TensorFlow 2.3.0 to training in case you want to use MultiGPU.** ## Installation ### With pip ```bash $ pip install TensorFlowTTS ``` ### From source Examples are included in the repository but are not shipped with the framework. Therefore, to run the latest version of examples, you need to install the source below. ```bash $ git clone https://github.com/TensorSpeech/TensorFlowTTS.git $ cd TensorFlowTTS $ pip install . ``` If you want to upgrade the repository and its dependencies: ```bash $ git pull $ pip install --upgrade . ``` # Supported Model architectures TensorFlowTTS currently provides the following architectures: 1. **MelGAN** released with the paper [MelGAN: Generative Adversarial Networks for Conditional Waveform Synthesis](https://arxiv.org/abs/1910.06711) by Kundan Kumar, Rithesh Kumar, Thibault de Boissiere, Lucas Gestin, Wei Zhen Teoh, Jose Sotelo, Alexandre de Brebisson, Yoshua Bengio, Aaron Courville. 2. **Tacotron-2** released with the paper [Natural TTS Synthesis by Conditioning WaveNet on Mel Spectrogram Predictions](https://arxiv.org/abs/1712.05884) by Jonathan Shen, Ruoming Pang, Ron J. Weiss, Mike Schuster, Navdeep Jaitly, Zongheng Yang, Zhifeng Chen, Yu Zhang, Yuxuan Wang, RJ Skerry-Ryan, Rif A. Saurous, Yannis Agiomyrgiannakis, Yonghui Wu. 3. **FastSpeech** released with the paper [FastSpeech: Fast, Robust, and Controllable Text to Speech](https://arxiv.org/abs/1905.09263) by Yi Ren, Yangjun Ruan, Xu Tan, Tao Qin, Sheng Zhao, Zhou Zhao, Tie-Yan Liu. 4. **Multi-band MelGAN** released with the paper [Multi-band MelGAN: Faster Waveform Generation for High-Quality Text-to-Speech](https://arxiv.org/abs/2005.05106) by Geng Yang, Shan Yang, Kai Liu, Peng Fang, Wei Chen, Lei Xie. 5. **FastSpeech2** released with the paper [FastSpeech 2: Fast and High-Quality End-to-End Text to Speech](https://arxiv.org/abs/2006.04558) by Yi Ren, Chenxu Hu, Xu Tan, Tao Qin, Sheng Zhao, Zhou Zhao, Tie-Yan Liu. 6. **Parallel WaveGAN** released with the paper [Parallel WaveGAN: A fast waveform generation model based on generative adversarial networks with multi-resolution spectrogram](https://arxiv.org/abs/1910.11480) by Ryuichi Yamamoto, Eunwoo Song, Jae-Min Kim. We are also implementing some techniques to improve quality and convergence speed from the following papers: 2. **Guided Attention Loss** released with the paper [Efficiently Trainable Text-to-Speech System Based on Deep Convolutional Networks with Guided Attention ](https://arxiv.org/abs/1710.08969) by Hideyuki Tachibana, Katsuya Uenoyama, Shunsuke Aihara. # Audio Samples Here in an audio samples on valid set. [tacotron-2](https://drive.google.com/open?id=1kaPXRdLg9gZrll9KtvH3-feOBMM8sn3_), [fastspeech](https://drive.google.com/open?id=1f69ujszFeGnIy7PMwc8AkUckhIaT2OD0), [melgan](https://drive.google.com/open?id=1mBwGVchwtNkgFsURl7g4nMiqx4gquAC2), [melgan.stft](https://drive.google.com/open?id=1xUkDjbciupEkM3N4obiJAYySTo6J9z6b), [fastspeech2](https://drive.google.com/drive/u/1/folders/1NG7oOfNuXSh7WyAoM1hI8P5BxDALY_mU), [multiband_melgan](https://drive.google.com/drive/folders/1DCV3sa6VTyoJzZmKATYvYVDUAFXlQ_Zp) # Tutorial End-to-End ## Prepare Dataset Prepare a dataset in the following format: ``` |- [NAME_DATASET]/ | |- metadata.csv | |- wav/ | |- file1.wav | |- ... ``` Where `metadata.csv` has the following format: `id|transcription`. This is a ljspeech-like format; you can ignore preprocessing steps if you have other format datasets. Note that `NAME_DATASET` should be `[ljspeech/kss/baker/libritts]` for example. ## Preprocessing The preprocessing has two steps: 1. Preprocess audio features - Convert characters to IDs - Compute mel spectrograms - Normalize mel spectrograms to [-1, 1] range - Split the dataset into train and validation - Compute the mean and standard deviation of multiple features from the **training** split 2. Standardize mel spectrogram based on computed statistics To reproduce the steps above: ``` tensorflow-tts-preprocess --rootdir ./[ljspeech/kss/baker/libritts] --outdir ./dump_[ljspeech/kss/baker/libritts] --config preprocess/[ljspeech/kss/baker]_preprocess.yaml --dataset [ljspeech/kss/baker/libritts] tensorflow-tts-normalize --rootdir ./dump_[ljspeech/kss/baker/libritts] --outdir ./dump_[ljspeech/kss/baker/libritts] --config preprocess/[ljspeech/kss/baker/libritts]_preprocess.yaml --dataset [ljspeech/kss/baker/libritts] ``` Right now we only support [`ljspeech`](https://keithito.com/LJ-Speech-Dataset/), [`kss`](https://www.kaggle.com/bryanpark/korean-single-speaker-speech-dataset), [`baker`](https://weixinxcxdb.oss-cn-beijing.aliyuncs.com/gwYinPinKu/BZNSYP.rar) and [`libritts`](http://www.openslr.org/60/) for dataset argument. In the future, we intend to support more datasets. **Note**: To run `libritts` preprocessing, please first read the instruction in [examples/fastspeech2_libritts](https://github.com/TensorSpeech/TensorFlowTTS/tree/master/examples/fastspeech2_libritts). We need to reformat it first before run preprocessing. After preprocessing, the structure of the project folder should be: ``` |- [NAME_DATASET]/ | |- metadata.csv | |- wav/ | |- file1.wav | |- ... |- dump_[ljspeech/kss/baker/libritts]/ | |- train/ | |- ids/ | |- LJ001-0001-ids.npy | |- ... | |- raw-feats/ | |- LJ001-0001-raw-feats.npy | |- ... | |- raw-f0/ | |- LJ001-0001-raw-f0.npy | |- ... | |- raw-energies/ | |- LJ001-0001-raw-energy.npy | |- ... | |- norm-feats/ | |- LJ001-0001-norm-feats.npy | |- ... | |- wavs/ | |- LJ001-0001-wave.npy | |- ... | |- valid/ | |- ids/ | |- LJ001-0009-ids.npy | |- ... | |- raw-feats/ | |- LJ001-0009-raw-feats.npy | |- ... | |- raw-f0/ | |- LJ001-0001-raw-f0.npy | |- ... | |- raw-energies/ | |- LJ001-0001-raw-energy.npy | |- ... | |- norm-feats/ | |- LJ001-0009-norm-feats.npy | |- ... | |- wavs/ | |- LJ001-0009-wave.npy | |- ... | |- stats.npy | |- stats_f0.npy | |- stats_energy.npy | |- train_utt_ids.npy | |- valid_utt_ids.npy |- examples/ | |- melgan/ | |- fastspeech/ | |- tacotron2/ | ... ``` - `stats.npy` contains the mean and std from the training split mel spectrograms - `stats_energy.npy` contains the mean and std of energy values from the training split - `stats_f0.npy` contains the mean and std of F0 values in the training split - `train_utt_ids.npy` / `valid_utt_ids.npy` contains training and validation utterances IDs respectively We use suffix (`ids`, `raw-feats`, `raw-energy`, `raw-f0`, `norm-feats`, and `wave`) for each input type. **IMPORTANT NOTES**: - This preprocessing step is based on [ESPnet](https://github.com/espnet/espnet) so you can combine all models here with other models from ESPnet repository. - Regardless of how your dataset is formatted, the final structure of the `dump` folder **SHOULD** follow the above structure to be able to use the training script, or you can modify it by yourself 😄. ## Training models To know how to train model from scratch or fine-tune with other datasets/languages, please see detail at example directory. - For Tacotron-2 tutorial, pls see [examples/tacotron2](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/tacotron2) - For FastSpeech tutorial, pls see [examples/fastspeech](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/fastspeech) - For FastSpeech2 tutorial, pls see [examples/fastspeech2](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/fastspeech2) - For FastSpeech2 + MFA tutorial, pls see [examples/fastspeech2_libritts](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/fastspeech2_libritts) - For MelGAN tutorial, pls see [examples/melgan](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/melgan) - For MelGAN + STFT Loss tutorial, pls see [examples/melgan.stft](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/melgan.stft) - For Multiband-MelGAN tutorial, pls see [examples/multiband_melgan](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/multiband_melgan) - For Parallel WaveGAN tutorial, pls see [examples/parallel_wavegan](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/parallel_wavegan) - For Multiband-MelGAN Generator + Parallel WaveGAN Discriminator tutorial, pls see [examples/multiband_pwgan](https://github.com/tensorspeech/TensorFlowTTS/tree/master/examples/multiband_pwgan) # Abstract Class Explaination ## Abstract DataLoader Tensorflow-based dataset A detail implementation of abstract dataset class from [tensorflow_tts/dataset/abstract_dataset](https://github.com/tensorspeech/TensorFlowTTS/blob/master/tensorflow_tts/datasets/abstract_dataset.py). There are some functions you need overide and understand: 1. **get_args**: This function return argumentation for **generator** class, normally is utt_ids. 2. **generator**: This function have an inputs from **get_args** function and return a inputs for models. **Note that we return a dictionary for all generator functions with the keys that exactly match with the model's parameters because base_trainer will use model(\*\*batch) to do forward step.** 3. **get_output_dtypes**: This function need return dtypes for each element from **generator** function. 4. **get_len_dataset**: Return len of datasets, normaly is len(utt_ids). **IMPORTANT NOTES**: - A pipeline of creating dataset should be: cache -> shuffle -> map_fn -> get_batch -> prefetch. - If you do shuffle before cache, the dataset won't shuffle when it re-iterate over datasets. - You should apply map_fn to make each element return from **generator** function have the same length before getting batch and feed it into a model. Some examples to use this **abstract_dataset** are [tacotron_dataset.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/tacotron2/tacotron_dataset.py), [fastspeech_dataset.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/fastspeech/fastspeech_dataset.py), [melgan_dataset.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/melgan/audio_mel_dataset.py), [fastspeech2_dataset.py](https://github.com/TensorSpeech/TensorFlowTTS/blob/master/examples/fastspeech2/fastspeech2_dataset.py) ## Abstract Trainer Class A detail implementation of base_trainer from [tensorflow_tts/trainer/base_trainer.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/tensorflow_tts/trainers/base_trainer.py). It include [Seq2SeqBasedTrainer](https://github.com/tensorspeech/TensorFlowTTS/blob/master/tensorflow_tts/trainers/base_trainer.py#L265) and [GanBasedTrainer](https://github.com/tensorspeech/TensorFlowTTS/blob/master/tensorflow_tts/trainers/base_trainer.py#L149) inherit from [BasedTrainer](https://github.com/tensorspeech/TensorFlowTTS/blob/master/tensorflow_tts/trainers/base_trainer.py#L16). All trainer support both single/multi GPU. There a some functions you **MUST** overide when implement new_trainer: - **compile**: This function aim to define a models, and losses. - **generate_and_save_intermediate_result**: This function will save intermediate result such as: plot alignment, save audio generated, plot mel-spectrogram ... - **compute_per_example_losses**: This function will compute per_example_loss for model, note that all element of the loss **MUST** has shape [batch_size]. All models on this repo are trained based-on **GanBasedTrainer** (see [train_melgan.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/melgan/train_melgan.py), [train_melgan_stft.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/melgan.stft/train_melgan_stft.py), [train_multiband_melgan.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/multiband_melgan/train_multiband_melgan.py)) and **Seq2SeqBasedTrainer** (see [train_tacotron2.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/tacotron2/train_tacotron2.py), [train_fastspeech.py](https://github.com/tensorspeech/TensorFlowTTS/blob/master/examples/fastspeech/train_fastspeech.py)). # End-to-End Examples You can know how to inference each model at [notebooks](https://github.com/tensorspeech/TensorFlowTTS/tree/master/notebooks) or see a [colab](https://colab.research.google.com/drive/1akxtrLZHKuMiQup00tzO2olCaN-y3KiD?usp=sharing) (for English), [colab](https://colab.research.google.com/drive/1ybWwOS5tipgPFttNulp77P6DAB5MtiuN?usp=sharing) (for Korean). Here is an example code for end2end inference with fastspeech and melgan. ```python import numpy as np import soundfile as sf import yaml import tensorflow as tf from tensorflow_tts.inference import AutoConfig from tensorflow_tts.inference import TFAutoModel from tensorflow_tts.inference import AutoProcessor # initialize fastspeech model. fs_config = AutoConfig.from_pretrained('/examples/fastspeech/conf/fastspeech.v1.yaml') fastspeech = TFAutoModel.from_pretrained( config=fs_config, pretrained_path="./examples/fastspeech/pretrained/model-195000.h5" ) # initialize melgan model melgan_config = AutoConfig.from_pretrained('./examples/melgan/conf/melgan.v1.yaml') melgan = TFAutoModel.from_pretrained( config=melgan_config, pretrained_path="./examples/melgan/checkpoint/generator-1500000.h5" ) # inference processor = AutoProcessor.from_pretrained(pretrained_path="./test/files/ljspeech_mapper.json") ids = processor.text_to_sequence("Recent research at Harvard has shown meditating for as little as 8 weeks, can actually increase the grey matter in the parts of the brain responsible for emotional regulation, and learning.") ids = tf.expand_dims(ids, 0) # fastspeech inference masked_mel_before, masked_mel_after, duration_outputs = fastspeech.inference( ids, speaker_ids=tf.zeros(shape=[tf.shape(ids)[0]], dtype=tf.int32), speed_ratios=tf.constant([1.0], dtype=tf.float32) ) # melgan inference audio_before = melgan.inference(masked_mel_before)[0, :, 0] audio_after = melgan.inference(masked_mel_after)[0, :, 0] # save to file sf.write('./audio_before.wav', audio_before, 22050, "PCM_16") sf.write('./audio_after.wav', audio_after, 22050, "PCM_16") ``` # Contact [Minh Nguyen Quan Anh](https://github.com/tensorspeech): nguyenquananhminh@gmail.com, [erogol](https://github.com/erogol): erengolge@gmail.com, [Kuan Chen](https://github.com/azraelkuan): azraelkuan@gmail.com, [Dawid Kobus](https://github.com/machineko): machineko@protonmail.com, [Takuya Ebata](https://github.com/MokkeMeguru): meguru.mokke@gmail.com, [Trinh Le Quang](https://github.com/l4zyf9x): trinhle.cse@gmail.com, [Yunchao He](https://github.com/candlewill): yunchaohe@gmail.com, [Alejandro Miguel Velasquez](https://github.com/ZDisket): xml506ok@gmail.com # License Overall, Almost models here are licensed under the [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0) for all countries in the world, except in **Viet Nam** this framework cannot be used for production in any way without permission from TensorFlowTTS's Authors. There is an exception, Tacotron-2 can be used with any purpose. If you are Vietnamese and want to use this framework for production, you **Must** contact us in advance. # Acknowledgement We want to thank [Tomoki Hayashi](https://github.com/kan-bayashi), who discussed with us much about Melgan, Multi-band melgan, Fastspeech, and Tacotron. This framework based-on his great open-source [ParallelWaveGan](https://github.com/kan-bayashi/ParallelWaveGAN) project. ================================================ FILE: TensorFlowTTS/setup.cfg ================================================ [aliases] test=pytest [tool:pytest] addopts = --verbose --durations=0 testpaths = test [flake8] ignore = H102,W504,H238,D104,H306,H405,D205 # 120 is a workaround, 79 is good max-line-length = 120 ================================================ FILE: TensorFlowTTS/setup.py ================================================ """Setup Tensorflow TTS libarary.""" import os import sys from distutils.version import LooseVersion import pip from setuptools import find_packages, setup if LooseVersion(sys.version) < LooseVersion("3.6"): raise RuntimeError( "Tensorflow TTS requires python >= 3.6, " "but your Python version is {}".format(sys.version) ) if LooseVersion(pip.__version__) < LooseVersion("19"): raise RuntimeError( "pip>=19.0.0 is required, but your pip version is {}. " 'Try again after "pip install -U pip"'.format(pip.__version__) ) # TODO(@dathudeptrai) update requirement if needed. requirements = { "install": [ "tensorflow-gpu==2.6.0", "tensorflow-addons==0.14.0", "keras==2.6.0", "setuptools>=38.5.1", "librosa>=0.7.0", "soundfile>=0.10.2", "matplotlib>=3.1.0", "PyYAML>=3.12", "tqdm>=4.26.1", "h5py>=2.10.0", "unidecode>=1.1.1", "inflect>=4.1.0", "scikit-learn>=0.22.0", "pyworld>=0.2.10", "numba<=0.48", # Fix No module named "numba.decorators" "jamo>=0.4.1", "pypinyin", "g2pM", "textgrid", "click", "g2p_en", "dataclasses", "pysptk", "webrtcvad", ], "setup": ["numpy", "pytest-runner",], "test": [ "pytest>=3.3.0", "hacking>=1.1.0", ], } # TODO(@dathudeptrai) update console_scripts. entry_points = { "console_scripts": [ "tensorflow-tts-preprocess-unetts-duration=tensorflow_tts.bin.preprocess_unetts:preprocess_duration", "tensorflow-tts-preprocess-unetts-acous=tensorflow_tts.bin.preprocess_unetts:preprocess_acous", "tensorflow-tts-preprocess-unetts-vocoder=tensorflow_tts.bin.preprocess_unetts:preprocess_vocoder", ] } install_requires = requirements["install"] setup_requires = requirements["setup"] tests_require = requirements["test"] extras_require = { k: v for k, v in requirements.items() if k not in ["install", "setup"] } dirname = os.path.dirname(__file__) setup( name="TensorFlowTTS", version="0.0.0", url="https://github.com/tensorspeech/TensorFlowTTS", author="Minh Nguyen Quan Anh, Eren Gölge, Kuan Chen, Dawid Kobus, Takuya Ebata, Trinh Le Quang, Yunchao He, Alejandro Miguel Velasquez", author_email="nguyenquananhminh@gmail.com", description="TensorFlowTTS: Real-Time State-of-the-art Speech Synthesis for Tensorflow 2", long_description=open(os.path.join(dirname, "README.md"), encoding="utf-8").read(), long_description_content_type="text/markdown", license="Apache-2.0", packages=find_packages(include=["tensorflow_tts*"]), install_requires=install_requires, setup_requires=setup_requires, tests_require=tests_require, extras_require=extras_require, entry_points=entry_points, classifiers=[ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Intended Audience :: Science/Research", "Operating System :: POSIX :: Linux", "License :: OSI Approved :: Apache Software License", "Topic :: Software Development :: Libraries :: Python Modules", ], ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/__init__.py ================================================ __version__ = "0.0" ================================================ FILE: TensorFlowTTS/tensorflow_tts/audio_process/__init__.py ================================================ from tensorflow_tts.audio_process.audio import preprocess_wav, melbasis_make, mel_make from tensorflow_tts.audio_process import audio_spec ================================================ FILE: TensorFlowTTS/tensorflow_tts/audio_process/audio.py ================================================ import struct from pathlib import Path from typing import Optional, Union import librosa import numpy as np from scipy.ndimage.morphology import binary_dilation try: import webrtcvad except: print("Unable to import 'webrtcvad'. This package enables noise removal and is recommended.") webrtcvad=None # ## Voice Activation Detection # # Window size of the VAD. Must be either 10, 20 or 30 milliseconds. # # This sets the granularity of the VAD. Should not need to be changed. # vad_window_length = 30 # In milliseconds # # Number of frames to average together when performing the moving average smoothing. # # The larger this value, the larger the VAD variations must be to not get smoothed out. # vad_moving_average_width = 8 # # Maximum number of consecutive silent frames a segment can have. # vad_max_silence_length = 6 int16_max = (2 ** 15) - 1 sampling_rate = 16000 def preprocess_wav(fpath_or_wav: Union[str, Path, np.ndarray], source_sr: Optional[int] = None, normalize: Optional[bool] = True, trim_silence: Optional[bool] = True, is_sil_pad: Optional[bool] = True, vad_window_length = 30, vad_moving_average_width = 8, vad_max_silence_length = 6): """ Applies the preprocessing operations used in training the Speaker Encoder to a waveform either on disk or in memory. The waveform will be resampled to match the data hyperparameters. :param fpath_or_wav: either a filepath to an audio file (many extensions are supported, not just .wav), either the waveform as a numpy array of floats. :param source_sr: if passing an audio waveform, the sampling rate of the waveform before preprocessing. After preprocessing, the waveform's sampling rate will match the data hyperparameters. If passing a filepath, the sampling rate will be automatically detected and this argument will be ignored. """ # Load the wav from disk if needed if isinstance(fpath_or_wav, str) or isinstance(fpath_or_wav, Path): wav, source_sr = librosa.load(str(fpath_or_wav), sr=None) else: wav = fpath_or_wav # Resample the wav if needed if source_sr is not None and source_sr != sampling_rate: wav = librosa.resample(wav, source_sr, sampling_rate) # Apply the preprocessing: normalize volume and shorten long silences if normalize: wav = normalize_volume(wav) if trim_silence: wav = trim_long_silences(wav, vad_window_length, vad_moving_average_width, vad_max_silence_length) if is_sil_pad: wav = sil_pad(wav) return wav def normalize_volume(wav, ratio=0.6): return wav / np.max(np.abs(wav)) * ratio def sil_pad(wav, pad_length=100): pad_length = int(sampling_rate / 1000 * pad_length) return np.pad(wav, (pad_length, pad_length)) def trim_long_silences(wav, vad_window_length, vad_moving_average_width, vad_max_silence_length): """ Ensures that segments without voice in the waveform remain no longer than a threshold determined by the VAD parameters in params.py. :param wav: the raw waveform as a numpy array of floats :return: the same waveform with silences trimmed away (length <= original wav length) """ # Compute the voice detection window size samples_per_window = (vad_window_length * sampling_rate) // 1000 # Trim the end of the audio to have a multiple of the window size wav = wav[:len(wav) - (len(wav) % samples_per_window)] # Convert the float waveform to 16-bit mono PCM pcm_wave = struct.pack("%dh" % len(wav), *(np.round(wav * int16_max)).astype(np.int16)) # Perform voice activation detection voice_flags = [] vad = webrtcvad.Vad(mode=3) for window_start in range(0, len(wav), samples_per_window): window_end = window_start + samples_per_window voice_flags.append(vad.is_speech(pcm_wave[window_start * 2:window_end * 2], sample_rate=sampling_rate)) voice_flags = np.array(voice_flags) # Smooth the voice detection with a moving average def moving_average(array, width): array_padded = np.concatenate((np.zeros((width - 1) // 2), array, np.zeros(width // 2))) ret = np.cumsum(array_padded, dtype=float) ret[width:] = ret[width:] - ret[:-width] return ret[width - 1:] / width audio_mask = moving_average(voice_flags, vad_moving_average_width) audio_mask = np.round(audio_mask).astype(np.bool) # Dilate the voiced regions audio_mask = binary_dilation(audio_mask, np.ones(vad_max_silence_length + 1)) audio_mask = np.repeat(audio_mask, samples_per_window) return wav[audio_mask == True] def melbasis_make(sr=16000, n_fft=1024, n_mels=80, fmin=80, fmax=7600): return librosa.filters.mel(sr=sr, n_fft=n_fft, n_mels=n_mels, fmin=fmin, fmax=fmax) def mel_make(filepath: str, sr=16000, n_fft=1024, framesize=256, mel_basis=None, fn=None): if fn is None: audio, _ = librosa.load(filepath, sr=sr) else: audio = fn(filepath, trim_silence=False, is_sil_pad=False) D = librosa.stft(audio, n_fft=n_fft, hop_length=framesize) S, _ = librosa.magphase(D) if mel_basis: mel = np.log10(np.maximum(np.dot(mel_basis, S), 1e-10)).T return audio, mel else: return audio, S ================================================ FILE: TensorFlowTTS/tensorflow_tts/audio_process/audio_spec.py ================================================ import librosa import matplotlib.pyplot as plt import numpy as np from scipy import signal import soundfile as sf def preemphasis(wav, k, preemphasize=True): if preemphasize: return signal.lfilter([1, -k], [1], wav) return wav def inv_preemphasis(wav, k, inv_preemphasize=True): if inv_preemphasize: return signal.lfilter([1], [1, -k], wav) return wav class AudioMelSpec(): ''' Audio to Mel_Spec ''' def __init__( self, sample_rate=16000, n_fft=800, num_mels=80, hop_size=200, win_size=800, fmin=55, fmax=7600, min_level_db=-100, ref_level_db=20, max_abs_value=4., preemphasis=0.97, preemphasize=True, signal_normalization=True, allow_clipping_in_normalization=True, symmetric_mels=True, power=1.5, griffin_lim_iters=60, rescale=True, rescaling_max=0.9 ): self.sample_rate = sample_rate self.n_fft = n_fft self.num_mels = num_mels self.hop_size = hop_size self.win_size = win_size self.fmin = fmin self.fmax = fmax self.min_level_db = min_level_db self.ref_level_db = ref_level_db self.max_abs_value = max_abs_value self.preemphasis = preemphasis self.preemphasize = preemphasize self.signal_normalization = signal_normalization self.symmetric_mels = symmetric_mels self.allow_clipping_in_normalization = allow_clipping_in_normalization self.power = power self.griffin_lim_iters = griffin_lim_iters self.rescale = rescale self.rescaling_max = rescaling_max self._mel_basis_create() def _mel_basis_create(self): self._mel_basis = librosa.filters.mel(self.sample_rate, self.n_fft, self.num_mels, self.fmin, self.fmax) self._inv_mel_basis = np.linalg.pinv(self._mel_basis) def _stft(self, y): return librosa.stft(y=y, n_fft=self.n_fft, hop_length=self.hop_size, win_length=self.win_size) def _istft(self, y): return librosa.istft(y, hop_length=self.hop_size, win_length=self.win_size) def _linear_to_mel(self, spectogram): return np.dot(self._mel_basis, spectogram) def _mel_to_linear(self, mel_spectrogram): return np.maximum(1e-10, np.dot(self._inv_mel_basis, mel_spectrogram)) def _amp_to_db(self, x): min_level = np.exp(self.min_level_db / 20 * np.log(10)) return 20 * np.log10(np.maximum(min_level, x)) def _db_to_amp(self, x): return np.power(10.0, (x) * 0.05) def _normalize(self, S): if self.allow_clipping_in_normalization: if self.symmetric_mels: return np.clip((2 * self.max_abs_value) * ((S - self.min_level_db) / (-self.min_level_db)) - self.max_abs_value, -self.max_abs_value, self.max_abs_value) else: return np.clip(self.max_abs_value * ((S - self.min_level_db) / (-self.min_level_db)), 0, self.max_abs_value) assert S.max() <= 0 and S.min() - self.min_level_db >= 0 if self.symmetric_mels: return (2 * self.max_abs_value) * ((S - self.min_level_db) / (-self.min_level_db)) - self.max_abs_value else: return self.max_abs_value * ((S - self.min_level_db) / (-self.min_level_db)) def _denormalize(self, D): if self.allow_clipping_in_normalization: if self.symmetric_mels: return (((np.clip(D, -self.max_abs_value, self.max_abs_value) + self.max_abs_value) * -self.min_level_db / (2 * self.max_abs_value)) + self.min_level_db) else: return ((np.clip(D, 0, self.max_abs_value) * -self.min_level_db / self.max_abs_value) + self.min_level_db) if self.symmetric_mels: return (((D + self.max_abs_value) * -self.min_level_db / (2 * self.max_abs_value)) + self.min_level_db) else: return ((D * -self.min_level_db / self.max_abs_value) + self.min_level_db) def _griffin_lim(self, S): """librosa implementation of Griffin-Lim Based on https://github.com/librosa/librosa/issues/434 """ angles = np.exp(2j * np.pi * np.random.rand(*S.shape)) S_complex = np.abs(S).astype(np.complex) y = self._istft(S_complex * angles) for i in range(self.griffin_lim_iters): angles = np.exp(1j * np.angle(self._stft(y))) y = self._istft(S_complex * angles) return y def load_wav(self, wav_fpath): wav, _ = librosa.load(wav_fpath, sr=self.sample_rate) if self.rescale: wav = wav / np.abs(wav).max() * self.rescaling_max return wav def save_wav(self, wav, fpath): if self.rescale: wav = wav / np.abs(wav).max() * self.rescaling_max sf.write(fpath, wav, self.sample_rate, subtype="PCM_16") def melspectrogram(self, wav): D = self._stft(preemphasis(wav, self.preemphasis, self.preemphasize)) S = self._amp_to_db(self._linear_to_mel(np.abs(D))) - self.ref_level_db if self.signal_normalization: return self._normalize(S.T) return S.T def inv_mel_spectrogram(self, mel_spectrogram): """Converts mel spectrogram to waveform using librosa""" if self.signal_normalization: D = self._denormalize(mel_spectrogram.T) else: D = mel_spectrogram.T S = self._mel_to_linear(self._db_to_amp(D + self.ref_level_db)) # Convert back to linear return inv_preemphasis(self._griffin_lim(S ** self.power), self.preemphasis, self.preemphasize) def compare_plot(self, targets, preds, filepath=None, frame_real_len=None, text=None): if frame_real_len: targets = targets[:frame_real_len] preds = preds[:frame_real_len] fig = plt.figure(figsize=(14,10)) if text: fig.text(0.4, 0.48, text, horizontalalignment="center", fontsize=16) ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212) im = ax1.imshow(targets.T, aspect='auto', origin="lower", interpolation="none") ax1.set_title("Target Mel-Spectrogram") fig.colorbar(mappable=im, shrink=0.65, ax=ax1) im = ax2.imshow(preds.T, aspect='auto', origin="lower", interpolation="none") ax2.set_title("Pred Mel-Spectrogram") fig.colorbar(mappable=im, shrink=0.65, ax=ax2) plt.tight_layout() if filepath is None: plt.show() else: plt.savefig(filepath) plt.close() def melspec_plot(self, mels): plt.figure(figsize=(10,6)) plt.imshow(mels.T, aspect='auto', origin="lower", interpolation="none") plt.colorbar() plt.show() class AudioSpec(): ''' # TODO Now just for sqrt(sp) from world ''' def __init__(self, sr, nfft, mel_dim=80, f0_min=71, f0_max=7800, min_level_db=-120., ref_level_db=-5., max_abs_value=4., is_norm=True, is_symmetric=True, is_clipping_in_normalization=False): self.sr = sr self.nfft = nfft self.mel_dim = mel_dim self.f0_min = f0_min self.f0_max = f0_max self.min_level_db = min_level_db self.min_level_amp = np.exp((self.min_level_db + 0.1) / 20 * np.log(10)) # sp from world, self.ref_level_db should be less than zero # otherwise, is_clipping_in_normalization should be true self.ref_level_db = ref_level_db self.max_abs_value = max_abs_value self.is_norm = is_norm self.is_symmetric = is_symmetric self.is_clipping_in_normalization = is_clipping_in_normalization if self.ref_level_db > 0.: try: assert self.is_norm and self.is_clipping_in_normalization except: self.is_clipping_in_normalization = True self._mel_basis_create() def _mel_basis_create(self): self._mel_basis = librosa.filters.mel(self.sr, self.nfft, self.mel_dim, self.f0_min, self.f0_max) self._inv_mel_basis = np.linalg.pinv(self._mel_basis) def _normalize(self, log_sepc, is_symmetric, is_clipping_in_normalization): if is_clipping_in_normalization: if is_symmetric: return np.clip((2 * self.max_abs_value) * ((log_sepc - self.min_level_db) / (-self.min_level_db)) - self.max_abs_value, -self.max_abs_value, self.max_abs_value) else: return np.clip(self.max_abs_value * ((log_sepc - self.min_level_db) / (-self.min_level_db)), 0, self.max_abs_value) assert log_sepc.max() <= 0 and log_sepc.min() >= self.min_level_db if is_symmetric: return (2 * self.max_abs_value) * ((log_sepc - self.min_level_db) / (-self.min_level_db)) - self.max_abs_value else: return self.max_abs_value * ((log_sepc - self.min_level_db) / (-self.min_level_db)) def _denormalize(self, log_sepc, is_symmetric, is_clipping_in_normalization): if is_clipping_in_normalization: if is_symmetric: return (((np.clip(log_sepc, -self.max_abs_value, self.max_abs_value) + self.max_abs_value) * -self.min_level_db / (2 * self.max_abs_value)) + self.min_level_db) else: return ((np.clip(log_sepc, 0, self.max_abs_value) * -self.min_level_db / self.max_abs_value) + self.min_level_db) if is_symmetric: return (((log_sepc + self.max_abs_value) * -self.min_level_db / (2 * self.max_abs_value)) + self.min_level_db) else: return ((log_sepc * -self.min_level_db / self.max_abs_value) + self.min_level_db) def ampspec2logspec(self, amp_spec): mel_spec = np.dot(amp_spec, self._mel_basis.T) log_sepc = 20 * np.log10(np.maximum(self.min_level_amp, mel_spec)) - self.ref_level_db if self.is_norm: log_sepc = self._normalize(log_sepc, self.is_symmetric, self.is_clipping_in_normalization) return log_sepc def logspec2ampspec(self, log_spec): if self.is_norm: log_spec = self._denormalize(log_spec, self.is_symmetric, self.is_clipping_in_normalization) log_spec += self.ref_level_db amp_spec = np.maximum(self.min_level_amp**2, np.dot(np.power(10.0, log_spec * 0.05), self._inv_mel_basis.T)) return amp_spec class VariableNormProcess(): ''' Variable, like duration, f0 and bap from world ''' def __init__(self, var_min, var_max, max_abs_value=4.0, is_symmetric=True): self.var_min = var_min self.var_max = var_max self.scale = var_max - var_min self.max_abs_value = max_abs_value self.is_symmetric = is_symmetric assert self.scale > 0 def normalize(self, var): if self.is_symmetric: return np.clip((2 * self.max_abs_value) * ((var - self.var_min) / self.scale) - self.max_abs_value, -self.max_abs_value, self.max_abs_value) else: return np.clip(self.max_abs_value * ((var - self.var_min) / self.scale), 0, self.max_abs_value) def denormalize(self, nvar): if self.is_symmetric: return (((np.clip(nvar, -self.max_abs_value, self.max_abs_value) + self.max_abs_value) * self.scale / (2 * self.max_abs_value)) + self.var_min) else: return ((np.clip(nvar, 0, self.max_abs_value) * self.scale / self.max_abs_value) + self.var_min) ================================================ FILE: TensorFlowTTS/tensorflow_tts/bin/__init__.py ================================================ ================================================ FILE: TensorFlowTTS/tensorflow_tts/bin/preprocess_unetts.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Perform preprocessing, with raw feature extraction and normalization of train/valid split.""" import argparse import logging import os import yaml import numpy as np from functools import partial from multiprocessing import Pool from sklearn.model_selection import train_test_split from tqdm import tqdm from tensorflow_tts.processor.multispk_voiceclone import MultiSPKVoiceCloneProcessor from tensorflow_tts.processor.multispk_voiceclone import AISHELL_CHN_SYMBOLS from tensorflow_tts.audio_process.audio_spec import AudioMelSpec os.environ["CUDA_VISIBLE_DEVICES"] = "" import random import tensorflow as tf SEED = 2021 random.seed(SEED) np.random.seed(SEED) tf.random.set_seed(SEED) _feats_handle = None def parse_and_config(): """Parse arguments and set configuration parameters.""" parser = argparse.ArgumentParser( description="Preprocess audio and text features " "(See detail in tensorflow_tts/bin/preprocess_dataset.py)." ) parser.add_argument( "--rootdir", default=None, type=str, required=True, help="Directory containing the dataset files.", ) parser.add_argument( "--outdir", default=None, type=str, required=True, help="Output directory where features will be saved.", ) parser.add_argument( "--dataset", type=str, default="multispk_voiceclone", choices=["multispk_voiceclone"], help="Dataset to preprocess.", ) parser.add_argument( "--during_train", type=int, default=0, choices=[0, 1], help="0-False, 1-True: trainging during model" ) parser.add_argument( "--all_train", type=int, default=0, choices=[0, 1], help="0-False, 1-True: trainging f0 model" ) parser.add_argument( "--mfaed_txt", type=str, default=None, required=True, help="mfa results txt" ) parser.add_argument( "--wavs_dir", type=str, default=None, required=True, help="wav dir" ) parser.add_argument( "--spkinfo_dir", type=str, default=None, required=True, help="spkinfo dir" ) parser.add_argument( "--embed_dir", type=str, default=None, required=True, help="embed dir" ) parser.add_argument( "--unseen_dir", type=str, default=None, required=True, help="unseen speaker dir" ) parser.add_argument( "--config", type=str, required=True, help="YAML format configuration file." ) parser.add_argument( "--n_cpus", type=int, default=4, required=False, help="Number of CPUs to use in parallel.", ) parser.add_argument( "--test_size", type=float, default=0.05, required=False, help="Proportion of files to use as test dataset.", ) parser.add_argument( "--verbose", type=int, default=0, choices=[0, 1, 2], help="Logging level. 0: DEBUG, 1: INFO and WARNING, 2: INFO, WARNING, and ERROR", ) args = parser.parse_args() # set logger FORMAT = "%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s" log_level = {0: logging.DEBUG, 1: logging.WARNING, 2: logging.ERROR} logging.basicConfig(level=log_level[args.verbose], format=FORMAT) # load config config = yaml.load(open(args.config), Loader=yaml.Loader) config.update(vars(args)) # config checks assert config["format"] == "npy", "'npy' is the only supported format." return config ''' ############################################################################### ############################# Duration ####################################### ############################################################################### ''' def preprocess_duration(): """Run preprocessing process and compute statistics for normalizing.""" config = parse_and_config() dataset_processor = { "multispk_voiceclone": MultiSPKVoiceCloneProcessor, } dataset_symbol = { "multispk_voiceclone": AISHELL_CHN_SYMBOLS, } dataset_cleaner = { "multispk_voiceclone": None, } logging.info(f"Selected '{config['dataset']}' processor.") processor = dataset_processor[config["dataset"]]( config["rootdir"], symbols = dataset_symbol[config["dataset"]], cleaner_names = dataset_cleaner[config["dataset"]], during_train = True if config["during_train"] else False, mfaed_txt = config["mfaed_txt"], wavs_dir = config["wavs_dir"], embed_dir = config["embed_dir"], spkinfo_dir = config["spkinfo_dir"], unseen_dir = config["unseen_dir"] ) # check output directories build_dir = lambda x: [ os.makedirs(os.path.join(config["outdir"], x, y), exist_ok=True) for y in ["ids", "raw-durations", "stat-durations"] ] build_dir("train") build_dir("valid") # save pretrained-processor to feature dir processor._save_mapper( os.path.join(config["outdir"], f"{config['dataset']}_mapper.json"), extra_attrs_to_save={"pinyin_dict": processor.pinyin_dict} if config["dataset"] == "multispk_voiceclone" else {}, ) # build train test split _Y = [i[0] for i in processor.items] train_split, valid_split = train_test_split( processor.items, test_size=config["test_size"], random_state=42, shuffle=True, stratify=_Y ) logging.info(f"Training items: {len(train_split)}") logging.info(f"Validation items: {len(valid_split)}") train_utt_ids = [x[1] for x in train_split] valid_utt_ids = [x[1] for x in valid_split] # save train and valid utt_ids to track later np.save(os.path.join(config["outdir"], "train_utt_ids.npy"), train_utt_ids, allow_pickle=False) np.save(os.path.join(config["outdir"], "valid_utt_ids.npy"), valid_utt_ids, allow_pickle=False) config["none_pinyin_symnum"] = processor.none_pinyin_symnum # define map iterator def iterator_data(items_list): for item in items_list: yield processor.get_one_sample(item) train_iterator_data = iterator_data(train_split) valid_iterator_data = iterator_data(valid_split) p = Pool(config["n_cpus"]) # preprocess train files and get statistics for normalizing partial_fn = partial(gen_duration_features, config=config) train_map = p.imap( partial_fn, tqdm(train_iterator_data, total=len(train_split), desc="[Preprocessing train]"), chunksize=10, ) for item in train_map: save_duration_to_file(item, "train", config) # preprocess valid files partial_fn = partial(gen_duration_features, config=config) valid_map = p.imap( partial_fn, tqdm(valid_iterator_data, total=len(valid_split), desc="[Preprocessing valid]"), chunksize=10, ) for item in valid_map: save_duration_to_file(item, "valid", config) """ sample = { "speaker_name": spkname, "filename" : filename, "wav_path" : wav_path, "text_ids" : text_ids, "durs" : durs, "embed_path" : embed_path, "rate" : self.target_rate, } """ def gen_duration_features(item, config): text_ids = item["text_ids"] durs = item["durs"] assert len(text_ids) == len(durs) none_phnum = config["none_pinyin_symnum"] shengmu = [] yunmu = [] is_shengmu = True for t_id, dur in zip(text_ids, durs): if t_id < none_phnum: continue if is_shengmu: shengmu.append(dur) is_shengmu = False else: yunmu.append(dur) is_shengmu = True assert len(shengmu) == len(yunmu) dur_stats = np.array([np.mean(shengmu), np.std(shengmu), np.mean(yunmu), np.std(yunmu)]) item["text_ids"] = np.array(text_ids) item["durs"] = np.array(durs) item["dur_stats"] = dur_stats return item def save_duration_to_file(features, subdir, config): filename = features["filename"] if config["format"] == "npy": save_list = [ (features["text_ids"], "ids", "ids", np.int32), (features["durs"], "raw-durations", "raw-durations", np.float32), (features["dur_stats"], "stat-durations", "stat-durations", np.float32), ] for item, name_dir, name_file, fmt in save_list: np.save( os.path.join( config["outdir"], subdir, name_dir, f"{filename}-{name_file}.npy" ), item.astype(fmt), allow_pickle=False, ) else: raise ValueError("'npy' is the only supported format.") ''' ############################################################################### ################################ Acous ######################################## ############################################################################### ''' def preprocess_acous(): """Run preprocessing process and compute statistics for normalizing.""" config = parse_and_config() dataset_processor = { "multispk_voiceclone": MultiSPKVoiceCloneProcessor, } dataset_symbol = { "multispk_voiceclone": AISHELL_CHN_SYMBOLS, } dataset_cleaner = { "multispk_voiceclone": None, } logging.info(f"Selected '{config['dataset']}' processor.") processor = dataset_processor[config["dataset"]]( config["rootdir"], symbols = dataset_symbol[config["dataset"]], cleaner_names = dataset_cleaner[config["dataset"]], all_train = True if config["all_train"] else False, mfaed_txt = config["mfaed_txt"], wavs_dir = config["wavs_dir"], embed_dir = config["embed_dir"], spkinfo_dir = config["spkinfo_dir"], unseen_dir = config["unseen_dir"] ) # check output directories build_dir = lambda x: [ os.makedirs(os.path.join(config["outdir"], x, y), exist_ok=True) for y in ["ids", "raw-durations", "raw-mels", "embeds"] ] build_dir("train") build_dir("valid") # save pretrained-processor to feature dir processor._save_mapper( os.path.join(config["outdir"], f"{config['dataset']}_mapper.json"), extra_attrs_to_save={"pinyin_dict": processor.pinyin_dict} if config["dataset"] == "multispk_voiceclone" else {}, ) # build train test split _Y = [i[0] for i in processor.items] train_split, valid_split = train_test_split( processor.items, test_size=config["test_size"], random_state=42, shuffle=True, stratify=_Y ) logging.info(f"Training items: {len(train_split)}") logging.info(f"Validation items: {len(valid_split)}") train_utt_ids = [x[1] for x in train_split] valid_utt_ids = [x[1] for x in valid_split] # save train and valid utt_ids to track later np.save(os.path.join(config["outdir"], "train_utt_ids.npy"), train_utt_ids, allow_pickle=False) np.save(os.path.join(config["outdir"], "valid_utt_ids.npy"), valid_utt_ids, allow_pickle=False) # config["none_pinyin_symnum"] = processor.none_pinyin_symnum # define map iterator def iterator_data(items_list): for item in items_list: yield processor.get_one_sample(item) train_iterator_data = iterator_data(train_split) valid_iterator_data = iterator_data(valid_split) p = Pool(config["n_cpus"]) # preprocess train files and get statistics for normalizing partial_fn = partial(gen_acous_features, config=config) train_map = p.imap_unordered( partial_fn, tqdm(train_iterator_data, total=len(train_split), desc="[Preprocessing train]"), chunksize=10, ) for item in train_map: save_acous_to_file(item, "train", config) # preprocess valid files partial_fn = partial(gen_acous_features, config=config) valid_map = p.imap_unordered( partial_fn, tqdm(valid_iterator_data, total=len(valid_split), desc="[Preprocessing valid]"), chunksize=10, ) for item in valid_map: save_acous_to_file(item, "valid", config) """ sample = { "speaker_name": spkname, "filename" : filename, "wav_path" : wav_path, "text_ids" : text_ids, "durs" : durs, "embed_path" : embed_path, "rate" : self.target_rate, } """ def gen_acous_features(item, config): text_ids = item["text_ids"] durs = item["durs"] assert len(text_ids) == len(durs) global _feats_handle if _feats_handle is None: _feats_handle = AudioMelSpec(**config["feat_params"]) audio = _feats_handle.load_wav(item["wav_path"]) mel = _feats_handle.melspectrogram(audio) assert len(mel) == sum(durs) item["text_ids"] = np.array(text_ids) item["durs"] = np.array(durs) item["mels"] = mel item["embeds"] = np.load(item["embed_path"]) return item def save_acous_to_file(features, subdir, config): filename = features["filename"] if config["format"] == "npy": save_list = [ (features["text_ids"], "ids", "ids", np.int32), (features["durs"], "raw-durations", "raw-durations", np.int32), (features["mels"], "raw-mels", "raw-mels", np.float32), (features["embeds"], "embeds", "embeds", np.float32), ] for item, name_dir, name_file, fmt in save_list: np.save( os.path.join( config["outdir"], subdir, name_dir, f"{filename}-{name_file}.npy" ), item.astype(fmt), allow_pickle=False, ) else: raise ValueError("'npy' is the only supported format.") ''' ############################################################################### ################################ Vocoder ###################################### ############################################################################### ''' def preprocess_vocoder(): """Run preprocessing process and compute statistics for normalizing.""" config = parse_and_config() dataset_processor = { "multispk_voiceclone": MultiSPKVoiceCloneProcessor, } dataset_symbol = { "multispk_voiceclone": AISHELL_CHN_SYMBOLS, } dataset_cleaner = { "multispk_voiceclone": None, } logging.info(f"Selected '{config['dataset']}' processor.") processor = dataset_processor[config["dataset"]]( config["rootdir"], symbols = dataset_symbol[config["dataset"]], cleaner_names = dataset_cleaner[config["dataset"]], during_train = True if config["during_train"] else False, mfaed_txt = config["mfaed_txt"], wavs_dir = config["wavs_dir"], embed_dir = config["embed_dir"], spkinfo_dir = config["spkinfo_dir"] ) # check output directories build_dir = lambda x: [ os.makedirs(os.path.join(config["outdir"], x, y), exist_ok=True) for y in ["norm-feats", "wavs"] ] build_dir("train") build_dir("valid") # save pretrained-processor to feature dir processor._save_mapper( os.path.join(config["outdir"], f"{config['dataset']}_mapper.json"), extra_attrs_to_save={"pinyin_dict": processor.pinyin_dict} if config["dataset"] == "multispk_voiceclone" else {}, ) # build train test split _Y = [i[0] for i in processor.items] train_split, valid_split = train_test_split( processor.items, test_size=config["test_size"], random_state=42, shuffle=True, stratify=_Y ) logging.info(f"Training items: {len(train_split)}") logging.info(f"Validation items: {len(valid_split)}") train_utt_ids = [x[1] for x in train_split] valid_utt_ids = [x[1] for x in valid_split] # save train and valid utt_ids to track later np.save(os.path.join(config["outdir"], "train_utt_ids.npy"), train_utt_ids, allow_pickle=False) np.save(os.path.join(config["outdir"], "valid_utt_ids.npy"), valid_utt_ids, allow_pickle=False) # config["none_pinyin_symnum"] = processor.none_pinyin_symnum # define map iterator def iterator_data(items_list): for item in items_list: yield processor.get_one_sample(item) train_iterator_data = iterator_data(train_split) valid_iterator_data = iterator_data(valid_split) p = Pool(config["n_cpus"]) # preprocess train files and get statistics for normalizing partial_fn = partial(gen_vocoder, config=config) train_map = p.imap_unordered( partial_fn, tqdm(train_iterator_data, total=len(train_split), desc="[Preprocessing train]"), chunksize=10, ) for item in train_map: save_vocoder_to_file(item, "train", config) # preprocess valid files partial_fn = partial(gen_vocoder, config=config) valid_map = p.imap_unordered( partial_fn, tqdm(valid_iterator_data, total=len(valid_split), desc="[Preprocessing valid]"), chunksize=10, ) for item in valid_map: save_vocoder_to_file(item, "valid", config) """ sample = { "speaker_name": spkname, "filename" : filename, "wav_path" : wav_path, "text_ids" : text_ids, "durs" : durs, "embed_path" : embed_path, "rate" : self.target_rate, } """ def gen_vocoder(item, config): global _feats_handle if _feats_handle is None: _feats_handle = AudioMelSpec(**config["feat_params"]) audio = _feats_handle.load_wav(item["wav_path"]) mel = _feats_handle.melspectrogram(audio) # check audio and feature length audio = np.pad(audio, (0, _feats_handle.n_fft), mode="edge") audio = audio[: len(mel) * _feats_handle.hop_size] assert len(mel) * _feats_handle.hop_size == len(audio) item["audio"] = audio item["mels"] = mel return item def save_vocoder_to_file(features, subdir, config): filename = features["filename"] if config["format"] == "npy": save_list = [ (features["audio"], "wavs", "wave", np.float32), (features["mels"], "norm-feats", "norm-feats", np.float32), ] for item, name_dir, name_file, fmt in save_list: np.save( os.path.join( config["outdir"], subdir, name_dir, f"{filename}-{name_file}.npy" ), item.astype(fmt), allow_pickle=False, ) else: raise ValueError("'npy' is the only supported format.") ================================================ FILE: TensorFlowTTS/tensorflow_tts/configs/__init__.py ================================================ from tensorflow_tts.configs.melgan import ( MelGANDiscriminatorConfig, MelGANGeneratorConfig, ) from tensorflow_tts.configs.mb_melgan import ( MultiBandMelGANDiscriminatorConfig, MultiBandMelGANGeneratorConfig, ) from tensorflow_tts.configs.unetts import UNETTSDurationConfig, UNETTSAcousConfig ================================================ FILE: TensorFlowTTS/tensorflow_tts/configs/mb_melgan.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Multi-band MelGAN Config object.""" from tensorflow_tts.configs import MelGANDiscriminatorConfig, MelGANGeneratorConfig class MultiBandMelGANGeneratorConfig(MelGANGeneratorConfig): """Initialize Multi-band MelGAN Generator Config.""" def __init__(self, **kwargs): super().__init__(**kwargs) self.subbands = kwargs.pop("subbands", 4) self.taps = kwargs.pop("taps", 62) self.cutoff_ratio = kwargs.pop("cutoff_ratio", 0.142) self.beta = kwargs.pop("beta", 9.0) class MultiBandMelGANDiscriminatorConfig(MelGANDiscriminatorConfig): """Initialize Multi-band MelGAN Discriminator Config.""" def __init__(self, **kwargs): super().__init__(**kwargs) ================================================ FILE: TensorFlowTTS/tensorflow_tts/configs/melgan.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """MelGAN Config object.""" class MelGANGeneratorConfig(object): """Initialize MelGAN Generator Config.""" def __init__( self, out_channels=1, kernel_size=7, filters=512, use_bias=True, upsample_scales=[8, 8, 2, 2], stack_kernel_size=3, stacks=3, nonlinear_activation="LeakyReLU", nonlinear_activation_params={"alpha": 0.2}, padding_type="REFLECT", use_final_nolinear_activation=True, is_weight_norm=True, initializer_seed=42, **kwargs ): """Init parameters for MelGAN Generator model.""" self.out_channels = out_channels self.kernel_size = kernel_size self.filters = filters self.use_bias = use_bias self.upsample_scales = upsample_scales self.stack_kernel_size = stack_kernel_size self.stacks = stacks self.nonlinear_activation = nonlinear_activation self.nonlinear_activation_params = nonlinear_activation_params self.padding_type = padding_type self.use_final_nolinear_activation = use_final_nolinear_activation self.is_weight_norm = is_weight_norm self.initializer_seed = initializer_seed class MelGANDiscriminatorConfig(object): """Initialize MelGAN Discriminator Config.""" def __init__( self, out_channels=1, scales=3, downsample_pooling="AveragePooling1D", downsample_pooling_params={"pool_size": 4, "strides": 2,}, kernel_sizes=[5, 3], filters=16, max_downsample_filters=1024, use_bias=True, downsample_scales=[4, 4, 4, 4], nonlinear_activation="LeakyReLU", nonlinear_activation_params={"alpha": 0.2}, padding_type="REFLECT", is_weight_norm=True, initializer_seed=42, **kwargs ): """Init parameters for MelGAN Discriminator model.""" self.out_channels = out_channels self.scales = scales self.downsample_pooling = downsample_pooling self.downsample_pooling_params = downsample_pooling_params self.kernel_sizes = kernel_sizes self.filters = filters self.max_downsample_filters = max_downsample_filters self.use_bias = use_bias self.downsample_scales = downsample_scales self.nonlinear_activation = nonlinear_activation self.nonlinear_activation_params = nonlinear_activation_params self.padding_type = padding_type self.is_weight_norm = is_weight_norm self.initializer_seed = initializer_seed ================================================ FILE: TensorFlowTTS/tensorflow_tts/configs/unetts.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """UnetTTS Config object.""" import collections from tensorflow_tts.processor.multispk_voiceclone import AISHELL_CHN_SYMBOLS as aishell_symbols SelfAttentionParams = collections.namedtuple( "SelfAttentionParams", [ "hidden_size", "num_hidden_layers", "num_attention_heads", "attention_head_size", "intermediate_size", "intermediate_kernel_size", "hidden_act", "output_attentions", "output_hidden_states", "initializer_range", "hidden_dropout_prob", "attention_probs_dropout_prob", "layer_norm_eps", ], ) SelfAttentionConditionalParams = collections.namedtuple( "SelfAttentionParams", [ "hidden_size", "num_hidden_layers", "num_attention_heads", "attention_head_size", "intermediate_size", "intermediate_kernel_size", "hidden_act", "output_attentions", "output_hidden_states", "initializer_range", "hidden_dropout_prob", "attention_probs_dropout_prob", "layer_norm_eps", "conditional_norm_type", ], ) class UNETTSDurationConfig(object): """Initialize UNETTSDuration Config.""" def __init__( self, dataset = 'multispk_voiceclone', vocab_size = len(aishell_symbols), encoder_hidden_size = 384, encoder_num_hidden_layers = 4, encoder_num_attention_heads = 2, encoder_attention_head_size = 192, encoder_intermediate_size = 1024, encoder_intermediate_kernel_size = 3, encoder_hidden_act = "mish", output_attentions = True, output_hidden_states = True, hidden_dropout_prob = 0.1, attention_probs_dropout_prob = 0.1, initializer_range = 0.02, layer_norm_eps = 1e-5, num_duration_conv_layers = 2, duration_predictor_filters = 256, duration_predictor_kernel_sizes = 3, duration_predictor_dropout_probs = 0.1, **kwargs ): """Init parameters for UNETTSDuration model.""" if dataset == "multispk_voiceclone": self.vocab_size = len(aishell_symbols) else: raise ValueError("No such dataset: {}".format(dataset)) self.initializer_range = initializer_range # self.max_position_embeddings = max_position_embeddings self.layer_norm_eps = layer_norm_eps # encoder params self.encoder_self_attention_params = SelfAttentionParams( hidden_size = encoder_hidden_size, num_hidden_layers = encoder_num_hidden_layers, num_attention_heads = encoder_num_attention_heads, attention_head_size = encoder_attention_head_size, hidden_act = encoder_hidden_act, intermediate_size = encoder_intermediate_size, intermediate_kernel_size = encoder_intermediate_kernel_size, output_attentions = output_attentions, output_hidden_states = output_hidden_states, initializer_range = initializer_range, hidden_dropout_prob = hidden_dropout_prob, attention_probs_dropout_prob = attention_probs_dropout_prob, layer_norm_eps = layer_norm_eps, ) self.duration_predictor_dropout_probs = duration_predictor_dropout_probs self.num_duration_conv_layers = num_duration_conv_layers self.duration_predictor_filters = duration_predictor_filters self.duration_predictor_kernel_sizes = duration_predictor_kernel_sizes class UNETTSAcousConfig(object): """Initialize UNETTSAcou Config.""" def __init__( self, dataset = 'multispk_voiceclone', vocab_size = len(aishell_symbols), encoder_hidden_size = 384, encoder_num_hidden_layers = 4, encoder_num_attention_heads = 2, encoder_attention_head_size = 192, encoder_intermediate_size = 1024, encoder_intermediate_kernel_size = 3, encoder_hidden_act = "mish", output_attentions = True, output_hidden_states = True, hidden_dropout_prob = 0.1, attention_probs_dropout_prob = 0.1, initializer_range = 0.02, layer_norm_eps = 1e-5, addfeatures_num = 3, isaddur = True, num_mels = 80, content_latent_dim = 132, n_conv_blocks = 6, adain_filter_size = 256, enc_kernel_size = 5, dec_kernel_size = 5, gen_kernel_size = 5, decoder_hidden_size = 384, decoder_num_hidden_layers = 4, decoder_num_attention_heads = 2, decoder_attention_head_size = 192, decoder_intermediate_size = 1024, decoder_intermediate_kernel_size = 3, decoder_hidden_act = "mish", decoder_conditional_norm_type = "Layer", decoder_is_conditional = True, num_variant_conv_layers = 2, variant_predictor_dropout_probs = 0.1, variant_predictor_filters = 256, variant_predictor_kernel_sizes = 3, n_conv_postnet = 5, postnet_conv_filters = 512, postnet_conv_kernel_sizes = 5, postnet_dropout_rate = 0.1, **kwargs ): """Init parameters for UNETTSAcou model.""" if dataset == "multispk_voiceclone": self.vocab_size = len(aishell_symbols) else: raise ValueError("No such dataset: {}".format(dataset)) self.initializer_range = initializer_range # self.max_position_embeddings = max_position_embeddings self.layer_norm_eps = layer_norm_eps self.num_mels = num_mels # encoder params self.encoder_self_attention_params = SelfAttentionParams( hidden_size = encoder_hidden_size, num_hidden_layers = encoder_num_hidden_layers, num_attention_heads = encoder_num_attention_heads, attention_head_size = encoder_attention_head_size, hidden_act = encoder_hidden_act, intermediate_size = encoder_intermediate_size, intermediate_kernel_size = encoder_intermediate_kernel_size, output_attentions = output_attentions, output_hidden_states = output_hidden_states, initializer_range = initializer_range, hidden_dropout_prob = hidden_dropout_prob, attention_probs_dropout_prob = attention_probs_dropout_prob, layer_norm_eps = layer_norm_eps, ) self.content_latent_dim = content_latent_dim self.n_conv_blocks = n_conv_blocks self.adain_filter_size = adain_filter_size self.enc_kernel_size = enc_kernel_size self.dec_kernel_size = dec_kernel_size self.gen_kernel_size = gen_kernel_size self.decoder_is_conditional = decoder_is_conditional self.decoder_self_attention_conditional_params = SelfAttentionConditionalParams( hidden_size = decoder_hidden_size, num_hidden_layers = decoder_num_hidden_layers, num_attention_heads = decoder_num_attention_heads, attention_head_size = decoder_attention_head_size, hidden_act = decoder_hidden_act, intermediate_size = decoder_intermediate_size, intermediate_kernel_size = decoder_intermediate_kernel_size, output_attentions = output_attentions, output_hidden_states = output_hidden_states, initializer_range = initializer_range, hidden_dropout_prob = hidden_dropout_prob, attention_probs_dropout_prob = attention_probs_dropout_prob, layer_norm_eps = layer_norm_eps, conditional_norm_type = decoder_conditional_norm_type, ) self.decoder_self_attention_params = SelfAttentionParams( hidden_size = decoder_hidden_size, num_hidden_layers = decoder_num_hidden_layers, num_attention_heads = decoder_num_attention_heads, attention_head_size = decoder_attention_head_size, hidden_act = decoder_hidden_act, intermediate_size = decoder_intermediate_size, intermediate_kernel_size = decoder_intermediate_kernel_size, output_attentions = output_attentions, output_hidden_states = output_hidden_states, initializer_range = initializer_range, hidden_dropout_prob = hidden_dropout_prob, attention_probs_dropout_prob = attention_probs_dropout_prob, layer_norm_eps = layer_norm_eps, ) self.num_variant_conv_layers = num_variant_conv_layers self.variant_predictor_dropout_probs = variant_predictor_dropout_probs self.variant_predictor_filters = variant_predictor_filters self.variant_predictor_kernel_sizes = variant_predictor_kernel_sizes # postnet self.n_conv_postnet = n_conv_postnet self.postnet_conv_filters = postnet_conv_filters self.postnet_conv_kernel_sizes = postnet_conv_kernel_sizes self.postnet_dropout_rate = postnet_dropout_rate self.addfeatures_num = addfeatures_num self.isaddur = isaddur ================================================ FILE: TensorFlowTTS/tensorflow_tts/datasets/__init__.py ================================================ from tensorflow_tts.datasets.abstract_dataset import AbstractDataset from tensorflow_tts.datasets.audio_dataset import AudioDataset from tensorflow_tts.datasets.mel_dataset import MelDataset ================================================ FILE: TensorFlowTTS/tensorflow_tts/datasets/abstract_dataset.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Abstract Dataset modules.""" import abc import tensorflow as tf class AbstractDataset(metaclass=abc.ABCMeta): """Abstract Dataset module for Dataset Loader.""" @abc.abstractmethod def get_args(self): """Return args for generator function.""" pass @abc.abstractmethod def generator(self): """Generator function, should have args from get_args function.""" pass @abc.abstractmethod def get_output_dtypes(self): """Return output dtypes for each element from generator.""" pass @abc.abstractmethod def get_len_dataset(self): """Return number of samples on dataset.""" pass def create( self, allow_cache=False, batch_size=1, is_shuffle=False, map_fn=None, reshuffle_each_iteration=True, ): """Create tf.dataset function.""" output_types = self.get_output_dtypes() datasets = tf.data.Dataset.from_generator( self.generator, output_types=output_types, args=(self.get_args()) ) if allow_cache: datasets = datasets.cache() if is_shuffle: datasets = datasets.shuffle( self.get_len_dataset(), reshuffle_each_iteration=reshuffle_each_iteration, ) if batch_size > 1 and map_fn is None: raise ValueError("map function must define when batch_size > 1.") if map_fn is not None: datasets = datasets.map(map_fn, tf.data.experimental.AUTOTUNE) datasets = datasets.batch(batch_size) datasets = datasets.prefetch(tf.data.experimental.AUTOTUNE) return datasets ================================================ FILE: TensorFlowTTS/tensorflow_tts/datasets/audio_dataset.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Audio modules.""" import logging import os import numpy as np import tensorflow as tf from tensorflow_tts.datasets.abstract_dataset import AbstractDataset from tensorflow_tts.utils import find_files class AudioDataset(AbstractDataset): """Tensorflow compatible audio dataset.""" def __init__( self, root_dir, audio_query="*-wave.npy", audio_load_fn=np.load, audio_length_threshold=0, ): """Initialize dataset. Args: root_dir (str): Root directory including dumped files. audio_query (str): Query to find feature files in root_dir. audio_load_fn (func): Function to load feature file. audio_length_threshold (int): Threshold to remove short feature files. return_utt_id (bool): Whether to return the utterance id with arrays. """ # find all of mel files. audio_files = sorted(find_files(root_dir, audio_query)) audio_lengths = [audio_load_fn(f).shape[0] for f in audio_files] # assert the number of files assert len(audio_files) != 0, f"Not found any mel files in ${root_dir}." if ".npy" in audio_query: suffix = audio_query[1:] utt_ids = [os.path.basename(f).replace(suffix, "") for f in audio_files] # set global params self.utt_ids = utt_ids self.audio_files = audio_files self.audio_lengths = audio_lengths self.audio_load_fn = audio_load_fn self.audio_length_threshold = audio_length_threshold def get_args(self): return [self.utt_ids] def generator(self, utt_ids): for i, utt_id in enumerate(utt_ids): audio_file = self.audio_files[i] audio = self.audio_load_fn(audio_file) audio_length = self.audio_lengths[i] items = {"utt_ids": utt_id, "audios": audio, "audio_lengths": audio_length} yield items def get_output_dtypes(self): output_types = { "utt_ids": tf.string, "audios": tf.float32, "audio_lengths": tf.float32, } return output_types def create( self, allow_cache=False, batch_size=1, is_shuffle=False, map_fn=None, reshuffle_each_iteration=True, ): """Create tf.dataset function.""" output_types = self.get_output_dtypes() datasets = tf.data.Dataset.from_generator( self.generator, output_types=output_types, args=(self.get_args()) ) datasets = datasets.filter( lambda x: x["audio_lengths"] > self.audio_length_threshold ) if allow_cache: datasets = datasets.cache() if is_shuffle: datasets = datasets.shuffle( self.get_len_dataset(), reshuffle_each_iteration=reshuffle_each_iteration, ) # define padded shapes padded_shapes = { "utt_ids": [], "audios": [None], "audio_lengths": [], } datasets = datasets.padded_batch(batch_size, padded_shapes=padded_shapes) datasets = datasets.prefetch(tf.data.experimental.AUTOTUNE) return datasets def get_len_dataset(self): return len(self.utt_ids) def __name__(self): return "AudioDataset" ================================================ FILE: TensorFlowTTS/tensorflow_tts/datasets/mel_dataset.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Dataset modules.""" import logging import os import numpy as np import tensorflow as tf from tensorflow_tts.datasets.abstract_dataset import AbstractDataset from tensorflow_tts.utils import find_files class MelDataset(AbstractDataset): """Tensorflow compatible mel dataset.""" def __init__( self, root_dir, mel_query="*-raw-feats.h5", mel_load_fn=np.load, mel_length_threshold=0, ): """Initialize dataset. Args: root_dir (str): Root directory including dumped files. mel_query (str): Query to find feature files in root_dir. mel_load_fn (func): Function to load feature file. mel_length_threshold (int): Threshold to remove short feature files. """ # find all of mel files. mel_files = sorted(find_files(root_dir, mel_query)) mel_lengths = [mel_load_fn(f).shape[0] for f in mel_files] # assert the number of files assert len(mel_files) != 0, f"Not found any mel files in ${root_dir}." if ".npy" in mel_query: suffix = mel_query[1:] utt_ids = [os.path.basename(f).replace(suffix, "") for f in mel_files] # set global params self.utt_ids = utt_ids self.mel_files = mel_files self.mel_lengths = mel_lengths self.mel_load_fn = mel_load_fn self.mel_length_threshold = mel_length_threshold def get_args(self): return [self.utt_ids] def generator(self, utt_ids): for i, utt_id in enumerate(utt_ids): mel_file = self.mel_files[i] mel = self.mel_load_fn(mel_file) mel_length = self.mel_lengths[i] items = {"utt_ids": utt_id, "mels": mel, "mel_lengths": mel_length} yield items def get_output_dtypes(self): output_types = { "utt_ids": tf.string, "mels": tf.float32, "mel_lengths": tf.int32, } return output_types def create( self, allow_cache=False, batch_size=1, is_shuffle=False, map_fn=None, reshuffle_each_iteration=True, ): """Create tf.dataset function.""" output_types = self.get_output_dtypes() datasets = tf.data.Dataset.from_generator( self.generator, output_types=output_types, args=(self.get_args()) ) datasets = datasets.filter( lambda x: x["mel_lengths"] > self.mel_length_threshold ) if allow_cache: datasets = datasets.cache() if is_shuffle: datasets = datasets.shuffle( self.get_len_dataset(), reshuffle_each_iteration=reshuffle_each_iteration, ) # define padded shapes padded_shapes = { "utt_ids": [], "mels": [None, 80], "mel_lengths": [], } datasets = datasets.padded_batch(batch_size, padded_shapes=padded_shapes) datasets = datasets.prefetch(tf.data.experimental.AUTOTUNE) return datasets def get_len_dataset(self): return len(self.utt_ids) def __name__(self): return "MelDataset" ================================================ FILE: TensorFlowTTS/tensorflow_tts/inference/__init__.py ================================================ from tensorflow_tts.inference.auto_model import TFAutoModel from tensorflow_tts.inference.auto_config import AutoConfig from tensorflow_tts.inference.auto_processor import AutoProcessor ================================================ FILE: TensorFlowTTS/tensorflow_tts/inference/auto_config.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 The HuggingFace Inc. team and Minh Nguyen (@dathudeptrai) # # 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. """Tensorflow Auto Config modules.""" import logging import yaml from collections import OrderedDict from tensorflow_tts.configs import ( MelGANGeneratorConfig, MultiBandMelGANGeneratorConfig, UNETTSDurationConfig, UNETTSAcousConfig, ) CONFIG_MAPPING = OrderedDict( [ ("multiband_melgan_generator", MultiBandMelGANGeneratorConfig), ("melgan_generator", MelGANGeneratorConfig), ("unetts_duration", UNETTSDurationConfig), ("unetts_acous", UNETTSAcousConfig), ] ) class AutoConfig: def __init__(self): raise EnvironmentError( "AutoConfig is designed to be instantiated " "using the `AutoConfig.from_pretrained(pretrained_path)` method." ) @classmethod def from_pretrained(cls, pretrained_path, **kwargs): with open(pretrained_path) as f: config = yaml.load(f, Loader=yaml.Loader) try: model_type = config["model_type"] config_class = CONFIG_MAPPING[model_type] config_class = config_class(**config[model_type + "_params"], **kwargs) return config_class except Exception: raise ValueError( "Unrecognized config in {}. " "Should have a `model_type` key in its config.yaml, or contain one of the following strings " "in its name: {}".format( pretrained_path, ", ".join(CONFIG_MAPPING.keys()) ) ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/inference/auto_model.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 The HuggingFace Inc. team and Minh Nguyen (@dathudeptrai) # # 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. """Tensorflow Auto Model modules.""" import logging import warnings from collections import OrderedDict from tensorflow_tts.configs import ( MelGANGeneratorConfig, MultiBandMelGANGeneratorConfig, UNETTSDurationConfig, UNETTSAcousConfig, ) from tensorflow_tts.models import ( TFMelGANGenerator, TFMBMelGANGenerator, TFUNETTSDuration, TFUNETTSAcous, ) TF_MODEL_MAPPING = OrderedDict( [ (MultiBandMelGANGeneratorConfig, TFMBMelGANGenerator), (MelGANGeneratorConfig, TFMelGANGenerator), (UNETTSDurationConfig, TFUNETTSDuration), (UNETTSAcousConfig, TFUNETTSAcous), ] ) class TFAutoModel(object): """General model class for inferencing.""" def __init__(self): raise EnvironmentError("Cannot be instantiated using `__init__()`") @classmethod def from_pretrained(cls, config, pretrained_path=None, **kwargs): is_build = kwargs.pop("is_build", True) for config_class, model_class in TF_MODEL_MAPPING.items(): if isinstance(config, config_class) and str(config_class.__name__) in str( config ): model = model_class(config=config, **kwargs) if is_build: model._build() if pretrained_path is not None and ".h5" in pretrained_path: model.load_weights(pretrained_path) return model raise ValueError( "Unrecognized configuration class {} for this kind of TFAutoModel: {}.\n" "Model type should be one of {}.".format( config.__class__, cls.__name__, ", ".join(c.__name__ for c in TF_MODEL_MAPPING.keys()), ) ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/inference/auto_processor.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 The TensorFlowTTS Team. # # 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. """Tensorflow Auto Processor modules.""" import logging import json from collections import OrderedDict from tensorflow_tts.processor import ( MultiSPKVoiceCloneProcessor, ) CONFIG_MAPPING = OrderedDict( [ ("MultiSPKVoiceCloneProcessor", MultiSPKVoiceCloneProcessor), ] ) class AutoProcessor: def __init__(self): raise EnvironmentError( "AutoProcessor is designed to be instantiated " "using the `AutoProcessor.from_pretrained(pretrained_path)` method." ) @classmethod def from_pretrained(cls, pretrained_path, **kwargs): with open(pretrained_path, "r") as f: config = json.load(f) try: processor_name = config["processor_name"] processor_class = CONFIG_MAPPING[processor_name] processor_class = processor_class( data_dir=None, loaded_mapper_path=pretrained_path ) return processor_class except Exception: raise ValueError( "Unrecognized processor in {}. " "Should have a `processor_name` key in its config.json, or contain one of the following strings " "in its name: {}".format( pretrained_path, ", ".join(CONFIG_MAPPING.keys()) ) ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/losses/__init__.py ================================================ from tensorflow_tts.losses.spectrogram import TFMelSpectrogram from tensorflow_tts.losses.stft import TFMultiResolutionSTFT ================================================ FILE: TensorFlowTTS/tensorflow_tts/losses/spectrogram.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Spectrogram-based loss modules.""" import tensorflow as tf class TFMelSpectrogram(tf.keras.layers.Layer): """Mel Spectrogram loss.""" def __init__( self, n_mels=80, f_min=80.0, f_max=7600, frame_length=1024, frame_step=256, fft_length=1024, sample_rate=16000, **kwargs ): """Initialize.""" super().__init__(**kwargs) self.frame_length = frame_length self.frame_step = frame_step self.fft_length = fft_length self.linear_to_mel_weight_matrix = tf.signal.linear_to_mel_weight_matrix( n_mels, fft_length // 2 + 1, sample_rate, f_min, f_max ) def _calculate_log_mels_spectrogram(self, signals): """Calculate forward propagation. Args: signals (Tensor): signal (B, T). Returns: Tensor: Mel spectrogram (B, T', 80) """ stfts = tf.signal.stft( signals, frame_length=self.frame_length, frame_step=self.frame_step, fft_length=self.fft_length, ) linear_spectrograms = tf.abs(stfts) mel_spectrograms = tf.tensordot( linear_spectrograms, self.linear_to_mel_weight_matrix, 1 ) mel_spectrograms.set_shape( linear_spectrograms.shape[:-1].concatenate( self.linear_to_mel_weight_matrix.shape[-1:] ) ) log_mel_spectrograms = tf.math.log(mel_spectrograms + 1e-6) # prevent nan. return log_mel_spectrograms def call(self, y, x): """Calculate forward propagation. Args: y (Tensor): Groundtruth signal (B, T). x (Tensor): Predicted signal (B, T). Returns: Tensor: Mean absolute Error Spectrogram Loss. """ y_mels = self._calculate_log_mels_spectrogram(y) x_mels = self._calculate_log_mels_spectrogram(x) return tf.reduce_mean( tf.abs(y_mels - x_mels), axis=list(range(1, len(x_mels.shape))) ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/losses/stft.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """STFT-based loss modules.""" import tensorflow as tf class TFSpectralConvergence(tf.keras.layers.Layer): """Spectral convergence loss.""" def __init__(self): """Initialize.""" super().__init__() def call(self, y_mag, x_mag): """Calculate forward propagation. Args: y_mag (Tensor): Magnitude spectrogram of groundtruth signal (B, #frames, #freq_bins). x_mag (Tensor): Magnitude spectrogram of predicted signal (B, #frames, #freq_bins). Returns: Tensor: Spectral convergence loss value. """ return tf.norm(y_mag - x_mag, ord="fro", axis=(-2, -1)) / tf.norm( y_mag, ord="fro", axis=(-2, -1) ) class TFLogSTFTMagnitude(tf.keras.layers.Layer): """Log STFT magnitude loss module.""" def __init__(self): """Initialize.""" super().__init__() def call(self, y_mag, x_mag): """Calculate forward propagation. Args: y_mag (Tensor): Magnitude spectrogram of groundtruth signal (B, #frames, #freq_bins). x_mag (Tensor): Magnitude spectrogram of predicted signal (B, #frames, #freq_bins). Returns: Tensor: Spectral convergence loss value. """ return tf.abs(tf.math.log(y_mag) - tf.math.log(x_mag)) class TFSTFT(tf.keras.layers.Layer): """STFT loss module.""" def __init__(self, frame_length=600, frame_step=120, fft_length=1024): """Initialize.""" super().__init__() self.frame_length = frame_length self.frame_step = frame_step self.fft_length = fft_length self.spectral_convergenge_loss = TFSpectralConvergence() self.log_stft_magnitude_loss = TFLogSTFTMagnitude() def call(self, y, x): """Calculate forward propagation. Args: y (Tensor): Groundtruth signal (B, T). x (Tensor): Predicted signal (B, T). Returns: Tensor: Spectral convergence loss value (pre-reduce). Tensor: Log STFT magnitude loss value (pre-reduce). """ x_mag = tf.abs( tf.signal.stft( signals=x, frame_length=self.frame_length, frame_step=self.frame_step, fft_length=self.fft_length, ) ) y_mag = tf.abs( tf.signal.stft( signals=y, frame_length=self.frame_length, frame_step=self.frame_step, fft_length=self.fft_length, ) ) # add small number to prevent nan value. # compatible with pytorch version. x_mag = tf.clip_by_value(tf.math.sqrt(x_mag ** 2 + 1e-7), 1e-7, 1e3) y_mag = tf.clip_by_value(tf.math.sqrt(y_mag ** 2 + 1e-7), 1e-7, 1e3) sc_loss = self.spectral_convergenge_loss(y_mag, x_mag) mag_loss = self.log_stft_magnitude_loss(y_mag, x_mag) return sc_loss, mag_loss class TFMultiResolutionSTFT(tf.keras.layers.Layer): """Multi resolution STFT loss module.""" def __init__( self, fft_lengths=[1024, 2048, 512], frame_lengths=[600, 1200, 240], frame_steps=[120, 240, 50], ): """Initialize Multi resolution STFT loss module. Args: frame_lengths (list): List of FFT sizes. frame_steps (list): List of hop sizes. fft_lengths (list): List of window lengths. """ super().__init__() assert len(frame_lengths) == len(frame_steps) == len(fft_lengths) self.stft_losses = [] for frame_length, frame_step, fft_length in zip( frame_lengths, frame_steps, fft_lengths ): self.stft_losses.append(TFSTFT(frame_length, frame_step, fft_length)) def call(self, y, x): """Calculate forward propagation. Args: y (Tensor): Groundtruth signal (B, T). x (Tensor): Predicted signal (B, T). Returns: Tensor: Multi resolution spectral convergence loss value. Tensor: Multi resolution log STFT magnitude loss value. """ sc_loss = 0.0 mag_loss = 0.0 for f in self.stft_losses: sc_l, mag_l = f(y, x) sc_loss += tf.reduce_mean(sc_l, axis=list(range(1, len(sc_l.shape)))) mag_loss += tf.reduce_mean(mag_l, axis=list(range(1, len(mag_l.shape)))) sc_loss /= len(self.stft_losses) mag_loss /= len(self.stft_losses) return sc_loss, mag_loss ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/__init__.py ================================================ from tensorflow_tts.models.melgan import ( TFMelGANDiscriminator, TFMelGANGenerator, TFMelGANMultiScaleDiscriminator, ) from tensorflow_tts.models.mb_melgan import TFPQMF from tensorflow_tts.models.mb_melgan import TFMBMelGANGenerator from tensorflow_tts.models.unetts import TFUNETTSDuration, TFUNETTSAcous, TFUNETTSContentPretrain ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/mb_melgan.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 The Multi-band MelGAN Authors , Minh Nguyen (@dathudeptrai) and Tomoki Hayashi (@kan-bayashi) # # 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. # ============================================================================ # # Compatible with https://github.com/kan-bayashi/ParallelWaveGAN/blob/master/parallel_wavegan/layers/pqmf.py. """Multi-band MelGAN Modules.""" import numpy as np import tensorflow as tf from scipy.signal import kaiser from tensorflow_tts.models import TFMelGANGenerator def design_prototype_filter(taps=62, cutoff_ratio=0.15, beta=9.0): """Design prototype filter for PQMF. This method is based on `A Kaiser window approach for the design of prototype filters of cosine modulated filterbanks`_. Args: taps (int): The number of filter taps. cutoff_ratio (float): Cut-off frequency ratio. beta (float): Beta coefficient for kaiser window. Returns: ndarray: Impluse response of prototype filter (taps + 1,). .. _`A Kaiser window approach for the design of prototype filters of cosine modulated filterbanks`: https://ieeexplore.ieee.org/abstract/document/681427 """ # check the arguments are valid assert taps % 2 == 0, "The number of taps mush be even number." assert 0.0 < cutoff_ratio < 1.0, "Cutoff ratio must be > 0.0 and < 1.0." # make initial filter omega_c = np.pi * cutoff_ratio with np.errstate(invalid="ignore"): h_i = np.sin(omega_c * (np.arange(taps + 1) - 0.5 * taps)) / ( np.pi * (np.arange(taps + 1) - 0.5 * taps) ) # fix nan due to indeterminate form h_i[taps // 2] = np.cos(0) * cutoff_ratio # apply kaiser window w = kaiser(taps + 1, beta) h = h_i * w return h class TFPQMF(tf.keras.layers.Layer): """PQMF module.""" def __init__(self, config, **kwargs): """Initilize PQMF module. Args: config (class): MultiBandMelGANGeneratorConfig """ super().__init__(**kwargs) subbands = config.subbands taps = config.taps cutoff_ratio = config.cutoff_ratio beta = config.beta # define filter coefficient h_proto = design_prototype_filter(taps, cutoff_ratio, beta) h_analysis = np.zeros((subbands, len(h_proto))) h_synthesis = np.zeros((subbands, len(h_proto))) for k in range(subbands): h_analysis[k] = ( 2 * h_proto * np.cos( (2 * k + 1) * (np.pi / (2 * subbands)) * (np.arange(taps + 1) - (taps / 2)) + (-1) ** k * np.pi / 4 ) ) h_synthesis[k] = ( 2 * h_proto * np.cos( (2 * k + 1) * (np.pi / (2 * subbands)) * (np.arange(taps + 1) - (taps / 2)) - (-1) ** k * np.pi / 4 ) ) # [subbands, 1, taps + 1] == [filter_width, in_channels, out_channels] analysis_filter = np.expand_dims(h_analysis, 1) analysis_filter = np.transpose(analysis_filter, (2, 1, 0)) synthesis_filter = np.expand_dims(h_synthesis, 0) synthesis_filter = np.transpose(synthesis_filter, (2, 1, 0)) # filter for downsampling & upsampling updown_filter = np.zeros((subbands, subbands, subbands), dtype=np.float32) for k in range(subbands): updown_filter[0, k, k] = 1.0 self.subbands = subbands self.taps = taps self.analysis_filter = analysis_filter.astype(np.float32) self.synthesis_filter = synthesis_filter.astype(np.float32) self.updown_filter = updown_filter.astype(np.float32) @tf.function( experimental_relax_shapes=True, input_signature=[tf.TensorSpec(shape=[None, None, 1], dtype=tf.float32)], ) def analysis(self, x): """Analysis with PQMF. Args: x (Tensor): Input tensor (B, T, 1). Returns: Tensor: Output tensor (B, T // subbands, subbands). """ x = tf.pad(x, [[0, 0], [self.taps // 2, self.taps // 2], [0, 0]]) x = tf.nn.conv1d(x, self.analysis_filter, stride=1, padding="VALID") x = tf.nn.conv1d(x, self.updown_filter, stride=self.subbands, padding="VALID") return x @tf.function( experimental_relax_shapes=True, input_signature=[tf.TensorSpec(shape=[None, None, None], dtype=tf.float32)], ) def synthesis(self, x): """Synthesis with PQMF. Args: x (Tensor): Input tensor (B, T // subbands, subbands). Returns: Tensor: Output tensor (B, T, 1). """ x = tf.nn.conv1d_transpose( x, self.updown_filter * self.subbands, strides=self.subbands, output_shape=( tf.shape(x)[0], tf.shape(x)[1] * self.subbands, self.subbands, ), ) x = tf.pad(x, [[0, 0], [self.taps // 2, self.taps // 2], [0, 0]]) return tf.nn.conv1d(x, self.synthesis_filter, stride=1, padding="VALID") class TFMBMelGANGenerator(TFMelGANGenerator): """Tensorflow MBMelGAN generator module.""" def __init__(self, config, **kwargs): super().__init__(config, **kwargs) self.pqmf = TFPQMF(config=config, name="pqmf") def call(self, mels, **kwargs): """Calculate forward propagation. Args: c (Tensor): Input tensor (B, T, channels) Returns: Tensor: Output tensor (B, T ** prod(upsample_scales), out_channels) """ return self.inference(mels) @tf.function( input_signature=[ tf.TensorSpec(shape=[None, None, 80], dtype=tf.float32, name="mels") ] ) def inference(self, mels): mb_audios = self.melgan(mels) return self.pqmf.synthesis(mb_audios) @tf.function( input_signature=[ tf.TensorSpec(shape=[1, None, 80], dtype=tf.float32, name="mels") ] ) def inference_tflite(self, mels): mb_audios = self.melgan(mels) return self.pqmf.synthesis(mb_audios) ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/melgan.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 The MelGAN Authors and Minh Nguyen (@dathudeptrai) # # 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. """MelGAN Modules.""" import numpy as np import tensorflow as tf from tensorflow_tts.utils import GroupConv1D, WeightNormalization def get_initializer(initializer_seed=42): """Creates a `tf.initializers.glorot_normal` with the given seed. Args: initializer_seed: int, initializer seed. Returns: GlorotNormal initializer with seed = `initializer_seed`. """ return tf.keras.initializers.GlorotNormal(seed=initializer_seed) class TFReflectionPad1d(tf.keras.layers.Layer): """Tensorflow ReflectionPad1d module.""" def __init__(self, padding_size, padding_type="REFLECT", **kwargs): """Initialize TFReflectionPad1d module. Args: padding_size (int) padding_type (str) ("CONSTANT", "REFLECT", or "SYMMETRIC". Default is "REFLECT") """ super().__init__(**kwargs) self.padding_size = padding_size self.padding_type = padding_type def call(self, x): """Calculate forward propagation. Args: x (Tensor): Input tensor (B, T, C). Returns: Tensor: Padded tensor (B, T + 2 * padding_size, C). """ return tf.pad( x, [[0, 0], [self.padding_size, self.padding_size], [0, 0]], self.padding_type, ) class TFConvTranspose1d(tf.keras.layers.Layer): """Tensorflow ConvTranspose1d module.""" def __init__( self, filters, kernel_size, strides, padding, is_weight_norm, initializer_seed, **kwargs ): """Initialize TFConvTranspose1d( module. Args: filters (int): Number of filters. kernel_size (int): kernel size. strides (int): Stride width. padding (str): Padding type ("same" or "valid"). """ super().__init__(**kwargs) self.conv1d_transpose = tf.keras.layers.Conv2DTranspose( filters=filters, kernel_size=(kernel_size, 1), strides=(strides, 1), padding="same", kernel_initializer=get_initializer(initializer_seed), ) if is_weight_norm: self.conv1d_transpose = WeightNormalization(self.conv1d_transpose) def call(self, x): """Calculate forward propagation. Args: x (Tensor): Input tensor (B, T, C). Returns: Tensor: Output tensor (B, T', C'). """ x = tf.expand_dims(x, 2) x = self.conv1d_transpose(x) x = tf.squeeze(x, 2) return x class TFResidualStack(tf.keras.layers.Layer): """Tensorflow ResidualStack module.""" def __init__( self, kernel_size, filters, dilation_rate, use_bias, nonlinear_activation, nonlinear_activation_params, is_weight_norm, initializer_seed, **kwargs ): """Initialize TFResidualStack module. Args: kernel_size (int): Kernel size. filters (int): Number of filters. dilation_rate (int): Dilation rate. use_bias (bool): Whether to add bias parameter in convolution layers. nonlinear_activation (str): Activation function module name. nonlinear_activation_params (dict): Hyperparameters for activation function. """ super().__init__(**kwargs) self.blocks = [ getattr(tf.keras.layers, nonlinear_activation)( **nonlinear_activation_params ), TFReflectionPad1d((kernel_size - 1) // 2 * dilation_rate), tf.keras.layers.Conv1D( filters=filters, kernel_size=kernel_size, dilation_rate=dilation_rate, use_bias=use_bias, kernel_initializer=get_initializer(initializer_seed), ), getattr(tf.keras.layers, nonlinear_activation)( **nonlinear_activation_params ), tf.keras.layers.Conv1D( filters=filters, kernel_size=1, use_bias=use_bias, kernel_initializer=get_initializer(initializer_seed), ), ] self.shortcut = tf.keras.layers.Conv1D( filters=filters, kernel_size=1, use_bias=use_bias, kernel_initializer=get_initializer(initializer_seed), name="shortcut", ) # apply weightnorm if is_weight_norm: self._apply_weightnorm(self.blocks) self.shortcut = WeightNormalization(self.shortcut) def call(self, x): """Calculate forward propagation. Args: x (Tensor): Input tensor (B, T, C). Returns: Tensor: Output tensor (B, T, C). """ _x = tf.identity(x) for layer in self.blocks: _x = layer(_x) shortcut = self.shortcut(x) return shortcut + _x def _apply_weightnorm(self, list_layers): """Try apply weightnorm for all layer in list_layers.""" for i in range(len(list_layers)): try: layer_name = list_layers[i].name.lower() if "conv1d" in layer_name or "dense" in layer_name: list_layers[i] = WeightNormalization(list_layers[i]) except Exception: pass class TFMelGANGenerator(tf.keras.Model): """Tensorflow MelGAN generator module.""" def __init__(self, config, **kwargs): """Initialize TFMelGANGenerator module. Args: config: config object of Melgan generator. """ super().__init__(**kwargs) # check hyper parameter is valid or not assert config.filters >= np.prod(config.upsample_scales) assert config.filters % (2 ** len(config.upsample_scales)) == 0 # add initial layer layers = [] layers += [ TFReflectionPad1d( (config.kernel_size - 1) // 2, padding_type=config.padding_type, name="first_reflect_padding", ), tf.keras.layers.Conv1D( filters=config.filters, kernel_size=config.kernel_size, use_bias=config.use_bias, kernel_initializer=get_initializer(config.initializer_seed), ), ] for i, upsample_scale in enumerate(config.upsample_scales): # add upsampling layer layers += [ getattr(tf.keras.layers, config.nonlinear_activation)( **config.nonlinear_activation_params ), TFConvTranspose1d( filters=config.filters // (2 ** (i + 1)), kernel_size=upsample_scale * 2, strides=upsample_scale, padding="same", is_weight_norm=config.is_weight_norm, initializer_seed=config.initializer_seed, name="conv_transpose_._{}".format(i), ), ] # ad residual stack layer for j in range(config.stacks): layers += [ TFResidualStack( kernel_size=config.stack_kernel_size, filters=config.filters // (2 ** (i + 1)), dilation_rate=config.stack_kernel_size ** j, use_bias=config.use_bias, nonlinear_activation=config.nonlinear_activation, nonlinear_activation_params=config.nonlinear_activation_params, is_weight_norm=config.is_weight_norm, initializer_seed=config.initializer_seed, name="residual_stack_._{}._._{}".format(i, j), ) ] # add final layer layers += [ getattr(tf.keras.layers, config.nonlinear_activation)( **config.nonlinear_activation_params ), TFReflectionPad1d( (config.kernel_size - 1) // 2, padding_type=config.padding_type, name="last_reflect_padding", ), tf.keras.layers.Conv1D( filters=config.out_channels, kernel_size=config.kernel_size, use_bias=config.use_bias, kernel_initializer=get_initializer(config.initializer_seed), ), ] if config.use_final_nolinear_activation: layers += [tf.keras.layers.Activation("tanh")] if config.is_weight_norm is True: self._apply_weightnorm(layers) self.melgan = tf.keras.models.Sequential(layers) def call(self, mels, **kwargs): """Calculate forward propagation. Args: c (Tensor): Input tensor (B, T, channels) Returns: Tensor: Output tensor (B, T ** prod(upsample_scales), out_channels) """ return self.inference(mels) @tf.function( input_signature=[ tf.TensorSpec(shape=[None, None, 80], dtype=tf.float32, name="mels") ] ) def inference(self, mels): return self.melgan(mels) @tf.function( input_signature=[ tf.TensorSpec(shape=[1, None, 80], dtype=tf.float32, name="mels") ] ) def inference_tflite(self, mels): return self.melgan(mels) def _apply_weightnorm(self, list_layers): """Try apply weightnorm for all layer in list_layers.""" for i in range(len(list_layers)): try: layer_name = list_layers[i].name.lower() if "conv1d" in layer_name or "dense" in layer_name: list_layers[i] = WeightNormalization(list_layers[i]) except Exception: pass def _build(self): """Build model by passing fake input.""" fake_mels = tf.random.uniform(shape=[1, 100, 80], dtype=tf.float32) self(fake_mels) class TFMelGANDiscriminator(tf.keras.layers.Layer): """Tensorflow MelGAN generator module.""" def __init__( self, out_channels=1, kernel_sizes=[5, 3], filters=16, max_downsample_filters=1024, use_bias=True, downsample_scales=[4, 4, 4, 4], nonlinear_activation="LeakyReLU", nonlinear_activation_params={"alpha": 0.2}, padding_type="REFLECT", is_weight_norm=True, initializer_seed=0.02, **kwargs ): """Initilize MelGAN discriminator module. Args: out_channels (int): Number of output channels. kernel_sizes (list): List of two kernel sizes. The prod will be used for the first conv layer, and the first and the second kernel sizes will be used for the last two layers. For example if kernel_sizes = [5, 3], the first layer kernel size will be 5 * 3 = 15. the last two layers' kernel size will be 5 and 3, respectively. filters (int): Initial number of filters for conv layer. max_downsample_filters (int): Maximum number of filters for downsampling layers. use_bias (bool): Whether to add bias parameter in convolution layers. downsample_scales (list): List of downsampling scales. nonlinear_activation (str): Activation function module name. nonlinear_activation_params (dict): Hyperparameters for activation function. padding_type (str): Padding type (support only "REFLECT", "CONSTANT", "SYMMETRIC") """ super().__init__(**kwargs) discriminator = [] # check kernel_size is valid assert len(kernel_sizes) == 2 assert kernel_sizes[0] % 2 == 1 assert kernel_sizes[1] % 2 == 1 # add first layer discriminator = [ TFReflectionPad1d( (np.prod(kernel_sizes) - 1) // 2, padding_type=padding_type ), tf.keras.layers.Conv1D( filters=filters, kernel_size=int(np.prod(kernel_sizes)), use_bias=use_bias, kernel_initializer=get_initializer(initializer_seed), ), getattr(tf.keras.layers, nonlinear_activation)( **nonlinear_activation_params ), ] # add downsample layers in_chs = filters with tf.keras.utils.CustomObjectScope({"GroupConv1D": GroupConv1D}): for downsample_scale in downsample_scales: out_chs = min(in_chs * downsample_scale, max_downsample_filters) discriminator += [ GroupConv1D( filters=out_chs, kernel_size=downsample_scale * 10 + 1, strides=downsample_scale, padding="same", use_bias=use_bias, groups=in_chs // 4, kernel_initializer=get_initializer(initializer_seed), ) ] discriminator += [ getattr(tf.keras.layers, nonlinear_activation)( **nonlinear_activation_params ) ] in_chs = out_chs # add final layers out_chs = min(in_chs * 2, max_downsample_filters) discriminator += [ tf.keras.layers.Conv1D( filters=out_chs, kernel_size=kernel_sizes[0], padding="same", use_bias=use_bias, kernel_initializer=get_initializer(initializer_seed), ) ] discriminator += [ getattr(tf.keras.layers, nonlinear_activation)( **nonlinear_activation_params ) ] discriminator += [ tf.keras.layers.Conv1D( filters=out_channels, kernel_size=kernel_sizes[1], padding="same", use_bias=use_bias, kernel_initializer=get_initializer(initializer_seed), ) ] if is_weight_norm is True: self._apply_weightnorm(discriminator) self.disciminator = discriminator def call(self, x, **kwargs): """Calculate forward propagation. Args: x (Tensor): Input noise signal (B, T, 1). Returns: List: List of output tensors of each layer. """ outs = [] for f in self.disciminator: x = f(x) outs += [x] return outs def _apply_weightnorm(self, list_layers): """Try apply weightnorm for all layer in list_layers.""" for i in range(len(list_layers)): try: layer_name = list_layers[i].name.lower() if "conv1d" in layer_name or "dense" in layer_name: list_layers[i] = WeightNormalization(list_layers[i]) except Exception: pass class TFMelGANMultiScaleDiscriminator(tf.keras.Model): """MelGAN multi-scale discriminator module.""" def __init__(self, config, **kwargs): """Initilize MelGAN multi-scale discriminator module. Args: config: config object for melgan discriminator """ super().__init__(**kwargs) self.discriminator = [] # add discriminator for i in range(config.scales): self.discriminator += [ TFMelGANDiscriminator( out_channels=config.out_channels, kernel_sizes=config.kernel_sizes, filters=config.filters, max_downsample_filters=config.max_downsample_filters, use_bias=config.use_bias, downsample_scales=config.downsample_scales, nonlinear_activation=config.nonlinear_activation, nonlinear_activation_params=config.nonlinear_activation_params, padding_type=config.padding_type, is_weight_norm=config.is_weight_norm, initializer_seed=config.initializer_seed, name="melgan_discriminator_scale_._{}".format(i), ) ] self.pooling = getattr(tf.keras.layers, config.downsample_pooling)( **config.downsample_pooling_params ) def call(self, x, **kwargs): """Calculate forward propagation. Args: x (Tensor): Input noise signal (B, T, 1). Returns: List: List of list of each discriminator outputs, which consists of each layer output tensors. """ outs = [] for f in self.discriminator: outs += [f(x)] x = self.pooling(x) return outs ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/moduls/__init__.py ================================================ from tensorflow_tts.models.moduls import ( core, core2, conditional, adain_en_de_code ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/moduls/adain_en_de_code.py ================================================ import tensorflow as tf import tensorflow_addons as tfa from tensorflow_tts.models.moduls.conditional import MaskInstanceNormalization def get_initializer(initializer_range=0.02): """Creates a `tf.initializers.truncated_normal` with the given range. Args: initializer_range: float, initializer range for stddev. Returns: TruncatedNormal initializer with stddev = `initializer_range`. """ return tf.keras.initializers.TruncatedNormal(stddev=initializer_range) class ConvModul(tf.keras.layers.Layer): def __init__(self, hidden_size, kernel_size, initializer_range, layer_norm_eps=1e-5, **kwargs): super().__init__(**kwargs) self.conv_0 = tf.keras.layers.Conv1D( filters = hidden_size, kernel_size = kernel_size, kernel_initializer = get_initializer(initializer_range), padding = 'same', ) self.conv_1 = tf.keras.layers.Conv1D( filters = hidden_size, kernel_size = kernel_size, kernel_initializer = get_initializer(initializer_range), padding = 'same', ) self.atc = tf.keras.layers.Activation(tf.nn.relu) self.batch_norm = tf.keras.layers.BatchNormalization(epsilon=layer_norm_eps) # TODO def call(self, x): y = self.conv_0(x) y = self.batch_norm(y) y = self.atc(y) y = self.conv_1(y) return y class EncConvBlock(tf.keras.layers.Layer): def __init__(self, config, **kwargs): super().__init__(**kwargs) self.conv = ConvModul( config.adain_filter_size, config.enc_kernel_size, config.initializer_range, config.layer_norm_eps) def call(self, x): return x + self.conv(x) class DecConvBlock(tf.keras.layers.Layer): def __init__(self, config, **kwargs): super().__init__(**kwargs) self.dec_conv = ConvModul( config.adain_filter_size, config.dec_kernel_size, config.initializer_range, config.layer_norm_eps) self.gen_conv = ConvModul( config.adain_filter_size, config.gen_kernel_size, config.initializer_range, config.layer_norm_eps) def call(self, x): y = self.dec_conv(x) y = y + self.gen_conv(y) return x + y class AadINEncoder(tf.keras.Model): def __init__(self, config, **kwargs): super().__init__(**kwargs) self.config = config self.in_hidden_size = config.adain_filter_size # 256 self.out_hidden_size = config.content_latent_dim # content_latent_dim self.n_conv_blocks = config.n_conv_blocks self.in_conv = tf.keras.layers.Conv1D( filters = self.in_hidden_size, kernel_size = 1, kernel_initializer = get_initializer(config.initializer_range), padding = 'same', ) self.out_conv = tf.keras.layers.Conv1D( filters = self.out_hidden_size, kernel_size = 1, kernel_initializer = get_initializer(config.initializer_range), padding = 'same', ) self.inorm = MaskInstanceNormalization(config.layer_norm_eps) self.conv_blocks = [ EncConvBlock(config) for _ in range(self.n_conv_blocks) ] def call(self, x, mask): means = [] stds = [] y = self.in_conv(x) # 80 -> 256 for block in self.conv_blocks: y = block(y) y, mean, std = self.inorm(y, mask, return_mean_std=True) means.append(mean) stds.append(std) y = self.out_conv(y) # 256 -> 128 + 4 # TODO sigmoid means.reverse() stds.reverse() return y, means, stds class AdaINDecoder(tf.keras.Model): def __init__(self, config, **kwargs): super().__init__(**kwargs) self.config = config self.in_hidden_size = config.adain_filter_size # 256 self.out_hidden_size = config.num_mels # 80 self.n_conv_blocks = config.n_conv_blocks self.in_conv = tf.keras.layers.Conv1D( filters = self.in_hidden_size, kernel_size = 1, kernel_initializer = get_initializer(config.initializer_range), padding = 'same', ) self.out_conv = tf.keras.layers.Conv1D( filters = self.out_hidden_size, kernel_size = 1, kernel_initializer = get_initializer(config.initializer_range), padding = 'same', ) self.inorm = MaskInstanceNormalization(config.layer_norm_eps) self.conv_blocks = [ DecConvBlock(config) for _ in range(self.n_conv_blocks) ] def call(self, enc, cond, mask): _, means, stds = cond # TODO # y, means, stds = cond # _, mean, std = self.inorm(y, mask, return_mean_std=True) # enc = self.inorm(enc, mask) # enc = enc * tf.expand_dims(std, 1) + tf.expand_dims(mean, 1) y = self.in_conv(enc) # 132 -> 256 for block, mean, std in zip(self.conv_blocks, means, stds): y = self.inorm(y, mask) y = y * tf.expand_dims(std, 1) + tf.expand_dims(mean, 1) y = block(y) y = self.out_conv(y) # 256 -> 80 return y ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/moduls/conditional.py ================================================ import tensorflow as tf import tensorflow_addons as tfa import numpy as np def get_initializer(initializer_range=0.02): """Creates a `tf.initializers.truncated_normal` with the given range. Args: initializer_range: float, initializer range for stddev. Returns: TruncatedNormal initializer with stddev = `initializer_range`. """ return tf.keras.initializers.TruncatedNormal(stddev=initializer_range) class MaskInstanceNormalization(tf.keras.layers.Layer): def __init__(self, layer_norm_eps, **kwargs): super().__init__(**kwargs) self.layer_norm_eps = layer_norm_eps def _cal_mean_std(self, inputs, mask): expend_mask = tf.cast(tf.expand_dims(mask, axis=2), inputs.dtype) sums = tf.math.reduce_sum(tf.cast(mask, inputs.dtype), axis=-1, keepdims=True) mean = tf.math.reduce_sum(inputs * expend_mask, axis=1) / sums std = tf.math.sqrt( tf.math.reduce_sum( tf.math.pow(inputs - tf.expand_dims(mean, 1), 2) * expend_mask, axis = 1 ) / sums + self.layer_norm_eps ) return mean, std, expend_mask def call(self, inputs, mask, return_mean_std=False): ''' inputs: [B, T, hidden_size] mask: [B, T] ''' mean, std, expend_mask = self._cal_mean_std(inputs, mask) outputs = (inputs - tf.expand_dims(mean, 1)) / tf.expand_dims(std, 1) * expend_mask if return_mean_std: return outputs, mean, std else: return outputs # TODO class ConditionalNormalization(tf.keras.layers.Layer): def __init__(self, config, **kwargs): super().__init__(**kwargs) self.config = config self.scale = tf.keras.layers.Dense( config.hidden_size, use_bias = False, kernel_initializer = get_initializer(config.initializer_range), name = "Scale", ) self.mean = tf.keras.layers.Dense( config.hidden_size, use_bias = False, kernel_initializer = get_initializer(config.initializer_range), name = "Mean", ) if config.conditional_norm_type == "Layer": self.norm_layer = tf.keras.layers.LayerNormalization( center = False, scale = False, epsilon = config.layer_norm_eps, name = "LayerNorm", ) elif config.conditional_norm_type == "Instance": # self.norm_layer = tfa.layers.InstanceNormalization( # center = False, # scale = False, # epsilon = config.layer_norm_eps, # name = "InstanceNorm", # ) self.norm_layer = MaskInstanceNormalization(config.layer_norm_eps) else: print(f"Not support norm type {config.conditional_norm_type} !") exit(0) def call(self, inputs, conds, mask): ''' inputs: [B, T, hidden_size] conds: [B, 1, C'] mask: [B, T] ''' if self.config.conditional_norm_type == "Layer": tmp = self.norm_layer(inputs) elif self.config.conditional_norm_type == "Instance": tmp = self.norm_layer(inputs, mask) scale = self.scale(conds) mean = self.mean(conds) return tmp * scale + mean ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/moduls/core.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 The FastSpeech Authors, The HuggingFace Inc. team and Minh Nguyen (@dathudeptrai) # # 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. """Tensorflow Model modules for FastSpeech.""" import numpy as np import tensorflow as tf import scipy.stats def get_initializer(initializer_range=0.02): """Creates a `tf.initializers.truncated_normal` with the given range. Args: initializer_range: float, initializer range for stddev. Returns: TruncatedNormal initializer with stddev = `initializer_range`. """ return tf.keras.initializers.TruncatedNormal(stddev=initializer_range) def gelu(x): """Gaussian Error Linear unit.""" cdf = 0.5 * (1.0 + tf.math.erf(x / tf.math.sqrt(2.0))) return x * cdf def gelu_new(x): """Smoother gaussian Error Linear Unit.""" cdf = 0.5 * (1.0 + tf.tanh((np.sqrt(2 / np.pi) * (x + 0.044715 * tf.pow(x, 3))))) return x * cdf def swish(x): """Swish activation function.""" return x * tf.sigmoid(x) def mish(x): return x * tf.math.tanh(tf.math.softplus(x)) ACT2FN = { "identity": tf.keras.layers.Activation("linear"), "tanh": tf.keras.layers.Activation("tanh"), "gelu": tf.keras.layers.Activation(gelu), "relu": tf.keras.activations.relu, "swish": tf.keras.layers.Activation(swish), "gelu_new": tf.keras.layers.Activation(gelu_new), "mish": tf.keras.layers.Activation(mish), } class TFEmbedding(tf.keras.layers.Embedding): """Faster version of embedding.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def call(self, inputs): inputs = tf.cast(inputs, tf.int32) outputs = tf.gather(self.embeddings, inputs) return outputs class TFFastSpeechEmbeddings(tf.keras.layers.Layer): """Construct charactor/phoneme/positional/speaker embeddings.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.vocab_size = config.vocab_size self.hidden_size = config.encoder_self_attention_params.hidden_size self.initializer_range = config.initializer_range self.config = config def build(self, input_shape): """Build shared charactor/phoneme embedding layers.""" with tf.name_scope("charactor_embeddings"): self.charactor_embeddings = self.add_weight( "weight", shape=[self.vocab_size, self.hidden_size], initializer=get_initializer(self.initializer_range), ) super().build(input_shape) def call(self, input_ids): return tf.gather(self.charactor_embeddings, input_ids) class TFFastSpeechSelfAttention(tf.keras.layers.Layer): """Self attention module for fastspeech.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) if config.hidden_size % config.num_attention_heads != 0: raise ValueError( "The hidden size (%d) is not a multiple of the number of attention " "heads (%d)" % (config.hidden_size, config.num_attention_heads) ) self.output_attentions = config.output_attentions self.num_attention_heads = config.num_attention_heads self.all_head_size = self.num_attention_heads * config.attention_head_size self.query = tf.keras.layers.Dense( self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="query", ) self.key = tf.keras.layers.Dense( self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="key", ) self.value = tf.keras.layers.Dense( self.all_head_size, kernel_initializer=get_initializer(config.initializer_range), name="value", ) self.dropout = tf.keras.layers.Dropout(config.attention_probs_dropout_prob) self.config = config # TODO # self.half_win = config.local_attention_halfwin_size # self.frames_max = 100 # self.local_maxs = self._local_attention_mask() # self.local_ones = tf.ones([self.frames_max, self.frames_max], tf.float32) def transpose_for_scores(self, x, batch_size): """Transpose to calculate attention scores.""" x = tf.reshape( x, (batch_size, -1, self.num_attention_heads, self.config.attention_head_size), ) return tf.transpose(x, perm=[0, 2, 1, 3]) # def _local_attention_mask(self, frames_num): # xv, yv = tf.meshgrid(tf.range(frames_num), tf.range(frames_num), indexing="ij") # f32_matrix = tf.cast(yv - xv, tf.float32) # val = f32_matrix[0][self.half_win] # local1 = tf.math.greater_equal(f32_matrix, -val) # local2 = tf.math.less_equal(f32_matrix, val) # return tf.cast(tf.logical_and(local1, local2), tf.float32) def call(self, inputs, training=False): """Call logic.""" hidden_states, attention_mask = inputs batch_size = tf.shape(hidden_states)[0] mixed_query_layer = self.query(hidden_states) mixed_key_layer = self.key(hidden_states) mixed_value_layer = self.value(hidden_states) query_layer = self.transpose_for_scores(mixed_query_layer, batch_size) key_layer = self.transpose_for_scores(mixed_key_layer, batch_size) value_layer = self.transpose_for_scores(mixed_value_layer, batch_size) attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True) dk = tf.cast(tf.shape(key_layer)[-1], attention_scores.dtype) # scale attention_scores attention_scores = attention_scores / tf.math.sqrt(dk) if attention_mask is not None: # extended_attention_masks for self attention encoder. extended_attention_mask = attention_mask[:, tf.newaxis, tf.newaxis, :] extended_attention_mask = tf.cast(extended_attention_mask, attention_scores.dtype) extended_attention_mask = (1.0 - extended_attention_mask) * -1e9 attention_scores = attention_scores + extended_attention_mask # TODO # frames_num = tf.shape(attention_mask)[-1] # local_attention_mask = tf.cond(tf.greater(frames_num, self.half_win + 1), # lambda: self._local_attention_mask(frames_num), # lambda: tf.ones([frames_num, frames_num], tf.float32)) # local_attention_mask = (1.0 - local_attention_mask) * -1e9 # attention_scores = attention_scores + local_attention_mask # Normalize the attention scores to probabilities. attention_probs = tf.nn.softmax(attention_scores, axis=-1) attention_probs = self.dropout(attention_probs, training=training) context_layer = tf.matmul(attention_probs, value_layer) context_layer = tf.transpose(context_layer, perm=[0, 2, 1, 3]) context_layer = tf.reshape(context_layer, (batch_size, -1, self.all_head_size)) outputs = ( (context_layer, attention_probs) if self.output_attentions else (context_layer,) ) return outputs class TFFastSpeechSelfOutput(tf.keras.layers.Layer): """Fastspeech output of self attention module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.dense = tf.keras.layers.Dense( config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense", ) self.LayerNorm = tf.keras.layers.LayerNormalization( epsilon=config.layer_norm_eps, name="LayerNorm" ) self.dropout = tf.keras.layers.Dropout(config.hidden_dropout_prob) def call(self, inputs, training=False): """Call logic.""" hidden_states, input_tensor = inputs hidden_states = self.dense(hidden_states) hidden_states = self.dropout(hidden_states, training=training) hidden_states = self.LayerNorm(hidden_states + input_tensor) return hidden_states class TFFastSpeechAttention(tf.keras.layers.Layer): """Fastspeech attention module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.self_attention = TFFastSpeechSelfAttention(config, name="self") self.dense_output = TFFastSpeechSelfOutput(config, name="output") def call(self, inputs, training=False): input_tensor, attention_mask = inputs self_outputs = self.self_attention( [input_tensor, attention_mask], training=training ) attention_output = self.dense_output( [self_outputs[0], input_tensor], training=training ) masked_attention_output = attention_output * tf.cast( tf.expand_dims(attention_mask, 2), dtype=attention_output.dtype ) outputs = (masked_attention_output,) + self_outputs[ 1: ] # add attentions if we output them return outputs class TFFastSpeechIntermediate(tf.keras.layers.Layer): """Intermediate representation module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.conv1d_1 = tf.keras.layers.Conv1D( config.intermediate_size, kernel_size=config.intermediate_kernel_size, kernel_initializer=get_initializer(config.initializer_range), padding="same", name="conv1d_1", ) self.conv1d_2 = tf.keras.layers.Conv1D( config.hidden_size, kernel_size=config.intermediate_kernel_size, kernel_initializer=get_initializer(config.initializer_range), padding="same", name="conv1d_2", ) if isinstance(config.hidden_act, str): self.intermediate_act_fn = ACT2FN[config.hidden_act] else: self.intermediate_act_fn = config.hidden_act def call(self, inputs): """Call logic.""" hidden_states, attention_mask = inputs hidden_states = self.conv1d_1(hidden_states) hidden_states = self.intermediate_act_fn(hidden_states) hidden_states = self.conv1d_2(hidden_states) masked_hidden_states = hidden_states * tf.cast( tf.expand_dims(attention_mask, 2), dtype=hidden_states.dtype ) return masked_hidden_states class TFFastSpeechOutput(tf.keras.layers.Layer): """Output module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.LayerNorm = tf.keras.layers.LayerNormalization( epsilon=config.layer_norm_eps, name="LayerNorm" ) self.dropout = tf.keras.layers.Dropout(config.hidden_dropout_prob) def call(self, inputs, training=False): """Call logic.""" hidden_states, input_tensor = inputs hidden_states = self.dropout(hidden_states, training=training) hidden_states = self.LayerNorm(hidden_states + input_tensor) return hidden_states class TFFastSpeechLayer(tf.keras.layers.Layer): """Fastspeech module (FFT module on the paper).""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.attention = TFFastSpeechAttention(config, name="attention") self.intermediate = TFFastSpeechIntermediate(config, name="intermediate") self.bert_output = TFFastSpeechOutput(config, name="output") def call(self, inputs, training=False): """Call logic.""" hidden_states, attention_mask = inputs attention_outputs = self.attention( [hidden_states, attention_mask], training=training ) attention_output = attention_outputs[0] intermediate_output = self.intermediate( [attention_output, attention_mask], training=training ) layer_output = self.bert_output( [intermediate_output, attention_output], training=training ) masked_layer_output = layer_output * tf.cast( tf.expand_dims(attention_mask, 2), dtype=layer_output.dtype ) outputs = (masked_layer_output,) + attention_outputs[ 1: ] # add attentions if we output them return outputs class TFFastSpeechEncoder(tf.keras.layers.Layer): """Fast Speech encoder module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.output_attentions = config.output_attentions self.output_hidden_states = config.output_hidden_states self.layer = [ TFFastSpeechLayer(config, name="layer_._{}".format(i)) for i in range(config.num_hidden_layers) ] def call(self, inputs, training=False): """Call logic.""" hidden_states, attention_mask = inputs all_hidden_states = () all_attentions = () for _, layer_module in enumerate(self.layer): if self.output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) layer_outputs = layer_module( [hidden_states, attention_mask], training=training ) hidden_states = layer_outputs[0] if self.output_attentions: all_attentions = all_attentions + (layer_outputs[1],) # Add last layer if self.output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) outputs = (hidden_states,) if self.output_hidden_states: outputs = outputs + (all_hidden_states,) if self.output_attentions: outputs = outputs + (all_attentions,) return outputs # outputs, (hidden states), (attentions) class TFFastSpeechDecoder(TFFastSpeechEncoder): """Fast Speech decoder module.""" def __init__(self, config, **kwargs): self.is_compatible_encoder = kwargs.pop("is_compatible_encoder", True) super().__init__(config, **kwargs) self.config = config if self.is_compatible_encoder is False: self.project_compatible_decoder = tf.keras.layers.Dense( units=config.hidden_size, name="project_compatible_decoder" ) def call(self, inputs, training=False): hidden_states, encoder_mask = inputs if self.is_compatible_encoder is False: hidden_states = self.project_compatible_decoder(hidden_states) return super().call([hidden_states, encoder_mask], training=training) class TFTacotronPostnet(tf.keras.layers.Layer): """Tacotron-2 postnet.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.conv_batch_norm = [] for i in range(config.n_conv_postnet): conv = tf.keras.layers.Conv1D( filters=config.postnet_conv_filters if i < config.n_conv_postnet - 1 else config.num_mels, kernel_size=config.postnet_conv_kernel_sizes, padding="same", name="conv_._{}".format(i), ) batch_norm = tf.keras.layers.BatchNormalization( axis=-1, name="batch_norm_._{}".format(i) ) self.conv_batch_norm.append((conv, batch_norm)) self.dropout = tf.keras.layers.Dropout( rate=config.postnet_dropout_rate, name="dropout" ) self.activation = [tf.nn.tanh] * (config.n_conv_postnet - 1) + [tf.identity] def call(self, inputs, training=False): """Call logic.""" outputs, mask = inputs extended_mask = tf.cast(tf.expand_dims(mask, axis=2), outputs.dtype) for i, (conv, bn) in enumerate(self.conv_batch_norm): outputs = conv(outputs) outputs = bn(outputs) outputs = self.activation[i](outputs) outputs = self.dropout(outputs, training=training) return outputs * extended_mask # TODO Drop infer trainning=False class TFFastSpeechVariantPredictor(tf.keras.layers.Layer): """FastSpeech variant predictor module.""" def __init__(self, config, sub_name="f0", is_sigmod=False, **kwargs): """Init variables.""" super().__init__(**kwargs) self.is_sigmod = is_sigmod self.conv_layers = [] for i in range(config.num_variant_conv_layers): self.conv_layers.append( tf.keras.layers.Conv1D( config.variant_predictor_filters, config.variant_predictor_kernel_sizes, padding="same", name="{}_conv_._{}".format(sub_name, i), ) ) self.conv_layers.append(tf.keras.layers.Activation(tf.nn.relu)) self.conv_layers.append( tf.keras.layers.LayerNormalization( epsilon=config.layer_norm_eps, name="{}_LayerNorm_._{}".format(sub_name, i) ) ) self.conv_layers.append( tf.keras.layers.Dropout(config.variant_predictor_dropout_probs) ) self.conv_layers_sequence = tf.keras.Sequential(self.conv_layers, name=sub_name) self.output_layer = tf.keras.layers.Dense(1) if self.is_sigmod: self.sigmod_layer = tf.keras.layers.Activation(tf.nn.sigmoid) def call(self, inputs, training=False): """Call logic.""" encoder_hidden_states, attention_mask = inputs attention_mask = tf.cast(tf.expand_dims(attention_mask, 2), encoder_hidden_states.dtype) # mask encoder hidden states masked_encoder_hidden_states = encoder_hidden_states * attention_mask # pass though first layer outputs = self.conv_layers_sequence(masked_encoder_hidden_states) outputs = self.output_layer(outputs) if self.is_sigmod: outputs = self.sigmod_layer(outputs) masked_outputs = outputs * attention_mask return tf.squeeze(masked_outputs, -1) class TFFastSpeechDurationPredictor(tf.keras.layers.Layer): """FastSpeech duration predictor module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.conv_layers = [] for i in range(config.num_duration_conv_layers): self.conv_layers.append( tf.keras.layers.Conv1D( config.duration_predictor_filters, config.duration_predictor_kernel_sizes, padding="same", name="conv_._{}".format(i), ) ) self.conv_layers.append(tf.keras.layers.Activation(tf.nn.relu)) self.conv_layers.append( tf.keras.layers.LayerNormalization( epsilon=config.layer_norm_eps, name="LayerNorm_._{}".format(i) ) ) self.conv_layers.append( tf.keras.layers.Dropout(config.duration_predictor_dropout_probs) ) self.conv_layers_sequence = tf.keras.Sequential(self.conv_layers) self.output_layer = tf.keras.layers.Dense(1) def call(self, inputs, training=False): """Call logic.""" encoder_hidden_states, attention_mask = inputs attention_mask = tf.cast(tf.expand_dims(attention_mask, 2), encoder_hidden_states.dtype) # mask encoder hidden states masked_encoder_hidden_states = encoder_hidden_states * attention_mask # pass though first layer outputs = self.conv_layers_sequence(masked_encoder_hidden_states) outputs = self.output_layer(outputs) masked_outputs = outputs * attention_mask # return tf.squeeze(tf.nn.relu(masked_outputs), -1) # make sure positive value. return tf.squeeze(masked_outputs, -1) class TFFastSpeechLengthRegulator(tf.keras.layers.Layer): """FastSpeech lengthregulator module.""" def __init__(self, config, **kwargs): """Init variables.""" self.enable_tflite_convertible = kwargs.pop("enable_tflite_convertible", False) super().__init__(**kwargs) self.config = config self.addfeatures_num = 0 if config.addfeatures_num > 0: self._compute_coarse_coding_features() self.addfeatures_num = config.addfeatures_num if config.isaddur: self.addfeatures_num += 1 def _compute_coarse_coding_features(self): npoints = 600 x1 = np.linspace(-1.5, 1.5, npoints) x2 = np.linspace(-1.0, 2.0, npoints) x3 = np.linspace(-0.5, 2.5, npoints) x4 = np.linspace(0.0, 3.0, npoints) mu1 = 0.0 mu2 = 0.5 mu3 = 1.0 mu4 = 1.5 sigma = 0.4 self.cc_features0 = tf.convert_to_tensor(scipy.stats.norm.pdf(x1, mu1, sigma), tf.float32) self.cc_features1 = tf.convert_to_tensor(scipy.stats.norm.pdf(x2, mu2, sigma), tf.float32) self.cc_features2 = tf.convert_to_tensor(scipy.stats.norm.pdf(x3, mu3, sigma), tf.float32) self.cc_features3 = tf.convert_to_tensor(scipy.stats.norm.pdf(x4, mu4, sigma), tf.float32) def call(self, inputs, training=False): """Call logic. Args: 1. encoder_hidden_states, Tensor (float32) shape [batch_size, length, hidden_size] 2. durations_gt, Tensor (float32/int32) shape [batch_size, length] """ encoder_hidden_states, durations_gt = inputs outputs, encoder_masks = self._length_regulator( encoder_hidden_states, durations_gt ) return outputs, encoder_masks def _length_regulator(self, encoder_hidden_states, durations_gt): """Length regulator logic.""" sum_durations = tf.reduce_sum(durations_gt, axis=-1) # [batch_size] max_durations = tf.reduce_max(sum_durations) input_shape = tf.shape(encoder_hidden_states) batch_size = input_shape[0] hidden_size = input_shape[-1] # initialize output hidden states and encoder masking. # TODO add tflite_infer for coarse_coding if self.enable_tflite_convertible: # There is only 1 batch in inference, so we don't have to use # `tf.While` op with 3-D output tensor. repeats = durations_gt[0] real_length = tf.reduce_sum(repeats) pad_size = max_durations - real_length # masks : [max_durations] masks = tf.sequence_mask([real_length], max_durations, dtype=tf.int32) repeat_encoder_hidden_states = tf.repeat( encoder_hidden_states[0], repeats=repeats, axis=0 ) repeat_encoder_hidden_states = tf.expand_dims( tf.pad(repeat_encoder_hidden_states, [[0, pad_size], [0, 0]]), 0 ) # [1, max_durations, hidden_size] outputs = repeat_encoder_hidden_states encoder_masks = masks else: outputs = tf.zeros(shape=[0, max_durations, hidden_size + self.addfeatures_num], dtype=encoder_hidden_states.dtype) # outputs = tf.zeros(shape=[0, max_durations, hidden_size], dtype=encoder_hidden_states.dtype) encoder_masks = tf.zeros(shape=[0, max_durations], dtype=tf.int32) def condition( i, batch_size, outputs, encoder_masks, encoder_hidden_states, durations_gt, max_durations, ): return tf.less(i, batch_size) def body( i, batch_size, outputs, encoder_masks, encoder_hidden_states, durations_gt, max_durations, ): ############################### ori ################################## # repeats = durations_gt[i] # real_length = tf.reduce_sum(repeats) # pad_size = max_durations - real_length # masks = tf.sequence_mask([real_length], max_durations, dtype=tf.int32) # repeat_encoder_hidden_states = tf.repeat( # encoder_hidden_states[i], repeats=repeats, axis=0 # ) # repeat_encoder_hidden_states = tf.expand_dims( # tf.pad(repeat_encoder_hidden_states, [[0, pad_size], [0, 0]]), 0 # ) # [1, max_durations, hidden_size] # outputs = tf.concat([outputs, repeat_encoder_hidden_states], axis=0) # encoder_masks = tf.concat([encoder_masks, masks], axis=0) ############################### add duration info ################################## repeats = durations_gt[i] real_length = tf.reduce_sum(repeats) pad_size = max_durations - real_length masks = tf.sequence_mask([real_length], max_durations, dtype=tf.int32) repeat_encoder_hidden_states = tf.repeat( encoder_hidden_states[i], repeats=repeats, axis=0 ) if self.addfeatures_num > 0: # duration sum per phone durdur = tf.repeat(repeats[:, tf.newaxis], repeats=repeats, axis=0) durdur = tf.cast(durdur, encoder_hidden_states.dtype) # acc duration maskbool = tf.sequence_mask(repeats, tf.reduce_max(repeats)) durindex = tf.cumsum(tf.cast(maskbool, encoder_hidden_states.dtype), -1) durindex = tf.boolean_mask(durindex, maskbool)[:, tf.newaxis] # duration/(sum) durindex = (durindex - 1) / durdur # coarse_coding indexs = tf.cast(durindex*100, tf.int32) cc0 = tf.gather(self.cc_features0, 400+indexs) cc1 = tf.gather(self.cc_features1, 300+indexs) cc2 = tf.gather(self.cc_features2, 200+indexs) cc3 = tf.gather(self.cc_features3, 100+indexs) ccc = tf.concat([cc0, cc1, cc2, cc3], axis=-1) if self.config.isaddur: repeat_encoder_hidden_states = tf.concat([repeat_encoder_hidden_states, durdur], -1) repeat_encoder_hidden_states = tf.concat([repeat_encoder_hidden_states, ccc], -1) repeat_encoder_hidden_states = tf.expand_dims( tf.pad(repeat_encoder_hidden_states, [[0, pad_size], [0, 0]]), 0 ) # [1, max_durations, hidden_size] outputs = tf.concat([outputs, repeat_encoder_hidden_states], axis=0) encoder_masks = tf.concat([encoder_masks, masks], axis=0) return [ i + 1, batch_size, outputs, encoder_masks, encoder_hidden_states, durations_gt, max_durations, ] # initialize iteration i. i = tf.constant(0, dtype=tf.int32) _, _, outputs, encoder_masks, _, _, _, = tf.while_loop( condition, body, [ i, batch_size, outputs, encoder_masks, encoder_hidden_states, durations_gt, max_durations, ], shape_invariants=[ i.get_shape(), batch_size.get_shape(), tf.TensorShape( [ None, None, self.config.content_latent_dim, ] ), tf.TensorShape([None, None]), encoder_hidden_states.get_shape(), durations_gt.get_shape(), max_durations.get_shape(), ], ) return outputs, encoder_masks ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/moduls/core2.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 The FastSpeech Authors, The HuggingFace Inc. team and Minh Nguyen (@dathudeptrai) # # 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. """Tensorflow Model modules for FastSpeech.""" import tensorflow as tf from tensorflow_tts.models.moduls.core import * from tensorflow_tts.models.moduls.conditional import ConditionalNormalization class TFFastSpeechConditionalSelfOutput(tf.keras.layers.Layer): """Fastspeech output of self attention module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.dense = tf.keras.layers.Dense( config.hidden_size, kernel_initializer=get_initializer(config.initializer_range), name="dense", ) self.normlayer = ConditionalNormalization(config) self.dropout = tf.keras.layers.Dropout(config.hidden_dropout_prob) def call(self, inputs, training=False): ''' hidden_states: [B, T, C] input_tensor: [B, T, C] conds: [B, 1, T] attention_mask:[B, T] ''' hidden_states, input_tensor, conds, attention_mask = inputs hidden_states = self.dense(hidden_states) hidden_states = self.dropout(hidden_states, training=training) hidden_states = self.normlayer(hidden_states + input_tensor, conds, attention_mask) return hidden_states class TFFastSpeechConditionalAttention(tf.keras.layers.Layer): """Fastspeech attention module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.self_attention = TFFastSpeechSelfAttention(config, name="self") self.dense_output = TFFastSpeechConditionalSelfOutput(config, name="output") def call(self, inputs, training=False): ''' input_tensor: [B, T, C] conds: [B, 1, C'] attention_mask: [B, T] ''' input_tensor, conds, attention_mask = inputs self_outputs = self.self_attention( [input_tensor, attention_mask], training=training ) attention_output = self.dense_output( [self_outputs[0], input_tensor, conds, attention_mask], training=training ) masked_attention_output = attention_output * tf.cast( tf.expand_dims(attention_mask, 2), dtype=attention_output.dtype ) outputs = (masked_attention_output,) + self_outputs[ 1: ] # add attentions if we output them return outputs class TFFastSpeechConditionalOutput(tf.keras.layers.Layer): """Output module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.normlayer = ConditionalNormalization(config) self.dropout = tf.keras.layers.Dropout(config.hidden_dropout_prob) def call(self, inputs, training=False): ''' hidden_states: [B, T, C] input_tensor: [B, T, C] conds: [B, 1, T] attention_mask:[B, T] ''' hidden_states, input_tensor, conds, attention_mask = inputs hidden_states = self.dropout(hidden_states, training=training) hidden_states = self.normlayer(hidden_states + input_tensor, conds, attention_mask) return hidden_states class TFFastSpeechConditionalLayer(tf.keras.layers.Layer): """Fastspeech module (FFT module on the paper).""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.attention = TFFastSpeechConditionalAttention(config, name="attention") self.intermediate = TFFastSpeechIntermediate(config, name="intermediate") self.bert_output = TFFastSpeechConditionalOutput(config, name="output") def call(self, inputs, training=False): ''' hidden_states: [B, T, C] conds: [B, 1, C'] attention_mask: [B, T] ''' hidden_states, conds, attention_mask = inputs attention_outputs = self.attention( [hidden_states, conds, attention_mask], training=training ) attention_output = attention_outputs[0] intermediate_output = self.intermediate( [attention_output, attention_mask], training=training ) layer_output = self.bert_output( [intermediate_output, attention_output, conds, attention_mask], training=training ) masked_layer_output = layer_output * tf.cast( tf.expand_dims(attention_mask, 2), dtype=layer_output.dtype ) outputs = (masked_layer_output,) + attention_outputs[ 1: ] # add attentions if we output them return outputs class TFFastSpeechConditionalEncoder(tf.keras.layers.Layer): """Fast Speech encoder module.""" def __init__(self, config, **kwargs): """Init variables.""" super().__init__(**kwargs) self.output_attentions = config.output_attentions self.output_hidden_states = config.output_hidden_states self.layer = [ TFFastSpeechConditionalLayer(config, name="layer_._{}".format(i)) for i in range(config.num_hidden_layers) ] def call(self, inputs, training=False): ''' hidden_states: [B, T, C] conds: [B, 1, C'] attention_mask: [B, T] ''' hidden_states, conds, attention_mask = inputs all_hidden_states = () all_attentions = () for _, layer_module in enumerate(self.layer): if self.output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) layer_outputs = layer_module( [hidden_states, conds, attention_mask], training=training ) hidden_states = layer_outputs[0] if self.output_attentions: all_attentions = all_attentions + (layer_outputs[1],) # Add last layer if self.output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) outputs = (hidden_states,) if self.output_hidden_states: outputs = outputs + (all_hidden_states,) if self.output_attentions: outputs = outputs + (all_attentions,) return outputs # outputs, (hidden states), (attentions) class TFFastSpeechConditionalDecoder(TFFastSpeechConditionalEncoder): """Fast Speech decoder module.""" def __init__(self, config, **kwargs): self.is_compatible_encoder = kwargs.pop("is_compatible_encoder", True) super().__init__(config, **kwargs) self.config = config if self.is_compatible_encoder is False: self.project_compatible_decoder = tf.keras.layers.Dense( units=config.hidden_size, name="project_compatible_decoder" ) def call(self, inputs, training=False): ''' hidden_states: [B, T, C] conds: [B, 1, C'] encoder_mask: [B, T] ''' hidden_states, conds, encoder_mask = inputs if self.is_compatible_encoder is False: hidden_states = self.project_compatible_decoder(hidden_states) return super().call([hidden_states, conds, encoder_mask], training=training) ================================================ FILE: TensorFlowTTS/tensorflow_tts/models/unetts.py ================================================ import tensorflow as tf import numpy as np from tensorflow_tts.models.moduls.core import ( TFFastSpeechEmbeddings, TFFastSpeechEncoder, TFFastSpeechDecoder, TFTacotronPostnet, TFFastSpeechLengthRegulator, TFFastSpeechVariantPredictor, TFFastSpeechDurationPredictor ) from tensorflow_tts.models.moduls.core2 import TFFastSpeechConditionalDecoder from tensorflow_tts.models.moduls.adain_en_de_code import ( AadINEncoder, AdaINDecoder ) ''' ############################################################################### ############################# Duration ####################################### ############################################################################### ''' class TFUNETTSDuration(tf.keras.Model): def __init__(self, config, **kwargs): """Init layers for UNETTSDuration.""" self.enable_tflite_convertible = kwargs.pop("enable_tflite_convertible", False) super().__init__(**kwargs) self.embeddings = TFFastSpeechEmbeddings(config, name="embeddings") self.encoder = TFFastSpeechEncoder( config.encoder_self_attention_params, name = "encoder" ) self.duration_predictor = TFFastSpeechDurationPredictor( config, name = "duration_predictor" ) self.duration_stat_cal = tf.keras.layers.Dense(4, use_bias=False, kernel_initializer=tf.constant_initializer( [[0.97, 0.01, 0.01, 0.01], [0.01, 0.97, 0.01, 0.01], [0.01, 0.01, 0.97, 0.01], [0.01, 0.01, 0.01, 0.97]] ), kernel_constraint=tf.keras.constraints.NonNeg(), name="duration_stat_cal") self.setup_inference_fn() def _build(self): """Dummy input for building model.""" # fake inputs char_ids = tf.convert_to_tensor([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], tf.int32) duration_stat = tf.convert_to_tensor([[1., 1., 1., 1.]], tf.float32) self(char_ids, duration_stat) def call( self, char_ids, duration_stat, training=False, **kwargs, ): """Call logic.""" attention_mask = tf.math.not_equal(char_ids, 0) sheng_mask = char_ids < 27 yun_mask = char_ids > 26 duration_stat = self.duration_stat_cal(duration_stat) sheng_mean, sheng_std, yun_mean, yun_std = \ duration_stat[:,0][:, None], duration_stat[:,1][:, None], duration_stat[:,2][:, None], duration_stat[:,3][:, None] embedding_output = self.embeddings(char_ids) encoder_output = self.encoder([embedding_output, attention_mask], training=training) last_encoder_hidden_states = encoder_output[0] duration_outputs = self.duration_predictor([last_encoder_hidden_states, attention_mask]) sheng_outputs = duration_outputs * sheng_std + sheng_mean sheng_outputs = sheng_outputs * tf.cast(sheng_mask, tf.float32) yun_outputs = duration_outputs * yun_std + yun_mean yun_outputs = yun_outputs * tf.cast(yun_mask, tf.float32) duration_outputs = sheng_outputs + yun_outputs duration_outputs = tf.nn.relu(duration_outputs * tf.cast(attention_mask, tf.float32)) return duration_outputs def _inference(self, char_ids, duration_stat, **kwargs): """Call logic.""" attention_mask = tf.math.not_equal(char_ids, 0) sheng_mask = char_ids < 27 yun_mask = char_ids > 26 duration_stat = self.duration_stat_cal(duration_stat) sheng_mean, sheng_std, yun_mean, yun_std = \ duration_stat[:,0][:, None], duration_stat[:,1][:, None], duration_stat[:,2][:, None], duration_stat[:,3][:, None] embedding_output = self.embeddings(char_ids, training=False) encoder_output = self.encoder([embedding_output, attention_mask], training=False) last_encoder_hidden_states = encoder_output[0] duration_outputs = self.duration_predictor([last_encoder_hidden_states, attention_mask]) sheng_outputs = duration_outputs * sheng_std + sheng_mean sheng_outputs = sheng_outputs * tf.cast(sheng_mask, tf.float32) yun_outputs = duration_outputs * yun_std + yun_mean yun_outputs = yun_outputs * tf.cast(yun_mask, tf.float32) duration_outputs = sheng_outputs + yun_outputs duration_outputs = tf.nn.relu(duration_outputs * tf.cast(attention_mask, tf.float32)) return duration_outputs def setup_inference_fn(self): self.inference = tf.function( self._inference, experimental_relax_shapes=True, input_signature=[ tf.TensorSpec(shape=[None, None], dtype=tf.int32, name="char_ids"), tf.TensorSpec(shape=[None, None], dtype=tf.float32, name="duration_stat"), ], ) self.inference_tflite = tf.function( self._inference, experimental_relax_shapes=True, input_signature=[ tf.TensorSpec(shape=[1, None], dtype=tf.int32, name="char_ids"), tf.TensorSpec(shape=[1, None], dtype=tf.float32, name="duration_stat"), ], ) ''' ############################################################################### ################################ Acous ######################################## ############################################################################### ''' class ContentEncoder(tf.keras.Model): def __init__(self, config, **kwargs): """Init layers for ContentEncoder.""" self.enable_tflite_convertible = kwargs.pop("enable_tflite_convertible", False) super().__init__(**kwargs) self.embeddings = TFFastSpeechEmbeddings(config, name="embeddings") self.encoder = TFFastSpeechEncoder( config.encoder_self_attention_params, name="encoder" ) self.length_regulator = TFFastSpeechLengthRegulator( config, enable_tflite_convertible = self.enable_tflite_convertible, name = "length_regulator", ) def call(self, char_ids, duration_gts, training=False): attention_mask = tf.math.not_equal(char_ids, 0) embedding_output = self.embeddings(char_ids) encoder_output = self.encoder([embedding_output, attention_mask], training=training) last_encoder_hidden_states = encoder_output[0] length_regulator_outputs, encoder_masks = self.length_regulator( [last_encoder_hidden_states, duration_gts], training=training ) return length_regulator_outputs, encoder_masks class TFUNETTSAcous(tf.keras.Model): """TF UNETTSAcous module.""" def __init__(self, config, **kwargs): """Init layers for UNETTSAcous.""" self.enable_tflite_convertible = kwargs.pop("enable_tflite_convertible", False) super().__init__(**kwargs) self.config = config self.content_encoder = ContentEncoder( config, enable_tflite_convertible=self.enable_tflite_convertible, name="content_encoder" ) self.src_mel_encoder = AadINEncoder(config, name="src_mel_encoder") self.tar_mel_decoder = AdaINDecoder(config, name="tar_mel_decoder") self.setup_inference_fn() def _build(self): """Dummy input for building model.""" # fake inputs char_ids = tf.convert_to_tensor([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], tf.int32) duration_gts = tf.convert_to_tensor([[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]], tf.int32) mel_src = tf.random.normal([1, 30, self.config.num_mels], dtype=tf.float32) self(char_ids, duration_gts, mel_src) def text_encoder_weight_load(self, content_encoder_path): self.content_encoder.load_weights(content_encoder_path) def freezen_encoder(self): self.content_encoder.trainable = False def call( self, char_ids, duration_gts, mel_src, training=False, **kwargs, ): """Call logic.""" content_latents, encoder_masks = self.content_encoder(char_ids, duration_gts, training=False) content_latents = content_latents * tf.cast(tf.expand_dims(encoder_masks, axis=2), content_latents.dtype) content_latent_pred, means, stds = self.src_mel_encoder(mel_src, encoder_masks) content_latent_pred = content_latent_pred * tf.cast(tf.expand_dims(encoder_masks, axis=2), content_latent_pred.dtype) mel_before = self.tar_mel_decoder(content_latents, (content_latent_pred, means, stds), encoder_masks) mel_before = mel_before * tf.cast(tf.expand_dims(encoder_masks, axis=2), mel_before.dtype) return (mel_before, content_latents, content_latent_pred) def _inference(self, char_ids, duration_gts, mel_src, **kwargs): """Call logic.""" content_latents, encoder_masks = self.content_encoder(char_ids, duration_gts, training=False) tmp_masks = tf.ones([tf.shape(mel_src)[0], tf.shape(mel_src)[1]], dtype=tf.bool) _, means, stds = self.src_mel_encoder(mel_src, tmp_masks) mel_before = self.tar_mel_decoder(content_latents, (_, means, stds), encoder_masks) return mel_before, means, stds def extract_dur_pos_embed(self, mel_src): tmp_masks = tf.ones([tf.shape(mel_src)[0], tf.shape(mel_src)[1]], dtype=tf.bool) content_latent_pred, _, _ = self.src_mel_encoder(mel_src, tmp_masks) return content_latent_pred[:, :, -4:] def setup_inference_fn(self): self.inference = tf.function( self._inference, experimental_relax_shapes=True, input_signature=[ tf.TensorSpec(shape=[None, None], dtype=tf.int32, name="char_ids"), tf.TensorSpec(shape=[None, None], dtype=tf.int32, name="duration_gts"), tf.TensorSpec(shape=[None, None, None], dtype=tf.float32, name="mel_src"), ], ) self.inference_tflite = tf.function( self._inference, experimental_relax_shapes=True, input_signature=[ tf.TensorSpec(shape=[1, None], dtype=tf.int32, name="char_ids"), tf.TensorSpec(shape=[1, None], dtype=tf.int32, name="duration_gts"), tf.TensorSpec(shape=[1, None, None], dtype=tf.float32, name="mel_src"), ], ) class TFUNETTSContentPretrain(tf.keras.Model): """UNETTSContentPretrain""" def __init__(self, config, **kwargs): self.enable_tflite_convertible = kwargs.pop("enable_tflite_convertible", False) super().__init__(**kwargs) self.config = config self.content_encoder = ContentEncoder( config, enable_tflite_convertible=self.enable_tflite_convertible, name="content_encoder" ) if self.config.decoder_is_conditional: self.decoder = TFFastSpeechConditionalDecoder( config.decoder_self_attention_conditional_params, is_compatible_encoder = True, name = "decoder", ) else: self.decoder = TFFastSpeechDecoder( config.decoder_self_attention_params, is_compatible_encoder = False, name = "decoder", ) self.mel_dense = tf.keras.layers.Dense(units=config.num_mels, dtype=tf.float32, name="mel_before") self.postnet = TFTacotronPostnet(config=config, dtype=tf.float32, name="postnet") self.setup_inference_fn() def _build(self): """Dummy input for building model.""" # fake inputs char_ids = tf.convert_to_tensor([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], tf.int32) duration_gts = tf.convert_to_tensor([[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]], tf.int32) embed = tf.random.normal([1, 256], dtype=tf.float32) self(char_ids, duration_gts, embed) def content_encoder_weight_save(self, path): self.content_encoder.save_weights(path) def call( self, char_ids, duration_gts, embed, training=False, **kwargs, ): """Call logic.""" content_latents, encoder_masks = self.content_encoder(char_ids, duration_gts, training=training) if self.config.decoder_is_conditional: decoder_output = self.decoder( [content_latents, tf.expand_dims(embed, 1), encoder_masks], training=training, ) else: # TODO frame_num = tf.reduce_max(tf.reduce_sum(duration_gts, 1)) expand_embeds = tf.tile(tf.expand_dims(embed, 1), [1, frame_num, 1]) content_latents = tf.concat([content_latents, expand_embeds], -1) decoder_output = self.decoder( [content_latents, encoder_masks], training=training, ) last_decoder_hidden_states = decoder_output[0] spebap_before = self.mel_dense(last_decoder_hidden_states) spebap_before = spebap_before * tf.cast(tf.expand_dims(encoder_masks, axis=2), spebap_before.dtype) spebap_after = self.postnet([spebap_before, encoder_masks], training=training) + spebap_before outputs = (spebap_before, spebap_after) return outputs def _inference(self, char_ids, duration_gts, embed, **kwargs): """Call logic.""" content_latents, encoder_masks = self.content_encoder(char_ids, duration_gts, training=False) if self.config.decoder_is_conditional: decoder_output = self.decoder( [content_latents, tf.expand_dims(embed, 1), encoder_masks], training=False, ) else: # TODO frame_num = tf.reduce_max(tf.reduce_sum(duration_gts, 1)) expand_embeds = tf.tile(tf.expand_dims(embed, 1), [1, frame_num, 1]) content_latents = tf.concat([content_latents, expand_embeds], -1) decoder_output = self.decoder( [content_latents, encoder_masks], training=False, ) last_decoder_hidden_states = decoder_output[0] spebap_before = self.mel_dense(last_decoder_hidden_states) spebap_before = spebap_before * tf.cast(tf.expand_dims(encoder_masks, axis=2), spebap_before.dtype) spebap_after = self.postnet([spebap_before, encoder_masks], training=False) + spebap_before outputs = (spebap_before, spebap_after) return outputs def setup_inference_fn(self): self.inference = tf.function( self._inference, experimental_relax_shapes=True, input_signature=[ tf.TensorSpec(shape=[None, None], dtype=tf.int32, name="char_ids"), tf.TensorSpec(shape=[None, None], dtype=tf.int32, name="duration_gts"), tf.TensorSpec(shape=[None, None], dtype=tf.float32, name="embed") ], ) self.inference_tflite = tf.function( self._inference, experimental_relax_shapes=True, input_signature=[ tf.TensorSpec(shape=[1, None], dtype=tf.int32, name="char_ids"), tf.TensorSpec(shape=[1, None], dtype=tf.int32, name="duration_gts"), tf.TensorSpec(shape=[1, None], dtype=tf.float32, name="embed") ], ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/optimizers/__init__.py ================================================ from tensorflow_tts.optimizers.adamweightdecay import AdamWeightDecay, WarmUp ================================================ FILE: TensorFlowTTS/tensorflow_tts/optimizers/adamweightdecay.py ================================================ # -*- coding: utf-8 -*- # Copyright 2019 The TensorFlow Authors. 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. """AdamW for training self-attention.""" import re import tensorflow as tf class WarmUp(tf.keras.optimizers.schedules.LearningRateSchedule): """Applys a warmup schedule on a given learning rate decay schedule.""" def __init__( self, initial_learning_rate, decay_schedule_fn, warmup_steps, power=1.0, name=None, ): super(WarmUp, self).__init__() self.initial_learning_rate = initial_learning_rate self.warmup_steps = warmup_steps self.power = power self.decay_schedule_fn = decay_schedule_fn self.name = name def __call__(self, step): with tf.name_scope(self.name or "WarmUp") as name: # Implements polynomial warmup. i.e., if global_step < warmup_steps, the # learning rate will be `global_step/num_warmup_steps * init_lr`. global_step_float = tf.cast(step, tf.float32) warmup_steps_float = tf.cast(self.warmup_steps, tf.float32) warmup_percent_done = global_step_float / warmup_steps_float warmup_learning_rate = self.initial_learning_rate * tf.math.pow( warmup_percent_done, self.power ) return tf.cond( global_step_float < warmup_steps_float, lambda: warmup_learning_rate, lambda: self.decay_schedule_fn(step), name=name, ) def get_config(self): return { "initial_learning_rate": self.initial_learning_rate, "decay_schedule_fn": self.decay_schedule_fn, "warmup_steps": self.warmup_steps, "power": self.power, "name": self.name, } class AdamWeightDecay(tf.keras.optimizers.Adam): """Adam enables L2 weight decay and clip_by_global_norm on gradients. Just adding the square of the weights to the loss function is *not* the correct way of using L2 regularization/weight decay with Adam, since that will interact with the m and v parameters in strange ways. Instead we want ot decay the weights in a manner that doesn't interact with the m/v parameters. This is equivalent to adding the square of the weights to the loss with plain (non-momentum) SGD. """ def __init__( self, learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-7, amsgrad=False, weight_decay_rate=0.0, include_in_weight_decay=None, exclude_from_weight_decay=None, name="AdamWeightDecay", **kwargs ): super(AdamWeightDecay, self).__init__( learning_rate, beta_1, beta_2, epsilon, amsgrad, name, **kwargs ) self.weight_decay_rate = weight_decay_rate self._include_in_weight_decay = include_in_weight_decay self._exclude_from_weight_decay = exclude_from_weight_decay @classmethod def from_config(cls, config): """Creates an optimizer from its config with WarmUp custom object.""" custom_objects = {"WarmUp": WarmUp} return super(AdamWeightDecay, cls).from_config( config, custom_objects=custom_objects ) def _prepare_local(self, var_device, var_dtype, apply_state): super(AdamWeightDecay, self)._prepare_local(var_device, var_dtype, apply_state) apply_state["weight_decay_rate"] = tf.constant( self.weight_decay_rate, name="adam_weight_decay_rate" ) def _decay_weights_op(self, var, learning_rate, apply_state): do_decay = self._do_use_weight_decay(var.name) if do_decay: return var.assign_sub( learning_rate * var * apply_state["weight_decay_rate"], use_locking=self._use_locking, ) return tf.no_op() def apply_gradients(self, grads_and_vars, clip_norm=0.5, **kwargs): grads, tvars = list(zip(*grads_and_vars)) (grads, _) = tf.clip_by_global_norm(grads, clip_norm=clip_norm) return super(AdamWeightDecay, self).apply_gradients(zip(grads, tvars), **kwargs) def _get_lr(self, var_device, var_dtype, apply_state): """Retrieves the learning rate with the given state.""" if apply_state is None: return self._decayed_lr_t[var_dtype], {} apply_state = apply_state or {} coefficients = apply_state.get((var_device, var_dtype)) if coefficients is None: coefficients = self._fallback_apply_state(var_device, var_dtype) apply_state[(var_device, var_dtype)] = coefficients return coefficients["lr_t"], dict(apply_state=apply_state) def _resource_apply_dense(self, grad, var, apply_state=None): lr_t, kwargs = self._get_lr(var.device, var.dtype.base_dtype, apply_state) decay = self._decay_weights_op(var, lr_t, apply_state) with tf.control_dependencies([decay]): return super(AdamWeightDecay, self)._resource_apply_dense( grad, var, **kwargs ) def _resource_apply_sparse(self, grad, var, indices, apply_state=None): lr_t, kwargs = self._get_lr(var.device, var.dtype.base_dtype, apply_state) decay = self._decay_weights_op(var, lr_t, apply_state) with tf.control_dependencies([decay]): return super(AdamWeightDecay, self)._resource_apply_sparse( grad, var, indices, **kwargs ) def get_config(self): config = super(AdamWeightDecay, self).get_config() config.update( {"weight_decay_rate": self.weight_decay_rate,} ) return config def _do_use_weight_decay(self, param_name): """Whether to use L2 weight decay for `param_name`.""" if self.weight_decay_rate == 0: return False if self._include_in_weight_decay: for r in self._include_in_weight_decay: if re.search(r, param_name) is not None: return True if self._exclude_from_weight_decay: for r in self._exclude_from_weight_decay: if re.search(r, param_name) is not None: return False return True ================================================ FILE: TensorFlowTTS/tensorflow_tts/processor/__init__.py ================================================ from tensorflow_tts.processor.base_processor import BaseProcessor from tensorflow_tts.processor.multispk_voiceclone import MultiSPKVoiceCloneProcessor ================================================ FILE: TensorFlowTTS/tensorflow_tts/processor/base_processor.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 TensorFlowTTS Team. # # 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. """Base Processor for all processor.""" import abc import json import os from typing import Dict, List, Union from dataclasses import dataclass, field class DataProcessorError(Exception): pass @dataclass class BaseProcessor(abc.ABC): data_dir: str symbols: List[str] = field(default_factory=list) speakers_map: Dict[str, int] = field(default_factory=dict) train_f_name: str = "train.txt" delimiter: str = "|" positions = { "file": 0, "text": 1, "speaker_name": 2, } # positions of file,text,speaker_name after split line f_extension: str = ".wav" saved_mapper_path: str = None loaded_mapper_path: str = None # extras items: List[List[str]] = field(default_factory=list) # text, wav_path, speaker_name symbol_to_id: Dict[str, int] = field(default_factory=dict) id_to_symbol: Dict[int, str] = field(default_factory=dict) def __post_init__(self): if self.loaded_mapper_path is not None: self._load_mapper(loaded_path=self.loaded_mapper_path) if self.setup_eos_token(): self.add_symbol( self.setup_eos_token() ) # if this eos token not yet present in symbols list. self.eos_id = self.symbol_to_id[self.setup_eos_token()] return if self.symbols.__len__() < 1: raise DataProcessorError("Symbols list is empty but mapper isn't loaded") self.create_symbols() self.create_items() self.create_speaker_map() self.reverse_speaker = {v: k for k, v in self.speakers_map.items()} if self.saved_mapper_path is not None: self._save_mapper(saved_path=self.saved_mapper_path) # processor name. usefull to use it for AutoProcessor self._processor_name = type(self).__name__ if self.setup_eos_token(): self.add_symbol( self.setup_eos_token() ) # if this eos token not yet present in symbols list. self.eos_id = self.symbol_to_id[self.setup_eos_token()] def __getattr__(self, name: str) -> Union[str, int]: if "_id" in name: # map symbol to id return self.symbol_to_id[name.replace("_id", "")] return self.symbol_to_id[name] # map symbol to value def create_speaker_map(self): """ Create speaker map for dataset. """ sp_id = 0 for i in self.items: speaker_name = i[-1] if speaker_name not in self.speakers_map: self.speakers_map[speaker_name] = sp_id sp_id += 1 def get_speaker_id(self, name: str) -> int: return self.speakers_map[name] def get_speaker_name(self, speaker_id: int) -> str: return self.speakers_map[speaker_id] def create_symbols(self): self.symbol_to_id = {s: i for i, s in enumerate(self.symbols)} self.id_to_symbol = {i: s for i, s in enumerate(self.symbols)} def create_items(self): """ Method used to create items from training file items struct example => text, wav_file_path, speaker_name. Note that the speaker_name should be a last. """ with open( os.path.join(self.data_dir, self.train_f_name), mode="r", encoding="utf-8" ) as f: for line in f: parts = line.strip().split(self.delimiter) wav_path = os.path.join(self.data_dir, parts[self.positions["file"]]) wav_path = ( wav_path + self.f_extension if wav_path[-len(self.f_extension) :] != self.f_extension else wav_path ) text = parts[self.positions["text"]] speaker_name = parts[self.positions["speaker_name"]] self.items.append([text, wav_path, speaker_name]) def add_symbol(self, symbol: Union[str, list]): if isinstance(symbol, str): if symbol in self.symbol_to_id: return self.symbols.append(symbol) symbol_id = len(self.symbol_to_id) self.symbol_to_id[symbol] = symbol_id self.id_to_symbol[symbol_id] = symbol elif isinstance(symbol, list): for i in symbol: self.add_symbol(i) else: raise ValueError("A new_symbols must be a string or list of string.") @abc.abstractmethod def get_one_sample(self, item): """Get one sample from dataset items. Args: item: one item in Dataset items. Dataset items may include (raw_text, speaker_id, wav_path, ...) Returns: sample (dict): sample dictionary return all feature used for preprocessing later. """ sample = { "raw_text": None, "text_ids": None, "audio": None, "utt_id": None, "speaker_name": None, "rate": None, } return sample @abc.abstractmethod def text_to_sequence(self, text: str): return [] @abc.abstractmethod def setup_eos_token(self): """Return eos symbol of type string.""" return "eos" def convert_symbols_to_ids(self, symbols: Union[str, list]): sequence = [] if isinstance(symbols, str): sequence.append(self._symbol_to_id[symbols]) return sequence elif isinstance(symbols, list): for s in symbols: if isinstance(s, str): sequence.append(self._symbol_to_id[s]) else: raise ValueError("All elements of symbols must be a string.") else: raise ValueError("A symbols must be a string or list of string.") return sequence def _load_mapper(self, loaded_path: str = None): """ Save all needed mappers to file """ loaded_path = ( os.path.join(self.data_dir, "mapper.json") if loaded_path is None else loaded_path ) with open(loaded_path, "r") as f: data = json.load(f) self.speakers_map = data["speakers_map"] self.symbol_to_id = data["symbol_to_id"] self.id_to_symbol = {int(k): v for k, v in data["id_to_symbol"].items()} self._processor_name = data["processor_name"] # other keys all_data_keys = data.keys() for key in all_data_keys: if key not in ["speakers_map", "symbol_to_id", "id_to_symbol"]: setattr(self, key, data[key]) def _save_mapper(self, saved_path: str = None, extra_attrs_to_save: dict = None): """ Save all needed mappers to file """ saved_path = ( os.path.join(self.data_dir, "mapper.json") if saved_path is None else saved_path ) with open(saved_path, "w") as f: full_mapper = { "symbol_to_id": self.symbol_to_id, "id_to_symbol": self.id_to_symbol, "speakers_map": self.speakers_map, "processor_name": self._processor_name, } if extra_attrs_to_save: full_mapper = {**full_mapper, **extra_attrs_to_save} json.dump(full_mapper, f) ================================================ FILE: TensorFlowTTS/tensorflow_tts/processor/multispk_voiceclone.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 TensorFlowTTS Team. # # 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. """Perform preprocessing and raw feature extraction for Aishell3 dataset.""" import os import re from typing import Dict, List, Union, Tuple, Any from dataclasses import dataclass, field from pypinyin import Style from pypinyin.contrib.neutral_tone import NeutralToneWith5Mixin from pypinyin.converter import DefaultConverter from pypinyin.core import Pinyin from tensorflow_tts.processor import BaseProcessor from tqdm import tqdm from g2p_en import G2p g2p = G2p() _pad = ["pad"] _eos = [None] _pause = ["sil", "#0", "#1", "#3"] CHN_WORD = "#0" ENG_WORD = "#1" PUC_SYM = "#3" _initials = [ "^", "b", "c", "ch", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "sh", "t", "x", "z", "zh", ] _tones = ["1", "2", "3", "4", "5"] _finals = [ "a", "ai", "an", "ang", "ao", "e", "ei", "en", "eng", "er", "i", "ia", "ian", "iang", "iao", "ie", "ii", "iii", "in", "ing", "iong", "iou", "o", "ong", "ou", "u", "ua", "uai", "uan", "uang", "uei", "uen", "ueng", "uo", "v", "van", "ve", "vn", ] AISHELL_CHN_SYMBOLS = _pad + _pause + _initials + [i + j for i in _finals for j in _tones] PINYIN_DICT = { "a": ("^", "a"), "ai": ("^", "ai"), "an": ("^", "an"), "ang": ("^", "ang"), "ao": ("^", "ao"), "ba": ("b", "a"), "bai": ("b", "ai"), "ban": ("b", "an"), "bang": ("b", "ang"), "bao": ("b", "ao"), "be": ("b", "e"), "bei": ("b", "ei"), "ben": ("b", "en"), "beng": ("b", "eng"), "bi": ("b", "i"), "bian": ("b", "ian"), "biao": ("b", "iao"), "bie": ("b", "ie"), "bin": ("b", "in"), "bing": ("b", "ing"), "bo": ("b", "o"), "bu": ("b", "u"), "ca": ("c", "a"), "cai": ("c", "ai"), "can": ("c", "an"), "cang": ("c", "ang"), "cao": ("c", "ao"), "ce": ("c", "e"), "cen": ("c", "en"), "ceng": ("c", "eng"), "cha": ("ch", "a"), "chai": ("ch", "ai"), "chan": ("ch", "an"), "chang": ("ch", "ang"), "chao": ("ch", "ao"), "che": ("ch", "e"), "chen": ("ch", "en"), "cheng": ("ch", "eng"), "chi": ("ch", "iii"), "chong": ("ch", "ong"), "chou": ("ch", "ou"), "chu": ("ch", "u"), "chua": ("ch", "ua"), "chuai": ("ch", "uai"), "chuan": ("ch", "uan"), "chuang": ("ch", "uang"), "chui": ("ch", "uei"), "chun": ("ch", "uen"), "chuo": ("ch", "uo"), "ci": ("c", "ii"), "cong": ("c", "ong"), "cou": ("c", "ou"), "cu": ("c", "u"), "cuan": ("c", "uan"), "cui": ("c", "uei"), "cun": ("c", "uen"), "cuo": ("c", "uo"), "da": ("d", "a"), "dai": ("d", "ai"), "dan": ("d", "an"), "dang": ("d", "ang"), "dao": ("d", "ao"), "de": ("d", "e"), "dei": ("d", "ei"), "den": ("d", "en"), "deng": ("d", "eng"), "di": ("d", "i"), "dia": ("d", "ia"), "dian": ("d", "ian"), "diao": ("d", "iao"), "die": ("d", "ie"), "ding": ("d", "ing"), "diu": ("d", "iou"), "dong": ("d", "ong"), "dou": ("d", "ou"), "du": ("d", "u"), "duan": ("d", "uan"), "dui": ("d", "uei"), "dun": ("d", "uen"), "duo": ("d", "uo"), "e": ("^", "e"), "ei": ("^", "ei"), "en": ("^", "en"), "ng": ("^", "en"), "eng": ("^", "eng"), "er": ("^", "er"), "fa": ("f", "a"), "fan": ("f", "an"), "fang": ("f", "ang"), "fei": ("f", "ei"), "fen": ("f", "en"), "feng": ("f", "eng"), "fo": ("f", "o"), "fou": ("f", "ou"), "fu": ("f", "u"), "ga": ("g", "a"), "gai": ("g", "ai"), "gan": ("g", "an"), "gang": ("g", "ang"), "gao": ("g", "ao"), "ge": ("g", "e"), "gei": ("g", "ei"), "gen": ("g", "en"), "geng": ("g", "eng"), "gong": ("g", "ong"), "gou": ("g", "ou"), "gu": ("g", "u"), "gua": ("g", "ua"), "guai": ("g", "uai"), "guan": ("g", "uan"), "guang": ("g", "uang"), "gui": ("g", "uei"), "gun": ("g", "uen"), "guo": ("g", "uo"), "ha": ("h", "a"), "hai": ("h", "ai"), "han": ("h", "an"), "hang": ("h", "ang"), "hao": ("h", "ao"), "he": ("h", "e"), "hei": ("h", "ei"), "hen": ("h", "en"), "heng": ("h", "eng"), "hong": ("h", "ong"), "hou": ("h", "ou"), "hu": ("h", "u"), "hua": ("h", "ua"), "huai": ("h", "uai"), "huan": ("h", "uan"), "huang": ("h", "uang"), "hui": ("h", "uei"), "hun": ("h", "uen"), "huo": ("h", "uo"), "ji": ("j", "i"), "jia": ("j", "ia"), "jian": ("j", "ian"), "jiang": ("j", "iang"), "jiao": ("j", "iao"), "jie": ("j", "ie"), "jin": ("j", "in"), "jing": ("j", "ing"), "jiong": ("j", "iong"), "jiu": ("j", "iou"), "ju": ("j", "v"), "juan": ("j", "van"), "jue": ("j", "ve"), "jun": ("j", "vn"), "ka": ("k", "a"), "kai": ("k", "ai"), "kan": ("k", "an"), "kang": ("k", "ang"), "kao": ("k", "ao"), "ke": ("k", "e"), "kei": ("k", "ei"), "ken": ("k", "en"), "keng": ("k", "eng"), "kong": ("k", "ong"), "kou": ("k", "ou"), "ku": ("k", "u"), "kua": ("k", "ua"), "kuai": ("k", "uai"), "kuan": ("k", "uan"), "kuang": ("k", "uang"), "kui": ("k", "uei"), "kun": ("k", "uen"), "kuo": ("k", "uo"), "la": ("l", "a"), "lai": ("l", "ai"), "lan": ("l", "an"), "lang": ("l", "ang"), "lao": ("l", "ao"), "le": ("l", "e"), "lei": ("l", "ei"), "leng": ("l", "eng"), "li": ("l", "i"), "lia": ("l", "ia"), "lian": ("l", "ian"), "liang": ("l", "iang"), "liao": ("l", "iao"), "lie": ("l", "ie"), "lin": ("l", "in"), "ling": ("l", "ing"), "liu": ("l", "iou"), "lo": ("l", "o"), "long": ("l", "ong"), "lou": ("l", "ou"), "lu": ("l", "u"), "lv": ("l", "v"), "luan": ("l", "uan"), "lve": ("l", "ve"), "lue": ("l", "ve"), "lun": ("l", "uen"), "luo": ("l", "uo"), "ma": ("m", "a"), "mai": ("m", "ai"), "man": ("m", "an"), "mang": ("m", "ang"), "mao": ("m", "ao"), "me": ("m", "e"), "mei": ("m", "ei"), "men": ("m", "en"), "meng": ("m", "eng"), "mi": ("m", "i"), "mian": ("m", "ian"), "miao": ("m", "iao"), "mie": ("m", "ie"), "min": ("m", "in"), "ming": ("m", "ing"), "miu": ("m", "iou"), "mo": ("m", "o"), "mou": ("m", "ou"), "mu": ("m", "u"), "na": ("n", "a"), "nai": ("n", "ai"), "nan": ("n", "an"), "nang": ("n", "ang"), "nao": ("n", "ao"), "ne": ("n", "e"), "nei": ("n", "ei"), "nen": ("n", "en"), "neng": ("n", "eng"), "ni": ("n", "i"), "nia": ("n", "ia"), "nian": ("n", "ian"), "niang": ("n", "iang"), "niao": ("n", "iao"), "nie": ("n", "ie"), "nin": ("n", "in"), "ning": ("n", "ing"), "niu": ("n", "iou"), "nong": ("n", "ong"), "nou": ("n", "ou"), "nu": ("n", "u"), "nv": ("n", "v"), "nuan": ("n", "uan"), "nve": ("n", "ve"), "nue": ("n", "ve"), "nuo": ("n", "uo"), "o": ("^", "o"), "ou": ("^", "ou"), "pa": ("p", "a"), "pai": ("p", "ai"), "pan": ("p", "an"), "pang": ("p", "ang"), "pao": ("p", "ao"), "pe": ("p", "e"), "pei": ("p", "ei"), "pen": ("p", "en"), "peng": ("p", "eng"), "pi": ("p", "i"), "pian": ("p", "ian"), "piao": ("p", "iao"), "pie": ("p", "ie"), "pin": ("p", "in"), "ping": ("p", "ing"), "po": ("p", "o"), "pou": ("p", "ou"), "pu": ("p", "u"), "qi": ("q", "i"), "qia": ("q", "ia"), "qian": ("q", "ian"), "qiang": ("q", "iang"), "qiao": ("q", "iao"), "qie": ("q", "ie"), "qin": ("q", "in"), "qing": ("q", "ing"), "qiong": ("q", "iong"), "qiu": ("q", "iou"), "qu": ("q", "v"), "quan": ("q", "van"), "que": ("q", "ve"), "qun": ("q", "vn"), "ran": ("r", "an"), "rang": ("r", "ang"), "rao": ("r", "ao"), "re": ("r", "e"), "ren": ("r", "en"), "reng": ("r", "eng"), "ri": ("r", "iii"), "rong": ("r", "ong"), "rou": ("r", "ou"), "ru": ("r", "u"), "rua": ("r", "ua"), "ruan": ("r", "uan"), "rui": ("r", "uei"), "run": ("r", "uen"), "ruo": ("r", "uo"), "sa": ("s", "a"), "sai": ("s", "ai"), "san": ("s", "an"), "sang": ("s", "ang"), "sao": ("s", "ao"), "se": ("s", "e"), "sen": ("s", "en"), "seng": ("s", "eng"), "sha": ("sh", "a"), "shai": ("sh", "ai"), "shan": ("sh", "an"), "shang": ("sh", "ang"), "shao": ("sh", "ao"), "she": ("sh", "e"), "shei": ("sh", "ei"), "shen": ("sh", "en"), "sheng": ("sh", "eng"), "shi": ("sh", "iii"), "shou": ("sh", "ou"), "shu": ("sh", "u"), "shua": ("sh", "ua"), "shuai": ("sh", "uai"), "shuan": ("sh", "uan"), "shuang": ("sh", "uang"), "shui": ("sh", "uei"), "shun": ("sh", "uen"), "shuo": ("sh", "uo"), "si": ("s", "ii"), "song": ("s", "ong"), "sou": ("s", "ou"), "su": ("s", "u"), "suan": ("s", "uan"), "sui": ("s", "uei"), "sun": ("s", "uen"), "suo": ("s", "uo"), "ta": ("t", "a"), "tai": ("t", "ai"), "tan": ("t", "an"), "tang": ("t", "ang"), "tao": ("t", "ao"), "te": ("t", "e"), "tei": ("t", "ei"), "teng": ("t", "eng"), "ti": ("t", "i"), "tian": ("t", "ian"), "tiao": ("t", "iao"), "tie": ("t", "ie"), "ting": ("t", "ing"), "tong": ("t", "ong"), "tou": ("t", "ou"), "tu": ("t", "u"), "tuan": ("t", "uan"), "tui": ("t", "uei"), "tun": ("t", "uen"), "tuo": ("t", "uo"), "wa": ("^", "ua"), "wai": ("^", "uai"), "wan": ("^", "uan"), "wang": ("^", "uang"), "wei": ("^", "uei"), "wen": ("^", "uen"), "weng": ("^", "ueng"), "wo": ("^", "uo"), "wu": ("^", "u"), "xi": ("x", "i"), "xia": ("x", "ia"), "xian": ("x", "ian"), "xiang": ("x", "iang"), "xiao": ("x", "iao"), "xie": ("x", "ie"), "xin": ("x", "in"), "xing": ("x", "ing"), "xiong": ("x", "iong"), "xiu": ("x", "iou"), "xu": ("x", "v"), "xuan": ("x", "van"), "xue": ("x", "ve"), "xun": ("x", "vn"), "ya": ("^", "ia"), "yan": ("^", "ian"), "yang": ("^", "iang"), "yao": ("^", "iao"), "ye": ("^", "ie"), "yi": ("^", "i"), "yin": ("^", "in"), "ying": ("^", "ing"), "yo": ("^", "iou"), "yong": ("^", "iong"), "you": ("^", "iou"), "yu": ("^", "v"), "yuan": ("^", "van"), "yue": ("^", "ve"), "yun": ("^", "vn"), "za": ("z", "a"), "zai": ("z", "ai"), "zan": ("z", "an"), "zang": ("z", "ang"), "zao": ("z", "ao"), "ze": ("z", "e"), "zei": ("z", "ei"), "zen": ("z", "en"), "zeng": ("z", "eng"), "zha": ("zh", "a"), "zhai": ("zh", "ai"), "zhan": ("zh", "an"), "zhang": ("zh", "ang"), "zhao": ("zh", "ao"), "zhe": ("zh", "e"), "zhei": ("zh", "ei"), "zhen": ("zh", "en"), "zheng": ("zh", "eng"), "zhi": ("zh", "iii"), "zhong": ("zh", "ong"), "zhou": ("zh", "ou"), "zhu": ("zh", "u"), "zhua": ("zh", "ua"), "zhuai": ("zh", "uai"), "zhuan": ("zh", "uan"), "zhuang": ("zh", "uang"), "zhui": ("zh", "uei"), "zhun": ("zh", "uen"), "zhuo": ("zh", "uo"), "zi": ("z", "ii"), "zong": ("z", "ong"), "zou": ("z", "ou"), "zu": ("z", "u"), "zuan": ("z", "uan"), "zui": ("z", "uei"), "zun": ("z", "uen"), "zuo": ("z", "uo"), } zh_pattern = re.compile(r"([\u4e00-\u9fa5]+)") en_pattern = re.compile(r"([a-zA-Z]+)") def is_zh(word): global zh_pattern match = zh_pattern.search(word) return match is not None def is_en(word): global en_pattern match = en_pattern.search(word) return match is not None class MyConverter(NeutralToneWith5Mixin, DefaultConverter): pass @dataclass class MultiSPKVoiceCloneProcessor(BaseProcessor): pinyin_dict : Dict[str, Tuple[str, str]] = field(default_factory=lambda: PINYIN_DICT) cleaner_names : str = None target_rate : int = 16000 speaker_name : str = "multispk_voiceclone" none_pinyin_symnum : int = len(_pad + _pause) during_train : bool = False f0_train : bool = False all_train : bool = False mfaed_txt : str = "" wavs_dir : str = "" embed_dir : str = "" spkinfo_dir : str = "" unseen_dir : str = "" def __post_init__(self): self.pinyin_parser = self.get_pinyin_parser() if self.spkinfo_dir: self.create_speaker_info() if self.unseen_dir: self.create_unseen_speaker() super().__post_init__() def setup_eos_token(self): return _eos[0] def create_speaker_info(self): self.spk2sex_dict = {} with open(self.spkinfo_dir, "r") as fr: lines = fr.readlines() for line in lines: spk_name, _, sex, *_ = line.strip().split() if spk_name not in self.spk2sex_dict.keys(): self.spk2sex_dict[spk_name] = sex print("*"*50) print(f"Have {len(self.spk2sex_dict)} Speakers") print("*"*50) def create_unseen_speaker(self): self.unseen_spk = [] with open(self.unseen_dir, "r") as fr: lines = fr.readlines() for line in lines: self.unseen_spk.append(line.strip()) self.unseen_spk_num = 0 print("*"*50) print(f"Have {len(self.unseen_spk)} UNSeen Speakers") print("*"*50) # TODO now just support for aishell3 def create_items(self): items = [] if self.data_dir: with open( os.path.join(self.data_dir, self.mfaed_txt), encoding="utf-8", ) as ttf: lines = ttf.readlines() for line in tqdm(lines): filename, phoneseq, durseq = line.strip().split("|") spkname = filename[:7] if filename[0] == "S" else filename.split("_")[0] if self.spkinfo_dir and self.spk2sex_dict[spkname] == "male": continue # if self.unseen_dir and (spkname in self.unseen_spk or "_" in filename): if self.unseen_dir and spkname in self.unseen_spk: self.unseen_spk_num += 1 continue wav_path = os.path.join(self.data_dir, self.wavs_dir, f"{spkname}", f"{filename}.wav") embed_path = os.path.join(self.data_dir, self.embed_dir, f"{filename}-embed.npy") if ((self.during_train or self.f0_train) and os.path.exists(wav_path)) or \ (self.all_train and os.path.exists(wav_path) and os.path.exists(embed_path)): try: text_ids = [self.symbol_to_id[phone] for phone in phoneseq.split()] durs = [int(dur) for dur in durseq.split()] embed_path = embed_path if self.all_train else None assert len(text_ids) == len(durs) except Exception: print("error: generate sequence ids", filename) continue items.append([spkname, filename, wav_path, text_ids, durs, embed_path]) self.items = items print("*"*50) print(f"Have {len(self.items)} samples") if self.unseen_dir: print(f"Have {self.unseen_spk_num} UNSeen samples") print("*"*50) def get_phoneme_from_char_and_pinyin(self, txt, pinyin): txt = txt.replace("'", "") txt = txt.replace("-", "") phrase_list = re.split("#\d", txt) rhythms_list = re.findall("#\d", txt) pinyin_index = 0 last_phrase_type = 'chn' result = ["sil"] phrase = phrase_list[0] if is_zh(phrase): length = len(phrase) for pinyin_one in pinyin[pinyin_index:pinyin_index+length]: tone = pinyin_one[-1] a1, a2 = self.pinyin_dict[pinyin_one[:-1]] result.append(a1) result.append(a2+tone) pinyin_index += length last_phrase_type = 'chn' elif is_en(phrase): pinyin_one = pinyin[pinyin_index] result += [ph[:-1] if ph[-1].isdigit() else ph for ph in pinyin_one.split("*")] pinyin_index += 1 last_phrase_type = 'eng' # TODO elif phrase == "" or phrase == " ": pass else: print("Error: processed text ->", txt) assert False phrase_list = phrase_list[1:] for rhythm, phrase in zip(rhythms_list, phrase_list): if is_zh(phrase): if rhythm == "#3": result.append(PUC_SYM) elif last_phrase_type == 'eng': result.append(ENG_WORD) else: result.append(CHN_WORD) length = len(phrase) for pinyin_one in pinyin[pinyin_index:pinyin_index+length]: tone = pinyin_one[-1] a1, a2 = self.pinyin_dict[pinyin_one[:-1]] result.append(a1) result.append(a2+tone) pinyin_index += length last_phrase_type = 'chn' elif is_en(phrase): if rhythm == "#3": result.append(PUC_SYM) else: result.append(ENG_WORD) pinyin_one = pinyin[pinyin_index] result += [ph[:-1] if ph[-1].isdigit() else ph for ph in pinyin_one.split("*")] pinyin_index += 1 last_phrase_type = 'eng' # TODO elif phrase == "" or phrase == " ": continue else: print("Error: processed text ->", txt) assert False # result.append(PUC_SYM) result.append("sil") assert pinyin_index == len(pinyin) return result def get_one_sample(self, item): spkname, filename, wav_path, text_ids, durs, embed_path = item sample = { "speaker_name": spkname, "filename" : filename, "wav_path" : wav_path, "text_ids" : text_ids, "durs" : durs, "embed_path" : embed_path, "rate" : self.target_rate, } return sample def get_pinyin_parser(self): my_pinyin = Pinyin(MyConverter()) pinyin = my_pinyin.pinyin return pinyin def text_to_sequence(self, text, inference=False): if inference: pinyin = self.pinyin_parser(text, style=Style.TONE3) # print(pinyin) new_pinyin = [] for x in pinyin: x = "".join(x) if "#" not in x: new_pinyin.append(x) else: if len(x) == 2: continue else: eng_list = re.split("#\d", x) if eng_list[0] == "": eng_list = eng_list[1:] if eng_list[-1] == "": eng_list = eng_list[:-1] for e in eng_list: new_pinyin.append("*".join(g2p(e))) print(new_pinyin) phonemes = self.get_phoneme_from_char_and_pinyin(text, new_pinyin) text = " ".join(phonemes) print(f"phoneme seq: {text}") sequence = [] #print("text",text) for symbol in text.split(): idx = self.symbol_to_id[symbol] sequence.append(idx) return sequence def create_speaker_map(self): pass ================================================ FILE: TensorFlowTTS/tensorflow_tts/trainers/__init__.py ================================================ from tensorflow_tts.trainers.base_trainer import GanBasedTrainer, Seq2SeqBasedTrainer ================================================ FILE: TensorFlowTTS/tensorflow_tts/trainers/base_trainer.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Based Trainer.""" import abc import logging import os import tensorflow as tf from tqdm import tqdm import random import numpy as np SEED = 2021 random.seed(SEED) np.random.seed(SEED) tf.random.set_seed(SEED) class BasedTrainer(metaclass=abc.ABCMeta): """Customized trainer module for all models.""" def __init__(self, steps, epochs, config): self.steps = steps self.epochs = epochs self.config = config self.finish_train = False self.writer = tf.summary.create_file_writer(config["outdir"]) self.train_data_loader = None self.eval_data_loader = None self.train_metrics = None self.eval_metrics = None self.list_metrics_name = None def init_train_eval_metrics(self, list_metrics_name): """Init train and eval metrics to save it to tensorboard.""" self.train_metrics = {} self.eval_metrics = {} for name in list_metrics_name: self.train_metrics.update( {name: tf.keras.metrics.Mean(name="train_" + name, dtype=tf.float32)} ) self.eval_metrics.update( {name: tf.keras.metrics.Mean(name="eval_" + name, dtype=tf.float32)} ) def reset_states_train(self): """Reset train metrics after save it to tensorboard.""" for metric in self.train_metrics.keys(): self.train_metrics[metric].reset_states() def reset_states_eval(self): """Reset eval metrics after save it to tensorboard.""" for metric in self.eval_metrics.keys(): self.eval_metrics[metric].reset_states() def update_train_metrics(self, dict_metrics_losses): for name, value in dict_metrics_losses.items(): self.train_metrics[name].update_state(value) def update_eval_metrics(self, dict_metrics_losses): for name, value in dict_metrics_losses.items(): self.eval_metrics[name].update_state(value) def set_train_data_loader(self, train_dataset): """Set train data loader (MUST).""" self.train_data_loader = train_dataset def get_train_data_loader(self): """Get train data loader.""" return self.train_data_loader def set_eval_data_loader(self, eval_dataset): """Set eval data loader (MUST).""" self.eval_data_loader = eval_dataset def get_eval_data_loader(self): """Get eval data loader.""" return self.eval_data_loader @abc.abstractmethod def compile(self): pass @abc.abstractmethod def create_checkpoint_manager(self, saved_path=None, max_to_keep=10): """Create checkpoint management.""" pass def run(self): """Run training.""" self.tqdm = tqdm( initial=self.steps, total=self.config["train_max_steps"], desc="[train]" ) while True: self._train_epoch() if self.finish_train: break self.tqdm.close() logging.info("Finish training.") @abc.abstractmethod def save_checkpoint(self): """Save checkpoint.""" pass @abc.abstractmethod def load_checkpoint(self, pretrained_path): """Load checkpoint.""" pass def _train_epoch(self): """Train model one epoch.""" for train_steps_per_epoch, batch in enumerate(self.train_data_loader, 1): # one step training self._train_step(batch) # check interval self._check_log_interval() self._check_eval_interval() self._check_save_interval() # check wheter training is finished if self.finish_train: return # update self.epochs += 1 self.train_steps_per_epoch = train_steps_per_epoch logging.info( f"(Steps: {self.steps}) Finished {self.epochs} epoch training " f"({self.train_steps_per_epoch} steps per epoch)." ) @abc.abstractmethod def _eval_epoch(self): """One epoch evaluation.""" pass @abc.abstractmethod def _train_step(self, batch): """One step training.""" pass @abc.abstractmethod def _check_log_interval(self): """Save log interval.""" pass @abc.abstractmethod def fit(self): pass def _check_eval_interval(self): """Evaluation interval step.""" if self.steps % self.config["eval_interval_steps"] == 0: self._eval_epoch() def _check_save_interval(self): """Save interval checkpoint.""" if self.steps % self.config["save_interval_steps"] == 0: self.save_checkpoint() logging.info(f"Successfully saved checkpoint @ {self.steps} steps.") def generate_and_save_intermediate_result(self, batch): """Generate and save intermediate result.""" pass def _write_to_tensorboard(self, list_metrics, stage="train"): """Write variables to tensorboard.""" with self.writer.as_default(): for key, value in list_metrics.items(): tf.summary.scalar(stage + "/" + key, value.result(), step=self.steps) self.writer.flush() class GanBasedTrainer(BasedTrainer): """Customized trainer module for GAN TTS training (MelGAN, GAN-TTS, ParallelWaveGAN).""" def __init__( self, steps, epochs, config, strategy, is_generator_mixed_precision=False, is_discriminator_mixed_precision=False, ): """Initialize trainer. Args: steps (int): Initial global steps. epochs (int): Initial global epochs. config (dict): Config dict loaded from yaml format configuration file. """ super().__init__(steps, epochs, config) self._is_generator_mixed_precision = is_generator_mixed_precision self._is_discriminator_mixed_precision = is_discriminator_mixed_precision self._strategy = strategy self._already_apply_input_signature = False def init_train_eval_metrics(self, list_metrics_name): with self._strategy.scope(): super().init_train_eval_metrics(list_metrics_name) def get_n_gpus(self): return self._strategy.num_replicas_in_sync def _get_train_element_signature(self): return self.train_data_loader.element_spec def _get_eval_element_signature(self): return self.eval_data_loader.element_spec def set_gen_model(self, generator_model): """Set generator class model (MUST).""" self._generator = generator_model def get_gen_model(self): """Get generator model.""" return self._generator def set_dis_model(self, discriminator_model): """Set discriminator class model (MUST).""" self._discriminator = discriminator_model def get_dis_model(self): """Get discriminator model.""" return self._discriminator def set_gen_optimizer(self, generator_optimizer): """Set generator optimizer (MUST).""" self._gen_optimizer = generator_optimizer if self._is_generator_mixed_precision: self._gen_optimizer = tf.keras.mixed_precision.experimental.LossScaleOptimizer( self._gen_optimizer, "dynamic" ) def get_gen_optimizer(self): """Get generator optimizer.""" return self._gen_optimizer def set_dis_optimizer(self, discriminator_optimizer): """Set discriminator optimizer (MUST).""" self._dis_optimizer = discriminator_optimizer if self._is_discriminator_mixed_precision: self._dis_optimizer = tf.keras.mixed_precision.experimental.LossScaleOptimizer( self._dis_optimizer, "dynamic" ) def get_dis_optimizer(self): """Get discriminator optimizer.""" return self._dis_optimizer def compile(self, gen_model, dis_model, gen_optimizer, dis_optimizer): self.set_gen_model(gen_model) self.set_dis_model(dis_model) self.set_gen_optimizer(gen_optimizer) self.set_dis_optimizer(dis_optimizer) def _train_step(self, batch): if self._already_apply_input_signature is False: train_element_signature = self._get_train_element_signature() eval_element_signature = self._get_eval_element_signature() self.one_step_forward = tf.function( self._one_step_forward, input_signature=[train_element_signature] ) self.one_step_evaluate = tf.function( self._one_step_evaluate, input_signature=[eval_element_signature] ) self.one_step_predict = tf.function( self._one_step_predict, input_signature=[eval_element_signature] ) self._already_apply_input_signature = True # run one_step_forward self.one_step_forward(batch) # update counts self.steps += 1 self.tqdm.update(1) self._check_train_finish() def _one_step_forward(self, batch): per_replica_losses = self._strategy.run( self._one_step_forward_per_replica, args=(batch,) ) return self._strategy.reduce( tf.distribute.ReduceOp.SUM, per_replica_losses, axis=None ) @abc.abstractmethod def compute_per_example_generator_losses(self, batch, outputs): """Compute per example generator losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ per_example_losses = 0.0 dict_metrics_losses = {} return per_example_losses, dict_metrics_losses @abc.abstractmethod def compute_per_example_discriminator_losses(self, batch, gen_outputs): """Compute per example discriminator losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ per_example_losses = 0.0 dict_metrics_losses = {} return per_example_losses, dict_metrics_losses def _one_step_forward_per_replica(self, batch): per_replica_gen_losses = 0.0 per_replica_dis_losses = 0.0 # one step generator. with tf.GradientTape() as g_tape: outputs = self._generator(**batch, training=True) ( per_example_losses, dict_metrics_losses, ) = self.compute_per_example_generator_losses(batch, outputs) per_replica_gen_losses = tf.nn.compute_average_loss( per_example_losses, global_batch_size=self.config["batch_size"] * self.get_n_gpus(), ) if self._is_generator_mixed_precision: scaled_per_replica_gen_losses = self._gen_optimizer.get_scaled_loss( per_replica_gen_losses ) if self._is_generator_mixed_precision: scaled_gradients = g_tape.gradient( scaled_per_replica_gen_losses, self._generator.trainable_variables ) gradients = self._gen_optimizer.get_unscaled_gradients(scaled_gradients) else: gradients = g_tape.gradient( per_replica_gen_losses, self._generator.trainable_variables ) self._gen_optimizer.apply_gradients( zip(gradients, self._generator.trainable_variables) ) # accumulate loss into metrics self.update_train_metrics(dict_metrics_losses) # one step discriminator # recompute y_hat after 1 step generator for discriminator training. if self.steps >= self.config["discriminator_train_start_steps"]: with tf.GradientTape() as d_tape: ( per_example_losses, dict_metrics_losses, ) = self.compute_per_example_discriminator_losses( batch, self._generator(**batch) ) per_replica_dis_losses = tf.nn.compute_average_loss( per_example_losses, global_batch_size=self.config["batch_size"] * self.get_n_gpus(), ) if self._is_discriminator_mixed_precision: scaled_per_replica_dis_losses = self._dis_optimizer.get_scaled_loss( per_replica_dis_losses ) if self._is_discriminator_mixed_precision: scaled_gradients = d_tape.gradient( scaled_per_replica_dis_losses, self._discriminator.trainable_variables, ) gradients = self._dis_optimizer.get_unscaled_gradients(scaled_gradients) else: gradients = d_tape.gradient( per_replica_dis_losses, self._discriminator.trainable_variables ) self._dis_optimizer.apply_gradients( zip(gradients, self._discriminator.trainable_variables) ) # accumulate loss into metrics self.update_train_metrics(dict_metrics_losses) return per_replica_gen_losses + per_replica_dis_losses def _eval_epoch(self): """Evaluate model one epoch.""" logging.info(f"(Steps: {self.steps}) Start evaluation.") # calculate loss for each batch for eval_steps_per_epoch, batch in enumerate( tqdm(self.eval_data_loader, desc="[eval]"), 1 ): # eval one step self.one_step_evaluate(batch) if eval_steps_per_epoch <= self.config["num_save_intermediate_results"]: # save intermedia self.generate_and_save_intermediate_result(batch) logging.info( f"(Steps: {self.steps}) Finished evaluation " f"({eval_steps_per_epoch} steps per epoch)." ) # average loss for key in self.eval_metrics.keys(): logging.info( f"(Steps: {self.steps}) eval_{key} = {self.eval_metrics[key].result():.4f}." ) # record self._write_to_tensorboard(self.eval_metrics, stage="eval") # reset self.reset_states_eval() def _one_step_evaluate_per_replica(self, batch): ################################################ # one step generator. outputs = self._generator(**batch, training=False) _, dict_metrics_losses = self.compute_per_example_generator_losses( batch, outputs ) # accumulate loss into metrics self.update_eval_metrics(dict_metrics_losses) ################################################ # one step discriminator if self.steps >= self.config["discriminator_train_start_steps"]: _, dict_metrics_losses = self.compute_per_example_discriminator_losses( batch, outputs ) # accumulate loss into metrics self.update_eval_metrics(dict_metrics_losses) ################################################ def _one_step_evaluate(self, batch): self._strategy.run(self._one_step_evaluate_per_replica, args=(batch,)) def _one_step_predict_per_replica(self, batch): outputs = self._generator(**batch, training=False) return outputs def _one_step_predict(self, batch): outputs = self._strategy.run(self._one_step_predict_per_replica, args=(batch,)) return outputs @abc.abstractmethod def generate_and_save_intermediate_result(self, batch): return def create_checkpoint_manager(self, saved_path=None, max_to_keep=10): """Create checkpoint management.""" if saved_path is None: saved_path = self.config["outdir"] + "/checkpoints/" os.makedirs(saved_path, exist_ok=True) self.saved_path = saved_path self.ckpt = tf.train.Checkpoint( steps=tf.Variable(1), epochs=tf.Variable(1), gen_optimizer=self.get_gen_optimizer(), dis_optimizer=self.get_dis_optimizer(), ) self.ckp_manager = tf.train.CheckpointManager( self.ckpt, saved_path, max_to_keep=max_to_keep ) def save_checkpoint(self): """Save checkpoint.""" self.ckpt.steps.assign(self.steps) self.ckpt.epochs.assign(self.epochs) self.ckp_manager.save(checkpoint_number=self.steps) self._generator.save_weights( self.saved_path + "generator-{}.h5".format(self.steps) ) self._discriminator.save_weights( self.saved_path + "discriminator-{}.h5".format(self.steps) ) def load_checkpoint(self, pretrained_path): """Load checkpoint.""" self.ckpt.restore(pretrained_path) self.steps = self.ckpt.steps.numpy() self.epochs = self.ckpt.epochs.numpy() self._gen_optimizer = self.ckpt.gen_optimizer # re-assign iterations (global steps) for gen_optimizer. self._gen_optimizer.iterations.assign(tf.cast(self.steps, tf.int64)) # re-assign iterations (global steps) for dis_optimizer. try: discriminator_train_start_steps = self.config[ "discriminator_train_start_steps" ] discriminator_train_start_steps = tf.math.maximum( 0, discriminator_train_start_steps - self.steps ) except Exception: discriminator_train_start_steps = self.steps self._dis_optimizer = self.ckpt.dis_optimizer self._dis_optimizer.iterations.assign( tf.cast(discriminator_train_start_steps, tf.int64) ) # load weights. self._generator.load_weights( self.saved_path + "generator-{}.h5".format(self.steps) ) self._discriminator.load_weights( self.saved_path + "discriminator-{}.h5".format(self.steps) ) def _check_train_finish(self): """Check training finished.""" if self.steps >= self.config["train_max_steps"]: self.finish_train = True if ( self.steps != 0 and self.steps == self.config["discriminator_train_start_steps"] ): self.finish_train = True logging.info( f"Finished training only generator at {self.steps}steps, pls resume and continue training." ) def _check_log_interval(self): """Log to tensorboard.""" if self.steps % self.config["log_interval_steps"] == 0: for metric_name in self.list_metrics_name: logging.info( f"(Step: {self.steps}) train_{metric_name} = {self.train_metrics[metric_name].result():.4f}." ) self._write_to_tensorboard(self.train_metrics, stage="train") # reset self.reset_states_train() def fit(self, train_data_loader, valid_data_loader, saved_path, resume=None): self.set_train_data_loader(train_data_loader) self.set_eval_data_loader(valid_data_loader) self.train_data_loader = self._strategy.experimental_distribute_dataset( self.train_data_loader ) self.eval_data_loader = self._strategy.experimental_distribute_dataset( self.eval_data_loader ) with self._strategy.scope(): self.create_checkpoint_manager(saved_path=saved_path, max_to_keep=10000) if len(resume) > 1: self.load_checkpoint(resume) logging.info(f"Successfully resumed from {resume}.") self.run() class Seq2SeqBasedTrainer(BasedTrainer, metaclass=abc.ABCMeta): """Customized trainer module for Seq2Seq TTS training (Tacotron, FastSpeech).""" def __init__( self, steps, epochs, config, strategy, is_mixed_precision=False, ): """Initialize trainer. Args: steps (int): Initial global steps. epochs (int): Initial global epochs. config (dict): Config dict loaded from yaml format configuration file. strategy (tf.distribute): Strategy for distributed training. is_mixed_precision (bool): Use mixed_precision training or not. """ super().__init__(steps, epochs, config) self._is_mixed_precision = is_mixed_precision self._strategy = strategy # check if we already apply input_signature for train_step. self._already_apply_input_signature = False def init_train_eval_metrics(self, list_metrics_name): with self._strategy.scope(): super().init_train_eval_metrics(list_metrics_name) def set_model(self, model): """Set generator class model (MUST).""" self._model = model def get_model(self): """Get generator model.""" return self._model def set_optimizer(self, optimizer): """Set optimizer (MUST).""" self._optimizer = optimizer if self._is_mixed_precision: self._optimizer = tf.keras.mixed_precision.experimental.LossScaleOptimizer( self._optimizer, "dynamic" ) def get_optimizer(self): """Get optimizer.""" return self._optimizer def get_n_gpus(self): return self._strategy.num_replicas_in_sync def compile(self, model, optimizer): self.set_model(model) self.set_optimizer(optimizer) def _get_train_element_signature(self): return self.train_data_loader.element_spec def _get_eval_element_signature(self): return self.eval_data_loader.element_spec def _train_step(self, batch): if self._already_apply_input_signature is False: train_element_signature = self._get_train_element_signature() eval_element_signature = self._get_eval_element_signature() self.one_step_forward = tf.function( self._one_step_forward, input_signature=[train_element_signature] ) self.one_step_evaluate = tf.function( self._one_step_evaluate, input_signature=[eval_element_signature] ) self.one_step_predict = tf.function( self._one_step_predict, input_signature=[eval_element_signature] ) self._already_apply_input_signature = True # run one_step_forward self.one_step_forward(batch) # update counts self.steps += 1 self.tqdm.update(1) self._check_train_finish() def _one_step_forward(self, batch): per_replica_losses = self._strategy.run( self._one_step_forward_per_replica, args=(batch,) ) return self._strategy.reduce( tf.distribute.ReduceOp.SUM, per_replica_losses, axis=None ) def _one_step_forward_per_replica(self, batch): with tf.GradientTape() as tape: outputs = self._model(**batch, training=True) per_example_losses, dict_metrics_losses = self.compute_per_example_losses( batch, outputs ) per_replica_losses = tf.nn.compute_average_loss( per_example_losses, global_batch_size=self.config["batch_size"] * self.get_n_gpus(), ) if self._is_mixed_precision: scaled_per_replica_losses = self._optimizer.get_scaled_loss( per_replica_losses ) if self._is_mixed_precision: scaled_gradients = tape.gradient( scaled_per_replica_losses, self._model.trainable_variables ) gradients = self._optimizer.get_unscaled_gradients(scaled_gradients) else: gradients = tape.gradient( per_replica_losses, self._model.trainable_variables ) self._optimizer.apply_gradients( zip(gradients, self._model.trainable_variables), 1.0 ) # accumulate loss into metrics self.update_train_metrics(dict_metrics_losses) return per_replica_losses @abc.abstractmethod def compute_per_example_losses(self, batch, outputs): """Compute per example losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ per_example_losses = 0.0 dict_metrics_losses = {} return per_example_losses, dict_metrics_losses def _eval_epoch(self): """Evaluate model one epoch.""" logging.info(f"(Steps: {self.steps}) Start evaluation.") # calculate loss for each batch for eval_steps_per_epoch, batch in enumerate( tqdm(self.eval_data_loader, desc="[eval]"), 1 ): # eval one step self.one_step_evaluate(batch) if eval_steps_per_epoch <= self.config["num_save_intermediate_results"]: # save intermedia self.generate_and_save_intermediate_result(batch) logging.info( f"(Steps: {self.steps}) Finished evaluation " f"({eval_steps_per_epoch} steps per epoch)." ) # average loss for key in self.eval_metrics.keys(): logging.info( f"(Steps: {self.steps}) eval_{key} = {self.eval_metrics[key].result():.4f}." ) # record self._write_to_tensorboard(self.eval_metrics, stage="eval") # reset self.reset_states_eval() def _one_step_evaluate_per_replica(self, batch): outputs = self._model(**batch, training=False) _, dict_metrics_losses = self.compute_per_example_losses(batch, outputs) self.update_eval_metrics(dict_metrics_losses) def _one_step_evaluate(self, batch): self._strategy.run(self._one_step_evaluate_per_replica, args=(batch,)) def _one_step_predict_per_replica(self, batch): outputs = self._model(**batch, training=False) return outputs def _one_step_predict(self, batch): outputs = self._strategy.run(self._one_step_predict_per_replica, args=(batch,)) return outputs @abc.abstractmethod def generate_and_save_intermediate_result(self, batch): return def create_checkpoint_manager(self, saved_path=None, max_to_keep=10): """Create checkpoint management.""" if saved_path is None: saved_path = self.config["outdir"] + "/checkpoints/" os.makedirs(saved_path, exist_ok=True) self.saved_path = saved_path self.ckpt = tf.train.Checkpoint( steps=tf.Variable(1), epochs=tf.Variable(1), optimizer=self.get_optimizer() ) self.ckp_manager = tf.train.CheckpointManager( self.ckpt, saved_path, max_to_keep=max_to_keep ) def save_checkpoint(self): """Save checkpoint.""" self.ckpt.steps.assign(self.steps) self.ckpt.epochs.assign(self.epochs) self.ckp_manager.save(checkpoint_number=self.steps) self._model.save_weights(self.saved_path + "model-{}.h5".format(self.steps)) def load_checkpoint(self, pretrained_path): """Load checkpoint.""" self.ckpt.restore(pretrained_path) self.steps = self.ckpt.steps.numpy() self.epochs = self.ckpt.epochs.numpy() self._optimizer = self.ckpt.optimizer # re-assign iterations (global steps) for optimizer. self._optimizer.iterations.assign(tf.cast(self.steps, tf.int64)) # load weights. self._model.load_weights(self.saved_path + "model-{}.h5".format(self.steps)) def _check_train_finish(self): """Check training finished.""" if self.steps >= self.config["train_max_steps"]: self.finish_train = True def _check_log_interval(self): """Log to tensorboard.""" if self.steps % self.config["log_interval_steps"] == 0: for metric_name in self.list_metrics_name: logging.info( f"(Step: {self.steps}) train_{metric_name} = {self.train_metrics[metric_name].result():.4f}." ) self._write_to_tensorboard(self.train_metrics, stage="train") # reset self.reset_states_train() def fit(self, train_data_loader, valid_data_loader, saved_path, resume=None): self.set_train_data_loader(train_data_loader) self.set_eval_data_loader(valid_data_loader) self.train_data_loader = self._strategy.experimental_distribute_dataset( self.train_data_loader ) self.eval_data_loader = self._strategy.experimental_distribute_dataset( self.eval_data_loader ) with self._strategy.scope(): self.create_checkpoint_manager(saved_path=saved_path, max_to_keep=10000) if len(resume) > 1: self.load_checkpoint(resume) logging.info(f"Successfully resumed from {resume}.") self.run() class StreamBasedTrainer(Seq2SeqBasedTrainer): def __init__( self, steps, epochs, config, strategy, is_mixed_precision=False, ): super().__init__(steps, epochs, config, strategy, is_mixed_precision) def _one_step_evaluate_per_replica(self, batch): # TODO self._model.stream(**batch) # outputs = self._model(**batch, training=False) _, dict_metrics_losses = self.compute_per_example_losses(batch, outputs) self.update_eval_metrics(dict_metrics_losses) ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/__init__.py ================================================ from tensorflow_tts.utils.cleaners import ( basic_cleaners, collapse_whitespace, convert_to_ascii, english_cleaners, expand_abbreviations, expand_numbers, lowercase, transliteration_cleaners, ) from tensorflow_tts.utils.decoder import dynamic_decode from tensorflow_tts.utils.griffin_lim import TFGriffinLim, griffin_lim_lb from tensorflow_tts.utils.group_conv import GroupConv1D from tensorflow_tts.utils.number_norm import normalize_numbers from tensorflow_tts.utils.outliers import remove_outlier from tensorflow_tts.utils.strategy import ( calculate_2d_loss, calculate_3d_loss, calculate_loss_norm_lens, return_strategy, ) from tensorflow_tts.utils.utils import find_files from tensorflow_tts.utils.weight_norm import WeightNormalization ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/cleaners.py ================================================ # -*- coding: utf-8 -*- # Copyright (c) 2017 Keith Ito # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import re from tensorflow_tts.utils.korean import tokenize as ko_tokenize from tensorflow_tts.utils.number_norm import normalize_numbers from unidecode import unidecode # Regular expression matching whitespace: _whitespace_re = re.compile(r"\s+") # List of (regular expression, replacement) pairs for abbreviations: _abbreviations = [ (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) for x in [ ("mrs", "misess"), ("mr", "mister"), ("dr", "doctor"), ("st", "saint"), ("co", "company"), ("jr", "junior"), ("maj", "major"), ("gen", "general"), ("drs", "doctors"), ("rev", "reverend"), ("lt", "lieutenant"), ("hon", "honorable"), ("sgt", "sergeant"), ("capt", "captain"), ("esq", "esquire"), ("ltd", "limited"), ("col", "colonel"), ("ft", "fort"), ] ] def expand_abbreviations(text): for regex, replacement in _abbreviations: text = re.sub(regex, replacement, text) return text def expand_numbers(text): return normalize_numbers(text) def lowercase(text): return text.lower() def collapse_whitespace(text): return re.sub(_whitespace_re, " ", text) def convert_to_ascii(text): return unidecode(text) def basic_cleaners(text): """Basic pipeline that lowercases and collapses whitespace without transliteration.""" text = lowercase(text) text = collapse_whitespace(text) return text def transliteration_cleaners(text): """Pipeline for non-English text that transliterates to ASCII.""" text = convert_to_ascii(text) text = lowercase(text) text = collapse_whitespace(text) return text def english_cleaners(text): """Pipeline for English text, including number and abbreviation expansion.""" text = convert_to_ascii(text) text = lowercase(text) text = expand_numbers(text) text = expand_abbreviations(text) text = collapse_whitespace(text) return text def korean_cleaners(text): """Pipeline for Korean text, including number and abbreviation expansion.""" text = ko_tokenize( text ) # '존경하는' --> ['ᄌ', 'ᅩ', 'ᆫ', 'ᄀ', 'ᅧ', 'ᆼ', 'ᄒ', 'ᅡ', 'ᄂ', 'ᅳ', 'ᆫ'] return text ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/decoder.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 TensorFlow Authors, 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. from typing import Any, Optional, Tuple, Union import tensorflow as tf from tensorflow.python.ops import control_flow_util from tensorflow_addons.seq2seq import Decoder from tensorflow_addons.seq2seq.decoder import ( BaseDecoder, _prepend_batch, _transpose_batch_time, ) from tensorflow_addons.utils.types import Number, TensorLike def dynamic_decode( decoder: Union[Decoder, BaseDecoder], output_time_major: bool = False, impute_finished: bool = False, maximum_iterations: Optional[TensorLike] = None, parallel_iterations: int = 32, swap_memory: bool = False, training: Optional[bool] = None, scope: Optional[str] = None, enable_tflite_convertible: bool = False, **kwargs ) -> Tuple[Any, Any, Any]: """Perform dynamic decoding with `decoder`. Calls initialize() once and step() repeatedly on the Decoder object. Args: decoder: A `Decoder` instance. output_time_major: Python boolean. Default: `False` (batch major). If `True`, outputs are returned as time major tensors (this mode is faster). Otherwise, outputs are returned as batch major tensors (this adds extra time to the computation). impute_finished: Python boolean. If `True`, then states for batch entries which are marked as finished get copied through and the corresponding outputs get zeroed out. This causes some slowdown at each time step, but ensures that the final state and outputs have the correct values and that backprop ignores time steps that were marked as finished. maximum_iterations: A strictly positive `int32` scalar, the maximum allowed number of decoding steps. Default is `None` (decode until the decoder is fully done). parallel_iterations: Argument passed to `tf.while_loop`. swap_memory: Argument passed to `tf.while_loop`. training: Python boolean. Indicates whether the layer should behave in training mode or in inference mode. Only relevant when `dropout` or `recurrent_dropout` is used. scope: Optional name scope to use. enable_tflite_convertible: Python boolean. If `True`, then the variables of `TensorArray` become of 1-D static shape. Also zero pads in the output tensor will be discarded. Default: `False`. **kwargs: dict, other keyword arguments for dynamic_decode. It might contain arguments for `BaseDecoder` to initialize, which takes all tensor inputs during call(). Returns: `(final_outputs, final_state, final_sequence_lengths)`. Raises: ValueError: if `maximum_iterations` is provided but is not a scalar. """ with tf.name_scope(scope or "decoder"): is_xla = not tf.executing_eagerly() and control_flow_util.GraphOrParentsInXlaContext( tf.compat.v1.get_default_graph() ) if maximum_iterations is not None: maximum_iterations = tf.convert_to_tensor( maximum_iterations, dtype=tf.int32, name="maximum_iterations" ) if maximum_iterations.shape.ndims != 0: raise ValueError("maximum_iterations must be a scalar") tf.debugging.assert_greater( maximum_iterations, 0, message="maximum_iterations should be greater than 0", ) elif is_xla: raise ValueError("maximum_iterations is required for XLA compilation.") if isinstance(decoder, Decoder): initial_finished, initial_inputs, initial_state = decoder.initialize() else: # For BaseDecoder that takes tensor inputs during call. decoder_init_input = kwargs.pop("decoder_init_input", None) decoder_init_kwargs = kwargs.pop("decoder_init_kwargs", {}) initial_finished, initial_inputs, initial_state = decoder.initialize( decoder_init_input, **decoder_init_kwargs ) if enable_tflite_convertible: # Assume the batch_size = 1 for inference. # So we can change 2-D TensorArray into 1-D by reshaping it. zero_outputs = tf.nest.map_structure( lambda shape, dtype: tf.reshape( tf.zeros(_prepend_batch(decoder.batch_size, shape), dtype=dtype), [-1], ), decoder.output_size, decoder.output_dtype, ) else: zero_outputs = tf.nest.map_structure( lambda shape, dtype: tf.zeros( _prepend_batch(decoder.batch_size, shape), dtype=dtype ), decoder.output_size, decoder.output_dtype, ) if maximum_iterations is not None: initial_finished = tf.logical_or(initial_finished, 0 >= maximum_iterations) initial_sequence_lengths = tf.zeros_like(initial_finished, dtype=tf.int32) initial_time = tf.constant(0, dtype=tf.int32) def _shape(batch_size, from_shape): if not isinstance(from_shape, tf.TensorShape) or from_shape.ndims == 0: return None else: batch_size = tf.get_static_value( tf.convert_to_tensor(batch_size, name="batch_size") ) if enable_tflite_convertible: # Since we can't use 2-D TensoArray and assume `batch_size` = 1, # we use `from_shape` dimension only. return from_shape return tf.TensorShape([batch_size]).concatenate(from_shape) dynamic_size = maximum_iterations is None or not is_xla # The dynamic shape `TensoArray` is not allowed in TFLite yet. dynamic_size = dynamic_size and (not enable_tflite_convertible) def _create_ta(s, d): return tf.TensorArray( dtype=d, size=0 if dynamic_size else maximum_iterations, dynamic_size=dynamic_size, element_shape=_shape(decoder.batch_size, s), ) initial_outputs_ta = tf.nest.map_structure( _create_ta, decoder.output_size, decoder.output_dtype ) def condition( unused_time, unused_outputs_ta, unused_state, unused_inputs, finished, unused_sequence_lengths, ): return tf.logical_not(tf.reduce_all(finished)) def body(time, outputs_ta, state, inputs, finished, sequence_lengths): """Internal while_loop body. Args: time: scalar int32 tensor. outputs_ta: structure of TensorArray. state: (structure of) state tensors and TensorArrays. inputs: (structure of) input tensors. finished: bool tensor (keeping track of what's finished). sequence_lengths: int32 tensor (keeping track of time of finish). Returns: `(time + 1, outputs_ta, next_state, next_inputs, next_finished, next_sequence_lengths)`. ``` """ (next_outputs, decoder_state, next_inputs, decoder_finished) = decoder.step( time, inputs, state, training ) decoder_state_sequence_lengths = False if decoder.tracks_own_finished: next_finished = decoder_finished lengths = getattr(decoder_state, "lengths", None) if lengths is not None: # sequence lengths are provided by decoder_state.lengths; # overwrite our sequence lengths. decoder_state_sequence_lengths = True sequence_lengths = tf.cast(lengths, tf.int32) else: next_finished = tf.logical_or(decoder_finished, finished) if decoder_state_sequence_lengths: # Just pass something through the loop; at the next iteration # we'll pull the sequence lengths from the decoder_state again. next_sequence_lengths = sequence_lengths else: next_sequence_lengths = tf.where( tf.logical_not(finished), tf.fill(tf.shape(sequence_lengths), time + 1), sequence_lengths, ) tf.nest.assert_same_structure(state, decoder_state) tf.nest.assert_same_structure(outputs_ta, next_outputs) tf.nest.assert_same_structure(inputs, next_inputs) # Zero out output values past finish if impute_finished: def zero_out_finished(out, zero): if finished.shape.rank < zero.shape.rank: broadcast_finished = tf.broadcast_to( tf.expand_dims(finished, axis=-1), zero.shape ) return tf.where(broadcast_finished, zero, out) else: return tf.where(finished, zero, out) emit = tf.nest.map_structure( zero_out_finished, next_outputs, zero_outputs ) else: emit = next_outputs # Copy through states past finish def _maybe_copy_state(new, cur): # TensorArrays and scalar states get passed through. if isinstance(cur, tf.TensorArray): pass_through = True else: new.set_shape(cur.shape) pass_through = new.shape.ndims == 0 if not pass_through: broadcast_finished = tf.broadcast_to( tf.expand_dims(finished, axis=-1), new.shape ) return tf.where(broadcast_finished, cur, new) else: return new if impute_finished: next_state = tf.nest.map_structure( _maybe_copy_state, decoder_state, state ) else: next_state = decoder_state if enable_tflite_convertible: # Reshape to 1-D. emit = tf.nest.map_structure(lambda x: tf.reshape(x, [-1]), emit) outputs_ta = tf.nest.map_structure( lambda ta, out: ta.write(time, out), outputs_ta, emit ) return ( time + 1, outputs_ta, next_state, next_inputs, next_finished, next_sequence_lengths, ) res = tf.while_loop( condition, body, loop_vars=( initial_time, initial_outputs_ta, initial_state, initial_inputs, initial_finished, initial_sequence_lengths, ), parallel_iterations=parallel_iterations, maximum_iterations=maximum_iterations, swap_memory=swap_memory, ) final_outputs_ta = res[1] final_state = res[2] final_sequence_lengths = res[5] final_outputs = tf.nest.map_structure(lambda ta: ta.stack(), final_outputs_ta) try: final_outputs, final_state = decoder.finalize( final_outputs, final_state, final_sequence_lengths ) except NotImplementedError: pass if not output_time_major: if enable_tflite_convertible: # Reshape the output to the original shape. def _restore_batch(x): return tf.expand_dims(x, [1]) final_outputs = tf.nest.map_structure(_restore_batch, final_outputs) final_outputs = tf.nest.map_structure(_transpose_batch_time, final_outputs) return final_outputs, final_state, final_sequence_lengths ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/griffin_lim.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Griffin-Lim phase reconstruction algorithm from mel spectrogram.""" import os import librosa import numpy as np import soundfile as sf import tensorflow as tf from sklearn.preprocessing import StandardScaler def griffin_lim_lb( mel_spec, stats_path, dataset_config, n_iter=32, output_dir=None, wav_name="lb" ): """Generate wave from mel spectrogram with Griffin-Lim algorithm using Librosa. Args: mel_spec (ndarray): array representing the mel spectrogram. stats_path (str): path to the `stats.npy` file containing norm statistics. dataset_config (Dict): dataset configuration parameters. n_iter (int): number of iterations for GL. output_dir (str): output directory where audio file will be saved. wav_name (str): name of the output file. Returns: gl_lb (ndarray): generated wave. """ scaler = StandardScaler() scaler.mean_, scaler.scale_ = np.load(stats_path) mel_spec = np.power(10.0, scaler.inverse_transform(mel_spec)).T mel_basis = librosa.filters.mel( dataset_config["sampling_rate"], n_fft=dataset_config["fft_size"], n_mels=dataset_config["num_mels"], fmin=dataset_config["fmin"], fmax=dataset_config["fmax"], ) mel_to_linear = np.maximum(1e-10, np.dot(np.linalg.pinv(mel_basis), mel_spec)) gl_lb = librosa.griffinlim( mel_to_linear, n_iter=n_iter, hop_length=dataset_config["hop_size"], win_length=dataset_config["win_length"] or dataset_config["fft_size"], ) if output_dir: output_path = os.path.join(output_dir, f"{wav_name}.wav") sf.write(output_path, gl_lb, dataset_config["sampling_rate"], "PCM_16") return gl_lb class TFGriffinLim(tf.keras.layers.Layer): """Griffin-Lim algorithm for phase reconstruction from mel spectrogram magnitude.""" def __init__(self, stats_path, dataset_config, normalized: bool = True): """Init GL params. Args: stats_path (str): path to the `stats.npy` file containing norm statistics. dataset_config (Dict): dataset configuration parameters. """ super().__init__() self.normalized = normalized if normalized: scaler = StandardScaler() scaler.mean_, scaler.scale_ = np.load(stats_path) self.scaler = scaler self.ds_config = dataset_config self.mel_basis = librosa.filters.mel( self.ds_config["sampling_rate"], n_fft=self.ds_config["fft_size"], n_mels=self.ds_config["num_mels"], fmin=self.ds_config["fmin"], fmax=self.ds_config["fmax"], ) # [num_mels, fft_size // 2 + 1] def save_wav(self, gl_tf, output_dir, wav_name): """Generate WAV file and save it. Args: gl_tf (tf.Tensor): reconstructed signal from GL algorithm. output_dir (str): output directory where audio file will be saved. wav_name (str): name of the output file. """ encode_fn = lambda x: tf.audio.encode_wav(x, self.ds_config["sampling_rate"]) gl_tf = tf.expand_dims(gl_tf, -1) if not isinstance(wav_name, list): wav_name = [wav_name] if len(gl_tf.shape) > 2: bs, *_ = gl_tf.shape assert bs == len(wav_name), "Batch and 'wav_name' have different size." tf_wav = tf.map_fn(encode_fn, gl_tf, dtype=tf.string) for idx in tf.range(bs): output_path = os.path.join(output_dir, f"{wav_name[idx]}.wav") tf.io.write_file(output_path, tf_wav[idx]) else: tf_wav = encode_fn(gl_tf) tf.io.write_file(os.path.join(output_dir, f"{wav_name[0]}.wav"), tf_wav) @tf.function( input_signature=[ tf.TensorSpec(shape=[None, None, None], dtype=tf.float32), tf.TensorSpec(shape=[], dtype=tf.int32), ] ) def call(self, mel_spec, n_iter=32): """Apply GL algorithm to batched mel spectrograms. Args: mel_spec (tf.Tensor): normalized mel spectrogram. n_iter (int): number of iterations to run GL algorithm. Returns: (tf.Tensor): reconstructed signal from GL algorithm. """ # de-normalize mel spectogram if self.normalized: mel_spec = tf.math.pow( 10.0, mel_spec * self.scaler.scale_ + self.scaler.mean_ ) else: mel_spec = tf.math.pow( 10.0, mel_spec ) # TODO @dathudeptrai check if its ok without it wavs were too quiet inverse_mel = tf.linalg.pinv(self.mel_basis) # [:, num_mels] @ [fft_size // 2 + 1, num_mels].T mel_to_linear = tf.linalg.matmul(mel_spec, inverse_mel, transpose_b=True) mel_to_linear = tf.cast(tf.math.maximum(1e-10, mel_to_linear), tf.complex64) init_phase = tf.cast( tf.random.uniform(tf.shape(mel_to_linear), maxval=1), tf.complex64 ) phase = tf.math.exp(2j * np.pi * init_phase) for _ in tf.range(n_iter): inverse = tf.signal.inverse_stft( mel_to_linear * phase, frame_length=self.ds_config["win_length"] or self.ds_config["fft_size"], frame_step=self.ds_config["hop_size"], fft_length=self.ds_config["fft_size"], window_fn=tf.signal.inverse_stft_window_fn(self.ds_config["hop_size"]), ) phase = tf.signal.stft( inverse, self.ds_config["win_length"] or self.ds_config["fft_size"], self.ds_config["hop_size"], self.ds_config["fft_size"], ) phase /= tf.cast(tf.maximum(1e-10, tf.abs(phase)), tf.complex64) return tf.signal.inverse_stft( mel_to_linear * phase, frame_length=self.ds_config["win_length"] or self.ds_config["fft_size"], frame_step=self.ds_config["hop_size"], fft_length=self.ds_config["fft_size"], window_fn=tf.signal.inverse_stft_window_fn(self.ds_config["hop_size"]), ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/group_conv.py ================================================ # -*- coding: utf-8 -*- # This code is copy from https://github.com/tensorflow/tensorflow/pull/36773. """Group Convolution Modules.""" from tensorflow.python.framework import tensor_shape from tensorflow.python.keras import activations, constraints, initializers, regularizers from tensorflow.python.keras.engine.base_layer import Layer from tensorflow.python.keras.engine.input_spec import InputSpec from tensorflow.python.keras.layers import Conv1D, SeparableConv1D from tensorflow.python.keras.utils import conv_utils from tensorflow.python.ops import array_ops, nn, nn_ops class Convolution(object): """Helper class for convolution. Note that this class assumes that shapes of input and filter passed to __call__ are compatible with input_shape and filter_shape passed to the constructor. Arguments input_shape: static shape of input. i.e. input.get_shape(). filter_shape: static shape of the filter. i.e. filter.get_shape(). padding: see convolution. strides: see convolution. dilation_rate: see convolution. name: see convolution. data_format: see convolution. """ def __init__( self, input_shape, filter_shape, padding, strides=None, dilation_rate=None, name=None, data_format=None, ): """Helper function for convolution.""" num_total_dims = filter_shape.ndims if num_total_dims is None: num_total_dims = input_shape.ndims if num_total_dims is None: raise ValueError("rank of input or filter must be known") num_spatial_dims = num_total_dims - 2 try: input_shape.with_rank(num_spatial_dims + 2) except ValueError: raise ValueError("input tensor must have rank %d" % (num_spatial_dims + 2)) try: filter_shape.with_rank(num_spatial_dims + 2) except ValueError: raise ValueError("filter tensor must have rank %d" % (num_spatial_dims + 2)) if data_format is None or not data_format.startswith("NC"): input_channels_dim = tensor_shape.dimension_at_index( input_shape, num_spatial_dims + 1 ) spatial_dims = range(1, num_spatial_dims + 1) else: input_channels_dim = tensor_shape.dimension_at_index(input_shape, 1) spatial_dims = range(2, num_spatial_dims + 2) filter_dim = tensor_shape.dimension_at_index(filter_shape, num_spatial_dims) if not (input_channels_dim % filter_dim).is_compatible_with(0): raise ValueError( "number of input channels is not divisible by corresponding " "dimension of filter, {} % {} != 0".format( input_channels_dim, filter_dim ) ) strides, dilation_rate = nn_ops._get_strides_and_dilation_rate( num_spatial_dims, strides, dilation_rate ) self.input_shape = input_shape self.filter_shape = filter_shape self.data_format = data_format self.strides = strides self.padding = padding self.name = name self.dilation_rate = dilation_rate self.conv_op = nn_ops._WithSpaceToBatch( input_shape, dilation_rate=dilation_rate, padding=padding, build_op=self._build_op, filter_shape=filter_shape, spatial_dims=spatial_dims, data_format=data_format, ) def _build_op(self, _, padding): return nn_ops._NonAtrousConvolution( self.input_shape, filter_shape=self.filter_shape, padding=padding, data_format=self.data_format, strides=self.strides, name=self.name, ) def __call__(self, inp, filter): return self.conv_op(inp, filter) class Conv(Layer): """Abstract N-D convolution layer (private, used as implementation base). This layer creates a convolution kernel that is convolved (actually cross-correlated) with the layer input to produce a tensor of outputs. If `use_bias` is True (and a `bias_initializer` is provided), a bias vector is created and added to the outputs. Finally, if `activation` is not `None`, it is applied to the outputs as well. Note: layer attributes cannot be modified after the layer has been called once (except the `trainable` attribute). Arguments: rank: An integer, the rank of the convolution, e.g. "2" for 2D convolution. filters: Integer, the dimensionality of the output space (i.e. the number of filters in the convolution). kernel_size: An integer or tuple/list of n integers, specifying the length of the convolution window. strides: An integer or tuple/list of n integers, specifying the stride length of the convolution. Specifying any stride value != 1 is incompatible with specifying any `dilation_rate` value != 1. padding: One of `"valid"`, `"same"`, or `"causal"` (case-insensitive). data_format: A string, one of `channels_last` (default) or `channels_first`. The ordering of the dimensions in the inputs. `channels_last` corresponds to inputs with shape `(batch_size, ..., channels)` while `channels_first` corresponds to inputs with shape `(batch_size, channels, ...)`. dilation_rate: An integer or tuple/list of n integers, specifying the dilation rate to use for dilated convolution. Currently, specifying any `dilation_rate` value != 1 is incompatible with specifying any `strides` value != 1. groups: Integer, the number of channel groups controlling the connections between inputs and outputs. Input channels and `filters` must both be divisible by `groups`. For example, - At `groups=1`, all inputs are convolved to all outputs. - At `groups=2`, the operation becomes equivalent to having two convolutional layers side by side, each seeing half the input channels, and producing half the output channels, and both subsequently concatenated. - At `groups=input_channels`, each input channel is convolved with its own set of filters, of size `input_channels / filters` activation: Activation function to use. If you don't specify anything, no activation is applied. use_bias: Boolean, whether the layer uses a bias. kernel_initializer: An initializer for the convolution kernel. bias_initializer: An initializer for the bias vector. If None, the default initializer will be used. kernel_regularizer: Optional regularizer for the convolution kernel. bias_regularizer: Optional regularizer for the bias vector. activity_regularizer: Optional regularizer function for the output. kernel_constraint: Optional projection function to be applied to the kernel after being updated by an `Optimizer` (e.g. used to implement norm constraints or value constraints for layer weights). The function must take as input the unprojected variable and must return the projected variable (which must have the same shape). Constraints are not safe to use when doing asynchronous distributed training. bias_constraint: Optional projection function to be applied to the bias after being updated by an `Optimizer`. trainable: Boolean, if `True` the weights of this layer will be marked as trainable (and listed in `layer.trainable_weights`). name: A string, the name of the layer. """ def __init__( self, rank, filters, kernel_size, strides=1, padding="valid", data_format=None, dilation_rate=1, groups=1, activation=None, use_bias=True, kernel_initializer="glorot_uniform", bias_initializer="zeros", kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, trainable=True, name=None, **kwargs ): super(Conv, self).__init__( trainable=trainable, name=name, activity_regularizer=regularizers.get(activity_regularizer), **kwargs ) self.rank = rank if filters is not None and not isinstance(filters, int): filters = int(filters) self.filters = filters self.groups = groups or 1 if filters is not None and filters % self.groups != 0: raise ValueError( "The number of filters must be evenly divisible by the number of " "groups. Received: groups={}, filters={}".format(groups, filters) ) self.kernel_size = conv_utils.normalize_tuple(kernel_size, rank, "kernel_size") if not all(self.kernel_size): raise ValueError( "The argument `kernel_size` cannot contain 0(s). " "Received: %s" % (kernel_size,) ) self.strides = conv_utils.normalize_tuple(strides, rank, "strides") self.padding = conv_utils.normalize_padding(padding) if self.padding == "causal" and not isinstance(self, (Conv1D, SeparableConv1D)): raise ValueError( "Causal padding is only supported for `Conv1D`" "and ``SeparableConv1D`." ) self.data_format = conv_utils.normalize_data_format(data_format) self.dilation_rate = conv_utils.normalize_tuple( dilation_rate, rank, "dilation_rate" ) self.activation = activations.get(activation) self.use_bias = use_bias self.kernel_initializer = initializers.get(kernel_initializer) self.bias_initializer = initializers.get(bias_initializer) self.kernel_regularizer = regularizers.get(kernel_regularizer) self.bias_regularizer = regularizers.get(bias_regularizer) self.kernel_constraint = constraints.get(kernel_constraint) self.bias_constraint = constraints.get(bias_constraint) self.input_spec = InputSpec(ndim=self.rank + 2) def build(self, input_shape): input_shape = tensor_shape.TensorShape(input_shape) input_channel = self._get_input_channel(input_shape) if input_channel % self.groups != 0: raise ValueError( "The number of input channels must be evenly divisible by the number " "of groups. Received groups={}, but the input has {} channels " "(full input shape is {}).".format( self.groups, input_channel, input_shape ) ) kernel_shape = self.kernel_size + (input_channel // self.groups, self.filters) self.kernel = self.add_weight( name="kernel", shape=kernel_shape, initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True, dtype=self.dtype, ) if self.use_bias: self.bias = self.add_weight( name="bias", shape=(self.filters,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True, dtype=self.dtype, ) else: self.bias = None channel_axis = self._get_channel_axis() self.input_spec = InputSpec( ndim=self.rank + 2, axes={channel_axis: input_channel} ) self._build_conv_op_input_shape = input_shape self._build_input_channel = input_channel self._padding_op = self._get_padding_op() self._conv_op_data_format = conv_utils.convert_data_format( self.data_format, self.rank + 2 ) self._convolution_op = Convolution( input_shape, filter_shape=self.kernel.shape, dilation_rate=self.dilation_rate, strides=self.strides, padding=self._padding_op, data_format=self._conv_op_data_format, ) self.built = True def call(self, inputs): if self._recreate_conv_op(inputs): self._convolution_op = Convolution( inputs.get_shape(), filter_shape=self.kernel.shape, dilation_rate=self.dilation_rate, strides=self.strides, padding=self._padding_op, data_format=self._conv_op_data_format, ) self._build_conv_op_input_shape = inputs.get_shape() # Apply causal padding to inputs for Conv1D. if self.padding == "causal" and self.__class__.__name__ == "Conv1D": inputs = array_ops.pad(inputs, self._compute_causal_padding()) outputs = self._convolution_op(inputs, self.kernel) if self.use_bias: if self.data_format == "channels_first": if self.rank == 1: # nn.bias_add does not accept a 1D input tensor. bias = array_ops.reshape(self.bias, (1, self.filters, 1)) outputs += bias else: outputs = nn.bias_add(outputs, self.bias, data_format="NCHW") else: outputs = nn.bias_add(outputs, self.bias, data_format="NHWC") if self.activation is not None: return self.activation(outputs) return outputs def compute_output_shape(self, input_shape): input_shape = tensor_shape.TensorShape(input_shape).as_list() if self.data_format == "channels_last": space = input_shape[1:-1] new_space = [] for i in range(len(space)): new_dim = conv_utils.conv_output_length( space[i], self.kernel_size[i], padding=self.padding, stride=self.strides[i], dilation=self.dilation_rate[i], ) new_space.append(new_dim) return tensor_shape.TensorShape( [input_shape[0]] + new_space + [self.filters] ) else: space = input_shape[2:] new_space = [] for i in range(len(space)): new_dim = conv_utils.conv_output_length( space[i], self.kernel_size[i], padding=self.padding, stride=self.strides[i], dilation=self.dilation_rate[i], ) new_space.append(new_dim) return tensor_shape.TensorShape([input_shape[0], self.filters] + new_space) def get_config(self): config = { "filters": self.filters, "kernel_size": self.kernel_size, "strides": self.strides, "padding": self.padding, "data_format": self.data_format, "dilation_rate": self.dilation_rate, "groups": self.groups, "activation": activations.serialize(self.activation), "use_bias": self.use_bias, "kernel_initializer": initializers.serialize(self.kernel_initializer), "bias_initializer": initializers.serialize(self.bias_initializer), "kernel_regularizer": regularizers.serialize(self.kernel_regularizer), "bias_regularizer": regularizers.serialize(self.bias_regularizer), "activity_regularizer": regularizers.serialize(self.activity_regularizer), "kernel_constraint": constraints.serialize(self.kernel_constraint), "bias_constraint": constraints.serialize(self.bias_constraint), } base_config = super(Conv, self).get_config() return dict(list(base_config.items()) + list(config.items())) def _compute_causal_padding(self): """Calculates padding for 'causal' option for 1-d conv layers.""" left_pad = self.dilation_rate[0] * (self.kernel_size[0] - 1) if self.data_format == "channels_last": causal_padding = [[0, 0], [left_pad, 0], [0, 0]] else: causal_padding = [[0, 0], [0, 0], [left_pad, 0]] return causal_padding def _get_channel_axis(self): if self.data_format == "channels_first": return 1 else: return -1 def _get_input_channel(self, input_shape): channel_axis = self._get_channel_axis() if input_shape.dims[channel_axis].value is None: raise ValueError( "The channel dimension of the inputs " "should be defined. Found `None`." ) return int(input_shape[channel_axis]) def _get_padding_op(self): if self.padding == "causal": op_padding = "valid" else: op_padding = self.padding if not isinstance(op_padding, (list, tuple)): op_padding = op_padding.upper() return op_padding def _recreate_conv_op(self, inputs): """Recreate conv_op if necessary. Check if the input_shape in call() is different from that in build(). For the values that are not None, if they are different, recreate the _convolution_op to avoid the stateful behavior. Args: inputs: The input data to call() method. Returns: `True` or `False` to indicate whether to recreate the conv_op. """ call_input_shape = inputs.get_shape() for axis in range(1, len(call_input_shape)): if ( call_input_shape[axis] is not None and self._build_conv_op_input_shape[axis] is not None and call_input_shape[axis] != self._build_conv_op_input_shape[axis] ): return True return False class GroupConv1D(Conv): """1D convolution layer (e.g. temporal convolution). This layer creates a convolution kernel that is convolved with the layer input over a single spatial (or temporal) dimension to produce a tensor of outputs. If `use_bias` is True, a bias vector is created and added to the outputs. Finally, if `activation` is not `None`, it is applied to the outputs as well. When using this layer as the first layer in a model, provide an `input_shape` argument (tuple of integers or `None`, e.g. `(10, 128)` for sequences of 10 vectors of 128-dimensional vectors, or `(None, 128)` for variable-length sequences of 128-dimensional vectors. Examples: >>> # The inputs are 128-length vectors with 10 timesteps, and the batch size >>> # is 4. >>> input_shape = (4, 10, 128) >>> x = tf.random.normal(input_shape) >>> y = tf.keras.layers.Conv1D( ... 32, 3, activation='relu',input_shape=input_shape)(x) >>> print(y.shape) (4, 8, 32) Arguments: filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution). kernel_size: An integer or tuple/list of a single integer, specifying the length of the 1D convolution window. strides: An integer or tuple/list of a single integer, specifying the stride length of the convolution. Specifying any stride value != 1 is incompatible with specifying any `dilation_rate` value != 1. padding: One of `"valid"`, `"causal"` or `"same"` (case-insensitive). `"causal"` results in causal (dilated) convolutions, e.g. `output[t]` does not depend on `input[t+1:]`. Useful when modeling temporal data where the model should not violate the temporal order. See [WaveNet: A Generative Model for Raw Audio, section 2.1](https://arxiv.org/abs/1609.03499). data_format: A string, one of `channels_last` (default) or `channels_first`. groups: Integer, the number of channel groups controlling the connections between inputs and outputs. Input channels and `filters` must both be divisible by `groups`. For example, - At `groups=1`, all inputs are convolved to all outputs. - At `groups=2`, the operation becomes equivalent to having two convolutional layers side by side, each seeing half the input channels, and producing half the output channels, and both subsequently concatenated. - At `groups=input_channels`, each input channel is convolved with its own set of filters, of size `input_channels / filters` dilation_rate: an integer or tuple/list of a single integer, specifying the dilation rate to use for dilated convolution. Currently, specifying any `dilation_rate` value != 1 is incompatible with specifying any `strides` value != 1. activation: Activation function to use. If you don't specify anything, no activation is applied ( see `keras.activations`). use_bias: Boolean, whether the layer uses a bias vector. kernel_initializer: Initializer for the `kernel` weights matrix ( see `keras.initializers`). bias_initializer: Initializer for the bias vector ( see `keras.initializers`). kernel_regularizer: Regularizer function applied to the `kernel` weights matrix (see `keras.regularizers`). bias_regularizer: Regularizer function applied to the bias vector ( see `keras.regularizers`). activity_regularizer: Regularizer function applied to the output of the layer (its "activation") ( see `keras.regularizers`). kernel_constraint: Constraint function applied to the kernel matrix ( see `keras.constraints`). bias_constraint: Constraint function applied to the bias vector ( see `keras.constraints`). Input shape: 3D tensor with shape: `(batch_size, steps, input_dim)` Output shape: 3D tensor with shape: `(batch_size, new_steps, filters)` `steps` value might have changed due to padding or strides. Returns: A tensor of rank 3 representing `activation(conv1d(inputs, kernel) + bias)`. Raises: ValueError: when both `strides` > 1 and `dilation_rate` > 1. """ def __init__( self, filters, kernel_size, strides=1, padding="valid", data_format="channels_last", dilation_rate=1, groups=1, activation=None, use_bias=True, kernel_initializer="glorot_uniform", bias_initializer="zeros", kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs ): super().__init__( rank=1, filters=filters, kernel_size=kernel_size, strides=strides, padding=padding, data_format=data_format, dilation_rate=dilation_rate, groups=groups, activation=activations.get(activation), use_bias=use_bias, kernel_initializer=initializers.get(kernel_initializer), bias_initializer=initializers.get(bias_initializer), kernel_regularizer=regularizers.get(kernel_regularizer), bias_regularizer=regularizers.get(bias_regularizer), activity_regularizer=regularizers.get(activity_regularizer), kernel_constraint=constraints.get(kernel_constraint), bias_constraint=constraints.get(bias_constraint), **kwargs ) ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/korean.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 TensorFlowTTS Team, Jaehyoung Kim(@crux153) and Taehoon Kim(@carpedm20) # # 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. # Code based on https://github.com/carpedm20/multi-speaker-tacotron-tensorflow """Korean related helpers.""" import ast import json import os import re from jamo import h2j, hangul_to_jamo, j2h, jamo_to_hcj etc_dictionary = { "2 30대": "이삼십대", "20~30대": "이삼십대", "20, 30대": "이십대 삼십대", "1+1": "원플러스원", "3에서 6개월인": "3개월에서 육개월인", } english_dictionary = { "Devsisters": "데브시스터즈", "track": "트랙", # krbook "LA": "엘에이", "LG": "엘지", "KOREA": "코리아", "JSA": "제이에스에이", "PGA": "피지에이", "GA": "지에이", "idol": "아이돌", "KTX": "케이티엑스", "AC": "에이씨", "DVD": "디비디", "US": "유에스", "CNN": "씨엔엔", "LPGA": "엘피지에이", "P": "피", "L": "엘", "T": "티", "B": "비", "C": "씨", "BIFF": "비아이에프에프", "GV": "지비", # JTBC "IT": "아이티", "IQ": "아이큐", "JTBC": "제이티비씨", "trickle down effect": "트리클 다운 이펙트", "trickle up effect": "트리클 업 이펙트", "down": "다운", "up": "업", "FCK": "에프씨케이", "AP": "에이피", "WHERETHEWILDTHINGSARE": "", "Rashomon Effect": "", "O": "오", "OO": "오오", "B": "비", "GDP": "지디피", "CIPA": "씨아이피에이", "YS": "와이에스", "Y": "와이", "S": "에스", "JTBC": "제이티비씨", "PC": "피씨", "bill": "빌", "Halmuny": "하모니", ##### "X": "엑스", "SNS": "에스엔에스", "ability": "어빌리티", "shy": "", "CCTV": "씨씨티비", "IT": "아이티", "the tenth man": "더 텐쓰 맨", #### "L": "엘", "PC": "피씨", "YSDJJPMB": "", ######## "Content Attitude Timing": "컨텐트 애티튜드 타이밍", "CAT": "캣", "IS": "아이에스", "K": "케이", "Y": "와이", "KDI": "케이디아이", "DOC": "디오씨", "CIA": "씨아이에이", "PBS": "피비에스", "D": "디", "PPropertyPositionPowerPrisonP" "S": "에스", "francisco": "프란시스코", "I": "아이", "III": "아이아이", ###### "No joke": "노 조크", "BBK": "비비케이", "LA": "엘에이", "Don": "", "t worry be happy": " 워리 비 해피", "NO": "엔오", ##### "it was our sky": "잇 워즈 아워 스카이", "it is our sky": "잇 이즈 아워 스카이", #### "NEIS": "엔이아이에스", ##### "IMF": "아이엠에프", "apology": "어폴로지", "humble": "험블", "M": "엠", "Nowhere Man": "노웨어 맨", "The Tenth Man": "더 텐쓰 맨", "PBS": "피비에스", "BBC": "비비씨", "MRJ": "엠알제이", "CCTV": "씨씨티비", "Pick me up": "픽 미 업", "DNA": "디엔에이", "UN": "유엔", "STOP": "스탑", ##### "PRESS": "프레스", ##### "not to be": "낫 투비", "Denial": "디나이얼", "G": "지", "IMF": "아이엠에프", "GDP": "지디피", "JTBC": "제이티비씨", "Time flies like an arrow": "타임 플라이즈 라이크 언 애로우", "DDT": "디디티", "AI": "에이아이", "Z": "제트", "OECD": "오이씨디", "N": "앤", "A": "에이", "MB": "엠비", "EH": "이에이치", "IS": "아이에스", "TV": "티비", "MIT": "엠아이티", "KBO": "케이비오", "I love America": "아이 러브 아메리카", "SF": "에스에프", "Q": "큐", "KFX": "케이에프엑스", "PM": "피엠", "Prime Minister": "프라임 미니스터", "Swordline": "스워드라인", "TBS": "티비에스", "DDT": "디디티", "CS": "씨에스", "Reflecting Absence": "리플렉팅 앱센스", "PBS": "피비에스", "Drum being beaten by everyone": "드럼 빙 비튼 바이 에브리원", "negative pressure": "네거티브 프레셔", "F": "에프", "KIA": "기아", "FTA": "에프티에이", "Que sais-je": "", "UFC": "유에프씨", "P": "피", "DJ": "디제이", "Chaebol": "채벌", "BBC": "비비씨", "OECD": "오이씨디", "BC": "삐씨", "C": "씨", "B": "씨", "KY": "케이와이", "K": "케이", "CEO": "씨이오", "YH": "와이에치", "IS": "아이에스", "who are you": "후 얼 유", "Y": "와이", "The Devils Advocate": "더 데빌즈 어드보카트", "YS": "와이에스", "so sorry": "쏘 쏘리", "Santa": "산타", "Big Endian": "빅 엔디안", "Small Endian": "스몰 엔디안", "Oh Captain My Captain": "오 캡틴 마이 캡틴", "AIB": "에이아이비", "K": "케이", "PBS": "피비에스", # IU "ASMR": "에이에스엠알", "V": "브이", "PD": "피디", "CD": "씨디", "ANR": "에이엔알", "Twenty Three": "투엔티 쓰리", "Through The Night": "쓰루 더 나잇", "MD": "엠디", } num_to_kor = { "0": "영", "1": "일", "2": "이", "3": "삼", "4": "사", "5": "오", "6": "육", "7": "칠", "8": "팔", "9": "구", } unit_to_kor1 = {"%": "퍼센트", "cm": "센치미터", "mm": "밀리미터", "km": "킬로미터", "kg": "킬로그람"} unit_to_kor2 = {"m": "미터"} upper_to_kor = { "A": "에이", "B": "비", "C": "씨", "D": "디", "E": "이", "F": "에프", "G": "지", "H": "에이치", "I": "아이", "J": "제이", "K": "케이", "L": "엘", "M": "엠", "N": "엔", "O": "오", "P": "피", "Q": "큐", "R": "알", "S": "에스", "T": "티", "U": "유", "V": "브이", "W": "더블유", "X": "엑스", "Y": "와이", "Z": "지", } """ 초성과 종성은 같아보이지만, 다른 character이다. '_-!'(),-.:;? ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ~' '_': 0, '-': 7, '!': 2, "'": 3, '(': 4, ')': 5, ',': 6, '.': 8, ':': 9, ';': 10, '?': 11, ' ': 12, 'ᄀ': 13, 'ᄁ': 14, 'ᄂ': 15, 'ᄃ': 16, 'ᄄ': 17, 'ᄅ': 18, 'ᄆ': 19, 'ᄇ': 20, 'ᄈ': 21, 'ᄉ': 22, 'ᄊ': 23, 'ᄋ': 24, 'ᄌ': 25, 'ᄍ': 26, 'ᄎ': 27, 'ᄏ': 28, 'ᄐ': 29, 'ᄑ': 30, 'ᄒ': 31, 'ᅡ': 32, 'ᅢ': 33, 'ᅣ': 34, 'ᅤ': 35, 'ᅥ': 36, 'ᅦ': 37, 'ᅧ': 38, 'ᅨ': 39, 'ᅩ': 40, 'ᅪ': 41, 'ᅫ': 42, 'ᅬ': 43, 'ᅭ': 44, 'ᅮ': 45, 'ᅯ': 46, 'ᅰ': 47, 'ᅱ': 48, 'ᅲ': 49, 'ᅳ': 50, 'ᅴ': 51, 'ᅵ': 52, 'ᆨ': 53, 'ᆩ': 54, 'ᆪ': 55, 'ᆫ': 56, 'ᆬ': 57, 'ᆭ': 58, 'ᆮ': 59, 'ᆯ': 60, 'ᆰ': 61, 'ᆱ': 62, 'ᆲ': 63, 'ᆳ': 64, 'ᆴ': 65, 'ᆵ': 66, 'ᆶ': 67, 'ᆷ': 68, 'ᆸ': 69, 'ᆹ': 70, 'ᆺ': 71, 'ᆻ': 72, 'ᆼ': 73, 'ᆽ': 74, 'ᆾ': 75, 'ᆿ': 76, 'ᇀ': 77, 'ᇁ': 78, 'ᇂ': 79, '~': 80 """ _pad = "pad" _eos = "eos" _punctuation = "!'(),-.:;? " _special = "-" _jamo_leads = [chr(_) for _ in range(0x1100, 0x1113)] _jamo_vowels = [chr(_) for _ in range(0x1161, 0x1176)] _jamo_tails = [chr(_) for _ in range(0x11A8, 0x11C3)] _letters = _jamo_leads + _jamo_vowels + _jamo_tails symbols = [_pad] + list(_special) + list(_punctuation) + _letters + [_eos] _symbol_to_id = {c: i for i, c in enumerate(symbols)} _id_to_symbol = {i: c for i, c in enumerate(symbols)} quote_checker = """([`"'"“‘])(.+?)([`"'"”’])""" def is_lead(char): return char in _jamo_leads def is_vowel(char): return char in _jamo_vowels def is_tail(char): return char in _jamo_tails def get_mode(char): if is_lead(char): return 0 elif is_vowel(char): return 1 elif is_tail(char): return 2 else: return -1 def _get_text_from_candidates(candidates): if len(candidates) == 0: return "" elif len(candidates) == 1: return jamo_to_hcj(candidates[0]) else: return j2h(**dict(zip(["lead", "vowel", "tail"], candidates))) def jamo_to_korean(text): text = h2j(text) idx = 0 new_text = "" candidates = [] while True: if idx >= len(text): new_text += _get_text_from_candidates(candidates) break char = text[idx] mode = get_mode(char) if mode == 0: new_text += _get_text_from_candidates(candidates) candidates = [char] elif mode == -1: new_text += _get_text_from_candidates(candidates) new_text += char candidates = [] else: candidates.append(char) idx += 1 return new_text def compare_sentence_with_jamo(text1, text2): return h2j(text1) != h2j(text2) def tokenize(text, as_id=False): # jamo package에 있는 hangul_to_jamo를 이용하여 한글 string을 초성/중성/종성으로 나눈다. text = normalize(text) tokens = list( hangul_to_jamo(text) ) # '존경하는' --> ['ᄌ', 'ᅩ', 'ᆫ', 'ᄀ', 'ᅧ', 'ᆼ', 'ᄒ', 'ᅡ', 'ᄂ', 'ᅳ', 'ᆫ', '~'] if as_id: return [_symbol_to_id[token] for token in tokens] else: return [token for token in tokens] def tokenizer_fn(iterator): return (token for x in iterator for token in tokenize(x, as_id=False)) def normalize(text): text = text.strip() text = re.sub("\(\d+일\)", "", text) text = re.sub("\([⺀-⺙⺛-⻳⼀-⿕々〇〡-〩〸-〺〻㐀-䶵一-鿃豈-鶴侮-頻並-龎]+\)", "", text) text = normalize_with_dictionary(text, etc_dictionary) text = normalize_english(text) text = re.sub("[a-zA-Z]+", normalize_upper, text) text = normalize_quote(text) text = normalize_number(text) return text def normalize_with_dictionary(text, dic): if any(key in text for key in dic.keys()): pattern = re.compile("|".join(re.escape(key) for key in dic.keys())) return pattern.sub(lambda x: dic[x.group()], text) else: return text def normalize_english(text): def fn(m): word = m.group() if word in english_dictionary: return english_dictionary.get(word) else: return word text = re.sub("([A-Za-z]+)", fn, text) return text def normalize_upper(text): text = text.group(0) if all([char.isupper() for char in text]): return "".join(upper_to_kor[char] for char in text) else: return text def normalize_quote(text): def fn(found_text): from nltk import sent_tokenize # NLTK doesn't along with multiprocessing found_text = found_text.group() unquoted_text = found_text[1:-1] sentences = sent_tokenize(unquoted_text) return " ".join(["'{}'".format(sent) for sent in sentences]) return re.sub(quote_checker, fn, text) number_checker = "([+-]?\d[\d,]*)[\.]?\d*" count_checker = "(시|명|가지|살|마리|포기|송이|수|톨|통|점|개|벌|척|채|다발|그루|자루|줄|켤레|그릇|잔|마디|상자|사람|곡|병|판)" def normalize_number(text): text = normalize_with_dictionary(text, unit_to_kor1) text = normalize_with_dictionary(text, unit_to_kor2) text = re.sub( number_checker + count_checker, lambda x: number_to_korean(x, True), text ) text = re.sub(number_checker, lambda x: number_to_korean(x, False), text) return text num_to_kor1 = [""] + list("일이삼사오육칠팔구") num_to_kor2 = [""] + list("만억조경해") num_to_kor3 = [""] + list("십백천") # count_to_kor1 = [""] + ["하나","둘","셋","넷","다섯","여섯","일곱","여덟","아홉"] count_to_kor1 = [""] + ["한", "두", "세", "네", "다섯", "여섯", "일곱", "여덟", "아홉"] count_tenth_dict = { "십": "열", "두십": "스물", "세십": "서른", "네십": "마흔", "다섯십": "쉰", "여섯십": "예순", "일곱십": "일흔", "여덟십": "여든", "아홉십": "아흔", } def number_to_korean(num_str, is_count=False): if is_count: num_str, unit_str = num_str.group(1), num_str.group(2) else: num_str, unit_str = num_str.group(), "" num_str = num_str.replace(",", "") num = ast.literal_eval(num_str) if num == 0: return "영" check_float = num_str.split(".") if len(check_float) == 2: digit_str, float_str = check_float elif len(check_float) >= 3: raise Exception(" [!] Wrong number format") else: digit_str, float_str = check_float[0], None if is_count and float_str is not None: raise Exception(" [!] `is_count` and float number does not fit each other") digit = int(digit_str) if digit_str.startswith("-"): digit, digit_str = abs(digit), str(abs(digit)) kor = "" size = len(str(digit)) tmp = [] for i, v in enumerate(digit_str, start=1): v = int(v) if v != 0: if is_count: tmp += count_to_kor1[v] else: tmp += num_to_kor1[v] tmp += num_to_kor3[(size - i) % 4] if (size - i) % 4 == 0 and len(tmp) != 0: kor += "".join(tmp) tmp = [] kor += num_to_kor2[int((size - i) / 4)] if is_count: if kor.startswith("한") and len(kor) > 1: kor = kor[1:] if any(word in kor for word in count_tenth_dict): kor = re.sub( "|".join(count_tenth_dict.keys()), lambda x: count_tenth_dict[x.group()], kor, ) if not is_count and kor.startswith("일") and len(kor) > 1: kor = kor[1:] if float_str is not None: kor += "쩜 " kor += re.sub("\d", lambda x: num_to_kor[x.group()], float_str) if num_str.startswith("+"): kor = "플러스 " + kor elif num_str.startswith("-"): kor = "마이너스 " + kor return kor + unit_str ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/number_norm.py ================================================ # -*- coding: utf-8 -*- # Copyright (c) 2017 Keith Ito # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """Number norm module.""" import re import inflect _inflect = inflect.engine() _comma_number_re = re.compile(r"([0-9][0-9\,]+[0-9])") _decimal_number_re = re.compile(r"([0-9]+\.[0-9]+)") _pounds_re = re.compile(r"£([0-9\,]*[0-9]+)") _dollars_re = re.compile(r"\$([0-9\.\,]*[0-9]+)") _ordinal_re = re.compile(r"[0-9]+(st|nd|rd|th)") _number_re = re.compile(r"[0-9]+") def _remove_commas(m): return m.group(1).replace(",", "") def _expand_decimal_point(m): return m.group(1).replace(".", " point ") def _expand_dollars(m): match = m.group(1) parts = match.split(".") if len(parts) > 2: return match + " dollars" # Unexpected format dollars = int(parts[0]) if parts[0] else 0 cents = int(parts[1]) if len(parts) > 1 and parts[1] else 0 if dollars and cents: dollar_unit = "dollar" if dollars == 1 else "dollars" cent_unit = "cent" if cents == 1 else "cents" return "%s %s, %s %s" % (dollars, dollar_unit, cents, cent_unit) elif dollars: dollar_unit = "dollar" if dollars == 1 else "dollars" return "%s %s" % (dollars, dollar_unit) elif cents: cent_unit = "cent" if cents == 1 else "cents" return "%s %s" % (cents, cent_unit) else: return "zero dollars" def _expand_ordinal(m): return _inflect.number_to_words(m.group(0)) def _expand_number(m): num = int(m.group(0)) if num > 1000 and num < 3000: if num == 2000: return "two thousand" elif num > 2000 and num < 2010: return "two thousand " + _inflect.number_to_words(num % 100) elif num % 100 == 0: return _inflect.number_to_words(num // 100) + " hundred" else: return _inflect.number_to_words( num, andword="", zero="oh", group=2 ).replace(", ", " ") else: return _inflect.number_to_words(num, andword="") def normalize_numbers(text): text = re.sub(_comma_number_re, _remove_commas, text) text = re.sub(_pounds_re, r"\1 pounds", text) text = re.sub(_dollars_re, _expand_dollars, text) text = re.sub(_decimal_number_re, _expand_decimal_point, text) text = re.sub(_ordinal_re, _expand_ordinal, text) text = re.sub(_number_re, _expand_number, text) return text ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/outliers.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Outliers detection and remove.""" import numpy as np def is_outlier(x, p25, p75): """Check if value is an outlier.""" lower = p25 - 1.5 * (p75 - p25) upper = p75 + 1.5 * (p75 - p25) return x <= lower or x >= upper def remove_outlier(x, p_bottom: int = 25, p_top: int = 75): """Remove outlier from x.""" p_bottom = np.percentile(x, p_bottom) p_top = np.percentile(x, p_top) indices_of_outliers = [] for ind, value in enumerate(x): if is_outlier(value, p_bottom, p_top): indices_of_outliers.append(ind) x[indices_of_outliers] = 0.0 # replace by mean f0. x[indices_of_outliers] = np.max(x) return x ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/strategy.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Strategy util functions""" import tensorflow as tf def return_strategy(): physical_devices = tf.config.list_physical_devices("GPU") if len(physical_devices) == 0: return tf.distribute.OneDeviceStrategy(device="/cpu:0") elif len(physical_devices) == 1: return tf.distribute.OneDeviceStrategy(device="/gpu:0") else: return tf.distribute.MirroredStrategy() def calculate_3d_loss(y_gt, y_pred, loss_fn): """Calculate 3d loss, normally it's mel-spectrogram loss.""" y_gt_T = tf.shape(y_gt)[1] y_pred_T = tf.shape(y_pred)[1] # there is a mismath length when training multiple GPU. # we need slice the longer tensor to make sure the loss # calculated correctly. if y_gt_T > y_pred_T: y_gt = tf.slice(y_gt, [0, 0, 0], [-1, y_pred_T, -1]) elif y_pred_T > y_gt_T: y_pred = tf.slice(y_pred, [0, 0, 0], [-1, y_gt_T, -1]) loss = loss_fn(y_gt, y_pred) if isinstance(loss, tuple) is False: loss = tf.reduce_mean(loss, list(range(1, len(loss.shape)))) # shape = [B] else: loss = list(loss) for i in range(len(loss)): loss[i] = tf.reduce_mean( loss[i], list(range(1, len(loss[i].shape))) ) # shape = [B] return loss def calculate_2d_loss(y_gt, y_pred, loss_fn): """Calculate 2d loss, normally it's durrations/f0s/energys loss.""" y_gt_T = tf.shape(y_gt)[1] y_pred_T = tf.shape(y_pred)[1] # there is a mismath length when training multiple GPU. # we need slice the longer tensor to make sure the loss # calculated correctly. if y_gt_T > y_pred_T: y_gt = tf.slice(y_gt, [0, 0], [-1, y_pred_T]) elif y_pred_T > y_gt_T: y_pred = tf.slice(y_pred, [0, 0], [-1, y_gt_T]) loss = loss_fn(y_gt, y_pred) if isinstance(loss, tuple) is False: loss = tf.reduce_mean(loss, list(range(1, len(loss.shape)))) # shape = [B] else: loss = list(loss) for i in range(len(loss)): loss[i] = tf.reduce_mean( loss[i], list(range(1, len(loss[i].shape))) ) # shape = [B] return loss def calculate_loss_norm_lens(y_gt, y_pred, loss_fn, norm_lens): if len(y_gt.shape) == 2: y_gt = tf.expand_dims(y_gt, -1) y_pred = tf.expand_dims(y_pred, -1) loss = loss_fn(y_gt, y_pred) loss = tf.reduce_sum(loss, list(range(1, len(loss.shape)))) loss = loss / tf.cast(norm_lens, loss.dtype) return loss ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/utils.py ================================================ # -*- coding: utf-8 -*- # Copyright 2019 Tomoki Hayashi # MIT License (https://opensource.org/licenses/MIT) """Utility functions.""" import fnmatch import os def find_files(root_dir, query="*.wav", include_root_dir=True): """Find files recursively. Args: root_dir (str): Root root_dir to find. query (str): Query to find. include_root_dir (bool): If False, root_dir name is not included. Returns: list: List of found filenames. """ files = [] for root, _, filenames in os.walk(root_dir, followlinks=True): for filename in fnmatch.filter(filenames, query): files.append(os.path.join(root, filename)) if not include_root_dir: files = [file_.replace(root_dir + "/", "") for file_ in files] return files ================================================ FILE: TensorFlowTTS/tensorflow_tts/utils/weight_norm.py ================================================ # -*- coding: utf-8 -*- # Copyright 2019 The TensorFlow Probability Authors and Minh Nguyen (@dathudeptrai) # # 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. """Weight Norm Modules.""" import warnings import tensorflow as tf class WeightNormalization(tf.keras.layers.Wrapper): """Layer wrapper to decouple magnitude and direction of the layer's weights. This wrapper reparameterizes a layer by decoupling the weight's magnitude and direction. This speeds up convergence by improving the conditioning of the optimization problem. It has an optional data-dependent initialization scheme, in which initial values of weights are set as functions of the first minibatch of data. Both the weight normalization and data- dependent initialization are described in [Salimans and Kingma (2016)][1]. #### Example ```python net = WeightNorm(tf.keras.layers.Conv2D(2, 2, activation='relu'), input_shape=(32, 32, 3), data_init=True)(x) net = WeightNorm(tf.keras.layers.Conv2DTranspose(16, 5, activation='relu'), data_init=True) net = WeightNorm(tf.keras.layers.Dense(120, activation='relu'), data_init=True)(net) net = WeightNorm(tf.keras.layers.Dense(num_classes), data_init=True)(net) ``` #### References [1]: Tim Salimans and Diederik P. Kingma. Weight Normalization: A Simple Reparameterization to Accelerate Training of Deep Neural Networks. In _30th Conference on Neural Information Processing Systems_, 2016. https://arxiv.org/abs/1602.07868 """ def __init__(self, layer, data_init=True, **kwargs): """Initialize WeightNorm wrapper. Args: layer: A `tf.keras.layers.Layer` instance. Supported layer types are `Dense`, `Conv2D`, and `Conv2DTranspose`. Layers with multiple inputs are not supported. data_init: `bool`, if `True` use data dependent variable initialization. **kwargs: Additional keyword args passed to `tf.keras.layers.Wrapper`. Raises: ValueError: If `layer` is not a `tf.keras.layers.Layer` instance. """ if not isinstance(layer, tf.keras.layers.Layer): raise ValueError( "Please initialize `WeightNorm` layer with a `tf.keras.layers.Layer` " "instance. You passed: {input}".format(input=layer) ) layer_type = type(layer).__name__ if layer_type not in [ "Dense", "Conv2D", "Conv2DTranspose", "Conv1D", "GroupConv1D", ]: warnings.warn( "`WeightNorm` is tested only for `Dense`, `Conv2D`, `Conv1D`, `GroupConv1D`, " "`GroupConv2D`, and `Conv2DTranspose` layers. You passed a layer of type `{}`".format( layer_type ) ) super().__init__(layer, **kwargs) self.data_init = data_init self._track_trackable(layer, name="layer") self.filter_axis = -2 if layer_type == "Conv2DTranspose" else -1 def _compute_weights(self): """Generate weights with normalization.""" # Determine the axis along which to expand `g` so that `g` broadcasts to # the shape of `v`. new_axis = -self.filter_axis - 3 self.layer.kernel = tf.nn.l2_normalize( self.v, axis=self.kernel_norm_axes ) * tf.expand_dims(self.g, new_axis) def _init_norm(self): """Set the norm of the weight vector.""" kernel_norm = tf.sqrt( tf.reduce_sum(tf.square(self.v), axis=self.kernel_norm_axes) ) self.g.assign(kernel_norm) def _data_dep_init(self, inputs): """Data dependent initialization.""" # Normalize kernel first so that calling the layer calculates # `tf.dot(v, x)/tf.norm(v)` as in (5) in ([Salimans and Kingma, 2016][1]). self._compute_weights() activation = self.layer.activation self.layer.activation = None use_bias = self.layer.bias is not None if use_bias: bias = self.layer.bias self.layer.bias = tf.zeros_like(bias) # Since the bias is initialized as zero, setting the activation to zero and # calling the initialized layer (with normalized kernel) yields the correct # computation ((5) in Salimans and Kingma (2016)) x_init = self.layer(inputs) norm_axes_out = list(range(x_init.shape.rank - 1)) m_init, v_init = tf.nn.moments(x_init, norm_axes_out) scale_init = 1.0 / tf.sqrt(v_init + 1e-10) self.g.assign(self.g * scale_init) if use_bias: self.layer.bias = bias self.layer.bias.assign(-m_init * scale_init) self.layer.activation = activation def build(self, input_shape=None): """Build `Layer`. Args: input_shape: The shape of the input to `self.layer`. Raises: ValueError: If `Layer` does not contain a `kernel` of weights """ if not self.layer.built: self.layer.build(input_shape) if not hasattr(self.layer, "kernel"): raise ValueError( "`WeightNorm` must wrap a layer that" " contains a `kernel` for weights" ) self.kernel_norm_axes = list(range(self.layer.kernel.shape.ndims)) self.kernel_norm_axes.pop(self.filter_axis) self.v = self.layer.kernel # to avoid a duplicate `kernel` variable after `build` is called self.layer.kernel = None self.g = self.add_weight( name="g", shape=(int(self.v.shape[self.filter_axis]),), initializer="ones", dtype=self.v.dtype, trainable=True, ) self.initialized = self.add_weight( name="initialized", dtype=tf.bool, trainable=False ) self.initialized.assign(False) super().build() def call(self, inputs): """Call `Layer`.""" if not self.initialized: if self.data_init: self._data_dep_init(inputs) else: # initialize `g` as the norm of the initialized kernel self._init_norm() self.initialized.assign(True) self._compute_weights() output = self.layer(inputs) return output def compute_output_shape(self, input_shape): return tf.TensorShape(self.layer.compute_output_shape(input_shape).as_list()) ================================================ FILE: UnetTTS_syn.py ================================================ import re from pathlib import Path import numpy as np import soundfile as sf import tensorflow as tf import yaml from tensorflow_tts.audio_process import preprocess_wav from tensorflow_tts.audio_process.audio_spec import AudioMelSpec from tensorflow_tts.inference import AutoConfig, AutoProcessor, TFAutoModel class UnetTTS(): def __init__(self, models_and_params, text2id_mapper, feats_yaml): self.models_and_params = models_and_params self.text2id_mapper = text2id_mapper self.feats_yaml = feats_yaml self.rhythm_txt_pat = re.compile("[^\u4e00-\u9fa5^a-z^A-Z^'^\-^#\d]") self.duration_stats_default = np.array([8.7, 2.8, 10.4, 4.7]) self.text_id_start = [1, 17, 79, 12, 49] self.text_id_end = [25, 35, 13, 90, 1] self.phone_dur_min = 5 self.phone_dur_max = 20 self.__init_models() def one_shot_TTS(self, text, src_audio, duration_stats=None, is_wrap_txt=True): char_ids = self.txt2ids(text) # print(char_ids) mel_src = self.mel_feats_extractor(src_audio) if duration_stats is None: print("The statistics of the reference speech duration is calculated using the Style_Encoder.") duration_stats = self.infer_duration_stats(mel_src) print("Duration statistics equal to {}".format(duration_stats)) elif len(duration_stats) != 4: print("Warning: The dimension of the reference speech duration'statistics of is not equal to 4, use default.") duration_stats = self.duration_stats_default if is_wrap_txt: char_ids = self.text_id_start + char_ids + self.text_id_end dur_pred = self.duration_model.inference( char_ids = tf.expand_dims(tf.convert_to_tensor(char_ids, dtype=tf.int32), 0), duration_stat = tf.expand_dims(tf.convert_to_tensor(duration_stats, dtype=tf.float32), 0) ) dur_gts = np.round(dur_pred[0].numpy()).astype(np.int32) mel_pred, _, _ = self.acous_model.inference( char_ids = tf.expand_dims(tf.convert_to_tensor(char_ids, dtype=tf.int32), 0), duration_gts = tf.expand_dims(tf.convert_to_tensor(dur_gts, dtype=tf.int32), 0), mel_src = tf.expand_dims(tf.convert_to_tensor(mel_src, dtype=tf.float32), 0) ) if is_wrap_txt: start_dur = sum([dur_gts[i] for i in range(len(self.text_id_start))]) end_dur = sum([dur_gts[-i] for i in range(1, len(self.text_id_end)+1)]) audio = self.vocoder_model.inference(mel_pred[:, start_dur:-end_dur, :])[0, :, 0].numpy() return audio, mel_pred.numpy()[0][start_dur:-end_dur], mel_src else: audio = self.vocoder_model.inference(mel_pred)[0, :, 0].numpy() return audio, mel_pred.numpy()[0], mel_src def __init_models(self): self.processor = AutoProcessor.from_pretrained(pretrained_path=self.text2id_mapper) self.feats_config = yaml.load(open(self.feats_yaml), Loader=yaml.Loader) self.feats_handle = AudioMelSpec(**self.feats_config["feat_params"]) # print(self.feats_config) self.duration_model = TFAutoModel.from_pretrained(config=AutoConfig.from_pretrained(self.models_and_params["duration_param"]), pretrained_path=self.models_and_params["duration_model"], name="Normalized_duration_predictor") print("duration model load finished.") self.acous_model = TFAutoModel.from_pretrained(config=AutoConfig.from_pretrained(self.models_and_params["acous_param"]), pretrained_path=self.models_and_params["acous_model"], name="Unet-TTS") print("acoustics model load finished.") self.vocoder_model = TFAutoModel.from_pretrained(config=AutoConfig.from_pretrained(self.models_and_params["vocoder_param"]), pretrained_path=self.models_and_params["vocoder_model"], name="Mb_MelGan") print("vocode model load finished.") def _stats_duration(self, dur_pos_embed): dur_pos_embed = dur_pos_embed[0].numpy() embed_num = dur_pos_embed.shape[-1] # 4 mean = [] std = [] for i in range(embed_num): dur_pred = [] phone_num = 0 last = dur_pos_embed[1:, i][0] for j in dur_pos_embed[2:-1, i]: phone_num += 1 if (phone_num >= self.phone_dur_max) or \ (i <= 1 and j > last and phone_num >= self.phone_dur_min) or \ (i > 1 and j < last and phone_num >= self.phone_dur_min): dur_pred.append(phone_num) phone_num = 0 last = j mean.append(np.mean(dur_pred)) std.append(np.std(dur_pred)) return np.mean(mean)*1.0, np.mean(std)*0.8, np.mean(mean)*1.2, np.mean(std)*1.5 def mel_feats_extractor(self, audio): return self.feats_handle.melspectrogram(audio) def txt2ids(self, input_text): assert re.search(self.rhythm_txt_pat, input_text) == None, "Remove punctuation" input_ids = self.processor.text_to_sequence(input_text, inference=True) return input_ids def infer_duration_stats(self, mel_src): dur_pos_embed = self.acous_model.extract_dur_pos_embed( tf.expand_dims(tf.convert_to_tensor(mel_src, dtype=tf.float32), 0) ) return self._stats_duration(dur_pos_embed) if __name__ == '__main__': """ More examples can be seen in notebook. """ models_and_params = {"duration_param": "train/configs/unetts_duration.yaml", "duration_model": "models/duration4k.h5", "acous_param": "train/configs/unetts_acous.yaml", "acous_model": "models/acous12k.h5", "vocoder_param": "train/configs/multiband_melgan.yaml", "vocoder_model": "models/vocoder800k.h5"} feats_yaml = "train/configs/unetts_preprocess.yaml" text2id_mapper = "models/unetts_mapper.json" emotional_src_wav = {"neutral":{"wav": "test_wavs/neutral.wav", "dur_stat": "test_wavs/neutral_dur_stat.npy", "text": "现在全城的人都要向我借钱了"}, "happy": {"wav": "test_wavs/happy.wav", "dur_stat": "test_wavs/happy_dur_stat.npy", "text": "我参加了一个有关全球变暖的集会"}, "surprise": {"wav": "test_wavs/surprise.wav", "dur_stat": "test_wavs/surprise_dur_stat.npy", "text": "沙尘暴好像给每个人都带来了麻烦"}, "angry": {"wav": "test_wavs/angry.wav", "dur_stat": "test_wavs/angry_dur_stat.npy", "text": "不管怎么说主队好象是志在夺魁"}, "sad": {"wav": "test_wavs/sad.wav", "dur_stat": "test_wavs/sad_dur_stat.npy", "text": "我必须再次感谢您的慷慨相助"}, } Tts_handel = UnetTTS(models_and_params, text2id_mapper, feats_yaml) emotion_type = "neutral" # Inserting #3 marks into text is regarded as punctuation, and synthetic speech can produce pause. text = emotional_src_wav[emotion_type]["text"] wav_fpath = Path(emotional_src_wav[emotion_type]["wav"]) src_audio = preprocess_wav(wav_fpath, source_sr=16000, normalize=True, trim_silence=True, is_sil_pad=True, vad_window_length=30, vad_moving_average_width=1, vad_max_silence_length=1) """ * The phoneme duration statistis of reference speech are composed of the initial and vowel of Chinese Pinyin, including their respective mean and standard deviation. They will scale and bias the predicted duration of phonemes and control the speed style of speech. * dur_stat = [initial_mean, initial_std, vowel_mean, vowel_std], like dur_stat = [10., 2., 8., 4.] * The value is the frame length, and the frame shift of this model is 200. * The accurate value of phoneme duration can be extracted by ASR, MFA and other tools, or the approximate value can be estimated using Style_Encoder. """ Using_Style_Encoder = True if Using_Style_Encoder: syn_audio, _, _ = Tts_handel.one_shot_TTS(text, src_audio) else: # or dur_stat = None, or dur_stat = np.array([10., 2., 8., 4.]) dur_stat = np.load(emotional_src_wav[emotion_type]["dur_stat"]) print("dur_stat:", dur_stat) syn_audio, _, _ = Tts_handel.one_shot_TTS(text, src_audio, dur_stat) sf.write("./syn.wav", syn_audio, 16000, subtype='PCM_16') ================================================ FILE: models/acous12k.h5 ================================================ [File too large to display: 49.3 MB] ================================================ FILE: models/unetts_mapper.json ================================================ {"symbol_to_id": {"pad": 0, "sil": 1, "#0": 2, "#1": 3, "#3": 4, "^": 5, "b": 6, "c": 7, "ch": 8, "d": 9, "f": 10, "g": 11, "h": 12, "j": 13, "k": 14, "l": 15, "m": 16, "n": 17, "p": 18, "q": 19, "r": 20, "s": 21, "sh": 22, "t": 23, "x": 24, "z": 25, "zh": 26, "a1": 27, "a2": 28, "a3": 29, "a4": 30, "a5": 31, "ai1": 32, "ai2": 33, "ai3": 34, "ai4": 35, "ai5": 36, "an1": 37, "an2": 38, "an3": 39, "an4": 40, "an5": 41, "ang1": 42, "ang2": 43, "ang3": 44, "ang4": 45, "ang5": 46, "ao1": 47, "ao2": 48, "ao3": 49, "ao4": 50, "ao5": 51, "e1": 52, "e2": 53, "e3": 54, "e4": 55, "e5": 56, "ei1": 57, "ei2": 58, "ei3": 59, "ei4": 60, "ei5": 61, "en1": 62, "en2": 63, "en3": 64, "en4": 65, "en5": 66, "eng1": 67, "eng2": 68, "eng3": 69, "eng4": 70, "eng5": 71, "er1": 72, "er2": 73, "er3": 74, "er4": 75, "er5": 76, "i1": 77, "i2": 78, "i3": 79, "i4": 80, "i5": 81, "ia1": 82, "ia2": 83, "ia3": 84, "ia4": 85, "ia5": 86, "ian1": 87, "ian2": 88, "ian3": 89, "ian4": 90, "ian5": 91, "iang1": 92, "iang2": 93, "iang3": 94, "iang4": 95, "iang5": 96, "iao1": 97, "iao2": 98, "iao3": 99, "iao4": 100, "iao5": 101, "ie1": 102, "ie2": 103, "ie3": 104, "ie4": 105, "ie5": 106, "ii1": 107, "ii2": 108, "ii3": 109, "ii4": 110, "ii5": 111, "iii1": 112, "iii2": 113, "iii3": 114, "iii4": 115, "iii5": 116, "in1": 117, "in2": 118, "in3": 119, "in4": 120, "in5": 121, "ing1": 122, "ing2": 123, "ing3": 124, "ing4": 125, "ing5": 126, "iong1": 127, "iong2": 128, "iong3": 129, "iong4": 130, "iong5": 131, "iou1": 132, "iou2": 133, "iou3": 134, "iou4": 135, "iou5": 136, "o1": 137, "o2": 138, "o3": 139, "o4": 140, "o5": 141, "ong1": 142, "ong2": 143, "ong3": 144, "ong4": 145, "ong5": 146, "ou1": 147, "ou2": 148, "ou3": 149, "ou4": 150, "ou5": 151, "u1": 152, "u2": 153, "u3": 154, "u4": 155, "u5": 156, "ua1": 157, "ua2": 158, "ua3": 159, "ua4": 160, "ua5": 161, "uai1": 162, "uai2": 163, "uai3": 164, "uai4": 165, "uai5": 166, "uan1": 167, "uan2": 168, "uan3": 169, "uan4": 170, "uan5": 171, "uang1": 172, "uang2": 173, "uang3": 174, "uang4": 175, "uang5": 176, "uei1": 177, "uei2": 178, "uei3": 179, "uei4": 180, "uei5": 181, "uen1": 182, "uen2": 183, "uen3": 184, "uen4": 185, "uen5": 186, "ueng1": 187, "ueng2": 188, "ueng3": 189, "ueng4": 190, "ueng5": 191, "uo1": 192, "uo2": 193, "uo3": 194, "uo4": 195, "uo5": 196, "v1": 197, "v2": 198, "v3": 199, "v4": 200, "v5": 201, "van1": 202, "van2": 203, "van3": 204, "van4": 205, "van5": 206, "ve1": 207, "ve2": 208, "ve3": 209, "ve4": 210, "ve5": 211, "vn1": 212, "vn2": 213, "vn3": 214, "vn4": 215, "vn5": 216}, "id_to_symbol": {"0": "pad", "1": "sil", "2": "#0", "3": "#1", "4": "#3", "5": "^", "6": "b", "7": "c", "8": "ch", "9": "d", "10": "f", "11": "g", "12": "h", "13": "j", "14": "k", "15": "l", "16": "m", "17": "n", "18": "p", "19": "q", "20": "r", "21": "s", "22": "sh", "23": "t", "24": "x", "25": "z", "26": "zh", "27": "a1", "28": "a2", "29": "a3", "30": "a4", "31": "a5", "32": "ai1", "33": "ai2", "34": "ai3", "35": "ai4", "36": "ai5", "37": "an1", "38": "an2", "39": "an3", "40": "an4", "41": "an5", "42": "ang1", "43": "ang2", "44": "ang3", "45": "ang4", "46": "ang5", "47": "ao1", "48": "ao2", "49": "ao3", "50": "ao4", "51": "ao5", "52": "e1", "53": "e2", "54": "e3", "55": "e4", "56": "e5", "57": "ei1", "58": "ei2", "59": "ei3", "60": "ei4", "61": "ei5", "62": "en1", "63": "en2", "64": "en3", "65": "en4", "66": "en5", "67": "eng1", "68": "eng2", "69": "eng3", "70": "eng4", "71": "eng5", "72": "er1", "73": "er2", "74": "er3", "75": "er4", "76": "er5", "77": "i1", "78": "i2", "79": "i3", "80": "i4", "81": "i5", "82": "ia1", "83": "ia2", "84": "ia3", "85": "ia4", "86": "ia5", "87": "ian1", "88": "ian2", "89": "ian3", "90": "ian4", "91": "ian5", "92": "iang1", "93": "iang2", "94": "iang3", "95": "iang4", "96": "iang5", "97": "iao1", "98": "iao2", "99": "iao3", "100": "iao4", "101": "iao5", "102": "ie1", "103": "ie2", "104": "ie3", "105": "ie4", "106": "ie5", "107": "ii1", "108": "ii2", "109": "ii3", "110": "ii4", "111": "ii5", "112": "iii1", "113": "iii2", "114": "iii3", "115": "iii4", "116": "iii5", "117": "in1", "118": "in2", "119": "in3", "120": "in4", "121": "in5", "122": "ing1", "123": "ing2", "124": "ing3", "125": "ing4", "126": "ing5", "127": "iong1", "128": "iong2", "129": "iong3", "130": "iong4", "131": "iong5", "132": "iou1", "133": "iou2", "134": "iou3", "135": "iou4", "136": "iou5", "137": "o1", "138": "o2", "139": "o3", "140": "o4", "141": "o5", "142": "ong1", "143": "ong2", "144": "ong3", "145": "ong4", "146": "ong5", "147": "ou1", "148": "ou2", "149": "ou3", "150": "ou4", "151": "ou5", "152": "u1", "153": "u2", "154": "u3", "155": "u4", "156": "u5", "157": "ua1", "158": "ua2", "159": "ua3", "160": "ua4", "161": "ua5", "162": "uai1", "163": "uai2", "164": "uai3", "165": "uai4", "166": "uai5", "167": "uan1", "168": "uan2", "169": "uan3", "170": "uan4", "171": "uan5", "172": "uang1", "173": "uang2", "174": "uang3", "175": "uang4", "176": "uang5", "177": "uei1", "178": "uei2", "179": "uei3", "180": "uei4", "181": "uei5", "182": "uen1", "183": "uen2", "184": "uen3", "185": "uen4", "186": "uen5", "187": "ueng1", "188": "ueng2", "189": "ueng3", "190": "ueng4", "191": "ueng5", "192": "uo1", "193": "uo2", "194": "uo3", "195": "uo4", "196": "uo5", "197": "v1", "198": "v2", "199": "v3", "200": "v4", "201": "v5", "202": "van1", "203": "van2", "204": "van3", "205": "van4", "206": "van5", "207": "ve1", "208": "ve2", "209": "ve3", "210": "ve4", "211": "ve5", "212": "vn1", "213": "vn2", "214": "vn3", "215": "vn4", "216": "vn5"}, "speakers_map": {}, "processor_name": "MultiSPKVoiceCloneProcessor", "pinyin_dict": {"a": ["^", "a"], "ai": ["^", "ai"], "an": ["^", "an"], "ang": ["^", "ang"], "ao": ["^", "ao"], "ba": ["b", "a"], "bai": ["b", "ai"], "ban": ["b", "an"], "bang": ["b", "ang"], "bao": ["b", "ao"], "be": ["b", "e"], "bei": ["b", "ei"], "ben": ["b", "en"], "beng": ["b", "eng"], "bi": ["b", "i"], "bian": ["b", "ian"], "biao": ["b", "iao"], "bie": ["b", "ie"], "bin": ["b", "in"], "bing": ["b", "ing"], "bo": ["b", "o"], "bu": ["b", "u"], "ca": ["c", "a"], "cai": ["c", "ai"], "can": ["c", "an"], "cang": ["c", "ang"], "cao": ["c", "ao"], "ce": ["c", "e"], "cen": ["c", "en"], "ceng": ["c", "eng"], "cha": ["ch", "a"], "chai": ["ch", "ai"], "chan": ["ch", "an"], "chang": ["ch", "ang"], "chao": ["ch", "ao"], "che": ["ch", "e"], "chen": ["ch", "en"], "cheng": ["ch", "eng"], "chi": ["ch", "iii"], "chong": ["ch", "ong"], "chou": ["ch", "ou"], "chu": ["ch", "u"], "chua": ["ch", "ua"], "chuai": ["ch", "uai"], "chuan": ["ch", "uan"], "chuang": ["ch", "uang"], "chui": ["ch", "uei"], "chun": ["ch", "uen"], "chuo": ["ch", "uo"], "ci": ["c", "ii"], "cong": ["c", "ong"], "cou": ["c", "ou"], "cu": ["c", "u"], "cuan": ["c", "uan"], "cui": ["c", "uei"], "cun": ["c", "uen"], "cuo": ["c", "uo"], "da": ["d", "a"], "dai": ["d", "ai"], "dan": ["d", "an"], "dang": ["d", "ang"], "dao": ["d", "ao"], "de": ["d", "e"], "dei": ["d", "ei"], "den": ["d", "en"], "deng": ["d", "eng"], "di": ["d", "i"], "dia": ["d", "ia"], "dian": ["d", "ian"], "diao": ["d", "iao"], "die": ["d", "ie"], "ding": ["d", "ing"], "diu": ["d", "iou"], "dong": ["d", "ong"], "dou": ["d", "ou"], "du": ["d", "u"], "duan": ["d", "uan"], "dui": ["d", "uei"], "dun": ["d", "uen"], "duo": ["d", "uo"], "e": ["^", "e"], "ei": ["^", "ei"], "en": ["^", "en"], "ng": ["^", "en"], "eng": ["^", "eng"], "er": ["^", "er"], "fa": ["f", "a"], "fan": ["f", "an"], "fang": ["f", "ang"], "fei": ["f", "ei"], "fen": ["f", "en"], "feng": ["f", "eng"], "fo": ["f", "o"], "fou": ["f", "ou"], "fu": ["f", "u"], "ga": ["g", "a"], "gai": ["g", "ai"], "gan": ["g", "an"], "gang": ["g", "ang"], "gao": ["g", "ao"], "ge": ["g", "e"], "gei": ["g", "ei"], "gen": ["g", "en"], "geng": ["g", "eng"], "gong": ["g", "ong"], "gou": ["g", "ou"], "gu": ["g", "u"], "gua": ["g", "ua"], "guai": ["g", "uai"], "guan": ["g", "uan"], "guang": ["g", "uang"], "gui": ["g", "uei"], "gun": ["g", "uen"], "guo": ["g", "uo"], "ha": ["h", "a"], "hai": ["h", "ai"], "han": ["h", "an"], "hang": ["h", "ang"], "hao": ["h", "ao"], "he": ["h", "e"], "hei": ["h", "ei"], "hen": ["h", "en"], "heng": ["h", "eng"], "hong": ["h", "ong"], "hou": ["h", "ou"], "hu": ["h", "u"], "hua": ["h", "ua"], "huai": ["h", "uai"], "huan": ["h", "uan"], "huang": ["h", "uang"], "hui": ["h", "uei"], "hun": ["h", "uen"], "huo": ["h", "uo"], "ji": ["j", "i"], "jia": ["j", "ia"], "jian": ["j", "ian"], "jiang": ["j", "iang"], "jiao": ["j", "iao"], "jie": ["j", "ie"], "jin": ["j", "in"], "jing": ["j", "ing"], "jiong": ["j", "iong"], "jiu": ["j", "iou"], "ju": ["j", "v"], "juan": ["j", "van"], "jue": ["j", "ve"], "jun": ["j", "vn"], "ka": ["k", "a"], "kai": ["k", "ai"], "kan": ["k", "an"], "kang": ["k", "ang"], "kao": ["k", "ao"], "ke": ["k", "e"], "kei": ["k", "ei"], "ken": ["k", "en"], "keng": ["k", "eng"], "kong": ["k", "ong"], "kou": ["k", "ou"], "ku": ["k", "u"], "kua": ["k", "ua"], "kuai": ["k", "uai"], "kuan": ["k", "uan"], "kuang": ["k", "uang"], "kui": ["k", "uei"], "kun": ["k", "uen"], "kuo": ["k", "uo"], "la": ["l", "a"], "lai": ["l", "ai"], "lan": ["l", "an"], "lang": ["l", "ang"], "lao": ["l", "ao"], "le": ["l", "e"], "lei": ["l", "ei"], "leng": ["l", "eng"], "li": ["l", "i"], "lia": ["l", "ia"], "lian": ["l", "ian"], "liang": ["l", "iang"], "liao": ["l", "iao"], "lie": ["l", "ie"], "lin": ["l", "in"], "ling": ["l", "ing"], "liu": ["l", "iou"], "lo": ["l", "o"], "long": ["l", "ong"], "lou": ["l", "ou"], "lu": ["l", "u"], "lv": ["l", "v"], "luan": ["l", "uan"], "lve": ["l", "ve"], "lue": ["l", "ve"], "lun": ["l", "uen"], "luo": ["l", "uo"], "ma": ["m", "a"], "mai": ["m", "ai"], "man": ["m", "an"], "mang": ["m", "ang"], "mao": ["m", "ao"], "me": ["m", "e"], "mei": ["m", "ei"], "men": ["m", "en"], "meng": ["m", "eng"], "mi": ["m", "i"], "mian": ["m", "ian"], "miao": ["m", "iao"], "mie": ["m", "ie"], "min": ["m", "in"], "ming": ["m", "ing"], "miu": ["m", "iou"], "mo": ["m", "o"], "mou": ["m", "ou"], "mu": ["m", "u"], "na": ["n", "a"], "nai": ["n", "ai"], "nan": ["n", "an"], "nang": ["n", "ang"], "nao": ["n", "ao"], "ne": ["n", "e"], "nei": ["n", "ei"], "nen": ["n", "en"], "neng": ["n", "eng"], "ni": ["n", "i"], "nia": ["n", "ia"], "nian": ["n", "ian"], "niang": ["n", "iang"], "niao": ["n", "iao"], "nie": ["n", "ie"], "nin": ["n", "in"], "ning": ["n", "ing"], "niu": ["n", "iou"], "nong": ["n", "ong"], "nou": ["n", "ou"], "nu": ["n", "u"], "nv": ["n", "v"], "nuan": ["n", "uan"], "nve": ["n", "ve"], "nue": ["n", "ve"], "nuo": ["n", "uo"], "o": ["^", "o"], "ou": ["^", "ou"], "pa": ["p", "a"], "pai": ["p", "ai"], "pan": ["p", "an"], "pang": ["p", "ang"], "pao": ["p", "ao"], "pe": ["p", "e"], "pei": ["p", "ei"], "pen": ["p", "en"], "peng": ["p", "eng"], "pi": ["p", "i"], "pian": ["p", "ian"], "piao": ["p", "iao"], "pie": ["p", "ie"], "pin": ["p", "in"], "ping": ["p", "ing"], "po": ["p", "o"], "pou": ["p", "ou"], "pu": ["p", "u"], "qi": ["q", "i"], "qia": ["q", "ia"], "qian": ["q", "ian"], "qiang": ["q", "iang"], "qiao": ["q", "iao"], "qie": ["q", "ie"], "qin": ["q", "in"], "qing": ["q", "ing"], "qiong": ["q", "iong"], "qiu": ["q", "iou"], "qu": ["q", "v"], "quan": ["q", "van"], "que": ["q", "ve"], "qun": ["q", "vn"], "ran": ["r", "an"], "rang": ["r", "ang"], "rao": ["r", "ao"], "re": ["r", "e"], "ren": ["r", "en"], "reng": ["r", "eng"], "ri": ["r", "iii"], "rong": ["r", "ong"], "rou": ["r", "ou"], "ru": ["r", "u"], "rua": ["r", "ua"], "ruan": ["r", "uan"], "rui": ["r", "uei"], "run": ["r", "uen"], "ruo": ["r", "uo"], "sa": ["s", "a"], "sai": ["s", "ai"], "san": ["s", "an"], "sang": ["s", "ang"], "sao": ["s", "ao"], "se": ["s", "e"], "sen": ["s", "en"], "seng": ["s", "eng"], "sha": ["sh", "a"], "shai": ["sh", "ai"], "shan": ["sh", "an"], "shang": ["sh", "ang"], "shao": ["sh", "ao"], "she": ["sh", "e"], "shei": ["sh", "ei"], "shen": ["sh", "en"], "sheng": ["sh", "eng"], "shi": ["sh", "iii"], "shou": ["sh", "ou"], "shu": ["sh", "u"], "shua": ["sh", "ua"], "shuai": ["sh", "uai"], "shuan": ["sh", "uan"], "shuang": ["sh", "uang"], "shui": ["sh", "uei"], "shun": ["sh", "uen"], "shuo": ["sh", "uo"], "si": ["s", "ii"], "song": ["s", "ong"], "sou": ["s", "ou"], "su": ["s", "u"], "suan": ["s", "uan"], "sui": ["s", "uei"], "sun": ["s", "uen"], "suo": ["s", "uo"], "ta": ["t", "a"], "tai": ["t", "ai"], "tan": ["t", "an"], "tang": ["t", "ang"], "tao": ["t", "ao"], "te": ["t", "e"], "tei": ["t", "ei"], "teng": ["t", "eng"], "ti": ["t", "i"], "tian": ["t", "ian"], "tiao": ["t", "iao"], "tie": ["t", "ie"], "ting": ["t", "ing"], "tong": ["t", "ong"], "tou": ["t", "ou"], "tu": ["t", "u"], "tuan": ["t", "uan"], "tui": ["t", "uei"], "tun": ["t", "uen"], "tuo": ["t", "uo"], "wa": ["^", "ua"], "wai": ["^", "uai"], "wan": ["^", "uan"], "wang": ["^", "uang"], "wei": ["^", "uei"], "wen": ["^", "uen"], "weng": ["^", "ueng"], "wo": ["^", "uo"], "wu": ["^", "u"], "xi": ["x", "i"], "xia": ["x", "ia"], "xian": ["x", "ian"], "xiang": ["x", "iang"], "xiao": ["x", "iao"], "xie": ["x", "ie"], "xin": ["x", "in"], "xing": ["x", "ing"], "xiong": ["x", "iong"], "xiu": ["x", "iou"], "xu": ["x", "v"], "xuan": ["x", "van"], "xue": ["x", "ve"], "xun": ["x", "vn"], "ya": ["^", "ia"], "yan": ["^", "ian"], "yang": ["^", "iang"], "yao": ["^", "iao"], "ye": ["^", "ie"], "yi": ["^", "i"], "yin": ["^", "in"], "ying": ["^", "ing"], "yo": ["^", "iou"], "yong": ["^", "iong"], "you": ["^", "iou"], "yu": ["^", "v"], "yuan": ["^", "van"], "yue": ["^", "ve"], "yun": ["^", "vn"], "za": ["z", "a"], "zai": ["z", "ai"], "zan": ["z", "an"], "zang": ["z", "ang"], "zao": ["z", "ao"], "ze": ["z", "e"], "zei": ["z", "ei"], "zen": ["z", "en"], "zeng": ["z", "eng"], "zha": ["zh", "a"], "zhai": ["zh", "ai"], "zhan": ["zh", "an"], "zhang": ["zh", "ang"], "zhao": ["zh", "ao"], "zhe": ["zh", "e"], "zhei": ["zh", "ei"], "zhen": ["zh", "en"], "zheng": ["zh", "eng"], "zhi": ["zh", "iii"], "zhong": ["zh", "ong"], "zhou": ["zh", "ou"], "zhu": ["zh", "u"], "zhua": ["zh", "ua"], "zhuai": ["zh", "uai"], "zhuan": ["zh", "uan"], "zhuang": ["zh", "uang"], "zhui": ["zh", "uei"], "zhun": ["zh", "uen"], "zhuo": ["zh", "uo"], "zi": ["z", "ii"], "zong": ["z", "ong"], "zou": ["z", "ou"], "zu": ["z", "u"], "zuan": ["z", "uan"], "zui": ["z", "uei"], "zun": ["z", "uen"], "zuo": ["z", "uo"]}} ================================================ FILE: notebook/OneShotVoiceClone_Inference.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "e0ebb61b", "metadata": {}, "outputs": [], "source": [ "import os, sys\n", "sys.path.append(\"..\")\n", "\n", "import numpy as np\n", "import IPython.display as ipd\n", "from pathlib import Path\n", "\n", "from tensorflow_tts.audio_process import preprocess_wav\n", "from UnetTTS_syn import UnetTTS" ] }, { "cell_type": "code", "execution_count": 2, "id": "d2e5af55", "metadata": {}, "outputs": [], "source": [ "os.environ[\"CUDA_VISIBLE_DEVICES\"]= \"0\"" ] }, { "cell_type": "code", "execution_count": 3, "id": "e2721028", "metadata": {}, "outputs": [], "source": [ "models_and_params = {\"duration_param\": \"../train/configs/unetts_duration.yaml\",\n", " \"duration_model\": \"../models/duration4k.h5\",\n", " \"acous_param\": \"../train/configs/unetts_acous.yaml\",\n", " \"acous_model\": \"../models/acous12k.h5\",\n", " \"vocoder_param\": \"../train/configs/multiband_melgan.yaml\",\n", " \"vocoder_model\": \"../models/vocoder800k.h5\"}\n", "\n", "feats_yaml = \"../train/configs/unetts_preprocess.yaml\"\n", "\n", "text2id_mapper = \"../models/unetts_mapper.json\"" ] }, { "cell_type": "code", "execution_count": 4, "id": "efa01cf3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "duration model load finished.\n", "acoustics model load finished.\n", "vocode model load finished.\n" ] } ], "source": [ "Tts_handel = UnetTTS(models_and_params, text2id_mapper, feats_yaml)" ] }, { "cell_type": "code", "execution_count": 5, "id": "76b70ddc", "metadata": {}, "outputs": [], "source": [ "emotional_src_wav = {\"neutral\":{\"wav\": \"../test_wavs/neutral.wav\",\n", " \"dur_stat\": \"../test_wavs/neutral_dur_stat.npy\",\n", " \"text\": \"现在全城的人都要向我借钱了\"},\n", " \"happy\": {\"wav\": \"../test_wavs/happy.wav\",\n", " \"dur_stat\": \"../test_wavs/happy_dur_stat.npy\",\n", " \"text\": \"我参加了一个有关全球变暖的集会\"},\n", " \"surprise\": {\"wav\": \"../test_wavs/surprise.wav\",\n", " \"dur_stat\": \"../test_wavs/surprise_dur_stat.npy\",\n", " \"text\": \"沙尘暴好像给每个人都带来了麻烦\"},\n", " \"angry\": {\"wav\": \"../test_wavs/angry.wav\",\n", " \"dur_stat\": \"../test_wavs/angry_dur_stat.npy\",\n", " \"text\": \"不管怎么说主队好象是志在夺魁\"},\n", " \"sad\": {\"wav\": \"../test_wavs/sad.wav\",\n", " \"dur_stat\": \"../test_wavs/sad_dur_stat.npy\",\n", " \"text\": \"我必须再次感谢您的慷慨相助\"},\n", " }" ] }, { "cell_type": "markdown", "id": "3d1686ba", "metadata": {}, "source": [ "# 1. Same Text as Reference\n", "- The phoneme duration statistis of reference speech are composed of the initial and vowel of Chinese Pinyin, including their respective mean and standard deviation. They will scale and bias the duration of phonemes and control the speed style of speech.\n", "- dur_stat = [initial_mean, initial_std, vowel_mean, vowel_std], like dur_stat = [10., 2., 8., 4.]\n", "- The value is the frame length, and the frame shift of this model is 200.\n", "- The accurate value of phoneme duration can be extracted by ASR, MFA and other tools, or the approximate value can be estimated manually." ] }, { "cell_type": "code", "execution_count": 6, "id": "8e035519", "metadata": {}, "outputs": [], "source": [ "# change emotion name[\"neutral\", \"happy\", \"surprise\", \"angry\", \"sad\"]\n", "emotion_type = \"angry\"\n", "text = emotional_src_wav[emotion_type][\"text\"]\n", "\n", "wav_fpath = Path(emotional_src_wav[emotion_type][\"wav\"])\n", "src_audio = preprocess_wav(wav_fpath, source_sr=16000, normalize=True, trim_silence=True, is_sil_pad=True,\n", " vad_window_length=30,\n", " vad_moving_average_width=1,\n", " vad_max_silence_length=1)" ] }, { "cell_type": "markdown", "id": "c812fe24", "metadata": {}, "source": [ "## 1.1 *You can Only use the reference speech for one-shot voice cloning, and the duration statistics of the reference speech can be estimated Automatically using Style_Encoder" ] }, { "cell_type": "code", "execution_count": 7, "id": "b29cbb6d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['bu4', 'guan3', 'zen3', 'me5', 'shuo1', 'zhu3', 'dui4', 'hao3', 'xiang4', 'shi4', 'zhi4', 'zai4', 'duo2', 'kui2']\n", "phoneme seq: sil b u4 g uan3 z en3 m e5 sh uo1 zh u3 d uei4 h ao3 x iang4 sh iii4 zh iii4 z ai4 d uo2 k uei2 sil\n", "The statistics of the reference speech duration is calculated using the Style_Encoder.\n", "Duration statistics equal to (7.2711597542242705, 2.0288354905751587, 8.725391705069125, 3.804066544828422)\n" ] } ], "source": [ "syn_audio, mel_pred, mel_src = Tts_handel.one_shot_TTS(text, src_audio, is_wrap_txt=False)" ] }, { "cell_type": "markdown", "id": "b9fd9924", "metadata": {}, "source": [ "### Refence_audio" ] }, { "cell_type": "code", "execution_count": 8, "id": "791be4c2", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# plt.plot(src_audio)\n", "Tts_handel.feats_handle.melspec_plot(mel_src)\n", "ipd.Audio(src_audio, rate=16000)" ] }, { "cell_type": "markdown", "id": "1fa53c42", "metadata": {}, "source": [ "### Synthetic audio\n", "- For faster inferencing, the multi-bank melgan vocoder is used here.\n", "- Using other vocoders, such as HiFi-Gan, WaveNet or WaveRNN can improve sound quality." ] }, { "cell_type": "code", "execution_count": 9, "id": "3666aefc", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# plt.plot(syn_audio)\n", "Tts_handel.feats_handle.melspec_plot(mel_pred)\n", "ipd.Audio(syn_audio, rate=16000)" ] }, { "cell_type": "markdown", "id": "0ec898b0", "metadata": {}, "source": [ "## 1.2 Or, you can input the exact duration statistics of the reference speech to improve the similarity." ] }, { "cell_type": "code", "execution_count": 10, "id": "ea5edb73", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "dur_stat: [7.214286 2.623481 7.142857 4.2904735]\n", "['bu4', 'guan3', 'zen3', 'me5', 'shuo1', 'zhu3', 'dui4', 'hao3', 'xiang4', 'shi4', 'zhi4', 'zai4', 'duo2', 'kui2']\n", "phoneme seq: sil b u4 g uan3 z en3 m e5 sh uo1 zh u3 d uei4 h ao3 x iang4 sh iii4 zh iii4 z ai4 d uo2 k uei2 sil\n" ] } ], "source": [ "dur_stat = np.load(emotional_src_wav[emotion_type][\"dur_stat\"])\n", "print(\"dur_stat:\", dur_stat)\n", "\n", "syn_audio, mel_pred, mel_src = Tts_handel.one_shot_TTS(text, src_audio, dur_stat, False)" ] }, { "cell_type": "code", "execution_count": 11, "id": "07801d72", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# plt.plot(syn_audio)\n", "Tts_handel.feats_handle.melspec_plot(mel_pred)\n", "ipd.Audio(syn_audio, rate=16000)" ] }, { "cell_type": "markdown", "id": "95d06cd7", "metadata": { "scrolled": false }, "source": [ "# 2. *Arbitrary Text" ] }, { "cell_type": "markdown", "id": "c1c18921", "metadata": {}, "source": [ "- Because the silence at both ends of the reference audio may cause pronunciation errors at the beginning and end of the generated speech. \n", "- So we add some characters at both ends of the input text as the new input of the synthesizer. \n", "- After the synthesis is completed, the audio of the added character is removed from the speech according to their phoneme frame length.\n", "- Inserting #3 marks into text is regarded as punctuation, and synthetic speech can produce pause." ] }, { "cell_type": "code", "execution_count": 12, "id": "6de3e38d", "metadata": {}, "outputs": [], "source": [ "# Inserting #3 marks into text is regarded as punctuation, and synthetic speech can produce pause.\n", "a_text = \"一句话#3风格迁移#3语音合成系统\"" ] }, { "cell_type": "code", "execution_count": 13, "id": "bd749ed6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['yi1', 'ju4', 'hua4', 'feng1', 'ge2', 'qian1', 'yi2', 'yu3', 'yin1', 'he2', 'cheng2', 'xi4', 'tong3']\n", "phoneme seq: sil ^ i1 j v4 h ua4 #3 f eng1 g e2 q ian1 ^ i2 #3 ^ v3 ^ in1 h e2 ch eng2 x i4 t ong3 sil\n", "The statistics of the reference speech duration is calculated using the Style_Encoder.\n", "Duration statistics equal to (7.955729166666667, 2.4811523765991477, 9.546875, 4.652160706123402)\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# change emotion name[\"neutral\", \"happy\", \"surprise\", \"angry\", \"sad\"]\n", "emotion_type = \"happy\"\n", "\n", "wav_fpath = Path(emotional_src_wav[emotion_type][\"wav\"])\n", "src_audio = preprocess_wav(wav_fpath, source_sr=16000, normalize=True, trim_silence=True, is_sil_pad=True,\n", " vad_window_length=30,\n", " vad_moving_average_width=1,\n", " vad_max_silence_length=1)\n", "\n", "text = a_text\n", "\n", "syn_audio, mel_pred, mel_src = Tts_handel.one_shot_TTS(text, src_audio)\n", "\n", "## or\n", "# dur_stat = np.load(emotional_src_wav[emotion_type][\"dur_stat\"])\n", "# print(\"dur_stat:\", dur_stat)\n", "# syn_audio, mel_pred, mel_src = Tts_handel.one_shot_TTS(text, src_audio, dur_stat)\n", "\n", "# plt.plot(syn_audio)\n", "Tts_handel.feats_handle.melspec_plot(mel_pred)\n", "ipd.Audio(syn_audio, rate=16000)" ] }, { "cell_type": "markdown", "id": "c032ae3f", "metadata": {}, "source": [ "# 3. Adjust speech speed according to the statistics of phoneme duration" ] }, { "cell_type": "code", "execution_count": 14, "id": "c07b16d5", "metadata": {}, "outputs": [], "source": [ "a_text = \"一句话#3风格迁移#3语音合成系统\"" ] }, { "cell_type": "code", "execution_count": 15, "id": "a11ce2b5", "metadata": {}, "outputs": [], "source": [ "# change emotion name[\"neutral\", \"happy\", \"surprise\", \"angry\", \"sad\"]\n", "emotion_type = \"happy\"\n", "\n", "wav_fpath = Path(emotional_src_wav[emotion_type][\"wav\"])\n", "\n", "src_audio = preprocess_wav(wav_fpath, source_sr=16000, normalize=True, trim_silence=True, is_sil_pad=True,\n", " vad_window_length=30,\n", " vad_moving_average_width=1,\n", " vad_max_silence_length=1)\n", "\n", "text = a_text" ] }, { "cell_type": "code", "execution_count": 16, "id": "35072516", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['yi1', 'ju4', 'hua4', 'feng1', 'ge2', 'qian1', 'yi2', 'yu3', 'yin1', 'he2', 'cheng2', 'xi4', 'tong3']\n", "phoneme seq: sil ^ i1 j v4 h ua4 #3 f eng1 g e2 q ian1 ^ i2 #3 ^ v3 ^ in1 h e2 ch eng2 x i4 t ong3 sil\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dur_stat = np.array([15, 6, 18, 9])\n", "\n", "syn_audio, mel_pred, mel_src = Tts_handel.one_shot_TTS(text, src_audio, dur_stat, True)\n", "\n", "# plt.plot(syn_audio)\n", "Tts_handel.feats_handle.melspec_plot(mel_pred)\n", "ipd.Audio(syn_audio, rate=16000)" ] }, { "cell_type": "code", "execution_count": 17, "id": "9f7a67ea", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['yi1', 'ju4', 'hua4', 'feng1', 'ge2', 'qian1', 'yi2', 'yu3', 'yin1', 'he2', 'cheng2', 'xi4', 'tong3']\n", "phoneme seq: sil ^ i1 j v4 h ua4 #3 f eng1 g e2 q ian1 ^ i2 #3 ^ v3 ^ in1 h e2 ch eng2 x i4 t ong3 sil\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dur_stat = np.array([10, 4, 12, 6])\n", "\n", "syn_audio, mel_pred, mel_src = Tts_handel.one_shot_TTS(text, src_audio, dur_stat, True)\n", "\n", "# plt.plot(syn_audio)\n", "Tts_handel.feats_handle.melspec_plot(mel_pred)\n", "ipd.Audio(syn_audio, rate=16000)" ] }, { "cell_type": "code", "execution_count": null, "id": "5cc68224", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "37dd49ef", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: train/configs/multiband_melgan.yaml ================================================ # This is the hyperparameter configuration file for Multi-Band MelGAN. # Please make sure this is adjusted for the Baker dataset. If you want to # apply to the other dataset, you might need to carefully change some parameters. # This configuration performs 1000k iters. ########################################################### # FEATURE EXTRACTION SETTING # ########################################################### sampling_rate: 16000 hop_size: 200 # Hop size. format: "npy" ########################################################### # GENERATOR NETWORK ARCHITECTURE SETTING # ########################################################### model_type: "multiband_melgan_generator" multiband_melgan_generator_params: out_channels: 4 # Number of output channels (number of subbands). kernel_size: 7 # Kernel size of initial and final conv layers. filters: 384 # Initial number of channels for conv layers. upsample_scales: [5, 5, 2] # List of Upsampling scales. stack_kernel_size: 3 # Kernel size of dilated conv layers in residual stack. stacks: 4 # Number of stacks in a single residual stack module. is_weight_norm: false # Use weight-norm or not. ########################################################### # DISCRIMINATOR NETWORK ARCHITECTURE SETTING # ########################################################### multiband_melgan_discriminator_params: out_channels: 1 # Number of output channels. scales: 3 # Number of multi-scales. downsample_pooling: "AveragePooling1D" # Pooling type for the input downsampling. downsample_pooling_params: # Parameters of the above pooling function. pool_size: 4 strides: 2 kernel_sizes: [5, 3] # List of kernel size. filters: 16 # Number of channels of the initial conv layer. max_downsample_filters: 512 # Maximum number of channels of downsampling layers. downsample_scales: [4, 4, 4] # List of downsampling scales. nonlinear_activation: "LeakyReLU" # Nonlinear activation function. nonlinear_activation_params: # Parameters of nonlinear activation function. alpha: 0.2 is_weight_norm: false # Use weight-norm or not. ########################################################### # STFT LOSS SETTING # ########################################################### stft_loss_params: fft_lengths: [1024, 2048, 512] # List of FFT size for STFT-based loss. frame_steps: [120, 240, 50] # List of hop size for STFT-based loss frame_lengths: [600, 1200, 240] # List of window length for STFT-based loss. subband_stft_loss_params: fft_lengths: [384, 683, 171] # List of FFT size for STFT-based loss. frame_steps: [30, 60, 10] # List of hop size for STFT-based loss frame_lengths: [150, 300, 60] # List of window length for STFT-based loss. ########################################################### # ADVERSARIAL LOSS SETTING # ########################################################### lambda_feat_match: 10.0 # Loss balancing coefficient for feature matching loss lambda_adv: 2.5 # Loss balancing coefficient for adversarial loss. ########################################################### # DATA LOADER SETTING # ########################################################### batch_size: 64 # Batch size. batch_max_steps: 6400 # Length of each audio in batch for training. Make sure dividable by hop_size. batch_max_steps_valid: 32000 # Length of each audio for validation. Make sure dividable by hope_size. remove_short_samples: true # Whether to remove samples the length of which are less than batch_max_steps. allow_cache: true # Whether to allow cache in dataset. If true, it requires cpu memory. is_shuffle: true # shuffle dataset after each epoch. ########################################################### # OPTIMIZER & SCHEDULER SETTING # ########################################################### generator_optimizer_params: lr_fn: "PiecewiseConstantDecay" lr_params: boundaries: [100000, 200000, 300000, 400000, 500000, 600000, 700000] # values: [0.001, 0.0005, 0.00025, 0.000125, 0.0000625, 0.00003125, 0.000015625, 0.000001] values: [0.0001, 0.0001, 0.0001, 0.0001, 0.0000625, 0.00003125, 0.000015625, 0.000001] amsgrad: false discriminator_optimizer_params: lr_fn: "PiecewiseConstantDecay" lr_params: boundaries: [100000, 200000, 300000, 400000, 500000] # values: [0.00025, 0.000125, 0.0000625, 0.00003125, 0.000015625, 0.000001] values: [0.0001, 0.0001, 0.0000625, 0.00003125, 0.000015625, 0.000001] amsgrad: false ########################################################### # INTERVAL SETTING # ########################################################### discriminator_train_start_steps: 200000 # steps begin training discriminator train_max_steps: 4000000 # Number of training steps. save_interval_steps: 20000 # Interval steps to save checkpoint. eval_interval_steps: 5000 # Interval steps to evaluate the network. log_interval_steps: 200 # Interval steps to record the training log. ########################################################### # OTHER SETTING # ########################################################### num_save_intermediate_results: 1 # Number of batch to be saved as intermediate results. ================================================ FILE: train/configs/unetts_acous.yaml ================================================ ########################################################### # FEATURE EXTRACTION SETTING # ########################################################### hop_size: 200 # Hop size. format: "npy" ########################################################### # NETWORK ARCHITECTURE SETTING # ########################################################### model_type: "unetts_acous" unetts_acous_params: dataset: multispk_voiceclone # content encoder encoder_hidden_size: 128 encoder_num_hidden_layers: 2 encoder_num_attention_heads: 2 encoder_attention_head_size: 64 encoder_intermediate_size: 512 encoder_intermediate_kernel_size: 3 encoder_hidden_act: "mish" addfeatures_num: 4 isaddur: False # AdaIN encoder and decoder content_latent_dim: 132 # content_latent_dim = proj(encoder_output) + (3 + (1 if isaddur else 0) if addfeatures_num else 0) n_conv_blocks: 6 adain_filter_size: 256 enc_kernel_size: 5 dec_kernel_size: 5 gen_kernel_size: 5 num_mels: 80 hidden_dropout_prob: 0.2 attention_probs_dropout_prob: 0.1 initializer_range: 0.02 output_attentions: False output_hidden_states: False unetts_acous_context_pre_params: dataset: multispk_voiceclone encoder_hidden_size: 128 encoder_num_hidden_layers: 2 encoder_num_attention_heads: 2 encoder_attention_head_size: 64 encoder_intermediate_size: 512 encoder_intermediate_kernel_size: 3 encoder_hidden_act: "mish" addfeatures_num: 4 isaddur: False content_latent_dim: 132 # content_latent_dim = proj(encoder_output) + (3 + (1 if isaddur else 0) if addfeatures_num else 0) decoder_is_conditional: True decoder_conditional_norm_type: "Instance" # "Layer" or "Instance" decoder_hidden_size: 132 decoder_num_hidden_layers: 3 decoder_num_attention_heads: 2 decoder_attention_head_size: 66 decoder_intermediate_size: 512 decoder_intermediate_kernel_size: 9 decoder_hidden_act: "mish" num_mels: 80 hidden_dropout_prob: 0.2 attention_probs_dropout_prob: 0.1 initializer_range: 0.02 output_attentions: False output_hidden_states: False ########################################################### # DATA LOADER SETTING # ########################################################### batch_size: 32 # Batch size. # remove_short_samples: true # Whether to remove samples the length of which are less than batch_max_steps. allow_cache: true # Whether to allow cache in dataset. If true, it requires cpu memory. # mel_length_threshold: 32 # remove all targets has mel_length <= 32 is_shuffle: true # shuffle dataset after each epoch. ########################################################### # OPTIMIZER & SCHEDULER SETTING # ########################################################### optimizer_params: initial_learning_rate: 0.001 end_learning_rate: 0.00001 decay_steps: 150000 # < train_max_steps is recommend. warmup_proportion: 0.02 weight_decay: 0.001 ########################################################### # INTERVAL SETTING # ########################################################### train_max_steps: 200000 # Number of training steps. save_interval_steps: 10000 # Interval steps to save checkpoint. eval_interval_steps: 2000 # Interval steps to evaluate the network. log_interval_steps: 250 # Interval steps to record the training log. ########################################################### # OTHER SETTING # ########################################################### num_save_intermediate_results: 1 # Number of batch to be saved as intermediate results. results_num: 10 wav_output_epochs: 20 ================================================ FILE: train/configs/unetts_duration.yaml ================================================ ########################################################### # FEATURE EXTRACTION SETTING # ########################################################### hop_size: 200 # Hop size. format: "npy" ########################################################### # NETWORK ARCHITECTURE SETTING # ########################################################### model_type: "unetts_duration" unetts_duration_params: dataset: multispk_voiceclone encoder_hidden_size: 128 encoder_num_hidden_layers: 2 encoder_num_attention_heads: 2 encoder_attention_head_size: 64 encoder_intermediate_size: 512 encoder_intermediate_kernel_size: 3 encoder_hidden_act: "mish" hidden_dropout_prob: 0.2 attention_probs_dropout_prob: 0.1 num_duration_conv_layers: 2 duration_predictor_filters: 128 duration_predictor_kernel_sizes: 3 duration_predictor_dropout_probs: 0.1 initializer_range: 0.02 output_attentions: False output_hidden_states: False ########################################################### # DATA LOADER SETTING # ########################################################### batch_size: 32 # Batch size. allow_cache: true # Whether to allow cache in dataset. If true, it requires cpu memory. is_shuffle: true # shuffle dataset after each epoch. ########################################################### # OPTIMIZER & SCHEDULER SETTING # ########################################################### optimizer_params: initial_learning_rate: 0.001 end_learning_rate: 0.00001 decay_steps: 75000 # < train_max_steps is recommend. warmup_proportion: 0.02 weight_decay: 0.001 ########################################################### # INTERVAL SETTING # ########################################################### train_max_steps: 100000 # Number of training steps. save_interval_steps: 10000 # Interval steps to save checkpoint. eval_interval_steps: 1000 # Interval steps to evaluate the network. log_interval_steps: 500 # Interval steps to record the training log. ########################################################### # OTHER SETTING # ########################################################### num_save_intermediate_results: 1 # Number of batch to be saved as intermediate results. ================================================ FILE: train/configs/unetts_preprocess.yaml ================================================ ########################################################### # FEATURE EXTRACTION SETTING # ########################################################### feat_params: sample_rate: 16000 n_fft: 800 num_mels: 80 hop_size: 200 win_size: 800 fmin: 55 fmax: 7600 min_level_db: -100 ref_level_db: 20 max_abs_value: 4.0 preemphasis: 0.97 preemphasize: True signal_normalization: True allow_clipping_in_normalization: True symmetric_mels: True power: 1.5 griffin_lim_iters: 60 rescale: True rescaling_max: 0.9 format: "npy" # Feature file format. Only "npy" is supported. ================================================ FILE: train/train_multiband_melgan.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Train Multi-Band MelGAN.""" import tensorflow as tf physical_devices = tf.config.list_physical_devices("GPU") for i in range(len(physical_devices)): tf.config.experimental.set_memory_growth(physical_devices[i], True) import sys sys.path.append("../..") import argparse import logging import os import numpy as np import soundfile as sf import yaml from tensorflow.keras.mixed_precision import experimental as mixed_precision import tensorflow_tts from examples.melgan.audio_mel_dataset import AudioMelDataset from examples.melgan.train_melgan import MelganTrainer, collater from tensorflow_tts.configs import (MultiBandMelGANDiscriminatorConfig, MultiBandMelGANGeneratorConfig) from tensorflow_tts.losses import TFMultiResolutionSTFT from tensorflow_tts.models import (TFPQMF, TFMelGANGenerator, TFMelGANMultiScaleDiscriminator) from tensorflow_tts.utils import (calculate_2d_loss, calculate_3d_loss, return_strategy) class MultiBandMelganTrainer(MelganTrainer): """Multi-Band MelGAN Trainer class based on MelganTrainer.""" def __init__( self, config, strategy, steps=0, epochs=0, is_generator_mixed_precision=False, is_discriminator_mixed_precision=False, ): """Initialize trainer. Args: steps (int): Initial global steps. epochs (int): Initial global epochs. config (dict): Config dict loaded from yaml format configuration file. is_generator_mixed_precision (bool): Use mixed precision for generator or not. is_discriminator_mixed_precision (bool): Use mixed precision for discriminator or not. """ super(MultiBandMelganTrainer, self).__init__( config=config, steps=steps, epochs=epochs, strategy=strategy, is_generator_mixed_precision=is_generator_mixed_precision, is_discriminator_mixed_precision=is_discriminator_mixed_precision, ) # define metrics to aggregates data and use tf.summary logs them self.list_metrics_name = [ "adversarial_loss", "subband_spectral_convergence_loss", "subband_log_magnitude_loss", "fullband_spectral_convergence_loss", "fullband_log_magnitude_loss", "gen_loss", "real_loss", "fake_loss", "dis_loss", ] self.init_train_eval_metrics(self.list_metrics_name) self.reset_states_train() self.reset_states_eval() def compile(self, gen_model, dis_model, gen_optimizer, dis_optimizer, pqmf): super().compile(gen_model, dis_model, gen_optimizer, dis_optimizer) # define loss self.sub_band_stft_loss = TFMultiResolutionSTFT( **self.config["subband_stft_loss_params"] ) self.full_band_stft_loss = TFMultiResolutionSTFT( **self.config["stft_loss_params"] ) # define pqmf module self.pqmf = pqmf def compute_per_example_generator_losses(self, batch, outputs): """Compute per example generator losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ dict_metrics_losses = {} per_example_losses = 0.0 audios = batch["audios"] y_mb_hat = outputs y_hat = self.pqmf.synthesis(y_mb_hat) y_mb = self.pqmf.analysis(tf.expand_dims(audios, -1)) y_mb = tf.transpose(y_mb, (0, 2, 1)) # [B, subbands, T//subbands] y_mb = tf.reshape(y_mb, (-1, tf.shape(y_mb)[-1])) # [B * subbands, T'] y_mb_hat = tf.transpose(y_mb_hat, (0, 2, 1)) # [B, subbands, T//subbands] y_mb_hat = tf.reshape( y_mb_hat, (-1, tf.shape(y_mb_hat)[-1]) ) # [B * subbands, T'] # calculate sub/full band spectral_convergence and log mag loss. sub_sc_loss, sub_mag_loss = calculate_2d_loss( y_mb, y_mb_hat, self.sub_band_stft_loss ) sub_sc_loss = tf.reduce_mean( tf.reshape(sub_sc_loss, [-1, self.pqmf.subbands]), -1 ) sub_mag_loss = tf.reduce_mean( tf.reshape(sub_mag_loss, [-1, self.pqmf.subbands]), -1 ) full_sc_loss, full_mag_loss = calculate_2d_loss( audios, tf.squeeze(y_hat, -1), self.full_band_stft_loss ) # define generator loss gen_loss = 0.5 * (sub_sc_loss + sub_mag_loss) + 0.5 * ( full_sc_loss + full_mag_loss ) if self.steps >= self.config["discriminator_train_start_steps"]: p_hat = self._discriminator(y_hat) p = self._discriminator(tf.expand_dims(audios, 2)) adv_loss = 0.0 for i in range(len(p_hat)): adv_loss += calculate_3d_loss( tf.ones_like(p_hat[i][-1]), p_hat[i][-1], loss_fn=self.mse_loss ) adv_loss /= i + 1 gen_loss += self.config["lambda_adv"] * adv_loss dict_metrics_losses.update({"adversarial_loss": adv_loss},) dict_metrics_losses.update({"gen_loss": gen_loss}) dict_metrics_losses.update({"subband_spectral_convergence_loss": sub_sc_loss}) dict_metrics_losses.update({"subband_log_magnitude_loss": sub_mag_loss}) dict_metrics_losses.update({"fullband_spectral_convergence_loss": full_sc_loss}) dict_metrics_losses.update({"fullband_log_magnitude_loss": full_mag_loss}) per_example_losses = gen_loss return per_example_losses, dict_metrics_losses def compute_per_example_discriminator_losses(self, batch, gen_outputs): """Compute per example discriminator losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ y_mb_hat = gen_outputs y_hat = self.pqmf.synthesis(y_mb_hat) ( per_example_losses, dict_metrics_losses, ) = super().compute_per_example_discriminator_losses(batch, y_hat) return per_example_losses, dict_metrics_losses def generate_and_save_intermediate_result(self, batch): """Generate and save intermediate result.""" import matplotlib.pyplot as plt y_mb_batch_ = self.one_step_predict(batch) # [B, T // subbands, subbands] y_batch = batch["audios"] # convert to tensor. # here we just take a sample at first replica. try: y_mb_batch_ = y_mb_batch_.values[0].numpy() y_batch = y_batch.values[0].numpy() except Exception: y_mb_batch_ = y_mb_batch_.numpy() y_batch = y_batch.numpy() y_batch_ = self.pqmf.synthesis(y_mb_batch_).numpy() # [B, T, 1] # check directory utt_ids = batch["utt_ids"].numpy() dirname = os.path.join(self.config["outdir"], f"predictions/{self.steps}steps") if not os.path.exists(dirname): os.makedirs(dirname) for idx, (y, y_) in enumerate(zip(y_batch, y_batch_), 0): # convert to ndarray y, y_ = tf.reshape(y, [-1]).numpy(), tf.reshape(y_, [-1]).numpy() # plit figure and save it utt_id = utt_ids[idx] figname = os.path.join(dirname, f"{utt_id}.png") plt.subplot(2, 1, 1) plt.plot(y) plt.title("groundtruth speech") plt.subplot(2, 1, 2) plt.plot(y_) plt.title(f"generated speech @ {self.steps} steps") plt.tight_layout() plt.savefig(figname) plt.close() # save as wavefile y = np.clip(y, -1, 1) y_ = np.clip(y_, -1, 1) sf.write( figname.replace(".png", "_ref.wav"), y, self.config["sampling_rate"], "PCM_16", ) sf.write( figname.replace(".png", "_gen.wav"), y_, self.config["sampling_rate"], "PCM_16", ) def main(): """Run training process.""" parser = argparse.ArgumentParser( description="Train MultiBand MelGAN (See detail in examples/multiband_melgan/train_multiband_melgan.py)" ) parser.add_argument( "--train-dir", default=None, type=str, help="directory including training data. ", ) parser.add_argument( "--dev-dir", default=None, type=str, help="directory including development data. ", ) parser.add_argument( "--use-norm", default=1, type=int, help="use norm mels for training or raw." ) parser.add_argument( "--outdir", type=str, required=True, help="directory to save checkpoints." ) parser.add_argument( "--config", type=str, required=True, help="yaml format configuration file." ) parser.add_argument( "--resume", default="", type=str, nargs="?", help='checkpoint file path to resume training. (default="")', ) parser.add_argument( "--verbose", type=int, default=1, help="logging level. higher is more logging. (default=1)", ) parser.add_argument( "--generator_mixed_precision", default=0, type=int, help="using mixed precision for generator or not.", ) parser.add_argument( "--discriminator_mixed_precision", default=0, type=int, help="using mixed precision for discriminator or not.", ) parser.add_argument( "--pretrained", default="", type=str, nargs="?", help='path of .h5 mb-melgan generator to load weights from', ) args = parser.parse_args() # return strategy STRATEGY = return_strategy() # set mixed precision config if args.generator_mixed_precision == 1 or args.discriminator_mixed_precision == 1: tf.config.optimizer.set_experimental_options({"auto_mixed_precision": True}) args.generator_mixed_precision = bool(args.generator_mixed_precision) args.discriminator_mixed_precision = bool(args.discriminator_mixed_precision) args.use_norm = bool(args.use_norm) # set logger if args.verbose > 1: logging.basicConfig( level=logging.DEBUG, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) elif args.verbose > 0: logging.basicConfig( level=logging.INFO, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) else: logging.basicConfig( level=logging.WARN, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) logging.warning("Skip DEBUG/INFO messages") # check directory existence if not os.path.exists(args.outdir): os.makedirs(args.outdir) # check arguments if args.train_dir is None: raise ValueError("Please specify --train-dir") if args.dev_dir is None: raise ValueError("Please specify either --valid-dir") # load and save config with open(args.config) as f: config = yaml.load(f, Loader=yaml.Loader) config.update(vars(args)) config["version"] = tensorflow_tts.__version__ with open(os.path.join(args.outdir, "config.yml"), "w") as f: yaml.dump(config, f, Dumper=yaml.Dumper) for key, value in config.items(): logging.info(f"{key} = {value}") # get dataset if config["remove_short_samples"]: mel_length_threshold = config["batch_max_steps"] // config[ "hop_size" ] + 2 * config["multiband_melgan_generator_params"].get("aux_context_window", 0) else: mel_length_threshold = None if config["format"] == "npy": audio_query = "*-wave.npy" mel_query = "*-raw-feats.npy" if args.use_norm is False else "*-norm-feats.npy" audio_load_fn = np.load mel_load_fn = np.load else: raise ValueError("Only npy are supported.") # define train/valid dataset train_dataset = AudioMelDataset( root_dir=args.train_dir, audio_query=audio_query, mel_query=mel_query, audio_load_fn=audio_load_fn, mel_load_fn=mel_load_fn, mel_length_threshold=mel_length_threshold, ).create( is_shuffle=config["is_shuffle"], map_fn=lambda items: collater( items, batch_max_steps=tf.constant(config["batch_max_steps"], dtype=tf.int32), hop_size=tf.constant(config["hop_size"], dtype=tf.int32), ), allow_cache=config["allow_cache"], batch_size=config["batch_size"] * STRATEGY.num_replicas_in_sync, ) valid_dataset = AudioMelDataset( root_dir=args.dev_dir, audio_query=audio_query, mel_query=mel_query, audio_load_fn=audio_load_fn, mel_load_fn=mel_load_fn, mel_length_threshold=mel_length_threshold, ).create( is_shuffle=config["is_shuffle"], map_fn=lambda items: collater( items, batch_max_steps=tf.constant( config["batch_max_steps_valid"], dtype=tf.int32 ), hop_size=tf.constant(config["hop_size"], dtype=tf.int32), ), allow_cache=config["allow_cache"], batch_size=config["batch_size"] * STRATEGY.num_replicas_in_sync, ) # define trainer trainer = MultiBandMelganTrainer( steps=0, epochs=0, config=config, strategy=STRATEGY, is_generator_mixed_precision=args.generator_mixed_precision, is_discriminator_mixed_precision=args.discriminator_mixed_precision, ) with STRATEGY.scope(): # define generator and discriminator generator = TFMelGANGenerator( MultiBandMelGANGeneratorConfig(**config["multiband_melgan_generator_params"]), name="multi_band_melgan_generator", ) discriminator = TFMelGANMultiScaleDiscriminator( MultiBandMelGANDiscriminatorConfig(**config["multiband_melgan_discriminator_params"]), name="multi_band_melgan_discriminator", ) pqmf = TFPQMF( MultiBandMelGANGeneratorConfig(**config["multiband_melgan_generator_params"]), name="pqmf" ) # dummy input to build model. fake_mels = tf.random.uniform(shape=[1, 100, 80], dtype=tf.float32) y_mb_hat = generator(fake_mels) y_hat = pqmf.synthesis(y_mb_hat) discriminator(y_hat) if len(args.pretrained) > 1: generator.load_weights(args.pretrained) logging.info(f"Successfully loaded pretrained weight from {args.pretrained}.") generator.summary() discriminator.summary() # define optimizer generator_lr_fn = getattr( tf.keras.optimizers.schedules, config["generator_optimizer_params"]["lr_fn"] )(**config["generator_optimizer_params"]["lr_params"]) discriminator_lr_fn = getattr( tf.keras.optimizers.schedules, config["discriminator_optimizer_params"]["lr_fn"], )(**config["discriminator_optimizer_params"]["lr_params"]) gen_optimizer = tf.keras.optimizers.Adam( learning_rate=generator_lr_fn, amsgrad=config["generator_optimizer_params"]["amsgrad"], ) dis_optimizer = tf.keras.optimizers.Adam( learning_rate=discriminator_lr_fn, amsgrad=config["discriminator_optimizer_params"]["amsgrad"], ) trainer.compile( gen_model=generator, dis_model=discriminator, gen_optimizer=gen_optimizer, dis_optimizer=dis_optimizer, pqmf=pqmf, ) # start training try: trainer.fit( train_dataset, valid_dataset, saved_path=os.path.join(config["outdir"], "checkpoints/"), resume=args.resume, ) except KeyboardInterrupt: trainer.save_checkpoint() logging.info(f"Successfully saved checkpoint @ {trainer.steps}steps.") if __name__ == "__main__": main() ================================================ FILE: train/train_unetts_acous.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Train Unet-TTS""" import tensorflow as tf physical_devices = tf.config.list_physical_devices("GPU") for i in range(len(physical_devices)): tf.config.experimental.set_memory_growth(physical_devices[i], True) import sys # sys.path.append("../..") import argparse import logging import os import traceback import numpy as np import yaml import tensorflow_tts from train.unetts_dataset import UNETTSAcousDataset from tensorflow_tts.configs import UNETTSAcousConfig from tensorflow_tts.models import TFUNETTSContentPretrain, TFUNETTSAcous from tensorflow_tts.optimizers import AdamWeightDecay, WarmUp from tensorflow_tts.trainers import Seq2SeqBasedTrainer from tensorflow_tts.utils import calculate_loss_norm_lens, return_strategy from tensorflow_tts.audio_process.audio_spec import AudioMelSpec class UNETTSAcousTrainer(Seq2SeqBasedTrainer): """UNETTSAcousTrainer.""" def __init__( self, config, strategy, steps=0, epochs=0, is_mixed_precision=False, ): """Initialize trainer. Args: steps (int): Initial global steps. epochs (int): Initial global epochs. config (dict): Config dict loaded from yaml format configuration file. is_mixed_precision (bool): Use mixed precision or not. """ super(UNETTSAcousTrainer, self).__init__( steps=steps, epochs=epochs, config=config, strategy=strategy, is_mixed_precision=is_mixed_precision, ) # define metrics to aggregates data and use tf.summary logs them self.list_metrics_name = [ "mel_before", "content_loss", ] self.init_train_eval_metrics(self.list_metrics_name) self.reset_states_train() self.reset_states_eval() self.feature_handle = AudioMelSpec(**config["feat_params"]) def compile(self, model, optimizer): super().compile(model, optimizer) self.mse = tf.keras.losses.MeanSquaredError( reduction=tf.keras.losses.Reduction.NONE ) self.mae = tf.keras.losses.MeanAbsoluteError( reduction=tf.keras.losses.Reduction.NONE ) # self.bce = tf.keras.losses.BinaryCrossentropy( # reduction=tf.keras.losses.Reduction.NONE # ) def compute_per_example_losses(self, batch, outputs): """Compute per example losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ mel_before, content_latents, content_latent_pred = outputs # mse, 0.01; mae, 0.05 mel_loss_before = calculate_loss_norm_lens(batch["mel_gts"], mel_before, self.mae, batch["mel_lengths"]) content_loss = calculate_loss_norm_lens(content_latents, content_latent_pred, self.mse, batch["mel_lengths"]) per_example_losses = ( mel_loss_before + content_loss ) dict_metrics_losses = { "mel_before": mel_loss_before, "content_loss" : content_loss, } return per_example_losses, dict_metrics_losses def generate_and_save_intermediate_result(self, batch): """Generate and save intermediate result.""" # predict with tf.function. mel_before, *_ = self.one_step_predict(batch) mel_gts = batch["mel_gts"].numpy() frame_real_length = batch["mel_lengths"].numpy() # convert to tensor. # here we just take a sample at first replica. try: mel_before = mel_before.values[0].numpy() except Exception: mel_before = mel_before.numpy() # check directory utt_ids = batch["utt_ids"].numpy() dirname = os.path.join(self.config["outdir"], f"predictions/{self.steps}steps") if not os.path.exists(dirname): os.makedirs(dirname) for i, utt in enumerate(utt_ids): figname = os.path.join(dirname, f"{utt}.png") wavname = os.path.join(dirname, f"{utt}.wav") self.feature_handle.compare_plot(mel_gts[i], mel_before[i], filepath=figname, frame_real_len=frame_real_length[i], text=None) if self.epochs > self.config["wav_output_epochs"] and i < self.config["results_num"]: audio = self.feature_handle.inv_mel_spectrogram(mel_before[i][:frame_real_length[i]]) self.feature_handle.save_wav(audio, wavname) class UNETTSContentPreTrainer(Seq2SeqBasedTrainer): """UNETTSContentPreTrainer""" def __init__( self, config, strategy, steps=0, epochs=0, is_mixed_precision=False, ): """Initialize trainer. Args: steps (int): Initial global steps. epochs (int): Initial global epochs. config (dict): Config dict loaded from yaml format configuration file. is_mixed_precision (bool): Use mixed precision or not. """ super(UNETTSContentPreTrainer, self).__init__( steps=steps, epochs=epochs, config=config, strategy=strategy, is_mixed_precision=is_mixed_precision, ) # define metrics to aggregates data and use tf.summary logs them self.list_metrics_name = [ "mel_before", "mel_after", ] self.init_train_eval_metrics(self.list_metrics_name) self.reset_states_train() self.reset_states_eval() self.feature_handle = AudioMelSpec(**config["feat_params"]) def compile(self, model, optimizer): super().compile(model, optimizer) self.mse = tf.keras.losses.MeanSquaredError( reduction=tf.keras.losses.Reduction.NONE ) self.mae = tf.keras.losses.MeanAbsoluteError( reduction=tf.keras.losses.Reduction.NONE ) # self.bce = tf.keras.losses.BinaryCrossentropy( # reduction=tf.keras.losses.Reduction.NONE # ) def compute_per_example_losses(self, batch, outputs): """Compute per example losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ mel_before, mel_after = outputs # mse, 0.01; mae, 0.05 mel_loss_before = calculate_loss_norm_lens(batch["mel_gts"], mel_before, self.mae, batch["mel_lengths"]) mel_loss_after = calculate_loss_norm_lens(batch["mel_gts"], mel_after, self.mae, batch["mel_lengths"]) per_example_losses = ( mel_loss_before + mel_loss_after ) dict_metrics_losses = { "mel_before": mel_loss_before, "mel_after" : mel_loss_after, } return per_example_losses, dict_metrics_losses def generate_and_save_intermediate_result(self, batch): """Generate and save intermediate result.""" # predict with tf.function. outputs = self.one_step_predict(batch) mel_before, mel_after = outputs mel_gts = batch["mel_gts"].numpy() frame_real_length = batch["mel_lengths"].numpy() # convert to tensor. # here we just take a sample at first replica. try: mel_before = mel_before.values[0].numpy() mel_after = mel_after.values[0].numpy() except Exception: mel_before = mel_before.numpy() mel_after = mel_after.numpy() # check directory utt_ids = batch["utt_ids"].numpy() dirname = os.path.join(self.config["outdir"], f"predictions/{self.steps}steps") if not os.path.exists(dirname): os.makedirs(dirname) for i, utt in enumerate(utt_ids): figname = os.path.join(dirname, f"{utt}.png") wavname = os.path.join(dirname, f"{utt}.wav") self.feature_handle.compare_plot(mel_gts[i], mel_after[i], filepath=figname, frame_real_len=frame_real_length[i], text=None) if self.epochs > self.config["wav_output_epochs"] and i < self.config["results_num"]: audio = self.feature_handle.inv_mel_spectrogram(mel_after[i][:frame_real_length[i]]) self.feature_handle.save_wav(audio, wavname) def main(): """Run training process.""" parser = argparse.ArgumentParser( description="Train model (See detail in tensorflow_tts/models)" ) parser.add_argument( "--train-dir", default=None, type=str, help="directory including training data. ", ) parser.add_argument( "--dev-dir", default=None, type=str, help="directory including development data. ", ) parser.add_argument( "--content_training", default=0, type=int, help="is need to training context_model" ) parser.add_argument( "--content_pretrained_path", type=str, required=True, help="directory to content_pretrained_path" ) parser.add_argument( "--outdir", type=str, required=True, help="directory to save checkpoints." ) parser.add_argument( "--config", type=str, required=True, help="yaml format configuration file." ) parser.add_argument( "--data_config", type=str, required=True, help="yaml format data_process file." ) parser.add_argument( "--resume", default="", type=str, nargs="?", help='checkpoint file path to resume training. (default="")', ) parser.add_argument( "--verbose", type=int, default=1, help="logging level. higher is more logging. (default=1)", ) parser.add_argument( "--mixed_precision", default=0, type=int, help="using mixed precision for generator or not.", ) parser.add_argument( "--pretrained", default="", type=str, nargs="?", help='pretrained weights .h5 file to load weights from. Auto-skips non-matching layers', ) args = parser.parse_args() # return strategy STRATEGY = return_strategy() # set mixed precision config if args.mixed_precision == 1: tf.config.optimizer.set_experimental_options({"auto_mixed_precision": True}) args.mixed_precision = bool(args.mixed_precision) # args.use_norm = bool(args.use_norm) # set logger if args.verbose > 1: logging.basicConfig( level=logging.DEBUG, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) elif args.verbose > 0: logging.basicConfig( level=logging.INFO, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) else: logging.basicConfig( level=logging.WARN, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) logging.warning("Skip DEBUG/INFO messages") # check directory existence if not os.path.exists(args.outdir): os.makedirs(args.outdir) # check arguments if args.train_dir is None: raise ValueError("Please specify --train-dir") if args.dev_dir is None: raise ValueError("Please specify --valid-dir") # load and save config with open(args.config) as f: config = yaml.load(f, Loader=yaml.Loader) with open(args.data_config) as f: data_config = yaml.load(f, Loader=yaml.Loader) config.update(data_config) config.update(vars(args)) config["version"] = tensorflow_tts.__version__ with open(os.path.join(args.outdir, "config.yml"), "w") as f: yaml.dump(config, f, Dumper=yaml.Dumper) for key, value in config.items(): logging.info(f"{key} = {value}") config["content_training"] = True if config["content_training"] else False if config["content_training"]: print("*"*50) print("*"*20 + "Training Content Encoder ......" + "*"*20) print("*"*50) assert config["unetts_acous_context_pre_params"]["num_mels"] == config["feat_params"]["num_mels"] else: assert config["unetts_acous_params"]["num_mels"] == config["feat_params"]["num_mels"] # get dataset # if config["remove_short_samples"]: # mel_length_threshold = config["mel_length_threshold"] # else: # mel_length_threshold = None # if config["format"] == "npy": # charactor_query = "*-ids.npy" # mel_query = "*-raw-feats.npy" if args.use_norm is False else "*-norm-feats.npy" # duration_query = "*-durations.npy" # lf0_query = "*-raw-lf0.npy" # energy_query = "*-raw-energy.npy" # else: # raise ValueError("Only npy are supported.") # define train/valid dataset train_dataset = UNETTSAcousDataset( root_dir=args.train_dir, ).create( is_shuffle=config["is_shuffle"], allow_cache=config["allow_cache"], batch_size=config["batch_size"] * STRATEGY.num_replicas_in_sync, ) valid_dataset = UNETTSAcousDataset( root_dir=args.dev_dir, ).create( is_shuffle=config["is_shuffle"], allow_cache=config["allow_cache"], batch_size=config["batch_size"] * STRATEGY.num_replicas_in_sync, ) # define trainer if config["content_training"]: trainer = UNETTSContentPreTrainer( config=config, strategy=STRATEGY, steps=0, epochs=0, is_mixed_precision=args.mixed_precision, ) else: trainer = UNETTSAcousTrainer( config=config, strategy=STRATEGY, steps=0, epochs=0, is_mixed_precision=args.mixed_precision, ) with STRATEGY.scope(): # define model if config["content_training"]: model = TFUNETTSContentPretrain( config=UNETTSAcousConfig(**config["unetts_acous_context_pre_params"]) ) else: model = TFUNETTSAcous( config=UNETTSAcousConfig(**config["unetts_acous_params"]) ) model._build() if not config["content_training"]: logging.info("Model content_pretrained_path: {}".format(config["content_pretrained_path"])) try: # TODO model.text_encoder_weight_load(config["content_pretrained_path"]) model.freezen_encoder() except: logging.error("Error: Model embedding and text_encoder") exit(1) model.summary() if len(args.pretrained) > 1: model.load_weights(args.pretrained, by_name=True, skip_mismatch=True) logging.info(f"Successfully loaded pretrained weight from {args.pretrained}.") # AdamW for model learning_rate_fn = tf.keras.optimizers.schedules.PolynomialDecay( initial_learning_rate=config["optimizer_params"]["initial_learning_rate"], decay_steps=config["optimizer_params"]["decay_steps"], end_learning_rate=config["optimizer_params"]["end_learning_rate"], ) learning_rate_fn = WarmUp( initial_learning_rate=config["optimizer_params"]["initial_learning_rate"], decay_schedule_fn=learning_rate_fn, warmup_steps=int( config["train_max_steps"] * config["optimizer_params"]["warmup_proportion"] ), ) optimizer = AdamWeightDecay( learning_rate=learning_rate_fn, weight_decay_rate=config["optimizer_params"]["weight_decay"], beta_1=0.9, beta_2=0.98, epsilon=1e-6, exclude_from_weight_decay=["LayerNorm", "layer_norm", "bias"], ) _ = optimizer.iterations # compile trainer trainer.compile(model=model, optimizer=optimizer) # start training try: trainer.fit( train_dataset, valid_dataset, saved_path=os.path.join(config["outdir"], "checkpoints/"), resume=args.resume, ) except KeyboardInterrupt: trainer.save_checkpoint() logging.info(f"Successfully saved checkpoint @ {trainer.steps}steps.") except: error = traceback.format_exc() print(error) with open(os.path.join(config["outdir"], "error.txt"), 'a') as fw: fw.write(error + "\n") if __name__ == "__main__": main() ================================================ FILE: train/train_unetts_duration.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Train MultiSPKCLDuration.""" import tensorflow as tf physical_devices = tf.config.list_physical_devices("GPU") for i in range(len(physical_devices)): tf.config.experimental.set_memory_growth(physical_devices[i], True) import sys sys.path.append("../..") import argparse import logging import os import traceback import numpy as np import yaml import matplotlib.pyplot as plt import tensorflow_tts from train.unetts_dataset import UNETTSDurationDataset from tensorflow_tts.configs import UNETTSDurationConfig from tensorflow_tts.models import TFUNETTSDuration from tensorflow_tts.optimizers import AdamWeightDecay, WarmUp from tensorflow_tts.trainers import Seq2SeqBasedTrainer from tensorflow_tts.utils import (calculate_loss_norm_lens, return_strategy) class UNETTSDurationTrainer(Seq2SeqBasedTrainer): """UNETTSDurationTrainer""" def __init__( self, config, strategy, steps=0, epochs=0, is_mixed_precision=False, ): """Initialize trainer. Args: steps (int): Initial global steps. epochs (int): Initial global epochs. config (dict): Config dict loaded from yaml format configuration file. is_mixed_precision (bool): Use mixed precision or not. """ super(UNETTSDurationTrainer, self).__init__( steps=steps, epochs=epochs, config=config, strategy=strategy, is_mixed_precision=is_mixed_precision, ) # define metrics to aggregates data and use tf.summary logs them self.list_metrics_name = [ "dur_loss", ] self.init_train_eval_metrics(self.list_metrics_name) self.reset_states_train() self.reset_states_eval() def compile(self, model, optimizer): super().compile(model, optimizer) self.mse = tf.keras.losses.MeanSquaredError( reduction=tf.keras.losses.Reduction.NONE ) self.mae = tf.keras.losses.MeanAbsoluteError( reduction=tf.keras.losses.Reduction.NONE ) self.huber = tf.keras.losses.Huber( delta = 2.0, reduction=tf.keras.losses.Reduction.NONE ) def compute_per_example_losses(self, batch, outputs): """Compute per example losses and return dict_metrics_losses Note that all element of the loss MUST has a shape [batch_size] and the keys of dict_metrics_losses MUST be in self.list_metrics_name. Args: batch: dictionary batch input return from dataloader outputs: outputs of the model Returns: per_example_losses: per example losses for each GPU, shape [B] dict_metrics_losses: dictionary loss. """ # log_duration = tf.math.log( # tf.cast(tf.math.add(batch["duration_gts"], 1), tf.float32) # ) per_example_losses = calculate_loss_norm_lens(batch["duration_gts"], outputs, self.mae, batch["char_lengths"]) dict_metrics_losses = { "dur_loss": per_example_losses, } return per_example_losses, dict_metrics_losses def generate_and_save_intermediate_result(self, batch): """Generate and save intermediate result.""" outputs = self.one_step_predict(batch) try: dur_preds = outputs.values[0].numpy() except Exception: dur_preds = outputs.numpy() dur_gts = batch["duration_gts"].numpy() char_lengths = batch["char_lengths"].numpy() utt_ids = batch["utt_ids"].numpy() dirname = os.path.join(self.config["outdir"], f"predictions/{self.steps}steps") if not os.path.exists(dirname): os.makedirs(dirname) for i, utt_id in enumerate(utt_ids): figname = os.path.join(dirname, f"{utt_id}.png") plt.figure(figsize=(10, 4)) plt.plot(dur_gts[i][:char_lengths[i]], 'b--o', markersize=6) plt.plot(dur_preds[i][:char_lengths[i]], 'r-x', markersize=10) plt.grid() plt.legend(("gst", "pred")) plt.tight_layout() plt.savefig(figname) plt.close() def main(): """Run training process.""" parser = argparse.ArgumentParser( description="Train model (See detail in tensorflow_tts/models)" ) parser.add_argument( "--train-dir", default=None, type=str, help="directory including training data. ", ) parser.add_argument( "--dev-dir", default=None, type=str, help="directory including development data. ", ) parser.add_argument( "--outdir", type=str, required=True, help="directory to save checkpoints." ) parser.add_argument( "--config", type=str, required=True, help="yaml format configuration file." ) parser.add_argument( "--resume", default="", type=str, nargs="?", help='checkpoint file path to resume training. (default="")', ) parser.add_argument( "--verbose", type=int, default=1, help="logging level. higher is more logging. (default=1)", ) parser.add_argument( "--mixed_precision", default=0, type=int, help="using mixed precision for generator or not.", ) parser.add_argument( "--pretrained", default="", type=str, nargs="?", help='pretrained weights .h5 file to load weights from. Auto-skips non-matching layers', ) args = parser.parse_args() # return strategy STRATEGY = return_strategy() # set mixed precision config if args.mixed_precision == 1: tf.config.optimizer.set_experimental_options({"auto_mixed_precision": True}) args.mixed_precision = bool(args.mixed_precision) # args.use_norm = bool(args.use_norm) # set logger if args.verbose > 1: logging.basicConfig( level=logging.DEBUG, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) elif args.verbose > 0: logging.basicConfig( level=logging.INFO, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) else: logging.basicConfig( level=logging.WARN, stream=sys.stdout, format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s", ) logging.warning("Skip DEBUG/INFO messages") # check directory existence if not os.path.exists(args.outdir): os.makedirs(args.outdir) # check arguments if args.train_dir is None: raise ValueError("Please specify --train-dir") if args.dev_dir is None: raise ValueError("Please specify --valid-dir") # load and save config with open(args.config) as f: config = yaml.load(f, Loader=yaml.Loader) config.update(vars(args)) config["version"] = tensorflow_tts.__version__ with open(os.path.join(args.outdir, "config.yml"), "w") as f: yaml.dump(config, f, Dumper=yaml.Dumper) for key, value in config.items(): logging.info(f"{key} = {value}") # # get dataset # if config["remove_short_samples"]: # mel_length_threshold = config["mel_length_threshold"] # else: # mel_length_threshold = None # if config["format"] == "npy": # charactor_query = "*-ids.npy" # mel_query = "*-raw-feats.npy" if args.use_norm is False else "*-norm-feats.npy" # duration_query = "*-durations.npy" # lf0_query = "*-raw-lf0.npy" # energy_query = "*-raw-energy.npy" # else: # raise ValueError("Only npy are supported.") # define train/valid dataset train_dataset = UNETTSDurationDataset( root_dir=args.train_dir ).create( is_shuffle=config["is_shuffle"], allow_cache=config["allow_cache"], batch_size=config["batch_size"] * STRATEGY.num_replicas_in_sync, ) valid_dataset = UNETTSDurationDataset( root_dir=args.dev_dir ).create( is_shuffle=config["is_shuffle"], allow_cache=config["allow_cache"], batch_size=config["batch_size"] * STRATEGY.num_replicas_in_sync, ) # define trainer trainer = UNETTSDurationTrainer( config=config, strategy=STRATEGY, steps=0, epochs=0, is_mixed_precision=args.mixed_precision, ) with STRATEGY.scope(): # define model model = TFUNETTSDuration( config=UNETTSDurationConfig(**config["unetts_duration"]) ) model._build() model.summary() if len(args.pretrained) > 1: model.load_weights(args.pretrained, by_name=True, skip_mismatch=True) logging.info(f"Successfully loaded pretrained weight from {args.pretrained}.") # AdamW for model learning_rate_fn = tf.keras.optimizers.schedules.PolynomialDecay( initial_learning_rate=config["optimizer_params"]["initial_learning_rate"], decay_steps=config["optimizer_params"]["decay_steps"], end_learning_rate=config["optimizer_params"]["end_learning_rate"], ) learning_rate_fn = WarmUp( initial_learning_rate=config["optimizer_params"]["initial_learning_rate"], decay_schedule_fn=learning_rate_fn, warmup_steps=int( config["train_max_steps"] * config["optimizer_params"]["warmup_proportion"] ), ) optimizer = AdamWeightDecay( learning_rate=learning_rate_fn, weight_decay_rate=config["optimizer_params"]["weight_decay"], beta_1=0.9, beta_2=0.98, epsilon=1e-6, exclude_from_weight_decay=["LayerNorm", "layer_norm", "bias"], ) _ = optimizer.iterations # compile trainer trainer.compile(model=model, optimizer=optimizer) # start training try: trainer.fit( train_dataset, valid_dataset, saved_path=os.path.join(config["outdir"], "checkpoints/"), resume=args.resume, ) except KeyboardInterrupt: trainer.save_checkpoint() logging.info(f"Successfully saved checkpoint @ {trainer.steps}steps.") except: error = traceback.format_exc() print(error) with open(os.path.join(config["outdir"], "error.txt"), 'a') as fw: fw.write(error + "\n") if __name__ == "__main__": main() ================================================ FILE: train/unetts_dataset.py ================================================ # -*- coding: utf-8 -*- # Copyright 2020 Minh Nguyen (@dathudeptrai) # # 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. """Dataset modules.""" import itertools import logging import os import random import numpy as np import tensorflow as tf from tensorflow_tts.datasets.abstract_dataset import AbstractDataset from tensorflow_tts.utils import find_files class UNETTSDurationDataset(AbstractDataset): """UNETTSDurationDataset""" def __init__( self, root_dir, charactor_query = "*-ids.npy", duration_query = "*-raw-durations.npy", stat_dur_query = "*-stat-durations.npy", charactor_load_fn = np.load, duration_load_fn = np.load, stat_dur_load_fn = np.load, ): """Initialize dataset. Args: root_dir (str): Root directory including dumped files. ... """ # find all of charactor and mel files. charactor_files = sorted(find_files(root_dir, charactor_query)) duration_files = sorted(find_files(root_dir, duration_query)) stat_dur_files = sorted(find_files(root_dir, stat_dur_query)) # assert the number of files assert len(duration_files) != 0, f"Not found any mels files in ${root_dir}." assert ( len(charactor_files) == len(duration_files) == len(stat_dur_files) ), f"Number of charactor, duration and its stats files are different" if ".npy" in charactor_query: suffix = charactor_query[1:] utt_ids = [os.path.basename(f).replace(suffix, "") for f in charactor_files] # set global params self.utt_ids = utt_ids self.charactor_files = charactor_files self.duration_files = duration_files self.stat_dur_files = stat_dur_files self.charactor_load_fn = charactor_load_fn self.duration_load_fn = duration_load_fn self.stat_dur_load_fn = stat_dur_load_fn def get_args(self): return [self.utt_ids] def generator(self, utt_ids): for i, utt_id in enumerate(utt_ids): charactor_file = self.charactor_files[i] duration_file = self.duration_files[i] stat_dur_file = self.stat_dur_files[i] items = { "utt_ids" : utt_id, "charactor_files": charactor_file, "duration_files" : duration_file, "stat_dur_files" : stat_dur_file, } yield items @tf.function def _load_data(self, items): charactor = tf.numpy_function(np.load, [items["charactor_files"]], tf.int32) duration = tf.numpy_function(np.load, [items["duration_files"]], tf.float32) durstats = tf.numpy_function(np.load, [items["stat_dur_files"]], tf.float32) items = { "utt_ids" : items["utt_ids"], "char_ids" : charactor, "char_lengths" : len(charactor), "duration_gts" : duration, "duration_stat": durstats } return items def create( self, allow_cache=False, batch_size=1, is_shuffle=False, map_fn=None, reshuffle_each_iteration=True, ): """Create tf.dataset function.""" output_types = self.get_output_dtypes() datasets = tf.data.Dataset.from_generator( self.generator, output_types=output_types, args=(self.get_args()) ) # load data datasets = datasets.map( lambda items: self._load_data(items), tf.data.experimental.AUTOTUNE ) if allow_cache: datasets = datasets.cache() if is_shuffle: datasets = datasets.shuffle( self.get_len_dataset(), reshuffle_each_iteration=reshuffle_each_iteration, ) # define padded shapes padded_shapes = { "utt_ids" : [], "char_ids" : [None], "char_lengths" : [], "duration_gts" : [None], "duration_stat": [None], } datasets = datasets.padded_batch(batch_size, padded_shapes=padded_shapes) datasets = datasets.prefetch(tf.data.experimental.AUTOTUNE) return datasets def get_output_dtypes(self): output_types = { "utt_ids" : tf.string, "charactor_files": tf.string, "duration_files" : tf.string, "stat_dur_files" : tf.string, } return output_types def get_len_dataset(self): return len(self.utt_ids) def __name__(self): return "UNETTSDurationDataset" class UNETTSAcousDataset(AbstractDataset): """UNETTSAcousDataset""" def __init__( self, root_dir, charactor_query = "*-ids.npy", duration_query = "*-raw-durations.npy", mel_query = "*-raw-mels.npy", embed_query = "*-embeds.npy", mel_load_fn = np.load, charactor_load_fn = np.load, duration_load_fn = np.load, embed_load_fn = np.load, mel_length_threshold = 0, ): """Initialize dataset. Args: root_dir (str): Root directory including dumped files. ... """ # find all of charactor and mel files. charactor_files = sorted(find_files(root_dir, charactor_query)) duration_files = sorted(find_files(root_dir, duration_query)) mel_files = sorted(find_files(root_dir, mel_query)) embed_files = sorted(find_files(root_dir, embed_query)) # assert the number of files assert len(mel_files) != 0, f"Not found any mels files in ${root_dir}." assert ( len(charactor_files) == len(duration_files) == len(mel_files) == len(embed_files) ), f"Number of charactor, duration and its stats files are different" if ".npy" in charactor_query: suffix = charactor_query[1:] utt_ids = [os.path.basename(f).replace(suffix, "") for f in charactor_files] # set global params self.utt_ids = utt_ids self.charactor_files = charactor_files self.duration_files = duration_files self.mel_files = mel_files self.embed_files = embed_files self.charactor_load_fn = charactor_load_fn self.duration_load_fn = duration_load_fn self.mel_load_fn = mel_load_fn self.embed_load_fn = embed_load_fn self.mel_length_threshold = mel_length_threshold def get_args(self): return [self.utt_ids] def generator(self, utt_ids): for i, utt_id in enumerate(utt_ids): charactor_file = self.charactor_files[i] duration_file = self.duration_files[i] mel_file = self.mel_files[i] embed_file = self.embed_files[i] items = { "utt_ids" : utt_id, "charactor_files": charactor_file, "duration_files" : duration_file, "mel_files" : mel_file, "embed_files" : embed_file, } yield items @tf.function def _load_data(self, items): charactor = tf.numpy_function(np.load, [items["charactor_files"]], tf.int32) duration = tf.numpy_function(np.load, [items["duration_files"]], tf.int32) mel = tf.numpy_function(np.load, [items["mel_files"]], tf.float32) embed = tf.numpy_function(np.load, [items["embed_files"]], tf.float32) items = { "utt_ids" : items["utt_ids"], "char_ids" : charactor, "char_lengths": len(charactor), "mel_gts" : mel, "mel_lengths" : len(mel), "duration_gts": duration, "embed" : embed, } return items def create( self, allow_cache=False, batch_size=1, is_shuffle=False, map_fn=None, reshuffle_each_iteration=True, ): """Create tf.dataset function.""" output_types = self.get_output_dtypes() datasets = tf.data.Dataset.from_generator( self.generator, output_types=output_types, args=(self.get_args()) ) # load data datasets = datasets.map( lambda items: self._load_data(items), tf.data.experimental.AUTOTUNE ) # datasets = datasets.filter( # lambda x: x["spe_lengths"] > self.mel_length_threshold # ) if allow_cache: datasets = datasets.cache() if is_shuffle: datasets = datasets.shuffle( self.get_len_dataset(), reshuffle_each_iteration=reshuffle_each_iteration, ) # define padded shapes padded_shapes = { "utt_ids" : [], "char_ids" : [None], "char_lengths": [], "mel_gts" : [None, None], "mel_lengths" : [], "duration_gts": [None], "embed" : [None], } datasets = datasets.padded_batch(batch_size, padded_shapes=padded_shapes) datasets = datasets.prefetch(tf.data.experimental.AUTOTUNE) return datasets def get_output_dtypes(self): output_types = { "utt_ids" : tf.string, "charactor_files": tf.string, "mel_files" : tf.string, "duration_files" : tf.string, "embed_files" : tf.string, } return output_types def get_len_dataset(self): return len(self.utt_ids) def __name__(self): return "UNETTSAcousDataset"