File size: 7,856 Bytes
77852b1
 
 
 
 
 
 
 
41bb41d
 
 
77852b1
d08ac9f
77852b1
 
 
d08ac9f
 
 
 
 
77852b1
 
 
d08ac9f
77852b1
 
 
41bb41d
d08ac9f
77852b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41bb41d
77852b1
 
41bb41d
 
 
77852b1
 
 
41bb41d
77852b1
41bb41d
77852b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41bb41d
 
 
 
77852b1
 
d08ac9f
41bb41d
 
 
d08ac9f
 
 
 
 
77852b1
41bb41d
77852b1
41bb41d
 
77852b1
41bb41d
77852b1
 
 
 
d08ac9f
41bb41d
 
 
77852b1
41bb41d
 
 
 
 
77852b1
d08ac9f
77852b1
d08ac9f
 
 
 
 
 
77852b1
 
41bb41d
 
 
77852b1
 
 
d08ac9f
 
 
 
 
 
 
 
e4c3a70
41bb41d
 
 
77852b1
 
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
import torch
import soundfile as sf
import gradio as gr
from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech
from transformers import SpeechT5HifiGan
from datasets import load_dataset
from IPython.display import Audio
import numpy as np
import math
import re

#processor
processor = SpeechT5Processor.from_pretrained("trangiabao17032000/final_tts")
tokenizer = processor.tokenizer

#model
model_model_tts_mix = SpeechT5ForTextToSpeech.from_pretrained("trangiabao17032000/model_tts_mix")
model_model_tts_mix.eval()

model_final_tts = SpeechT5ForTextToSpeech.from_pretrained("trangiabao17032000/final_tts")
model_final_tts.eval()

#vocoder
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
vocoder.eval()

#speaker embedding
embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")

speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)

#cleaner text
def convert_string_to_numbers(input_str):
    try:
        # Replace comma with period and attempt to convert the string to a float
        num = float(input_str.replace(',', '.'))
        if num.is_integer():
            return int(num)
        return num
    except ValueError:
        # If it's not a valid float, check if it's an integer or a negative integer
        if input_str.replace('.', '', 1).isdigit():  # Remove one dot for checking integers
            return int(input_str.replace(',', ''))
        elif input_str[0] == '-' and input_str[1:].replace('.', '', 1).isdigit():
            return int(input_str.replace(',', ''))
        else:
            raise ValueError("Invalid input: couldn't convert to a number")

