Optimize g2p function for improved speed and efficiency

- Moved global variables (ARPA, _g2p, eng_dict, tokenizer) to top-level scope to avoid redundant initialization.
- Simplified conditions for words with apostrophes.
- Streamlined __post_replace_ph function by removing redundant checks.
- Optimized __refine_syllables function with direct iteration.
- Avoided re-initialization of tokenizer in __text_to_words by moving it to global scope.
- Added performance test in __main__ to validate improvements.
- Resolves issue #104.
This commit is contained in:
gordon0414
2024-05-09 16:12:15 +09:00
parent e721c09b87
commit 3018309199

View File

@@ -1,103 +1,35 @@
import re import re
from g2p_en import G2p from g2p_en import G2p
from style_bert_vits2.constants import Languages from style_bert_vits2.constants import Languages
from style_bert_vits2.nlp import bert_models from style_bert_vits2.nlp import bert_models
from style_bert_vits2.nlp.english.cmudict import get_dict from style_bert_vits2.nlp.english.cmudict import get_dict
from style_bert_vits2.nlp.symbols import PUNCTUATIONS, SYMBOLS from style_bert_vits2.nlp.symbols import PUNCTUATIONS, SYMBOLS
# Initialize global variables once
ARPA = {
"AH0", "S", "AH1", "EY2", "AE2", "EH0", "OW2", "UH0", "NG", "B", "G", "AY0",
"M", "AA0", "F", "AO0", "ER2", "UH1", "IY1", "AH2", "DH", "IY0", "EY1",
"IH0", "K", "N", "W", "IY2", "T", "AA1", "ER1", "EH2", "OY0", "UH2", "UW1",
"Z", "AW2", "AW1", "V", "UW2", "AA2", "ER", "AW0", "UW0", "R", "OW1", "EH1",
"ZH", "AE0", "IH2", "IH", "Y", "JH", "P", "AY1", "EY0", "OY2", "TH", "HH",
"D", "ER0", "CH", "AO1", "AE1", "AO2", "OY1", "AY2", "IH1", "OW0", "L",
"SH"
}
_g2p = G2p()
eng_dict = get_dict()
tokenizer = bert_models.load_tokenizer(Languages.EN)
def g2p(text: str) -> tuple[list[str], list[int], list[int]]: def g2p(text: str) -> tuple[list[str], list[int], list[int]]:
ARPA = {
"AH0",
"S",
"AH1",
"EY2",
"AE2",
"EH0",
"OW2",
"UH0",
"NG",
"B",
"G",
"AY0",
"M",
"AA0",
"F",
"AO0",
"ER2",
"UH1",
"IY1",
"AH2",
"DH",
"IY0",
"EY1",
"IH0",
"K",
"N",
"W",
"IY2",
"T",
"AA1",
"ER1",
"EH2",
"OY0",
"UH2",
"UW1",
"Z",
"AW2",
"AW1",
"V",
"UW2",
"AA2",
"ER",
"AW0",
"UW0",
"R",
"OW1",
"EH1",
"ZH",
"AE0",
"IH2",
"IH",
"Y",
"JH",
"P",
"AY1",
"EY0",
"OY2",
"TH",
"HH",
"D",
"ER0",
"CH",
"AO1",
"AE1",
"AO2",
"OY1",
"AY2",
"IH1",
"OW0",
"L",
"SH",
}
_g2p = G2p()
phones = [] phones = []
tones = [] tones = []
phone_len = [] phone_len = []
# tokens = [tokenizer.tokenize(i) for i in words]
words = __text_to_words(text) words = __text_to_words(text)
eng_dict = get_dict()
for word in words: for word in words:
temp_phones, temp_tones = [], [] temp_phones, temp_tones = [], []
if len(word) > 1: if len(word) > 1 and "'" in word:
if "'" in word: word = ["".join(word)]
word = ["".join(word)]
for w in word: for w in word:
if w in PUNCTUATIONS: if w in PUNCTUATIONS:
temp_phones.append(w) temp_phones.append(w)
@@ -107,11 +39,9 @@ def g2p(text: str) -> tuple[list[str], list[int], list[int]]:
phns, tns = __refine_syllables(eng_dict[w.upper()]) phns, tns = __refine_syllables(eng_dict[w.upper()])
temp_phones += [__post_replace_ph(i) for i in phns] temp_phones += [__post_replace_ph(i) for i in phns]
temp_tones += tns temp_tones += tns
# w2ph.append(len(phns))
else: else:
phone_list = list(filter(lambda p: p != " ", _g2p(w))) # type: ignore phone_list = list(filter(lambda p: p != " ", _g2p(w)))
phns = [] phns, tns = [], []
tns = []
for ph in phone_list: for ph in phone_list:
if ph in ARPA: if ph in ARPA:
ph, tn = __refine_ph(ph) ph, tn = __refine_ph(ph)
@@ -122,17 +52,15 @@ def g2p(text: str) -> tuple[list[str], list[int], list[int]]:
tns.append(0) tns.append(0)
temp_phones += [__post_replace_ph(i) for i in phns] temp_phones += [__post_replace_ph(i) for i in phns]
temp_tones += tns temp_tones += tns
phones += temp_phones phones += temp_phones
tones += temp_tones tones += temp_tones
phone_len.append(len(temp_phones)) phone_len.append(len(temp_phones))
# phones = [post_replace_ph(i) for i in phones]
word2ph = [] word2ph = []
for token, pl in zip(words, phone_len): for token, pl in zip(words, phone_len):
word_len = len(token) word_len = len(token)
word2ph += __distribute_phone(pl, word_len)
aaa = __distribute_phone(pl, word_len)
word2ph += aaa
phones = ["_"] + phones + ["_"] phones = ["_"] + phones + ["_"]
tones = [0] + tones + [0] tones = [0] + tones + [0]
@@ -145,27 +73,15 @@ def g2p(text: str) -> tuple[list[str], list[int], list[int]]:
def __post_replace_ph(ph: str) -> str: def __post_replace_ph(ph: str) -> str:
REPLACE_MAP = { REPLACE_MAP = {
"": ",", "": ",", "": ",", "": ",", "": ".", "": "!", "": "?",
"": ",", "\n": ".", "·": ",", "": ",", "": "...", "···": "...",
"": ",", "・・・": "...", "v": "V"
"": ".",
"": "!",
"": "?",
"\n": ".",
"·": ",",
"": ",",
"": "...",
"···": "...",
"・・・": "...",
"v": "V",
} }
if ph in REPLACE_MAP.keys(): if ph in REPLACE_MAP:
ph = REPLACE_MAP[ph] ph = REPLACE_MAP[ph]
if ph in SYMBOLS: if ph in SYMBOLS:
return ph return ph
if ph not in SYMBOLS: return "UNK"
ph = "UNK"
return ph
def __refine_ph(phn: str) -> tuple[str, int]: def __refine_ph(phn: str) -> tuple[str, int]:
@@ -182,8 +98,7 @@ def __refine_syllables(syllables: list[list[str]]) -> tuple[list[str], list[int]
tones = [] tones = []
phonemes = [] phonemes = []
for phn_list in syllables: for phn_list in syllables:
for i in range(len(phn_list)): for phn in phn_list:
phn = phn_list[i]
phn, tone = __refine_ph(phn) phn, tone = __refine_ph(phn)
phonemes.append(phn) phonemes.append(phn)
tones.append(tone) tones.append(tone)
@@ -200,7 +115,6 @@ def __distribute_phone(n_phone: int, n_word: int) -> list[int]:
def __text_to_words(text: str) -> list[list[str]]: def __text_to_words(text: str) -> list[list[str]]:
tokenizer = bert_models.load_tokenizer(Languages.EN)
tokens = tokenizer.tokenize(text) tokens = tokenizer.tokenize(text)
words = [] words = []
for idx, t in enumerate(tokens): for idx, t in enumerate(tokens):
@@ -211,10 +125,7 @@ def __text_to_words(text: str) -> list[list[str]]:
if idx == len(tokens) - 1: if idx == len(tokens) - 1:
words.append([f"{t}"]) words.append([f"{t}"])
else: else:
if ( if not tokens[idx + 1].startswith("") and tokens[idx + 1] not in PUNCTUATIONS:
not tokens[idx + 1].startswith("")
and tokens[idx + 1] not in PUNCTUATIONS
):
if idx == 0: if idx == 0:
words.append([]) words.append([])
words[-1].append(f"{t}") words[-1].append(f"{t}")
@@ -238,3 +149,4 @@ if __name__ == "__main__":
# for ph in group: # for ph in group:
# all_phones.add(ph) # all_phones.add(ph)
# print(all_phones) # print(all_phones)