hoanglinhn0 commited on
Commit
186ca64
·
1 Parent(s): dd48e8c

Upload 4 files

Browse files
Files changed (3) hide show
  1. app.py +101 -0
  2. config.json +504 -0
  3. requirements.txt +11 -0
app.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import onnxruntime as ort
3
+ import numpy as np
4
+ import json
5
+ from vinorm import TTSnorm
6
+ from underthesea import word_tokenize
7
+
8
+ # --- 1. CẤU HÌNH & LOAD MODEL ---
9
+ MODEL_PATH = "model.onnx"
10
+ SAMPLE_RATE = 22050 # Thay đổi theo model của bạn (22050, 24000, hoặc 44100)
11
+
12
+ # Khởi tạo session ONNX
13
+ try:
14
+ sess = ort.InferenceSession(MODEL_PATH, providers=['CPUExecutionProvider'])
15
+ print("✅ Model ONNX đã tải thành công!")
16
+ except Exception as e:
17
+ print(f"❌ Lỗi tải model: {e}")
18
+
19
+ # --- 2. LOGIC CHUYỂN ĐỔI VĂN BẢN (PHONEMIZER) ---
20
+ # LƯU Ý: Mỗi model TTS có một bộ từ điển (map ký tự -> số) riêng.
21
+ # Bạn nên có file 'config.json' đi kèm model. Dưới đây là logic mẫu:
22
+
23
+ def text_to_sequence(text):
24
+ """
25
+ Chuyển đổi văn bản tiếng Việt sang danh sách ID số nguyên.
26
+ """
27
+ # Bước A: Chuẩn hóa văn bản (Ví dụ: "100k" -> "một trăm nghìn đồng")
28
+ text = TTSnorm(text)
29
+
30
+ # Bước B: Tách từ/âm tiết
31
+ # tokens = word_tokenize(text) # Có thể dùng nếu model học theo từ
32
+
33
+ # Bước C: Chuyển ký tự thành ID (Đây là logic giả lập, bạn cần khớp với bộ vocab của model)
34
+ # Thông thường model sẽ có một dictionary như: {'a': 1, 'b': 2, 'tr': 50...}
35
+ # Ở đây tôi ví dụ chuyển từng ký tự thành mã ASCII đơn giản:
36
+ sequence = [ord(c) for c in text.lower() if ord(c) < 500]
37
+
38
+ return sequence
39
+
40
+ # --- 3. HÀM XỬ LÝ CHÍNH (INFERENCE) ---
41
+ def tts_predict(text, speed, noise, noise_w):
42
+ if not text.strip():
43
+ return "Vui lòng nhập văn bản", None
44
+
45
+ try:
46
+ # Chuyển text thành sequence IDs
47
+ sequence = text_to_sequence(text)
48
+ input_ids = np.array([sequence], dtype=np.int64)
49
+ input_lengths = np.array([len(sequence)], dtype=np.int64)
50
+
51
+ # Scales: [noise_scale, noise_scale_w, length_scale (speed)]
52
+ # Lưu ý: Thứ tự 3 số này phải khớp với model của bạn (thường là vậy)
53
+ scales = np.array([noise, noise_w, 1.0/speed], dtype=np.float32)
54
+
55
+ # Chạy model
56
+ # Tên input phải khớp với ảnh Netron của bạn: 'input', 'input_lengths', 'scales'
57
+ inputs = {
58
+ "input": input_ids,
59
+ "input_lengths": input_lengths,
60
+ "scales": scales
61
+ }
62
+
63
+ outputs = sess.run(None, inputs)
64
+ audio = outputs[0].squeeze() # Loại bỏ các chiều dư thừa
65
+
66
+ return "Tạo âm thanh thành công!", (SAMPLE_RATE, audio)
67
+
68
+ except Exception as e:
69
+ return f"Lỗi: {str(e)}", None
70
+
71
+ # --- 4. GIAO DIỆN GRADIO ---
72
+ with gr.Blocks(title="Vietnamese TTS ONNX") as demo:
73
+ gr.Markdown("# 🇻🇳 Vietnamese TTS với ONNX & Vinorm")
74
+ gr.Markdown("Ứng dụng sử dụng `vinorm` để xử lý số/ký hiệu và `underthesea` để tối ưu tiếng Việt.")
75
+
76
+ with gr.Row():
77
+ with gr.Column():
78
+ input_text = gr.Textbox(
79
+ label="Văn bản đầu vào",
80
+ placeholder="Ví dụ: Giá của chiếc máy này là 5.000.000đ",
81
+ lines=4
82
+ )
83
+ with gr.Row():
84
+ speed = gr.Slider(0.5, 2.0, value=1.0, step=0.1, label="Tốc độ (Speed)")
85
+ noise = gr.Slider(0.1, 1.0, value=0.667, step=0.01, label="Độ nhiễu (Noise)")
86
+ noise_w = gr.Slider(0.1, 1.0, value=0.8, step=0.01, label="Noise W")
87
+
88
+ run_btn = gr.Button("Tạo giọng nói", variant="primary")
89
+
90
+ with gr.Column():
91
+ status_msg = gr.Textbox(label="Trạng thái")
92
+ audio_out = gr.Audio(label="Kết quả Audio")
93
+
94
+ run_btn.click(
95
+ fn=tts_predict,
96
+ inputs=[input_text, speed, noise, noise_w],
97
+ outputs=[status_msg, audio_out]
98
+ )
99
+
100
+ if __name__ == "__main__":
101
+ demo.launch()
config.json ADDED
@@ -0,0 +1,504 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "audio": {
3
+ "sample_rate": 22050
4
+ },
5
+ "espeak": {
6
+ "voice": "vi"
7
+ },
8
+ "phoneme_type": "espeak",
9
+ "num_symbols": 256,
10
+ "num_speakers": 1,
11
+ "inference": {
12
+ "noise_scale": 0.667,
13
+ "length_scale": 1.0,
14
+ "noise_w": 0.8
15
+ },
16
+ "phoneme_id_map": {
17
+ "_": [
18
+ 0
19
+ ],
20
+ "^": [
21
+ 1
22
+ ],
23
+ "$": [
24
+ 2
25
+ ],
26
+ " ": [
27
+ 3
28
+ ],
29
+ "!": [
30
+ 4
31
+ ],
32
+ "'": [
33
+ 5
34
+ ],
35
+ "(": [
36
+ 6
37
+ ],
38
+ ")": [
39
+ 7
40
+ ],
41
+ ",": [
42
+ 8
43
+ ],
44
+ "-": [
45
+ 9
46
+ ],
47
+ ".": [
48
+ 10
49
+ ],
50
+ ":": [
51
+ 11
52
+ ],
53
+ ";": [
54
+ 12
55
+ ],
56
+ "?": [
57
+ 13
58
+ ],
59
+ "a": [
60
+ 14
61
+ ],
62
+ "b": [
63
+ 15
64
+ ],
65
+ "c": [
66
+ 16
67
+ ],
68
+ "d": [
69
+ 17
70
+ ],
71
+ "e": [
72
+ 18
73
+ ],
74
+ "f": [
75
+ 19
76
+ ],
77
+ "h": [
78
+ 20
79
+ ],
80
+ "i": [
81
+ 21
82
+ ],
83
+ "j": [
84
+ 22
85
+ ],
86
+ "k": [
87
+ 23
88
+ ],
89
+ "l": [
90
+ 24
91
+ ],
92
+ "m": [
93
+ 25
94
+ ],
95
+ "n": [
96
+ 26
97
+ ],
98
+ "o": [
99
+ 27
100
+ ],
101
+ "p": [
102
+ 28
103
+ ],
104
+ "q": [
105
+ 29
106
+ ],
107
+ "r": [
108
+ 30
109
+ ],
110
+ "s": [
111
+ 31
112
+ ],
113
+ "t": [
114
+ 32
115
+ ],
116
+ "u": [
117
+ 33
118
+ ],
119
+ "v": [
120
+ 34
121
+ ],
122
+ "w": [
123
+ 35
124
+ ],
125
+ "x": [
126
+ 36
127
+ ],
128
+ "y": [
129
+ 37
130
+ ],
131
+ "z": [
132
+ 38
133
+ ],
134
+ "æ": [
135
+ 39
136
+ ],
137
+ "ç": [
138
+ 40
139
+ ],
140
+ "ð": [
141
+ 41
142
+ ],
143
+ "ø": [
144
+ 42
145
+ ],
146
+ "ħ": [
147
+ 43
148
+ ],
149
+ "ŋ": [
150
+ 44
151
+ ],
152
+ "œ": [
153
+ 45
154
+ ],
155
+ "ǀ": [
156
+ 46
157
+ ],
158
+ "ǁ": [
159
+ 47
160
+ ],
161
+ "ǂ": [
162
+ 48
163
+ ],
164
+ "ǃ": [
165
+ 49
166
+ ],
167
+ "ɐ": [
168
+ 50
169
+ ],
170
+ "ɑ": [
171
+ 51
172
+ ],
173
+ "ɒ": [
174
+ 52
175
+ ],
176
+ "ɓ": [
177
+ 53
178
+ ],
179
+ "ɔ": [
180
+ 54
181
+ ],
182
+ "ɕ": [
183
+ 55
184
+ ],
185
+ "ɖ": [
186
+ 56
187
+ ],
188
+ "ɗ": [
189
+ 57
190
+ ],
191
+ "ɘ": [
192
+ 58
193
+ ],
194
+ "ə": [
195
+ 59
196
+ ],
197
+ "ɚ": [
198
+ 60
199
+ ],
200
+ "ɛ": [
201
+ 61
202
+ ],
203
+ "ɜ": [
204
+ 62
205
+ ],
206
+ "ɞ": [
207
+ 63
208
+ ],
209
+ "ɟ": [
210
+ 64
211
+ ],
212
+ "ɠ": [
213
+ 65
214
+ ],
215
+ "ɡ": [
216
+ 66
217
+ ],
218
+ "ɢ": [
219
+ 67
220
+ ],
221
+ "ɣ": [
222
+ 68
223
+ ],
224
+ "ɤ": [
225
+ 69
226
+ ],
227
+ "ɥ": [
228
+ 70
229
+ ],
230
+ "ɦ": [
231
+ 71
232
+ ],
233
+ "ɧ": [
234
+ 72
235
+ ],
236
+ "ɨ": [
237
+ 73
238
+ ],
239
+ "ɪ": [
240
+ 74
241
+ ],
242
+ "ɫ": [
243
+ 75
244
+ ],
245
+ "ɬ": [
246
+ 76
247
+ ],
248
+ "ɭ": [
249
+ 77
250
+ ],
251
+ "ɮ": [
252
+ 78
253
+ ],
254
+ "ɯ": [
255
+ 79
256
+ ],
257
+ "ɰ": [
258
+ 80
259
+ ],
260
+ "ɱ": [
261
+ 81
262
+ ],
263
+ "ɲ": [
264
+ 82
265
+ ],
266
+ "ɳ": [
267
+ 83
268
+ ],
269
+ "ɴ": [
270
+ 84
271
+ ],
272
+ "ɵ": [
273
+ 85
274
+ ],
275
+ "ɶ": [
276
+ 86
277
+ ],
278
+ "ɸ": [
279
+ 87
280
+ ],
281
+ "ɹ": [
282
+ 88
283
+ ],
284
+ "ɺ": [
285
+ 89
286
+ ],
287
+ "ɻ": [
288
+ 90
289
+ ],
290
+ "ɽ": [
291
+ 91
292
+ ],
293
+ "ɾ": [
294
+ 92
295
+ ],
296
+ "ʀ": [
297
+ 93
298
+ ],
299
+ "ʁ": [
300
+ 94
301
+ ],
302
+ "ʂ": [
303
+ 95
304
+ ],
305
+ "ʃ": [
306
+ 96
307
+ ],
308
+ "ʄ": [
309
+ 97
310
+ ],
311
+ "ʈ": [
312
+ 98
313
+ ],
314
+ "ʉ": [
315
+ 99
316
+ ],
317
+ "ʊ": [
318
+ 100
319
+ ],
320
+ "ʋ": [
321
+ 101
322
+ ],
323
+ "ʌ": [
324
+ 102
325
+ ],
326
+ "ʍ": [
327
+ 103
328
+ ],
329
+ "ʎ": [
330
+ 104
331
+ ],
332
+ "ʏ": [
333
+ 105
334
+ ],
335
+ "ʐ": [
336
+ 106
337
+ ],
338
+ "ʑ": [
339
+ 107
340
+ ],
341
+ "ʒ": [
342
+ 108
343
+ ],
344
+ "ʔ": [
345
+ 109
346
+ ],
347
+ "ʕ": [
348
+ 110
349
+ ],
350
+ "ʘ": [
351
+ 111
352
+ ],
353
+ "ʙ": [
354
+ 112
355
+ ],
356
+ "ʛ": [
357
+ 113
358
+ ],
359
+ "ʜ": [
360
+ 114
361
+ ],
362
+ "ʝ": [
363
+ 115
364
+ ],
365
+ "ʟ": [
366
+ 116
367
+ ],
368
+ "ʡ": [
369
+ 117
370
+ ],
371
+ "ʢ": [
372
+ 118
373
+ ],
374
+ "ʲ": [
375
+ 119
376
+ ],
377
+ "ˈ": [
378
+ 120
379
+ ],
380
+ "ˌ": [
381
+ 121
382
+ ],
383
+ "ː": [
384
+ 122
385
+ ],
386
+ "ˑ": [
387
+ 123
388
+ ],
389
+ "˞": [
390
+ 124
391
+ ],
392
+ "β": [
393
+ 125
394
+ ],
395
+ "θ": [
396
+ 126
397
+ ],
398
+ "χ": [
399
+ 127
400
+ ],
401
+ "ᵻ": [
402
+ 128
403
+ ],
404
+ "ⱱ": [
405
+ 129
406
+ ],
407
+ "0": [
408
+ 130
409
+ ],
410
+ "1": [
411
+ 131
412
+ ],
413
+ "2": [
414
+ 132
415
+ ],
416
+ "3": [
417
+ 133
418
+ ],
419
+ "4": [
420
+ 134
421
+ ],
422
+ "5": [
423
+ 135
424
+ ],
425
+ "6": [
426
+ 136
427
+ ],
428
+ "7": [
429
+ 137
430
+ ],
431
+ "8": [
432
+ 138
433
+ ],
434
+ "9": [
435
+ 139
436
+ ],
437
+ "̧": [
438
+ 140
439
+ ],
440
+ "̃": [
441
+ 141
442
+ ],
443
+ "̪": [
444
+ 142
445
+ ],
446
+ "̯": [
447
+ 143
448
+ ],
449
+ "̩": [
450
+ 144
451
+ ],
452
+ "ʰ": [
453
+ 145
454
+ ],
455
+ "ˤ": [
456
+ 146
457
+ ],
458
+ "ε": [
459
+ 147
460
+ ],
461
+ "↓": [
462
+ 148
463
+ ],
464
+ "#": [
465
+ 149
466
+ ],
467
+ "\"": [
468
+ 150
469
+ ],
470
+ "↑": [
471
+ 151
472
+ ],
473
+ "̺": [
474
+ 152
475
+ ],
476
+ "̻": [
477
+ 153
478
+ ],
479
+ "g": [
480
+ 154
481
+ ],
482
+ "ʦ": [
483
+ 155
484
+ ],
485
+ "X": [
486
+ 156
487
+ ],
488
+ "̝": [
489
+ 157
490
+ ],
491
+ "̊": [
492
+ 158
493
+ ],
494
+ "ɝ": [
495
+ 159
496
+ ],
497
+ "ʷ": [
498
+ 160
499
+ ]
500
+ },
501
+ "speaker_id_map": {},
502
+ "hop_length": 256,
503
+ "piper_version": "1.3.0"
504
+ }
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Thư viện chính để chạy model và giao diện
2
+ onnxruntime-gpu
3
+ numpy
4
+ gradio
5
+
6
+ # Thư viện xử lý ngôn ngữ tiếng Việt (NLP)
7
+ underthesea
8
+ vinorm
9
+
10
+ # Thư viện hỗ trợ âm thanh
11
+ scipy