Spaces:
Running
Running
Yurii Paniv
commited on
Commit
•
c49c056
1
Parent(s):
a575152
Fix stress using model
Browse files- app.py +14 -11
- ukrainian_tts/formatter.py +1 -2
- ukrainian_tts/stress.py +33 -5
- ukrainian_tts/stress_with_model.py +0 -26
- ukrainian_tts/tts.py +10 -6
app.py
CHANGED
@@ -2,7 +2,7 @@ import tempfile
|
|
2 |
import gradio as gr
|
3 |
from datetime import datetime
|
4 |
from enum import Enum
|
5 |
-
from ukrainian_tts.tts import TTS
|
6 |
from torch.cuda import is_available
|
7 |
|
8 |
class StressOption(Enum):
|
@@ -32,18 +32,21 @@ def tts(text: str, voice: str, stress: str):
|
|
32 |
print("Voice", voice)
|
33 |
print("Stress:", stress)
|
34 |
print("Time:", datetime.utcnow())
|
35 |
-
|
36 |
-
True if stress == StressOption.AutomaticStressWithModel.value else False
|
37 |
-
)
|
38 |
voice_mapping = {
|
39 |
-
VoiceOption.Olena.value:
|
40 |
-
VoiceOption.Mykyta.value:
|
41 |
-
VoiceOption.Lada.value:
|
42 |
-
VoiceOption.Dmytro.value:
|
43 |
-
VoiceOption.Olga.value:
|
|
|
|
|
|
|
|
|
44 |
}
|
45 |
-
speaker_name = voice_mapping[voice]
|
46 |
|
|
|
|
|
47 |
text_limit = 7200
|
48 |
text = (
|
49 |
text if len(text) < text_limit else text[0:text_limit]
|
@@ -51,7 +54,7 @@ def tts(text: str, voice: str, stress: str):
|
|
51 |
|
52 |
|
53 |
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as fp:
|
54 |
-
_, text = ukr_tts.tts(text, speaker_name,
|
55 |
return fp.name, text
|
56 |
|
57 |
|
|
|
2 |
import gradio as gr
|
3 |
from datetime import datetime
|
4 |
from enum import Enum
|
5 |
+
from ukrainian_tts.tts import TTS, Stress, Voices
|
6 |
from torch.cuda import is_available
|
7 |
|
8 |
class StressOption(Enum):
|
|
|
32 |
print("Voice", voice)
|
33 |
print("Stress:", stress)
|
34 |
print("Time:", datetime.utcnow())
|
35 |
+
|
|
|
|
|
36 |
voice_mapping = {
|
37 |
+
VoiceOption.Olena.value: Voices.Olena.value,
|
38 |
+
VoiceOption.Mykyta.value: Voices.Mykyta.value,
|
39 |
+
VoiceOption.Lada.value: Voices.Lada.value,
|
40 |
+
VoiceOption.Dmytro.value: Voices.Dmytro.value,
|
41 |
+
VoiceOption.Olga.value: Voices.Olga.value,
|
42 |
+
}
|
43 |
+
stress_mapping = {
|
44 |
+
StressOption.AutomaticStress.value: Stress.Dictionary.value,
|
45 |
+
StressOption.AutomaticStressWithModel.value: Stress.Model.value
|
46 |
}
|
|
|
47 |
|
48 |
+
speaker_name = voice_mapping[voice]
|
49 |
+
stress_selected = stress_mapping[stress]
|
50 |
text_limit = 7200
|
51 |
text = (
|
52 |
text if len(text) < text_limit else text[0:text_limit]
|
|
|
54 |
|
55 |
|
56 |
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as fp:
|
57 |
+
_, text = ukr_tts.tts(text, speaker_name, stress_selected, fp)
|
58 |
return fp.name, text
|
59 |
|
60 |
|
ukrainian_tts/formatter.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
import num2words
|
2 |
import re
|
3 |
-
from .stress import sentence_to_stress, stress_dict
|
4 |
-
from .stress_with_model import stress_with_model
|
5 |
|
6 |
|
7 |
def preprocess_text(text, use_autostress_model=False):
|
|
|
1 |
import num2words
|
2 |
import re
|
3 |
+
from .stress import sentence_to_stress, stress_dict, stress_with_model
|
|
|
4 |
|
5 |
|
6 |
def preprocess_text(text, use_autostress_model=False):
|
ukrainian_tts/stress.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
from typing import List
|
2 |
-
import numpy as np
|
3 |
from ukrainian_word_stress import Stressifier, StressSymbol
|
|
|
4 |
|
5 |
stressify = Stressifier(stress_symbol=StressSymbol.CombiningAcuteAccent)
|
6 |
|
@@ -10,10 +10,7 @@ special = "'"
|
|
10 |
alphabet = vowels + consonants + special
|
11 |
|
12 |
|
13 |
-
def
|
14 |
-
stressed = stressify(sentence.replace("+", "")).replace(
|
15 |
-
StressSymbol.CombiningAcuteAccent, "+"
|
16 |
-
)
|
17 |
new_stressed = ""
|
18 |
start = 0
|
19 |
last = 0
|
@@ -33,6 +30,19 @@ def stress_dict(sentence: str):
|
|
33 |
return new_stressed
|
34 |
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
def sentence_to_stress(sentence: str, stress_function=stress_dict) -> str:
|
37 |
# save custom stress positions
|
38 |
all_stresses = []
|
@@ -68,6 +78,7 @@ def sentence_to_stress(sentence: str, stress_function=stress_dict) -> str:
|
|
68 |
|
69 |
|
70 |
if __name__ == "__main__":
|
|
|
71 |
sentence = "Кам'янець-Подільський - місто в Хмельницькій області України, центр Кам'янець-Подільської міської об'єднаної територіальної громади і Кам'янець-Подільського району."
|
72 |
print(sentence_to_stress(sentence))
|
73 |
sentence = "Привіт, як тебе звати?"
|
@@ -84,3 +95,20 @@ if __name__ == "__main__":
|
|
84 |
print(sentence_to_stress(sentence))
|
85 |
sentence = "Н тльк в крн тк мж бт."
|
86 |
print(sentence_to_stress(sentence))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
from typing import List
|
|
|
2 |
from ukrainian_word_stress import Stressifier, StressSymbol
|
3 |
+
import ukrainian_accentor as accentor
|
4 |
|
5 |
stressify = Stressifier(stress_symbol=StressSymbol.CombiningAcuteAccent)
|
6 |
|
|
|
10 |
alphabet = vowels + consonants + special
|
11 |
|
12 |
|
13 |
+
def _shift_stress(stressed):
|
|
|
|
|
|
|
14 |
new_stressed = ""
|
15 |
start = 0
|
16 |
last = 0
|
|
|
30 |
return new_stressed
|
31 |
|
32 |
|
33 |
+
def stress_with_model(text: str):
|
34 |
+
text = text.lower()
|
35 |
+
result = accentor.process(text, mode="plus")
|
36 |
+
return result
|
37 |
+
|
38 |
+
|
39 |
+
def stress_dict(sentence: str):
|
40 |
+
stressed = stressify(sentence.replace("+", "")).replace(
|
41 |
+
StressSymbol.CombiningAcuteAccent, "+"
|
42 |
+
)
|
43 |
+
return _shift_stress(stressed)
|
44 |
+
|
45 |
+
|
46 |
def sentence_to_stress(sentence: str, stress_function=stress_dict) -> str:
|
47 |
# save custom stress positions
|
48 |
all_stresses = []
|
|
|
78 |
|
79 |
|
80 |
if __name__ == "__main__":
|
81 |
+
# TODO: move it to unit tests
|
82 |
sentence = "Кам'янець-Подільський - місто в Хмельницькій області України, центр Кам'янець-Подільської міської об'єднаної територіальної громади і Кам'янець-Подільського району."
|
83 |
print(sentence_to_stress(sentence))
|
84 |
sentence = "Привіт, як тебе звати?"
|
|
|
95 |
print(sentence_to_stress(sentence))
|
96 |
sentence = "Н тльк в крн тк мж бт."
|
97 |
print(sentence_to_stress(sentence))
|
98 |
+
|
99 |
+
sentence = "Кам'янець-Подільський - місто в Хмельницькій області України, центр Кам'янець-Подільської міської об'єднаної територіальної громади і Кам'янець-Подільського району."
|
100 |
+
print(stress_with_model(sentence))
|
101 |
+
sentence = "Привіт, як тебе звати?"
|
102 |
+
print(stress_with_model(sentence))
|
103 |
+
sentence = "АННА - український панк-рок гурт"
|
104 |
+
print(stress_with_model(sentence))
|
105 |
+
sentence = "Не тільки в Україні таке може бути."
|
106 |
+
print(stress_with_model(sentence))
|
107 |
+
sentence = "Не тільки в +Укра+їні т+аке може бути."
|
108 |
+
print(stress_with_model(sentence))
|
109 |
+
sentence = "два + два"
|
110 |
+
print(stress_with_model(sentence))
|
111 |
+
sentence = "Н тльк в крн тк мж бт."
|
112 |
+
print(stress_with_model(sentence))
|
113 |
+
sentence = "Н тльк в крн тк мж бт."
|
114 |
+
print(stress_with_model(sentence))
|
ukrainian_tts/stress_with_model.py
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
import ukrainian_accentor as accentor
|
2 |
-
|
3 |
-
# run
|
4 |
-
def stress_with_model(text: str):
|
5 |
-
text = text.lower()
|
6 |
-
result = accentor.process(text, mode="plus")
|
7 |
-
return result
|
8 |
-
|
9 |
-
|
10 |
-
if __name__ == "__main__":
|
11 |
-
sentence = "Кам'янець-Подільський - місто в Хмельницькій області України, центр Кам'янець-Подільської міської об'єднаної територіальної громади і Кам'янець-Подільського району."
|
12 |
-
print(stress_with_model(sentence))
|
13 |
-
sentence = "Привіт, як тебе звати?"
|
14 |
-
print(stress_with_model(sentence))
|
15 |
-
sentence = "АННА - український панк-рок гурт"
|
16 |
-
print(stress_with_model(sentence))
|
17 |
-
sentence = "Не тільки в Україні таке може бути."
|
18 |
-
print(stress_with_model(sentence))
|
19 |
-
sentence = "Не тільки в +Укра+їні т+аке може бути."
|
20 |
-
print(stress_with_model(sentence))
|
21 |
-
sentence = "два + два"
|
22 |
-
print(stress_with_model(sentence))
|
23 |
-
sentence = "Н тльк в крн тк мж бт."
|
24 |
-
print(stress_with_model(sentence))
|
25 |
-
sentence = "Н тльк в крн тк мж бт."
|
26 |
-
print(stress_with_model(sentence))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ukrainian_tts/tts.py
CHANGED
@@ -15,7 +15,7 @@ class Voices(Enum):
|
|
15 |
Olga = "olga"
|
16 |
|
17 |
|
18 |
-
class
|
19 |
"""Options how to stress sentence.
|
20 |
- `dictionary` - performs lookup in dictionary, taking into account grammatical case of a word and its' neighbors
|
21 |
- `model` - stress using transformer model"""
|
@@ -40,17 +40,21 @@ class TTS:
|
|
40 |
Run a Text-to-Speech engine and output to `output_fp` BytesIO-like object.
|
41 |
- `text` - your model input text.
|
42 |
- `voice` - one of predefined voices from `Voices` enum.
|
43 |
-
- `stress` - stress method options, predefined in `
|
44 |
- `output_fp` - file-like object output. Stores in RAM by default.
|
45 |
"""
|
46 |
-
autostress_with_model = (
|
47 |
-
True if stress == StressOption.Model.value else False
|
48 |
-
)
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
if voice not in [option.value for option in Voices]:
|
51 |
raise ValueError(f"Invalid value for voice selected! Please use one of the following values: {', '.join([option.value for option in Voices])}.")
|
52 |
|
53 |
-
text = preprocess_text(text,
|
54 |
|
55 |
with no_grad():
|
56 |
wavs = self.synthesizer.tts(text, speaker_name=voice)
|
|
|
15 |
Olga = "olga"
|
16 |
|
17 |
|
18 |
+
class Stress(Enum):
|
19 |
"""Options how to stress sentence.
|
20 |
- `dictionary` - performs lookup in dictionary, taking into account grammatical case of a word and its' neighbors
|
21 |
- `model` - stress using transformer model"""
|
|
|
40 |
Run a Text-to-Speech engine and output to `output_fp` BytesIO-like object.
|
41 |
- `text` - your model input text.
|
42 |
- `voice` - one of predefined voices from `Voices` enum.
|
43 |
+
- `stress` - stress method options, predefined in `Stress` enum.
|
44 |
- `output_fp` - file-like object output. Stores in RAM by default.
|
45 |
"""
|
|
|
|
|
|
|
46 |
|
47 |
+
if stress not in [option.value for option in Stress]:
|
48 |
+
raise ValueError(f"Invalid value for stress option selected! Please use one of the following values: {', '.join([option.value for option in Stress])}.")
|
49 |
+
|
50 |
+
if stress == Stress.Model.value:
|
51 |
+
stress = True
|
52 |
+
else:
|
53 |
+
stress = False
|
54 |
if voice not in [option.value for option in Voices]:
|
55 |
raise ValueError(f"Invalid value for voice selected! Please use one of the following values: {', '.join([option.value for option in Voices])}.")
|
56 |
|
57 |
+
text = preprocess_text(text, stress)
|
58 |
|
59 |
with no_grad():
|
60 |
wavs = self.synthesizer.tts(text, speaker_name=voice)
|