diff --git a/Jenkinsfile b/Jenkinsfile
index 178d2a2b2144..6ba65f340eab 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -137,18 +137,18 @@ pipeline {
parallel {
stage('En TN grammars') {
steps {
- sh 'CUDA_VISIBLE_DEVICES="" python nemo_text_processing/text_normalization/normalize.py --text="1" --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22'
+ sh 'CUDA_VISIBLE_DEVICES="" python nemo_text_processing/text_normalization/normalize.py --text="1" --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22'
}
}
stage('En ITN grammars') {
steps {
- sh 'CUDA_VISIBLE_DEVICES="" python nemo_text_processing/inverse_text_normalization/inverse_normalize.py --language en --text="twenty" --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22'
+ sh 'CUDA_VISIBLE_DEVICES="" python nemo_text_processing/inverse_text_normalization/inverse_normalize.py --language en --text="twenty" --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22'
}
}
stage('Test En non-deterministic TN & Run all En TN/ITN tests (restore grammars from cache)') {
steps {
- sh 'CUDA_VISIBLE_DEVICES="" python nemo_text_processing/text_normalization/normalize_with_audio.py --text "\$.01" --n_tagged 2 --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22'
- sh 'CUDA_VISIBLE_DEVICES="" pytest tests/nemo_text_processing/en/ -m "not pleasefixme" --cpu --tn_cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22'
+ sh 'CUDA_VISIBLE_DEVICES="" python nemo_text_processing/text_normalization/normalize_with_audio.py --text "\$.01" --n_tagged 2 --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22'
+ sh 'CUDA_VISIBLE_DEVICES="" pytest tests/nemo_text_processing/en/ -m "not pleasefixme" --cpu --tn_cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22'
}
}
}
@@ -165,7 +165,7 @@ pipeline {
parallel {
stage('L2: Eng TN') {
steps {
- sh 'cd tools/text_processing_deployment && python pynini_export.py --output=/home/TestData/nlp/text_norm/output/ --grammars=tn_grammars --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22 --language=en && ls -R /home/TestData/nlp/text_norm/output/ && echo ".far files created "|| exit 1'
+ sh 'cd tools/text_processing_deployment && python pynini_export.py --output=/home/TestData/nlp/text_norm/output/ --grammars=tn_grammars --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22 --language=en && ls -R /home/TestData/nlp/text_norm/output/ && echo ".far files created "|| exit 1'
sh 'cd nemo_text_processing/text_normalization/ && python normalize.py --input_file=/home/TestData/nlp/text_norm/ci/test.txt --input_case="lower_cased" --language=en --output_file=/home/TestData/nlp/text_norm/output/test.pynini.txt --verbose'
sh 'cat /home/TestData/nlp/text_norm/output/test.pynini.txt'
sh 'cmp --silent /home/TestData/nlp/text_norm/output/test.pynini.txt /home/TestData/nlp/text_norm/ci/test_goal_py_05-25.txt || exit 1'
@@ -175,7 +175,7 @@ pipeline {
stage('L2: Eng ITN export') {
steps {
- sh 'cd tools/text_processing_deployment && python pynini_export.py --output=/home/TestData/nlp/text_denorm/output/ --grammars=itn_grammars --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22 --language=en && ls -R /home/TestData/nlp/text_denorm/output/ && echo ".far files created "|| exit 1'
+ sh 'cd tools/text_processing_deployment && python pynini_export.py --output=/home/TestData/nlp/text_denorm/output/ --grammars=itn_grammars --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22 --language=en && ls -R /home/TestData/nlp/text_denorm/output/ && echo ".far files created "|| exit 1'
sh 'cd nemo_text_processing/inverse_text_normalization/ && python inverse_normalize.py --input_file=/home/TestData/nlp/text_denorm/ci/test.txt --language=en --output_file=/home/TestData/nlp/text_denorm/output/test.pynini.txt --verbose'
sh 'cmp --silent /home/TestData/nlp/text_denorm/output/test.pynini.txt /home/TestData/nlp/text_denorm/ci/test_goal_py.txt || exit 1'
sh 'rm -rf /home/TestData/nlp/text_denorm/output/*'
@@ -184,7 +184,7 @@ pipeline {
stage('L2: TN with Audio (audio and raw text)') {
steps {
sh 'cd nemo_text_processing/text_normalization && \
- python normalize_with_audio.py --language=en --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22 --text "The total amounts to \\$4.76." \
+ python normalize_with_audio.py --language=en --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22 --text "The total amounts to \\$4.76." \
--audio_data /home/TestData/nlp/text_norm/audio_based/audio.wav | tail -n2 | head -n1 > /tmp/out_raw.txt 2>&1 && \
cmp --silent /tmp/out_raw.txt /home/TestData/nlp/text_norm/audio_based/result.txt || exit 1'
}
@@ -192,7 +192,7 @@ pipeline {
stage('L2: TN with Audio (audio and text file)') {
steps {
sh 'cd nemo_text_processing/text_normalization && \
- python normalize_with_audio.py --language=en --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22 --text /home/TestData/nlp/text_norm/audio_based/text.txt \
+ python normalize_with_audio.py --language=en --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22 --text /home/TestData/nlp/text_norm/audio_based/text.txt \
--audio_data /home/TestData/nlp/text_norm/audio_based/audio.wav | tail -n2 | head -n1 > /tmp/out_file.txt 2>&1 && \
cmp --silent /tmp/out_file.txt /home/TestData/nlp/text_norm/audio_based/result.txt || exit 1'
}
@@ -200,7 +200,7 @@ pipeline {
stage('L2: TN with Audio (manifest)') {
steps {
sh 'cd nemo_text_processing/text_normalization && \
- python normalize_with_audio.py --language=en --audio_data /home/TestData/nlp/text_norm/audio_based/manifest.json --n_tagged=120 --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-14-22'
+ python normalize_with_audio.py --language=en --audio_data /home/TestData/nlp/text_norm/audio_based/manifest.json --n_tagged=120 --cache_dir /home/TestData/nlp/text_norm/ci/grammars/6-28-22'
}
}
}
@@ -2129,7 +2129,7 @@ pipeline {
model.num_attention_heads=8 \
model.activation='swiglu' \
model.masked_softmax_fusion=False \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.micro_batch_size=2 \
@@ -2161,7 +2161,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='swiglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.masked_softmax_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
@@ -2893,7 +2893,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='swiglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.transformer_block_type='pre_ln' \
@@ -2918,7 +2918,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='swiglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.transformer_block_type='pre_ln' \
@@ -3015,7 +3015,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='swiglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.transformer_block_type='normformer' \
@@ -3040,7 +3040,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='swiglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.transformer_block_type='normformer' \
@@ -3094,7 +3094,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='reglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.data.data_prefix=[.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document,.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document]"
@@ -3116,7 +3116,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='reglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.data.data_prefix=[.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document,.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document]"
@@ -3150,7 +3150,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='geglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.data.data_prefix=[.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document,.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document]"
@@ -3173,7 +3173,7 @@ pipeline {
model.hidden_size=64 \
model.num_attention_heads=8 \
model.activation='geglu' \
- model.bias_gelu_fusion=False \
+ model.bias_activation_fusion=False \
model.activations_checkpoint_method='block' \
model.activations_checkpoint_num_layers=1 \
model.data.data_prefix=[.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document,.5,/home/TestData/nlp/megatron_t5/data/pile_val_small_bert_tokenizer_text_document]"
diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css
index a071bc424c60..16fc8d3b469f 100644
--- a/docs/source/_static/css/custom.css
+++ b/docs/source/_static/css/custom.css
@@ -2,55 +2,53 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400&display=swap');
body {
- font-size: 100%;
- font-family: 'Roboto', sans-serif;
+ font-size: 100%;
+ font-family: 'Roboto', sans-serif;
}
/* Width of template */
.wy-nav-content {
- max-width: 1200px !important;
+ max-width: 1200px !important;
}
/* Standard Text Formatting */
-h1
-{
+h1 {
color: #76b900;
- text-align: center;
+ text-align: center;
background-color: #ffffff;
}
-h2
-{
+h2 {
color: #ffffff;
- background-color: #ffffff; /* #76b900 */
- Padding: 5px;
+ background-color: #ffffff;
+ /* #76b900 */
+ Padding: 5px;
}
-h3
-{
+h3 {
padding-top: 0px;
- border-top: solid 3px #000000; /* #76b900 */
- border-bottom: solid 3px #000000; /* #76b900 */
+ border-top: solid 3px #000000;
+ /* #76b900 */
+ border-bottom: solid 3px #000000;
+ /* #76b900 */
}
-p
-{
+p {
margin-bottom: 24px;
}
+
/* Link Colors */
-a
-{
- color: #76b900;
+a {
+ color: #76b900;
}
-a:visited
-{
- color: #218219;
+a:visited {
+ color: #218219;
}
.container-xl {
@@ -73,56 +71,52 @@ table {
}
/* Table head Color */
-thead td
-{
+thead td {
background-color: #333333 !important;
}
-.row-odd p
-{
+.row-odd p {
/*padding-bottom: 0px;*/
/*margin-bottom: 0px;*/
}
+
/* even rows*/
-.row-even tr
-{
- background-color: #e5f1e6 !important;
+.row-even tr {
+ background-color: #e5f1e6 !important;
}
/* odd rows*/
.wy-table-responsive table tr {
- background-color: #ffffff !important;
+ background-color: #ffffff !important;
}
.wy-table-responsive table td {
- white-space: normal;
+ white-space: normal;
}
/* Removes bottom margin in tables*/
.rst-content .line-block {
- margin-bottom: 0px;
+ margin-bottom: 0px;
}
.wy-table-responsive {
- overflow: visible !important;
+ overflow: visible !important;
}
/* reduces the size of text in multiline table columns. */
-.rst-content table.docutils td
-{
- font-size: 80%;
+.rst-content table.docutils td {
+ font-size: 80%;
}
-.rst-content dl:not(.docutils) dt
-{
+.rst-content dl:not(.docutils) dt {
background-color: inherit;
color: #000000;
@@ -131,100 +125,130 @@ thead td
}
.rst-content dl:not(.docutils) dt:before {
- color: #333333;
+ color: #333333;
}
.rst-content .line-block {
- margin-bottom: 0px;
+ margin-bottom: 0px;
}
-.wy-side-nav-search, .wy-nav-top
- {
- background-color: #000000;
- padding: 0;
- }
+.wy-side-nav-search,
+.wy-nav-top {
+ background-color: #000000;
+ padding: 0;
+}
-.wy-side-nav-search img
- {
- padding: 0px;
- padding: 0px 0px;
- margin-bottom: 0;
- }
+.wy-side-nav-search img {
+ padding: 0px;
+ padding: 0px 0px;
+ margin-bottom: 0;
+}
-.wy-side-nav-search input[type=text]
- {
- border-radius: 0px;
- }
+.wy-side-nav-search input[type=text] {
+ border-radius: 0px;
+}
-.wy-menu-vertical p.caption
- {
+.wy-menu-vertical p.caption {
color: #76b900;
- }
+}
-.wy-side-nav-search>a img.logo, .wy-side-nav-search .wy-dropdown>a img.logo
- {
+.wy-side-nav-search>a img.logo,
+.wy-side-nav-search .wy-dropdown>a img.logo {
margin: 0px 0px 0px 0px;
- }
+}
-.wy-nav-content
- {
- margin: 0;
- min-height: 100%;
- height: 100%;
- background: #ffffff;
- }
+.wy-nav-content {
+ margin: 0;
+ min-height: 100%;
+ height: 100%;
+ background: #ffffff;
+}
- /* List (numbered, bulleted) padding Fix */
+/* List (numbered, bulleted) padding Fix */
-.wy-plain-list-decimal li
-{
- margin-top: -6px;
- margin-bottom: -6px;
+.wy-plain-list-decimal li {
+ margin-top: -6px;
+ margin-bottom: -6px;
}
-.rst-content .section ol.loweralpha
-{
- margin-top: -6px;
- margin-bottom: 12px;
+.rst-content .section ol.loweralpha {
+ margin-top: -6px;
+ margin-bottom: 12px;
}
-.wy-plain-list-disc, .rst-content .toctree-wrapper ul, article ul
-{
- margin-top: 0px !important;
- margin-bottom: 12px;
+.wy-plain-list-disc,
+.rst-content .toctree-wrapper ul,
+article ul {
+ margin-top: 0px !important;
+ margin-bottom: 12px;
}
- /* Alert Boxes */
- /* Background color of Alert Box Title */
+/* Alert Boxes */
+/* Background color of Alert Box Title */
-.rst-content .section ul
-{
- margin-top: -12px;
- margin-bottom: 16px;
+.rst-content .section ul {
+ margin-top: -12px;
+ margin-bottom: 16px;
}
-.wy-alert.wy-alert-info .wy-alert-title, .rst-content .note .wy-alert-title, .rst-content .wy-alert-info.attention .wy-alert-title, .rst-content .wy-alert-info.caution .wy-alert-title, .rst-content .wy-alert-info.danger .wy-alert-title, .rst-content .wy-alert-info.error .wy-alert-title, .rst-content .wy-alert-info.hint .wy-alert-title, .rst-content .wy-alert-info.important .wy-alert-title, .rst-content .wy-alert-info.tip .wy-alert-title, .rst-content .wy-alert-info.warning .wy-alert-title, .rst-content .seealso .wy-alert-title, .rst-content .wy-alert-info.admonition-todo .wy-alert-title, .rst-content .wy-alert-info.admonition .wy-alert-title, .wy-alert.wy-alert-info .rst-content .admonition-title, .rst-content .wy-alert.wy-alert-info .admonition-title, .rst-content .note .admonition-title, .rst-content .wy-alert-info.attention .admonition-title, .rst-content .wy-alert-info.caution .admonition-title, .rst-content .wy-alert-info.danger .admonition-title, .rst-content .wy-alert-info.error .admonition-title, .rst-content .wy-alert-info.hint .admonition-title, .rst-content .wy-alert-info.important .admonition-title, .rst-content .wy-alert-info.tip .admonition-title, .rst-content .wy-alert-info.warning .admonition-title, .rst-content .seealso .admonition-title, .rst-content .wy-alert-info.admonition-todo .admonition-title, .rst-content .wy-alert-info.admonition .admonition-title
- {
+.wy-alert.wy-alert-info .wy-alert-title,
+.rst-content .note .wy-alert-title,
+.rst-content .wy-alert-info.attention .wy-alert-title,
+.rst-content .wy-alert-info.caution .wy-alert-title,
+.rst-content .wy-alert-info.danger .wy-alert-title,
+.rst-content .wy-alert-info.error .wy-alert-title,
+.rst-content .wy-alert-info.hint .wy-alert-title,
+.rst-content .wy-alert-info.important .wy-alert-title,
+.rst-content .wy-alert-info.tip .wy-alert-title,
+.rst-content .wy-alert-info.warning .wy-alert-title,
+.rst-content .seealso .wy-alert-title,
+.rst-content .wy-alert-info.admonition-todo .wy-alert-title,
+.rst-content .wy-alert-info.admonition .wy-alert-title,
+.wy-alert.wy-alert-info .rst-content .admonition-title,
+.rst-content .wy-alert.wy-alert-info .admonition-title,
+.rst-content .note .admonition-title,
+.rst-content .wy-alert-info.attention .admonition-title,
+.rst-content .wy-alert-info.caution .admonition-title,
+.rst-content .wy-alert-info.danger .admonition-title,
+.rst-content .wy-alert-info.error .admonition-title,
+.rst-content .wy-alert-info.hint .admonition-title,
+.rst-content .wy-alert-info.important .admonition-title,
+.rst-content .wy-alert-info.tip .admonition-title,
+.rst-content .wy-alert-info.warning .admonition-title,
+.rst-content .seealso .admonition-title,
+.rst-content .wy-alert-info.admonition-todo .admonition-title,
+.rst-content .wy-alert-info.admonition .admonition-title {
background: #76b900;
- }
+}
- /* Background and Font Color of Alert Box Main Body*/
-.wy-alert.wy-alert-info, .rst-content .note, .rst-content .wy-alert-info.attention, .rst-content .wy-alert-info.caution, .rst-content .wy-alert-info.danger, .rst-content .wy-alert-info.error, .rst-content .wy-alert-info.hint, .rst-content .wy-alert-info.important, .rst-content .wy-alert-info.tip, .rst-content .wy-alert-info.warning, .rst-content .seealso, .rst-content .wy-alert-info.admonition-todo, .rst-content .wy-alert-info.admonition {
- background: #333333;
- color: #999999;
- }
+/* Background and Font Color of Alert Box Main Body*/
+.wy-alert.wy-alert-info,
+.rst-content .note,
+.rst-content .wy-alert-info.attention,
+.rst-content .wy-alert-info.caution,
+.rst-content .wy-alert-info.danger,
+.rst-content .wy-alert-info.error,
+.rst-content .wy-alert-info.hint,
+.rst-content .wy-alert-info.important,
+.rst-content .wy-alert-info.tip,
+.rst-content .wy-alert-info.warning,
+.rst-content .seealso,
+.rst-content .wy-alert-info.admonition-todo,
+.rst-content .wy-alert-info.admonition {
+ background: #333333;
+ color: #999999;
+}
-.section
-{
+.section {
margin-top: 50px;
}
/* Logo */
.navbar-brand-box {
- background-color: #ffffff;
+ background-color: #ffffff;
}
/* ---------------------------------------------- Media Queries --------------------------------------- */
@@ -238,7 +262,7 @@ thead td
body {
font-size: 18px;
}
-
+
#site-navigation nav ul.nav {
font-size: 18px;
}
@@ -254,7 +278,7 @@ thead td
.toc-h2 {
font-size: 18px;
}
-
+
.toc-h3 {
font-size: 1rem;
}
@@ -267,8 +291,8 @@ thead td
font-size: 18px;
}
- #main-content > div {
+ #main-content>div {
margin-left: 10%;
margin-right: 10%;
}
-}
+}
\ No newline at end of file
diff --git a/examples/nlp/language_modeling/conf/megatron_bart_config.yaml b/examples/nlp/language_modeling/conf/megatron_bart_config.yaml
index fb8094842ca3..03bc6466f1e6 100644
--- a/examples/nlp/language_modeling/conf/megatron_bart_config.yaml
+++ b/examples/nlp/language_modeling/conf/megatron_bart_config.yaml
@@ -63,12 +63,15 @@ model:
init_method_std: 0.02 # Standard deviation of the zero mean normal distribution used for weight initialization.')
hidden_dropout: 0.1 # Dropout probability for hidden state transformer.
attention_dropout: 0.1 # Dropout probability in the attention layer.
+ position_embedding_type: 'learned_absolute' # Position embedding type. Options ['learned_absolute', 'relative']
+ relative_attention_num_buckets: 32 # Relative position number of buckets for computing the bias
+ relative_attention_max_distance: 128 # max_distance to keep relative distance in the attention_num_buckets.
kv_channels: null # Projection weights dimension in multi-head attention. Set to hidden_size // num_attention_heads if null
apply_query_key_layer_scaling: True # scale Q * K^T by 1 / layer-number.
layernorm_epsilon: 1e-5
persist_layer_norm: True # Use of persistent fused layer norm kernel.
gradient_as_bucket_view: True # Allocate gradients in a contiguous bucket to save memory (less fragmentation and buffer memory)
- bias_gelu_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent gelu activation.
+ bias_activation_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent activation function.
masked_softmax_fusion: True # Use a kernel that fuses the attention softmax with it's mask.
bias_dropout_add_fusion: True # Use a kernel that fuses the bias addition, dropout and residual connection addition.
bias: True # Whether to use bias terms in all weight matrices.
diff --git a/examples/nlp/language_modeling/conf/megatron_retro_config.yaml b/examples/nlp/language_modeling/conf/megatron_retro_config.yaml
index 3cb87bb19c52..3b99d2ad904d 100644
--- a/examples/nlp/language_modeling/conf/megatron_retro_config.yaml
+++ b/examples/nlp/language_modeling/conf/megatron_retro_config.yaml
@@ -59,7 +59,7 @@ model:
layernorm_epsilon: 1e-5
gradient_as_bucket_view: True # Allocate gradients in a contiguous bucket to save memory (less fragmentation and buffer memory)
persist_layer_norm: False
- bias_gelu_fusion: True
+ bias_activation_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent activation function.
bias_dropout_add_fusion: True
masked_softmax_fusion: True
activation: 'gelu'
diff --git a/examples/nlp/language_modeling/conf/megatron_t5_config.yaml b/examples/nlp/language_modeling/conf/megatron_t5_config.yaml
index d3f8f402bdb2..df8010fa6258 100644
--- a/examples/nlp/language_modeling/conf/megatron_t5_config.yaml
+++ b/examples/nlp/language_modeling/conf/megatron_t5_config.yaml
@@ -72,7 +72,6 @@ model:
layernorm_epsilon: 1e-5
persist_layer_norm: True # Use of persistent fused layer norm kernel.
gradient_as_bucket_view: True # Allocate gradients in a contiguous bucket to save memory (less fragmentation and buffer memory)
- bias_gelu_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent gelu activation.
bias_activation_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent activation function.
grad_div_ar_fusion: True # Fuse grad division into torch.distributed.all_reduce
masked_softmax_fusion: True # Use a kernel that fuses the attention softmax with it's mask.
diff --git a/examples/nlp/language_modeling/conf/megatron_t5_lm_adaptation_finetune.yaml b/examples/nlp/language_modeling/conf/megatron_t5_lm_adaptation_finetune.yaml
index c499e9d76bcf..d3860e9957c0 100644
--- a/examples/nlp/language_modeling/conf/megatron_t5_lm_adaptation_finetune.yaml
+++ b/examples/nlp/language_modeling/conf/megatron_t5_lm_adaptation_finetune.yaml
@@ -53,7 +53,7 @@ model:
megatron_amp_O2: False # use AMP with O2 style mixed precision instead of native amp on-the-fly weight autocasting.
# JIT fusion params.
- bias_gelu_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent gelu activation.
+ bias_activation_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent activation function.
masked_softmax_fusion: True # Use a kernel that fuses the attention softmax with it's mask.
bias_dropout_add_fusion: True # Use a kernel that fuses the bias addition, dropout and residual connection addition.
diff --git a/examples/nlp/language_modeling/conf/megatron_ul2_config.yaml b/examples/nlp/language_modeling/conf/megatron_ul2_config.yaml
index 20cd172e460c..113f2a6961af 100644
--- a/examples/nlp/language_modeling/conf/megatron_ul2_config.yaml
+++ b/examples/nlp/language_modeling/conf/megatron_ul2_config.yaml
@@ -62,12 +62,15 @@ model:
init_method_std: 0.02 # Standard deviation of the zero mean normal distribution used for weight initialization.')
hidden_dropout: 0.1 # Dropout probability for hidden state transformer.
attention_dropout: 0.1 # Dropout probability in the attention layer.
+ position_embedding_type: 'learned_absolute' # Position embedding type. Options ['learned_absolute', 'relative']
+ relative_attention_num_buckets: 32 # Relative position number of buckets for computing the bias
+ relative_attention_max_distance: 128 # max_distance to keep relative distance in the attention_num_buckets.
kv_channels: null # Projection weights dimension in multi-head attention. Set to hidden_size // num_attention_heads if null
apply_query_key_layer_scaling: True # scale Q * K^T by 1 / layer-number.
layernorm_epsilon: 1e-5
persist_layer_norm: True # Use of persistent fused layer norm kernel.
gradient_as_bucket_view: True # Allocate gradients in a contiguous bucket to save memory (less fragmentation and buffer memory)
- bias_gelu_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent gelu activation.
+ bias_activation_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent activation function.
masked_softmax_fusion: True # Use a kernel that fuses the attention softmax with it's mask.
bias_dropout_add_fusion: True # Use a kernel that fuses the bias addition, dropout and residual connection addition.
bias: True # Whether to use bias terms in all weight matrices.
diff --git a/examples/nlp/machine_translation/conf/aayn_base_megatron.yaml b/examples/nlp/machine_translation/conf/aayn_base_megatron.yaml
index d85946287e2d..286bfaf6d8d7 100644
--- a/examples/nlp/machine_translation/conf/aayn_base_megatron.yaml
+++ b/examples/nlp/machine_translation/conf/aayn_base_megatron.yaml
@@ -73,12 +73,15 @@ model:
init_method_std: 0.02 # Standard deviation of the zero mean normal distribution used for weight initialization.')
hidden_dropout: 0.1 # Dropout probability for hidden state transformer.
attention_dropout: 0.1 # Dropout probability in the attention layer.
+ position_embedding_type: 'learned_absolute' # Position embedding type. Options ['learned_absolute', 'relative']
+ relative_attention_num_buckets: 32 # Relative position number of buckets for computing the bias
+ relative_attention_max_distance: 128 # max_distance to keep relative distance in the attention_num_buckets.
kv_channels: null # Projection weights dimension in multi-head attention. Set to hidden_size // num_attention_heads if null
apply_query_key_layer_scaling: True # scale Q * K^T by 1 / layer-number.
layernorm_epsilon: 1e-5
persist_layer_norm: True # Use of persistent fused layer norm kernel.
gradient_as_bucket_view: True # Allocate gradients in a contiguous bucket to save memory (less fragmentation and buffer memory)
- bias_gelu_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent gelu activation.
+ bias_activation_fusion: True # Use a kernel that fuses the bias addition from weight matrices with the subsequent activation function.
masked_softmax_fusion: True # Use a kernel that fuses the attention softmax with it's mask.
bias_dropout_add_fusion: True # Use a kernel that fuses the bias addition, dropout and residual connection addition.
bias: True # Whether to use bias terms in all weight matrices.
diff --git a/examples/tts/conf/de/fastpitch_align_22050.yaml b/examples/tts/conf/de/fastpitch_align_22050.yaml
index d12ca3d2478d..2ba41b6fef1e 100644
--- a/examples/tts/conf/de/fastpitch_align_22050.yaml
+++ b/examples/tts/conf/de/fastpitch_align_22050.yaml
@@ -202,7 +202,7 @@ model:
optim:
name: adamw
- lr: 1e-1
+ lr: 1e-3
# optimizer arguments
betas: [0.9, 0.999]
weight_decay: 1e-6
diff --git a/nemo/collections/common/metrics/classification_accuracy.py b/nemo/collections/common/metrics/classification_accuracy.py
index db746b869001..eca7379a382e 100644
--- a/nemo/collections/common/metrics/classification_accuracy.py
+++ b/nemo/collections/common/metrics/classification_accuracy.py
@@ -154,7 +154,7 @@ def compute_topk_accuracy(correct_counts_k, total_counts_k):
class ExactStringPerCategoryMatchMetric(Metric):
- def __init__(self, categories=[], dist_sync_on_step=False):
+ def __init__(self, categories=[], dist_sync_on_step=False, **kwargs):
super().__init__(dist_sync_on_step=dist_sync_on_step)
self.categories = set(categories)
@@ -190,7 +190,7 @@ def compute(self):
class ExactStringMatchMetric(Metric):
- def __init__(self, dist_sync_on_step=False):
+ def __init__(self, dist_sync_on_step=False, **kwargs):
super().__init__(dist_sync_on_step=dist_sync_on_step)
self.add_state("correct", default=torch.tensor(0), dist_reduce_fx="sum")
diff --git a/nemo/collections/nlp/models/language_modeling/megatron_lm_encoder_decoder_model.py b/nemo/collections/nlp/models/language_modeling/megatron_lm_encoder_decoder_model.py
index cad504e04a28..6fa4e9d0129e 100644
--- a/nemo/collections/nlp/models/language_modeling/megatron_lm_encoder_decoder_model.py
+++ b/nemo/collections/nlp/models/language_modeling/megatron_lm_encoder_decoder_model.py
@@ -69,6 +69,10 @@ class MegatronLMEncoderDecoderModel(MegatronBaseModel):
def __init__(self, cfg: DictConfig, trainer: Trainer):
super().__init__(cfg, trainer=trainer)
+ if cfg.get('pipeline_model_parallel_size', 1) > 2 and self.cfg.get('position_embedding_type') == 'relative':
+ raise ValueError(
+ "pipeline_model_parallel_size cannot be > 2 with position_embedding_type == relative at the moment."
+ )
if cfg.get('pipeline_model_parallel_size', 1) > 1:
if cfg.get('pipeline_model_parallel_split_rank', 0) <= 0:
raise ValueError(
@@ -116,7 +120,11 @@ def setup_optimizer_param_groups(self):
def model_provider_func(self, pre_process, post_process, add_encoder, add_decoder):
# TODO: create get_encoder_decoder_model()here for different losses (e..g, nll, vae, mim)
-
+ if hasattr(self.cfg, 'bias_gelu_fusion'):
+ logging.warning('bias_gelu_fusion is deprecated. Please use bias_activation_fusion instead.')
+ activation_fusion = self.cfg.bias_gelu_fusion
+ else:
+ activation_fusion = self.cfg.get('bias_activation_fusion', True)
model = MegatronTokenLevelEncoderDecoderModule(
encoder_arch=self.cfg.encoder_arch,
decoder_arch=self.cfg.decoder_arch,
@@ -146,10 +154,7 @@ def model_provider_func(self, pre_process, post_process, add_encoder, add_decode
activations_checkpoint_num_layers=self.cfg.get('activations_checkpoint_num_layers', 1),
layernorm_epsilon=self.cfg.get('layernorm_epsilon', 1e-5),
persist_layer_norm=self.cfg.get('persist_layer_norm', False),
- bias_activation_fusion=(
- (self.cfg.get('bias_gelu_fusion', True) and self.cfg.get('activation', 'gelu') == 'gelu')
- or (self.cfg.get('bias_activation_fusion', True) and self.cfg.get('activation', 'gelu') == 'geglu')
- ),
+ bias_activation_fusion=activation_fusion,
bias_dropout_add_fusion=self.cfg.get('bias_dropout_add_fusion', True),
masked_softmax_fusion=self.cfg.get('masked_softmax_fusion', True),
onnx_safe=self.cfg.get('onnx_safe', False),
@@ -393,7 +398,7 @@ def allreduce_word_and_position_embeddings(self):
and parallel_state.get_pipeline_model_parallel_world_size() > 1
and parallel_state.get_pipeline_model_parallel_split_rank() is not None
):
- if self.enc_dec_model.position_embedding_type != 'relative':
+ if self.cfg.get('position_embedding_type') != 'relative':
position_embeddings_weight = self.enc_dec_model.position_embeddings_weight()
if self.megatron_amp_o2:
grad = position_embeddings_weight.main_grad
@@ -706,7 +711,7 @@ def setup(self, stage=None):
# when using pipeline model parallel the final stage need to initialize word embeddings
if parallel_state.get_pipeline_model_parallel_world_size() > 1:
self.enc_dec_model.sync_initial_word_embeddings()
- if self.enc_dec_model.position_embedding_type != 'relative':
+ if self.cfg.get('position_embedding_type') != 'relative':
self.enc_dec_model.sync_initial_position_embeddings()
def setup_training_data(self, cfg):
@@ -837,12 +842,12 @@ def dummy():
torch.distributed.broadcast(
predicted_tokens_dec,
parallel_state.get_pipeline_model_parallel_last_rank(),
- group=parallel_state.get_model_parallel_group(),
+ group=parallel_state.get_pipeline_model_parallel_group(),
)
torch.distributed.broadcast(
log_probs,
parallel_state.get_pipeline_model_parallel_last_rank(),
- group=parallel_state.get_model_parallel_group(),
+ group=parallel_state.get_pipeline_model_parallel_group(),
)
# Reset microbatch calculator to what it was before decoding.
diff --git a/nemo/collections/nlp/modules/common/megatron/transformer.py b/nemo/collections/nlp/modules/common/megatron/transformer.py
index 6fc77f01c27a..d1cdf7eb2211 100644
--- a/nemo/collections/nlp/modules/common/megatron/transformer.py
+++ b/nemo/collections/nlp/modules/common/megatron/transformer.py
@@ -159,19 +159,20 @@ def __init__(
bias=bias,
)
- glu_activation_family = activation in ['reglu', 'swiglu']
+ self.glu_activation_family = activation in ['geglu', 'reglu', 'swiglu']
+ bias_activation_fusion_unavailable = activation in ['reglu', 'swiglu']
- if glu_activation_family and bias_activation_fusion:
+ if bias_activation_fusion_unavailable and bias_activation_fusion:
raise ValueError(
f"Cannot use bias_activation_fusion with {activation} activation. Please turn bias gelu fusion off."
)
- if glu_activation_family and openai_gelu:
+ if self.glu_activation_family and openai_gelu:
raise ValueError(
f"Cannot use openai_gelu with specificed activation function : {activation} Please turn openai gelu off."
)
- if glu_activation_family and onnx_safe:
+ if self.glu_activation_family and onnx_safe:
raise ValueError(
f"Cannot use onnx_safe with specificed activation function : {activation} Please turn onnx safe off."
)
@@ -180,8 +181,6 @@ def __init__(
raise ValueError(
f"Cannot use bias_activation_fusion without bias terms. Please set bias=True or bias_activation_fusion=False."
)
- else:
- glu_activation_family = False
self.bias_activation_fusion = bias_activation_fusion
@@ -224,18 +223,18 @@ def forward(self, hidden_states):
# [s, b, 4hp]
intermediate_parallel, bias_parallel = self.dense_h_to_4h(hidden_states)
- if self.activation in ['geglu', 'reglu', 'swiglu']:
+ if self.glu_activation_family:
intermediate_parallel_2, bias_parallel_2 = self.dense_h_to_4h_2(hidden_states)
if self.bias_activation_fusion:
if self.activation == 'gelu':
intermediate_parallel = fused_bias_gelu(intermediate_parallel, bias_parallel)
- else:
+ elif self.activation == 'geglu':
intermediate_parallel = fused_bias_geglu(
intermediate_parallel, bias_parallel, intermediate_parallel_2, bias_parallel_2
)
- elif self.activation in ['geglu', 'reglu', 'swiglu']:
+ elif self.activation in ['reglu', 'swiglu']:
if bias_parallel is not None:
intermediate_parallel = self.activation_func(intermediate_parallel + bias_parallel) * (
intermediate_parallel_2 + bias_parallel_2
@@ -287,6 +286,7 @@ def __init__(
megatron_legacy=False,
bias=True,
headscale=False,
+ has_relative_attention_bias=False,
):
super(ParallelAttention, self).__init__()
@@ -299,6 +299,7 @@ def __init__(
self.attn_mask_type = attn_mask_type
self.megatron_legacy = megatron_legacy
self.headscale = headscale
+ self.has_relative_attention_bias = has_relative_attention_bias
if kv_channels is None:
assert (
@@ -382,7 +383,7 @@ def __init__(
self.position_embedding_type = position_embedding_type
self.relative_attention_num_buckets = relative_attention_num_buckets
self.relative_attention_max_distance = relative_attention_max_distance
- if self.position_embedding_type == 'relative':
+ if self.position_embedding_type == 'relative' and self.has_relative_attention_bias:
self.relative_attention_bias = torch.nn.Embedding(
relative_attention_num_buckets, self.num_attention_heads_per_partition
).to(torch.cuda.current_device())
@@ -498,7 +499,7 @@ def compute_bias(self, query_length, key_length):
relative_position = memory_position - context_position # shape (query_length, key_length)
relative_position_bucket = self._relative_position_bucket(
relative_position, # shape (query_length, key_length)
- bidirectional=(self.layer_type != LayerType.decoder), # (not self.is_decoder),
+ bidirectional=(self.attention_type != AttnMaskType.causal), # self.is_decoder and self_attention.
num_buckets=self.relative_attention_num_buckets,
max_distance=self.relative_attention_max_distance,
)
@@ -683,9 +684,12 @@ def forward(
if position_bias is None:
if self.position_embedding_type == 'relative':
- position_bias = self.compute_bias(real_seq_length, key_length)
- else:
- pass # HuggingFace implementation initialize position_bias to zero when not using
+ if self.has_relative_attention_bias:
+ position_bias = self.compute_bias(real_seq_length, key_length)
+ elif attention_mask is not None:
+ position_bias = torch.zeros_like(attention_mask).to(torch.cuda.current_device())
+ else:
+ position_bias = torch.zeros(1, key_length, key_length).to(torch.cuda.current_device())
# if key and values are already calculated
# we want only the last query position bias
@@ -977,6 +981,7 @@ def __init__(
normalization='layernorm',
transformer_block_type='pre_ln',
headscale=False,
+ has_relative_attention_bias=False,
):
super(ParallelTransformerLayer_, self).__init__()
@@ -1040,6 +1045,7 @@ def __init__(
megatron_legacy=megatron_legacy,
bias=bias,
headscale=headscale,
+ has_relative_attention_bias=has_relative_attention_bias,
)
# Normformer normalization
if transformer_block_type == 'normformer':
@@ -1092,6 +1098,7 @@ def __init__(
megatron_legacy=megatron_legacy,
bias=bias,
headscale=headscale,
+ has_relative_attention_bias=False,
)
# Normformer normalization
if transformer_block_type == 'normformer':
@@ -1221,14 +1228,6 @@ def forward(
# Post-LN: x -> MHA -> Residual -> LN -> MLP -> Residual -> LN
# Normformer: x -> LN -> MHA -> LN -> Residual -> MLP (w/LN) -> Residual
- if type(hidden_states) is tuple:
- if len(hidden_states) == 2:
- hidden_states, position_bias = hidden_states
- elif len(hidden_states) == 3:
- hidden_states, position_bias, encoder_decoder_position_bias = hidden_states
- else:
- raise IndexError('Hidden_states needs to be tuple containing 2 or 3 elements.')
-
residual = hidden_states
# Layer norm at the beginning of the transformer layer.
if self.transformer_block_type in ['pre_ln', 'normformer']:
@@ -1242,6 +1241,7 @@ def forward(
set_inference_key_value_memory=set_inference_key_value_memory,
inference_max_sequence_len=inference_max_sequence_len,
rotary_pos_emb=self_attention_pos_emb,
+ position_bias=position_bias,
)
if get_key_value:
@@ -1491,7 +1491,7 @@ def __init__(
self.num_layers = self.get_num_layers(num_layers)
# Transformer layers.
- def build_layer(layer_number):
+ def build_layer(layer_number, has_relative_attention_bias=False):
if isinstance(layer_type, list):
lt = layer_type[layer_number - 1]
else:
@@ -1529,6 +1529,7 @@ def build_layer(layer_number):
normalization=normalization,
transformer_block_type=transformer_block_type,
headscale=headscale,
+ has_relative_attention_bias=has_relative_attention_bias,
)
if parallel_state.get_virtual_pipeline_model_parallel_world_size() is not None:
@@ -1565,7 +1566,14 @@ def build_layer(layer_number):
else:
offset = parallel_state.get_pipeline_model_parallel_rank() * self.num_layers
- self.layers = torch.nn.ModuleList([build_layer(i + 1 + offset) for i in range(self.num_layers)])
+ self.layers = torch.nn.ModuleList(
+ [
+ build_layer(
+ i + 1 + offset, has_relative_attention_bias=(i == 0) and parallel_state.is_pipeline_first_stage()
+ )
+ for i in range(self.num_layers)
+ ]
+ )
if self.post_process and self.transformer_block_type != 'post_ln':
# Final layer norm before output.
@@ -1631,9 +1639,16 @@ def custom_forward(*inputs):
encoder_output,
enc_dec_attn_mask,
rotary_pos_emb,
- position_bias,
- encoder_decoder_position_bias,
+ position_bias=position_bias,
+ encoder_decoder_position_bias=encoder_decoder_position_bias,
)
+ if type(x_) is tuple:
+ if len(x_) == 2:
+ x_, position_bias = x_
+ elif len(x_) == 3:
+ x_, position_bias, encoder_decoder_position_bias = x_
+ else:
+ raise IndexError('Hidden_states (x_) needs to be tuple containing 2 or 3 elements.')
return x_
return custom_forward
@@ -1711,9 +1726,10 @@ def forward(
inference_max_sequence_len=None,
rotary_pos_emb=None, # list of positional embedding tensors, first one self attention, second one and third one are for cross attention (q, k)
retrieved_emb=None, # tensor of retrieved embedding of shape [b, k, r, n, d]
- position_bias=None,
- encoder_decoder_position_bias=None,
):
+ position_bias = None
+ encoder_decoder_position_bias = None
+
# Checks.
if inference_max_sequence_len:
assert self.activations_checkpoint_method is None, 'inference does not work with activation checkpointing'
diff --git a/nemo/collections/tts/torch/g2ps.py b/nemo/collections/tts/torch/g2ps.py
index 694f8b25820a..a6286aa5710c 100644
--- a/nemo/collections/tts/torch/g2ps.py
+++ b/nemo/collections/tts/torch/g2ps.py
@@ -405,7 +405,7 @@ def parse_one_word(self, word: str):
):
if word[-3] == 'T':
# Case like "airport's"
- return self.phoneme_dict[word[:-2]][0] + ["t", "s"], True
+ return self.phoneme_dict[word[:-2]][0] + ["s"], True
elif word[-3] == 'S':
# Case like "jones's"
return self.phoneme_dict[word[:-2]][0] + ["ɪ", "z"], True
@@ -420,14 +420,11 @@ def parse_one_word(self, word: str):
and (word[:-1] in self.phoneme_dict)
and (not self.ignore_ambiguous_words or self.is_unique_in_phoneme_dict(word[:-1]))
):
- if word[-3] == 'T':
- # Case like "airport's"
- return self.phoneme_dict[word[:-2]][0] + ["t", "s"], True
- elif word[-3] == 'S':
- # Case like "jones's"
- return self.phoneme_dict[word[:-2]][0] + ["ɪ", "z"], True
+ if word[-2] == 'T':
+ # Case like "airports"
+ return self.phoneme_dict[word[:-1]][0] + ["s"], True
else:
- return self.phoneme_dict[word[:-2]][0] + ["z"], True
+ return self.phoneme_dict[word[:-1]][0] + ["z"], True
# Phoneme dict lookup for unique words (or default pron if ignore_ambiguous_words=False)
if word in self.phoneme_dict and (not self.ignore_ambiguous_words or self.is_unique_in_phoneme_dict(word)):
diff --git a/nemo_text_processing/text_normalization/en/data/measure/unit.tsv b/nemo_text_processing/text_normalization/en/data/measure/unit.tsv
index c8893cbbdcd0..96afbb71d27f 100644
--- a/nemo_text_processing/text_normalization/en/data/measure/unit.tsv
+++ b/nemo_text_processing/text_normalization/en/data/measure/unit.tsv
@@ -1,8 +1,11 @@
amu atomic mass unit
bar bar
° degree
+º degree
°c degree Celsius
°C degree Celsius
+ºc degree Celsius
+ºC degree Celsius
℃ degree Celsius
cm2 square centimeter
cm² square centimeter
diff --git a/nemo_text_processing/text_normalization/en/data/whitelist/symbol.tsv b/nemo_text_processing/text_normalization/en/data/whitelist/symbol.tsv
index 63c035026564..6f2f8c69a8e6 100644
--- a/nemo_text_processing/text_normalization/en/data/whitelist/symbol.tsv
+++ b/nemo_text_processing/text_normalization/en/data/whitelist/symbol.tsv
@@ -19,3 +19,5 @@ $ dollar
€ euro
₩ won
¥ yen
+° degree
+º degree
diff --git a/nemo_text_processing/text_normalization/en/taggers/word.py b/nemo_text_processing/text_normalization/en/taggers/word.py
index 0b1ebc469384..fa6a965aab2e 100644
--- a/nemo_text_processing/text_normalization/en/taggers/word.py
+++ b/nemo_text_processing/text_normalization/en/taggers/word.py
@@ -14,6 +14,7 @@
import pynini
from nemo_text_processing.text_normalization.en.graph_utils import (
+ MIN_NEG_WEIGHT,
NEMO_ALPHA,
NEMO_DIGIT,
NEMO_NOT_SPACE,
@@ -22,6 +23,7 @@
convert_space,
get_abs_path,
)
+from nemo_text_processing.text_normalization.en.taggers.punctuation import PunctuationFst
from pynini.examples import plurals
from pynini.lib import pynutil
@@ -40,8 +42,11 @@ class WordFst(GraphFst):
def __init__(self, punctuation: GraphFst, deterministic: bool = True):
super().__init__(name="word", kind="classify", deterministic=deterministic)
+ punct = PunctuationFst().graph
+ default_graph = pynini.closure(pynini.difference(NEMO_NOT_SPACE, punct.project("input")), 1)
symbols_to_exclude = (pynini.union("$", "€", "₩", "£", "¥", "#", "%") | NEMO_DIGIT).optimize()
graph = pynini.closure(pynini.difference(NEMO_NOT_SPACE, symbols_to_exclude), 1)
+ graph = pynutil.add_weight(graph, MIN_NEG_WEIGHT) | default_graph
# leave phones of format [HH AH0 L OW1] untouched
phoneme_unit = pynini.closure(NEMO_ALPHA, 1) + pynini.closure(NEMO_DIGIT)
diff --git a/tests/nemo_text_processing/en/data_text_normalization/test_cases_measure.txt b/tests/nemo_text_processing/en/data_text_normalization/test_cases_measure.txt
index 8d5e6dee094f..c26138f813ca 100644
--- a/tests/nemo_text_processing/en/data_text_normalization/test_cases_measure.txt
+++ b/tests/nemo_text_processing/en/data_text_normalization/test_cases_measure.txt
@@ -15,3 +15,4 @@ covid-19.5~covid- nineteen point five
2°C~two degrees Celsius
1°C~one degree Celsius
1234-123kg~one thousand two hundred and thirty four to one hundred and twenty three kilograms
+45º&C~forty five degree and C
diff --git a/tests/nemo_text_processing/en/data_text_normalization/test_cases_normalize_with_audio.txt b/tests/nemo_text_processing/en/data_text_normalization/test_cases_normalize_with_audio.txt
index 639cea6366ad..5698b7886116 100644
--- a/tests/nemo_text_processing/en/data_text_normalization/test_cases_normalize_with_audio.txt
+++ b/tests/nemo_text_processing/en/data_text_normalization/test_cases_normalize_with_audio.txt
@@ -65,7 +65,7 @@ four five six seven
forty five sixty seven
four thousand five hundred and sixty seven
~This example number 15,000 can be a very long one, and can fail to produce valid normalization for such an easy number like 10,125 or dollar value $5349.01, and can fail to terminate, and can fail to terminate, and can fail to terminate, and can fail to terminate, and can fail to terminate, 452.
-This example number fifteen thousand can be a very long one, and can fail to produce valid normalization for such an easy number like ten thousand one hundred twenty five or dollar value five thousand and three forty nine us dollars one cent, and can fail to terminate, and can fail to terminate, and can fail to terminate, and can fail to terminate, and can fail to terminate, four hundred fifty two.
+This example number fifteen thousand can be a very long one, and can fail to produce valid normalization for such an easy number like ten thousand one hundred twenty five or dollar value five thousand and three forty nine us dollars and one cent, and can fail to terminate, and can fail to terminate, and can fail to terminate, and can fail to terminate, and can fail to terminate, four fifty two.
~$1.01
one dollar one cent
one dollar and one cent
diff --git a/tests/nemo_text_processing/en/data_text_normalization/test_cases_punctuation.txt b/tests/nemo_text_processing/en/data_text_normalization/test_cases_punctuation.txt
index 56ab0c1ca12e..c3073a3934bf 100644
--- a/tests/nemo_text_processing/en/data_text_normalization/test_cases_punctuation.txt
+++ b/tests/nemo_text_processing/en/data_text_normalization/test_cases_punctuation.txt
@@ -60,3 +60,4 @@ dr. Evil~dr. Evil
(1)Hello~(one) Hello
ÀÁÂÃ check §- and ƛ, also ɧ~ÀÁÂÃ check section - and ƛ, also ɧ
Hi it's 5pm,4A.M.?-34. Hi,no,yes,34! 12,again,4 and NO?17 and $.01,here & there--0.004kg~Hi it's five PM, four AM.? minus thirty four. Hi,no,yes, thirty four! twelve, again, four and NO? seventeen and one cent, here and there - minus zero point zero zero four kilograms
+1°C.~one degree Celsius.
diff --git a/tutorials/nlp/Non_English_Downstream_Tasks_(NER).ipynb b/tutorials/nlp/Non_English_Downstream_Tasks_(NER).ipynb
index 443f0713a45c..bfa56e5a2567 100644
--- a/tutorials/nlp/Non_English_Downstream_Tasks_(NER).ipynb
+++ b/tutorials/nlp/Non_English_Downstream_Tasks_(NER).ipynb
@@ -31,7 +31,7 @@
"# If you're using Google Colab and not running locally, run this cell\n",
"\n",
"# install NeMo\n",
- "!python -m pip install git+https://github.com/NVIDIA/NeMo.git@${BRANCH}#egg=nemo_toolkit[nlp]"
+ "!python -m pip install git+https://github.com/NVIDIA/NeMo.git@$BRANCH#egg=nemo_toolkit[nlp]"
]
},
{
diff --git a/tutorials/tts/Fastpitch_Training_GermanTTS.ipynb b/tutorials/tts/Fastpitch_Training_GermanTTS.ipynb
index 1c0ec8716701..a35fb9d94d77 100644
--- a/tutorials/tts/Fastpitch_Training_GermanTTS.ipynb
+++ b/tutorials/tts/Fastpitch_Training_GermanTTS.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "markdown",
- "id": "f5adc294",
+ "id": "9e23311d",
"metadata": {},
"source": [
"# Modifying FastPitch to Train on a Non-English (German) Dataset\n",
@@ -16,7 +16,7 @@
},
{
"cell_type": "markdown",
- "id": "fc18f4fb",
+ "id": "2e57b884",
"metadata": {},
"source": [
"# License\n",
@@ -39,7 +39,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "e27a7dc1",
+ "id": "392161ff",
"metadata": {},
"outputs": [],
"source": [
@@ -51,7 +51,7 @@
"3. Connect to an instance with a GPU (Runtime -> Change runtime type -> select \"GPU\" for hardware accelerator)\n",
"4. Run this cell to set up dependencies# .\n",
"\"\"\"\n",
- "BRANCH = 'tts_germanfastpitch'\n",
+ "BRANCH = 'main'\n",
"# # If you're using Colab and not running locally, uncomment and run this cell.\n",
"# !apt-get install sox libsndfile1 ffmpeg\n",
"# !pip install wget unidecode pynini==2.1.4 scipy==1.7.3\n",
@@ -61,7 +61,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "bf1cc79c",
+ "id": "d9a5e132",
"metadata": {},
"outputs": [],
"source": [
@@ -78,25 +78,28 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "0023bb0f",
+ "id": "c588ff4f",
"metadata": {},
"outputs": [],
"source": [
"# lets download the files we need to run this tutorial\n",
"\n",
- "!mkdir /NeMo\n",
- "!cd /NeMo && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/scripts/dataset_processing/tts/openslr/get_data.py\n",
- "!cd /NeMo && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/examples/tts/fastpitch.py\n",
- "!cd /NeMo && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/examples/tts/hifigan_finetune.py\n",
- "!cd /NeMo && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/scripts/dataset_processing/tts/extract_sup_data.py\n",
- "!cd /NeMo && wget https://raw.githubusercontent.com/NVIDIA/NeMo/$BRANCH/examples/tts/conf/de/fastpitch_align_22050.yaml\n",
- "!cd /NeMo && wget https://raw.githubusercontent.com/NVIDIA/NeMo/$BRANCH/examples/tts/conf/hifigan/hifigan.yaml\n",
- "!cd /NeMo && wget https://raw.githubusercontent.com/NVIDIA/NeMo/$BRANCH/nemo_text_processing/text_normalization/de/data/whitelist.tsv"
+ "!mkdir NeMoGermanTTS\n",
+ "!cd NeMoGermanTTS && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/scripts/dataset_processing/tts/openslr/get_data.py\n",
+ "!cd NeMoGermanTTS && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/examples/tts/fastpitch.py\n",
+ "!cd NeMoGermanTTS && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/examples/tts/hifigan_finetune.py\n",
+ "!cd NeMoGermanTTS && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/scripts/dataset_processing/tts/extract_sup_data.py\n",
+ "!cd NeMoGermanTTS && wget https://raw.githubusercontent.com/NVIDIA/NeMo/$BRANCH/examples/tts/conf/de/fastpitch_align_22050.yaml\n",
+ "!cd NeMoGermanTTS && wget https://raw.githubusercontent.com/NVIDIA/NeMo/$BRANCH/examples/tts/conf/hifigan/hifigan.yaml\n",
+ "!cd NeMoGermanTTS && wget https://raw.githubusercontent.com/NVIDIA/NeMo/$BRANCH/nemo_text_processing/text_normalization/de/data/whitelist.tsv\n",
+ "!cd NeMoGermanTTS && mkdir -p model/train_ds && cd model/train_ds && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/examples/tts/conf/hifigan/model/train_ds/train_ds_finetune.yaml\n",
+ "!cd NeMoGermanTTS && mkdir -p model/train_ds && cd model/validation_ds && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/examples/tts/conf/hifigan/model/validation_ds/val_ds_finetune.yaml\n",
+ "!cd NeMoGermanTTS && mkdir -p model/generator && cd model/generator && wget https://raw.githubusercontent.com/nvidia/NeMo/$BRANCH/examples/tts/conf/hifigan/model/generator/v1.yaml"
]
},
{
"cell_type": "markdown",
- "id": "0addf41a",
+ "id": "c3b37631",
"metadata": {},
"source": [
"# Introduction"
@@ -104,7 +107,7 @@
},
{
"cell_type": "markdown",
- "id": "c0c67aa7",
+ "id": "ba60fc45",
"metadata": {},
"source": [
"### FastPitch\n",
@@ -119,7 +122,7 @@
},
{
"cell_type": "markdown",
- "id": "b0fb61bc",
+ "id": "747a9f24",
"metadata": {},
"source": [
"# Dataset Preparation"
@@ -127,7 +130,7 @@
},
{
"cell_type": "markdown",
- "id": "dbc3a5ab",
+ "id": "e1cf7a8d",
"metadata": {},
"source": [
"We will show example of preprocessing and training using OpenSLR's German Neutral TTS dataset ([link](https://www.openslr.org/95)). It is a free single german speaker dataset (> 23 hours) by Thorsten Müller (voice) and Dominik Kreutz (audio optimization) for tts training. \n",
@@ -138,12 +141,12 @@
"3. Normalizing text\n",
"4. Phonemization\n",
"5. Creating dataset config\n",
- "6. Creating suppplementary data"
+ "6. Creating supplementary data"
]
},
{
"cell_type": "markdown",
- "id": "add9f955",
+ "id": "40e76a38",
"metadata": {},
"source": [
"## 1. Downloading the dataset"
@@ -152,12 +155,12 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "9982b65b",
+ "id": "36b8a1d3",
"metadata": {},
"outputs": [],
"source": [
- "!mkdir /Data && \\\n",
- " cd /Data && \\\n",
+ "!mkdir DataGermanTTS && \\\n",
+ " cd DataGermanTTS && \\\n",
" wget https://us.openslr.org/resources/95/thorsten-de_v02.tgz && \\\n",
" tar -zxvf thorsten-de_v02.tgz"
]
@@ -165,29 +168,29 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "e500cf5b",
+ "id": "6db032e5",
"metadata": {},
"outputs": [],
"source": [
- "# /Data directory looks like\n",
- "!ls /Data -R"
+ "# DataGermanTTS directory looks like\n",
+ "!ls DataGermanTTS -R"
]
},
{
"cell_type": "markdown",
- "id": "8dd1f324",
+ "id": "0e94204b",
"metadata": {},
"source": [
"\n",
"```bash\n",
- "$ ls /Data -R\n",
- "/Data:\n",
+ "$ ls DataGermanTTS -R\n",
+ "DataGermanTTS:\n",
"thorsten-de thorsten-de_v02.tgz\n",
"\n",
- "/Data/thorsten-de:\n",
+ "DataGermanTTS/thorsten-de:\n",
"metadata.csv metadata_shuf.csv metadata_train.csv metadata_val.csv wavs\n",
"\n",
- "/Data/thorsten-de/wavs:\n",
+ "DataGermanTTS/thorsten-de/wavs:\n",
"00025a6fbea659dae6ece011e749aa34.wav 80689a91d5c8e32847ccbba2322e2122.wav\n",
"000314280388fb390b3e70b69ee53a23.wav 8068cbcbe28085c15d2e8a8f7291d009.wav\n",
"000624f768d7e282534a850980619fb2.wav 8071b84557c9a780d23414e241393f00.wav\n",
@@ -199,36 +202,38 @@
},
{
"cell_type": "markdown",
- "id": "1be59a49",
+ "id": "c4f33db9",
"metadata": {},
"source": [
"## 2. Creating manifests \n",
"\n",
- "We've created `scripts/dataset_processing/tts/openslr/get_data.py` script that reads the `/Data/thorsten-de/metadata.csv` provided with the dataset and generates the following fields per each datapoint:\n",
+ "We've created `scripts/dataset_processing/tts/openslr/get_data.py` script that reads the `DataGermanTTS/thorsten-de/metadata.csv` provided with the dataset and generates the following fields per each datapoint:\n",
"1. `audio_filepath`: location of the wav file\n",
"2. `duration`: duration of the wav file\n",
"3. `text`: original text supplied by OpenSLR\n",
" \n",
- "After that, the script randomly splits the datapoints into 3 buckets, `train_manifest.json`, `val_manifest.json` and `test_manifest.json`. Example:"
+ "After that, the script randomly splits the datapoints into 3 buckets, `train_manifest.json`, `val_manifest.json` and `test_manifest.json`.\n",
+ "\n",
+ "Note: This step will take sometime to run for the entire dataset. If you are only interested in testing the scripts, please feel free to shorten the `DataGermanTTS/thorsten-de/metadata.csv` file to include only, say, top 100 records."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "a887e246",
+ "id": "eb063cf4",
"metadata": {},
"outputs": [],
"source": [
- "!(cd /NeMo && \\\n",
+ "!(cd NeMoGermanTTS && \\\n",
" python get_data.py \\\n",
- " --data-root /Data/ \\\n",
+ " --data-root ../DataGermanTTS/ \\\n",
" --val-size 0.1 \\\n",
" --test-size 0.2)"
]
},
{
"cell_type": "markdown",
- "id": "7b5925c5",
+ "id": "3811cc56",
"metadata": {},
"source": [
"In the example above, 10% datapoints go to validation set, 20% go to test set and the remaining 70% go to training set."
@@ -237,26 +242,26 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "d85c0161",
+ "id": "5c7b9430",
"metadata": {},
"outputs": [],
"source": [
- "# /Data directory looks like\n",
- "!ls /Data -R"
+ "# DataGermanTTS directory looks like\n",
+ "!ls DataGermanTTS -R"
]
},
{
"cell_type": "markdown",
- "id": "e8478373",
+ "id": "4d2dd715",
"metadata": {},
"source": [
"```bash\n",
- "$ ls /Data -R\n",
- "/Data:\n",
+ "$ ls DataGermanTTS -R\n",
+ "DataGermanTTS:\n",
"thorsten-de\n",
"thorsten-de_v02.tgz\n",
"\n",
- "/Data/thorsten-de:\n",
+ "DataGermanTTS/thorsten-de:\n",
"metadata.csv\n",
"metadata_shuf.csv\n",
"metadata_train.csv\n",
@@ -266,7 +271,7 @@
"val_manifest.json\n",
"wavs\n",
"\n",
- "/Data/thorsten-de/wavs:\n",
+ "DataGermanTTS/thorsten-de/wavs:\n",
"00025a6fbea659dae6ece011e749aa34.wav\n",
"000314280388fb390b3e70b69ee53a23.wav\n",
"000624f768d7e282534a850980619fb2.wav\n",
@@ -276,12 +281,12 @@
},
{
"cell_type": "markdown",
- "id": "11ac14a9",
+ "id": "2f6ea189",
"metadata": {},
"source": [
"## 3. Normalizing text\n",
"\n",
- "The script above, i.e. `scripts/dataset_processing/tts/openslr/get_data.py`, also generates a another field per each datapoint:\n",
+ "The script above, i.e. `scripts/dataset_processing/tts/openslr/get_data.py`, also generates another field per each datapoint:\n",
"- `normalized_text`: normalized text via NeMo's text normalizer:\n",
" ```python\n",
" nemo_text_processing.text_normalization.normalize.Normalizer(lang=\"de\", input_case=\"cased\", overwrite_cache=True, cache_dir=str(file_path / \"cache_dir\"))\n",
@@ -289,30 +294,30 @@
" \n",
"German language text normalizer (defined here: `nemo_text_processing/text_normalization/de`) was created using the tutorial shared under NeMo's `Grammar customization` documentation [here](https://docs.nvidia.com/deeplearning/nemo/user-guide/docs/en/main/nlp/text_normalization/wfst/wfst_text_normalization.html#grammar-customization). Here are some example records:\n",
"```json\n",
- "{\"audio_filepath\": \"/Data/thorsten-de/wavs/f1becc89cb4079a123ead68c9c8bb8ae.wav\", \"duration\": 7.250023, \"text\": \"Öffne den Webbrowser und rufe www.archlinux.org auf.\", \"normalized_text\": \"Öffne den Webbrowser und rufe w w w punkt a r c h l i n u x punkt o r g auf.\"}\n",
+ "{\"audio_filepath\": \"DataGermanTTS/thorsten-de/wavs/f1becc89cb4079a123ead68c9c8bb8ae.wav\", \"duration\": 7.250023, \"text\": \"Öffne den Webbrowser und rufe www.archlinux.org auf.\", \"normalized_text\": \"Öffne den Webbrowser und rufe w w w punkt a r c h l i n u x punkt o r g auf.\"}\n",
"```\n",
"Notice that the URL has been spelled out. \n",
"\n",
"In other cases, the normalized text may look the same as text, example:\n",
"```json\n",
- "{\"audio_filepath\": \"/Data/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"Geht die Schandtat auf sein Konto?\"}\n",
+ "{\"audio_filepath\": \"DataGermanTTS/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"Geht die Schandtat auf sein Konto?\"}\n",
"```"
]
},
{
"cell_type": "markdown",
- "id": "1ea88eae",
+ "id": "6c7f253e",
"metadata": {},
"source": [
"## 4. Phonemization\n",
"\n",
- "The pronunciation of a word can be represented as a string of phones, which are speech sounds, each represented with symbols adapated from the Roman alphabet. The IPA is designed to represent those qualities of speech that are part of lexical (and to a limited extent prosodic) sounds in oral language: phones, phonemes, intonation and the separation of words and syllables. Training model with phonemes as well as text will help the model generate more accurate speech sounds."
+ "The pronunciation of a word can be represented as a string of phones, which are speech sounds, each represented with symbols adapted from the Roman alphabet. The IPA is designed to represent those qualities of speech that are part of lexical (and to a limited extent prosodic) sounds in oral language: phones, phonemes, intonation and the separation of words and syllables. Training model with phonemes as well as text will help the model generate more accurate speech sounds."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "00de9751",
+ "id": "b6c8dad0",
"metadata": {},
"outputs": [],
"source": [
@@ -322,7 +327,7 @@
},
{
"cell_type": "markdown",
- "id": "c2d57066",
+ "id": "f5a88926",
"metadata": {},
"source": [
"The original dataset only contains text input, so, in order to add phonemes, we need to convert German text into phonemes using [bootphon/phonemizer](https://github.com/bootphon/phonemizer).\n",
@@ -333,7 +338,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "5ce78633",
+ "id": "2ffe9bb6",
"metadata": {},
"outputs": [],
"source": [
@@ -342,7 +347,7 @@
},
{
"cell_type": "markdown",
- "id": "2d416091",
+ "id": "f6a79794",
"metadata": {},
"source": [
"Alternatively, you can use phonemizer via docker container:\n",
@@ -350,7 +355,7 @@
"git clone https://github.com/bootphon/phonemizer\n",
"cd phonemizer\n",
"docker build -t phonemizer .\n",
- "docker run --rm -d -it -p 8888:8888 -v /Data:/Data --ipc=host phonemizer /bin/bash\n",
+ "docker run --rm -d -it -p 8888:8888 -v DataGermanTTS:DataGermanTTS --ipc=host phonemizer /bin/bash\n",
"docker exec -it /bin/bash\n",
"```\n",
"\n",
@@ -360,7 +365,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "ec4f0de7",
+ "id": "131ce5d0",
"metadata": {},
"outputs": [],
"source": [
@@ -369,7 +374,9 @@
"\n",
"backend = EspeakBackend('de')\n",
"\n",
- "input_manifest_filepaths = [\"/Data/thorsten-de/train_manifest\", \"/Data/thorsten-de/test_manifest\", \"/Data/thorsten-de/val_manifest\"]\n",
+ "input_manifest_filepaths = [\"DataGermanTTS/thorsten-de/train_manifest\", \\\n",
+ " \"DataGermanTTS/thorsten-de/test_manifest\", \\\n",
+ " \"DataGermanTTS/thorsten-de/val_manifest\"]\n",
"\n",
"for input_manifest_filepath in input_manifest_filepaths:\n",
" output_manifest_filepath = input_manifest_filepath+\"_phonemes\"\n",
@@ -399,29 +406,29 @@
},
{
"cell_type": "markdown",
- "id": "f5994604",
+ "id": "e0e4a206",
"metadata": {},
"source": [
"To better understand the phonemize method, refer to the docs [here](https://github.com/bootphon/phonemizer/blob/master/phonemizer/backend/base.py#L137).\n",
"\n",
- "Run the above script for train, test and val records, resulting in `train_phonemes_manifest.json`, `test_phonemes_manifest.json` and `val_phonemes_manifest.json` respectively.\n",
+ "Run the above script for train, test and val records, resulting in `train_manifest_phonemes.json`, `test_manifest_phonemes.json` and `val_manifest_phonemes.json` respectively.\n",
"\n",
"We are effectively doubling the size of our dataset. Each original record maps on to two records, one with original `normalized_text` field value and `is_phoneme` set to 0 and another with phonemized text and `is_phoneme` flag set to 1.\n",
"\n",
"Example of input record:\n",
"```json\n",
- "{\"audio_filepath\": \"/Data/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"Geht die Schandtat auf sein Konto?\"}\n",
+ "{\"audio_filepath\": \"DataGermanTTS/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"Geht die Schandtat auf sein Konto?\"}\n",
"```\n",
"And corresponding output records:\n",
"```json\n",
- "{\"audio_filepath\": \"/Data/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"Geht die Schandtat auf sein Konto?\", \"is_phoneme\": 0}\n",
- "{\"audio_filepath\": \"/Data/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"\\u0261e\\u02d0t di\\u02d0 \\u0283ant\\u0251\\u02d0t a\\u028af za\\u026an k\\u0254nto\\u02d0 \", \"is_phoneme\": 1}\n",
+ "{\"audio_filepath\": \"DataGermanTTS/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"Geht die Schandtat auf sein Konto?\", \"is_phoneme\": 0}\n",
+ "{\"audio_filepath\": \"DataGermanTTS/thorsten-de/wavs/e50eb02c25353f85549900d2fc1e0e32.wav\", \"duration\": 2.409977, \"text\": \"Geht die Schandtat auf sein Konto?\", \"normalized_text\": \"\\u0261e\\u02d0t di\\u02d0 \\u0283ant\\u0251\\u02d0t a\\u028af za\\u026an k\\u0254nto\\u02d0 \", \"is_phoneme\": 1}\n",
"```"
]
},
{
"cell_type": "markdown",
- "id": "3f2a97df",
+ "id": "18578da2",
"metadata": {},
"source": [
"## 5. Creating dataset config\n",
@@ -441,7 +448,7 @@
"manifest_filepath: \"train_manifest.json\"\n",
"sup_data_path: \"sup_data\"\n",
"sup_data_types: [ \"align_prior_matrix\", \"pitch\" ]\n",
- "whitelist_path: \"/NeMo/whitelist.tsv\"\n",
+ "whitelist_path: \"NeMoGermanTTS/whitelist.tsv\"\n",
"\n",
"dataset:\n",
" _target_: nemo.collections.tts.torch.data.TTSDataset\n",
@@ -482,12 +489,12 @@
" phonemes: true\n",
"```\n",
"\n",
- "Save the above config in `/NeMo/ds_for_fastpitch_align.yaml`."
+ "Save the above config in `NeMoGermanTTS/ds_for_fastpitch_align.yaml`."
]
},
{
"cell_type": "markdown",
- "id": "20d3ea4b",
+ "id": "b515c5b4",
"metadata": {},
"source": [
"## 6. Creating Supplementary Data\n",
@@ -500,31 +507,30 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "a9bb1915",
+ "id": "114dabfc",
"metadata": {},
"outputs": [],
"source": [
- "!cd /NeMo/ && \\\n",
- " python extract_sup_data.py \\\n",
- " --config-path /NeMo \\\n",
+ "!python NeMoGermanTTS/extract_sup_data.py \\\n",
+ " --config-path . \\\n",
" --config-name ds_for_fastpitch_align.yaml \\\n",
- " manifest_filepath=/Data/thorsten-de/train_manifest_phonemes.json \\\n",
- " sup_data_path=/Data/thorsten-de/phonemes/"
+ " manifest_filepath=DataGermanTTS/thorsten-de/train_manifest_phonemes.json \\\n",
+ " sup_data_path=DataGermanTTS/thorsten-de/phonemes/"
]
},
{
"cell_type": "markdown",
- "id": "b7225af2",
+ "id": "adfba0f9",
"metadata": {},
"source": [
"The above example gives the following result:\n",
"1. Creates two folders under `sup_data_path` - `pitch` and `align_prior_matrix`\n",
- "2. Prints out `PITCH_MEAN, PITCH_STD = 132.524658203125, 37.389366149902344`"
+ "2. Prints out some values for pitch mean and standard deviation: `PITCH_MEAN, PITCH_STD = 132.524658203125, 37.389366149902344`. Use these values while training FastPitch."
]
},
{
"cell_type": "markdown",
- "id": "692ac466",
+ "id": "3278f1ee",
"metadata": {},
"source": [
"# Training"
@@ -532,7 +538,7 @@
},
{
"cell_type": "markdown",
- "id": "d552f7ab",
+ "id": "1ef91842",
"metadata": {},
"source": [
"Before we train our model, let's define model config. Most of the model config stays the same as defined here: `examples/tts/conf/fastpitch_align_44100.yaml`, except:\n",
@@ -542,22 +548,22 @@
"\n",
"3. The `sample_rate` is updated to 22050 KHz per our dataset. And accordingly halve the `n_window_size`, `n_window_stride` and `n_fft` parameters as well. \n",
"\n",
- "We have already downloaded the config after making these changes here: `/NeMo/fastpitch_align_22050.yaml`"
+ "We have already downloaded the config after making these changes here: `NeMoGermanTTS/fastpitch_align_22050.yaml`"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "f21fc784",
+ "id": "e7f2373e",
"metadata": {},
"outputs": [],
"source": [
- "!cat /NeMo/fastpitch_align_22050.yaml"
+ "!cat NeMoGermanTTS/fastpitch_align_22050.yaml"
]
},
{
"cell_type": "markdown",
- "id": "96edcb13",
+ "id": "1de1cf64",
"metadata": {},
"source": [
"If you are using Weights and Biases, you may need to login first. More details [here](https://docs.wandb.ai/ref/cli/wandb-login)."
@@ -566,51 +572,47 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "bb23fba3",
+ "id": "c60ed72a",
"metadata": {},
"outputs": [],
"source": [
- "wandb_api_key = \"apikey\"\n",
- "wandb_project_name = \"GermanTTS\"\n",
- "wandb_run_name = \"tutorial\"\n",
- "\n",
- "!wandb login ${wandb_api_key}"
+ "!wandb login #paste_wandb_apikey_here"
]
},
{
"cell_type": "markdown",
- "id": "48e16fed",
+ "id": "51ec332e",
"metadata": {},
"source": [
- "Now we are ready for training our model! Let's try to train FastPitch."
+ "Now we are ready for training our model! Let's try to train FastPitch. Paste the PITCH_MEAN and PITCH_STD from previous steps here."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "1b37ec68",
+ "id": "4ad43d30",
"metadata": {},
"outputs": [],
"source": [
- "!(cd /NeMo && CUDA_VISIBLE_DEVICES=0 python fastpitch.py --config-path /NeMo --config-name fastpitch_align_22050 \\\n",
+ "!(cd NeMoGermanTTS && CUDA_VISIBLE_DEVICES=0 python fastpitch.py --config-path . --config-name fastpitch_align_22050 \\\n",
" model.train_ds.dataloader_params.batch_size=32 \\\n",
" model.validation_ds.dataloader_params.batch_size=32 \\\n",
- " train_dataset=/Data/thorsten-de/train_manifest_phonemes.json \\\n",
- " validation_datasets=/Data/thorsten-de/val_manifest_phonemes.json \\\n",
- " sup_data_path=/Data/thorsten-de/phonemes/ \\\n",
- " whitelist_path=/NeMo/whitelist.tsv \\\n",
- " exp_manager.exp_dir=/result \\\n",
+ " train_dataset=../DataGermanTTS/thorsten-de/train_manifest_phonemes.json \\\n",
+ " validation_datasets=../DataGermanTTS/thorsten-de/val_manifest_phonemes.json \\\n",
+ " sup_data_path=../DataGermanTTS/thorsten-de/phonemes/ \\\n",
+ " whitelist_path=./whitelist.tsv \\\n",
+ " exp_manager.exp_dir=resultGermanTTS \\\n",
" trainer.max_epochs=1 \\\n",
- " pitch_mean=132.524658203125 \\\n",
- " pitch_std=37.389366149902344 \\\n",
+ " pitch_mean=#paste_pitch_mean_here \\\n",
+ " pitch_std=#paste_pitch_std_here \\\n",
" +exp_manager.create_wandb_logger=true \\\n",
- " +exp_manager.wandb_logger_kwargs.name=${wandb_run_name} \\\n",
- " +exp_manager.wandb_logger_kwargs.project=${wandb_project_name})"
+ " +exp_manager.wandb_logger_kwargs.name=\"tutorial\" \\\n",
+ " +exp_manager.wandb_logger_kwargs.project=\"GermanTTS\")"
]
},
{
"cell_type": "markdown",
- "id": "e422a61c",
+ "id": "b8082cfc",
"metadata": {},
"source": [
"Note:\n",
@@ -622,7 +624,7 @@
},
{
"cell_type": "markdown",
- "id": "02c5bea2",
+ "id": "7a36f955",
"metadata": {},
"source": [
"## Evaluating FastPitch + pretrained HiFi-GAN\n",
@@ -633,7 +635,20 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "bb7ae759",
+ "id": "d70d5f7d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import IPython.display as ipd\n",
+ "from nemo.collections.tts.models import HifiGanModel, FastPitchModel\n",
+ "from matplotlib.pyplot import imshow\n",
+ "from matplotlib import pyplot as plt"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4e9ee07a",
"metadata": {},
"outputs": [],
"source": [
@@ -641,13 +656,14 @@
"fastpitch_model_path = \"\" # from the results directory\n",
"test = \"Diese Musiksammlung soll die Vielfalt des Lebens widerspiegeln.\" # text input to the model\n",
"test_id = \"877d9f668a877713b48735f282af62ca\" # identifier for the audio corresponding to the test text\n",
- "data_path = \"/Data/thorsten-de/wavs/\" # path to dataset folder with wav files from original dataset"
+ "data_path = \"DataGermanTTS/thorsten-de/wavs/\" # path to dataset folder with wav files from original dataset\n",
+ "seed = 1234"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "d409870c",
+ "id": "32a234f4",
"metadata": {},
"outputs": [],
"source": [
@@ -671,7 +687,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "c5c60fc2",
+ "id": "9a3f5eaa",
"metadata": {},
"outputs": [],
"source": [
@@ -680,13 +696,13 @@
"if \".nemo\" in fastpitch_model_path:\n",
" spec_gen_model = FastPitchModel.restore_from(fastpitch_model_path).eval().cuda()\n",
"else:\n",
- " FastPitchModel.load_from_checkpoint(checkpoint_path=fastpitch_model_path).eval().cuda()"
+ " spec_gen_model = FastPitchModel.load_from_checkpoint(checkpoint_path=fastpitch_model_path).eval().cuda()"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "6695665f",
+ "id": "de04b514",
"metadata": {},
"outputs": [],
"source": [
@@ -708,15 +724,15 @@
},
{
"cell_type": "markdown",
- "id": "98782fb8",
+ "id": "e57e9baf",
"metadata": {},
"source": [
- "We see that audio quality is not as good as we expect. One of the ways mentioned in the [FastPitch_Finetuning.ipynb](FastPitch_Finetuning.ipynb) tutorial is to finetune HiFi-GAN. Lets try that out next!"
+ "We see that audio quality is not as good as we expect, even after training FastPitch for 1000 epochs. One of the ways mentioned in the [FastPitch_Finetuning.ipynb](FastPitch_Finetuning.ipynb) tutorial is to finetune HiFi-GAN. Lets try that out next!"
]
},
{
"cell_type": "markdown",
- "id": "4e33d57b",
+ "id": "e6d62337",
"metadata": {},
"source": [
"# Finetuning HiFi-GAN\n",
@@ -726,7 +742,7 @@
},
{
"cell_type": "markdown",
- "id": "473cbfb6",
+ "id": "4efcf84d",
"metadata": {},
"source": [
"## Generating synthetic mels\n",
@@ -736,20 +752,20 @@
},
{
"cell_type": "code",
- "execution_count": 7,
- "id": "14a34ba9",
+ "execution_count": null,
+ "id": "59d12874",
"metadata": {},
"outputs": [],
"source": [
- "test_audio_filepath = \"/Data/thorsten-de/wavs/5d000c81c8e7c4817cbfd7c4b8738feb.wav\"\n",
+ "test_audio_filepath = \"DataGermanTTS/thorsten-de/wavs/5d000c81c8e7c4817cbfd7c4b8738feb.wav\"\n",
"test_audio_text = \"Dieser Geruch, wenn jemand eine Clementine \\u00f6ffnet!\"\n",
"fastpitch_model_path = \"\""
]
},
{
"cell_type": "code",
- "execution_count": 12,
- "id": "dfa99f1e",
+ "execution_count": null,
+ "id": "9395abc3",
"metadata": {},
"outputs": [],
"source": [
@@ -782,7 +798,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "14988711",
+ "id": "1679a9f9",
"metadata": {},
"outputs": [],
"source": [
@@ -791,7 +807,7 @@
},
{
"cell_type": "markdown",
- "id": "046e7e7c",
+ "id": "4a2cb665",
"metadata": {},
"source": [
"So we have 2 types of mel spectrograms that we can use for finetuning HiFi-GAN:\n",
@@ -801,31 +817,10 @@
},
{
"cell_type": "code",
- "execution_count": 15,
- "id": "3ac663e7",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "loading original melspec\n",
- "spectrogram shape = (80, 315)\n"
- ]
- },
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "