mirror of
https://github.com/storytold/storyteller-ml.git
synced 2026-10-28 09:08:54 +00:00
Espeak phonemizer pipeline for spanish (and also english)
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
from typing import List
|
||||
from text.pipeline.base_pipeline import BasePipeline
|
||||
from text.pipeline_components.input_parsing.parser import ArpabetSequence, GraphemeSequence, ParsedSequence, parse_grapheme_and_arpabet_sequence
|
||||
from text.pipeline_components.normalization.espeak_normalization import normalize
|
||||
from text.pipeline_components.phonetization.espeak_phonemization import EspeakPhonetization
|
||||
from text.pipeline_components.sequencing.espeak_symbols import Symbols
|
||||
|
||||
class EspeakPipeline(BasePipeline):
|
||||
"""
|
||||
This is a new text pipeline for FakeYou that will be introduced in July 2022.
|
||||
It introduces Arpabet and individually upgradable components.
|
||||
The code is not 1:1 with our notebooks, but we'll go to efforts to make sure that
|
||||
the model input expectations on both sides match one another.
|
||||
"""
|
||||
|
||||
def __init__(self, lang='en'):
|
||||
self.lang = lang
|
||||
symbols = Symbols(lang)
|
||||
self.symbols_to_sequence = symbols.symbols_to_sequence
|
||||
self.arpabet_to_sequence = symbols.arpabet_to_sequence
|
||||
self.sequence_to_text = symbols.sequence_to_text
|
||||
self.SPACE_INTEGER_ENCODING = symbols.SPACE_INTEGER_ENCODING
|
||||
|
||||
self.phonetization = EspeakPhonetization(lang)
|
||||
|
||||
def user_input_to_sequence(self, input_text: str) -> List[int]:
|
||||
"""Convert raw user input into a numerical sequence for ML inference."""
|
||||
|
||||
parsed_sequence = parse_grapheme_and_arpabet_sequence(input_text)
|
||||
self._normalize_graphemes(parsed_sequence)
|
||||
|
||||
parsed_sequence = self._convert_phonemes(parsed_sequence)
|
||||
|
||||
return self._convert_to_integer_sequence(parsed_sequence)
|
||||
|
||||
def sequence_to_text(self, input_sequence: List[int]) -> str:
|
||||
return self.sequence_to_text(input_sequence)
|
||||
|
||||
def _normalize_graphemes(self, parsed_sequence: ParsedSequence):
|
||||
for i in range(len(parsed_sequence)):
|
||||
subsequence = parsed_sequence[i]
|
||||
if isinstance(subsequence, GraphemeSequence):
|
||||
normalized = normalize(subsequence.sequence, self.lang)
|
||||
parsed_sequence[i] = GraphemeSequence(normalized)
|
||||
|
||||
|
||||
def _convert_phonemes(self, parsed_sequence: ParsedSequence) -> ParsedSequence:
|
||||
# NB: We will likely break grapheme runs into multiple arpabet sequences, extending the
|
||||
# output list length.
|
||||
updated_sequence = []
|
||||
|
||||
for subsequence in parsed_sequence:
|
||||
if isinstance(subsequence, ArpabetSequence):
|
||||
updated_sequence.append(subsequence)
|
||||
|
||||
elif isinstance(subsequence, GraphemeSequence):
|
||||
converted_sequence = self.phonetization.try_convert_to_phonemes(subsequence.sequence)
|
||||
updated_sequence.extend(converted_sequence)
|
||||
|
||||
return updated_sequence
|
||||
|
||||
def _convert_to_integer_sequence(self, parsed_sequence: ParsedSequence) -> List[int]:
|
||||
integer_sequence = []
|
||||
last_index = len(parsed_sequence) - 1
|
||||
|
||||
for i, subsequence in enumerate(parsed_sequence):
|
||||
integer_subsequence = []
|
||||
|
||||
if isinstance(subsequence, ArpabetSequence):
|
||||
integer_subsequence = self.arpabet_to_sequence(subsequence.sequence)
|
||||
elif isinstance(subsequence, GraphemeSequence):
|
||||
integer_subsequence = self.symbols_to_sequence(subsequence.sequence)
|
||||
|
||||
if integer_subsequence:
|
||||
integer_sequence.extend(integer_subsequence)
|
||||
|
||||
if i < last_index and integer_sequence[-1] != self.SPACE_INTEGER_ENCODING:
|
||||
# Separate words with single spaces if not already present.
|
||||
integer_sequence.append(self.SPACE_INTEGER_ENCODING)
|
||||
|
||||
return integer_sequence
|
||||
Reference in New Issue
Block a user