Spaces:
Runtime error
Runtime error
Update kokoro.py
Browse files
kokoro.py
CHANGED
@@ -1,7 +1,15 @@
|
|
1 |
-
import phonemizer
|
2 |
import re
|
3 |
import torch
|
4 |
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
def split_num(num):
|
7 |
num = num.group()
|
@@ -84,19 +92,19 @@ def get_vocab():
|
|
84 |
return dicts
|
85 |
|
86 |
VOCAB = get_vocab()
|
|
|
87 |
def tokenize(ps):
|
88 |
return [i for i in map(VOCAB.get, ps) if i is not None]
|
89 |
|
90 |
phonemizers = dict(
|
91 |
-
a=
|
92 |
-
b=
|
93 |
)
|
|
|
94 |
def phonemize(text, lang, norm=True):
|
95 |
if norm:
|
96 |
text = normalize_text(text)
|
97 |
-
ps = phonemizers[lang]
|
98 |
-
ps = ps[0] if ps else ''
|
99 |
-
# https://en.wiktionary.org/wiki/kokoro#English
|
100 |
ps = ps.replace('kəkˈoːɹoʊ', 'kˈoʊkəɹoʊ').replace('kəkˈɔːɹəʊ', 'kˈəʊkəɹəʊ')
|
101 |
ps = ps.replace('ʲ', 'j').replace('r', 'ɹ').replace('x', 'k').replace('ɬ', 'l')
|
102 |
ps = re.sub(r'(?<=[a-zɹː])(?=hˈʌndɹɪd)', ' ', ps)
|
@@ -118,48 +126,4 @@ def forward(model, tokens, ref_s, speed):
|
|
118 |
input_lengths = torch.LongTensor([tokens.shape[-1]]).to(device)
|
119 |
text_mask = length_to_mask(input_lengths).to(device)
|
120 |
bert_dur = model.bert(tokens, attention_mask=(~text_mask).int())
|
121 |
-
d_en = model.bert_encoder(bert_dur).transpose(-1, -2
|
122 |
-
s = ref_s[:, 128:]
|
123 |
-
d = model.predictor.text_encoder(d_en, s, input_lengths, text_mask)
|
124 |
-
x, _ = model.predictor.lstm(d)
|
125 |
-
duration = model.predictor.duration_proj(x)
|
126 |
-
duration = torch.sigmoid(duration).sum(axis=-1) / speed
|
127 |
-
pred_dur = torch.round(duration).clamp(min=1).long()
|
128 |
-
pred_aln_trg = torch.zeros(input_lengths, pred_dur.sum().item())
|
129 |
-
c_frame = 0
|
130 |
-
for i in range(pred_aln_trg.size(0)):
|
131 |
-
pred_aln_trg[i, c_frame:c_frame + pred_dur[0,i].item()] = 1
|
132 |
-
c_frame += pred_dur[0,i].item()
|
133 |
-
en = d.transpose(-1, -2) @ pred_aln_trg.unsqueeze(0).to(device)
|
134 |
-
F0_pred, N_pred = model.predictor.F0Ntrain(en, s)
|
135 |
-
t_en = model.text_encoder(tokens, input_lengths, text_mask)
|
136 |
-
asr = t_en @ pred_aln_trg.unsqueeze(0).to(device)
|
137 |
-
return model.decoder(asr, F0_pred, N_pred, ref_s[:, :128]).squeeze().cpu().numpy()
|
138 |
-
|
139 |
-
def generate(model, text, voicepack, lang='a', speed=1, ps=None):
|
140 |
-
ps = ps or phonemize(text, lang)
|
141 |
-
tokens = tokenize(ps)
|
142 |
-
if not tokens:
|
143 |
-
return None
|
144 |
-
elif len(tokens) > 510:
|
145 |
-
tokens = tokens[:510]
|
146 |
-
print('Truncated to 510 tokens')
|
147 |
-
ref_s = voicepack[len(tokens)]
|
148 |
-
out = forward(model, tokens, ref_s, speed)
|
149 |
-
ps = ''.join(next(k for k, v in VOCAB.items() if i == v) for i in tokens)
|
150 |
-
return out, ps
|
151 |
-
|
152 |
-
def generate_full(model, text, voicepack, lang='a', speed=1, ps=None):
|
153 |
-
ps = ps or phonemize(text, lang)
|
154 |
-
tokens = tokenize(ps)
|
155 |
-
if not tokens:
|
156 |
-
return None
|
157 |
-
outs = []
|
158 |
-
loop_count = len(tokens)//510 + (1 if len(tokens) % 510 != 0 else 0)
|
159 |
-
for i in range(loop_count):
|
160 |
-
ref_s = voicepack[len(tokens[i*510:(i+1)*510])]
|
161 |
-
out = forward(model, tokens[i*510:(i+1)*510], ref_s, speed)
|
162 |
-
outs.append(out)
|
163 |
-
outs = np.concatenate(outs)
|
164 |
-
ps = ''.join(next(k for k, v in VOCAB.items() if i == v) for i in tokens)
|
165 |
-
return outs, ps
|
|
|
|
|
1 |
import re
|
2 |
import torch
|
3 |
import numpy as np
|
4 |
+
from gtts import gTTS # Import gTTS for text-to-speech
|
5 |
+
|
6 |
+
# Replace phonemizer backend with gTTS
|
7 |
+
def phonemize_with_gtts(text, lang='en'):
|
8 |
+
tts = gTTS(text=text, lang=lang)
|
9 |
+
# gTTS does not return phonemes, so we will simply return the text itself
|
10 |
+
# In your original code, this is where phonemizing is used
|
11 |
+
# For now, we can return the text or adapt further as needed
|
12 |
+
return text
|
13 |
|
14 |
def split_num(num):
|
15 |
num = num.group()
|
|
|
92 |
return dicts
|
93 |
|
94 |
VOCAB = get_vocab()
|
95 |
+
|
96 |
def tokenize(ps):
|
97 |
return [i for i in map(VOCAB.get, ps) if i is not None]
|
98 |
|
99 |
phonemizers = dict(
|
100 |
+
a=phonemize_with_gtts, # Replace with the new phonemizer function
|
101 |
+
b=phonemize_with_gtts, # Same for other language options
|
102 |
)
|
103 |
+
|
104 |
def phonemize(text, lang, norm=True):
|
105 |
if norm:
|
106 |
text = normalize_text(text)
|
107 |
+
ps = phonemizers[lang](text)
|
|
|
|
|
108 |
ps = ps.replace('kəkˈoːɹoʊ', 'kˈoʊkəɹoʊ').replace('kəkˈɔːɹəʊ', 'kˈəʊkəɹəʊ')
|
109 |
ps = ps.replace('ʲ', 'j').replace('r', 'ɹ').replace('x', 'k').replace('ɬ', 'l')
|
110 |
ps = re.sub(r'(?<=[a-zɹː])(?=hˈʌndɹɪd)', ' ', ps)
|
|
|
126 |
input_lengths = torch.LongTensor([tokens.shape[-1]]).to(device)
|
127 |
text_mask = length_to_mask(input_lengths).to(device)
|
128 |
bert_dur = model.bert(tokens, attention_mask=(~text_mask).int())
|
129 |
+
d_en = model.bert_encoder(bert_dur).transpose(-1, -2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|