-
Notifications
You must be signed in to change notification settings - Fork 0
/
inference.py
268 lines (213 loc) · 8.9 KB
/
inference.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# -*- coding: utf-8 -*-
"""infer-v2.ipynb의 사본
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1wXifT9QmVCSxfP_SgE1-c-jsrHw0Go1O
#google cloud project key 인증
"""
!gcloud auth activate-service-account --key-file "siliconwildcat.json"
"""#필수 라이브러리 및 함수 불러오기
실행에 필요한 라이브러리 및 함수를 불러옵니다.
이 과정은 약 10분 정도 소요될 수 있습니다.
"""
!git clone https://github.com/sce-tts/TTS.git -b sce-tts
import os
import sys
from pathlib import Path
!git clone https://github.com/sce-tts/g2pK.git
!gsutil cp -r gs://siliconwildcat_poc_bucket/tts_infer/TTS /content
# Commented out IPython magic to ensure Python compatibility.
# %cd /content/TTS
!pip install -q --no-cache-dir -e .
# %cd /content/g2pK
!pip install -q --no-cache-dir "konlpy" "jamo" "nltk" "python-mecab-ko"
!pip install -q --no-cache-dir -e .
# Commented out IPython magic to ensure Python compatibility.
# %cd /content/g2pK
import g2pk
g2p = g2pk.G2p()
# Commented out IPython magic to ensure Python compatibility.
# %cd /content/TTS
import re
import sys
from unicodedata import normalize
import IPython
from TTS.utils.synthesizer import Synthesizer
def normalize_text(text):
text = text.strip()
for c in ",;:":
text = text.replace(c, ".")
text = remove_duplicated_punctuations(text)
text = jamo_text(text)
text = g2p.idioms(text)
text = g2pk.english.convert_eng(text, g2p.cmu)
text = g2pk.utils.annotate(text, g2p.mecab)
text = g2pk.numerals.convert_num(text)
text = re.sub("/[PJEB]", "", text)
text = alphabet_text(text)
# remove unreadable characters
text = normalize("NFD", text)
text = "".join(c for c in text if c in symbols)
text = normalize("NFC", text)
text = text.strip()
if len(text) == 0:
return ""
# only single punctuation
if text in '.!?':
return punctuation_text(text)
# append punctuation if there is no punctuation at the end of the text
if text[-1] not in '.!?':
text += '.'
return text
def remove_duplicated_punctuations(text):
text = re.sub(r"[.?!]+\?", "?", text)
text = re.sub(r"[.?!]+!", "!", text)
text = re.sub(r"[.?!]+\.", ".", text)
return text
def split_text(text):
text = remove_duplicated_punctuations(text)
texts = []
for subtext in re.findall(r'[^.!?\n]*[.!?\n]', text):
texts.append(subtext.strip())
return texts
def alphabet_text(text):
text = re.sub(r"(a|A)", "에이", text)
text = re.sub(r"(b|B)", "비", text)
text = re.sub(r"(c|C)", "씨", text)
text = re.sub(r"(d|D)", "디", text)
text = re.sub(r"(e|E)", "이", text)
text = re.sub(r"(f|F)", "에프", text)
text = re.sub(r"(g|G)", "쥐", text)
text = re.sub(r"(h|H)", "에이치", text)
text = re.sub(r"(i|I)", "아이", text)
text = re.sub(r"(j|J)", "제이", text)
text = re.sub(r"(k|K)", "케이", text)
text = re.sub(r"(l|L)", "엘", text)
text = re.sub(r"(m|M)", "엠", text)
text = re.sub(r"(n|N)", "엔", text)
text = re.sub(r"(o|O)", "오", text)
text = re.sub(r"(p|P)", "피", text)
text = re.sub(r"(q|Q)", "큐", text)
text = re.sub(r"(r|R)", "알", text)
text = re.sub(r"(s|S)", "에스", text)
text = re.sub(r"(t|T)", "티", text)
text = re.sub(r"(u|U)", "유", text)
text = re.sub(r"(v|V)", "브이", text)
text = re.sub(r"(w|W)", "더블유", text)
text = re.sub(r"(x|X)", "엑스", text)
text = re.sub(r"(y|Y)", "와이", text)
text = re.sub(r"(z|Z)", "지", text)
return text
def punctuation_text(text):
# 문장부호
text = re.sub(r"!", "느낌표", text)
text = re.sub(r"\?", "물음표", text)
text = re.sub(r"\.", "마침표", text)
return text
def jamo_text(text):
# 기본 자모음
text = re.sub(r"ㄱ", "기역", text)
text = re.sub(r"ㄴ", "니은", text)
text = re.sub(r"ㄷ", "디귿", text)
text = re.sub(r"ㄹ", "리을", text)
text = re.sub(r"ㅁ", "미음", text)
text = re.sub(r"ㅂ", "비읍", text)
text = re.sub(r"ㅅ", "시옷", text)
text = re.sub(r"ㅇ", "이응", text)
text = re.sub(r"ㅈ", "지읒", text)
text = re.sub(r"ㅊ", "치읓", text)
text = re.sub(r"ㅋ", "키읔", text)
text = re.sub(r"ㅌ", "티읕", text)
text = re.sub(r"ㅍ", "피읖", text)
text = re.sub(r"ㅎ", "히읗", text)
text = re.sub(r"ㄲ", "쌍기역", text)
text = re.sub(r"ㄸ", "쌍디귿", text)
text = re.sub(r"ㅃ", "쌍비읍", text)
text = re.sub(r"ㅆ", "쌍시옷", text)
text = re.sub(r"ㅉ", "쌍지읒", text)
text = re.sub(r"ㄳ", "기역시옷", text)
text = re.sub(r"ㄵ", "니은지읒", text)
text = re.sub(r"ㄶ", "니은히읗", text)
text = re.sub(r"ㄺ", "리을기역", text)
text = re.sub(r"ㄻ", "리을미음", text)
text = re.sub(r"ㄼ", "리을비읍", text)
text = re.sub(r"ㄽ", "리을시옷", text)
text = re.sub(r"ㄾ", "리을티읕", text)
text = re.sub(r"ㄿ", "리을피읍", text)
text = re.sub(r"ㅀ", "리을히읗", text)
text = re.sub(r"ㅄ", "비읍시옷", text)
text = re.sub(r"ㅏ", "아", text)
text = re.sub(r"ㅑ", "야", text)
text = re.sub(r"ㅓ", "어", text)
text = re.sub(r"ㅕ", "여", text)
text = re.sub(r"ㅗ", "오", text)
text = re.sub(r"ㅛ", "요", text)
text = re.sub(r"ㅜ", "우", text)
text = re.sub(r"ㅠ", "유", text)
text = re.sub(r"ㅡ", "으", text)
text = re.sub(r"ㅣ", "이", text)
text = re.sub(r"ㅐ", "애", text)
text = re.sub(r"ㅒ", "얘", text)
text = re.sub(r"ㅔ", "에", text)
text = re.sub(r"ㅖ", "예", text)
text = re.sub(r"ㅘ", "와", text)
text = re.sub(r"ㅙ", "왜", text)
text = re.sub(r"ㅚ", "외", text)
text = re.sub(r"ㅝ", "워", text)
text = re.sub(r"ㅞ", "웨", text)
text = re.sub(r"ㅟ", "위", text)
text = re.sub(r"ㅢ", "의", text)
return text
def normalize_multiline_text(long_text):
texts = split_text(long_text)
normalized_texts = [normalize_text(text).strip() for text in texts]
return [text for text in normalized_texts if len(text) > 0]
def synthesize(text):
wavs = synthesizer.tts(text, None, None)
return wavs
"""#학습한 모델 불러오기
학습한 Glow-TTS와 HiFi-GAN 모델을 불러옵니다.
만약 다른 체크포인트에서 불러오시려면 아래 코드에서 경로를 아래와 같이 적절하게 수정합니다.
```python
synthesizer = Synthesizer(
"/content/drive/My Drive/Colab Notebooks/data/glowtts-v2/glowtts-v2-May-31-2021_08+17AM-d897f2e/best_model.pth.tar",
"/content/drive/My Drive/Colab Notebooks/data/glowtts-v2/glowtts-v2-May-31-2021_08+17AM-d897f2e/config.json",
None,
"/content/drive/My Drive/Colab Notebooks/data/hifigan-v2/hifigan-v2-May-31-2021_08+26AM-d897f2e/checkpoint_300000.pth.tar",
"/content/drive/My Drive/Colab Notebooks/data/hifigan-v2/hifigan-v2-May-31-2021_08+26AM-d897f2e/config.json",
None,
None,
False,
)
```
"""
# Commented out IPython magic to ensure Python compatibility.
# %cd /content/
!gsutil cp -r gs://siliconwildcat_poc_bucket/tts_infer/glowtts-v2 /content
!gsutil cp -r gs://siliconwildcat_poc_bucket/tts_infer/hifigan-v2 /content
synthesizer = Synthesizer(
"/content/glowtts-v2/best_model.pth.tar",
"/content/glowtts-v2/config.json",
None,
"/content/hifigan-v2/best_model.pth.tar",
"/content/hifigan-v2/config.json",
None,
None,
False,
)
symbols = synthesizer.tts_config.characters.characters
"""#음성 합성
실제 음성 합성을 수행합니다.
`long_text`의 값을 변경하여 다른 문장의 합성도 시도해보실 수 있습니다.
"""
texts = """
아래 문장들은 모델 학습을 위해 사용하지 않은 문장들입니다.
서울특별시 특허허가과 허가과장 허과장.
경찰청 철창살은 외철창살이고 검찰청 철창살은 쌍철창살이다.
지향을 지양으로 오기하는 일을 지양하는 언어 습관을 지향해야 한다.
그러니까 외계인이 우리 생각을 읽고 우리 생각을 우리가 다시 생각토록 해서 그 생각이 마치 우리가 생각한 것인 것처럼 속였다는 거냐?
안 촉촉한 초코칩 나라에 살던 안 촉촉한 초코칩이 촉촉한 초코칩 나라의 촉촉한 초코칩을 보고 촉촉한 초코칩이 되고 싶어서 촉촉한 초코칩 나라에 갔는데 촉촉한 초코칩 나라의 촉촉한 문지기가 넌 촉촉한 초코칩이 아니고 안 촉촉한 초코칩이니까 안 촉촉한 초코칩 나라에서 살라고 해서 안 촉촉한 초코칩은 촉촉한 초코칩이 되는 것을 포기하고 안 촉촉한 눈물을 흘리며 안 촉촉한 초코칩 나라로 돌아갔다.
"""
for text in normalize_multiline_text(texts):
wav = synthesizer.tts(text, None, None)
IPython.display.display(IPython.display.Audio(wav, rate=22050))