mirror of
https://github.com/storytold/vits-finetuning.git
synced 2026-10-18 07:33:53 +00:00
Initial commit (move files)
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2017 Keith Ito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,100 @@
|
||||
""" from https://github.com/keithito/tacotron """
|
||||
from text import cleaners
|
||||
from text.symbols import symbols
|
||||
import re
|
||||
|
||||
|
||||
# Mappings from symbol to numeric ID and vice versa:
|
||||
_symbol_to_id = {s: i for i, s in enumerate(symbols)}
|
||||
_id_to_symbol = {i: s for i, s in enumerate(symbols)}
|
||||
|
||||
# Regular expression matching text enclosed in curly braces:
|
||||
_curly_re = re.compile(r"(.*?)\{(.+?)\}(.*)")
|
||||
|
||||
|
||||
def text_to_sequence(text, cleaner_names):
|
||||
"""Converts a string of text to a sequence of IDs corresponding to the symbols in the text.
|
||||
|
||||
The text can optionally have ARPAbet sequences enclosed in curly braces embedded
|
||||
in it. For example, "Turn left on {HH AW1 S S T AH0 N} Street."
|
||||
|
||||
Args:
|
||||
text: string to convert to a sequence
|
||||
cleaner_names: names of the cleaner functions to run the text through
|
||||
|
||||
Returns:
|
||||
List of integers corresponding to the symbols in the text
|
||||
"""
|
||||
sequence = []
|
||||
|
||||
# Check for curly braces and treat their contents as ARPAbet:
|
||||
while len(text):
|
||||
m = _curly_re.match(text)
|
||||
|
||||
if not m:
|
||||
sequence += _symbols_to_sequence(_clean_text(text, cleaner_names))
|
||||
break
|
||||
sequence += _symbols_to_sequence(_clean_text(m.group(1), cleaner_names))
|
||||
sequence += _arpabet_to_sequence(m.group(2))
|
||||
text = m.group(3)
|
||||
|
||||
return sequence
|
||||
|
||||
|
||||
def cleaned_text_to_sequence(cleaned_text):
|
||||
"""Converts a cleaned string of text to a sequence of IDs corresponding to the symbols in the text.
|
||||
|
||||
The text can optionally have ARPAbet sequences enclosed in curly braces embedded
|
||||
in it. For example, "Turn left on {HH AW1 S S T AH0 N} Street."
|
||||
|
||||
Args:
|
||||
text: string to convert to a sequence
|
||||
cleaner_names: names of the cleaner functions to run the text through
|
||||
|
||||
Returns:
|
||||
List of integers corresponding to the symbols in the text
|
||||
"""
|
||||
sequence = []
|
||||
|
||||
# Check for curly braces and treat their contents as ARPAbet:
|
||||
while len(cleaned_text):
|
||||
m = _curly_re.match(cleaned_text)
|
||||
|
||||
if not m:
|
||||
sequence += _symbols_to_sequence(cleaned_text)
|
||||
break
|
||||
sequence += _symbols_to_sequence(m.group(1))
|
||||
sequence += _arpabet_to_sequence(m.group(2))
|
||||
cleaned_text = m.group(3)
|
||||
|
||||
return sequence
|
||||
|
||||
|
||||
def sequence_to_text(sequence):
|
||||
'''Converts a sequence of IDs back to a string'''
|
||||
result = ''
|
||||
for symbol_id in sequence:
|
||||
s = _id_to_symbol[symbol_id]
|
||||
result += s
|
||||
return result
|
||||
|
||||
|
||||
def _clean_text(text, cleaner_names):
|
||||
for name in cleaner_names:
|
||||
cleaner = getattr(cleaners, name)
|
||||
if not cleaner:
|
||||
raise Exception('Unknown cleaner: %s' % name)
|
||||
text = cleaner(text)
|
||||
return text
|
||||
|
||||
|
||||
def _symbols_to_sequence(symbols):
|
||||
return [_symbol_to_id[s] for s in symbols if _should_keep_symbol(s)]
|
||||
|
||||
|
||||
def _arpabet_to_sequence(text):
|
||||
return _symbols_to_sequence(['@' + s for s in text.split()])
|
||||
|
||||
|
||||
def _should_keep_symbol(s):
|
||||
return s in _symbol_to_id and s is not '_' and s is not '~'
|
||||
@@ -0,0 +1,63 @@
|
||||
from g2p_en import G2p
|
||||
import gdown
|
||||
import os
|
||||
|
||||
class ARPAPhonemizer():
|
||||
def __init__(self, dict_override = ""):
|
||||
dict_fn = "zdict.txt" if not len(dict_override) else dict_override
|
||||
|
||||
if not len(dict_override) and not os.path.isfile(dict_fn):
|
||||
print("Downloading ARPA dict..")
|
||||
gdown.download("https://drive.google.com/file/d/1lYKcml_bkTiOke2TMF3F_fn7UWTYHNWp/view?usp=share_link", dict_fn, fuzzy=True, quiet=False)
|
||||
|
||||
self.arpa_dict = self._load_dict(dict_fn)
|
||||
self.g2p = G2p()
|
||||
|
||||
|
||||
def _load_dict(self, in_dpath):
|
||||
dict_ret = {}
|
||||
|
||||
with open(in_dpath,encoding="utf-8-sig") as f:
|
||||
d_lines = f.readlines()
|
||||
|
||||
last_word = ""
|
||||
for d_li in d_lines:
|
||||
splits = d_li.strip().split("\t")
|
||||
|
||||
word = splits[0]
|
||||
pron = splits[1]
|
||||
|
||||
#only accept 1st entry for each word
|
||||
if word == last_word:
|
||||
continue
|
||||
|
||||
dict_ret[word] = pron
|
||||
last_word = word
|
||||
|
||||
return dict_ret
|
||||
|
||||
def _g2pfil(self, intxt):
|
||||
sta = self.g2p(intxt)
|
||||
ret = " ".join(sta)
|
||||
return ret
|
||||
|
||||
def doARPA(self, text):
|
||||
if text[0] == '{':
|
||||
return text
|
||||
out = ''
|
||||
for word_ in text.split(" "):
|
||||
word=word_; end_chars = ''
|
||||
while any(elem in word for elem in r"!?,.;") and len(word) > 1:
|
||||
if word[-1] == '!': end_chars = '!' + end_chars; word = word[:-1]
|
||||
if word[-1] == '?': end_chars = '?' + end_chars; word = word[:-1]
|
||||
if word[-1] == ',': end_chars = ',' + end_chars; word = word[:-1]
|
||||
if word[-1] == '.': end_chars = '.' + end_chars; word = word[:-1]
|
||||
if word[-1] == ';': end_chars = ';' + end_chars; word = word[:-1]
|
||||
else: break
|
||||
try: word_arpa = self.arpa_dict[word.lower()]
|
||||
except: word_arpa = self._g2pfil(word)
|
||||
if len(word_arpa)!=0: word = "{" + str(word_arpa) + "}"
|
||||
out = (out + " " + word + end_chars).strip()
|
||||
|
||||
return out
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
""" from https://github.com/keithito/tacotron """
|
||||
|
||||
'''
|
||||
Cleaners are transformations that run over the input text at both training and eval time.
|
||||
|
||||
Cleaners can be selected by passing a comma-delimited list of cleaner names as the "cleaners"
|
||||
hyperparameter. Some cleaners are English-specific. You'll typically want to use:
|
||||
1. "english_cleaners" for English text
|
||||
2. "transliteration_cleaners" for non-English text that can be transliterated to ASCII using
|
||||
the Unidecode library (https://pypi.python.org/pypi/Unidecode)
|
||||
3. "basic_cleaners" if you do not want to transliterate (in this case, you should also update
|
||||
the symbols in symbols.py to match your data).
|
||||
'''
|
||||
|
||||
import re
|
||||
from unidecode import unidecode
|
||||
from phonemizer import phonemize
|
||||
import phonemizer
|
||||
from .arpa import ARPAPhonemizer
|
||||
|
||||
global_phonemizer = phonemizer.backend.EspeakBackend(language='en-us', preserve_punctuation=True, with_stress=True)
|
||||
spanish_phonemizer = phonemizer.backend.EspeakBackend(language='es-419', preserve_punctuation=True, with_stress=True)
|
||||
|
||||
fest_phonemizer = phonemizer.backend.FestivalBackend(language='en-us', preserve_punctuation=True)
|
||||
arpa_phonemizer = ARPAPhonemizer()
|
||||
|
||||
|
||||
|
||||
|
||||
# Regular expression matching whitespace:
|
||||
_whitespace_re = re.compile(r'\s+')
|
||||
|
||||
# List of (regular expression, replacement) pairs for abbreviations:
|
||||
_abbreviations = [(re.compile('\\b%s\\.' % x[0], re.IGNORECASE), x[1]) for x in [
|
||||
('mrs', 'misess'),
|
||||
('mr', 'mister'),
|
||||
('dr', 'doctor'),
|
||||
('st', 'saint'),
|
||||
('co', 'company'),
|
||||
('jr', 'junior'),
|
||||
('maj', 'major'),
|
||||
('gen', 'general'),
|
||||
('drs', 'doctors'),
|
||||
('rev', 'reverend'),
|
||||
('lt', 'lieutenant'),
|
||||
('hon', 'honorable'),
|
||||
('sgt', 'sergeant'),
|
||||
('capt', 'captain'),
|
||||
('esq', 'esquire'),
|
||||
('ltd', 'limited'),
|
||||
('col', 'colonel'),
|
||||
('ft', 'fort'),
|
||||
]]
|
||||
|
||||
|
||||
def expand_abbreviations(text):
|
||||
for regex, replacement in _abbreviations:
|
||||
text = re.sub(regex, replacement, text)
|
||||
return text
|
||||
|
||||
|
||||
def expand_numbers(text):
|
||||
return normalize_numbers(text)
|
||||
|
||||
|
||||
def lowercase(text):
|
||||
return text.lower()
|
||||
|
||||
|
||||
def collapse_whitespace(text):
|
||||
return re.sub(_whitespace_re, ' ', text)
|
||||
|
||||
|
||||
def convert_to_ascii(text):
|
||||
return unidecode(text)
|
||||
|
||||
|
||||
def basic_cleaners(text):
|
||||
'''Basic pipeline that lowercases and collapses whitespace without transliteration.'''
|
||||
text = lowercase(text)
|
||||
text = collapse_whitespace(text)
|
||||
return text
|
||||
|
||||
|
||||
def transliteration_cleaners(text):
|
||||
'''Pipeline for non-English text that transliterates to ASCII.'''
|
||||
text = convert_to_ascii(text)
|
||||
text = lowercase(text)
|
||||
text = collapse_whitespace(text)
|
||||
return text
|
||||
|
||||
|
||||
def english_cleaners(text):
|
||||
'''Pipeline for English text, including abbreviation expansion.'''
|
||||
text = convert_to_ascii(text)
|
||||
text = lowercase(text)
|
||||
text = expand_abbreviations(text)
|
||||
phonemes = phonemize(text, language='en-us', backend='espeak', strip=True)
|
||||
phonemes = collapse_whitespace(phonemes)
|
||||
return phonemes
|
||||
|
||||
|
||||
def english_cleaners2(text):
|
||||
'''Pipeline for English text, including abbreviation expansion. + punctuation + stress'''
|
||||
text = convert_to_ascii(text)
|
||||
text = lowercase(text)
|
||||
text = expand_abbreviations(text)
|
||||
phonemes = global_phonemizer.phonemize([text], strip=True, njobs=1)
|
||||
phonemes = phonemes[0]
|
||||
phonemes = collapse_whitespace(phonemes)
|
||||
return phonemes
|
||||
|
||||
def f_english_cleaners2(text):
|
||||
'''Pipeline for English text with Festival phonemizer, including abbreviation expansion. + punctuation'''
|
||||
text = convert_to_ascii(text)
|
||||
text = lowercase(text)
|
||||
text = expand_abbreviations(text)
|
||||
phonemes = fest_phonemizer.phonemize([text], strip=True, njobs=1)
|
||||
phonemes = phonemes[0]
|
||||
phonemes = collapse_whitespace(phonemes)
|
||||
return phonemes
|
||||
|
||||
def arpa_precleaners(text):
|
||||
'''Pipeline for English text before ARPA'''
|
||||
text = convert_to_ascii(text)
|
||||
text = lowercase(text)
|
||||
text = expand_abbreviations(text)
|
||||
|
||||
return text
|
||||
|
||||
def arpa_cleaners(text):
|
||||
'''Pipeline for ARPA English text, including abbreviation expansion. + punctuation + stress'''
|
||||
text = convert_to_ascii(text)
|
||||
text = lowercase(text)
|
||||
text = expand_abbreviations(text)
|
||||
phonemes = arpa_phonemizer.doARPA(text)
|
||||
|
||||
return phonemes
|
||||
|
||||
def spanish_cleaners(text):
|
||||
'''Pipeline for Spanish text, punctuation + stress'''
|
||||
text = lowercase(text)
|
||||
phonemes = spanish_phonemizer.phonemize([text], strip=True, njobs=1)
|
||||
phonemes = phonemes[0].replace("(es-419)","").replace("(en)","")
|
||||
phonemes = collapse_whitespace(phonemes)
|
||||
return phonemes
|
||||
@@ -0,0 +1,22 @@
|
||||
""" from https://github.com/keithito/tacotron """
|
||||
|
||||
'''
|
||||
Defines the set of symbols used in text input to the model.
|
||||
'''
|
||||
from g2p_en import g2p as grapheme_to_phonem
|
||||
g2p = grapheme_to_phonem.G2p()
|
||||
|
||||
_pad = '_'
|
||||
_punctuation = ';:,.!?¡¿—…"«»“” '
|
||||
_letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
_letters_ipa = "ɑɐɒæɓʙβɔɕçɗɖðʤəɘɚɛɜɝɞɟʄɡɠɢʛɦɧħɥʜɨɪʝɭɬɫɮʟɱɯɰŋɳɲɴøɵɸθœɶʘɹɺɾɻʀʁɽʂʃʈʧʉʊʋⱱʌɣɤʍχʎʏʑʐʒʔʡʕʢǀǁǂǃˈˌːˑʼʴʰʱʲʷˠˤ˞↓↑→↗↘'̩'ᵻ"
|
||||
arpa_sym = g2p.phonemes
|
||||
_arpabet = ["@" + s for s in arpa_sym]
|
||||
|
||||
|
||||
|
||||
# Export all symbols:
|
||||
symbols = [_pad] + list(_punctuation) + list(_letters) + list(_letters_ipa) + _arpabet
|
||||
|
||||
# Special symbol ids
|
||||
SPACE_ID = symbols.index(" ")
|
||||
Reference in New Issue
Block a user