def number_to_vietnamese_words(number):
    ones = ['', 'một', 'hai', 'ba', 'bốn', 'năm', 'sáu', 'bảy', 'tám', 'chín']
    tens = ['', 'mười', 'hai mươi', 'ba mươi', 'bốn mươi', 'năm mươi', 'sáu mươi', 'bảy mươi', 'tám mươi', 'chín mươi']
    hundreds = ['', 'một trăm', 'Hai trăm', 'ba trăm', 'bốn trăm', 'năm trăm', 'sáu trăm', 'bảy trăm', 'tám trăm', 'chín trăm']
    thousands = [''] + ['nghìn', 'triệu', 'tỷ']

    def words(n):

        if n < 10:
            return ones[n]
        elif n < 20:
            return tens[n//10]  + " " + words(n % 10)
        elif n < 100:
            return tens[n // 10] + ('' if n % 10 == 0 else ' ' + ones[n % 10])
        else:
            return hundreds[n // 100] + ('' if n % 100 == 0 else (' lẻ ' if n % 100 < 10 else ' ') + words(n % 100))

    if number == 0:
        return 'không'

    integer_part = int(number)
    decimal_part = round((number - integer_part) * 100)  # Round the decimal part to 2 decimal places

    result = []
    i = 0
    while integer_part > 0:
        if integer_part % 1000 != 0:
            result.append(words(integer_part % 1000) + (' ' + thousands[i] if i > 0 else ''))
        integer_part //= 1000
        i += 1

    result_integer = ' '.join(result[::-1])

    result_decimal = ''
    if decimal_part > 0:
        result_decimal = ' phẩy'
        for digit in str(decimal_part):
            result_decimal += ' ' + ones[int(digit)]

    return result_integer + result_decimal

def is_num(string):
    try:
        temp = float(string)
        if math.isnan(temp):
          return False
    except ValueError:
        return False
    return True

def normalize(input):
     input = input.strip().lower()
     newstr = map(lambda x: number_to_vietnamese_words(convert_string_to_numbers(x)) if is_num(x) else x, input.split(" "))
     return ' '.join(newstr)

def split_paragraph_into_sentences(paragraph, max_chars = 300):
    sentences = []
    words = paragraph.split()
    current_sentence = words[0]

    for word in words[1:]:
        if len(current_sentence) + len(word) + 1 <= max_chars:
            current_sentence += ' ' + word
        else:
            sentences.append(current_sentence)
            current_sentence = word

    if current_sentence:
        sentences.append(current_sentence)

    return sentences


def cleanup_text(inputs):
    return re.sub('[0-9]', '', inputs.strip().lower())
    
# generator speech
def text_to_speech(paragraph, model_selected):
    if len(paragraph.strip()) == 0:
        return (16000, np.zeros(0).astype(np.int16))

    if model_selected == "final_tts":
      model_generate = model_final_tts
    else:
      model_generate = model_model_tts_mix

    try:
      paragraph = normalize(str(paragraph))
    except:
      paragraph = cleanup_text(paragraph)

    list_sentence = split_paragraph_into_sentences(paragraph)

    final_speech = np.array([])
    for sentence in list_sentence:

      inputs = processor(text=sentence, return_tensors="pt")
      spectrogram = model_generate.generate_speech(inputs["input_ids"], speaker_embeddings)
      with torch.no_grad():
        speech = vocoder(spectrogram)

      final_speech = np.concatenate((final_speech,  speech.numpy()))

    final_speech = (final_speech * 32767).astype(np.int16)
    return (16000, final_speech)
    # sf.write("tts_example.wav", final_speech, samplerate=16000)
    # return "tts_example.wav"


tts_examples = [
    ["xin chào mọi người, đây là sản phẩm thử nghiệm cho tiếng việt.", "final_tts"],
    ["xin chào mọi người, đây là sản phẩm thử nghiệm cho tiếng việt.", "model_tts_mix"],
    ["Mình sẽ tổ chức sinh nhật vào thứ 6 ngày 7 tháng này", "final_tts"],
    ["Mình sẽ tổ chức sinh nhật vào thứ 6 ngày 7 tháng này", "model_tts_mix"],
    ["Mùa thu đã đến với sự thanh bình và mát mẻ. Trời cao trải dài một tấm bầu trời xanh thăm thẳm, và những tia nắng ấm áp từ mặt trời chiếu sáng tỏa rạng. Nhiệt độ trong khoảng từ 20 đến 25 độ Celsius khiến cho không khí trở nên dễ chịu, đủ để ta cảm nhận sự se lạnh của mùa thu đang về. Các cây cỏ bắt đầu thay đổi màu sắc, chuyển từ màu xanh tươi sang những gam màu ấm áp và rực rỡ. Mọi người bắt đầu khoác lên mình những chiếc áo len mỏng và khăn quàng cổ để giữ ấm. Mùa thu thật sự là thời điểm tuyệt vời để thưởng thức cái se lạnh dịu dàng và cảm nhận sự thay đổi của thiên nhiên.", "final_tts"],
    ["Mùa thu đã đến với sự thanh bình và mát mẻ. Trời cao trải dài một tấm bầu trời xanh thăm thẳm, và những tia nắng ấm áp từ mặt trời chiếu sáng tỏa rạng. Nhiệt độ trong khoảng từ 20 đến 25 độ Celsius khiến cho không khí trở nên dễ chịu, đủ để ta cảm nhận sự se lạnh của mùa thu đang về. Các cây cỏ bắt đầu thay đổi màu sắc, chuyển từ màu xanh tươi sang những gam màu ấm áp và rực rỡ. Mọi người bắt đầu khoác lên mình những chiếc áo len mỏng và khăn quàng cổ để giữ ấm. Mùa thu thật sự là thời điểm tuyệt vời để thưởng thức cái se lạnh dịu dàng và cảm nhận sự thay đổi của thiên nhiên.", "model_tts_mix"]
]

title = "SpeechT5:Text-To-Speech"

description ="Nhập bất kỳ văn bản nào và mô hình sẽ chuyển nó thành giọng nói."
#gradio interface
iface = gr.Interface(
    fn=text_to_speech,
    inputs=[
        gr.Textbox("xin chào mọi người, đây là sản phẩm thử nghiệm cho tiếng việt.", label="Văn bản đầu vào"),
        gr.Radio(label="Model", choices=[
            "final_tts",
            "model_tts_mix"
        ],
        value="final_tts"),
    ],
    outputs=gr.Audio(label="Audio kết quả", streaming= True, type="numpy"),
    title=title,
    description=description,
    examples=tts_examples
)
iface.launch()