From 0ccab0474b02012b39ed95dcfc25ad88ce366c14 Mon Sep 17 00:00:00 2001 From: Feiyu Chan Date: Thu, 3 Oct 2019 10:41:28 +0800 Subject: [PATCH] init commit for deepvoice3 (#3458) * ini commit for deepvoice, add tensorboard to requirements * fix urls for code we adapted from * fix makedirs for python2, fix README * fix open with encoding for python2 compatability * fix python2's str(), use encode for unicode, and str() for int * fix python2 encoding issue, add model architecture and project structure for README * add model structure, add explanation for hyperparameter priority order. --- .../DeepVoice3/.pre-commit-config.yaml | 27 + PaddleSpeech/DeepVoice3/LICENSE | 18 + PaddleSpeech/DeepVoice3/README.md | 219 +++ PaddleSpeech/DeepVoice3/README_cn.md | 220 +++ .../DeepVoice3/_images/model_architecture.png | Bin 0 -> 458087 bytes PaddleSpeech/DeepVoice3/audio.py | 98 ++ .../DeepVoice3/compute_timestamp_ratio.py | 65 + PaddleSpeech/DeepVoice3/conversion/README.md | 37 + PaddleSpeech/DeepVoice3/conversion/convert.py | 95 ++ .../conversion/generate_name_map.py | 627 +++++++ .../DeepVoice3/deepvoice3_paddle/__init__.py | 0 .../DeepVoice3/deepvoice3_paddle/builder.py | 137 ++ .../DeepVoice3/deepvoice3_paddle/conv.py | 222 +++ .../DeepVoice3/deepvoice3_paddle/data.py | 329 ++++ .../deepvoice3_paddle/deepvoice3.py | 1498 +++++++++++++++++ .../DeepVoice3/deepvoice3_paddle/dry_run.py | 113 ++ .../deepvoice3_paddle/frontend/README.md | 1 + .../deepvoice3_paddle/frontend/__init__.py | 33 + .../deepvoice3_paddle/frontend/en/__init__.py | 35 + .../deepvoice3_paddle/frontend/es/__init__.py | 16 + .../deepvoice3_paddle/frontend/jp/__init__.py | 77 + .../deepvoice3_paddle/frontend/ko/__init__.py | 17 + .../frontend/text/__init__.py | 74 + .../frontend/text/cleaners.py | 104 ++ .../frontend/text/cmudict.py | 67 + .../frontend/text/numbers.py | 71 + .../frontend/text/symbols.py | 18 + .../DeepVoice3/deepvoice3_paddle/loss.py | 158 ++ .../DeepVoice3/deepvoice3_paddle/modules.py | 458 +++++ .../DeepVoice3/deepvoice3_paddle/save_load.py | 78 + .../deepvoice3_paddle/weight_norm.py | 863 ++++++++++ PaddleSpeech/DeepVoice3/eval_model.py | 321 ++++ PaddleSpeech/DeepVoice3/hparam_tf/__init__.py | 0 PaddleSpeech/DeepVoice3/hparam_tf/hparam.py | 731 ++++++++ PaddleSpeech/DeepVoice3/hparam_tf/readme.md | 8 + PaddleSpeech/DeepVoice3/hparams.py | 150 ++ PaddleSpeech/DeepVoice3/ljspeech.py | 89 + PaddleSpeech/DeepVoice3/preprocess.py | 90 + .../presets/deepvoice3_ljspeech.json | 65 + PaddleSpeech/DeepVoice3/requirements.txt | 14 + PaddleSpeech/DeepVoice3/synthesis.py | 175 ++ PaddleSpeech/DeepVoice3/train.py | 271 +++ PaddleSpeech/DeepVoice3/train_model.py | 236 +++ 43 files changed, 7925 insertions(+) create mode 100644 PaddleSpeech/DeepVoice3/.pre-commit-config.yaml create mode 100644 PaddleSpeech/DeepVoice3/LICENSE create mode 100644 PaddleSpeech/DeepVoice3/README.md create mode 100644 PaddleSpeech/DeepVoice3/README_cn.md create mode 100644 PaddleSpeech/DeepVoice3/_images/model_architecture.png create mode 100644 PaddleSpeech/DeepVoice3/audio.py create mode 100644 PaddleSpeech/DeepVoice3/compute_timestamp_ratio.py create mode 100644 PaddleSpeech/DeepVoice3/conversion/README.md create mode 100644 PaddleSpeech/DeepVoice3/conversion/convert.py create mode 100644 PaddleSpeech/DeepVoice3/conversion/generate_name_map.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/builder.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/conv.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/data.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/deepvoice3.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/dry_run.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/README.md create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/en/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/es/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/jp/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/ko/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cleaners.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cmudict.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/numbers.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/symbols.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/loss.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/modules.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/save_load.py create mode 100644 PaddleSpeech/DeepVoice3/deepvoice3_paddle/weight_norm.py create mode 100644 PaddleSpeech/DeepVoice3/eval_model.py create mode 100644 PaddleSpeech/DeepVoice3/hparam_tf/__init__.py create mode 100644 PaddleSpeech/DeepVoice3/hparam_tf/hparam.py create mode 100644 PaddleSpeech/DeepVoice3/hparam_tf/readme.md create mode 100644 PaddleSpeech/DeepVoice3/hparams.py create mode 100644 PaddleSpeech/DeepVoice3/ljspeech.py create mode 100644 PaddleSpeech/DeepVoice3/preprocess.py create mode 100644 PaddleSpeech/DeepVoice3/presets/deepvoice3_ljspeech.json create mode 100644 PaddleSpeech/DeepVoice3/requirements.txt create mode 100644 PaddleSpeech/DeepVoice3/synthesis.py create mode 100644 PaddleSpeech/DeepVoice3/train.py create mode 100644 PaddleSpeech/DeepVoice3/train_model.py diff --git a/PaddleSpeech/DeepVoice3/.pre-commit-config.yaml b/PaddleSpeech/DeepVoice3/.pre-commit-config.yaml new file mode 100644 index 00000000..4102b69a --- /dev/null +++ b/PaddleSpeech/DeepVoice3/.pre-commit-config.yaml @@ -0,0 +1,27 @@ +- repo: https://github.com/PaddlePaddle/mirrors-yapf.git + sha: 0d79c0c469bab64f7229c9aca2b1186ef47f0e37 + hooks: + - id: yapf + files: \.py$ +- repo: https://github.com/pre-commit/pre-commit-hooks + sha: a11d9314b22d8f8c7556443875b731ef05965464 + hooks: + - id: check-merge-conflict + - id: check-symlinks + - id: detect-private-key + files: (?!.*paddle)^.*$ + - id: end-of-file-fixer + files: \.md$ + - id: trailing-whitespace + files: \.md$ +- repo: https://github.com/Lucas-C/pre-commit-hooks + sha: v1.0.1 + hooks: + - id: forbid-crlf + files: \.md$ + - id: remove-crlf + files: \.md$ + - id: forbid-tabs + files: \.md$ + - id: remove-tabs + files: \.md$ diff --git a/PaddleSpeech/DeepVoice3/LICENSE b/PaddleSpeech/DeepVoice3/LICENSE new file mode 100644 index 00000000..93f68d8d --- /dev/null +++ b/PaddleSpeech/DeepVoice3/LICENSE @@ -0,0 +1,18 @@ + Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. + + 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. + + +Part of code was copied or adpated from https://github.com/r9y9/deepvoice3_pytorch/ +Copyright (c) 2017: Ryuichi Yamamoto, whose applies. + diff --git a/PaddleSpeech/DeepVoice3/README.md b/PaddleSpeech/DeepVoice3/README.md new file mode 100644 index 00000000..5842b766 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/README.md @@ -0,0 +1,219 @@ +# Deep Voice 3 with Paddle Fluid + +Paddle fluid implementation of DeepVoice 3, a convolutional network based text-to-speech synthesis model. The implementation is based on [Deep Voice 3: Scaling Text-to-Speech with Convolutional Sequence Learning](https://arxiv.org/abs/1710.07654). + +We implement Deepvoice3 model in paddle fluid with dynamic graph, which is convenient for flexible network architectures. + +## Installation + +### Install paddlepaddle + +For faster training speed and better support, it is recommended that you install the lasted develop version of paddlepaddle. You can either download the lasted dev wheel or build paddle from source. + +1. Download lasted wheel. See [**Multi-version whl package list - dev**](https://www.paddlepaddle.org.cn/documentation/docs/en/beginners_guide/install/Tables_en.html#multi-version-whl-package-list-dev) for more details. + +2. Build paddlepaddle from source. See [**Compile From Source Code**](https://www.paddlepaddle.org.cn/documentation/docs/en/1.5/beginners_guide/install/compile/fromsource_en.html) for more details. Note that if you want to enable data parallel training for multiple GPUs, you should set `-DWITH_DISTRIBUTE=ON` with cmake. + +### Other Requirements + +Install other requirements with pip. + + +```bash +pip install -r requirements.txt +``` + +You also need to download punkt and cmudict for nltk, because we tokenize text with `punkt` and convert text into phonemes with `cmudict`. + +```python +import nltk +nltk.download("punkt") +nltk.download("cmudict") +``` + +## Model Architecture + +![DeepVoice3 model architecture](./_images/model_architecture.png) + +The model consists of an encoder, a decoder and a converter (and a speaker embedding for multispeaker models). The encoder, together with the decoder forms the seq2seq part of the model, and the converter forms the postnet part. + +## Project Structure + +```text +├── audio.py # audio processing +├── compute_timestamp_ratio.py # script to compute position rate +├── conversion # parameter conversion from pytorch model +├── requirements.txt # requirements +├── hparams.py # HParam class for deepvoice3 +├── hparam_tf # hyper parameter related stuffs +├── ljspeech.py # functions for ljspeech preprocessing +├── preprocess.py # preprocrssing script +├── presets # preset hyperparameters +├── deepvoice3_paddle # DeepVoice3 model implementation +├── eval_model.py # functions for model evaluation +├── synthesis.py # script for speech synthesis +├── train_model.py # functions for model training +└── train.py # script for model training +``` + +## Usage + +There are many hyperparameters to be tuned depending on the specification of model and dataset you are working on. Hyperparameters that are known to work good are provided in the repository. See `presets` directory for details. Now we only provide preset with LJSpeech dataset (`deepvoice3_ljspeech.json`). Support for more models and datasets is pending. + +Note that `preprocess.py`, `train.py` and `synthesis.py` all accept a `--preset` parameter. To ensure consistency, you should use the same preset for preprocessing, training and synthesizing. + +Note that you can overwrite preset hyperparameters with command line argument `--hparams`, just pass several key-value pair in `${key}=${value}` format seperated by comma (`,`). For example `--hparams="batch_size=8, nepochs=500"` can overwrite default values in the preset json file. For more details about hyperparameters, see `hparams.py`, which contains the definition of `hparams`. Priority order of hyperparameters is command line option `--hparams` > `--preset` json configuration file > definition of hparams in `hparams.py`. + +Some hyperparameters are only related to training, like `batch_size`, `checkpoint_interval` and you can use different values for preprocessing and training. But hyperparameters related to data preprocessing, like `num_mels` and `ref_level_db`, should be kept the same for preprocessing and training. + + +### Dataset + +Download and unzip [LJSpeech](https://keithito.com/LJ-Speech-Dataset/). + +```bash +wget https://data.keithito.com/data/speech/LJSpeech-1.1.tar.bz2 +tar xjvf LJSpeech-1.1.tar.bz2 +``` + +Preprocessing with `preprocess.py`. + +```bash +python preprocess.py \ + --preset=${preset_json_path} \ + --hparams="hyper parameters you want to overwrite" \ + ${name} ${in_dir} ${out_dir} +``` + +Now `${dataset_name}$` only supports `ljspeech`. Support for other datasets is pending. + +Assuming that you use `presers/deepvoice3_ljspeech.json` for LJSpeech and the path of the unziped dataset is `~/data/LJSpeech-1.1`, then you can preprocess data with the following command. + +```bash +python preprocess.py \ + --preset=presets/deepvoice3_ljspeech.json \ + ljspeech ~/data/LJSpeech-1.1/ ./data/ljspeech +``` + +When this is done, you will see extracted features in `./data/ljspeech` including: + +1. text and corresponding file names for the extracted features in `train.txt`. +2. mel-spectrogram in `ljspeech-mel-*.npy` . +3. linear-spectrogram in `ljspeech-spec-*.npy`. + +### Train on single GPU + +Training the whole model on one single GPU: + +```bash +export CUDA_VISIBLE_DEVICES=0 +python train.py --data-root=${data-root} --use-gpu \ + --preset=${preset_json_path} \ + --hparams="parameters you may want to override" +``` + +For more details about `train.py`, see `python train.py --help`. + +#### load checkpoints + +You can load saved checkpoint and resume training with `--checkpoint`, if you wan to reset optimizer states, pass `--reset-optimizer` in addition. + +#### train a part of the model + +You can also train parts of the model while freezing other parts, by passing `--train-seq2seq-only` or `--train-postnet-only`. When training only parts of the model, other parts should be loaded from saved checkpoints. + +To train only the `seq2seq` or `postnet`, you should load from a whole model with `--checkpoint`and keep the same configurations. Note that when training only the `postnet`, you should set `use_decoder_state_for_postnet_input=false`, because when train only the postnet, the postnet takes the ground truth mel-spectrogram as input. + +example: + +```bash +export CUDA_VISIBLE_DEVICES=0 +python train.py --data-root=${data-root} --use-gpu \ + --preset=${preset_json_path} \ + --hparams="parameters you may want to override" \ + --train-seq2seq-only \ + --checkpoint=${path_of_the_saved_model} +``` + +### Training on multiple GPUs + +Training on multiple GPUs with data parallel is enabled. You can run `train.py` with `paddle.distributed.launch` module. Here is the command line usage. + +```bash +python -m paddle.distributed.launch \ + --started_port ${port_of_the_first_worker} \ + --selected_gpus ${logical_gpu_ids_to_choose} \ + --log_dir ${path_of_write_log} \ + training_script ... +``` + +`paddle.distributed.launch` parallelizes training in multiprocessing mode.`--selected_gpus` means the logical ids of the selected GPUs, and `started_port` means the port used by the first worker. Outputs of each worker are saved in `--log_dir.` Then follows the command for training on a single GPU, except that you should pass `--use-data-paralle` in addition. + +```bash +export CUDA_VISIBLE_DEVICES=2,3,4,5 # The IDs of visible physical devices +python -m paddle.distributed.launch \ + --selected_gpus=0,1,2,3 --log_dir ${multi_gpu_log_dir} \ + train.py --data-root=${data-root} \ + --use-gpu --use-data-parallel \ + --preset=${preset_json_path} \ + --hparams="parameters you may want to override" +``` + +In the example above, we set only GPU `2, 3, 4, 5` to be visible. Then `--selected_gpus="0, 1, 2, 3"` means the logical ids of the selected gpus, which correpond to GPU `2, 3, 4, 5`. + +Model checkpoints (directory ending with `.model`) are saved in `./checkpoints` per 10000 steps by default. Layer-wise averaged attention alignments (.png) are saved in `.checkpointys/alignment_ave`. And alignments for each attention layer are saved in `.checkpointys/alignment_layer{attention_layer_num}` per 10000 steps for inspection. + +Synthesis results of 6 sentences (hardcoded in `eval_model.py`) are saved in `checkpoints/eval`, including `step{step_num}_text{text_id}_single_alignment.png` for averaged alignments and `step{step_num}_text{text_id}_single_predicted.wav` for the predicted waveforms. + + +### Monitor with Tensorboard + +Logs with tensorboard are saved in `./log/${datetime}` directory by default. You can monitor logs by tensorboard. + +```bash +tensorboard --logdir=${log_dir} --host=$HOSTNAME --port=8888 +``` + +### Synthesize from a checkpoint + +Given a list of text, `synthesis.py` synthesize audio signals from a trained model. + +```bash +python infer.py --use-gpu --preset=${preset_json_path} \ + --hparams="parameters you may want to override" \ + ${checkpoint} ${text_list_file} ${dst_dir}} +``` + +Example test_list.txt: + +```text +Generative adversarial network or variational auto-encoder. +Once upon a time there was a dear little girl who was loved by every one who looked at her, but most of all by her grandmother, and there was nothing that she would not have given to the child. +A text-to-speech synthesis system typically consists of multiple stages, such as a text analysis frontend, an acoustic model and an audio synthesis module. +``` + +generated waveform files and alignment files are saved in `${dst_dir}`. + +### Compute position ratio + +According to [Deep Voice 3: Scaling Text-to-Speech with Convolutional Sequence Learning](https://arxiv.org/abs/1710.07654), the position rate is different for different datasets. There are 2 position rates, one for the query and the other for the key, which are referred to as $\omega_1$ and $\omega_2$ in th paper, and the corresponding names in preset json are `query_position_rate` and `key_position_rate`. + +For example, the `query_position_rate` and `key_position_rate` for LJSpeech are `1.0` and `1.385`, respectively. These values are computed with `compute_timestamp_ratio.py`. Run the command below. + +```bash +python compute_timestamp_ratio.py --preset=${preset_json_path} \ + --hparams="parameters you may want to override" ${data_root} +``` + +You will get outputs like this. + +```text +100%|██████████████████████████████████████████████████████████| 13047/13047 [00:12<00:00, 1058.19it/s] +1345587 1863884.0 1.3851828235558161 +``` + +Then set the `key_position_rate=1.385` and `query_position_rate=1.0` in the preset. + +## Acknowledgement + +We thankfully included and adapted some files r9y9's from [deepvoice3_pytorch](https://github.com/r9y9/deepvoice3_pytorch). diff --git a/PaddleSpeech/DeepVoice3/README_cn.md b/PaddleSpeech/DeepVoice3/README_cn.md new file mode 100644 index 00000000..7f15f4cc --- /dev/null +++ b/PaddleSpeech/DeepVoice3/README_cn.md @@ -0,0 +1,220 @@ +# Deep Voice 3 with Paddle Fluid + + +Paddle 实现的 Deepvoice3,一个基于卷积神经网络的语音合成 (Text to Speech) 模型。本实现基于 [Deep Voice 3: Scaling Text-to-Speech with Convolutional Sequence Learning](https://arxiv.org/abs/1710.07654) 。 + +本 Deepvoice3 实现使用 Paddle 动态图模式,这对于灵活的网络结构更为方便。 + +## 安装 + +### 安装 paddlepaddle 框架 + +为了更快的训练速度和更好的支持,我们推荐使用最新的开发版 paddle。用户可以最新编译的开发版 whl 包,也可以选择从源码编译 Paddle。 + +1. 下载最新编译的开发版 whl 包。可以从 [**多版本 wheel 包列表-dev**](https://www.paddlepaddle.org.cn/documentation/docs/zh/beginners_guide/install/Tables.html#whl-dev) 页面中选择合适的版本。 + +2. 从源码编译 Paddle. 参考[**从源码编译**](https://www.paddlepaddle.org.cn/documentation/docs/zh/beginners_guide/install/compile/fromsource.html) 页面。注意,如果你需要使用多卡训练,那么编译前需要设置选项 `-DWITH_DISTRIBUTE=ON`。 + +### 其他依赖 + +使用 pip 安装其他依赖。 + +```bash +pip install -r requirements.txt +``` + +另外需要下载 nltk 的两个库,因为使用了 `punkt` 对文本进行 tokenization,并且使用了 `cmudict` 来将文本转为音位。 + +```python +import nltk +nltk.download("punkt") +nltk.download("cmudict") +``` + +## 模型结构 + +![DeepVoice3 模型结构](./_images/model_architecture.png) + +模型包含 encoder, decoder, converter 几个部分,对于 multispeaker 数据集,还有一个 speaker embedding。其中 encoder 和 decoder 构成 seq2seq 部分,converter 构成 postnet 部分。 + +## 项目结构 + +```text +├── audio.py # 用于处理处理音频的函数 +├── compute_timestamp_ratio.py # 计算 position rate 的脚本 +├── conversion # 用于转换 pytorch 实现的参数 +├── requirements.txt # 项目依赖 +├── hparams.py # DeepVoice3 运行超参数配置类的定义 +├── hparam_tf # 超参数相关 +├── ljspeech.py # ljspeech 数据集预处理 +├── preprocess.py # 通用预处理脚本 +├── presets # 预设超参数配置 +├── deepvoice3_paddle # DeepVoice3 模型实现的主要文件 +├── eval_model.py # 模型测评相关函数 +├── synthesis.py # 用于语音合成的脚本 +├── train_model.py # 模型训练相关函数 +└── train.py # 用于模型训练的脚本 +``` + +## 使用方法 + +根据所使用的模型配置和数据集的不同,有不少超参数需要进行调节。我们提供已知结果较好的超参数设置,详见 `presets` 文件夹。目前我们只提供 LJSpeech 的预设配置 (`deepvoice3_ljspeech.json`)。后续将提供更多模型和数据集的预设配置。 + +`preprocess.py`,`train.py`,`synthesis.py` 都接受 `--preset` 参数。为了保持一致性,最好在数据预处理,模型训练和语音合成时使用相同的预设配置。 + +可以通过 `--hparams` 参数来覆盖预设的超参数配置,参数格式是逗号分隔的键值对 `${key}=${value}`,例如 `--hparams="batch_size=8, nepochs=500"`。关于超参数设置更多细节可以参考 `hparams.py` ,其中定义了 hparams。超参数的优先级序列是:通过命令行参数 `--hparams` 传入的参数优先级高于通过 `--preset` 参数传入的 json 配置文件,高于 `hparams.py` 中的定义。 + +部分参数可以只和训练有关,如 `batch_size`, `checkpoint_interval`, 用户在训练时可以使用不同的值。但部分参数和数据预处理相关,如 `num_mels` 和 `ref_level_db`, 这些参数在数据预处理和训练时候应该保持一致。 + +关于超参数设置更多细节可以参考 `hparams.py` ,其中定义了 hparams。超参数的优先级序列是:通过命令行参数 `--hparams` 传入的参数优先级高于通过 `--preset` 参数传入的 json 配置文件,高于 `hparams.py` 中的定义。 + +### 数据集 + +下载并解压 [LJSpeech](https://keithito.com/LJ-Speech-Dataset/) 数据集。 + +```bash +wget https://data.keithito.com/data/speech/LJSpeech-1.1.tar.bz2 +tar xjvf LJSpeech-1.1.tar.bz2 +``` + +使用 `preprocess.py`进行预处理。 + +```bash +python preprocess.py \ + --preset=${preset_json_path} \ + --hparams="hyper parameters you want to overwrite" \ + ${name} ${in_dir} ${out_dir} +``` + +目前 `${dataset_name}$` 只支持 `ljspeech`。未来将会支持更多数据集。 + +假设你使用 `presers/deepvoice3_ljspeech.json` 作为处理 LJSpeech 的预设配置文件,并且解压后的数据集位于 `~/data/LJSpeech-1.1`, 那么使用如下的命令进行数据预处理。 + +```bash +python preprocess.py \ + --preset=presets/deepvoice3_ljspeech.json \ + ljspeech ~/data/LJSpeech-1.1/ ./data/ljspeech +``` + +数据处理完成后,你会在 `./data/ljspeech` 看到提取的特征,包含如下文件。 + +1. `train.txt`,包含文本和对应的音频特征的文件名。 +2. `ljspeech-mel-*.npy`,包含 mel 频谱。 +3. `ljspeech-spec-*.npy`,包含线性频谱。 + +### 使用 GPU 单卡训练 + +在单个 GPU 上训练整个模型的使用方法如下。 + +```bash +export CUDA_VISIBLE_DEVICES=0 +python train.py --data-root=${data-root} --use-gpu \ + --preset=${preset_json_path} \ + --hparams="parameters you may want to override" +``` + +用于可以通过 `python train.py --help` 查看 `train.py` 的详细使用方法。 + +#### 加载保存的模型 + +用户可以通过 `--checkpoint` 参数加载保存的模型并恢复训练。如果你想要重置优化器的状态,在训练脚本加入 `--reset-optimizer` 参数。 + +#### 训练模型的一部分 + +用户可以通过 `--train-seq2seq-only` 或者 `--train-postnet-only` 来实现固定模型的其他部分,只训练需要训练的部分。但当只训练模型的一部分时,其他的部分需要从保存的模型中加载。 + +当只训练模型的 `seq2seq` 部分或者 `postnet` 部分时,需要使用 `--checkpoint` 加载整个模型并保持相同的配置。注意,当只训练 `postnet` 的时候,需要保证配置中的`use_decoder_state_for_postnet_input=false`,因为在这种情况下,postnet 使用真实的 mel 频谱作为输入。 + +示例: + +```bash +export CUDA_VISIBLE_DEVICES=0 +python train.py --data-root=${data-root} --use-gpu \ + --preset=${preset_json_path} \ + --hparams="parameters you may want to override" \ + --train-seq2seq-only \ + --checkpoint=${path_of_the_saved_model} +``` + +### 使用 GPU 多卡训练 + +本模型支持使用多个 GPU 通过数据并行的方式 训练。方法是使用 `paddle.distributed.launch` 模块来启动 `train.py`。 + +```bash +python -m paddle.distributed.launch \ + --started_port ${port_of_the_first_worker} \ + --selected_gpus ${logical_gpu_ids_to_choose} \ + --log_dir ${path_of_write_log} \ + training_script ... +``` + +paddle.distributed.launch 通过多进程的方式进行并行训练。`--selected_gpus` 指的是选择的 GPU 的逻辑序号,`started_port` 指的是 0 号显卡的使用的端口号,`--log_dir` 是日志保存的目录,每个进程的输出会在这个文件夹中保存为单独的文件。再在后面接上需要启动的脚本文件及其参数即可。这部分和单卡训练的脚本一致,但是需要传入 `--use-data-paralle` 以使用数据并行训练。示例命令如下。 + +```bash +export CUDA_VISIBLE_DEVICES=2,3,4,5 # The IDs of visible physical devices +python -m paddle.distributed.launch \ + --selected_gpus=0,1,2,3 --log_dir ${multi_gpu_log_dir} \ + train.py --data-root=${data-root} \ + --use-gpu --use-data-parallel \ + --preset=${preset_json_path} \ + --hparams="parameters you may want to override" +``` + +上述的示例中,设置了 `2, 3, 4, 5` 号显卡为可见的 GPU。然后 `--selected_gpus=0,1,2,3` 选择的是 GPU 的逻辑序号,分别对应于 `2, 3, 4, 5` 号卡。 + +模型默认被保存为后缀为 `.model`的文件夹,保存在 `./checkpoints` 文件夹中。多层平均的注意力机制对齐结果被保存为 `.png` 图片,默认保存在 `.checkpointys/alignment_ave` 中。每一层的注意力机制对齐结果默认被保存在 `.checkpointys/alignment_layer{attention_layer_num}`文件夹中。默认每 10000 步保存一次用于查看。 + +对 6 个给定的句子的语音合成结果保存在 `checkpoints/eval` 中,包含多层平均平均的注意力机制对齐结果,这被保存为名为 `step{step_num}_text{text_id}_single_alignment.png` 的图片;以及合成的音频文件,保存为名为 `step{step_num}_text{text_id}_single_predicted.wav` 的音频。 + + +### 使用 Tensorboard 查看训练 + +Tensorboard 训练日志默认被保存在 `./log/${datetime}` 文件夹,可以通过 tensorboard 查看。使用方法如下。 + +```bash +tensorboard --logdir=${log_dir} --host=$HOSTNAME --port=8888 +``` + +### 从保存的模型合成语音 + +给定一组文本,使用 `synthesis.py` 从一个训练好的模型来合成语音,使用方法如下。 + +```bash +python infer.py --use-gpu --preset=${preset_json_path} \ + --hparams="parameters you may want to override" \ + ${checkpoint} ${text_list_file} ${dst_dir}} +``` + +示例文本文件如下: + +```text +Generative adversarial network or variational auto-encoder. +Once upon a time there was a dear little girl who was loved by every one who looked at her, but most of all by her grandmother, and there was nothing that she would not have given to the child. +A text-to-speech synthesis system typically consists of multiple stages, such as a text analysis frontend, an acoustic model and an audio synthesis module. +``` + +合成的结果包含注意力机制对齐结果和音频文件,保存于 `${dst_dir}`。 + +### 计算 position rate + +根据 [Deep Voice 3: Scaling Text-to-Speech with Convolutional Sequence Learning](https://arxiv.org/abs/1710.07654), 对于不同的数据集,会有不同的 position rate. 有两个不同的 position rate,一个用于 query 一个用于 key, 这在论文中称为 $\omega_1$ 和 $\omega_2$ ,在预设配置文件中的名字分别为 `query_position_rate` 和 `key_position_rate`。 + +比如 LJSpeech 数据集的 `query_position_rate` 和 `key_position_rate` 分别为 `1.0` 和 `1.385`。这些值可以 `compute_timestamp_ratio.py`。使用如下命令计算。 + +```bash +python compute_timestamp_ratio.py --preset=${preset_json_path} \ + --hparams="parameters you may want to override" ${data_root} +``` + +可以得到如下的结果。 + +```text +100%|██████████████████████████████████████████████████████████| 13047/13047 [00:12<00:00, 1058.19it/s] +1345587 1863884.0 1.3851828235558161 +``` + +然后在预设配置文件中设置 `key_position_rate=1.385` 以及 `query_position_rate=1.0`。 + +## 致谢 + +本实现包含及改写了 r9y9's 的 [deepvoice3_pytorch](https://github.com/r9y9/deepvoice3_pytorch) 中的部分文件,在此表示感谢。 diff --git a/PaddleSpeech/DeepVoice3/_images/model_architecture.png b/PaddleSpeech/DeepVoice3/_images/model_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..4668a30490a50341c10a2660459f52f9e74482d5 GIT binary patch literal 458087 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 e<84JS-rr!m5i?4+nOhH$ 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
LYqr*?Zw38SL`eb!C|RjN)Z3UkQRc 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
@VM#6)8$(20CPQdb|-iULNjnN{> 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%0AZIR+!gk_96B*;=!8hRP(}-)<3OA7020> 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%0A%<{@CoP`@wm@baM#(^PBBS%M83BnO?dB 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 baITBQm92Y)6!+vWFz|7A*@tg*I+XTL@~yX4 literal 0 HcmV?d00001 diff --git a/PaddleSpeech/DeepVoice3/audio.py b/PaddleSpeech/DeepVoice3/audio.py new file mode 100644 index 00000000..1542a778 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/audio.py @@ -0,0 +1,98 @@ +# This file was copied from https://github.com/r9y9/deepvoice3_pytorch/tree/master/audio.py +# Copyright (c) 2017: Ryuichi Yamamoto. + +import librosa +import librosa.filters +import math +import numpy as np +from scipy import signal +from hparams import hparams +from scipy.io import wavfile + +import lws + + +def load_wav(path): + return librosa.core.load(path, sr=hparams.sample_rate)[0] + + +def save_wav(wav, path): + wav = wav * 32767 / max(0.01, np.max(np.abs(wav))) + wavfile.write(path, hparams.sample_rate, wav.astype(np.int16)) + + +def preemphasis(x): + from nnmnkwii.preprocessing import preemphasis + return preemphasis(x, hparams.preemphasis) + + +def inv_preemphasis(x): + from nnmnkwii.preprocessing import inv_preemphasis + return inv_preemphasis(x, hparams.preemphasis) + + +def spectrogram(y): + D = _lws_processor().stft(preemphasis(y)).T + S = _amp_to_db(np.abs(D)) - hparams.ref_level_db + return _normalize(S) + + +def inv_spectrogram(spectrogram): + '''Converts spectrogram to waveform using librosa''' + S = _db_to_amp(_denormalize(spectrogram) + + hparams.ref_level_db) # Convert back to linear + processor = _lws_processor() + D = processor.run_lws(S.astype(np.float64).T**hparams.power) + y = processor.istft(D).astype(np.float32) + return inv_preemphasis(y) + + +def melspectrogram(y): + D = _lws_processor().stft(preemphasis(y)).T + S = _amp_to_db(_linear_to_mel(np.abs(D))) - hparams.ref_level_db + if not hparams.allow_clipping_in_normalization: + assert S.max() <= 0 and S.min() - hparams.min_level_db >= 0 + return _normalize(S) + + +def _lws_processor(): + return lws.lws(hparams.fft_size, hparams.hop_size, mode="speech") + + +# Conversions: + +_mel_basis = None + + +def _linear_to_mel(spectrogram): + global _mel_basis + if _mel_basis is None: + _mel_basis = _build_mel_basis() + return np.dot(_mel_basis, spectrogram) + + +def _build_mel_basis(): + if hparams.fmax is not None: + assert hparams.fmax <= hparams.sample_rate // 2 + return librosa.filters.mel(hparams.sample_rate, + hparams.fft_size, + fmin=hparams.fmin, + fmax=hparams.fmax, + n_mels=hparams.num_mels) + + +def _amp_to_db(x): + min_level = np.exp(hparams.min_level_db / 20 * np.log(10)) + return 20 * np.log10(np.maximum(min_level, x)) + + +def _db_to_amp(x): + return np.power(10.0, x * 0.05) + + +def _normalize(S): + return np.clip((S - hparams.min_level_db) / -hparams.min_level_db, 0, 1) + + +def _denormalize(S): + return (np.clip(S, 0, 1) * -hparams.min_level_db) + hparams.min_level_db diff --git a/PaddleSpeech/DeepVoice3/compute_timestamp_ratio.py b/PaddleSpeech/DeepVoice3/compute_timestamp_ratio.py new file mode 100644 index 00000000..d6d07860 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/compute_timestamp_ratio.py @@ -0,0 +1,65 @@ +# Part of code was adpated from https://github.com/r9y9/deepvoice3_pytorch/tree/master/compute_timestamp_ratio.py +# Copyright (c) 2017: Ryuichi Yamamoto. + +import argparse +import sys +import numpy as np +from hparams import hparams, hparams_debug_string +from deepvoice3_paddle.data import TextDataSource, MelSpecDataSource +from nnmnkwii.datasets import FileSourceDataset +from tqdm import trange +from deepvoice3_paddle import frontend + + +def build_parser(): + parser = argparse.ArgumentParser( + description="Compute output/input timestamp ratio.") + parser.add_argument( + "--hparams", type=str, default="", help="Hyper parameters.") + parser.add_argument( + "--preset", + type=str, + required=True, + help="Path of preset parameters (json).") + parser.add_argument("data_root", type=str, help="path of the dataset.") + return parser + + +if __name__ == "__main__": + parser = build_parser() + args, _ = parser.parse_known_args() + + data_root = args.data_root + preset = args.preset + + # Load preset if specified + if preset is not None: + with open(preset) as f: + hparams.parse_json(f.read()) + # Override hyper parameters + hparams.parse(args.hparams) + assert hparams.name == "deepvoice3" + + # Code below + X = FileSourceDataset(TextDataSource(data_root)) + Mel = FileSourceDataset(MelSpecDataSource(data_root)) + + in_sizes = [] + out_sizes = [] + for i in trange(len(X)): + x, m = X[i], Mel[i] + if X.file_data_source.multi_speaker: + x = x[0] + in_sizes.append(x.shape[0]) + out_sizes.append(m.shape[0]) + + in_sizes = np.array(in_sizes) + out_sizes = np.array(out_sizes) + + input_timestamps = np.sum(in_sizes) + output_timestamps = np.sum( + out_sizes) / hparams.outputs_per_step / hparams.downsample_step + + print(input_timestamps, output_timestamps, + output_timestamps / input_timestamps) + sys.exit(0) diff --git a/PaddleSpeech/DeepVoice3/conversion/README.md b/PaddleSpeech/DeepVoice3/conversion/README.md new file mode 100644 index 00000000..a8b692e4 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/conversion/README.md @@ -0,0 +1,37 @@ +# Parameter conversion + +## generate name map + +To convert a model trained with `https://github.com/r9y9/deepvoice3_pytorch`, we provide a script to generate name map between pytorch model and paddle model for `deepvoice3`. You can provide `--preset` and `--hparams` to specify the model's configuration. + +```bash +python generate_name_map.py --preset=${preset_to_use} --haprams="hyper parameters to overwrite" +``` + +It would print a name map. The format of the name map file looks like this. Each line consists of 3 fields, the first is the name of a parameter in the saved state dict of pytorch model, the second and third is the name and shape of the corresponding parameter in the saved state dict of paddle. + + +``` +seq2seq.encoder.embed_tokens.weight encoder/Encoder_0/Embedding_0.w_0 [149, 256] +seq2seq.encoder.convolutions.0.bias encoder/Encoder_0/ConvProj1D_1/Conv2D_0.b_0 [512] +seq2seq.encoder.convolutions.0.weight_g encoder/Encoder_0/ConvProj1D_1/Conv2D_0.w_1 [512] +``` + +Redirect the output to a file to save it. + +```bash +python generate_name_map.py --preset=${preset_to_use} --haprams="hyper parameters to overwrite" > name_map.txt +``` + +## convert saved pytorch model to paddle model + +Given a name map and a saved pytorch model, you can convert it to a paddle model. + +```bash +python convert.py \ + --pytorch-model ${pytorch_model.pth} \ + --paddle-model ${path_to_save_paddle_model} \ + --name-map ${name_map_path} +``` + +Note that the user should provide the name map file, and ensure the models are equivalent to each other and corresponding parameters have the right shapes. diff --git a/PaddleSpeech/DeepVoice3/conversion/convert.py b/PaddleSpeech/DeepVoice3/conversion/convert.py new file mode 100644 index 00000000..96840c72 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/conversion/convert.py @@ -0,0 +1,95 @@ +# Copyright (c) 2019 PaddlePaddle 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. + +import numpy as np +import torch + +import paddle +from paddle import fluid + +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument( + "--pytorch-model", + dest='pytorch_model', + type=str, + help="The source pytorch mode.") +parser.add_argument( + "--paddle-model", + dest='paddle_model', + type=str, + help="The directory to save paddle model, now saves model as a folder.") +parser.add_argument( + "--name-map", + dest="name_map", + type=str, + help="name mapping for the source model and the target model.") + + +def read_name_map(fname): + """ + There should be a 3-column file. + The first comuln is the name of parameter in pytorch model's state dict; + The second column is the name of parameter in paddle model's state dict; + The third column is the shape of the repective parameter in paddle model. + """ + name_map = {} + with open(fname, 'rt') as f: + for line in f: + src_key, tgt_key, tgt_shape = line.strip().split('\t') + tgt_shape = eval(tgt_shape) + name_map[src_key] = (tgt_key, tgt_shape) + return name_map + + +def torch2paddle(state_dict, name_map, dirname): + """ + state_dict: pytorch model's state dict. + name_map: a text file for name mapping from pytorch model to paddle model. + dirname: path of the paddle model to save. + """ + program = fluid.Program() + global_block = program.global_block() + + for k in state_dict.keys(): + global_block.create_parameter( + name=name_map[k][0], + shape=[1], + dtype='float32', + initializer=fluid.initializer.Constant(value=0.0)) + + place = fluid.core.CPUPlace() + exe = fluid.Executor(place) + exe.run(fluid.default_startup_program()) + exe.run(program) + + # NOTE: transpose the pytorch model's parameter if neccessary + # we do not transpose here because we used conv instead of FC layer to replace Linear in pytorch, + # which does not need us to transpose the paramerters. + # but when you use a FC layer corresponding a torch Linear module, be sure to transpose the weight. + # Other transformations are not concerned, but users should check the data shape to ensure that + # the transformations are what's expected. + for k, v in state_dict.items(): + fluid.global_scope().find_var(name_map[k][0]).get_tensor().set( + v.cpu().numpy().reshape(name_map[k][1]), place) + fluid.io.save_params(exe, dirname, main_program=program) + + +if __name__ == "__main__": + args, _ = parser.parse_known_args() + result = torch.load(args.pytorch_model) + state_dict = result["state_dict"] + name_map = read_name_map(args.name_map) + torch2paddle(state_dict, name_map, args.paddle_model) diff --git a/PaddleSpeech/DeepVoice3/conversion/generate_name_map.py b/PaddleSpeech/DeepVoice3/conversion/generate_name_map.py new file mode 100644 index 00000000..0eb747f4 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/conversion/generate_name_map.py @@ -0,0 +1,627 @@ +# Copyright (c) 2019 PaddlePaddle 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. +""" +Generate a name map from configuration +""" +from collections import OrderedDict + +import numpy as np +from argparse import ArgumentParser +from deepvoice3_paddle import frontend +from hparams import hparams, hparams_debug_string + + +def build_arg_parser(): + parser = ArgumentParser(description="Train deepvoice 3 model.") + + parser.add_argument( + "--preset", + type=str, + required=True, + help="Path of preset parameters in json format.") + parser.add_argument( + "--hparams", + type=str, + default="", + help="Hyper parameters to override preset.") + return parser + + +def gen_conv(in_channels, out_channels, kernel_size, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name): + # bias + torch_bias_name = "{}.bias".format(torch_base_name) + paddle_bias_name = "{}.b_0".format(paddle_base_name) + torch_bias_shape = (out_channels, ) + paddle_bias_shape = [out_channels, ] + + torch_state[torch_bias_name] = torch_bias_shape + paddle_state[paddle_bias_name] = paddle_bias_shape + name_map[torch_bias_name] = paddle_bias_name + + # wg + torch_wg_name = "{}.weight_g".format(torch_base_name) + paddle_wg_name = "{}.w_1".format(paddle_base_name) + torch_wg_shape = (out_channels, 1, 1) + paddle_wg_shape = [out_channels, ] + + torch_state[torch_wg_name] = torch_wg_shape + paddle_state[paddle_wg_name] = paddle_wg_shape + name_map[torch_wg_name] = paddle_wg_name + + # wv + torch_wv_name = "{}.weight_v".format(torch_base_name) + paddle_wv_name = "{}.w_0".format(paddle_base_name) + torch_wv_shape = (out_channels, in_channels, kernel_size) + paddle_wv_shape = [out_channels, in_channels, 1, kernel_size] + + torch_state[torch_wv_name] = torch_wv_shape + paddle_state[paddle_wv_name] = paddle_wv_shape + name_map[torch_wv_name] = paddle_wv_name + + +def gen_fc2conv(in_channels, out_channels, torch_state, paddle_state, name_map, + torch_base_name, paddle_base_name): + # bias + torch_bias_name = "{}.bias".format(torch_base_name) + paddle_bias_name = "{}.b_0".format(paddle_base_name) + torch_bias_shape = (out_channels, ) + paddle_bias_shape = [out_channels, ] + + torch_state[torch_bias_name] = torch_bias_shape + paddle_state[paddle_bias_name] = paddle_bias_shape + name_map[torch_bias_name] = paddle_bias_name + + # wg + torch_wg_name = "{}.weight_g".format(torch_base_name) + paddle_wg_name = "{}.w_1".format(paddle_base_name) + torch_wg_shape = (out_channels, 1) + paddle_wg_shape = [out_channels, ] + + torch_state[torch_wg_name] = torch_wg_shape + paddle_state[paddle_wg_name] = paddle_wg_shape + name_map[torch_wg_name] = paddle_wg_name + + # wv + torch_wv_name = "{}.weight_v".format(torch_base_name) + paddle_wv_name = "{}.w_0".format(paddle_base_name) + torch_wv_shape = (out_channels, in_channels) + paddle_wv_shape = [out_channels, in_channels, 1, 1] + + torch_state[torch_wv_name] = torch_wv_shape + paddle_state[paddle_wv_name] = paddle_wv_shape + name_map[torch_wv_name] = paddle_wv_name + + +def generate_name_map(name_scope): + TTS_model_idx = 0 + prefix = "/".join([name_scope, "DeepVoiceTTS_{}".format(TTS_model_idx)]) + + _frontend = getattr(frontend, hparams.frontend) + + torch_state = OrderedDict() + paddle_state = OrderedDict() + name_map = OrderedDict() + + # text embedding + torch_name = "seq2seq.encoder.embed_tokens.weight" + paddle_name = "{}/ConvS2S_0/Encoder_0/Embedding_0.w_0".format(prefix) + torch_shape = (_frontend.n_vocab, hparams.text_embed_dim) + paddle_shape = [_frontend.n_vocab, hparams.text_embed_dim] + + torch_state[torch_name] = torch_shape + paddle_state[paddle_name] = paddle_shape + name_map[torch_name] = paddle_name + + # encoder + + Conv1D_idx = 0 + Conv1DGLU_idx = 0 + + if hparams.n_speakers > 1: + for i in [1, 2]: + torch_base_name = "seq2seq.encoder.speaker_fc{}".format(i) + paddle_base_name = "{}/ConvS2S_0/Encoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + Conv1D_idx += 1 + gen_fc2conv(hparams.speaker_embed_dim, hparams.text_embed_dim, + torch_state, paddle_state, name_map, torch_base_name, + paddle_base_name) + + # encoder convolution specs + encoder_channels = hparams.encoder_channels + kernel_size = hparams.kernel_size + + h = encoder_channels + k = kernel_size + convolutions = [(h, k, 1), (h, k, 3), (h, k, 9), (h, k, 27), (h, k, 1), + (h, k, 3), (h, k, 9), (h, k, 27), (h, k, 1), (h, k, 3)] + torch_layer_idx = 0 + + in_channels = hparams.text_embed_dim + + # first conv1d & conv1dglus + for out_channels, kernel_size, dilation in convolutions: + if in_channels != out_channels: + torch_base_name = "seq2seq.encoder.convolutions.{}".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Encoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_channels, out_channels, 1, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 2 + Conv1D_idx += 1 + in_channels = out_channels + + torch_base_name = "seq2seq.encoder.convolutions.{}.conv".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Encoder_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * out_channels, kernel_size, torch_state, + paddle_state, name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "seq2seq.encoder.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Encoder_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, out_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + in_channels = out_channels + + # last conv1d + torch_base_name = "seq2seq.encoder.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Encoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_channels, hparams.text_embed_dim, 1, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 2 + Conv1D_idx += 1 + in_channels = out_channels + + # decoder + + # position embeddings + PositionEmbedding_idx = 0 + torch_name = "seq2seq.decoder.embed_query_positions.weight" + paddle_name = "{}/ConvS2S_0/Decoder_0/PositionEmbedding_{}/Embedding_0.w_0".format( + prefix, PositionEmbedding_idx) + torch_shape = (hparams.max_positions, hparams.decoder_channels) + paddle_shape = [hparams.max_positions, hparams.decoder_channels] + PositionEmbedding_idx += 1 + + torch_state[torch_name] = torch_shape + paddle_state[paddle_name] = paddle_shape + name_map[torch_name] = paddle_name + + torch_name = "seq2seq.decoder.embed_keys_positions.weight" + paddle_name = "{}/ConvS2S_0/Decoder_0/PositionEmbedding_{}/Embedding_0.w_0".format( + prefix, PositionEmbedding_idx) + PositionEmbedding_idx += 1 + torch_shape = (hparams.max_positions, hparams.text_embed_dim) + paddle_shape = [hparams.max_positions, hparams.text_embed_dim] + + torch_state[torch_name] = torch_shape + paddle_state[paddle_name] = paddle_shape + name_map[torch_name] = paddle_name + + Conv1D_idx = 0 + Conv1DGLU_idx = 0 + + if hparams.n_speakers > 1: + for i in [1, 2]: + torch_base_name = "seq2seq.decoder.speaker_proj{}".format(i) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + Conv1D_idx += 1 + gen_fc2conv(hparams.speaker_embed_dim, 1, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + + # prenet + torch_layer_idx = 0 + + h = hparams.decoder_channels + k = hparams.kernel_size + prenet_convolutions = [(h, k, 1), (h, k, 3)] + + in_channels = hparams.num_mels * hparams.outputs_per_step + for out_channels, kernel_size, dilation in prenet_convolutions: + if in_channels != out_channels: + torch_base_name = "seq2seq.decoder.preattention.{}".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_channels, out_channels, 1, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 2 + Conv1D_idx += 1 + in_channels = out_channels + + torch_base_name = "seq2seq.decoder.preattention.{}.conv".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * out_channels, kernel_size, torch_state, + paddle_state, name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "seq2seq.decoder.preattention.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, out_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + in_channels = out_channels + + # conv & attn + torch_layer_idx = 0 + convolutions = [(h, k, 1), (h, k, 3), (h, k, 9), (h, k, 27), (h, k, 1)] + for out_channels, kernel_size, dilation in convolutions: + if in_channels != out_channels: + torch_base_name = "seq2seq.decoder.convolutions.{}".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_channels, out_channels, kernel_size, in_channels, + out_channels, kernel_size, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 2 + Conv1D_idx += 1 + in_channels = out_channels + + torch_base_name = "seq2seq.decoder.convolutions.{}.conv".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * out_channels, kernel_size, torch_state, + paddle_state, name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "seq2seq.decoder.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, out_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + in_channels = out_channels + + # attention + attention = [True, False, False, False, True] + AttentionLayer_idx = 0 + parts = [ + "query", "key" if hparams.key_projection else None, "value" + if hparams.value_projection else None, "out" + ] + parts = [x for x in parts if x is not None] + for (i, (attn, (out_channels, kernel_size, + dilation))) in enumerate(zip(attention, convolutions)): + if attn is False: + in_channels = out_channels + continue + for ipart, part in enumerate(parts): + torch_base_name = "seq2seq.decoder.attention.{}.{}_projection".format( + i, part) + paddle_base_name = "{}/ConvS2S_0/Decoder_0/AttentionLayer_{}/Conv1D_{}/Conv2D_0".format( + prefix, AttentionLayer_idx, ipart) + if part == "query": + C_in = out_channels + C_out = hparams.text_embed_dim + elif part == "out": + C_in = hparams.text_embed_dim + C_out = out_channels + else: + C_in = hparams.text_embed_dim + C_out = hparams.text_embed_dim + gen_fc2conv(C_in, C_out, torch_state, paddle_state, name_map, + torch_base_name, paddle_base_name) + in_channels = out_channels + AttentionLayer_idx += 1 + + # last conv + torch_base_name = "seq2seq.decoder.last_conv" + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_channels, hparams.num_mels * hparams.outputs_per_step, 1, + torch_state, paddle_state, name_map, torch_base_name, + paddle_base_name) + Conv1D_idx += 1 + + # for done output + torch_base_name = "seq2seq.decoder.fc" + paddle_base_name = "{}/ConvS2S_0/Decoder_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_fc2conv(hparams.num_mels * hparams.outputs_per_step, 1, torch_state, + paddle_state, name_map, torch_base_name, paddle_base_name) + + # converter + + # time_upsampling + if hparams.use_decoder_state_for_postnet_input: + in_dim = hparams.decoder_channels // hparams.outputs_per_step + else: + in_dim = hparams.num_mels + h = hparams.converter_channels + + time_upsampling = max(hparams.downsample_step // hparams.outputs_per_step, + 1) + assert time_upsampling == hparams.downsample_step, "implementation difference occured" + assert time_upsampling in [1, 2, 4], "other values not supported yet" + + torch_layer_idx = 0 + Conv1D_idx = 0 + Conv1DGLU_idx = 0 + Conv1DTranspose_idx = 0 + + h = hparams.converter_channels + k = hparams.kernel_size + + postnet_convolutions = [(h, k, 1), (h, k, 3), (2 * h, k, 1), (2 * h, k, 3)] + in_channels = postnet_convolutions[0][0] + + if time_upsampling == 4: + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_dim, in_channels, 1, torch_state, paddle_state, name_map, + torch_base_name, paddle_base_name) + torch_layer_idx += 1 + Conv1D_idx += 1 + + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DTranspose_{}/Conv2DTranspose_0".format( + prefix, Conv1DTranspose_idx) + gen_conv(in_channels, in_channels, 2, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 1 + Conv1DTranspose_idx += 1 + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * in_channels, 3, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, in_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DTranspose_idx) + gen_conv(in_channels, 2 * in_channels, 3, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, in_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DTranspose_{}/Conv2DTranspose_0".format( + prefix, Conv1DTranspose_idx) + gen_conv(in_channels, in_channels, 2, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 1 + Conv1DTranspose_idx += 1 + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * in_channels, 3, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, in_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * in_channels, 3, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, in_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + + elif time_upsampling == 2: + + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_dim, in_channels, 1, torch_state, paddle_state, name_map, + torch_base_name, paddle_base_name) + torch_layer_idx += 1 + Conv1D_idx += 1 + + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DTranspose_{}/Conv2DTranspose_0".format( + prefix, Conv1DTranspose_idx) + gen_conv(in_channels, in_channels, 2, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 1 + Conv1DTranspose_idx += 1 + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * in_channels, 3, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, in_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DTranspose_idx) + gen_conv(in_channels, 2 * in_channels, 3, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, in_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + + else: + assert time_upsampling == 1, "other values are not supported" + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_dim, in_channels, 1, torch_state, paddle_state, name_map, + torch_base_name, paddle_base_name) + torch_layer_idx += 1 + Conv1D_idx += 1 + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * in_channels, 3, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, in_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + + for (out_channels, kernel_size, dilation) in postnet_convolutions: + if in_channels != out_channels: + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1D_{}/Conv2D_0".format( + prefix, Conv1D_idx) + gen_conv(in_channels, out_channels, 1, torch_state, paddle_state, + name_map, torch_base_name, paddle_base_name) + torch_layer_idx += 2 + Conv1D_idx += 1 + in_channels = out_channels + + torch_base_name = "postnet.convolutions.{}.conv".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_0/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_conv(in_channels, 2 * out_channels, kernel_size, torch_state, + paddle_state, name_map, torch_base_name, paddle_base_name) + + if hparams.n_speakers > 1: + torch_base_name = "postnet.convolutions.{}.speaker_proj".format( + torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1DGLU_{}/Conv1D_1/Conv2D_0".format( + prefix, Conv1DGLU_idx) + gen_fc2conv(hparams.speaker_embed_dim, out_channels, torch_state, + paddle_state, name_map, torch_base_name, + paddle_base_name) + torch_layer_idx += 1 + Conv1DGLU_idx += 1 + in_channels = out_channels + + # last conv + linear_dim = hparams.fft_size // 2 + 1 + torch_base_name = "postnet.convolutions.{}".format(torch_layer_idx) + paddle_base_name = "{}/Converter_0/Conv1D_{}/Conv2D_0".format(prefix, + Conv1D_idx) + gen_conv(in_channels, linear_dim, 1, torch_state, paddle_state, name_map, + torch_base_name, paddle_base_name) + torch_layer_idx += 2 + Conv1D_idx += 1 + in_channels = out_channels + + # speaker_embed + if hparams.n_speakers > 1: + torch_name = "embed_speakers.weight" + torch_shape = (hparams.n_speakers, hparams.speaker_embed_dim) + paddle_name = "{}/Embedding_0.w_0".format(prefix) + paddle_shape = [hparams.n_speakers, hparams.speaker_embed_dim] + + torch_state[torch_name] = torch_shape + paddle_state[paddle_name] = paddle_shape + name_map[torch_name] = paddle_name + + # for k, v in torch_state.items(): + # print("{}\t{}".format(k, v)) + + # for k, v in paddle_state.items(): + # print("{}\t{}".format(k, v)) + + for k in name_map: + assert np.prod(torch_state[k]) == np.prod(paddle_state[name_map[ + k]]), "{} does not match".format(k) + print("{}\t{}\t{}".format(k, name_map[k], paddle_state[name_map[k]])) + + +if __name__ == "__main__": + parser = build_arg_parser() + args, _ = parser.parse_known_args() + + if args.preset is not None: + with open(args.preset) as f: + hparams.parse_json(f.read()) + # Override hyper parameters + hparams.parse(args.hparams) + # print(hparams_debug_string()) + + generate_name_map("dv3") diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/__init__.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/builder.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/builder.py new file mode 100644 index 00000000..90b0ccb2 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/builder.py @@ -0,0 +1,137 @@ +# Copyright (c) 2019 PaddlePaddle 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 deepvoice3_paddle.deepvoice3 import DeepVoiceTTS, ConvSpec, WindowRange + + +def deepvoice3(n_vocab, + embed_dim=256, + mel_dim=80, + linear_dim=513, + r=4, + downsample_step=1, + n_speakers=1, + speaker_dim=16, + padding_idx=0, + dropout=(1 - 0.96), + filter_size=5, + encoder_channels=128, + decoder_channels=256, + converter_channels=256, + query_position_rate=1.0, + key_position_rate=1.29, + use_memory_mask=False, + trainable_positional_encodings=False, + force_monotonic_attention=True, + use_decoder_state_for_postnet_input=True, + max_positions=512, + embedding_weight_std=0.1, + speaker_embedding_weight_std=0.01, + freeze_embedding=False, + window_range=WindowRange(-1, 3), + key_projection=False, + value_projection=False): + time_upsampling = max(downsample_step, 1) + + h = encoder_channels + k = filter_size + encoder_convolutions = (ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(h, k, 9), ConvSpec(h, k, 27), + ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(h, k, 9), ConvSpec(h, k, 27), + ConvSpec(h, k, 1), ConvSpec(h, k, 3)) + + h = decoder_channels + prenet_convolutions = (ConvSpec(h, k, 1), ConvSpec(h, k, 3)) + attentive_convolutions = (ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(h, k, 9), ConvSpec(h, k, 27), + ConvSpec(h, k, 1)) + attention = [True, False, False, False, True] + + h = converter_channels + postnet_convolutions = (ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(2 * h, k, 1), ConvSpec(2 * h, k, 3)) + + model = DeepVoiceTTS( + "dv3", n_speakers, speaker_dim, speaker_embedding_weight_std, n_vocab, + embed_dim, padding_idx, embedding_weight_std, freeze_embedding, + encoder_convolutions, max_positions, padding_idx, + trainable_positional_encodings, mel_dim, r, prenet_convolutions, + attentive_convolutions, attention, use_memory_mask, + force_monotonic_attention, query_position_rate, key_position_rate, + window_range, key_projection, value_projection, linear_dim, + postnet_convolutions, time_upsampling, dropout, + use_decoder_state_for_postnet_input, "float32") + return model + + +def deepvoice3_multispeaker(n_vocab, + embed_dim=256, + mel_dim=80, + linear_dim=513, + r=4, + downsample_step=1, + n_speakers=1, + speaker_dim=16, + padding_idx=0, + dropout=(1 - 0.96), + filter_size=5, + encoder_channels=128, + decoder_channels=256, + converter_channels=256, + query_position_rate=1.0, + key_position_rate=1.29, + use_memory_mask=False, + trainable_positional_encodings=False, + force_monotonic_attention=True, + use_decoder_state_for_postnet_input=True, + max_positions=512, + embedding_weight_std=0.1, + speaker_embedding_weight_std=0.01, + freeze_embedding=False, + window_range=WindowRange(-1, 3), + key_projection=False, + value_projection=False): + time_upsampling = max(downsample_step, 1) + + h = encoder_channels + k = filter_size + encoder_convolutions = (ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(h, k, 9), ConvSpec(h, k, 27), + ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(h, k, 9), ConvSpec(h, k, 27), + ConvSpec(h, k, 1), ConvSpec(h, k, 3)) + + h = decoder_channels + prenet_convolutions = (ConvSpec(h, k, 1)) + attentive_convolutions = (ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(h, k, 9), ConvSpec(h, k, 27), + ConvSpec(h, k, 1)) + attention = [True, False, False, False, False] + + h = converter_channels + postnet_convolutions = (ConvSpec(h, k, 1), ConvSpec(h, k, 3), + ConvSpec(2 * h, k, 1), ConvSpec(2 * h, k, 3)) + + model = DeepVoiceTTS( + "dv3", n_speakers, speaker_dim, speaker_embedding_weight_std, n_vocab, + embed_dim, padding_idx, embedding_weight_std, freeze_embedding, + encoder_convolutions, max_positions, padding_idx, + trainable_positional_encodings, mel_dim, r, prenet_convolutions, + attentive_convolutions, attention, use_memory_mask, + force_monotonic_attention, query_position_rate, key_position_rate, + window_range, key_projection, value_projection, linear_dim, + postnet_convolutions, time_upsampling, dropout, + use_decoder_state_for_postnet_input, "float32") + return model diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/conv.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/conv.py new file mode 100644 index 00000000..3e43232d --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/conv.py @@ -0,0 +1,222 @@ +# Copyright (c) 2019 PaddlePaddle 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. + +import math +import numpy as np + +import paddle +from paddle import fluid +import paddle.fluid.dygraph as dg + +from deepvoice3_paddle.weight_norm import Conv2D, Conv2DTranspose + + +class Conv1D(dg.Layer): + """ + A convolution 1D block implemented with Conv2D. Form simplicity and + ensuring the output has the same length as the input, it does not allow + stride > 1. + """ + + def __init__(self, + name_scope, + in_cahnnels, + num_filters, + filter_size=3, + dilation=1, + groups=None, + causal=False, + param_attr=None, + bias_attr=None, + use_cudnn=True, + act=None, + dtype="float32"): + super(Conv1D, self).__init__(name_scope, dtype=dtype) + + if causal: + padding = dilation * (filter_size - 1) + else: + padding = (dilation * (filter_size - 1)) // 2 + + self.in_channels = in_cahnnels + self.num_filters = num_filters + self.filter_size = filter_size + self.dilation = dilation + self.causal = causal + self.padding = padding + self.act = act + + self.conv = Conv2D( + self.full_name(), + num_filters=num_filters, + filter_size=(1, filter_size), + stride=(1, 1), + dilation=(1, dilation), + padding=(0, padding), + groups=groups, + param_attr=param_attr, + bias_attr=bias_attr, + use_cudnn=use_cudnn, + act=act, + dtype=dtype) + + def forward(self, x): + """ + Args: + x (Variable): Shape(B, C_in, 1, T), the input, where C_in means + input channels. + + Returns: + x (Variable): Shape(B, C_out, 1, T), the outputs, where C_out means + output channels (num_filters). + """ + x = self.conv(x) + if self.filter_size > 1: + if self.causal: + x = fluid.layers.slice( + x, axes=[3], starts=[0], ends=[-self.padding]) + elif self.filter_size % 2 == 0: + x = fluid.layers.slice(x, axes=[3], starts=[0], ends=[-1]) + return x + + def start_new_sequence(self): + self.temp_weight = None + self.input_buffer = None + + def add_input(self, x): + """ + Adding input for a time step and compute an output for a time step. + + Args: + x (Variable): Shape(B, C_in, 1, T), the input, where C_in means + input channels, and T = 1. + + Returns: + out (Variable): Shape(B, C_out, 1, T), the outputs, where C_out + means output channels (num_filters), and T = 1. + + """ + if self.temp_weight is None: + self.temp_weight = self._reshaped_weight() + + window_size = 1 + (self.filter_size - 1) * self.dilation + batch_size = x.shape[0] + in_channels = x.shape[1] + + if self.filter_size > 1: + if self.input_buffer is None: + self.input_buffer = fluid.layers.fill_constant( + [batch_size, in_channels, 1, window_size - 1], + dtype=x.dtype, + value=0.0) + else: + self.input_buffer = self.input_buffer[:, :, :, 1:] + self.input_buffer = fluid.layers.concat( + [self.input_buffer, x], axis=3) + x = self.input_buffer + if self.dilation > 1: + if not hasattr(self, "indices"): + self.indices = dg.to_variable( + np.arange(0, window_size, self.dilation)) + tmp = fluid.layers.transpose( + self.input_buffer, perm=[3, 1, 2, 0]) + tmp = fluid.layers.gather(tmp, index=self.indices) + tmp = fluid.layers.transpose(tmp, perm=[3, 1, 2, 0]) + x = tmp + inputs = fluid.layers.reshape( + x, shape=[batch_size, in_channels * 1 * self.filter_size]) + out = fluid.layers.matmul(inputs, self.temp_weight, transpose_y=True) + out = fluid.layers.elementwise_add(out, self.conv._bias_param, axis=-1) + out = fluid.layers.reshape(out, out.shape + [1, 1]) + out = self._helper.append_activation(out, act=self.act) + return out + + def _reshaped_weight(self): + """ + Get the linearized weight of convolution filter, cause it is by nature + a matmul weight. And because the model uses weight norm, compute the + weight by weight_v * weight_g to make it faster. + + Returns: + weight_matrix (Variable): Shape(C_out, C_in * 1 * kernel_size) + """ + shape = self.conv._filter_param_v.shape + matrix_shape = [shape[0], np.prod(shape[1:])] + weight_matrix = fluid.layers.reshape( + self.conv._filter_param_v, shape=matrix_shape) + weight_matrix = fluid.layers.elementwise_mul( + fluid.layers.l2_normalize( + weight_matrix, axis=1), + self.conv._filter_param_g, + axis=0) + return weight_matrix + + +class Conv1DTranspose(dg.Layer): + """ + A convolutional transpose 1D block implemented with convolutional transpose + 2D. It does not ensure that the output is exactly expanded stride times in + time dimension. + """ + + def __init__(self, + name_scope, + in_channels, + num_filters, + filter_size, + padding=0, + stride=1, + dilation=1, + groups=None, + param_attr=None, + bias_attr=None, + use_cudnn=True, + act=None, + dtype="float32"): + super(Conv1DTranspose, self).__init__(name_scope, dtype=dtype) + + self.in_channels = in_channels + self.num_filters = num_filters + self.filter_size = filter_size + self.padding = padding + self.stride = stride + self.dilation = dilation + self.groups = groups + + self.conv_transpose = Conv2DTranspose( + self.full_name(), + num_filters, + filter_size=(1, filter_size), + padding=(0, padding), + stride=(1, stride), + dilation=(1, dilation), + groups=groups, + param_attr=param_attr, + bias_attr=bias_attr, + use_cudnn=use_cudnn, + act=act, + dtype=dtype) + + def forward(self, x): + """ + Argss: + x (Variable): Shape(B, C_in, 1, T_in), where C_in means the input + channels and T_in means the number of time steps of input. + + Returns: + out (Variable): shape(B, C_out, 1, T_out), where C_out means the + output channels and T_out means the number of time steps of + input. + """ + return self.conv_transpose(x) diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/data.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/data.py new file mode 100644 index 00000000..d0f6ced1 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/data.py @@ -0,0 +1,329 @@ +# Copyright (c) 2019 PaddlePaddle 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. + +import numpy as np +import random + +import platform +from os.path import dirname, join + +from nnmnkwii.datasets import FileSourceDataset, FileDataSource +from os.path import join, expanduser +import random + +# import global hyper parameters +from hparams import hparams +from deepvoice3_paddle import frontend, builder + +_frontend = getattr(frontend, hparams.frontend) + + +def _pad(seq, max_len, constant_values=0): + return np.pad(seq, (0, max_len - len(seq)), + mode="constant", + constant_values=constant_values) + + +def _pad_2d(x, max_len, b_pad=0): + x = np.pad(x, [(b_pad, max_len - len(x) - b_pad), (0, 0)], + mode="constant", + constant_values=0) + return x + + +class TextDataSource(FileDataSource): + def __init__(self, data_root, speaker_id=None): + self.data_root = data_root + self.speaker_ids = None + self.multi_speaker = False + # If not None, filter by speaker_id + self.speaker_id = speaker_id + + def collect_files(self): + meta = join(self.data_root, "train.txt") + with open(meta, "rb") as f: + lines = f.readlines() + l = lines[0].decode("utf-8").split("|") + assert len(l) == 4 or len(l) == 5 + self.multi_speaker = len(l) == 5 + texts = list(map(lambda l: l.decode("utf-8").split("|")[3], lines)) + if self.multi_speaker: + speaker_ids = list( + map(lambda l: int(l.decode("utf-8").split("|")[-1]), lines)) + # Filter by speaker_id + # using multi-speaker dataset as a single speaker dataset + if self.speaker_id is not None: + indices = np.array(speaker_ids) == self.speaker_id + texts = list(np.array(texts)[indices]) + self.multi_speaker = False + return texts + + return texts, speaker_ids + else: + return texts + + def collect_features(self, *args): + if self.multi_speaker: + text, speaker_id = args + else: + text = args[0] + global _frontend + if _frontend is None: + _frontend = getattr(frontend, hparams.frontend) + seq = _frontend.text_to_sequence( + text, p=hparams.replace_pronunciation_prob) + + if platform.system() == "Windows": + if hasattr(hparams, "gc_probability"): + _frontend = None # memory leaking prevention in Windows + if np.random.rand() < hparams.gc_probability: + gc.collect() # garbage collection enforced + print("GC done") + + if self.multi_speaker: + return np.asarray(seq, dtype=np.int32), int(speaker_id) + else: + return np.asarray(seq, dtype=np.int32) + + +class _NPYDataSource(FileDataSource): + def __init__(self, data_root, col, speaker_id=None): + self.data_root = data_root + self.col = col + self.frame_lengths = [] + self.speaker_id = speaker_id + + def collect_files(self): + meta = join(self.data_root, "train.txt") + with open(meta, "rb") as f: + lines = f.readlines() + l = lines[0].decode("utf-8").split("|") + assert len(l) == 4 or len(l) == 5 + multi_speaker = len(l) == 5 + self.frame_lengths = list( + map(lambda l: int(l.decode("utf-8").split("|")[2]), lines)) + + paths = list( + map(lambda l: l.decode("utf-8").split("|")[self.col], lines)) + paths = list(map(lambda f: join(self.data_root, f), paths)) + + if multi_speaker and self.speaker_id is not None: + speaker_ids = list( + map(lambda l: int(l.decode("utf-8").split("|")[-1]), lines)) + # Filter by speaker_id + # using multi-speaker dataset as a single speaker dataset + indices = np.array(speaker_ids) == self.speaker_id + paths = list(np.array(paths)[indices]) + self.frame_lengths = list(np.array(self.frame_lengths)[indices]) + # aha, need to cast numpy.int64 to int + self.frame_lengths = list(map(int, self.frame_lengths)) + + return paths + + def collect_features(self, path): + return np.load(path) + + +class MelSpecDataSource(_NPYDataSource): + def __init__(self, data_root, speaker_id=None): + super(MelSpecDataSource, self).__init__(data_root, 1, speaker_id) + + +class LinearSpecDataSource(_NPYDataSource): + def __init__(self, data_root, speaker_id=None): + super(LinearSpecDataSource, self).__init__(data_root, 0, speaker_id) + + +class PartialyRandomizedSimilarTimeLengthSampler(object): + """Partially randmoized sampler + + 1. Sort by lengths + 2. Pick a small patch and randomize it + 3. Permutate mini-batchs + """ + + def __init__(self, + lengths, + batch_size=16, + batch_group_size=None, + permutate=True): + self.sorted_indices = np.argsort(lengths) + self.lengths = np.array(lengths)[self.sorted_indices] + self.batch_size = batch_size + if batch_group_size is None: + batch_group_size = min(batch_size * 32, len(self.lengths)) + if batch_group_size % batch_size != 0: + batch_group_size -= batch_group_size % batch_size + + self.batch_group_size = batch_group_size + assert batch_group_size % batch_size == 0 + self.permutate = permutate + + def __iter__(self): + indices = self.sorted_indices.copy() + batch_group_size = self.batch_group_size + s, e = 0, 0 + for i in range(len(indices) // batch_group_size): + s = i * batch_group_size + e = s + batch_group_size + random.shuffle(indices[s:e]) + + # Permutate batches + if self.permutate: + perm = np.arange(len(indices[:e]) // self.batch_size) + random.shuffle(perm) + indices[:e] = indices[:e].reshape( + -1, self.batch_size)[perm, :].reshape(-1) + + # Handle last elements + s += batch_group_size + if s < len(indices): + random.shuffle(indices[s:]) + + return iter(indices) + + def __len__(self): + return len(self.sorted_indices) + + +class Dataset(object): + def __init__(self, X, Mel, Y): + self.X = X + self.Mel = Mel + self.Y = Y + # alias + self.multi_speaker = X.file_data_source.multi_speaker + + def __getitem__(self, idx): + if self.multi_speaker: + text, speaker_id = self.X[idx] + return text, self.Mel[idx], self.Y[idx], speaker_id + else: + return self.X[idx], self.Mel[idx], self.Y[idx] + + def __len__(self): + return len(self.X) + + +def make_loader(dataset, batch_size, shuffle, sampler, create_batch_fn, + trainer_count, local_rank): + assert not ( + shuffle and + sampler), "shuffle and sampler should not be valid in the same time." + num_samples = len(dataset) + + def wrapper(): + if sampler is None: + ids = range(num_samples) + if shuffle: + random.shuffle(ids) + else: + ids = sampler + batch, batches = [], [] + for idx in ids: + batch.append(dataset[idx]) + if len(batch) >= batch_size: + batches.append(batch) + batch = [] + if len(batches) >= trainer_count: + yield create_batch_fn(batches[local_rank]) + batches = [] + + if len(batch) > 0: + batches.append(batch) + if len(batches) >= trainer_count: + yield create_batch_fn(batches[local_rank]) + + return wrapper + + +def create_batch(batch): + """Create batch""" + r = hparams.outputs_per_step + downsample_step = hparams.downsample_step + multi_speaker = len(batch[0]) == 4 + + # Lengths + input_lengths = [len(x[0]) for x in batch] + max_input_len = max(input_lengths) + input_lengths = np.array(input_lengths, dtype=np.int64) + + target_lengths = [len(x[1]) for x in batch] + + max_target_len = max(target_lengths) + target_lengths = np.array(target_lengths, dtype=np.int64) + + if max_target_len % (r * downsample_step) != 0: + max_target_len += (r * downsample_step) - max_target_len % ( + r * downsample_step) + assert max_target_len % (r * downsample_step) == 0 + + # Set 0 for zero beginning padding + # imitates initial decoder states + b_pad = r + max_target_len += b_pad * downsample_step + + x_batch = np.array( + [_pad(x[0], max_input_len) for x in batch], dtype=np.int64) + x_batch = np.expand_dims(x_batch, axis=-1) + + mel_batch = np.array( + [_pad_2d( + x[1], max_target_len, b_pad=b_pad) for x in batch], + dtype=np.float32) + + # down sampling is done here + if downsample_step > 1: + mel_batch = mel_batch[:, 0::downsample_step, :] + mel_batch = np.expand_dims(np.transpose(mel_batch, axes=[0, 2, 1]), axis=2) + + y_batch = np.array( + [_pad_2d( + x[2], max_target_len, b_pad=b_pad) for x in batch], + dtype=np.float32) + y_batch = np.expand_dims(np.transpose(y_batch, axes=[0, 2, 1]), axis=2) + + # text positions + text_positions = np.array( + [_pad(np.arange(1, len(x[0]) + 1), max_input_len) for x in batch], + dtype=np.int) + text_positions = np.expand_dims(text_positions, axis=-1) + + max_decoder_target_len = max_target_len // r // downsample_step + + # frame positions + s, e = 1, max_decoder_target_len + 1 + frame_positions = np.tile( + np.expand_dims( + np.arange(s, e), axis=0), (len(batch), 1)) + frame_positions = np.expand_dims(frame_positions, axis=-1) + + # done flags + done = np.array([ + _pad( + np.zeros( + len(x[1]) // r // downsample_step - 1, dtype=np.float32), + max_decoder_target_len, + constant_values=1) for x in batch + ]) + done = np.expand_dims(np.expand_dims(done, axis=1), axis=1) + + if multi_speaker: + speaker_ids = np.expand_dims(np.array([x[3] for x in batch]), axis=-1) + return (x_batch, input_lengths, mel_batch, y_batch, text_positions, + frame_positions, done, target_lengths, speaker_ids) + else: + speaker_ids = None + return (x_batch, input_lengths, mel_batch, y_batch, text_positions, + frame_positions, done, target_lengths) diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/deepvoice3.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/deepvoice3.py new file mode 100644 index 00000000..09837a19 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/deepvoice3.py @@ -0,0 +1,1498 @@ +# Copyright (c) 2019 PaddlePaddle 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 itertools import chain +from collections import namedtuple + +from paddle import fluid +import paddle.fluid.dygraph as dg + +import numpy as np + +from deepvoice3_paddle import conv + +from deepvoice3_paddle.modules import Embedding, PositionEmbedding +from deepvoice3_paddle.modules import FC, Conv1D, Conv1DGLU, Conv1DTranspose + +ConvSpec = namedtuple("ConvSpec", ["out_channels", "filter_size", "dilation"]) +WindowRange = namedtuple("WindowRange", ["backward", "ahead"]) + + +def expand_speaker_embed(x, speaker_embed, tdim=-1): + """ + Expand speaker embeddings for multiple timesteps. + + Args: + x (Variable): A reference Variable used to determine number of timesteps. + speaker_embed (Variable): Shape(B, C), embeddings of speakers, where + B means batch_size, C means speaker embedding size. + tdim (int, optional): The idex of time dimension in x. Defaults to -1, + which means the last dimension is time dimension. + + Returns: + Variable: Shape(B, C, 1, T), the expanded speaker embeddings, where + T = x.shape[tdim]. T means number of timesteps. + + """ + + speaker_embed = fluid.layers.reshape( + speaker_embed, shape=speaker_embed.shape + [1, 1]) + time_steps = x.shape[tdim] + speaker_embed_bc1t = fluid.layers.expand( + speaker_embed, expand_times=[1, 1, 1, time_steps]) + return speaker_embed_bc1t + + +def gen_mask2(valid_lengths, max_len, dtype="float32"): + """ + Generate a mask tensor from valid lengths. note that it return a *reverse* + mask. Indices within valid lengths correspond to 0, and those within + padding area correspond to 1. + + Assume that valid_lengths = [2,5,7], and max_len = 7, the generated mask is + [[0, 0, 1, 1, 1, 1, 1], + [0, 0, 0, 0, 0, 1, 1], + [0, 0, 0, 0, 0, 0, 0]]. + + Args: + valid_lengths (Variable): Shape(B), dtype: int64. A 1D-Tensor containing + the valid lengths (timesteps) of each example, where B means + beatch_size. + max_len (int): The length (number of timesteps) of the mask. + dtype (str, optional): A string that specifies the data type of the + returned mask. + + Returns: + mask (Variable): A mask computed from valid lengths. + """ + batch_size = valid_lengths.shape[0] + mask = fluid.layers.sequence_mask( + valid_lengths, maxlen=max_len, dtype=dtype) + mask = 1 - mask + return mask + + +def expand_mask(mask, attn): + """ + Expand a mask for multiple time steps. This function is used + by the AttentionLayer in the Decoder to expand a mask for every + timestep in the decoder. + + Args: + mask (Variable): Shape(B, T_enc), a mask generated with valid + text lengths, where T_enc means encoder length(time steps). + attn (Variable): Shape(B, T_dec, T_enc), a Variable stands for + the alignment tensor between encoder and decoder, where + T_dec means the decoder length(time_steps). + + Returns: + mask_btc (Variable): shape(B, T_dec, T_enc), the expanded mask. + """ + decoder_length = attn.shape[1] + mask = fluid.layers.reshape(mask, [mask.shape[0], 1, mask.shape[1]]) + mask_btc = fluid.layers.expand(mask, expand_times=[1, decoder_length, 1]) + return mask_btc + + +class Encoder(dg.Layer): + def __init__(self, + name_scope, + n_vocab, + embed_dim, + n_speakers, + speaker_dim, + padding_idx=None, + embedding_weight_std=0.1, + convolutions=(ConvSpec(64, 5, 1)) * 7, + max_positions=512, + dropout=0.1, + dtype="float32"): + super(Encoder, self).__init__(name_scope, dtype=dtype) + + self.dropout = dropout + self.embedding_weight_std = embedding_weight_std + + self.embed = Embedding( + self.full_name(), + n_vocab, + embed_dim, + padding_idx=padding_idx, + std=embedding_weight_std, + dtype=dtype) + + if n_speakers > 1: + self.sp_proj1 = Conv1D( + self.full_name(), + speaker_dim, + embed_dim, + filter_size=1, + std_mul=1.0, + dropout=dropout, + act="softsign", + dtype=dtype) + self.sp_proj2 = Conv1D( + self.full_name(), + speaker_dim, + embed_dim, + filter_size=1, + std_mul=1.0, + dropout=dropout, + act="softsign", + dtype=dtype) + self.n_speakers = n_speakers + + self.convolutions = [] + + in_channels = embed_dim + std_mul = 1.0 + for (out_channels, filter_size, dilation) in convolutions: + # 1 * 1 convolution & relu + if in_channels != out_channels: + self.convolutions.append( + Conv1D( + self.full_name(), + in_channels, + out_channels, + filter_size=1, + std_mul=std_mul, + act="relu", + dtype=dtype)) + in_channels = out_channels + std_mul = 2.0 + + self.convolutions.append( + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + in_channels, + out_channels, + filter_size, + dilation, + std_mul=std_mul, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype)) + in_channels = out_channels + std_mul = 4.0 + + self.convolutions.append( + Conv1D( + self.full_name(), + in_channels, + embed_dim, + filter_size=1, + std_mul=std_mul, + dropout=dropout, + dtype=dtype)) + + for i, layer in enumerate(self.convolutions): + self.add_sublayer("convolution_{}".format(i), layer) + + def forward(self, x, speaker_embed=None): + """ + Encode text sequence. + + Args: + x (Variable): Shape(B, T_enc, 1), dtype: int64. Ihe input text + indices. T_enc means the timesteps of decoder input x. + speaker_embed (Variable, optional): Shape(Batch_size, speaker_dim), + dtype: float32. Speaker embeddings. This arg is not None only + when the model is a multispeaker model. + + Returns: + keys (Variable), Shape(B, C_emb, 1, T_enc), the encoded + representation for keys, where C_emb menas the text embedding + size. + values (Variable), Shape(B, C_embed, 1, T_enc), the encoded + representation for values. + """ + + x = self.embed(x) + + x = fluid.layers.dropout( + x, self.dropout, dropout_implementation="upscale_in_train") + x = fluid.layers.transpose( + fluid.layers.reshape( + x, shape=x.shape + [1]), perm=[0, 2, 3, 1]) + + speaker_embed_bc1t = None + if speaker_embed is not None: + speaker_embed_bc1t = expand_speaker_embed(x, speaker_embed, tdim=3) + + speaker_embed_bc1t = fluid.layers.dropout( + speaker_embed_bc1t, + self.dropout, + dropout_implementation="upscale_in_train") + + x = x + self.sp_proj1(speaker_embed_bc1t) + + input_embed = x + + for layer in self.convolutions: + if isinstance(layer, Conv1DGLU): + x = layer(x, speaker_embed_bc1t) + else: + x = layer(x) + + if speaker_embed is not None: + x = x + self.sp_proj2(speaker_embed_bc1t) + + keys = x + values = fluid.layers.scale(input_embed + x, scale=np.sqrt(0.5)) + + return keys, values + + def freeze_embedding(self): + """Fix text embedding while training.""" + for param in self.embed.parameters(): + param.trainable = False + + +class AttentionLayer(dg.Layer): + def __init__(self, + name_scope, + conv_channels, + embed_dim, + dropout=0.0, + window_range=WindowRange(-1, 3), + key_projection=True, + value_projection=True, + dtype="float32"): + super(AttentionLayer, self).__init__(name_scope, dtype=dtype) + self.query_proj = Conv1D( + self.full_name(), + conv_channels, + embed_dim, + filter_size=1, + dtype=dtype) + + if key_projection: + self.key_proj = Conv1D( + self.full_name(), + embed_dim, + embed_dim, + filter_size=1, + dtype=dtype) + + if value_projection: + self.value_proj = Conv1D( + self.full_name(), + embed_dim, + embed_dim, + filter_size=1, + dtype=dtype) + + self.out_proj = Conv1D( + self.full_name(), + embed_dim, + conv_channels, + filter_size=1, + dtype=dtype) + + self.key_projection = key_projection + self.value_projection = value_projection + self.dropout = dropout + self.window_range = window_range + + def forward(self, query, encoder_out, mask=None, last_attended=None): + """ + Compute pooled context representation and alignment scores. + + Args: + query (Variable): shape(B, C_q, 1, T_dec), the query tensor, + where C_q means the channel of query. + encoder_out (Tuple(Variable, Variable)): + keys (Variable): shape(B, C_emb, 1, T_enc), the key + representation from an encoder, where C_emb means + text embedding size. + values (Variable): shape(B, C_emb, 1, T_enc), the value + representation from an encoder, where C_emb means + text embedding size. + mask (Variable, optional): Shape(B, T_enc), mask generated with + valid text lengths. + last_attended (int, optional): The position that received most + attention at last timestep. This is only used at decoding. + + Outpus: + x (Variable): Shape(B, C_q, 1, T_dec), the context representation + pooled from attention mechanism. + attn_scores (Variable): shape(B, T_dec, T_enc), the alignment + tensor, where T_dec means the number of decoder time steps and + T_enc means number the number of decoder time steps. + """ + keys, values = encoder_out + residual = query + if self.value_projection: + values = self.value_proj(values) + + if self.key_projection: + keys = self.key_proj(keys) + + x = self.query_proj(query) + + batch_size, conv_channels, _, decoder_length = query.shape + encoder_length = keys.shape[-1] + embed_dim = keys.shape[1] + + x = fluid.layers.matmul( + fluid.layers.reshape( + x, shape=[batch_size, embed_dim, decoder_length]), + fluid.layers.reshape( + keys, shape=[batch_size, embed_dim, encoder_length]), + transpose_x=True) + + mask_value = -1.0e30 + if mask is not None: + mask = expand_mask(mask, x) + neg_inf_mask = fluid.layers.scale(mask, mask_value) + x = x + neg_inf_mask + + # if last_attended is provided, focus only on a window range around it + # to enforce monotonic attention. + if last_attended is not None: + locality_mask = np.ones(shape=x.shape, dtype=np.float32) + backward, ahead = self.window_range + backward = last_attended + backward + ahead = last_attended + ahead + if backward < 0: + backward = 0 + if ahead > x.shape[-1]: + ahead = x.shape[-1] + locality_mask[:, :, backward:ahead] = 0. + + locality_mask = dg.to_variable(locality_mask) + neg_inf_mask = fluid.layers.scale(locality_mask, mask_value) + x = x + neg_inf_mask + + x = fluid.layers.softmax(x) + attn_scores = x + + x = fluid.layers.dropout( + x, self.dropout, dropout_implementation="upscale_in_train") + + x = fluid.layers.matmul( + fluid.layers.reshape( + values, shape=[batch_size, embed_dim, encoder_length]), + x, + transpose_y=True) + + x = fluid.layers.reshape(x, [batch_size, embed_dim, 1, decoder_length]) + + x = fluid.layers.scale(x, + encoder_length * np.sqrt(1.0 / encoder_length)) + + x = self.out_proj(x) + + x = fluid.layers.scale((x + residual), np.sqrt(0.5)) + return x, attn_scores + + +class Decoder(dg.Layer): + def __init__(self, + name_scope, + n_speakers, + speaker_dim, + embed_dim, + mel_dim=80, + r=5, + max_positions=512, + padding_idx=None, + preattention=(ConvSpec(128, 5, 1)) * 4, + convolutions=(ConvSpec(128, 5, 1)) * 4, + attention=True, + dropout=0.1, + use_memory_mask=False, + force_monotonic_attention=False, + query_position_rate=1.0, + key_position_rate=1.29, + window_range=WindowRange(-1, 3), + key_projection=True, + value_projection=True, + dtype="float32"): + super(Decoder, self).__init__(name_scope, dtype=dtype) + + self.dropout = dropout + self.mel_dim = mel_dim + self.r = r + self.query_position_rate = query_position_rate + self.key_position_rate = key_position_rate + self.window_range = window_range + self.n_speakers = n_speakers + + conv_channels = convolutions[0].out_channels + self.embed_query_positions = PositionEmbedding( + self.full_name(), + max_positions, + conv_channels, + padding_idx=padding_idx, + dtype=dtype) + self.embed_keys_positions = PositionEmbedding( + self.full_name(), + max_positions, + embed_dim, + padding_idx=padding_idx, + dtype=dtype) + + # Used to compute multiplier for position rate + if n_speakers > 1: + self.speaker_proj1 = FC(self.full_name(), + speaker_dim, + 1, + act="sigmoid", + dropout=dropout, + dtype=dtype) + self.speaker_proj2 = FC(self.full_name(), + speaker_dim, + 1, + act="sigmoid", + dropout=dropout, + dtype=dtype) + + # prenet + self.prenet = [] + in_channels = mel_dim * r + std_mul = 1.0 + for (out_channels, filter_size, dilation) in preattention: + if in_channels != out_channels: + # conv1d & relu + self.prenet.append( + Conv1D( + self.full_name(), + in_channels, + out_channels, + filter_size=1, + std_mul=std_mul, + act="relu")) + in_channels = out_channels + std_mul = 2.0 + self.prenet.append( + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + in_channels, + out_channels, + filter_size, + dilation, + std_mul=std_mul, + dropout=dropout, + causal=True, + residual=True, + dtype=dtype)) + in_channels = out_channels + std_mul = 4.0 + for i, layer in enumerate(self.prenet): + self.add_sublayer("prenet_{}".format(i), layer) + + self.use_memory_mask = use_memory_mask + if isinstance(attention, bool): + self.attention = [attention] * len(convolutions) + else: + self.attention = attention + + if isinstance(force_monotonic_attention, bool): + self.force_monotonic_attention = [force_monotonic_attention + ] * len(convolutions) + else: + self.force_monotonic_attention = force_monotonic_attention + + # causual convolution & attention + self.conv_attn = [] + for use_attention, (out_channels, filter_size, + dilation) in zip(self.attention, convolutions): + assert ( + in_channels == out_channels + ), "the stack of convolution & attention does not change channels" + conv_layer = Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + in_channels, + out_channels, + filter_size, + dilation, + std_mul=std_mul, + dropout=dropout, + causal=True, + residual=False, + dtype=dtype) + attn_layer = (AttentionLayer( + self.full_name(), + out_channels, + embed_dim, + dropout=dropout, + window_range=window_range, + key_projection=key_projection, + value_projection=value_projection, + dtype=dtype) if use_attention else None) + in_channels = out_channels + std_mul = 4.0 + self.conv_attn.append((conv_layer, attn_layer)) + for i, (conv_layer, attn_layer) in enumerate(self.conv_attn): + self.add_sublayer("conv_{}".format(i), conv_layer) + if attn_layer is not None: + self.add_sublayer("attn_{}".format(i), attn_layer) + + # 1 * 1 conv to transform channels + self.last_conv = Conv1D( + self.full_name(), + in_channels, + mel_dim * r, + filter_size=1, + std_mul=std_mul, + dropout=dropout, + dtype=dtype) + + # mel (before sigmoid) to done hat + self.fc = Conv1D( + self.full_name(), mel_dim * r, 1, filter_size=1, dtype=dtype) + + # decoding configs + self.max_decoder_steps = 200 + self.min_decoder_steps = 10 + + def freeze_positional_encoding(self): + for param in self.embed_query_positions.parameters(): + param.trainable = False + for param in self.embed_keys_positions.parameters(): + param.trainable = False + + def forward(self, + encoder_out, + lengths, + inputs, + text_positions, + frame_positions, + speaker_embed=None): + """ + Compute decoder outputs with ground truth mel spectrogram. + + Args: + encoder_out (Tuple(Variable, Variable)): + keys (Variable): shape(B, C_emb, 1, T_enc), the key + representation from an encoder, where C_emb means + text embedding size. + values (Variable): shape(B, C_emb, 1, T_enc), the value + representation from an encoder, where C_emb means + text embedding size. + lengths (Variable): Shape(batch_size,), dtype: int64, valid lengths + of text inputs for each example. + inputs (Variable): Shape(B, C_mel, 1, T_mel), ground truth + mel-spectrogram, which is used as decoder inputs when training. + text_positions (Variable): Shape(B, T_enc, 1), dtype: int64. + Positions indices for text inputs for the encoder, where + T_enc means the encoder timesteps. + frame_positions (Variable): Shape(B, T_dec // r, 1), dtype: + int64. Positions indices for each decoder time steps. + speaker_embed: shape(batch_size, speaker_dim), speaker embedding, + only used for multispeaker model. + + + Returns: + outputs (Variable): Shape(B, C_mel * r, 1, T_mel // r). Decoder + outputs, where C_mel means the channels of mel-spectrogram, r + means the outputs per decoder step, T_mel means the length(time + steps) of mel spectrogram. Note that, when r > 1, the decoder + outputs r frames of mel spectrogram per step. + alignments (Variable): Shape(N, B, T_mel // r, T_enc), the alignment + tensor between the decoder and the encoder, where N means number + of Attention Layers, T_mel means the length of mel spectrogram, + r means the outputs per decoder step, T_enc means the encoder + time steps. + done (Variable): Shape(B, 1, 1, T_mel // r), probability that the + outputs should stop. + decoder_states (Variable): Shape(B, C_dec, 1, T_mel // r), decoder + hidden states, where C_dec means the channels of decoder states. + """ + + # pack multiple frames if necessary + B, _, _, T = inputs.shape + if self.r > 1 and inputs.shape[1] == self.mel_dim: + if T % self.r != 0: + inputs = fluid.layers.slice( + inputs, axes=[3], starts=[0], ends=[T - T % self.r]) + inputs = fluid.layers.transpose(inputs, [0, 3, 2, 1]) + inputs = fluid.layers.reshape( + inputs, shape=[B, -1, 1, self.mel_dim * self.r]) + inputs = fluid.layers.transpose(inputs, [0, 3, 2, 1]) + assert inputs.shape[3] == T // self.r + + if speaker_embed is not None: + speaker_embed_bc1t = expand_speaker_embed(inputs, speaker_embed) + speaker_embed_bc1t = fluid.layers.dropout( + speaker_embed_bc1t, + self.dropout, + dropout_implementation="upscale_in_train") + else: + speaker_embed_bc1t = None + + keys, values = encoder_out + + if self.use_memory_mask and lengths is not None: + mask = gen_mask2(lengths, keys.shape[-1]) + else: + mask = None + + if text_positions is not None: + w = self.key_position_rate + if self.n_speakers > 1: + w = w * fluid.layers.reshape( + self.speaker_proj1(speaker_embed), [B, -1]) + text_pos_embed = self.embed_keys_positions(text_positions, w) + text_pos_embed = fluid.layers.transpose( + fluid.layers.reshape( + text_pos_embed, shape=text_pos_embed.shape + [1]), + perm=[0, 2, 3, 1]) + keys = keys + text_pos_embed + + if frame_positions is not None: + w = self.query_position_rate + if self.n_speakers > 1: + w = w * fluid.layers.reshape( + self.speaker_proj2(speaker_embed), [B, -1]) + frame_pos_embed = self.embed_query_positions(frame_positions, w) + frame_pos_embed = fluid.layers.transpose( + fluid.layers.reshape( + frame_pos_embed, shape=frame_pos_embed.shape + [1]), + perm=[0, 2, 3, 1]) + else: + frame_pos_embed = None + + x = inputs + x = fluid.layers.dropout( + x, self.dropout, dropout_implementation="upscale_in_train") + + # Prenet + for layer in self.prenet: + x = (layer(x, speaker_embed_bc1t) + if isinstance(layer, Conv1DGLU) else layer(x)) + + # Convolution & Multi-hop Attention + alignments = [] + for conv, attn in self.conv_attn: + residual = x + x = conv(x, speaker_embed_bc1t) + if attn is not None: + if frame_pos_embed is not None: + x = x + frame_pos_embed + x, attn_scores = attn(x, (keys, values), mask) + alignments.append(attn_scores) + x = fluid.layers.scale(residual + x, scale=np.sqrt(0.5)) + + alignments = fluid.layers.stack(alignments) + + decoder_states = x + x = self.last_conv(x) + outputs = fluid.layers.sigmoid(x) + done = fluid.layers.sigmoid(self.fc(x)) + + return outputs, alignments, done, decoder_states + + def decode(self, + encoder_out, + text_positions, + speaker_embed=None, + initial_input=None, + test_inputs=None): + """ + Decode without ground truth mel spectrogram. + + Args: + encoder_out (Tuple(Variable, Variable)): + keys (Variable): shape(B, C_emb, 1, T_enc), the key + representation from an encoder, where C_emb means + text embedding size. + values (Variable): shape(B, C_emb, 1, T_enc), the value + representation from an encoder, where C_emb means + text embedding size. + text_positions (Variable): Shape(B, T_enc, 1), dtype: int64. + Positions indices for text inputs for the encoder, where + T_enc means the encoder timesteps. + + speaker_embed (Variable): Shape(B, C_sp), where C_sp means + speaker embedding size. It is only used for multispeaker model. + initial_input (Variable, optional): Shape(B, C_mel * r, 1, 1). + The input for the first time step of the decoder. If r > 0, + it is a packed r frames of mel spectrograms. + test_inputs (Variable, optional): Shape(B, C_mel, 1, T_test), + where T_test means the time steps of test inputs. This is + only used for testing this method, the user should just leave + it None. + + Returns: + outputs (Variable): Shape(B, C_mel * r, 1, T_mel // r). Decoder + outputs, where C_mel means the channels of mel-spectrogram, r + means the outputs per decoder step, T_mel means the length(time + steps) of output mel spectrogram. Note that, when r > 1, + the decoder outputs r frames of mel spectrogram per step. + alignments (Variable): Shape(B, T_mel // r, T_enc), the alignment + tensor between the decoder and the encoder, T_mel means the + length of output mel spectrogram, r means the outputs per + decoder step, T_enc means the encoder time steps. + done (Variable): Shape(B, 1, 1, T_mel // r), probability that the + outputs stops. + decoder_states (Variable): Shape(B, C_dec, 1, T_mel // r), decoder + hidden states, where C_dec means the channels of decoder states. + """ + self.start_new_sequence() + keys, values = encoder_out + B = keys.shape[0] + assert B == 1, "now only supports single instance inference" + mask = None # no mask because we use single instance decoding + + w = self.key_position_rate + if speaker_embed is not None: + if self.n_speakers > 1: + w = w * fluid.layers.reshape( + self.speaker_proj1(speaker_embed), shape=[B, -1]) + speaker_embed_bc11 = fluid.layers.reshape( + speaker_embed, shape=[B, speaker_embed.shape[1], 1, 1]) + else: + speaker_embed_bc11 = None + + if text_positions is not None: + text_pos_embed = self.embed_keys_positions(text_positions, w) + text_pos_embed = fluid.layers.transpose( + fluid.layers.reshape( + text_pos_embed, shape=text_pos_embed.shape + [1]), + perm=[0, 2, 3, 1]) + keys = keys + text_pos_embed + + # start decoding, init accumulators + decoder_states = [] + outputs = [] + alignments = [] + dones = [] + + last_attended = [None] * len(self.conv_attn) + for idx, monotonic_attn in enumerate(self.force_monotonic_attention): + if monotonic_attn: + last_attended[idx] = 0 + + t = 0 # decoder time step + if initial_input is None: + initial_input = fluid.layers.zeros( + shape=[B, self.mel_dim * self.r, 1, 1], dtype=keys.dtype) + current_input = initial_input + + while True: + frame_pos = fluid.layers.fill_constant( + shape=[B, 1, 1], value=t + 1, dtype="int64") + w = self.query_position_rate + if self.n_speakers > 1: + w = w * fluid.layers.reshape( + self.speaker_proj2(speaker_embed), shape=[B, -1]) + frame_pos_embed = self.embed_query_positions(frame_pos, w) + frame_pos_embed = fluid.layers.transpose( + fluid.layers.reshape( + frame_pos_embed, shape=frame_pos_embed.shape + [1]), + perm=[0, 2, 3, 1]) + + if test_inputs is not None: + if t >= test_inputs.shape[3]: + break + current_input = fluid.layers.reshape( + test_inputs[:, :, :, t], + shape=[B, test_inputs.shape[1], 1, 1]) + else: + if t > 0: + current_input = outputs[-1] + + x = current_input + x = fluid.layers.dropout( + x, self.dropout, dropout_implementation="upscale_in_train") + + # Prenet + for layer in self.prenet: + x = (layer.add_input(x, speaker_embed_bc11) + if isinstance(layer, Conv1DGLU) else layer.add_input(x)) + + step_attn_scores = [] + # Casual convolutions + Multi-hop attentions + for i, (conv, attn) in enumerate(self.conv_attn): + residual = x + x = conv.add_input(x, speaker_embed_bc11) + if attn is not None: + if frame_pos_embed is not None: + x = x + frame_pos_embed + x, attn_scores = attn(x, (keys, values), mask, + last_attended[i]) + step_attn_scores.append(attn_scores) + + # update last attended when necessary + if self.force_monotonic_attention[i]: + last_attended[i] = np.argmax( + attn_scores.numpy(), axis=-1)[0][0] + x = fluid.layers.scale(residual + x, scale=np.sqrt(0.5)) + if len(step_attn_scores): + average_attn_scores = fluid.layers.reduce_mean( + fluid.layers.stack(step_attn_scores), dim=0) + else: + average_attn_scores = None + + decoder_state = x + x = self.last_conv.add_input(x) + + output = fluid.layers.sigmoid(x) # (B, r * C_mel, 1, 1) + done = fluid.layers.sigmoid(self.fc(x)) # (B, 1, 1, 1) + + decoder_states.append(decoder_state) + outputs.append(output) + if average_attn_scores is not None: + alignments.append(average_attn_scores) + dones.append(done) + + t += 1 + + if test_inputs is None: + if (fluid.layers.reduce_min(done).numpy()[0] > 0.5 and + t > self.min_decoder_steps): + break + elif t > self.max_decoder_steps: + break + + outputs = fluid.layers.concat(outputs, axis=3) + if len(alignments): + alignments = fluid.layers.concat(alignments, axis=1) + else: + alignments = None + dones = fluid.layers.concat(dones, axis=3) + decoder_states = fluid.layers.concat(decoder_states, axis=3) + + return outputs, alignments, dones, decoder_states + + def start_new_sequence(self): + for layer in self.sublayers(): + if isinstance(layer, conv.Conv1D): + layer.start_new_sequence() + + +class Converter(dg.Layer): + """ + Vocoder that transforms mel spectrogram (or ecoder hidden states) + to waveform. + """ + + def __init__(self, + name_scope, + n_speakers, + speaker_dim, + in_channels, + linear_dim, + convolutions=(ConvSpec(256, 5, 1)) * 4, + time_upsampling=1, + dropout=0.1, + dtype="float32"): + super(Converter, self).__init__(name_scope, dtype=dtype) + + self.n_speakers = n_speakers + self.speaker_dim = speaker_dim + self.in_channels = in_channels + self.linear_dim = linear_dim + self.time_upsampling = time_upsampling + self.dropout = dropout + + target_channels = convolutions[0][0] + + # conv proj to target channels + self.first_conv_proj = Conv1D( + self.full_name(), + in_channels, + target_channels, + filter_size=1, + std_mul=1.0, + dtype=dtype) + + # Idea from nyanko + # upsampling convolitions + if time_upsampling == 4: + self.upsampling_convolutions = [ + Conv1DTranspose( + self.full_name(), + target_channels, + target_channels, + filter_size=2, + padding=0, + stride=2, + std_mul=1.0, + dtype=dtype), + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + target_channels, + target_channels, + filter_size=3, + dilation=1, + std_mul=1.0, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype), + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + target_channels, + target_channels, + filter_size=3, + dilation=3, + std_mul=4.0, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype), + Conv1DTranspose( + self.full_name(), + target_channels, + target_channels, + filter_size=2, + padding=0, + stride=2, + std_mul=4.0, + dtype=dtype), + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + target_channels, + target_channels, + filter_size=3, + dilation=1, + std_mul=1.0, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype), + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + target_channels, + target_channels, + filter_size=3, + dilation=3, + std_mul=4.0, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype), + ] + + elif time_upsampling == 2: + self.upsampling_convolutions = [ + Conv1DTranspose( + self.full_name(), + target_channels, + target_channels, + filter_size=2, + padding=0, + stride=2, + std_mul=1.0, + dtype=dtype), + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + target_channels, + target_channels, + filter_size=3, + dilation=1, + std_mul=1.0, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype), + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + target_channels, + target_channels, + filter_size=3, + dilation=3, + std_mul=4.0, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype), + ] + elif time_upsampling == 1: + self.upsampling_convolutions = [ + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + target_channels, + target_channels, + filter_size=3, + dilation=3, + std_mul=4.0, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype) + ] + else: + raise ValueError("Not supported.") + + for i, layer in enumerate(self.upsampling_convolutions): + self.add_sublayer("upsampling_convolutions_{}".format(i), layer) + + # post conv layers + std_mul = 4.0 + in_channels = target_channels + self.convolutions = [] + for (out_channels, filter_size, dilation) in convolutions: + if in_channels != out_channels: + self.convolutions.append( + Conv1D( + self.full_name(), + in_channels, + out_channels, + filter_size=1, + std_mul=std_mul, + act="relu", + dtype=dtype)) + in_channels = out_channels + std_mul = 2.0 + self.convolutions.append( + Conv1DGLU( + self.full_name(), + n_speakers, + speaker_dim, + in_channels, + out_channels, + filter_size=filter_size, + dilation=dilation, + std_mul=std_mul, + dropout=dropout, + causal=False, + residual=True, + dtype=dtype)) + in_channels = out_channels + std_mul = 4.0 + + for i, layer in enumerate(self.convolutions): + self.add_sublayer("convolutions_{}".format(i), layer) + + # final conv proj, channel transformed to linear dim + self.last_conv_proj = Conv1D( + self.full_name(), + in_channels, + linear_dim, + filter_size=1, + std_mul=std_mul, + dropout=dropout, + act="sigmoid", + dtype=dtype) + + def forward(self, x, speaker_embed=None): + """ + Convert mel spectrogram or decoder hidden states to linear spectrogram. + + Args: + x (Variable): Shape(B, C_in, 1, T_mel), converter inputs, where + C_in means the input channel for the converter. Note that it + can be either C_mel (channel of mel spectrogram) or C_dec // r. + When use mel_spectrogram as the input of converter, C_in = + C_mel; and when use decoder states as the input of converter, + C_in = C_dec // r. In this scenario, decoder hidden states are + treated as if they were r outputs per decoder step and are + unpacked before passing to the converter. + speaker_embed (Variable, optional): shape(B, C_sp), speaker + embedding, where C_sp means the speaker embedding size. + + Returns: + out (Variable): Shape(B, C_lin, 1, T_lin), the output linear + spectrogram, where C_lin means the channel of linear + spectrogram and T_linear means the length(time steps) of linear + spectrogram. T_line = time_upsampling * T_mel, which depends + on the time_upsampling converter. + """ + speaker_embed_bc1t = None + if speaker_embed is not None: + speaker_embed_bc1t = expand_speaker_embed(x, speaker_embed, tdim=-1) + speaker_embed_bc1t = fluid.layers.dropout( + speaker_embed_bc1t, + self.dropout, + dropout_implementation="upscale_in_train") + + x = self.first_conv_proj(x) + + for layer in chain(self.upsampling_convolutions, self.convolutions): + # time_steps may change when timt_upsampling > 1 + if (speaker_embed_bc1t is not None and + speaker_embed_bc1t.shape[3] != x.shape[3]): + speaker_embed_bc1t = expand_speaker_embed( + x, speaker_embed, tdim=3) + speaker_embed_bc1t = fluid.layers.dropout( + speaker_embed_bc1t, + self.dropout, + dropout_implementation="upscale_in_train") + x = (layer(x, speaker_embed_bc1t) + if isinstance(layer, Conv1DGLU) else layer(x)) + + out = self.last_conv_proj(x) + return out + + +class DeepVoiceTTS(dg.Layer): + def __init__(self, name_scope, n_speakers, speaker_dim, + speaker_embedding_weight_std, n_vocab, embed_dim, + text_padding_idx, text_embedding_weight_std, + freeze_text_embedding, encoder_convolutions, max_positions, + position_padding_idx, trainable_positional_encodings, mel_dim, + r, prenet_convolutions, attentive_convolutions, attention, + use_memory_mask, force_monotonic_attention, + query_position_rate, key_position_rate, window_range, + key_projection, value_projection, linear_dim, + postnet_convolutions, time_upsampling, dropout, + use_decoder_state_for_postnet_input, dtype): + super(DeepVoiceTTS, self).__init__(name_scope, dtype) + + self.n_speakers = n_speakers + self.speaker_dim = speaker_dim + if n_speakers > 1: + self.speaker_embedding = Embedding( + self.full_name(), + n_speakers, + speaker_dim, + padding_idx=None, + std=speaker_embedding_weight_std, + dtype=dtype) + + self.embed_dim = embed_dim + self.mel_dim = mel_dim + self.r = r + + self.seq2seq = ConvS2S( + self.full_name(), n_speakers, speaker_dim, + speaker_embedding_weight_std, n_vocab, embed_dim, text_padding_idx, + text_embedding_weight_std, freeze_text_embedding, + encoder_convolutions, max_positions, position_padding_idx, + trainable_positional_encodings, mel_dim, r, prenet_convolutions, + attentive_convolutions, attention, use_memory_mask, + force_monotonic_attention, query_position_rate, key_position_rate, + window_range, key_projection, value_projection, dropout, dtype) + + self.use_decoder_state_for_postnet_input = use_decoder_state_for_postnet_input + if use_decoder_state_for_postnet_input: + assert ( + attentive_convolutions[-1].out_channels % self.r == 0 + ), "when using decoder states as converter input, you must assure the decoder state channels can be divided by r" + converter_input_channels = attentive_convolutions[ + -1].out_channels // r + else: + converter_input_channels = mel_dim + + self.converter_input_channels = converter_input_channels + self.linear_dim = linear_dim + self.converter = Converter( + self.full_name(), + n_speakers, + speaker_dim, + converter_input_channels, + linear_dim, + convolutions=postnet_convolutions, + time_upsampling=time_upsampling, + dropout=dropout, + dtype=dtype) + + def forward(self, + text_sequences, + valid_lengths, + mel_inputs, + speaker_indices=None, + text_positions=None, + frame_positions=None): + """ + Encode text sequence and decode with ground truth mel spectrogram. + + Args: + text_sequences (Variable): Shape(B, T_enc, 1), dtype: int64. Ihe + input text indices. T_enc means the timesteps of text_sequences. + valid_lengths (Variable): shape(batch_size,), dtype: int64, + valid lengths for each example in text_sequences. + mel_inputs (Variable): Shape(B, C_mel, 1, T_mel), ground truth + mel-spectrogram, which is used as decoder inputs when training. + speaker_indices (Variable, optional): Shape(Batch_size, 1), + dtype: int64. Speaker index for each example. This arg is not + None only when the model is a multispeaker model. + text_positions (Variable): Shape(B, T_enc, 1), dtype: int64. + Positions indices for text inputs for the encoder, where + T_enc means the encoder timesteps. + frame_positions (Variable): Shape(B, T_dec // r, 1), dtype: + int64. Positions indices for each decoder time steps. + + Returns: + mel_outputs (Variable): Shape(B, C_mel * r, 1, T_mel // r). Decoder + outputs, where C_mel means the channels of mel-spectrogram, r + means the outputs per decoder step, T_mel means the length(time + steps) of mel spectrogram. Note that, when r > 1, the decoder + outputs r frames of mel spectrogram per step. + linear_outputs (Variable): Shape(B, C_lin, 1, T_lin), the output + linear spectrogram, where C_lin means the channel of linear + spectrogram and T_linear means the length(time steps) of linear + spectrogram. T_line = time_upsampling * T_mel, which depends + on the time_upsampling converter. + alignments (Variable): Shape(N, B, T_mel // r, T_enc), the alignment + tensor between the decoder and the encoder, where N means number + of Attention Layers, T_mel means the length of mel spectrogram, + r means the outputs per decoder step, T_enc means the encoder + time steps. + done (Variable): Shape(B, 1, 1, T_mel // r), probability that the + outputs should stop. + """ + + batch_size = text_sequences.shape[0] + if self.n_speakers == 1: + assert speaker_indices is None, "this model does not support multi-speaker" + + if speaker_indices is not None: + speaker_embed = self.speaker_embedding(speaker_indices) + else: + speaker_embed = None + + mel_outputs, alignments, done, decoder_states = self.seq2seq( + text_sequences, valid_lengths, mel_inputs, speaker_embed, + text_positions, frame_positions) + + # unpack multi frames + if self.r > 1: + mel_outputs = fluid.layers.transpose(mel_outputs, [0, 3, 2, 1]) + mel_outputs = fluid.layers.reshape( + mel_outputs, [batch_size, -1, 1, self.mel_dim]) + mel_outputs = fluid.layers.transpose(mel_outputs, [0, 3, 2, 1]) + + if self.use_decoder_state_for_postnet_input: + postnet_input = fluid.layers.transpose(decoder_states, [0, 3, 2, 1]) + postnet_input = fluid.layers.reshape( + postnet_input, + [batch_size, -1, 1, self.converter_input_channels]) + postnet_input = fluid.layers.transpose(postnet_input, [0, 3, 2, 1]) + else: + postnet_input = mel_outputs + + linear_outputs = self.converter(postnet_input, speaker_embed) + + return mel_outputs, linear_outputs, alignments, done + + def transduce(self, text_sequences, text_positions, speaker_indices=None): + """ + Encode text sequence and decode without ground truth mel spectrogram. + + Args: + text_sequences (Variable): Shape(B, T_enc, 1), dtype: int64. Ihe + input text indices. T_enc means the timesteps of text_sequences. + text_positions (Variable): Shape(B, T_enc, 1), dtype: int64. + Positions indices for text inputs for the encoder, where + T_enc means the encoder timesteps. + speaker_indices (Variable, optional): Shape(Batch_size, 1), + dtype: int64. Speaker index for each example. This arg is not + None only when the model is a multispeaker model. + + Returns: + mel_outputs (Variable): Shape(B, C_mel * r, 1, T_mel // r). Decoder + outputs, where C_mel means the channels of mel-spectrogram, r + means the outputs per decoder step, T_mel means the length(time + steps) of mel spectrogram. Note that, when r > 1, the decoder + outputs r frames of mel spectrogram per step. + linear_outputs (Variable): Shape(B, C_lin, 1, T_lin), the output + linear spectrogram, where C_lin means the channel of linear + spectrogram and T_linear means the length(time steps) of linear + spectrogram. T_line = time_upsampling * T_mel, which depends + on the time_upsampling converter. + alignments (Variable): Shape(B, T_mel // r, T_enc), the alignment + tensor between the decoder and the encoder, T_mel means the + length of mel spectrogram, r means the outputs per decoder + step, T_enc means the encoder time steps. + done (Variable): Shape(B, 1, 1, T_mel // r), probability that the + outputs should stop. + """ + batch_size = text_sequences.shape[0] + + if speaker_indices is not None: + speaker_embed = self.speaker_embedding(speaker_indices) + else: + speaker_embed = None + + mel_outputs, alignments, done, decoder_states = self.seq2seq.transduce( + text_sequences, text_positions, speaker_embed) + + if self.r > 1: + mel_outputs = fluid.layers.transpose(mel_outputs, [0, 3, 2, 1]) + mel_outputs = fluid.layers.reshape( + mel_outputs, [batch_size, -1, 1, self.mel_dim]) + mel_outputs = fluid.layers.transpose(mel_outputs, [0, 3, 2, 1]) + + if self.use_decoder_state_for_postnet_input: + postnet_input = fluid.layers.transpose(decoder_states, [0, 3, 2, 1]) + postnet_input = fluid.layers.reshape( + postnet_input, + [batch_size, -1, 1, self.converter_input_channels]) + postnet_input = fluid.layers.transpose(postnet_input, [0, 3, 2, 1]) + else: + postnet_input = mel_outputs + + linear_outputs = self.converter(postnet_input, speaker_embed) + + return mel_outputs, linear_outputs, alignments, done + + +class ConvS2S(dg.Layer): + def __init__(self, name_scope, n_speakers, speaker_dim, + speaker_embedding_weight_std, n_vocab, embed_dim, + text_padding_idx, text_embedding_weight_std, + freeze_text_embedding, encoder_convolutions, max_positions, + position_padding_idx, trainable_positional_encodings, mel_dim, + r, prenet_convolutions, attentive_convolutions, attention, + use_memory_mask, force_monotonic_attention, + query_position_rate, key_position_rate, window_range, + key_projection, value_projection, dropout, dtype): + super(ConvS2S, self).__init__(name_scope, dtype) + + self.freeze_text_embedding = freeze_text_embedding + self.trainable_positional_encodings = trainable_positional_encodings + + self.n_speakers = n_speakers + self.speaker_dim = speaker_dim + + self.embed_dim = embed_dim + self.encoder = Encoder( + self.full_name(), + n_vocab, + embed_dim, + n_speakers, + speaker_dim, + padding_idx=None, + embedding_weight_std=text_embedding_weight_std, + convolutions=encoder_convolutions, + max_positions=max_positions, + dropout=dropout, + dtype=dtype) + if freeze_text_embedding: + self.encoder.freeze_embedding() + + self.mel_dim = mel_dim + self.r = r + self.decoder = Decoder( + self.full_name(), + n_speakers, + speaker_dim, + embed_dim, + mel_dim, + r, + max_positions, + position_padding_idx, + preattention=prenet_convolutions, + convolutions=attentive_convolutions, + attention=attention, + dropout=dropout, + use_memory_mask=use_memory_mask, + force_monotonic_attention=force_monotonic_attention, + query_position_rate=query_position_rate, + key_position_rate=key_position_rate, + window_range=window_range, + key_projection=key_projection, + value_projection=key_projection, + dtype=dtype) + if not trainable_positional_encodings: + self.decoder.freeze_positional_encoding() + + def forward(self, + text_sequences, + valid_lengths, + mel_inputs, + speaker_embed=None, + text_positions=None, + frame_positions=None): + """ + Encode text sequence and decode with ground truth mel spectrogram. + + Args: + text_sequences (Variable): Shape(B, T_enc, 1), dtype: int64. Ihe + input text indices. T_enc means the timesteps of text_sequences. + valid_lengths (Variable): shape(batch_size,), dtype: int64, + valid lengths for each example in text_sequences. + mel_inputs (Variable): Shape(B, C_mel, 1, T_mel), ground truth + mel-spectrogram, which is used as decoder inputs when training. + speaker_embed (Variable, optional): Shape(Batch_size, speaker_dim), + dtype: float32. Speaker embeddings. This arg is not None only + when the model is a multispeaker model. + text_positions (Variable): Shape(B, T_enc, 1), dtype: int64. + Positions indices for text inputs for the encoder, where + T_enc means the encoder timesteps. + frame_positions (Variable): Shape(B, T_dec // r, 1), dtype: + int64. Positions indices for each decoder time steps. + + Returns: + mel_outputs (Variable): Shape(B, C_mel * r, 1, T_mel // r). Decoder + outputs, where C_mel means the channels of mel-spectrogram, r + means the outputs per decoder step, T_mel means the length(time + steps) of mel spectrogram. Note that, when r > 1, the decoder + outputs r frames of mel spectrogram per step. + alignments (Variable): Shape(N, B, T_mel // r, T_enc), the alignment + tensor between the decoder and the encoder, where N means number + of Attention Layers, T_mel means the length of mel spectrogram, + r means the outputs per decoder step, T_enc means the encoder + time steps. + done (Variable): Shape(B, 1, 1, T_mel // r), probability that the + outputs should stop. + decoder_states (Variable): Shape(B, C_dec, 1, T_mel // r), decoder + hidden states, where C_dec means the channels of decoder states. + """ + keys, values = self.encoder(text_sequences, speaker_embed) + mel_outputs, alignments, done, decoder_states = self.decoder( + (keys, values), valid_lengths, mel_inputs, text_positions, + frame_positions, speaker_embed) + + return mel_outputs, alignments, done, decoder_states + + def transduce(self, text_sequences, text_positions, speaker_embed=None): + """ + Encode text sequence and decode without ground truth mel spectrogram. + + Args: + text_sequences (Variable): Shape(B, T_enc, 1), dtype: int64. Ihe + input text indices. T_enc means the timesteps of text_sequences. + text_positions (Variable): Shape(B, T_enc, 1), dtype: int64. + Positions indices for text inputs for the encoder, where + T_enc means the encoder timesteps. + speaker_embed (Variable, optional): Shape(Batch_size, speaker_dim), + dtype: float32. Speaker embeddings. This arg is not None only + when the model is a multispeaker model. + + Returns: + mel_outputs (Variable): Shape(B, C_mel * r, 1, T_mel // r). Decoder + outputs, where C_mel means the channels of mel-spectrogram, r + means the outputs per decoder step, T_mel means the length(time + steps) of mel spectrogram. Note that, when r > 1, the decoder + outputs r frames of mel spectrogram per step. + alignments (Variable): Shape(B, T_mel // r, T_enc), the alignment + tensor between the decoder and the encoder, T_mel means the + length of mel spectrogram, r means the outputs per decoder + step, T_enc means the encoder time steps. + done (Variable): Shape(B, 1, 1, T_mel // r), probability that the + outputs should stop. + decoder_states (Variable): Shape(B, C_dec, 1, T_mel // r), decoder + hidden states, where C_dec means the channels of decoder states. + """ + keys, values = self.encoder(text_sequences, speaker_embed) + mel_outputs, alignments, done, decoder_states = self.decoder.decode( + (keys, values), text_positions, speaker_embed) + + return mel_outputs, alignments, done, decoder_states diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/dry_run.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/dry_run.py new file mode 100644 index 00000000..9c9518ce --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/dry_run.py @@ -0,0 +1,113 @@ +# Copyright (c) 2019 PaddlePaddle 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. + +import numpy as np +from paddle import fluid +import paddle.fluid.dygraph as dg + +from hparams import hparams, hparams_debug_string +from deepvoice3_paddle import frontend +from deepvoice3_paddle.deepvoice3 import DeepVoiceTTS + + +def dry_run(model): + """ + Run the model once, just to get it initialized. + """ + model.train() + _frontend = getattr(frontend, hparams.frontend) + batch_size = 4 + enc_length = 157 + snd_sample_length = 500 + + r = hparams.outputs_per_step + downsample_step = hparams.downsample_step + n_speakers = hparams.n_speakers + + # make sure snd_sample_length can be divided by r * downsample_step + linear_shift = r * downsample_step + snd_sample_length += linear_shift - snd_sample_length % linear_shift + decoder_length = snd_sample_length // downsample_step // r + mel_length = snd_sample_length // downsample_step + + n_vocab = _frontend.n_vocab + max_pos = hparams.max_positions + spker_embed = hparams.speaker_embed_dim + linear_dim = model.linear_dim + mel_dim = hparams.num_mels + + x = np.random.randint( + low=0, high=n_vocab, size=(batch_size, enc_length, 1), dtype="int64") + input_lengths = np.arange( + enc_length - batch_size + 1, enc_length + 1, dtype="int64") + mel = np.random.randn(batch_size, mel_dim, 1, mel_length).astype("float32") + y = np.random.randn(batch_size, linear_dim, 1, + snd_sample_length).astype("float32") + + text_positions = np.tile( + np.arange( + 0, enc_length, dtype="int64"), (batch_size, 1)) + text_mask = text_positions > np.expand_dims(input_lengths, 1) + text_positions[text_mask] = 0 + text_positions = np.expand_dims(text_positions, axis=-1) + + frame_positions = np.tile( + np.arange( + 1, decoder_length + 1, dtype="int64"), (batch_size, 1)) + frame_positions = np.expand_dims(frame_positions, axis=-1) + + done = np.zeros(shape=(batch_size, 1, 1, decoder_length), dtype="float32") + target_lengths = np.array([snd_sample_length] * batch_size).astype("int64") + + speaker_ids = np.random.randint( + low=0, high=n_speakers, size=(batch_size, 1), + dtype="int64") if n_speakers > 1 else None + + ismultispeaker = speaker_ids is not None + + x = dg.to_variable(x) + input_lengths = dg.to_variable(input_lengths) + mel = dg.to_variable(mel) + y = dg.to_variable(y) + text_positions = dg.to_variable(text_positions) + frame_positions = dg.to_variable(frame_positions) + done = dg.to_variable(done) + target_lengths = dg.to_variable(target_lengths) + speaker_ids = dg.to_variable( + speaker_ids) if speaker_ids is not None else None + + # these two fields are used as numpy ndarray + text_lengths = input_lengths.numpy() + decoder_lengths = target_lengths.numpy() // r // downsample_step + + max_seq_len = max(text_lengths.max(), decoder_lengths.max()) + if max_seq_len >= hparams.max_positions: + raise RuntimeError( + "max_seq_len ({}) >= max_posision ({})\n" + "Input text or decoder targget length exceeded the maximum length.\n" + "Please set a larger value for ``max_position`` in hyper parameters." + .format(max_seq_len, hparams.max_positions)) + + # cause paddle's embedding layer expect shape[-1] == 1 + + # first dry run runs the whole model + mel_outputs, linear_outputs, attn, done_hat = model( + x, input_lengths, mel, speaker_ids, text_positions, frame_positions) + + num_parameters = 0 + for k, v in model.state_dict().items(): + print("{}|{}|{}".format(k, v.shape, np.prod(v.shape))) + num_parameters += np.prod(v.shape) + print("now model has {} parameters".format(len(model.state_dict()))) + print("now model has {} elements".format(num_parameters)) diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/README.md b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/README.md new file mode 100644 index 00000000..af4513e7 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/README.md @@ -0,0 +1 @@ +This package is adapted from https://github.com/r9y9/deepvoice3_pytorch/tree/master/deepvoice3_pytorch/frontend, Copyright (c) 2017: Ryuichi Yamamoto, whose license applies. diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/__init__.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/__init__.py new file mode 100644 index 00000000..49b79e89 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/__init__.py @@ -0,0 +1,33 @@ +# coding: utf-8 +"""Text processing frontend + +All frontend module should have the following functions: + +- text_to_sequence(text, p) +- sequence_to_text(sequence) + +and the property: + +- n_vocab + +""" +from deepvoice3_paddle.frontend import en + +# optinoal Japanese frontend +try: + from deepvoice3_paddle.frontend import jp +except ImportError: + jp = None + +try: + from deepvoice3_paddle.frontend import ko +except ImportError: + ko = None + +# if you are going to use the frontend, you need to modify _characters in +# symbol.py: +# _characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\'(),-.:;? ' + '¡¿ñáéíóúÁÉÍÓÚÑ' +try: + from deepvoice3_paddle.frontend import es +except ImportError: + es = None diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/en/__init__.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/en/__init__.py new file mode 100644 index 00000000..d560ab55 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/en/__init__.py @@ -0,0 +1,35 @@ +# coding: utf-8 +from deepvoice3_paddle.frontend.text.symbols import symbols + +import nltk +from random import random + +n_vocab = len(symbols) + +_arpabet = nltk.corpus.cmudict.dict() + + +def _maybe_get_arpabet(word, p): + try: + phonemes = _arpabet[word][0] + phonemes = " ".join(phonemes) + except KeyError: + return word + + return '{%s}' % phonemes if random() < p else word + + +def mix_pronunciation(text, p): + text = ' '.join(_maybe_get_arpabet(word, p) for word in text.split(' ')) + return text + + +def text_to_sequence(text, p=0.0): + if p >= 0: + text = mix_pronunciation(text, p) + from deepvoice3_paddle.frontend.text import text_to_sequence + text = text_to_sequence(text, ["english_cleaners"]) + return text + + +from deepvoice3_paddle.frontend.text import sequence_to_text diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/es/__init__.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/es/__init__.py new file mode 100644 index 00000000..24323e58 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/es/__init__.py @@ -0,0 +1,16 @@ +# coding: utf-8 +from deepvoice3_paddle.frontend.text.symbols import symbols + +import nltk +from random import random + +n_vocab = len(symbols) + + +def text_to_sequence(text, p=0.0): + from deepvoice3_paddle.frontend.text import text_to_sequence + text = text_to_sequence(text, ["basic_cleaners"]) + return text + + +from deepvoice3_paddle.frontend.text import sequence_to_text diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/jp/__init__.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/jp/__init__.py new file mode 100644 index 00000000..36c7fd84 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/jp/__init__.py @@ -0,0 +1,77 @@ +# coding: utf-8 + +import MeCab +import jaconv +from random import random + +n_vocab = 0xffff + +_eos = 1 +_pad = 0 +_tagger = None + + +def _yomi(mecab_result): + tokens = [] + yomis = [] + for line in mecab_result.split("\n")[:-1]: + s = line.split("\t") + if len(s) == 1: + break + token, rest = s + rest = rest.split(",") + tokens.append(token) + yomi = rest[7] if len(rest) > 7 else None + yomi = None if yomi == "*" else yomi + yomis.append(yomi) + + return tokens, yomis + + +def _mix_pronunciation(tokens, yomis, p): + return "".join(yomis[idx] + if yomis[idx] is not None and random() < p else tokens[idx] + for idx in range(len(tokens))) + + +def mix_pronunciation(text, p): + global _tagger + if _tagger is None: + _tagger = MeCab.Tagger("") + tokens, yomis = _yomi(_tagger.parse(text)) + return _mix_pronunciation(tokens, yomis, p) + + +def add_punctuation(text): + last = text[-1] + if last not in [".", ",", "、", "。", "!", "?", "!", "?"]: + text = text + "。" + return text + + +def normalize_delimitor(text): + text = text.replace(",", "、") + text = text.replace(".", "。") + text = text.replace(",", "、") + text = text.replace(".", "。") + return text + + +def text_to_sequence(text, p=0.0): + for c in [" ", " ", "「", "」", "『", "』", "・", "【", "】", "(", ")", "(", ")"]: + text = text.replace(c, "") + text = text.replace("!", "!") + text = text.replace("?", "?") + + text = normalize_delimitor(text) + text = jaconv.normalize(text) + if p > 0: + text = mix_pronunciation(text, p) + text = jaconv.hira2kata(text) + text = add_punctuation(text) + + return [ord(c) for c in text] + [_eos] # EOS + + +def sequence_to_text(seq): + return "".join(chr(n) for n in seq) diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/ko/__init__.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/ko/__init__.py new file mode 100644 index 00000000..ccb8b5f1 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/ko/__init__.py @@ -0,0 +1,17 @@ +# coding: utf-8 + +from random import random + +n_vocab = 0xffff + +_eos = 1 +_pad = 0 +_tagger = None + + +def text_to_sequence(text, p=0.0): + return [ord(c) for c in text] + [_eos] # EOS + + +def sequence_to_text(seq): + return "".join(chr(n) for n in seq) diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/__init__.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/__init__.py new file mode 100644 index 00000000..5ffe4a2c --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/__init__.py @@ -0,0 +1,74 @@ +import re +from deepvoice3_paddle.frontend.text import cleaners +from deepvoice3_paddle.frontend.text.symbols import symbols + +# Mappings from symbol to numeric ID and vice versa: +_symbol_to_id = {s: i for i, s in enumerate(symbols)} +_id_to_symbol = {i: s for i, s in enumerate(symbols)} + +# Regular expression matching text enclosed in curly braces: +_curly_re = re.compile(r'(.*?)\{(.+?)\}(.*)') + + +def text_to_sequence(text, cleaner_names): + '''Converts a string of text to a sequence of IDs corresponding to the symbols in the text. + + The text can optionally have ARPAbet sequences enclosed in curly braces embedded + in it. For example, "Turn left on {HH AW1 S S T AH0 N} Street." + + Args: + text: string to convert to a sequence + cleaner_names: names of the cleaner functions to run the text through + + Returns: + List of integers corresponding to the symbols in the text + ''' + sequence = [] + + # Check for curly braces and treat their contents as ARPAbet: + while len(text): + m = _curly_re.match(text) + if not m: + sequence += _symbols_to_sequence(_clean_text(text, cleaner_names)) + break + sequence += _symbols_to_sequence(_clean_text(m.group(1), cleaner_names)) + sequence += _arpabet_to_sequence(m.group(2)) + text = m.group(3) + + # Append EOS token + sequence.append(_symbol_to_id['~']) + return sequence + + +def sequence_to_text(sequence): + '''Converts a sequence of IDs back to a string''' + result = '' + for symbol_id in sequence: + if symbol_id in _id_to_symbol: + s = _id_to_symbol[symbol_id] + # Enclose ARPAbet back in curly braces: + if len(s) > 1 and s[0] == '@': + s = '{%s}' % s[1:] + result += s + return result.replace('}{', ' ') + + +def _clean_text(text, cleaner_names): + for name in cleaner_names: + cleaner = getattr(cleaners, name) + if not cleaner: + raise Exception('Unknown cleaner: %s' % name) + text = cleaner(text) + return text + + +def _symbols_to_sequence(symbols): + return [_symbol_to_id[s] for s in symbols if _should_keep_symbol(s)] + + +def _arpabet_to_sequence(text): + return _symbols_to_sequence(['@' + s for s in text.split()]) + + +def _should_keep_symbol(s): + return s in _symbol_to_id and s is not '_' and s is not '~' diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cleaners.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cleaners.py new file mode 100644 index 00000000..e9422647 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cleaners.py @@ -0,0 +1,104 @@ +''' +Cleaners are transformations that run over the input text at both training and +eval time. + +Cleaners can be selected by passing a comma-delimited list of cleaner names as +the "cleaners" hyperparameter. Some cleaners are English-specific. You'll +typically want to use: + 1. "english_cleaners" for English text + 2. "transliteration_cleaners" for non-English text that can be transliterated + to ASCII using the Unidecode library (https://pypi.python.org/pypi/Unidecode) + 3. "basic_cleaners" if you do not want to transliterate (in this case, you + should also update the symbols in symbols.py to match your data). +''' + +import re +from unidecode import unidecode +from .numbers import normalize_numbers + +# 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 add_punctuation(text): + if len(text) == 0: + return text + if text[-1] not in '!,.:;?': + text = text + '.' # without this decoder is confused when to output EOS + return 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 = add_punctuation(text) + text = lowercase(text) + text = expand_numbers(text) + text = expand_abbreviations(text) + text = collapse_whitespace(text) + return text diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cmudict.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cmudict.py new file mode 100644 index 00000000..304592b6 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/cmudict.py @@ -0,0 +1,67 @@ +import re + +valid_symbols = [ + 'AA', 'AA0', 'AA1', 'AA2', 'AE', 'AE0', 'AE1', 'AE2', 'AH', 'AH0', 'AH1', + 'AH2', 'AO', 'AO0', 'AO1', 'AO2', 'AW', 'AW0', 'AW1', 'AW2', 'AY', 'AY0', + 'AY1', 'AY2', 'B', 'CH', 'D', 'DH', 'EH', 'EH0', 'EH1', 'EH2', 'ER', 'ER0', + 'ER1', 'ER2', 'EY', 'EY0', 'EY1', 'EY2', 'F', 'G', 'HH', 'IH', 'IH0', 'IH1', + 'IH2', 'IY', 'IY0', 'IY1', 'IY2', 'JH', 'K', 'L', 'M', 'N', 'NG', 'OW', + 'OW0', 'OW1', 'OW2', 'OY', 'OY0', 'OY1', 'OY2', 'P', 'R', 'S', 'SH', 'T', + 'TH', 'UH', 'UH0', 'UH1', 'UH2', 'UW', 'UW0', 'UW1', 'UW2', 'V', 'W', 'Y', + 'Z', 'ZH' +] + +_valid_symbol_set = set(valid_symbols) + + +class CMUDict: + ''' + Thin wrapper around CMUDict data. + http://www.speech.cs.cmu.edu/cgi-bin/cmudict + ''' + + def __init__(self, file_or_path, keep_ambiguous=True): + if isinstance(file_or_path, str): + with open(file_or_path, encoding='latin-1') as f: + entries = _parse_cmudict(f) + else: + entries = _parse_cmudict(file_or_path) + if not keep_ambiguous: + entries = { + word: pron + for word, pron in entries.items() if len(pron) == 1 + } + self._entries = entries + + def __len__(self): + return len(self._entries) + + def lookup(self, word): + '''Returns list of ARPAbet pronunciations of the given word.''' + return self._entries.get(word.upper()) + + +_alt_re = re.compile(r'\([0-9]+\)') + + +def _parse_cmudict(file): + cmudict = {} + for line in file: + if len(line) and (line[0] >= 'A' and line[0] <= 'Z' or line[0] == "'"): + parts = line.split(' ') + word = re.sub(_alt_re, '', parts[0]) + pronunciation = _get_pronunciation(parts[1]) + if pronunciation: + if word in cmudict: + cmudict[word].append(pronunciation) + else: + cmudict[word] = [pronunciation] + return cmudict + + +def _get_pronunciation(s): + parts = s.strip().split(' ') + for part in parts: + if part not in _valid_symbol_set: + return None + return ' '.join(parts) diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/numbers.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/numbers.py new file mode 100644 index 00000000..24b58175 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/numbers.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +import inflect +import re + +_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 diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/symbols.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/symbols.py new file mode 100644 index 00000000..c6fc28bc --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/frontend/text/symbols.py @@ -0,0 +1,18 @@ +''' +Defines the set of symbols used in text input to the model. + +The default is a set of ASCII characters that works well for English or text +that has been run through Unidecode. For other data, you can modify _characters. +See TRAINING_DATA.md for details. +''' +from .cmudict import valid_symbols + +_pad = '_' +_eos = '~' +_characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\'(),-.:;? ' + +# Prepend "@" to ARPAbet symbols to ensure uniqueness (some are the same as uppercase letters): +_arpabet = ['@' + s for s in valid_symbols] + +# Export all symbols: +symbols = [_pad, _eos] + list(_characters) + _arpabet diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/loss.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/loss.py new file mode 100644 index 00000000..96bcd3ba --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/loss.py @@ -0,0 +1,158 @@ +# Copyright (c) 2019 PaddlePaddle 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 __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +from numba import jit + +from paddle import fluid +import paddle.fluid.dygraph as dg + + +def masked_mean(inputs, mask): + """ + Args: + inputs (Variable): Shape(B, C, 1, T), the input, where B means + batch size, C means channels of input, T means timesteps of + the input. + mask (Variable): Shape(B, T), a mask. + Returns: + loss (Variable): Shape(1, ), masked mean. + """ + channels = inputs.shape[1] + reshaped_mask = fluid.layers.reshape( + mask, shape=[mask.shape[0], 1, 1, mask.shape[-1]]) + expanded_mask = fluid.layers.expand( + reshaped_mask, expand_times=[1, channels, 1, 1]) + expanded_mask.stop_gradient = True + + valid_cnt = fluid.layers.reduce_sum(expanded_mask) + valid_cnt.stop_gradient = True + + masked_inputs = inputs * expanded_mask + loss = fluid.layers.reduce_sum(masked_inputs) / valid_cnt + return loss + + +@jit(nopython=True) +def guided_attention(N, max_N, T, max_T, g): + W = np.zeros((max_N, max_T), dtype=np.float32) + for n in range(N): + for t in range(T): + W[n, t] = 1 - np.exp(-(n / N - t / T)**2 / (2 * g * g)) + return W + + +def guided_attentions(input_lengths, target_lengths, max_target_len, g=0.2): + B = len(input_lengths) + max_input_len = input_lengths.max() + W = np.zeros((B, max_target_len, max_input_len), dtype=np.float32) + for b in range(B): + W[b] = guided_attention(input_lengths[b], max_input_len, + target_lengths[b], max_target_len, g).T + return W + + +class TTSLoss(object): + def __init__(self, + masked_weight=0.0, + priority_weight=0.0, + binary_divergence_weight=0.0, + guided_attention_sigma=0.2): + self.masked_weight = masked_weight + self.priority_weight = priority_weight + self.binary_divergence_weight = binary_divergence_weight + self.guided_attention_sigma = guided_attention_sigma + + def l1_loss(self, prediction, target, mask, priority_bin=None): + abs_diff = fluid.layers.abs(prediction - target) + + # basic mask-weighted l1 loss + w = self.masked_weight + if w > 0 and mask is not None: + base_l1_loss = w * masked_mean(abs_diff, mask) + ( + 1 - w) * fluid.layers.reduce_mean(abs_diff) + else: + base_l1_loss = fluid.layers.reduce_mean(abs_diff) + + if self.priority_weight > 0 and priority_bin is not None: + # mask-weighted priority channels' l1-loss + priority_abs_diff = fluid.layers.slice( + abs_diff, axes=[1], starts=[0], ends=[priority_bin]) + if w > 0 and mask is not None: + priority_loss = w * masked_mean(priority_abs_diff, mask) + ( + 1 - w) * fluid.layers.reduce_mean(priority_abs_diff) + else: + priority_loss = fluid.layers.reduce_mean(priority_abs_diff) + + # priority weighted sum + p = self.priority_weight + loss = p * priority_loss + (1 - p) * base_l1_loss + else: + loss = base_l1_loss + return loss + + def binary_divergence(self, prediction, target, mask): + flattened_prediction = fluid.layers.reshape(prediction, [-1, 1]) + flattened_target = fluid.layers.reshape(target, [-1, 1]) + flattened_loss = fluid.layers.log_loss( + flattened_prediction, flattened_target, epsilon=1e-8) + bin_div = fluid.layers.reshape(flattened_loss, prediction.shape) + + w = self.masked_weight + if w > 0 and mask is not None: + loss = w * masked_mean(bin_div, mask) + ( + 1 - w) * fluid.layers.reduce_mean(bin_div) + else: + loss = fluid.layers.reduce_mean(bin_div) + return loss + + @staticmethod + def done_loss(done_hat, done): + flat_done_hat = fluid.layers.reshape(done_hat, [-1, 1]) + flat_done = fluid.layers.reshape(done, [-1, 1]) + loss = fluid.layers.log_loss(flat_done_hat, flat_done, epsilon=1e-8) + loss = fluid.layers.reduce_mean(loss) + return loss + + def attention_loss(self, predicted_attention, input_lengths, + target_lengths): + """ + Given valid encoder_lengths and decoder_lengths, compute a diagonal + guide, and compute loss from the predicted attention and the guide. + + Args: + predicted_attention (Variable): Shape(*, B, T_dec, T_enc), the + alignment tensor, where B means batch size, T_dec means number + of time steps of the decoder, T_enc means the number of time + steps of the encoder, * means other possible dimensions. + input_lengths (numpy.ndarray): Shape(B,), dtype:int64, valid lengths + (time steps) of encoder outputs. + target_lengths (numpy.ndarray): Shape(batch_size,), dtype:int64, + valid lengths (time steps) of decoder outputs. + + Returns: + loss (Variable): Shape(1, ) attention loss. + """ + n_attention, batch_size, max_target_len, max_input_len = ( + predicted_attention.shape) + soft_mask = guided_attentions(input_lengths, target_lengths, + max_target_len, + self.guided_attention_sigma) + soft_mask_ = dg.to_variable(soft_mask) + loss = fluid.layers.reduce_mean(predicted_attention * soft_mask_) + return loss diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/modules.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/modules.py new file mode 100644 index 00000000..0df3ef10 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/modules.py @@ -0,0 +1,458 @@ +# Copyright (c) 2019 PaddlePaddle 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. + +import paddle +from paddle import fluid +import paddle.fluid.dygraph as dg + +import numpy as np + +import deepvoice3_paddle.conv as conv +import deepvoice3_paddle.weight_norm as weight_norm + + +def FC(name_scope, + in_features, + size, + num_flatten_dims=1, + dropout=0.0, + epsilon=1e-30, + act=None, + is_test=False, + dtype="float32"): + """ + A special Linear Layer, when it is used with dropout, the weight is + initialized as normal(0, std=np.sqrt((1-dropout) / in_features)) + """ + + # stds + if isinstance(in_features, int): + in_features = [in_features] + stds = [np.sqrt((1 - dropout) / in_feature) for in_feature in in_features] + weight_inits = [ + fluid.initializer.NormalInitializer(scale=std) for std in stds + ] + bias_init = fluid.initializer.ConstantInitializer(0.0) + + # param attrs + weight_attrs = [fluid.ParamAttr(initializer=init) for init in weight_inits] + bias_attr = fluid.ParamAttr(initializer=bias_init) + + layer = weight_norm.FC(name_scope, + size, + num_flatten_dims=num_flatten_dims, + param_attr=weight_attrs, + bias_attr=bias_attr, + act=act, + dtype=dtype) + return layer + + +def Conv1D(name_scope, + in_channels, + num_filters, + filter_size=3, + dilation=1, + groups=None, + causal=False, + std_mul=1.0, + dropout=0.0, + use_cudnn=True, + act=None, + dtype="float32"): + """ + A special Conv1D Layer, when it is used with dropout, the weight is + initialized as + normal(0, std=np.sqrt(std_mul * (1-dropout) / (filter_size * in_features))) + """ + # std + std = np.sqrt((std_mul * (1 - dropout)) / (filter_size * in_channels)) + weight_init = fluid.initializer.NormalInitializer(loc=0.0, scale=std) + bias_init = fluid.initializer.ConstantInitializer(0.0) + + # param attrs + weight_attr = fluid.ParamAttr(initializer=weight_init) + bias_attr = fluid.ParamAttr(initializer=bias_init) + + layer = conv.Conv1D( + name_scope, + in_channels, + num_filters, + filter_size, + dilation, + groups=groups, + causal=causal, + param_attr=weight_attr, + bias_attr=bias_attr, + use_cudnn=use_cudnn, + act=act, + dtype=dtype) + return layer + + +def Embedding(name_scope, + num_embeddings, + embed_dim, + is_sparse=False, + is_distributed=False, + padding_idx=None, + std=0.01, + dtype="float32"): + # param attrs + weight_attr = fluid.ParamAttr(initializer=fluid.initializer.Normal( + scale=std)) + layer = dg.Embedding( + name_scope, (num_embeddings, embed_dim), + padding_idx=padding_idx, + param_attr=weight_attr, + dtype=dtype) + return layer + + +class Conv1DGLU(dg.Layer): + """ + A Convolution 1D block with GLU activation. It also applys dropout for the + input x. It fuses speaker embeddings through a FC activated by softsign. It + has residual connection from the input x, and scale the output by + np.sqrt(0.5). + """ + + def __init__(self, + name_scope, + n_speakers, + speaker_dim, + in_channels, + num_filters, + filter_size, + dilation, + std_mul=4.0, + dropout=0.0, + causal=False, + residual=True, + dtype="float32"): + super(Conv1DGLU, self).__init__(name_scope, dtype=dtype) + + # conv spec + self.in_channels = in_channels + self.n_speakers = n_speakers + self.speaker_dim = speaker_dim + self.num_filters = num_filters + self.filter_size = filter_size + self.dilation = dilation + self.causal = causal + self.residual = residual + + # weight init and dropout + self.std_mul = std_mul + self.dropout = dropout + + if residual: + assert ( + in_channels == num_filters + ), "this block uses residual connection"\ + "the input_channes should equals num_filters" + + self.conv = Conv1D( + self.full_name(), + in_channels, + 2 * num_filters, + filter_size, + dilation, + causal=causal, + std_mul=std_mul, + dropout=dropout, + dtype=dtype) + + if n_speakers > 1: + assert (speaker_dim is not None + ), "speaker embed should not be null in multi-speaker case" + self.fc = Conv1D( + self.full_name(), + speaker_dim, + num_filters, + filter_size=1, + dilation=1, + causal=False, + act="softsign", + dtype=dtype) + + def forward(self, x, speaker_embed_bc1t=None): + """ + Args: + x (Variable): Shape(B, C_in, 1, T), the input of Conv1DGLU + layer, where B means batch_size, C_in means the input channels + T means input time steps. + speaker_embed_bct1 (Variable): Shape(B, C_sp, 1, T), expanded + speaker embed, where C_sp means speaker embedding size. Note + that when using residual connection, the Conv1DGLU does not + change the number of channels, so out channels equals input + channels. + + Returns: + x (Variable): Shape(B, C_out, 1, T), the output of Conv1DGLU, where + C_out means the output channels of Conv1DGLU. + """ + + residual = x + x = fluid.layers.dropout( + x, self.dropout, dropout_implementation="upscale_in_train") + x = self.conv(x) + + content, gate = fluid.layers.split(x, num_or_sections=2, dim=1) + + if speaker_embed_bc1t is not None: + sp = self.fc(speaker_embed_bc1t) + content = content + sp + + # glu + x = fluid.layers.elementwise_mul(fluid.layers.sigmoid(gate), content) + + if self.residual: + x = fluid.layers.scale(x + residual, np.sqrt(0.5)) + return x + + def add_input(self, x, speaker_embed_bc11=None): + """ + Inputs: + x: shape(B, num_filters, 1, time_steps) + speaker_embed_bc11: shape(B, speaker_dim, 1, time_steps) + + Outputs: + out: shape(B, num_filters, 1, time_steps), where time_steps = 1 + """ + + residual = x + + # add step input and produce step output + x = fluid.layers.dropout( + x, self.dropout, dropout_implementation="upscale_in_train") + x = self.conv.add_input(x) + + content, gate = fluid.layers.split(x, num_or_sections=2, dim=1) + + if speaker_embed_bc11 is not None: + sp = self.fc(speaker_embed_bc11) + content = content + sp + + x = fluid.layers.elementwise_mul(fluid.layers.sigmoid(gate), content) + + if self.residual: + x = fluid.layers.scale(x + residual, np.sqrt(0.5)) + return x + + +def Conv1DTranspose(name_scope, + in_channels, + num_filters, + filter_size, + padding=0, + stride=1, + dilation=1, + groups=None, + std_mul=1.0, + dropout=0.0, + use_cudnn=True, + act=None, + dtype="float32"): + std = np.sqrt(std_mul * (1 - dropout) / (in_channels * filter_size)) + weight_init = fluid.initializer.NormalInitializer(scale=std) + weight_attr = fluid.ParamAttr(initializer=weight_init) + bias_init = fluid.initializer.ConstantInitializer(0.0) + bias_attr = fluid.ParamAttr(initializer=bias_init) + layer = conv.Conv1DTranspose( + name_scope, + in_channels, + num_filters, + filter_size, + padding=padding, + stride=stride, + dilation=dilation, + groups=groups, + param_attr=weight_attr, + bias_attr=bias_attr, + use_cudnn=use_cudnn, + act=act, + dtype=dtype) + return layer + + +def compute_position_embedding(rad): + # rad is a transposed radius, shape(embed_dim, n_vocab) + embed_dim, n_vocab = rad.shape + + even_dims = dg.to_variable(np.arange(0, embed_dim, 2).astype("int32")) + odd_dims = dg.to_variable(np.arange(1, embed_dim, 2).astype("int32")) + + even_rads = fluid.layers.gather(rad, even_dims) + odd_rads = fluid.layers.gather(rad, odd_dims) + + sines = fluid.layers.sin(even_rads) + cosines = fluid.layers.cos(odd_rads) + + temp = fluid.layers.scatter(rad, even_dims, sines) + out = fluid.layers.scatter(temp, odd_dims, cosines) + out = fluid.layers.transpose(out, perm=[1, 0]) + return out + + +def position_encoding_init(n_position, + d_pos_vec, + position_rate=1.0, + sinusoidal=True): + """ Init the sinusoid position encoding table """ + + # keep idx 0 for padding token position encoding zero vector + position_enc = np.array([[ + position_rate * pos / np.power(10000, 2 * (i // 2) / d_pos_vec) + for i in range(d_pos_vec) + ] if pos != 0 else np.zeros(d_pos_vec) for pos in range(n_position)]) + + if sinusoidal: + position_enc[1:, 0::2] = np.sin(position_enc[1:, 0::2]) # dim 2i + position_enc[1:, 1::2] = np.cos(position_enc[1:, 1::2]) # dim 2i+1 + + return position_enc + + +class PositionEmbedding(dg.Layer): + def __init__(self, + name_scope, + n_position, + d_pos_vec, + position_rate=1.0, + is_sparse=False, + is_distributed=False, + param_attr=None, + max_norm=None, + padding_idx=None, + dtype="float32"): + super(PositionEmbedding, self).__init__(name_scope, dtype=dtype) + self.embed = dg.Embedding( + self.full_name(), + size=(n_position, d_pos_vec), + is_sparse=is_sparse, + is_distributed=is_distributed, + padding_idx=None, + param_attr=param_attr, + dtype=dtype) + self.set_weight( + position_encoding_init( + n_position, + d_pos_vec, + position_rate=position_rate, + sinusoidal=False).astype(dtype)) + + self._is_sparse = is_sparse + self._is_distributed = is_distributed + self._remote_prefetch = self._is_sparse and (not self._is_distributed) + if self._remote_prefetch: + assert self._is_sparse is True and self._is_distributed is False + + self._padding_idx = (-1 if padding_idx is None else padding_idx if + padding_idx >= 0 else (n_position + padding_idx)) + self._position_rate = position_rate + self._max_norm = max_norm + self._dtype = dtype + + def set_weight(self, array): + assert self.embed._w.shape == list(array.shape), "shape does not match" + self.embed._w._ivar.value().get_tensor().set( + array, fluid.framework._current_expected_place()) + + def forward(self, indices, speaker_position_rate=None): + """ + Args: + indices (Variable): Shape (B, T, 1), dtype: int64, position + indices, where B means the batch size, T means the time steps. + speaker_position_rate (Variable | float, optional), position + rate. It can be a float point number or a Variable with + shape (1,), then this speaker_position_rate is used for every + example. It can also be a Variable with shape (B, 1), which + contains a speaker position rate for each speaker. + Returns: + out (Variable): Shape(B, C_pos), position embedding, where C_pos + means position embedding size. + """ + rad = fluid.layers.transpose(self.embed._w, perm=[1, 0]) + batch_size = indices.shape[0] + + if speaker_position_rate is None: + weight = compute_position_embedding(rad) + out = self._helper.create_variable_for_type_inference(self._dtype) + self._helper.append_op( + type="lookup_table", + inputs={"Ids": indices, + "W": weight}, + outputs={"Out": out}, + attrs={ + "is_sparse": self._is_sparse, + "is_distributed": self._is_distributed, + "remote_prefetch": self._remote_prefetch, + "padding_idx": + self._padding_idx, # special value for lookup table op + }) + return out + + elif (np.isscalar(speaker_position_rate) or + isinstance(speaker_position_rate, fluid.framework.Variable) and + speaker_position_rate.shape == [1, 1]): + # # make a weight + # scale the weight (the operand for sin & cos) + if np.isscalar(speaker_position_rate): + scaled_rad = fluid.layers.scale(rad, speaker_position_rate) + else: + scaled_rad = fluid.layers.elementwise_mul( + rad, speaker_position_rate[0]) + weight = compute_position_embedding(scaled_rad) + out = self._helper.create_variable_for_type_inference(self._dtype) + self._helper.append_op( + type="lookup_table", + inputs={"Ids": indices, + "W": weight}, + outputs={"Out": out}, + attrs={ + "is_sparse": self._is_sparse, + "is_distributed": self._is_distributed, + "remote_prefetch": self._remote_prefetch, + "padding_idx": + self._padding_idx, # special value for lookup table op + }) + return out + + elif np.prod(speaker_position_rate.shape) > 1: + assert speaker_position_rate.shape == [batch_size, 1] + outputs = [] + for i in range(batch_size): + rate = speaker_position_rate[i] # rate has shape [1] + scaled_rad = fluid.layers.elementwise_mul(rad, rate) + weight = compute_position_embedding(scaled_rad) + out = self._helper.create_variable_for_type_inference( + self._dtype) + sequence = indices[i] + self._helper.append_op( + type="lookup_table", + inputs={"Ids": sequence, + "W": weight}, + outputs={"Out": out}, + attrs={ + "is_sparse": self._is_sparse, + "is_distributed": self._is_distributed, + "remote_prefetch": self._remote_prefetch, + "padding_idx": -1, + }) + outputs.append(out) + out = fluid.layers.stack(outputs) + return out + else: + raise Exception("Then you can just use position rate at init") diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/save_load.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/save_load.py new file mode 100644 index 00000000..bb5203cb --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/save_load.py @@ -0,0 +1,78 @@ +# Copyright (c) 2019 PaddlePaddle 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 __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import os +from os.path import dirname, join + +import paddle +from paddle import fluid +import paddle.fluid.dygraph as dg + + +def _load(checkpoint_path): + """ + Load saved state dict and optimizer state(optional). + """ + state_dict, optimizer_state = dg.load_persistables(dirname=checkpoint_path) + return state_dict, optimizer_state + + +def load_checkpoint(path, model, optimizer=None, reset_optimizer=True): + """ + layers like FC, Conv*, ... the Layer does not initialize their parameters + before first run. + + 1. if you want to load only a part of a saved whole model, to part of an + existing model, just pass the part as the target model , and path of the + saved whole model as source path. + 2. if you want to load exactly from what is saved, just passed the model + and path as expected. + + The rule of thumb is: + 1. loading to a model works with name, a unique global name. + 2. loading from a directory works with file structure, each parameter is + saved in a file. Loading a file from directory A/ would `create` a + corresponding Variable for each saved parameter, whose name is the file's + relative path from directory A/. + """ + print("Load checkpoint from: {}".format(path)) + state_dict, optimizer_state = _load(path) + + model.load_dict(state_dict) + if not reset_optimizer and optimizer is not None: + if optimizer_state is not None: + print("[loading] Load optimizer state from {}".format(path)) + optimizer.load(optimizer_state) + + return model + + +def _load_embedding(path, model): + print("[loading] Loading embedding from {}".format(path)) + state_dict, optimizer_state = _load(path) + key = os.path.join(model.full_name(), "ConvS2S_0/Encoder_0/Embedding_0.w_0") + tensor = model.state_dict()[key]._ivar.value().get_tensor() + tensor.set(state_dict[key], fluid.framework._current_expected_place()) + + +def save_checkpoint(model, optimizer, checkpoint_dir, global_step): + checkpoint_path = join(checkpoint_dir, + "checkpoint_step{:09d}.model".format(global_step)) + dg.save_persistables( + model.state_dict(), dirname=checkpoint_path, optimizers=optimizer) + print("[checkpoint] Saved checkpoint:", checkpoint_path) diff --git a/PaddleSpeech/DeepVoice3/deepvoice3_paddle/weight_norm.py b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/weight_norm.py new file mode 100644 index 00000000..cbb0d03f --- /dev/null +++ b/PaddleSpeech/DeepVoice3/deepvoice3_paddle/weight_norm.py @@ -0,0 +1,863 @@ +# Copyright (c) 2019 PaddlePaddle 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. + +import math +import numpy as np +from six.moves import reduce + +from copy import deepcopy + +import paddle +from paddle import fluid +import paddle.fluid.dygraph as dg +from paddle.fluid import core +from paddle.fluid.layers import utils +from paddle.fluid.framework import Variable +from paddle.fluid.initializer import Normal, Constant, NumpyArrayInitializer + + +def _norm(p, dim): + """Computes the norm over all dimensions except dim. + It differs from pytorch implementation that it does not keep dim. + This difference is related with the broadcast mechanism in paddle. + Read elementeise_mul for more. + """ + + if dim is None: + return np.linalg.norm(p, ord=2, axis=None) + elif dim == 0: + p = np.reshape(p, newshape=(p.shape[0], -1)) + return np.linalg.norm(p, ord=2, axis=1) + elif dim == p.ndim - 1: + p = np.reshape(p, newshape=(-1, p.shape[-1])) + return np.linalg.norm(p, ord=2, axis=0) + else: + perm = list(range(p.ndim)) + perm[0] = dim + perm[dim] = 0 + return _norm(np.transpose(p, axes=perm)) + + +class FC(dg.Layer): + """ + **Fully Connected Layer** + + This function creates a fully connected layer in the network. It can take + one or multiple tensors as its inputs(input can be a list of Variable, see + Args in detail). It creates a pair of variables called (magnitude(g), + direction(V)) for each input tensor. Elementwise_mul(V, g) represents a fully connected + weight matrix from each input unit to each output unit. + The fully connected layer multiplies each input tensor + with its corresponding weight to produce an output Tensor with shape [M, `size`], + where M is batch size. If multiple input tensors are given, the results of + multiple output tensors with shape [M, `size`] will be summed up. If bias_attr + is not None, a bias variable will be created and added to the output. + Finally, if activation is not None, it will be applied to the output as well. + + When the input is single tensor: + + .. math:: + + Out = Act({X(normalize(V)g) + b}) + + When the input are multiple tensors: + + .. math:: + + Out = Act({\sum_{i=0}^{N-1}X_i(V_ig_i) + b}) + + In the above equation: + + * :math:`N`: Number of the input. N equals to len(input) if input is list of Variable. + * :math:`X_i`: The i-th input tensor. + * :math:`V_i`: The i-th direction matrix corresponding i-th input tensor. + * :math:`g_i`: The i-th magnitude vector corresponding i-th input tensor. + * :math:`b`: The bias parameter created by this layer (if needed). + * :math:`Act`: The activation function. + * :math:`Out`: The output tensor. + + See below for an example. + + .. code-block:: text + + Given: + data_1.data = [[[0.1, 0.2], + [0.3, 0.4]]] + data_1.shape = (1, 2, 2) # 1 is batch_size + + data_2 = [[[0.1, 0.2, 0.3]]] + data_2.shape = (1, 1, 3) + + out = fluid.layers.fc(input=[data_1, data_2], size=2) + + Then: + out.data = [[0.18669507, 0.1893476]] + out.shape = (1, 2) + + Args: + name_scope(str): The name of this class. + size(int): The number of output units in this layer. + num_flatten_dims (int): The fc layer can accept an input tensor with more than + two dimensions. If this happens, the multidimensional tensor will first be flattened + into a 2-dimensional matrix. The parameter `num_flatten_dims` determines how the input + tensor is flattened: the first `num_flatten_dims` (inclusive, index starts from 1) + dimensions will be flatten to form the first dimension of the final matrix (height of + the matrix), and the rest `rank(X) - num_flatten_dims` dimensions are flattened to + form the second dimension of the final matrix (width of the matrix). For example, suppose + `X` is a 5-dimensional tensor with a shape [2, 3, 4, 5, 6], and `num_flatten_dims` = 3. + Then, the flattened matrix will have a shape [2 x 3 x 4, 5 x 6] = [24, 30]. Default: 1 + param_attr (ParamAttr|list of ParamAttr|None): The parameter attribute for learnable + parameters/weights of this layer. + bias_attr (ParamAttr|list of ParamAttr, default None): The parameter attribute for the bias + of this layer. If it is set to False, no bias will be added to the output units. + If it is set to None, the bias is initialized zero. Default: None. + act (str|None): Activation to be applied to the output of this layer. + is_test(bool): A flag indicating whether execution is in test phase. Default: False + dtype(str): Dtype used for weight + + Raises: + ValueError: If rank of the input tensor is less than 2. + + Examples: + .. code-block:: python + + from paddle.fluid.dygraph.base import to_variable + import paddle.fluid as fluid + from paddle.fluid.dygraph import FC + import numpy as np + + data = np.random.uniform( -1, 1, [30, 10, 32] ).astype('float32') + with fluid.dygraph.guard(): + fc = FC( "fc", 64, num_flatten_dims=2) + data = to_variable( data ) + conv = fc( data ) + + """ + + def __init__(self, + name_scope, + size, + num_flatten_dims=1, + epsilon=1e-30, + param_attr=None, + bias_attr=None, + act=None, + is_test=False, + dtype="float32"): + super(FC, self).__init__(name_scope, dtype) + + self._size = size + self._num_flatten_dims = num_flatten_dims + self._epsilon = epsilon + self._dtype = dtype + self._param_attr = param_attr + self._bias_attr = bias_attr + self._act = act + self.__g = list() + self.__v = list() + + @property + def _v(self, i=0): + return self.__v[i] + + @property + def _g(self, i=0): + return self.__g[i] + + @_v.setter + def _v(self, value, i=0): + assert isinstance(value, Parameter) + self.__v[i] = value + + @_g.setter + def _g(self, value, i=0): + assert isinstance(value, Parameter) + self.__g[i] = value + + def _build_once(self, input): + i = 0 + for inp, param in self._helper.iter_inputs_and_params(input, + self._param_attr): + input_shape = inp.shape + + param_shape = [ + reduce(lambda a, b: a * b, input_shape[self._num_flatten_dims:], + 1) + ] + [self._size] + self.__v.append( + self.add_parameter( + "_v%d" % i, + self.create_parameter( + attr=param, + shape=param_shape, + dtype=self._dtype, + is_bias=False))) + + magnitude_shape = param_shape[1:] + magnitude_value = np.linalg.norm(self.__v[i].numpy(), ord=2, axis=0) + + self.__g.append( + self.add_parameter( + "_g%d" % i, + self.create_parameter( + attr=fluid.ParamAttr( + initializer=fluid.initializer.NumpyArrayInitializer( + magnitude_value)), + shape=magnitude_shape, + dtype=self._dtype, + is_bias=False))) + i += 1 + + size = list([self._size]) + self._b = self.create_parameter( + attr=self._bias_attr, shape=size, dtype=self._dtype, is_bias=True) + + def forward(self, input): + mul_results = list() + i = 0 + for inp, param in self._helper.iter_inputs_and_params(input, + self._param_attr): + v_norm = self._helper.create_variable_for_type_inference( + self._dtype) + v_normalized = self._helper.create_variable_for_type_inference( + self._dtype) + self._helper.append_op( + type="norm", + inputs={"X": self.__v[i]}, + outputs={"Out": v_normalized, + "Norm": v_norm}, + attrs={"axis": 0, + "epsilon": self._epsilon}) + weight = self._helper.create_variable_for_type_inference( + self._dtype) + self._helper.append_op( + type="elementwise_mul", + inputs={"X": [v_normalized], + "Y": [self.__g[i]]}, + outputs={"Out": [weight]}, + attrs={"axis": 1}) + tmp = self._helper.create_variable_for_type_inference(self._dtype) + self._helper.append_op( + type="mul", + inputs={"X": inp, + "Y": weight}, + outputs={"Out": tmp}, + attrs={ + "x_num_col_dims": self._num_flatten_dims, + "y_num_col_dims": 1 + }) + i += 1 + mul_results.append(tmp) + + if len(mul_results) == 1: + pre_bias = mul_results[0] + else: + pre_bias = self._helper.create_variable_for_type_inference( + self._dtype) + self._helper.append_op( + type="sum", + inputs={"X": mul_results}, + outputs={"Out": pre_bias}, + attrs={"use_mkldnn": False}) + + if self._b: + pre_activation = self._helper.create_variable_for_type_inference( + dtype=self._dtype) + self._helper.append_op( + type="elementwise_add", + inputs={"X": [pre_bias], + "Y": [self._b]}, + outputs={"Out": [pre_activation]}, + attrs={"axis": self._num_flatten_dims}) + else: + pre_activation = pre_bias + # Currently, we don't support inplace in dygraph mode + return self._helper.append_activation(pre_activation, act=self._act) + + +class Conv2D(dg.Layer): + """ + The convolution2D layer calculates the output based on the input, filter + and strides, paddings, dilations, groups parameters. Input and + Output are in NCHW format, where N is batch size, C is the number of + channels, H is the height of the feature, and W is the width of the feature. + Filter is in MCHW format, where M is the number of output image channels, + C is the number of input image channels, H is the height of the filter, + and W is the width of the filter. If the groups is greater than 1, + C will equal the number of input image channels divided by the groups. + Please refer to UFLDL's `convolution + ` + for more detials. + If bias attribution and activation type are provided, bias is added to the + output of the convolution, and the corresponding activation function is + applied to the final result. + + For each input :math:`X`, the equation is: + + .. math:: + + Out = \sigma ((Vg) \\ast X + b) + + Where: + + * :math:`X`: Input value, a tensor with NCHW format. + * :math:`V`: Filter direction value, a tensor with MCHW format. + * :math:`g`: Filter magnitude value, a tensor with M format. + * :math:`\\ast`: Convolution operation. + * :math:`b`: Bias value, a 2-D tensor with shape [M, 1]. + * :math:`\\sigma`: Activation function. + * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different. + + Example: + + - Input: + + Input shape: :math:`(N, C_{in}, H_{in}, W_{in})` + + Filter shape: :math:`(C_{out}, C_{in}, H_f, W_f)` + + - Output: + + Output shape: :math:`(N, C_{out}, H_{out}, W_{out})` + + Where + + .. math:: + + H_{out}&= \\frac{(H_{in} + 2 * paddings[0] - (dilations[0] * (H_f - 1) + 1))}{strides[0]} + 1 \\\\ + W_{out}&= \\frac{(W_{in} + 2 * paddings[1] - (dilations[1] * (W_f - 1) + 1))}{strides[1]} + 1 + + Args: + name_scope(str) : The name for this class. + num_filters(int): The number of filter. It is as same as the output + image channel. + filter_size (int|tuple|None): The filter size. If filter_size is a tuple, + it must contain two integers, (filter_size_H, filter_size_W). + Otherwise, the filter will be a square. + stride (int|tuple): The stride size. If stride is a tuple, it must + contain two integers, (stride_H, stride_W). Otherwise, the + stride_H = stride_W = stride. Default: stride = 1. + padding (int|tuple): The padding size. If padding is a tuple, it must + contain two integers, (padding_H, padding_W). Otherwise, the + padding_H = padding_W = padding. Default: padding = 0. + dilation (int|tuple): The dilation size. If dilation is a tuple, it must + contain two integers, (dilation_H, dilation_W). Otherwise, the + dilation_H = dilation_W = dilation. Default: dilation = 1. + groups (int): The groups number of the Conv2d Layer. According to grouped + convolution in Alex Krizhevsky's Deep CNN paper: when group=2, + the first half of the filters is only connected to the first half + of the input channels, while the second half of the filters is only + connected to the second half of the input channels. Default: groups=1. + param_attr (ParamAttr|None): The parameter attribute for learnable parameters/weights + of conv2d. If it is set to None or one attribute of ParamAttr, conv2d + will create ParamAttr as param_attr. If the Initializer of the param_attr + is not set, the parameter is initialized with :math:`Normal(0.0, std)`, + and the :math:`std` is :math:`(\\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None. + bias_attr (ParamAttr|bool|None): The parameter attribute for the bias of conv2d. + If it is set to False, no bias will be added to the output units. + If it is set to None or one attribute of ParamAttr, conv2d + will create ParamAttr as bias_attr. If the Initializer of the bias_attr + is not set, the bias is initialized zero. Default: None. + use_cudnn (bool): Use cudnn kernel or not, it is valid only when the cudnn + library is installed. Default: True + act (str): Activation type, if it is set to None, activation is not appended. + Default: None + + Raises: + ValueError: If the shapes of input, filter_size, stride, padding and + groups mismatch. + + Examples: + .. code-block:: python + + from paddle.fluid.dygraph.base import to_variable + import paddle.fluid as fluid + from paddle.fluid.dygraph import Conv2D + import numpy as np + + data = np.random.uniform( -1, 1, [10, 3, 32, 32] ).astype('float32') + with fluid.dygraph.guard(): + conv2d = Conv2D( "conv2d", 2, 3) + data = to_variable( data ) + conv = conv2d( data ) + + """ + + def __init__(self, + name_scope, + num_filters, + filter_size, + stride=1, + padding=0, + dilation=1, + groups=None, + param_attr=None, + bias_attr=None, + use_cudnn=True, + act=None, + epsilon=1e-30, + dtype="float32"): + assert param_attr is not False, "param_attr should not be False here." + super(Conv2D, self).__init__(name_scope, dtype) + self._groups = groups + self._stride = utils.convert_to_list(stride, 2, "stride") + self._padding = utils.convert_to_list(padding, 2, "padding") + self._dilation = utils.convert_to_list(dilation, 2, "dilation") + self._act = act + if not isinstance(use_cudnn, bool): + raise ValueError("use_cudnn should be True or False") + self._use_cudnn = use_cudnn + self._filter_size = filter_size + self._num_filters = num_filters + self._param_attr = param_attr + self._bias_attr = bias_attr + self._epsilon = epsilon + self._dtype = dtype + # if (self._num_channels == self._groups and + # num_filters % self._num_channels == 0 and not self._use_cudnn): + # self._l_type = 'depthwise_conv2d' + # else: + # TODO(jiabin): recover the usage of depthwise_conv2d when it's + # kernel fixed https://github.com/PaddlePaddle/Paddle/issues/17275 + self._l_type = "conv2d" + + def _build_once(self, input): + self._num_channels = input.shape[1] + if self._groups is None: + num_filter_channels = self._num_channels + else: + if self._num_channels % self._groups != 0: + raise ValueError("num_channels must be divisible by groups.") + num_filter_channels = self._num_channels // self._groups + filter_size = utils.convert_to_list(self._filter_size, 2, "filter_size") + filter_shape = [self._num_filters, int(num_filter_channels) + ] + filter_size + + def _get_default_param_initializer(): + filter_elem_num = filter_size[0] * filter_size[ + 1] * self._num_channels + std = (2.0 / filter_elem_num)**0.5 + return Normal(0.0, std, 0) + + # weight_v + self._filter_param_v = self.create_parameter( + attr=self._param_attr, + shape=filter_shape, + dtype=self._dtype, + default_initializer=_get_default_param_initializer()) + + # weight_g + norm_value = _norm( + self._filter_param_v.numpy(), dim=0) # CAUTION: hard-code + self._filter_param_g = self.create_parameter( + attr=fluid.ParamAttr( + initializer=fluid.initializer.NumpyArrayInitializer( + norm_value)), + shape=norm_value.shape, + dtype=self._dtype, + default_initializer=_get_default_param_initializer()) + + if self._use_cudnn: + self.create_variable( + name="kCUDNNFwdAlgoCache", + persistable=True, + type=core.VarDesc.VarType.RAW) + self.create_variable( + name="kCUDNNBwdDataAlgoCache", + persistable=True, + type=core.VarDesc.VarType.RAW) + self.create_variable( + name="kCUDNNBwdFilterAlgoCache", + persistable=True, + type=core.VarDesc.VarType.RAW) + + self._bias_param = self.create_parameter( + attr=self._bias_attr, + shape=[self._num_filters], + dtype=self._dtype, + is_bias=True) + + def forward(self, input): + matrix = self._helper.create_variable_for_type_inference(self._dtype) + tmp = self._helper.create_variable_for_type_inference(self._dtype) + new_shape = [ + self._filter_param_v.shape[0], + reduce(lambda x, y: x * y, self._filter_param_v.shape[1:], 1), + ] + + self._helper.append_op( + type="reshape2", + inputs={"X": self._filter_param_v}, + attrs={"shape": new_shape}, + outputs={"Out": matrix, + "XShape": tmp}) + + m_norm = self._helper.create_variable_for_type_inference(self._dtype) + m_normalized = self._helper.create_variable_for_type_inference( + self._dtype) + self._helper.append_op( + type="norm", + inputs={"X": matrix}, + outputs={"Out": m_normalized, + "Norm": m_norm}, + attrs={"axis": 1, + "epsilon": self._epsilon}) + + v_normalized = self._helper.create_variable_for_type_inference( + self._dtype) + tmp2 = self._helper.create_variable_for_type_inference(self._dtype) + self._helper.append_op( + type="reshape2", + inputs={"X": m_normalized}, + attrs={"shape": self._filter_param_v.shape}, + outputs={"Out": v_normalized, + "XShape": tmp2}) + + filter_param = self._helper.create_variable_for_type_inference( + self._dtype) + self._helper.append_op( + type="elementwise_mul", + inputs={"X": [v_normalized], + "Y": [self._filter_param_g]}, + outputs={"Out": [filter_param]}, + attrs={"axis": 0}, # CAUTION: hard-code + ) + + pre_bias = self._helper.create_variable_for_type_inference( + dtype=self._dtype) + + self._helper.append_op( + type=self._l_type, + inputs={"Input": input, + "Filter": filter_param}, + outputs={"Output": pre_bias}, + attrs={ + "strides": self._stride, + "paddings": self._padding, + "dilations": self._dilation, + "groups": self._groups if self._groups else 1, + "use_cudnn": self._use_cudnn, + "use_mkldnn": False, + }) + + if self._bias_param is not None: + pre_act = self._helper.create_variable_for_type_inference( + dtype=self._dtype) + self._helper.append_op( + type="elementwise_add", + inputs={"X": [pre_bias], + "Y": [self._bias_param]}, + outputs={"Out": [pre_act]}, + attrs={"axis": 1}) + else: + pre_act = pre_bias + + # Currently, we don't support inplace in dygraph mode + return self._helper.append_activation(pre_act, act=self._act) + + +class Conv2DTranspose(dg.Layer): + """ + **Convlution2D transpose layer** + + The convolution2D transpose layer calculates the output based on the input, + filter, and dilations, strides, paddings. Input(Input) and output(Output) + are in NCHW format. Where N is batch size, C is the number of channels, + H is the height of the feature, and W is the width of the feature. + Parameters(dilations, strides, paddings) are two elements. These two elements + represent height and width, respectively. The details of convolution transpose + layer, please refer to the following explanation and references + `therein `_. + If bias attribution and activation type are provided, bias is added to + the output of the convolution, and the corresponding activation function + is applied to the final result. + + For each input :math:`X`, the equation is: + + .. math:: + + Out = \sigma ((Vg) \\ast X + b) + + Where: + + * :math:`X`: Input value, a tensor with NCHW format. + * :math:`V`: Filter value, a tensor with MCHW format. + * :math:`g`: Filter value, a tensor with M format. + * :math:`\\ast`: Convolution operation. + * :math:`b`: Bias value, a 2-D tensor with shape [M, 1]. + * :math:`\\sigma`: Activation function. + * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different. + + Example: + + - Input: + + Input shape: :math:`(N, C_{in}, H_{in}, W_{in})` + + Filter shape: :math:`(C_{in}, C_{out}, H_f, W_f)` + + - Output: + + Output shape: :math:`(N, C_{out}, H_{out}, W_{out})` + + Where + + .. math:: + + H^\prime_{out} &= (H_{in} - 1) * strides[0] - 2 * paddings[0] + dilations[0] * (H_f - 1) + 1 \\\\ + W^\prime_{out} &= (W_{in} - 1) * strides[1] - 2 * paddings[1] + dilations[1] * (W_f - 1) + 1 \\\\ + H_{out} &\in [ H^\prime_{out}, H^\prime_{out} + strides[0] ) \\\\ + W_{out} &\in [ W^\prime_{out}, W^\prime_{out} + strides[1] ) + + Args: + name_scope(str): The name of this class. + num_filters(int): The number of the filter. It is as same as the output + image channel. + output_size(int|tuple|None): The output image size. If output size is a + tuple, it must contain two integers, (image_H, image_W). None if use + filter_size, padding, and stride to calculate output_size. + if output_size and filter_size are specified at the same time, They + should follow the formula above. Default: None. + filter_size(int|tuple|None): The filter size. If filter_size is a tuple, + it must contain two integers, (filter_size_H, filter_size_W). + Otherwise, the filter will be a square. None if use output size to + calculate filter_size. Default: None. + padding(int|tuple): The padding size. If padding is a tuple, it must + contain two integers, (padding_H, padding_W). Otherwise, the + padding_H = padding_W = padding. Default: padding = 0. + stride(int|tuple): The stride size. If stride is a tuple, it must + contain two integers, (stride_H, stride_W). Otherwise, the + stride_H = stride_W = stride. Default: stride = 1. + dilation(int|tuple): The dilation size. If dilation is a tuple, it must + contain two integers, (dilation_H, dilation_W). Otherwise, the + dilation_H = dilation_W = dilation. Default: dilation = 1. + groups(int): The groups number of the Conv2d transpose layer. Inspired by + grouped convolution in Alex Krizhevsky's Deep CNN paper, in which + when group=2, the first half of the filters is only connected to the + first half of the input channels, while the second half of the + filters is only connected to the second half of the input channels. + Default: groups = 1. + param_attr (ParamAttr|None): The parameter attribute for learnable parameters/weights + of conv2d_transpose. If it is set to None or one attribute of ParamAttr, conv2d_transpose + will create ParamAttr as param_attr. If the Initializer of the param_attr + is not set, the parameter is initialized with Xavier. Default: None. + bias_attr (ParamAttr|bool|None): The parameter attribute for the bias of conv2d_transpose. + If it is set to False, no bias will be added to the output units. + If it is set to None or one attribute of ParamAttr, conv2d_transpose + will create ParamAttr as bias_attr. If the Initializer of the bias_attr + is not set, the bias is initialized zero. Default: None. + use_cudnn(bool): Use cudnn kernel or not, it is valid only when the cudnn + library is installed. Default: True. + act (str): Activation type, if it is set to None, activation is not appended. + Default: None. + + Returns: + Variable: The tensor variable storing the convolution transpose result. + + Raises: + ValueError: If the shapes of input, filter_size, stride, padding and + groups mismatch. + + Examples: + .. code-block:: python + + import paddle.fluid as fluid + import numpy + + with fluid.dygraph.guard(): + data = numpy.random.random((3, 32, 32)).astype('float32') + conv2DTranspose = fluid.dygraph.nn.Conv2DTranspose( + 'Conv2DTranspose', num_filters=2, filter_size=3) + ret = conv2DTranspose(fluid.dygraph.base.to_variable(data)) + + """ + + def __init__(self, + name_scope, + num_filters, + output_size=None, + filter_size=None, + padding=0, + stride=1, + dilation=1, + groups=None, + param_attr=None, + bias_attr=None, + use_cudnn=True, + epsilon=1e-30, + act=None, + dtype="float32"): + super(Conv2DTranspose, self).__init__(name_scope, dtype) + assert (param_attr is not False + ), "param_attr should not be False in conv2d_transpose." + self._param_attr = param_attr + self._bias_attr = bias_attr + self._groups = groups + self._num_filters = num_filters + self._use_cudnn = use_cudnn + self._padding = padding + self._stride = stride + self._dilation = dilation + self._filter_size = filter_size + self._output_size = output_size + self._op_type = "conv2d_transpose" + self._epsilon = epsilon + + def _build_once(self, input): + input_channel = input.shape[1] + if (input_channel == self._groups and + self._num_filters == input_channel and not self._use_cudnn): + self._op_type = "depthwise_conv2d_transpose" + + if not isinstance(input, Variable): + raise TypeError("Input of conv2d_transpose must be Variable") + + self._padding = utils.convert_to_list(self._padding, 2, "padding") + self._stride = utils.convert_to_list(self._stride, 2, "stride") + self._dilation = utils.convert_to_list(self._dilation, 2, "dilation") + + if not isinstance(self._use_cudnn, bool): + raise ValueError("use_cudnn should be True or False") + + if self._filter_size is None: + if self._output_size is None: + raise ValueError( + "output_size must be set when filter_size is None") + if isinstance(self._output_size, int): + self._output_size = [self._output_size, self._output_size] + + h_in = input.shape[2] + w_in = input.shape[3] + + filter_size_h = (self._output_size[0] - + (h_in - 1) * self._stride[0] + 2 * self._padding[0] + - 1) // self._dilation[0] + 1 + filter_size_w = (self._output_size[1] - + (w_in - 1) * self._stride[1] + 2 * self._padding[1] + - 1) // self._dilation[1] + 1 + self._filter_size = [filter_size_h, filter_size_w] + else: + self._filter_size = utils.convert_to_list( + self._filter_size, 2, "conv2d_transpose.filter_size") + + if self._output_size is None: + self._output_size = [] + elif isinstance(self._output_size, list) or isinstance( + self._output_size, int): + self._output_size = utils.convert_to_list(self._output_size, 2, + "output_size") + else: + raise ValueError("output_size should be list or int") + self._padding = utils.convert_to_list(self._padding, 2, "padding") + self._groups = 1 if self._groups is None else self._groups + filter_shape = [ + input_channel, + self._num_filters // self._groups, + ] + self._filter_size + + # img filter v (direction) + self._img_filter_v = self.create_parameter( + dtype=input.dtype, shape=filter_shape, attr=self._param_attr) + + # img filter g (magnitude) + img_filter_magnitude = _norm( + self._img_filter_v.numpy(), dim=0) # CAUTION: hard-code + self._img_filter_g = self.create_parameter( + dtype=input.dtype, + shape=img_filter_magnitude.shape, + attr=fluid.ParamAttr( + initializer=NumpyArrayInitializer(img_filter_magnitude))) + + self._img_bias = self.create_parameter( + attr=self._bias_attr, + shape=[self._num_filters], + dtype=self._dtype, + is_bias=True) + + def forward(self, input): + matrix = self._helper.create_variable_for_type_inference(self._dtype) + tmp = self._helper.create_variable_for_type_inference(self._dtype) + new_shape = [ + self._img_filter_v.shape[0], + reduce(lambda x, y: x * y, self._img_filter_v.shape[1:], 1), + ] + + self._helper.append_op( + type="reshape2", + inputs={"X": self._img_filter_v}, + attrs={"shape": new_shape}, + outputs={"Out": matrix, + "XShape": tmp}) + + m_norm = self._helper.create_variable_for_type_inference(self._dtype) + m_normalized = self._helper.create_variable_for_type_inference( + self._dtype) + self._helper.append_op( + type="norm", + inputs={"X": matrix}, + outputs={"Out": m_normalized, + "Norm": m_norm}, + attrs={"axis": 1, + "epsilon": self._epsilon}) + + v_normalized = self._helper.create_variable_for_type_inference( + self._dtype) + tmp2 = self._helper.create_variable_for_type_inference(self._dtype) + self._helper.append_op( + type="reshape2", + inputs={"X": m_normalized}, + attrs={"shape": self._img_filter_v.shape}, + outputs={"Out": v_normalized, + "XShape": tmp2}) + + img_filter = self._helper.create_variable_for_type_inference( + self._dtype) + self._helper.append_op( + type="elementwise_mul", + inputs={"X": [v_normalized], + "Y": [self._img_filter_g]}, + outputs={"Out": [img_filter]}, + attrs={"axis": 0}, # CAUTION: hard-code + ) + + pre_bias = self._helper.create_variable_for_type_inference( + dtype=input.dtype) + self._helper.append_op( + type=self._op_type, + inputs={"Input": [input], + "Filter": [img_filter]}, + outputs={"Output": pre_bias}, + attrs={ + "output_size": self._output_size, + "strides": self._stride, + "paddings": self._padding, + "dilations": self._dilation, + "groups": self._groups, + "use_cudnn": self._use_cudnn, + }) + + if self._img_bias is not None: + pre_act = self._helper.create_variable_for_type_inference( + dtype=self._dtype) + self._helper.append_op( + type="elementwise_add", + inputs={"X": [pre_bias], + "Y": [self._img_bias]}, + outputs={"Out": [pre_act]}, + attrs={"axis": 1}) + else: + pre_act = pre_bias + + out = self._helper.append_activation(pre_act) + return out diff --git a/PaddleSpeech/DeepVoice3/eval_model.py b/PaddleSpeech/DeepVoice3/eval_model.py new file mode 100644 index 00000000..2069871b --- /dev/null +++ b/PaddleSpeech/DeepVoice3/eval_model.py @@ -0,0 +1,321 @@ +# Copyright (c) 2019 PaddlePaddle 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 __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import sys +import os +from os.path import join, expanduser +from warnings import warn +from datetime import datetime + +import matplotlib +# Force matplotlib to not use any Xwindows backend. +matplotlib.use("Agg") +from matplotlib import pyplot as plt +from matplotlib import cm + +import audio +import numpy as np +from paddle import fluid +import paddle.fluid.dygraph as dg +import librosa.display +from tensorboardX import SummaryWriter + +# import global hyper parameters +from hparams import hparams +from deepvoice3_paddle import frontend + +_frontend = getattr(frontend, hparams.frontend) + + +def tts(model, text, p=0., speaker_id=None): + """ + Convert text to speech waveform given a deepvoice3 model. + + Args: + model (DeepVoiceTTS): Model used to synthesize waveform. + text (str) : Input text to be synthesized + p (float) : Replace word to pronounciation if p > 0. Default is 0. + + Returns: + waveform (numpy.ndarray): Shape(T_wav, ), predicted wave form, where + T_wav means the length of the synthesized wave form. + alignment (numpy.ndarray): Shape(T_dec, T_enc), predicted alignment + matrix, where T_dec means the time steps of decoder outputs, T_enc + means the time steps of encoder outoputs. + spectrogram (numpy.ndarray): Shape(T_lin, C_lin), predicted linear + spectrogram, where T__lin means the time steps of linear + spectrogram and C_lin mean sthe channels of linear spectrogram. + mel (numpy.ndarray): Shape(T_mel, C_mel), predicted mel spectrogram, + where T_mel means the time steps of mel spectrogram and C_mel means + the channels of mel spectrogram. + """ + model.eval() + + sequence = np.array(_frontend.text_to_sequence(text, p=p)).astype("int64") + sequence = np.reshape(sequence, (1, -1, 1)) + text_positions = np.arange(1, sequence.shape[1] + 1, dtype="int64") + text_positions = np.reshape(text_positions, (1, -1, 1)) + + sequence = dg.to_variable(sequence) + text_positions = dg.to_variable(text_positions) + speaker_ids = None if speaker_id is None else fluid.layers.fill_constant( + shape=[1, 1], value=speaker_id) + + # sequence: shape(1, input_length, 1) + # text_positions: shape(1, input_length, 1) + # Greedy decoding + mel_outputs, linear_outputs, alignments, done = model.transduce( + sequence, text_positions, speaker_ids) + + # reshape to the desired shape + linear_output = linear_outputs.numpy().squeeze().T + spectrogram = audio._denormalize(linear_output) + alignment = alignments.numpy()[0] + mel = mel_outputs.numpy().squeeze().T + mel = audio._denormalize(mel) + + # Predicted audio signal + waveform = audio.inv_spectrogram(linear_output.T) + + return waveform, alignment, spectrogram, mel + + +def prepare_spec_image(spectrogram): + """ + Prepare an image from spectrogram to be written to tensorboardX + summary writer. + + Args: + spectrogram (numpy.ndarray): Shape(T, C), spectrogram to be + visualized, where T means the time steps of the spectrogram, + and C means the channels of the spectrogram. + Return: + np.ndarray: Shape(C, T, 4), the generated image of the spectrogram, + where T means the time steps of the spectrogram. It is treated + as the width of the image. And C means the channels of the + spectrogram, which is treated as the height of the image. And 4 + means it is a 'ARGP' format. + """ + + # [0, 1] + spectrogram = (spectrogram - np.min(spectrogram)) / ( + np.max(spectrogram) - np.min(spectrogram)) + spectrogram = np.flip(spectrogram, axis=1) # flip against freq axis + return np.uint8(cm.magma(spectrogram.T) * 255) + + +def plot_alignment(alignment, path, info=None): + fig, ax = plt.subplots() + im = ax.imshow( + alignment, aspect="auto", origin="lower", interpolation="none") + fig.colorbar(im, ax=ax) + xlabel = "Decoder timestep" + if info is not None: + xlabel += "\n\n" + info + plt.xlabel(xlabel) + plt.ylabel("Encoder timestep") + plt.tight_layout() + plt.savefig(path, format="png") + plt.close() + + +def time_string(): + return datetime.now().strftime("%Y-%m-%d %H:%M") + + +def save_alignment(global_step, path, attn): + plot_alignment( + attn.T, + path, + info="{}, {}, step={}".format(hparams.builder, + time_string(), global_step)) + + +def eval_model(global_step, writer, model, checkpoint_dir, ismultispeaker): + # hard coded text sequences + texts = [ + "Scientists at the CERN laboratory say they have discovered a new particle.", + "There's a way to measure the acute emotional intelligence that has never gone out of style.", + "President Trump met with other leaders at the Group of 20 conference.", + "Generative adversarial network or variational auto-encoder.", + "Please call Stella.", + "Some have accepted this as a miracle without any physical explanation.", + ] + + eval_output_dir = join(checkpoint_dir, "eval") + if not os.path.exists(eval_output_dir): + os.makedirs(eval_output_dir) + print("[eval] Evaluating the model, results are saved in {}".format( + eval_output_dir)) + + model.eval() + # hard coded + speaker_ids = [0, 1, 10] if ismultispeaker else [None] + for speaker_id in speaker_ids: + speaker_str = ("multispeaker{}".format(speaker_id) + if speaker_id is not None else "single") + + for idx, text in enumerate(texts): + signal, alignment, _, mel = tts(model, + text, + p=0, + speaker_id=speaker_id) + signal /= np.max(np.abs(signal)) + + # Alignment + path = join(eval_output_dir, + "step{:09d}_text{}_{}_alignment.png".format( + global_step, idx, speaker_str)) + save_alignment(global_step, path, alignment) + tag = "eval_averaged_alignment_{}_{}".format(idx, speaker_str) + writer.add_image( + tag, + np.uint8(cm.viridis(np.flip(alignment, 1).T) * 255), + global_step, + dataformats='HWC') + + # Mel + writer.add_image( + "(Eval) Predicted mel spectrogram text{}_{}".format( + idx, speaker_str), + prepare_spec_image(mel), + global_step, + dataformats='HWC') + + # Audio + path = join(eval_output_dir, + "step{:09d}_text{}_{}_predicted.wav".format( + global_step, idx, speaker_str)) + audio.save_wav(signal, path) + + try: + writer.add_audio( + "(Eval) Predicted audio signal {}_{}".format(idx, + speaker_str), + signal, + global_step, + sample_rate=hparams.sample_rate) + except Exception as e: + warn(str(e)) + pass + + +def save_states(global_step, + writer, + mel_outputs, + linear_outputs, + attn, + mel, + y, + input_lengths, + checkpoint_dir=None): + """ + Save states for the trainning process. + """ + print("[train] Saving intermediate states at step {}".format(global_step)) + + idx = min(1, len(input_lengths) - 1) + input_length = input_lengths[idx] + + # Alignment, Multi-hop attention + if attn is not None and len(attn.shape) == 4: + attn = attn.numpy() + for i in range(attn.shape[0]): + alignment = attn[i] + alignment = alignment[idx] + tag = "alignment_layer{}".format(i + 1) + writer.add_image( + tag, + np.uint8(cm.viridis(np.flip(alignment, 1).T) * 255), + global_step, + dataformats='HWC') + + alignment_dir = join(checkpoint_dir, + "alignment_layer{}".format(i + 1)) + if not os.path.exists(alignment_dir): + os.makedirs(alignment_dir) + path = join( + alignment_dir, + "step{:09d}_layer_{}_alignment.png".format(global_step, i + 1)) + save_alignment(global_step, path, alignment) + + alignment_dir = join(checkpoint_dir, "alignment_ave") + if not os.path.exists(alignment_dir): + os.makedirs(alignment_dir) + path = join(alignment_dir, + "step{:09d}_alignment.png".format(global_step)) + alignment = np.mean(attn, axis=0)[idx] + save_alignment(global_step, path, alignment) + + tag = "averaged_alignment" + writer.add_image( + tag, + np.uint8(cm.viridis(np.flip(alignment, 1).T) * 255), + global_step, + dataformats="HWC") + + if mel_outputs is not None: + mel_output = mel_outputs[idx].numpy().squeeze().T + mel_output = prepare_spec_image(audio._denormalize(mel_output)) + writer.add_image( + "Predicted mel spectrogram", + mel_output, + global_step, + dataformats="HWC") + + if linear_outputs is not None: + linear_output = linear_outputs[idx].numpy().squeeze().T + spectrogram = prepare_spec_image(audio._denormalize(linear_output)) + writer.add_image( + "Predicted linear spectrogram", + spectrogram, + global_step, + dataformats="HWC") + + signal = audio.inv_spectrogram(linear_output.T) + signal /= np.max(np.abs(signal)) + path = join(checkpoint_dir, + "step{:09d}_predicted.wav".format(global_step)) + try: + writer.add_audio( + "Predicted audio signal", + signal, + global_step, + sample_rate=hparams.sample_rate) + except Exception as e: + warn(str(e)) + pass + audio.save_wav(signal, path) + + if mel_outputs is not None: + mel_output = mel[idx].numpy().squeeze().T + mel_output = prepare_spec_image(audio._denormalize(mel_output)) + writer.add_image( + "Target mel spectrogram", + mel_output, + global_step, + dataformats="HWC") + + if linear_outputs is not None: + linear_output = y[idx].numpy().squeeze().T + spectrogram = prepare_spec_image(audio._denormalize(linear_output)) + writer.add_image( + "Target linear spectrogram", + spectrogram, + global_step, + dataformats="HWC") diff --git a/PaddleSpeech/DeepVoice3/hparam_tf/__init__.py b/PaddleSpeech/DeepVoice3/hparam_tf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/PaddleSpeech/DeepVoice3/hparam_tf/hparam.py b/PaddleSpeech/DeepVoice3/hparam_tf/hparam.py new file mode 100644 index 00000000..012885c9 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/hparam_tf/hparam.py @@ -0,0 +1,731 @@ +# Copyright 2016 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. +# ============================================================================== +"""Hyperparameter values.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import json +import numbers +import re + +import six + +## from tensorflow.contrib.training.python.training import hparam_pb2 +## from tensorflow.python.framework import ops +## from tensorflow.python.util import compat +## from tensorflow.python.util import deprecation + +# Define the regular expression for parsing a single clause of the input +# (delimited by commas). A legal clause looks like: +# []? = +# where is either a single token or [] enclosed list of tokens. +# For example: "var[1] = a" or "x = [1,2,3]" +PARAM_RE = re.compile(r""" + (?P[a-zA-Z][\w\.]*) # variable name: "var" or "x" + (\[\s*(?P\d+)\s*\])? # (optional) index: "1" or None + \s*=\s* + ((?P[^,\[]*) # single value: "a" or None + | + \[(?P[^\]]*)\]) # list of values: None or "1,2,3" + ($|,\s*)""", re.VERBOSE) + + +def _parse_fail(name, var_type, value, values): + """Helper function for raising a value error for bad assignment.""" + raise ValueError( + 'Could not parse hparam \'%s\' of type \'%s\' with value \'%s\' in %s' % + (name, var_type.__name__, value, values)) + + +def _reuse_fail(name, values): + """Helper function for raising a value error for reuse of name.""" + raise ValueError('Multiple assignments to variable \'%s\' in %s' % + (name, values)) + + +def _process_scalar_value(name, parse_fn, var_type, m_dict, values, + results_dictionary): + """Update results_dictionary with a scalar value. + + Used to update the results_dictionary to be returned by parse_values when + encountering a clause with a scalar RHS (e.g. "s=5" or "arr[0]=5".) + + Mutates results_dictionary. + + Args: + name: Name of variable in assignment ("s" or "arr"). + parse_fn: Function for parsing the actual value. + var_type: Type of named variable. + m_dict: Dictionary constructed from regex parsing. + m_dict['val']: RHS value (scalar) + m_dict['index']: List index value (or None) + values: Full expression being parsed + results_dictionary: The dictionary being updated for return by the parsing + function. + + Raises: + ValueError: If the name has already been used. + """ + try: + parsed_value = parse_fn(m_dict['val']) + except ValueError: + _parse_fail(name, var_type, m_dict['val'], values) + + # If no index is provided + if not m_dict['index']: + if name in results_dictionary: + _reuse_fail(name, values) + results_dictionary[name] = parsed_value + else: + if name in results_dictionary: + # The name has already been used as a scalar, then it + # will be in this dictionary and map to a non-dictionary. + if not isinstance(results_dictionary.get(name), dict): + _reuse_fail(name, values) + else: + results_dictionary[name] = {} + + index = int(m_dict['index']) + # Make sure the index position hasn't already been assigned a value. + if index in results_dictionary[name]: + _reuse_fail('{}[{}]'.format(name, index), values) + results_dictionary[name][index] = parsed_value + + +def _process_list_value(name, parse_fn, var_type, m_dict, values, + results_dictionary): + """Update results_dictionary from a list of values. + + Used to update results_dictionary to be returned by parse_values when + encountering a clause with a list RHS (e.g. "arr=[1,2,3]".) + + Mutates results_dictionary. + + Args: + name: Name of variable in assignment ("arr"). + parse_fn: Function for parsing individual values. + var_type: Type of named variable. + m_dict: Dictionary constructed from regex parsing. + m_dict['val']: RHS value (scalar) + values: Full expression being parsed + results_dictionary: The dictionary being updated for return by the parsing + function. + + Raises: + ValueError: If the name has an index or the values cannot be parsed. + """ + if m_dict['index'] is not None: + raise ValueError('Assignment of a list to a list index.') + elements = filter(None, re.split('[ ,]', m_dict['vals'])) + # Make sure the name hasn't already been assigned a value + if name in results_dictionary: + raise _reuse_fail(name, values) + try: + results_dictionary[name] = [parse_fn(e) for e in elements] + except ValueError: + _parse_fail(name, var_type, m_dict['vals'], values) + + +def _cast_to_type_if_compatible(name, param_type, value): + """Cast hparam to the provided type, if compatible. + + Args: + name: Name of the hparam to be cast. + param_type: The type of the hparam. + value: The value to be cast, if compatible. + + Returns: + The result of casting `value` to `param_type`. + + Raises: + ValueError: If the type of `value` is not compatible with param_type. + * If `param_type` is a string type, but `value` is not. + * If `param_type` is a boolean, but `value` is not, or vice versa. + * If `param_type` is an integer type, but `value` is not. + * If `param_type` is a float type, but `value` is not a numeric type. + """ + fail_msg = ("Could not cast hparam '%s' of type '%s' from value %r" % + (name, param_type, value)) + + # Some callers use None, for which we can't do any casting/checking. :( + if issubclass(param_type, type(None)): + return value + + # Avoid converting a non-string type to a string. + if (issubclass(param_type, (six.string_types, six.binary_type)) and + not isinstance(value, (six.string_types, six.binary_type))): + raise ValueError(fail_msg) + + # Avoid converting a number or string type to a boolean or vice versa. + if issubclass(param_type, bool) != isinstance(value, bool): + raise ValueError(fail_msg) + + # Avoid converting float to an integer (the reverse is fine). + if (issubclass(param_type, numbers.Integral) and + not isinstance(value, numbers.Integral)): + raise ValueError(fail_msg) + + # Avoid converting a non-numeric type to a numeric type. + if (issubclass(param_type, numbers.Number) and + not isinstance(value, numbers.Number)): + raise ValueError(fail_msg) + + return param_type(value) + + +def parse_values(values, type_map): + """Parses hyperparameter values from a string into a python map. + + `values` is a string containing comma-separated `name=value` pairs. + For each pair, the value of the hyperparameter named `name` is set to + `value`. + + If a hyperparameter name appears multiple times in `values`, a ValueError + is raised (e.g. 'a=1,a=2', 'a[1]=1,a[1]=2'). + + If a hyperparameter name in both an index assignment and scalar assignment, + a ValueError is raised. (e.g. 'a=[1,2,3],a[0] = 1'). + + The hyperparameter name may contain '.' symbols, which will result in an + attribute name that is only accessible through the getattr and setattr + functions. (And must be first explicit added through add_hparam.) + + WARNING: Use of '.' in your variable names is allowed, but is not well + supported and not recommended. + + The `value` in `name=value` must follows the syntax according to the + type of the parameter: + + * Scalar integer: A Python-parsable integer point value. E.g.: 1, + 100, -12. + * Scalar float: A Python-parsable floating point value. E.g.: 1.0, + -.54e89. + * Boolean: Either true or false. + * Scalar string: A non-empty sequence of characters, excluding comma, + spaces, and square brackets. E.g.: foo, bar_1. + * List: A comma separated list of scalar values of the parameter type + enclosed in square brackets. E.g.: [1,2,3], [1.0,1e-12], [high,low]. + + When index assignment is used, the corresponding type_map key should be the + list name. E.g. for "arr[1]=0" the type_map must have the key "arr" (not + "arr[1]"). + + Args: + values: String. Comma separated list of `name=value` pairs where + 'value' must follow the syntax described above. + type_map: A dictionary mapping hyperparameter names to types. Note every + parameter name in values must be a key in type_map. The values must + conform to the types indicated, where a value V is said to conform to a + type T if either V has type T, or V is a list of elements of type T. + Hence, for a multidimensional parameter 'x' taking float values, + 'x=[0.1,0.2]' will parse successfully if type_map['x'] = float. + + Returns: + A python map mapping each name to either: + * A scalar value. + * A list of scalar values. + * A dictionary mapping index numbers to scalar values. + (e.g. "x=5,L=[1,2],arr[1]=3" results in {'x':5,'L':[1,2],'arr':{1:3}}") + + Raises: + ValueError: If there is a problem with input. + * If `values` cannot be parsed. + * If a list is assigned to a list index (e.g. 'a[1] = [1,2,3]'). + * If the same rvalue is assigned two different values (e.g. 'a=1,a=2', + 'a[1]=1,a[1]=2', or 'a=1,a=[1]') + """ + results_dictionary = {} + pos = 0 + while pos < len(values): + m = PARAM_RE.match(values, pos) + if not m: + raise ValueError('Malformed hyperparameter value: %s' % + values[pos:]) + # Check that there is a comma between parameters and move past it. + pos = m.end() + # Parse the values. + m_dict = m.groupdict() + name = m_dict['name'] + if name not in type_map: + raise ValueError('Unknown hyperparameter type for %s' % name) + type_ = type_map[name] + + # Set up correct parsing function (depending on whether type_ is a bool) + if type_ == bool: + + def parse_bool(value): + if value in ['true', 'True']: + return True + elif value in ['false', 'False']: + return False + else: + try: + return bool(int(value)) + except ValueError: + _parse_fail(name, type_, value, values) + + parse = parse_bool + else: + parse = type_ + + # If a singe value is provided + if m_dict['val'] is not None: + _process_scalar_value(name, parse, type_, m_dict, values, + results_dictionary) + + # If the assigned value is a list: + elif m_dict['vals'] is not None: + _process_list_value(name, parse, type_, m_dict, values, + results_dictionary) + + else: # Not assigned a list or value + _parse_fail(name, type_, '', values) + + return results_dictionary + + +class HParams(object): + """Class to hold a set of hyperparameters as name-value pairs. + + A `HParams` object holds hyperparameters used to build and train a model, + such as the number of hidden units in a neural net layer or the learning rate + to use when training. + + You first create a `HParams` object by specifying the names and values of the + hyperparameters. + + To make them easily accessible the parameter names are added as direct + attributes of the class. A typical usage is as follows: + + ```python + # Create a HParams object specifying names and values of the model + # hyperparameters: + hparams = HParams(learning_rate=0.1, num_hidden_units=100) + + # The hyperparameter are available as attributes of the HParams object: + hparams.learning_rate ==> 0.1 + hparams.num_hidden_units ==> 100 + ``` + + Hyperparameters have type, which is inferred from the type of their value + passed at construction type. The currently supported types are: integer, + float, boolean, string, and list of integer, float, boolean, or string. + + You can override hyperparameter values by calling the + [`parse()`](#HParams.parse) method, passing a string of comma separated + `name=value` pairs. This is intended to make it possible to override + any hyperparameter values from a single command-line flag to which + the user passes 'hyper-param=value' pairs. It avoids having to define + one flag for each hyperparameter. + + The syntax expected for each value depends on the type of the parameter. + See `parse()` for a description of the syntax. + + Example: + + ```python + # Define a command line flag to pass name=value pairs. + # For example using argparse: + import argparse + parser = argparse.ArgumentParser(description='Train my model.') + parser.add_argument('--hparams', type=str, + help='Comma separated list of "name=value" pairs.') + args = parser.parse_args() + ... + def my_program(): + # Create a HParams object specifying the names and values of the + # model hyperparameters: + hparams = tf.HParams(learning_rate=0.1, num_hidden_units=100, + activations=['relu', 'tanh']) + + # Override hyperparameters values by parsing the command line + hparams.parse(args.hparams) + + # If the user passed `--hparams=learning_rate=0.3` on the command line + # then 'hparams' has the following attributes: + hparams.learning_rate ==> 0.3 + hparams.num_hidden_units ==> 100 + hparams.activations ==> ['relu', 'tanh'] + + # If the hyperparameters are in json format use parse_json: + hparams.parse_json('{"learning_rate": 0.3, "activations": "relu"}') + ``` + """ + + _HAS_DYNAMIC_ATTRIBUTES = True # Required for pytype checks. + + def __init__(self, hparam_def=None, model_structure=None, **kwargs): + """Create an instance of `HParams` from keyword arguments. + + The keyword arguments specify name-values pairs for the hyperparameters. + The parameter types are inferred from the type of the values passed. + + The parameter names are added as attributes of `HParams` object, so they + can be accessed directly with the dot notation `hparams._name_`. + + Example: + + ```python + # Define 3 hyperparameters: 'learning_rate' is a float parameter, + # 'num_hidden_units' an integer parameter, and 'activation' a string + # parameter. + hparams = tf.HParams( + learning_rate=0.1, num_hidden_units=100, activation='relu') + + hparams.activation ==> 'relu' + ``` + + Note that a few names are reserved and cannot be used as hyperparameter + names. If you use one of the reserved name the constructor raises a + `ValueError`. + + Args: + hparam_def: Serialized hyperparameters, encoded as a hparam_pb2.HParamDef + protocol buffer. If provided, this object is initialized by + deserializing hparam_def. Otherwise **kwargs is used. + model_structure: An instance of ModelStructure, defining the feature + crosses to be used in the Trial. + **kwargs: Key-value pairs where the key is the hyperparameter name and + the value is the value for the parameter. + + Raises: + ValueError: If both `hparam_def` and initialization values are provided, + or if one of the arguments is invalid. + + """ + # Register the hyperparameters and their type in _hparam_types. + # This simplifies the implementation of parse(). + # _hparam_types maps the parameter name to a tuple (type, bool). + # The type value is the type of the parameter for scalar hyperparameters, + # or the type of the list elements for multidimensional hyperparameters. + # The bool value is True if the value is a list, False otherwise. + self._hparam_types = {} + self._model_structure = model_structure + if hparam_def: + ## self._init_from_proto(hparam_def) + ## if kwargs: + ## raise ValueError('hparam_def and initialization values are ' + ## 'mutually exclusive') + raise ValueError('hparam_def has been disabled in this version') + else: + for name, value in six.iteritems(kwargs): + self.add_hparam(name, value) + +## def _init_from_proto(self, hparam_def): +## """Creates a new HParams from `HParamDef` protocol buffer. +## +## Args: +## hparam_def: `HParamDef` protocol buffer. +## """ +## assert isinstance(hparam_def, hparam_pb2.HParamDef) +## for name, value in hparam_def.hparam.items(): +## kind = value.WhichOneof('kind') +## if kind.endswith('_value'): +## # Single value. +## if kind.startswith('int64'): +## # Setting attribute value to be 'int' to ensure the type is compatible +## # with both Python2 and Python3. +## self.add_hparam(name, int(getattr(value, kind))) +## elif kind.startswith('bytes'): +## # Setting attribute value to be 'str' to ensure the type is compatible +## # with both Python2 and Python3. UTF-8 encoding is assumed. +## self.add_hparam(name, compat.as_str(getattr(value, kind))) +## else: +## self.add_hparam(name, getattr(value, kind)) +## else: +## # List of values. +## if kind.startswith('int64'): +## # Setting attribute value to be 'int' to ensure the type is compatible +## # with both Python2 and Python3. +## self.add_hparam(name, [int(v) for v in getattr(value, kind).value]) +## elif kind.startswith('bytes'): +## # Setting attribute value to be 'str' to ensure the type is compatible +## # with both Python2 and Python3. UTF-8 encoding is assumed. +## self.add_hparam( +## name, [compat.as_str(v) for v in getattr(value, kind).value]) +## else: +## self.add_hparam(name, [v for v in getattr(value, kind).value]) + + def add_hparam(self, name, value): + """Adds {name, value} pair to hyperparameters. + + Args: + name: Name of the hyperparameter. + value: Value of the hyperparameter. Can be one of the following types: + int, float, string, int list, float list, or string list. + + Raises: + ValueError: if one of the arguments is invalid. + """ + # Keys in kwargs are unique, but 'name' could the name of a pre-existing + # attribute of this object. In that case we refuse to use it as a + # hyperparameter name. + if getattr(self, name, None) is not None: + raise ValueError('Hyperparameter name is reserved: %s' % name) + if isinstance(value, (list, tuple)): + if not value: + raise ValueError( + 'Multi-valued hyperparameters cannot be empty: %s' % name) + self._hparam_types[name] = (type(value[0]), True) + else: + self._hparam_types[name] = (type(value), False) + setattr(self, name, value) + + def set_hparam(self, name, value): + """Set the value of an existing hyperparameter. + + This function verifies that the type of the value matches the type of the + existing hyperparameter. + + Args: + name: Name of the hyperparameter. + value: New value of the hyperparameter. + + Raises: + ValueError: If there is a type mismatch. + """ + param_type, is_list = self._hparam_types[name] + if isinstance(value, list): + if not is_list: + raise ValueError( + 'Must not pass a list for single-valued parameter: %s' % + name) + setattr(self, name, [ + _cast_to_type_if_compatible(name, param_type, v) for v in value + ]) + else: + if is_list: + raise ValueError( + 'Must pass a list for multi-valued parameter: %s.' % name) + setattr(self, name, + _cast_to_type_if_compatible(name, param_type, value)) + + def del_hparam(self, name): + """Removes the hyperparameter with key 'name'. + + Args: + name: Name of the hyperparameter. + """ + if hasattr(self, name): + delattr(self, name) + del self._hparam_types[name] + + def parse(self, values): + """Override hyperparameter values, parsing new values from a string. + + See parse_values for more detail on the allowed format for values. + + Args: + values: String. Comma separated list of `name=value` pairs where + 'value' must follow the syntax described above. + + Returns: + The `HParams` instance. + + Raises: + ValueError: If `values` cannot be parsed. + """ + type_map = dict() + for name, t in self._hparam_types.items(): + param_type, _ = t + type_map[name] = param_type + + values_map = parse_values(values, type_map) + return self.override_from_dict(values_map) + + def override_from_dict(self, values_dict): + """Override hyperparameter values, parsing new values from a dictionary. + + Args: + values_dict: Dictionary of name:value pairs. + + Returns: + The `HParams` instance. + + Raises: + ValueError: If `values_dict` cannot be parsed. + """ + for name, value in values_dict.items(): + self.set_hparam(name, value) + return self + +## @deprecation.deprecated(None, 'Use `override_from_dict`.') + + def set_from_map(self, values_map): + """DEPRECATED. Use override_from_dict.""" + return self.override_from_dict(values_dict=values_map) + + def set_model_structure(self, model_structure): + self._model_structure = model_structure + + def get_model_structure(self): + return self._model_structure + + def to_json(self, indent=None, separators=None, sort_keys=False): + """Serializes the hyperparameters into JSON. + + Args: + indent: If a non-negative integer, JSON array elements and object members + will be pretty-printed with that indent level. An indent level of 0, or + negative, will only insert newlines. `None` (the default) selects the + most compact representation. + separators: Optional `(item_separator, key_separator)` tuple. Default is + `(', ', ': ')`. + sort_keys: If `True`, the output dictionaries will be sorted by key. + + Returns: + A JSON string. + """ + return json.dumps( + self.values(), + indent=indent, + separators=separators, + sort_keys=sort_keys) + + def parse_json(self, values_json): + """Override hyperparameter values, parsing new values from a json object. + + Args: + values_json: String containing a json object of name:value pairs. + + Returns: + The `HParams` instance. + + Raises: + ValueError: If `values_json` cannot be parsed. + """ + values_map = json.loads(values_json) + return self.override_from_dict(values_map) + + def values(self): + """Return the hyperparameter values as a Python dictionary. + + Returns: + A dictionary with hyperparameter names as keys. The values are the + hyperparameter values. + """ + return {n: getattr(self, n) for n in self._hparam_types.keys()} + + def get(self, key, default=None): + """Returns the value of `key` if it exists, else `default`.""" + if key in self._hparam_types: + # Ensure that default is compatible with the parameter type. + if default is not None: + param_type, is_param_list = self._hparam_types[key] + type_str = 'list<%s>' % param_type if is_param_list else str( + param_type) + fail_msg = ("Hparam '%s' of type '%s' is incompatible with " + 'default=%s' % (key, type_str, default)) + + is_default_list = isinstance(default, list) + if is_param_list != is_default_list: + raise ValueError(fail_msg) + + try: + if is_default_list: + for value in default: + _cast_to_type_if_compatible(key, param_type, value) + else: + _cast_to_type_if_compatible(key, param_type, default) + except ValueError as e: + raise ValueError('%s. %s' % (fail_msg, e)) + + return getattr(self, key) + + return default + + def __contains__(self, key): + return key in self._hparam_types + + def __str__(self): + return str(sorted(self.values().items())) + + def __repr__(self): + return '%s(%s)' % (type(self).__name__, self.__str__()) + + @staticmethod + def _get_kind_name(param_type, is_list): + """Returns the field name given parameter type and is_list. + + Args: + param_type: Data type of the hparam. + is_list: Whether this is a list. + + Returns: + A string representation of the field name. + + Raises: + ValueError: If parameter type is not recognized. + """ + if issubclass(param_type, bool): + # This check must happen before issubclass(param_type, six.integer_types), + # since Python considers bool to be a subclass of int. + typename = 'bool' + elif issubclass(param_type, six.integer_types): + # Setting 'int' and 'long' types to be 'int64' to ensure the type is + # compatible with both Python2 and Python3. + typename = 'int64' + elif issubclass(param_type, (six.string_types, six.binary_type)): + # Setting 'string' and 'bytes' types to be 'bytes' to ensure the type is + # compatible with both Python2 and Python3. + typename = 'bytes' + elif issubclass(param_type, float): + typename = 'float' + else: + raise ValueError('Unsupported parameter type: %s' % str(param_type)) + + suffix = 'list' if is_list else 'value' + return '_'.join([typename, suffix]) + + +## def to_proto(self, export_scope=None): # pylint: disable=unused-argument +## """Converts a `HParams` object to a `HParamDef` protocol buffer. +## +## Args: +## export_scope: Optional `string`. Name scope to remove. +## +## Returns: +## A `HParamDef` protocol buffer. +## """ +## hparam_proto = hparam_pb2.HParamDef() +## for name in self._hparam_types: +## # Parse the values. +## param_type, is_list = self._hparam_types.get(name, (None, None)) +## kind = HParams._get_kind_name(param_type, is_list) +## +## if is_list: +## if kind.startswith('bytes'): +## v_list = [compat.as_bytes(v) for v in getattr(self, name)] +## else: +## v_list = [v for v in getattr(self, name)] +## getattr(hparam_proto.hparam[name], kind).value.extend(v_list) +## else: +## v = getattr(self, name) +## if kind.startswith('bytes'): +## v = compat.as_bytes(getattr(self, name)) +## setattr(hparam_proto.hparam[name], kind, v) +## +## return hparam_proto + +## @staticmethod +## def from_proto(hparam_def, import_scope=None): # pylint: disable=unused-argument +## return HParams(hparam_def=hparam_def) + +## ops.register_proto_function( +## 'hparams', +## proto_type=hparam_pb2.HParamDef, +## to_proto=HParams.to_proto, +## from_proto=HParams.from_proto) diff --git a/PaddleSpeech/DeepVoice3/hparam_tf/readme.md b/PaddleSpeech/DeepVoice3/hparam_tf/readme.md new file mode 100644 index 00000000..3d94e4c4 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/hparam_tf/readme.md @@ -0,0 +1,8 @@ +Source: hparam.py copied from tensorflow v1.12.0. + +https://github.com/tensorflow/tensorflow/blob/v1.12.0/tensorflow/contrib/training/python/training/hparam.py + +with the following: +wget https://github.com/tensorflow/tensorflow/raw/v1.12.0/tensorflow/contrib/training/python/training/hparam.py + +Once all other tensorflow dependencies of these file are removed, the class keeps its goal. Functions not available due to this process are not used in this project. diff --git a/PaddleSpeech/DeepVoice3/hparams.py b/PaddleSpeech/DeepVoice3/hparams.py new file mode 100644 index 00000000..741cc65a --- /dev/null +++ b/PaddleSpeech/DeepVoice3/hparams.py @@ -0,0 +1,150 @@ +# Part of code was adpated from https://github.com/r9y9/deepvoice3_pytorch/tree/master/hparams.py +# Copyright (c) 2017: Ryuichi Yamamoto. + +import hparam_tf.hparam +# NOTE: If you want full control for model architecture. please take a look +# at the code and change whatever you want. Some hyper parameters are hardcoded. + +# Default hyperparameters: +hparams = hparam_tf.hparam.HParams( + name="deepvoice3", + + # Text: + # [en, jp] + frontend='en', + + # Replace words to its pronunciation with fixed probability. + # e.g., 'hello' to 'HH AH0 L OW1' + # [en, jp] + # en: Word -> pronunciation using CMUDict + # jp: Word -> pronounciation usnig MeCab + # [0 ~ 1.0]: 0 means no replacement happens. + replace_pronunciation_prob=0.5, + + # Convenient model builder + # [deepvoice3, deepvoice3_multispeaker, nyanko] + # Definitions can be found at deepvoice3_pytorch/builder.py + # deepvoice3: DeepVoice3 https://arxiv.org/abs/1710.07654 + # deepvoice3_multispeaker: Multi-speaker version of DeepVoice3 + # nyanko: https://arxiv.org/abs/1710.08969 + builder="deepvoice3", + + # Must be configured depends on the dataset and model you use + n_speakers=1, + speaker_embed_dim=16, + + # Audio: + num_mels=80, + fmin=125, + fmax=7600, + fft_size=1024, + hop_size=256, + sample_rate=22050, + preemphasis=0.97, + min_level_db=-100, + ref_level_db=20, + # whether to rescale waveform or not. + # Let x is an input waveform, rescaled waveform y is given by: + # y = x / np.abs(x).max() * rescaling_max + rescaling=False, + rescaling_max=0.999, + # mel-spectrogram is normalized to [0, 1] for each utterance and clipping may + # happen depends on min_level_db and ref_level_db, causing clipping noise. + # If False, assertion is added to ensure no clipping happens. + allow_clipping_in_normalization=True, + + # Model: + downsample_step=4, # must be 4 when builder="nyanko" + outputs_per_step=1, # must be 1 when builder="nyanko" + embedding_weight_std=0.1, + speaker_embedding_weight_std=0.01, + padding_idx=0, + # Maximum number of input text length + # try setting larger value if you want to give very long text input + max_positions=512, + dropout=1 - 0.95, + kernel_size=3, + text_embed_dim=128, + encoder_channels=256, + decoder_channels=256, + # Note: large converter channels requires significant computational cost + converter_channels=256, + query_position_rate=1.0, + # can be computed by `compute_timestamp_ratio.py`. + key_position_rate=1.385, # 2.37 for jsut + key_projection=False, + value_projection=False, + use_memory_mask=True, + trainable_positional_encodings=False, + freeze_embedding=False, + # If True, use decoder's internal representation for postnet inputs, + # otherwise use mel-spectrogram. + use_decoder_state_for_postnet_input=True, + + # Data loader + random_seed=1234, + pin_memory=True, + # Set it to 1 when in Windows (MemoryError, THAllocator.c 0x5) + num_workers=2, + + # Loss + masked_loss_weight=0.5, # (1-w)*loss + w * masked_loss + # heuristic: priotrize [0 ~ priotiry_freq] for linear loss + priority_freq=3000, + priority_freq_weight=0.0, # (1-w)*linear_loss + w*priority_linear_loss + # https://arxiv.org/pdf/1710.08969.pdf + # Adding the divergence to the loss stabilizes training, expecially for + # very deep (> 10 layers) networks. + # Binary div loss seems has approx 10x scale compared to L1 loss, so I choose 0.1. + binary_divergence_weight=0.1, # set 0 to disable + use_guided_attention=True, + guided_attention_sigma=0.2, + + # Training: + batch_size=16, + adam_beta1=0.5, + adam_beta2=0.9, + adam_eps=1e-6, + amsgrad=False, + initial_learning_rate=5e-4, # 0.001, + lr_schedule="noam_learning_rate_decay", + lr_schedule_kwargs={}, + nepochs=2000, + weight_decay=0.0, + clip_thresh=0.1, + + # Save + checkpoint_interval=10000, + eval_interval=10000, + save_optimizer_state=True, + + # Eval: + # this can be list for multple layers of attention + # e.g., [True, False, False, False, True] + force_monotonic_attention=True, + # Attention constraint for incremental decoding + window_ahead=3, + # 0 tends to prevent word repretetion, but sometime causes skip words + window_backward=1, + power=1.4, # Power to raise magnitudes to prior to phase retrieval + + # GC: + # Forced garbage collection probability + # Use only when MemoryError continues in Windows (Disabled by default) + #gc_probability = 0.001, + + # json_meta mode only + # 0: "use all", + # 1: "ignore only unmatched_alignment", + # 2: "fully ignore recognition", + ignore_recognition_level=2, + # when dealing with non-dedicated speech dataset(e.g. movie excerpts), setting min_text above 15 is desirable. Can be adjusted by dataset. + min_text=20, + # if true, data without phoneme alignment file(.lab) will be ignored + process_only_htk_aligned=False) + + +def hparams_debug_string(): + values = hparams.values() + hp = [' %s: %s' % (name, values[name]) for name in sorted(values)] + return 'Hyperparameters:\n' + '\n'.join(hp) diff --git a/PaddleSpeech/DeepVoice3/ljspeech.py b/PaddleSpeech/DeepVoice3/ljspeech.py new file mode 100644 index 00000000..69e79cfa --- /dev/null +++ b/PaddleSpeech/DeepVoice3/ljspeech.py @@ -0,0 +1,89 @@ +# This file is copied from https://github.com/r9y9/deepvoice3_pytorch/tree/master/ljspeech.py +# Copyright (c) 2017: Ryuichi Yamamoto. + +from concurrent.futures import ProcessPoolExecutor +from functools import partial +import numpy as np +import io +import os +import audio +from hparams import hparams + + +def build_from_path(in_dir, out_dir, num_workers=1, tqdm=lambda x: x): + '''Preprocesses the LJ Speech dataset from a given input path into a given output directory. + + Args: + in_dir: The directory where you have downloaded the LJ Speech dataset + out_dir: The directory to write the output into + num_workers: Optional number of worker processes to parallelize across + tqdm: You can optionally pass tqdm to get a nice progress bar + + Returns: + A list of tuples describing the training examples. This should be written to train.txt + ''' + + # We use ProcessPoolExecutor to parallize across processes. This is just an optimization and you + # can omit it and just call _process_utterance on each input if you want. + executor = ProcessPoolExecutor(max_workers=num_workers) + futures = [] + index = 1 + with io.open( + os.path.join(in_dir, 'metadata.csv'), "rt", encoding='utf-8') as f: + for line in f: + parts = line.strip().split('|') + wav_path = os.path.join(in_dir, 'wavs', '%s.wav' % parts[0]) + text = parts[2] + if len(text) < hparams.min_text: + continue + futures.append( + executor.submit( + partial(_process_utterance, out_dir, index, wav_path, + text))) + index += 1 + return [future.result() for future in tqdm(futures)] + + +def _process_utterance(out_dir, index, wav_path, text): + '''Preprocesses a single utterance audio/text pair. + + This writes the mel and linear scale spectrograms to disk and returns a tuple to write + to the train.txt file. + + Args: + out_dir: The directory to write the spectrograms into + index: The numeric index to use in the spectrogram filenames. + wav_path: Path to the audio file containing the speech input + text: The text spoken in the input audio file + + Returns: + A (spectrogram_filename, mel_filename, n_frames, text) tuple to write to train.txt + ''' + + # Load the audio to a numpy array: + wav = audio.load_wav(wav_path) + + if hparams.rescaling: + wav = wav / np.abs(wav).max() * hparams.rescaling_max + + # Compute the linear-scale spectrogram from the wav: + spectrogram = audio.spectrogram(wav).astype(np.float32) + n_frames = spectrogram.shape[1] + + # Compute a mel-scale spectrogram from the wav: + mel_spectrogram = audio.melspectrogram(wav).astype(np.float32) + + # Write the spectrograms to disk: + spectrogram_filename = 'ljspeech-spec-%05d.npy' % index + mel_filename = 'ljspeech-mel-%05d.npy' % index + np.save( + os.path.join(out_dir, spectrogram_filename), + spectrogram.T, + allow_pickle=False) + np.save( + os.path.join(out_dir, mel_filename), + mel_spectrogram.T, + allow_pickle=False) + + # Return a tuple describing this training example: + return (spectrogram_filename, mel_filename, n_frames, text) diff --git a/PaddleSpeech/DeepVoice3/preprocess.py b/PaddleSpeech/DeepVoice3/preprocess.py new file mode 100644 index 00000000..4b344640 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/preprocess.py @@ -0,0 +1,90 @@ +# coding: utf-8 +# Part of code was adpated from https://github.com/r9y9/deepvoice3_pytorch/tree/master/preprocess.py +# Copyright (c) 2017: Ryuichi Yamamoto. + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import io +import six +import os +from multiprocessing import cpu_count +from tqdm import tqdm +import importlib +from hparams import hparams, hparams_debug_string + + +def build_parser(): + parser = argparse.ArgumentParser(description="Data Preprocessing") + parser.add_argument("--num-workers", type=int, help="Num workers.") + parser.add_argument( + "--hparams", + type=str, + default="", + help="Hyper parameters to overwrite.") + parser.add_argument( + "--preset", + type=str, + required=True, + help="Path of preset parameters (json)") + parser.add_argument("name", type=str, help="Dataset name") + parser.add_argument("in_dir", type=str, help="Dataset path.") + parser.add_argument( + "out_dir", type=str, help="Path of preprocessed dataset.") + return parser + + +def preprocess(mod, in_dir, out_root, num_workers): + if not os.path.exists(out_dir): + os.makedirs(out_dir) + metadata = mod.build_from_path(in_dir, out_dir, num_workers, tqdm=tqdm) + write_metadata(metadata, out_dir) + + +def write_metadata(metadata, out_dir): + if six.PY3: + string_type = str + elif six.PY2: + string_type = unicode + else: + raise ValueError("Not running on Python2 or Python 3?") + with io.open( + os.path.join(out_dir, 'train.txt'), 'wt', encoding='utf-8') as f: + for m in metadata: + f.write(u'|'.join([string_type(x) for x in m]) + '\n') + + frames = sum([m[2] for m in metadata]) + frame_shift_ms = hparams.hop_size / hparams.sample_rate * 1000 + hours = frames * frame_shift_ms / (3600 * 1000) + print('Wrote %d utterances, %d frames (%.2f hours)' % + (len(metadata), frames, hours)) + print('Max input length: %d' % max(len(m[3]) for m in metadata)) + print('Max output length: %d' % max(m[2] for m in metadata)) + + +if __name__ == "__main__": + parser = build_parser() + args, _ = parser.parse_known_args() + + name = args.name + in_dir = args.in_dir + out_dir = args.out_dir + num_workers = args.num_workers + if num_workers is None: + num_workers = cpu_count() + preset = args.preset + + # Load preset if specified + if preset is not None: + with open(preset) as f: + hparams.parse_json(f.read()) + # Override hyper parameters + hparams.parse(args.hparams) + assert hparams.name == "deepvoice3" + print(hparams_debug_string()) + + assert name in ["ljspeech"], "now we only supports ljspeech" + mod = importlib.import_module(name) + preprocess(mod, in_dir, out_dir, num_workers) diff --git a/PaddleSpeech/DeepVoice3/presets/deepvoice3_ljspeech.json b/PaddleSpeech/DeepVoice3/presets/deepvoice3_ljspeech.json new file mode 100644 index 00000000..76687ba7 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/presets/deepvoice3_ljspeech.json @@ -0,0 +1,65 @@ +{ + "name": "deepvoice3", + "frontend": "en", + "replace_pronunciation_prob": 0.5, + "builder": "deepvoice3", + "n_speakers": 1, + "speaker_embed_dim": 16, + "num_mels": 80, + "fmin": 125, + "fmax": 7600, + "fft_size": 1024, + "hop_size": 256, + "sample_rate": 22050, + "preemphasis": 0.97, + "min_level_db": -100, + "ref_level_db": 20, + "rescaling": false, + "rescaling_max": 0.999, + "allow_clipping_in_normalization": true, + "downsample_step": 4, + "outputs_per_step": 1, + "embedding_weight_std": 0.1, + "speaker_embedding_weight_std": 0.01, + "padding_idx": 0, + "max_positions": 512, + "dropout": 0.050000000000000044, + "kernel_size": 3, + "text_embed_dim": 256, + "encoder_channels": 512, + "decoder_channels": 256, + "converter_channels": 256, + "query_position_rate": 1.0, + "key_position_rate": 1.385, + "key_projection": true, + "value_projection": true, + "use_memory_mask": true, + "trainable_positional_encodings": false, + "freeze_embedding": false, + "use_decoder_state_for_postnet_input": true, + "pin_memory": true, + "num_workers": 2, + "masked_loss_weight": 0.5, + "priority_freq": 3000, + "priority_freq_weight": 0.0, + "binary_divergence_weight": 0.1, + "use_guided_attention": true, + "guided_attention_sigma": 0.2, + "batch_size": 16, + "adam_beta1": 0.5, + "adam_beta2": 0.9, + "adam_eps": 1e-06, + "initial_learning_rate": 0.0005, + "lr_schedule": "noam_learning_rate_decay", + "lr_schedule_kwargs": {}, + "nepochs": 2000, + "weight_decay": 0.0, + "clip_thresh": 0.1, + "checkpoint_interval": 10000, + "eval_interval": 10000, + "save_optimizer_state": true, + "force_monotonic_attention": true, + "window_ahead": 3, + "window_backward": 1, + "power": 1.4 +} diff --git a/PaddleSpeech/DeepVoice3/requirements.txt b/PaddleSpeech/DeepVoice3/requirements.txt new file mode 100644 index 00000000..42d9ca74 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/requirements.txt @@ -0,0 +1,14 @@ +numba==0.45.1 +numpy==1.16.4 +nltk==3.4.4 +scipy +unidecode==1.1.1 +inflect==2.1.0 +librosa==0.7.0 +tqdm==4.35.0 +tensorboardX==1.8 +matplotlib +requests==2.22.0 +lws +nnmnkwii +tensorboard diff --git a/PaddleSpeech/DeepVoice3/synthesis.py b/PaddleSpeech/DeepVoice3/synthesis.py new file mode 100644 index 00000000..18b58c19 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/synthesis.py @@ -0,0 +1,175 @@ +# Copyright (c) 2019 PaddlePaddle 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 __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import sys +import os +from os.path import dirname, join, basename, splitext, exists +from tqdm import tqdm +import numpy as np +import nltk + +from paddle import fluid +import paddle.fluid.dygraph as dg + +import audio +from deepvoice3_paddle import frontend +from deepvoice3_paddle.dry_run import dry_run + +from hparams import hparams +from train import make_deepvoice3_from_hparams +from eval_model import tts, plot_alignment +from deepvoice3_paddle.save_load import load_checkpoint + + +def build_parser(): + parser = argparse.ArgumentParser( + description="Synthesis waveform from trained model.") + parser.add_argument( + "--hparams", type=str, default="", help="Hyper parameters.") + parser.add_argument( + "--preset", + type=str, + required=True, + help="Path of preset parameters (json).") + parser.add_argument( + "--use-gpu", + action="store_true", + help="Whether to use gpu for generation.") + parser.add_argument( + "--checkpoint-seq2seq", + type=str, + help="Load seq2seq model from checkpoint path.") + parser.add_argument( + "--checkpoint-postnet", + type=str, + help="Load postnet model from checkpoint path.") + parser.add_argument( + "--file-name-suffix", type=str, default="", help="File name suffix.") + parser.add_argument( + "--max-decoder-steps", type=int, default=500, help="Max decoder steps.") + parser.add_argument( + "--replace_pronunciation_prob", + type=float, + default=0., + help="Probility to replace text with pronunciation.") + parser.add_argument( + "--speaker-id", type=int, help="Speaker ID (for multi-speaker model).") + parser.add_argument( + "--output-html", action="store_true", help="Output html for blog post.") + parser.add_argument( + "checkpoint", type=str, help="The checkpoint used for synthesis") + parser.add_argument( + "text_list_file", + type=str, + help="Text file to synthesis, a sentence per line.") + parser.add_argument( + "dst_dir", type=str, help="Directory to save synthesis results.") + return parser + + +if __name__ == "__main__": + parser = build_parser() + args, _ = parser.parse_known_args() + + checkpoint_path = args.checkpoint + text_list_file_path = args.text_list_file + dst_dir = args.dst_dir + use_gpu = args.use_gpu + checkpoint_seq2seq_path = args.checkpoint_seq2seq + checkpoint_postnet_path = args.checkpoint_postnet + + max_decoder_steps = args.max_decoder_steps + file_name_suffix = args.file_name_suffix + replace_pronunciation_prob = args.replace_pronunciation_prob + output_html = args.output_html + speaker_id = args.speaker_id + preset = args.preset + + print("Command Line Args:") + for k, v in vars(args).items(): + print(" {}: {}".format(k, v)) + + # Load preset if specified + if preset is not None: + with open(preset) as f: + hparams.parse_json(f.read()) + # Override hyper parameters + hparams.parse(args.hparams) + assert hparams.name == "deepvoice3" + + place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace() + with dg.guard(place): + # Model + model = make_deepvoice3_from_hparams(hparams) + dry_run(model) + load_checkpoint(checkpoint_path, model) + + checkpoint_name = splitext(basename(checkpoint_path))[0] + + model.seq2seq.decoder.max_decoder_steps = max_decoder_steps + + if not os.path.exists(dst_dir): + os.mkdir(dst_dir) + with open(text_list_file_path, "rb") as f: + lines = f.readlines() + for idx, line in enumerate(lines): + text = line.decode("utf-8")[:-1] + words = nltk.word_tokenize(text) + waveform, alignment, _, _ = tts(model, + text, + p=replace_pronunciation_prob, + speaker_id=speaker_id) + + dst_wav_path = join(dst_dir, "{}_{}{}.wav".format( + idx, checkpoint_name, file_name_suffix)) + dst_alignment_path = join( + dst_dir, "{}_{}{}_alignment.png".format( + idx, checkpoint_name, file_name_suffix)) + plot_alignment( + alignment.T, + dst_alignment_path, + info="{}, {}".format(hparams.builder, + basename(checkpoint_path))) + audio.save_wav(waveform, dst_wav_path) + name = splitext(basename(text_list_file_path))[0] + if output_html: + print(""" + {} + + ({} chars, {} words) + + + +

+ """.format(text, + len(text), + len(words), hparams.builder, name, + basename(dst_wav_path), hparams.builder, name, + basename(dst_alignment_path))) + else: + print(idx, ": {}\n ({} chars, {} words)".format(text, + len(text), + len(words))) + + print("Finished! Check out {} for generated audio samples.".format( + dst_dir)) + sys.exit(0) diff --git a/PaddleSpeech/DeepVoice3/train.py b/PaddleSpeech/DeepVoice3/train.py new file mode 100644 index 00000000..db8b4295 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/train.py @@ -0,0 +1,271 @@ +# Copyright (c) 2019 PaddlePaddle 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 __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from paddle import fluid +import paddle.fluid.dygraph as dg + +from argparse import ArgumentParser +from hparams import hparams, hparams_debug_string + +from nnmnkwii.datasets import FileSourceDataset +from deepvoice3_paddle.data import (TextDataSource, MelSpecDataSource, + LinearSpecDataSource, + PartialyRandomizedSimilarTimeLengthSampler, + Dataset, make_loader, create_batch) + +from deepvoice3_paddle import frontend +from deepvoice3_paddle.builder import deepvoice3, WindowRange +from deepvoice3_paddle.dry_run import dry_run + +from deepvoice3_paddle.save_load import load_checkpoint, _load_embedding, save_checkpoint + +from train_model import train_model +from deepvoice3_paddle.loss import TTSLoss + +import platform +from datetime import datetime +from tensorboardX import SummaryWriter + + +def build_arg_parser(): + parser = ArgumentParser(description="Train deepvoice 3 model.") + + parser.add_argument( + "--data-root", + type=str, + required=True, + help="Directory contains preprocessed features.") + parser.add_argument( + "--use-data-parallel", + action="store_true", + help="Whether to use data parallel training.") + parser.add_argument( + "--use-gpu", action="store_true", help="Whether to use gpu training.") + parser.add_argument( + "--checkpoint-dir", + type=str, + default="checkpoints", + help="Directory where to save model checkpoints") + parser.add_argument( + "--preset", + type=str, + required=True, + help="Path of preset parameters in json format.") + parser.add_argument( + "--hparams", + type=str, + default="", + help="Hyper parameters to override preset.") + parser.add_argument( + "--checkpoint", + type=str, + help="Restore model from checkpoint path if given.") + parser.add_argument( + "--reset-optimizer", action="store_true", help="Reset optimizer.") + # mutually exclusive option + train_opt = parser.add_mutually_exclusive_group() + train_opt.add_argument( + "--train-seq2seq-only", + action="store_true", + help="Train only seq2seq model") + train_opt.add_argument( + "--train-postnet-only", + action="store_true", + help="Train only postnet model.") + parser.add_argument("--log-event-path", type=str, help="Log event path.") + parser.add_argument( + "--load-embedding", type=str, help="Load embedding from checkpoint.") + parser.add_argument( + "--speaker-id", + type=int, + help="Use specific speaker of data in case for multi-speaker datasets.", + ) + return parser + + +def make_deepvoice3_from_hparams(hparams): + n_vocab = getattr(frontend, hparams.frontend).n_vocab + model = deepvoice3( + n_vocab, hparams.text_embed_dim, hparams.num_mels, + hparams.fft_size // 2 + 1, hparams.outputs_per_step, + hparams.downsample_step, hparams.n_speakers, hparams.speaker_embed_dim, + hparams.padding_idx, hparams.dropout, hparams.kernel_size, + hparams.encoder_channels, hparams.decoder_channels, + hparams.converter_channels, hparams.query_position_rate, + hparams.key_position_rate, hparams.use_memory_mask, + hparams.trainable_positional_encodings, + hparams.force_monotonic_attention, + hparams.use_decoder_state_for_postnet_input, hparams.max_positions, + hparams.embedding_weight_std, hparams.speaker_embedding_weight_std, + hparams.freeze_embedding, + WindowRange(-hparams.window_backward, hparams.window_ahead), + hparams.key_projection, hparams.value_projection) + return model + + +def noam_learning_rate_decay(init_lr, warmup_steps=4000): + # Noam scheme from tensor2tensor: + warmup_steps = float(warmup_steps) + return dg.NoamDecay(1 / (warmup_steps * (init_lr**2)), warmup_steps) + + +def make_optimizer_from_hparams(hparams): + if hparams.lr_schedule is not None: + learning_rate = noam_learning_rate_decay(hparams.initial_learning_rate, + **hparams.lr_schedule_kwargs) + else: + learning_rate = hparams.initial_learning_rate + + if hparams.weight_decay > 0.0: + regularization = fluid.regularizer.L2DecayRegularizer( + hparams.weight_decay) + else: + regularization = None + + optim = fluid.optimizer.Adam( + learning_rate=learning_rate, + beta1=hparams.adam_beta1, + beta2=hparams.adam_beta2, + regularization=regularization) + + if hparams.clip_thresh > 0.0: + clipper = fluid.dygraph_grad_clip.GradClipByGlobalNorm( + hparams.clip_thresh) + else: + clipper = None + + return optim, clipper + + +def make_writer_from_args(args): + if args.log_event_path is None: + if platform.system() == "Windows": + log_event_path = "log/run-test" + str(datetime.now()).replace( + " ", "_").replace(":", "_") + else: + log_event_path = "log/run-test" + str(datetime.now()).replace(" ", + "_") + else: + log_event_path = args.log_event_path + print("Log event path: {}".format(log_event_path)) + writer = SummaryWriter(log_event_path) + return writer + + +def make_loss_from_hparams(hparams): + criterion = TTSLoss( + hparams.masked_loss_weight, hparams.priority_freq_weight, + hparams.binary_divergence_weight, hparams.guided_attention_sigma) + return criterion + + +class MyDataParallel(dg.parallel.DataParallel): + """ + A data parallel proxy for model. + """ + + def __init__(self, layers, strategy): + super(MyDataParallel, self).__init__(layers, strategy) + + def __getattr__(self, key): + if key in self.__dict__: + return object.__getattribute__(self, key) + elif key is "_layers": + return object.__getattribute__(self, "_sub_layers")["_layers"] + else: + return getattr( + object.__getattribute__(self, "_sub_layers")["_layers"], key) + + +if __name__ == "__main__": + parser = build_arg_parser() + args, _ = parser.parse_known_args() + + print("Command Line Args:") + for k, v in vars(args).items(): + print(" {}: {}".format(k, v)) + + # Load preset if specified + if args.preset is not None: + with open(args.preset) as f: + hparams.parse_json(f.read()) + # Override hyper parameters + hparams.parse(args.hparams) + print(hparams_debug_string()) + + data_root = args.data_root + speaker_id = args.speaker_id + X = FileSourceDataset(TextDataSource(data_root, speaker_id)) + Mel = FileSourceDataset(MelSpecDataSource(data_root, speaker_id)) + Y = FileSourceDataset(LinearSpecDataSource(data_root, speaker_id)) + + frame_lengths = Mel.file_data_source.frame_lengths + sampler = PartialyRandomizedSimilarTimeLengthSampler( + frame_lengths, batch_size=hparams.batch_size) + + dataset = Dataset(X, Mel, Y) + n_trainers = dg.parallel.Env().nranks + local_rank = dg.parallel.Env().local_rank + data_loader = make_loader( + dataset, + batch_size=hparams.batch_size, + shuffle=False, + sampler=sampler, + create_batch_fn=create_batch, + trainer_count=n_trainers, + local_rank=local_rank) + + place = (fluid.CUDAPlace(dg.parallel.Env().dev_id) + if args.use_data_parallel else fluid.CUDAPlace(0) + if args.use_gpu else fluid.CPUPlace()) + with dg.guard(place) as g: + pyreader = fluid.io.PyReader(capacity=10, return_list=True) + pyreader.decorate_batch_generator(data_loader, place) + + model = make_deepvoice3_from_hparams(hparams) + optimizer, clipper = make_optimizer_from_hparams(hparams) + writer = make_writer_from_args(args) + criterion = make_loss_from_hparams(hparams) + + # loading saved model + if args.train_postnet_only or args.train_seq2seq_only: + assert args.checkpoint is not None, \ + "you must train part of the model from a trained whole model" + if args.train_postnet_only: + assert hparams.use_decoder_state_for_postnet_input is False, \ + "when training only the postnet, there is no decoder states" + + dry_run(model) + + if args.checkpoint is not None: + load_checkpoint( + args.checkpoint, + model, + optimizer, + reset_optimizer=args.reset_optimizer) + + if args.load_embedding is not None: + _load_embedding(args.load_embedding, model) + + if args.use_data_parallel: + strategy = dg.parallel.prepare_context() + model = MyDataParallel(model, strategy) + + train_model(model, pyreader, criterion, optimizer, clipper, writer, + args, hparams) + print("Done!") diff --git a/PaddleSpeech/DeepVoice3/train_model.py b/PaddleSpeech/DeepVoice3/train_model.py new file mode 100644 index 00000000..6eb745d8 --- /dev/null +++ b/PaddleSpeech/DeepVoice3/train_model.py @@ -0,0 +1,236 @@ +# Copyright (c) 2019 PaddlePaddle 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 __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import os +from itertools import chain + +from paddle import fluid +import paddle.fluid.dygraph as dg + +from tqdm import tqdm +from deepvoice3_paddle.save_load import save_checkpoint +from eval_model import eval_model, save_states + + +def train_model(model, loader, criterion, optimizer, clipper, writer, args, + hparams): + assert fluid.framework.in_dygraph_mode( + ), "this function must be run with dygraph guard" + + local_rank = dg.parallel.Env().local_rank + + if not os.path.exists(args.checkpoint_dir): + os.mkdir(args.checkpoint_dir) + + # amount of shifting when compute losses + linear_shift = hparams.outputs_per_step + mel_shift = hparams.outputs_per_step + + global_step = 0 + global_epoch = 0 + ismultispeaker = model.n_speakers > 1 + + for epoch in range(hparams.nepochs): + epoch_loss = 0. + for step, inputs in tqdm(enumerate(loader())): + + if len(inputs) == 9: + (text, input_lengths, mel, linear, text_positions, + frame_positions, done, target_lengths, speaker_ids) = inputs + else: + (text, input_lengths, mel, linear, text_positions, + frame_positions, done, target_lengths) = inputs + speaker_ids = None + + model.train() + if not (args.train_seq2seq_only or args.train_postnet_only): + results = model(text, input_lengths, mel, speaker_ids, + text_positions, frame_positions) + mel_outputs, linear_outputs, alignments, done_hat = results + elif args.train_seq2seq_only: + + if speaker_ids is not None: + speaker_embed = model.speaker_embedding(speaker_ids) + else: + speaker_embed = None + results = model.seq2seq(text, input_lengths, mel, speaker_embed, + text_positions, frame_positions) + mel_outputs, alignments, done_hat, decoder_states = results + if model.r > 1: + mel_outputs = fluid.layers.transpose(mel_outputs, + [0, 3, 2, 1]) + mel_outputs = fluid.layers.reshape( + mel_outputs, + [mel_outputs.shape[0], -1, 1, model.mel_dim]) + mel_outputs = fluid.layers.transpose(mel_outputs, + [0, 3, 2, 1]) + + linear_outputs = None + else: + assert ( + model.use_decoder_state_for_postnet_input is False + ), "when train only the converter, you have no decoder states" + + if speaker_ids is not None: + speaker_embed = model.speaker_embedding(speaker_ids) + else: + speaker_embed = None + linear_outputs = model.converter(mel, speaker_embed) + alignments = None + mel_outputs = None + done_hat = None + + if not args.train_seq2seq_only: + n_priority_freq = int(hparams.priority_freq / + (hparams.sample_rate * 0.5) * + model.linear_dim) + linear_mask = fluid.layers.sequence_mask( + target_lengths, maxlen=linear.shape[-1], dtype="float32") + linear_mask = linear_mask[:, linear_shift:] + linear_predicted = linear_outputs[:, :, :, :-linear_shift] + linear_target = linear[:, :, :, linear_shift:] + lin_l1_loss = criterion.l1_loss( + linear_predicted, + linear_target, + linear_mask, + priority_bin=n_priority_freq) + lin_div = criterion.binary_divergence( + linear_predicted, linear_target, linear_mask) + lin_loss = criterion.binary_divergence_weight * lin_div \ + + (1 - criterion.binary_divergence_weight) * lin_l1_loss + if writer is not None: + writer.add_scalar("linear_loss", + float(lin_loss.numpy()), global_step) + writer.add_scalar("linear_l1_loss", + float(lin_l1_loss.numpy()), global_step) + writer.add_scalar("linear_binary_div_loss", + float(lin_div.numpy()), global_step) + + if not args.train_postnet_only: + mel_lengths = target_lengths // hparams.downsample_step + mel_mask = fluid.layers.sequence_mask( + mel_lengths, maxlen=mel.shape[-1], dtype="float32") + mel_mask = mel_mask[:, mel_shift:] + mel_predicted = mel_outputs[:, :, :, :-mel_shift] + mel_target = mel[:, :, :, mel_shift:] + mel_l1_loss = criterion.l1_loss(mel_predicted, mel_target, + mel_mask) + mel_div = criterion.binary_divergence(mel_predicted, mel_target, + mel_mask) + mel_loss = criterion.binary_divergence_weight * mel_div \ + + (1 - criterion.binary_divergence_weight) * mel_l1_loss + if writer is not None: + writer.add_scalar("mel_loss", + float(mel_loss.numpy()), global_step) + writer.add_scalar("mel_l1_loss", + float(mel_l1_loss.numpy()), global_step) + writer.add_scalar("mel_binary_div_loss", + float(mel_div.numpy()), global_step) + + done_loss = criterion.done_loss(done_hat, done) + if writer is not None: + writer.add_scalar("done_loss", + float(done_loss.numpy()), global_step) + + if hparams.use_guided_attention: + decoder_length = target_lengths.numpy() / ( + hparams.outputs_per_step * hparams.downsample_step) + attn_loss = criterion.attention_loss(alignments, + input_lengths.numpy(), + decoder_length) + if writer is not None: + writer.add_scalar("attention_loss", + float(attn_loss.numpy()), global_step) + + if not (args.train_seq2seq_only or args.train_postnet_only): + if hparams.use_guided_attention: + loss = lin_loss + mel_loss + done_loss + attn_loss + else: + loss = lin_loss + mel_loss + done_loss + elif args.train_seq2seq_only: + if hparams.use_guided_attention: + loss = mel_loss + done_loss + attn_loss + else: + loss = mel_loss + done_loss + else: + loss = lin_loss + if writer is not None: + writer.add_scalar("loss", float(loss.numpy()), global_step) + + if isinstance(optimizer._learning_rate, + fluid.optimizer.LearningRateDecay): + current_lr = optimizer._learning_rate.step().numpy() + else: + current_lr = optimizer._learning_rate + writer.add_scalar("learning_rate", current_lr, global_step) + + epoch_loss += loss.numpy()[0] + + if (local_rank == 0 and global_step > 0 and + global_step % hparams.checkpoint_interval == 0): + save_states(global_step, writer, mel_outputs, linear_outputs, + alignments, mel, linear, + input_lengths.numpy(), args.checkpoint_dir) + save_checkpoint(model, optimizer, args.checkpoint_dir, + global_step) + + if (local_rank == 0 and global_step > 0 and + global_step % hparams.eval_interval == 0): + eval_model(global_step, writer, model, args.checkpoint_dir, + ismultispeaker) + + if args.use_data_parallel: + loss = model.scale_loss(loss) + loss.backward() + model.apply_collective_grads() + else: + loss.backward() + + if not (args.train_seq2seq_only or args.train_postnet_only): + param_list = model.parameters() + elif args.train_seq2seq_only: + if ismultispeaker: + param_list = chain(model.speaker_embedding.parameters(), + model.seq2seq.parameters()) + else: + param_list = model.seq2seq.parameters() + else: + if ismultispeaker: + param_list = chain(model.speaker_embedding.parameters(), + model.seq2seq.parameters()) + else: + param_list = model.converter.parameters() + + optimizer.minimize( + loss, grad_clip=clipper, parameter_list=param_list) + + if not (args.train_seq2seq_only or args.train_postnet_only): + model.clear_gradients() + elif args.train_seq2seq_only: + if ismultispeaker: + model.speaker_embedding.clear_gradients() + model.seq2seq.clear_gradients() + else: + if ismultispeaker: + model.speaker_embedding.clear_gradients() + model.converter.clear_gradients() + + global_step += 1 + + global_epoch += 1 + print("Epoch loss: {}".format(epoch_loss / (step + 1))) -- GitLab