Plana-Archive commited on
Commit
7769a18
·
verified ·
1 Parent(s): 08c1bd7

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +12 -0
  2. MOE-TTS/.gitattributes +36 -0
  3. MOE-TTS/Mutsumi.jpg +0 -0
  4. MOE-TTS/README.md +13 -0
  5. MOE-TTS/app.py +329 -0
  6. MOE-TTS/app.py (Cadangan utama) +295 -0
  7. MOE-TTS/attentions.py +300 -0
  8. MOE-TTS/chinese_dialect_lexicons/changzhou.json +23 -0
  9. MOE-TTS/chinese_dialect_lexicons/changzhou.ocd2 +0 -0
  10. MOE-TTS/chinese_dialect_lexicons/cixi.json +23 -0
  11. MOE-TTS/chinese_dialect_lexicons/cixi.ocd2 +0 -0
  12. MOE-TTS/chinese_dialect_lexicons/fuyang.json +23 -0
  13. MOE-TTS/chinese_dialect_lexicons/fuyang.ocd2 +0 -0
  14. MOE-TTS/chinese_dialect_lexicons/hangzhou.json +19 -0
  15. MOE-TTS/chinese_dialect_lexicons/hangzhou.ocd2 +3 -0
  16. MOE-TTS/chinese_dialect_lexicons/jiading.json +23 -0
  17. MOE-TTS/chinese_dialect_lexicons/jiading.ocd2 +3 -0
  18. MOE-TTS/chinese_dialect_lexicons/jiashan.json +23 -0
  19. MOE-TTS/chinese_dialect_lexicons/jiashan.ocd2 +0 -0
  20. MOE-TTS/chinese_dialect_lexicons/jingjiang.json +23 -0
  21. MOE-TTS/chinese_dialect_lexicons/jingjiang.ocd2 +0 -0
  22. MOE-TTS/chinese_dialect_lexicons/jyutjyu.json +19 -0
  23. MOE-TTS/chinese_dialect_lexicons/jyutjyu.ocd2 +3 -0
  24. MOE-TTS/chinese_dialect_lexicons/linping.json +23 -0
  25. MOE-TTS/chinese_dialect_lexicons/linping.ocd2 +0 -0
  26. MOE-TTS/chinese_dialect_lexicons/ningbo.json +19 -0
  27. MOE-TTS/chinese_dialect_lexicons/ningbo.ocd2 +3 -0
  28. MOE-TTS/chinese_dialect_lexicons/pinghu.json +23 -0
  29. MOE-TTS/chinese_dialect_lexicons/pinghu.ocd2 +0 -0
  30. MOE-TTS/chinese_dialect_lexicons/ruao.json +23 -0
  31. MOE-TTS/chinese_dialect_lexicons/ruao.ocd2 +0 -0
  32. MOE-TTS/chinese_dialect_lexicons/sanmen.json +23 -0
  33. MOE-TTS/chinese_dialect_lexicons/sanmen.ocd2 +0 -0
  34. MOE-TTS/chinese_dialect_lexicons/shaoxing.json +23 -0
  35. MOE-TTS/chinese_dialect_lexicons/shaoxing.ocd2 +3 -0
  36. MOE-TTS/chinese_dialect_lexicons/suichang.json +23 -0
  37. MOE-TTS/chinese_dialect_lexicons/suichang.ocd2 +0 -0
  38. MOE-TTS/chinese_dialect_lexicons/suzhou.json +19 -0
  39. MOE-TTS/chinese_dialect_lexicons/suzhou.ocd2 +3 -0
  40. MOE-TTS/chinese_dialect_lexicons/tiantai.json +23 -0
  41. MOE-TTS/chinese_dialect_lexicons/tiantai.ocd2 +3 -0
  42. MOE-TTS/chinese_dialect_lexicons/tongxiang.json +23 -0
  43. MOE-TTS/chinese_dialect_lexicons/tongxiang.ocd2 +3 -0
  44. MOE-TTS/chinese_dialect_lexicons/wenzhou.json +23 -0
  45. MOE-TTS/chinese_dialect_lexicons/wenzhou.ocd2 +0 -0
  46. MOE-TTS/chinese_dialect_lexicons/wuxi.json +19 -0
  47. MOE-TTS/chinese_dialect_lexicons/wuxi.ocd2 +3 -0
  48. MOE-TTS/chinese_dialect_lexicons/xiaoshan.json +23 -0
  49. MOE-TTS/chinese_dialect_lexicons/xiaoshan.ocd2 +0 -0
  50. MOE-TTS/chinese_dialect_lexicons/xiashi.json +19 -0
.gitattributes CHANGED
@@ -134,3 +134,15 @@ BanG-Dream-VITS/img/微信图片_20231010105112.png filter=lfs diff=lfs merge=lf
134
  BanG-Dream-VITS/img/神里绫华.png filter=lfs diff=lfs merge=lfs -text
135
  BanG-Dream-VITS/img/纳西妲.png filter=lfs diff=lfs merge=lfs -text
136
  BanG-Dream-VITS/temp.wav filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  BanG-Dream-VITS/img/神里绫华.png filter=lfs diff=lfs merge=lfs -text
135
  BanG-Dream-VITS/img/纳西妲.png filter=lfs diff=lfs merge=lfs -text
136
  BanG-Dream-VITS/temp.wav filter=lfs diff=lfs merge=lfs -text
137
+ MOE-TTS/chinese_dialect_lexicons/hangzhou.ocd2 filter=lfs diff=lfs merge=lfs -text
138
+ MOE-TTS/chinese_dialect_lexicons/jiading.ocd2 filter=lfs diff=lfs merge=lfs -text
139
+ MOE-TTS/chinese_dialect_lexicons/jyutjyu.ocd2 filter=lfs diff=lfs merge=lfs -text
140
+ MOE-TTS/chinese_dialect_lexicons/ningbo.ocd2 filter=lfs diff=lfs merge=lfs -text
141
+ MOE-TTS/chinese_dialect_lexicons/shaoxing.ocd2 filter=lfs diff=lfs merge=lfs -text
142
+ MOE-TTS/chinese_dialect_lexicons/suzhou.ocd2 filter=lfs diff=lfs merge=lfs -text
143
+ MOE-TTS/chinese_dialect_lexicons/tiantai.ocd2 filter=lfs diff=lfs merge=lfs -text
144
+ MOE-TTS/chinese_dialect_lexicons/tongxiang.ocd2 filter=lfs diff=lfs merge=lfs -text
145
+ MOE-TTS/chinese_dialect_lexicons/wuxi.ocd2 filter=lfs diff=lfs merge=lfs -text
146
+ MOE-TTS/chinese_dialect_lexicons/yixing.ocd2 filter=lfs diff=lfs merge=lfs -text
147
+ MOE-TTS/chinese_dialect_lexicons/zaonhe.ocd2 filter=lfs diff=lfs merge=lfs -text
148
+ MOE-TTS/kurumi-tokisaki.gif filter=lfs diff=lfs merge=lfs -text
MOE-TTS/.gitattributes ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ftz filter=lfs diff=lfs merge=lfs -text
6
+ *.gz filter=lfs diff=lfs merge=lfs -text
7
+ *.h5 filter=lfs diff=lfs merge=lfs -text
8
+ *.joblib filter=lfs diff=lfs merge=lfs -text
9
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
10
+ *.model filter=lfs diff=lfs merge=lfs -text
11
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
12
+ *.npy filter=lfs diff=lfs merge=lfs -text
13
+ *.npz filter=lfs diff=lfs merge=lfs -text
14
+ *.onnx filter=lfs diff=lfs merge=lfs -text
15
+ *.ot filter=lfs diff=lfs merge=lfs -text
16
+ *.parquet filter=lfs diff=lfs merge=lfs -text
17
+ *.pickle filter=lfs diff=lfs merge=lfs -text
18
+ *.pkl filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pt filter=lfs diff=lfs merge=lfs -text
21
+ *.pth filter=lfs diff=lfs merge=lfs -text
22
+ *.rar filter=lfs diff=lfs merge=lfs -text
23
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
24
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
25
+ *.tflite filter=lfs diff=lfs merge=lfs -text
26
+ *.tgz filter=lfs diff=lfs merge=lfs -text
27
+ *.wasm filter=lfs diff=lfs merge=lfs -text
28
+ *.xz filter=lfs diff=lfs merge=lfs -text
29
+ *.zip filter=lfs diff=lfs merge=lfs -text
30
+ *.zstandard filter=lfs diff=lfs merge=lfs -text
31
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
32
+ *.o filter=lfs diff=lfs merge=lfs -text
33
+ *.dll filter=lfs diff=lfs merge=lfs -text
34
+ *.so filter=lfs diff=lfs merge=lfs -text
35
+ *.ocd2 filter=lfs diff=lfs merge=lfs -text
36
+ kurumi-tokisaki.gif filter=lfs diff=lfs merge=lfs -text
MOE-TTS/Mutsumi.jpg ADDED
MOE-TTS/README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Library Anime! MOE-TTS
3
+ emoji: 👒
4
+ colorFrom: gray
5
+ colorTo: gray
6
+ sdk: gradio
7
+ sdk_version: 3.50.2
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ short_description: Library Anime! VITS Generate Voice
12
+ python_version: "3.10"
13
+ ---
MOE-TTS/app.py ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import torch
4
+ import commons
5
+ import utils
6
+ from models import SynthesizerTrn
7
+ import numpy as np
8
+ import json
9
+ import shutil
10
+ import logging
11
+ import random
12
+ import re
13
+ from huggingface_hub import snapshot_download
14
+
15
+ # --- 1. SETUP LOGGING ---
16
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
17
+ logger = logging.getLogger(__name__)
18
+
19
+ # --- 2. ROMAJI CONVERTER ---
20
+ try:
21
+ import pykakasi
22
+ kks = pykakasi.kakasi()
23
+ def to_romaji(text):
24
+ if not text or text == "None": return ""
25
+ try:
26
+ result = kks.convert(str(text))
27
+ return "".join([item['hepburn'].capitalize() for item in result])
28
+ except:
29
+ return str(text)
30
+ except:
31
+ def to_romaji(text): return str(text)
32
+
33
+ # --- 3. CLEAN HARDCODED INFO ---
34
+ CLEAN_INFO = {
35
+ "0": {"title": "Sanoba Witch & Senren Banka", "example": "こんにちは。", "type": "vits"},
36
+ "1": {"title": "Hamidashi Creative", "example": "こんにちは。", "type": "vits"},
37
+ "2": {"title": "Cafe Stella & Shinigami no Chou", "example": "こんにちは。", "type": "vits"},
38
+ "3": {"title": "Yosuga no Sora", "example": "こんにちは。", "type": "vits"},
39
+ "4": {"title": "Bishoujo Mangekyou", "example": "こんにちは。", "type": "vits"},
40
+ "5": {"title": "Nene & Nanami Pack (Multi)", "example": "[JA]こんにちは。[JA]", "type": "vits"},
41
+ "6": {"title": "The Fox Waiting for You", "example": "안녕하세요.", "type": "vits"},
42
+ "7": {"title": "Galgame Characters Pack (13)", "example": "こんにちは。", "type": "vits"},
43
+ "8": {"title": "Zero no Tsukaima", "example": "こんにちは。", "type": "vits"},
44
+ "9": {"title": "Zero no Tsukaima (VC Mode)", "example": "", "type": "soft-vits-vc"},
45
+ "10": {"title": "Toaru Majutsu no Index (VC)", "example": "", "type": "soft-vits-vc"},
46
+ "11": {"title": "Shiki Natsume (VC Mode)", "example": "", "type": "soft-vits-vc"},
47
+ "12": {"title": "DRACU-RIOT!", "example": "こんにちは。", "type": "vits"},
48
+ "13": {"title": "To LOVE-Ru Series", "example": "こんにちは。", "type": "vits"},
49
+ "14": {"title": "CJKS Multi-Language", "example": "[JA]こんにちは。[JA]", "type": "vits"},
50
+ "15": {"title": "Voistock Mega Pack (2891 Chars)", "example": "[JA]こんにちは。[JA]", "type": "vits"},
51
+ "16": {"title": "Shanghainese Dialect", "example": "侬好!", "type": "vits"},
52
+ "17": {"title": "Chinese Dialects Pack", "example": "[SH]侬好![SH]", "type": "vits"},
53
+ "18": {"title": "Umamusume: Pretty Derby", "example": "こんにちは。", "type": "vits"},
54
+ "19": {"title": "Princess Connect! Re:Dive", "example": "[JA]こんにちは。[JA]", "type": "vits"},
55
+ "20": {"title": "Magia Record (Madoka Magica)", "example": "こんにちは。", "type": "vits"}
56
+ }
57
+
58
+ # --- 4. DOWNLOAD ASSETS ---
59
+ REPO_ID = "Plana-Archive/Anime-Models"
60
+ LOCAL_ROOT = "MOE-TTS/saved_model"
61
+
62
+ def download_assets():
63
+ os.makedirs(LOCAL_ROOT, exist_ok=True)
64
+ # Cek apakah data model minimal (folder "0") sudah ada, jika belum lakukan download
65
+ if not os.path.exists(os.path.join(LOCAL_ROOT, "0")):
66
+ try:
67
+ logger.info("Downloading Assets dari Hugging Face...")
68
+ temp_dir = "temp_dir"
69
+
70
+ # Mendownload spesifik path sesuai dengan struktur repositori Anda
71
+ snapshot_download(
72
+ repo_id=REPO_ID,
73
+ local_dir=temp_dir,
74
+ allow_patterns=["Anime-VITS/MOE-TTS/saved_model/**/*"]
75
+ )
76
+
77
+ # Path asal hasil download subfolder Hugging Face
78
+ src_path = os.path.join(temp_dir, "Anime-VITS", "MOE-TTS", "saved_model")
79
+
80
+ if os.path.exists(src_path):
81
+ # Menyalin folder ke direktori lokal target aplikasi
82
+ shutil.copytree(src_path, LOCAL_ROOT, dirs_exist_ok=True)
83
+ logger.info("Assets berhasil disalin ke saved_model lokal!")
84
+ else:
85
+ logger.error("Struktur folder hasil download tidak sesuai ekspektasi.")
86
+
87
+ # Membersihkan folder temporary
88
+ if os.path.exists(temp_dir):
89
+ shutil.rmtree(temp_dir)
90
+ except Exception as e:
91
+ logger.error(f"Download error: {e}")
92
+
93
+ download_assets()
94
+
95
+ # --- 5. ENGINE LOAD MODEL ---
96
+ loaded_models = {}
97
+
98
+ def clean_config(conf):
99
+ if isinstance(conf, dict):
100
+ return {str(k): clean_config(v) for k, v in conf.items()}
101
+ elif isinstance(conf, (list, tuple)):
102
+ return [clean_config(i) for i in conf]
103
+ elif isinstance(conf, (int, float, str, bool)) or conf is None:
104
+ return conf
105
+ else:
106
+ return str(conf)
107
+
108
+ def get_vits_model(m_id):
109
+ mid = str(m_id)
110
+ if mid in loaded_models: return loaded_models[mid]
111
+ try:
112
+ p = os.path.join(LOCAL_ROOT, mid)
113
+ cfg_p = os.path.join(p, "config.json")
114
+ if not os.path.exists(cfg_p): return None
115
+ hps = utils.get_hparams_from_file(cfg_p)
116
+
117
+ m_params = clean_config(hps.model.__dict__ if hasattr(hps.model, '__dict__') else dict(hps.model))
118
+
119
+ net = SynthesizerTrn(
120
+ len(hps.symbols),
121
+ hps.data.filter_length // 2 + 1,
122
+ hps.train.segment_size // hps.data.hop_length,
123
+ n_speakers=hps.data.n_speakers,
124
+ **m_params
125
+ )
126
+ utils.load_checkpoint(os.path.join(p, "model.pth"), net, None)
127
+ net.eval()
128
+
129
+ raw_spks = hps.speakers if hasattr(hps, 'speakers') else [f"Character {i}" for i in range(hps.data.n_speakers)]
130
+
131
+ display_spks = []
132
+ original_spks = []
133
+ for s in raw_spks:
134
+ romaji_name = to_romaji(s)
135
+ if romaji_name and romaji_name.lower() != "none":
136
+ display_spks.append(romaji_name)
137
+ original_spks.append(s)
138
+
139
+ loaded_models[mid] = (hps, net, display_spks, original_spks)
140
+ return loaded_models[mid]
141
+ except Exception as e:
142
+ logger.error(f"Load Error {mid}: {e}")
143
+ return None
144
+
145
+ def tts_execute(m_id, text, speaker_romaji, speed):
146
+ data = get_vits_model(m_id)
147
+ if not data: return "❌ Model Loading...", None
148
+ hps, net, display_spks, _ = data
149
+ if not speaker_romaji:
150
+ if display_spks:
151
+ speaker_romaji = display_spks[0]
152
+ else:
153
+ return "❌ No Speaker Selected", None
154
+ try:
155
+ sid = display_spks.index(speaker_romaji)
156
+ from text import text_to_sequence
157
+ clean_text = re.sub(r'\[[A-Z]{2}\]', '', text)
158
+ cleaners = hps.data.text_cleaners if hasattr(hps.data, 'text_cleaners') else ['japanese_cleaners']
159
+ seq = text_to_sequence(clean_text, hps.symbols, cleaners)
160
+ if hps.data.add_blank: seq = commons.intersperse(seq, 0)
161
+ with torch.no_grad():
162
+ audio = net.infer(
163
+ torch.LongTensor(seq).unsqueeze(0),
164
+ torch.LongTensor([len(seq)]),
165
+ sid=torch.LongTensor([sid]),
166
+ noise_scale=0.667,
167
+ noise_scale_w=0.8,
168
+ length_scale=1.0/speed
169
+ )[0][0,0].data.cpu().float().numpy()
170
+ return f"✅ Done!", (hps.data.sampling_rate, (audio * 32767).astype(np.int16))
171
+ except Exception as e: return f"Error: {e}", None
172
+
173
+ def get_random_jp():
174
+ return random.choice(["こんにちは!", "お元気ですか?", "先生、お疲れ様です!", "大好きだよ!", "また明日ね。"])
175
+
176
+ def get_char_info_html(m_id):
177
+ data = get_vits_model(m_id)
178
+ if not data: return ""
179
+ _, _, _, original_names = data
180
+ html = f"""<div class="info-content-area" id="info-content-{m_id}" style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 15px; background: white; border: 1px solid #e1f0e5; border-top: none; border-radius: 0 0 10px 10px; max-height: 300px; overflow-y: auto;">"""
181
+ for i, name in enumerate(original_names):
182
+ html += f"""
183
+ <div style="border: 1px solid #e1f0e5; border-radius: 12px; padding: 10px; border-left: 5px solid #a8e6cf; background: #fff;">
184
+ <div style="font-weight: 800; color: #2d3748; font-size: 14px; margin-bottom: 2px;">{name}</div>
185
+ <div style="color: #a0aec0; font-size: 11px;">Character {i+1}</div>
186
+ </div>
187
+ """
188
+ html += "</div>"
189
+ return html
190
+
191
+ # --- 6. UI STYLE (BABY GREEN THEME) ---
192
+ css = """
193
+ :root {
194
+ --primary-600: #a8e6cf !important;
195
+ --accent-600: #a8e6cf !important;
196
+ }
197
+ .gradio-container, .gradio-container * {
198
+ --loader-color: #dcedc1 !important;
199
+ }
200
+ .ba-header-container {
201
+ border: 1.5px solid #e1f0e5;
202
+ border-radius: 12px;
203
+ margin-bottom: 12px;
204
+ background: white;
205
+ overflow: hidden;
206
+ line-height: 0;
207
+ }
208
+ .ba-header-container img {
209
+ width: 100%;
210
+ height: auto;
211
+ }
212
+ .status-container {
213
+ border: 1.5px solid #e1f0e5;
214
+ border-radius: 12px;
215
+ padding: 15px 22px;
216
+ margin-bottom: 20px;
217
+ background: white;
218
+ }
219
+ .status-title {
220
+ color: #88d498 !important;
221
+ font-weight: 800;
222
+ font-size: 16px;
223
+ margin-bottom: 8px;
224
+ }
225
+ .text-green-bold { color: #88d498 !important; font-weight: 900 !important; }
226
+
227
+ /* Pulsing Dot Effect */
228
+ .dot {
229
+ height: 8px;
230
+ width: 8px;
231
+ background-color: #88d498;
232
+ border-radius: 50%;
233
+ display: inline-block;
234
+ margin-right: 5px;
235
+ box-shadow: 0 0 0 0 rgba(136, 212, 152, 1);
236
+ animation: pulse-green 2s infinite;
237
+ }
238
+ @keyframes pulse-green {
239
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(136, 212, 152, 0.7); }
240
+ 70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(136, 212, 152, 0); }
241
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(136, 212, 152, 0); }
242
+ }
243
+
244
+ .slim-card { max-width: 480px; margin: 0 auto; background: transparent; padding: 10px; }
245
+ .tabs > .tab-nav { display: flex !important; overflow-x: auto !important; white-space: nowrap !important; }
246
+ .scroll-box { height: 200px; overflow-y: auto; border: 1px solid #f0f4f8; border-radius: 12px; padding: 10px; background: #fafbfc; margin-bottom: 10px; }
247
+ .char-btn { background: white !important; border: 1px solid #e2e8f0 !important; border-left: 5px solid #a8e6cf !important; text-align: left !important; padding: 8px !important; font-size: 12px !important; margin-bottom: 4px !important; width: 100%; color: #4a5568 !important; }
248
+ .warning-card { background: #fffcf0; border: 2px dashed #ffd3b6; border-radius: 10px; padding: 12px; margin-bottom: 15px; text-align: center; }
249
+ .jp-btn { background: #f8fafc !important; border: 1px solid #cbd5e1 !important; color: #475569 !important; font-weight: 700 !important; border-radius: 10px !important; margin-bottom: 10px; font-size: 12px !important; width: 100%; }
250
+ .gen-btn { background: #a8e6cf !important; color: #4a5568 !important; font-weight: 700 !important; border-radius: 12px !important; height: 45px !important; width: 100%; border: none !important; cursor: pointer; }
251
+ .info-header-custom { background: #dcedc1 !important; color: #4a5568 !important; border: none !important; border-radius: 8px 8px 0 0 !important; padding: 12px 15px !important; width: 100% !important; cursor: pointer; font-weight: 800 !important; margin-top: 5px; }
252
+ .credit-footer { margin-top: 25px; padding: 15px; background: white; border-radius: 12px; text-align: center; border-bottom: 4px solid #a8e6cf; color: #94a3b8; font-weight: 700; font-size: 12px; letter-spacing: 2px; }
253
+ .gif-container { display: flex; justify-content: center; margin-top: 15px; }
254
+ .gif-container img { border-radius: 12px; max-width: 100%; height: auto; border: 1px solid #e1f0e5; }
255
+ """
256
+
257
+ with gr.Blocks(css=css) as demo:
258
+ with gr.Column(elem_classes="slim-card"):
259
+ gr.HTML("""
260
+ <div class="ba-header-container">
261
+ <img src="https://huggingface.co/spaces/Plana-Archive/MOE-TTS/resolve/main/Mutsumi.jpg" alt="Mutsumi Banner">
262
+ </div>
263
+ <div class="status-container">
264
+ <div class="status-title">System Status</div>
265
+ <div class="status-item"><span style="color:#4a5568">Model :</span> <span class="text-green-bold">&nbsp;LOADED ✅</span></div>
266
+ <div class="status-item"><span style="color:#4a5568">System :</span> <span style="color:#88d498; font-weight:700;"><span class="dot"></span>Online</span></div>
267
+ </div>
268
+ """)
269
+
270
+ with gr.Tabs(elem_classes="tabs"):
271
+ for m_id in sorted(CLEAN_INFO.keys(), key=int):
272
+ with gr.Tab(f"Model {m_id}"):
273
+ gr.Markdown(f"### 📂 {CLEAN_INFO[m_id]['title']}")
274
+
275
+ m_data = get_vits_model(m_id)
276
+ chars = m_data[2] if m_data else []
277
+
278
+ m_p = os.path.join(LOCAL_ROOT, str(m_id))
279
+ cov = next((os.path.join(m_p, f"cover.{e}") for e in ['png','jpg','jpeg','webp'] if os.path.exists(os.path.join(m_p, f"cover.{e}"))), None)
280
+ if cov: gr.Image(cov, show_label=False, interactive=False, height=140)
281
+
282
+ sel_name = gr.State("")
283
+ char_display = gr.Markdown("📍 *Silakan pilih karakter...*")
284
+
285
+ with gr.Column(elem_classes="scroll-box"):
286
+ if chars:
287
+ for name in chars:
288
+ btn = gr.Button(f"👤 {name}", elem_classes="char-btn")
289
+ btn.click(fn=lambda n=name: (n, f"📍 Selected: **{n}**"), outputs=[sel_name, char_display])
290
+
291
+ gr.HTML("""
292
+ <div class="warning-card">
293
+ <div style="color:#f5a623;font-weight:800;font-size:13px;">🔖 PERINGATAN MINNA 🔖</div>
294
+ <div style="color:#855d1a;font-size:11px;font-weight:600;">
295
+ Cara pakai: klik character, masukkan text, lalu Generate! ✨
296
+ </div>
297
+ </div>
298
+ """)
299
+
300
+ ex_text = re.sub(r'\[[A-Z]{2}\]', '', CLEAN_INFO[m_id].get("example", "こんにちは。"))
301
+ txt_in = gr.TextArea(label="Input Text", value=ex_text, lines=3)
302
+ gr.Button("🎲 INPUTS RANDOM TEXT 🎲", elem_classes="jp-btn").click(get_random_jp, outputs=[txt_in])
303
+
304
+ spd = gr.Slider(0.5, 2.0, 1.0, step=0.1, label="Speed Audio")
305
+ btn_gen = gr.Button("🫒 GENERATE VOICE 🫒", elem_classes="gen-btn")
306
+ aud_out = gr.Audio(label="Voice Output")
307
+
308
+ gr.HTML(f"""
309
+ <div class="gif-container">
310
+ <img src="https://huggingface.co/spaces/Plana-Archive/MOE-TTS/resolve/main/kurumi-tokisaki.gif" alt="Kurumi GIF">
311
+ </div>
312
+ <button onclick="document.getElementById('info-content-{m_id}').style.display = (document.getElementById('info-content-{m_id}').style.display === 'none') ? 'grid' : 'none';" class="info-header-custom">
313
+ 📑 Character Information 📑
314
+ </button>
315
+ """)
316
+ gr.HTML(get_char_info_html(m_id))
317
+
318
+ status_log = gr.Textbox(visible=False)
319
+ btn_gen.click(fn=tts_execute, inputs=[gr.State(m_id), txt_in, sel_name, spd], outputs=[status_log, aud_out])
320
+
321
+ gr.HTML("""<div class="credit-footer">🍏 CREATED BY MUTSUMI 🍏</div>""")
322
+
323
+ # --- 7. LAUNCH ---
324
+ if __name__ == "__main__":
325
+ demo.queue().launch(
326
+ server_name="0.0.0.0",
327
+ server_port=7860,
328
+ show_api=False
329
+ )
MOE-TTS/app.py (Cadangan utama) ADDED
@@ -0,0 +1,295 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import torch
4
+ import commons
5
+ import utils
6
+ from models import SynthesizerTrn
7
+ import numpy as np
8
+ import json
9
+ import shutil
10
+ import logging
11
+ import random
12
+ import re
13
+ from huggingface_hub import snapshot_download
14
+
15
+ # --- 1. SETUP LOGGING ---
16
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
17
+ logger = logging.getLogger(__name__)
18
+
19
+ # --- 2. ROMAJI CONVERTER ---
20
+ try:
21
+ import pykakasi
22
+ kks = pykakasi.kakasi()
23
+ def to_romaji(text):
24
+ if not text or text == "None": return ""
25
+ try:
26
+ result = kks.convert(str(text))
27
+ return "".join([item['hepburn'].capitalize() for item in result])
28
+ except:
29
+ return str(text)
30
+ except:
31
+ def to_romaji(text): return str(text)
32
+
33
+ # --- 3. CLEAN HARDCODED INFO ---
34
+ CLEAN_INFO = {
35
+ "0": {"title": "Sanoba Witch & Senren Banka", "example": "こんにちは。", "type": "vits"},
36
+ "1": {"title": "Hamidashi Creative", "example": "こんにちは。", "type": "vits"},
37
+ "2": {"title": "Cafe Stella & Shinigami no Chou", "example": "こんにちは。", "type": "vits"},
38
+ "3": {"title": "Yosuga no Sora", "example": "こんにちは。", "type": "vits"},
39
+ "4": {"title": "Bishoujo Mangekyou", "example": "こんにちは。", "type": "vits"},
40
+ "5": {"title": "Nene & Nanami Pack (Multi)", "example": "[JA]こんにちは。[JA]", "type": "vits"},
41
+ "6": {"title": "The Fox Waiting for You", "example": "안녕하세요.", "type": "vits"},
42
+ "7": {"title": "Galgame Characters Pack (13)", "example": "こんにちは。", "type": "vits"},
43
+ "8": {"title": "Zero no Tsukaima", "example": "こんにちは。", "type": "vits"},
44
+ "9": {"title": "Zero no Tsukaima (VC Mode)", "example": "", "type": "soft-vits-vc"},
45
+ "10": {"title": "Toaru Majutsu no Index (VC)", "example": "", "type": "soft-vits-vc"},
46
+ "11": {"title": "Shiki Natsume (VC Mode)", "example": "", "type": "soft-vits-vc"},
47
+ "12": {"title": "DRACU-RIOT!", "example": "こんにちは。", "type": "vits"},
48
+ "13": {"title": "To LOVE-Ru Series", "example": "こんにちは。", "type": "vits"},
49
+ "14": {"title": "CJKS Multi-Language", "example": "[JA]こんにちは。[JA]", "type": "vits"},
50
+ "15": {"title": "Voistock Mega Pack (2891 Chars)", "example": "[JA]こんにちは。[JA]", "type": "vits"},
51
+ "16": {"title": "Shanghainese Dialect", "example": "侬好!", "type": "vits"},
52
+ "17": {"title": "Chinese Dialects Pack", "example": "[SH]侬好![SH]", "type": "vits"},
53
+ "18": {"title": "Umamusume: Pretty Derby", "example": "こんにちは。", "type": "vits"},
54
+ "19": {"title": "Princess Connect! Re:Dive", "example": "[JA]こんにちは。[JA]", "type": "vits"},
55
+ "20": {"title": "Magia Record (Madoka Magica)", "example": "こんにちは。", "type": "vits"}
56
+ }
57
+
58
+ # --- 4. DOWNLOAD ASSETS ---
59
+ REPO_ID = "Plana-Archive/Plana-TTS"
60
+ LOCAL_ROOT = "saved_model"
61
+
62
+ def download_assets():
63
+ os.makedirs(LOCAL_ROOT, exist_ok=True)
64
+ if not os.path.exists(os.path.join(LOCAL_ROOT, "0")):
65
+ try:
66
+ logger.info("Downloading Assets...")
67
+ snapshot_download(repo_id=REPO_ID, local_dir="temp_dir", allow_patterns=["MOE-TTS/saved_model/*"])
68
+ src_path = os.path.join("temp_dir", "MOE-TTS", "saved_model")
69
+ if os.path.exists(src_path):
70
+ shutil.copytree(src_path, LOCAL_ROOT, dirs_exist_ok=True)
71
+ shutil.rmtree("temp_dir")
72
+ except Exception as e:
73
+ logger.error(f"Download error: {e}")
74
+
75
+ download_assets()
76
+
77
+ # --- 5. ENGINE LOAD MODEL ---
78
+ loaded_models = {}
79
+
80
+ def clean_config(conf):
81
+ """Memperbaiki error unhashable type: 'dict' di Jinja2/Gradio"""
82
+ if isinstance(conf, dict):
83
+ return {str(k): clean_config(v) for k, v in conf.items()}
84
+ elif isinstance(conf, (list, tuple)):
85
+ return [clean_config(i) for i in conf]
86
+ elif isinstance(conf, (int, float, str, bool)) or conf is None:
87
+ return conf
88
+ else:
89
+ return str(conf)
90
+
91
+ def get_vits_model(m_id):
92
+ mid = str(m_id)
93
+ if mid in loaded_models: return loaded_models[mid]
94
+ try:
95
+ p = os.path.join(LOCAL_ROOT, mid)
96
+ cfg_p = os.path.join(p, "config.json")
97
+ if not os.path.exists(cfg_p): return None
98
+ hps = utils.get_hparams_from_file(cfg_p)
99
+
100
+ # Membersihkan model params agar aman di UI
101
+ m_params = clean_config(hps.model.__dict__ if hasattr(hps.model, '__dict__') else dict(hps.model))
102
+
103
+ net = SynthesizerTrn(
104
+ len(hps.symbols),
105
+ hps.data.filter_length // 2 + 1,
106
+ hps.train.segment_size // hps.data.hop_length,
107
+ n_speakers=hps.data.n_speakers,
108
+ **m_params
109
+ )
110
+ utils.load_checkpoint(os.path.join(p, "model.pth"), net, None)
111
+ net.eval()
112
+
113
+ raw_spks = hps.speakers if hasattr(hps, 'speakers') else [f"Character {i}" for i in range(hps.data.n_speakers)]
114
+
115
+ display_spks = []
116
+ original_spks = []
117
+ for s in raw_spks:
118
+ romaji_name = to_romaji(s)
119
+ if romaji_name and romaji_name.lower() != "none":
120
+ display_spks.append(romaji_name)
121
+ original_spks.append(s)
122
+
123
+ loaded_models[mid] = (hps, net, display_spks, original_spks)
124
+ return loaded_models[mid]
125
+ except Exception as e:
126
+ logger.error(f"Load Error {mid}: {e}")
127
+ return None
128
+
129
+ def tts_execute(m_id, text, speaker_romaji, speed):
130
+ data = get_vits_model(m_id)
131
+ if not data: return "❌ Model Loading...", None
132
+ hps, net, display_spks, _ = data
133
+ if not speaker_romaji:
134
+ if display_spks:
135
+ speaker_romaji = display_spks[0]
136
+ else:
137
+ return "❌ No Speaker Selected", None
138
+ try:
139
+ sid = display_spks.index(speaker_romaji)
140
+ from text import text_to_sequence
141
+ clean_text = re.sub(r'\[[A-Z]{2}\]', '', text)
142
+ cleaners = hps.data.text_cleaners if hasattr(hps.data, 'text_cleaners') else ['japanese_cleaners']
143
+ seq = text_to_sequence(clean_text, hps.symbols, cleaners)
144
+ if hps.data.add_blank: seq = commons.intersperse(seq, 0)
145
+ with torch.no_grad():
146
+ audio = net.infer(
147
+ torch.LongTensor(seq).unsqueeze(0),
148
+ torch.LongTensor([len(seq)]),
149
+ sid=torch.LongTensor([sid]),
150
+ noise_scale=0.667,
151
+ noise_scale_w=0.8,
152
+ length_scale=1.0/speed
153
+ )[0][0,0].data.cpu().float().numpy()
154
+ return f"✅ Done!", (hps.data.sampling_rate, (audio * 32767).astype(np.int16))
155
+ except Exception as e: return f"Error: {e}", None
156
+
157
+ def get_random_jp():
158
+ return random.choice(["こんにちは!", "お元気ですか?", "先生、お疲れ様です!", "大好きだよ!", "また明日ね。"])
159
+
160
+ def get_char_info_html(m_id):
161
+ data = get_vits_model(m_id)
162
+ if not data: return ""
163
+ _, _, _, original_names = data
164
+
165
+ html = f"""<div class="info-content-area" id="info-content-{m_id}" style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 15px; background: white; border: 1px solid #f0f4f8; border-top: none; border-radius: 0 0 10px 10px;">"""
166
+ for i, name in enumerate(original_names):
167
+ html += f"""
168
+ <div style="border: 1px solid #f0f4f8; border-radius: 12px; padding: 10px; border-left: 5px solid #1299ff; background: #fff;">
169
+ <div style="font-weight: 800; color: #2d3748; font-size: 14px; margin-bottom: 2px;">{name}</div>
170
+ <div style="color: #a0aec0; font-size: 11px;">Character {i+1}</div>
171
+ </div>
172
+ """
173
+ html += "</div>"
174
+ return html
175
+
176
+ # --- 6. UI STYLE ---
177
+ css = """
178
+ :root {
179
+ --primary-600: #1299ff !important;
180
+ --accent-600: #1299ff !important;
181
+ }
182
+ .gradio-container, .gradio-container * {
183
+ --loader-color: #A2D2FF !important;
184
+ }
185
+ .ba-header-container {
186
+ border: 1.5px solid #e1e8f0;
187
+ border-radius: 12px;
188
+ padding: 20px 10px;
189
+ margin-bottom: 12px;
190
+ background: white;
191
+ text-align: center;
192
+ }
193
+ .ba-header-container h1 {
194
+ color: #1299ff !important;
195
+ font-weight: 700 !important;
196
+ font-size: 42px !important;
197
+ margin: 0;
198
+ }
199
+ .status-container {
200
+ border: 1.5px solid #e1e8f0;
201
+ border-radius: 12px;
202
+ padding: 15px 22px;
203
+ margin-bottom: 20px;
204
+ background: white;
205
+ }
206
+ .status-title {
207
+ color: #1299ff !important;
208
+ font-weight: 800;
209
+ font-size: 16px;
210
+ margin-bottom: 8px;
211
+ }
212
+ .text-green-bold { color: #28a745 !important; font-weight: 900 !important; }
213
+ .text-blue-status { color: #1299ff !important; }
214
+ .slim-card { max-width: 480px; margin: 0 auto; background: transparent; padding: 10px; }
215
+ .tabs > .tab-nav { display: flex !important; overflow-x: auto !important; white-space: nowrap !important; }
216
+ .scroll-box { height: 200px; overflow-y: auto; border: 1px solid #f0f4f8; border-radius: 12px; padding: 10px; background: #fafbfc; margin-bottom: 10px; }
217
+ .char-btn { background: white !important; border: 1px solid #e2e8f0 !important; border-left: 5px solid #1299ff !important; text-align: left !important; padding: 8px !important; font-size: 12px !important; margin-bottom: 4px !important; width: 100%; color: #4a5568 !important; }
218
+ .warning-card { background: #fff9f0; border: 2px dashed #f5a623; border-radius: 10px; padding: 12px; margin-bottom: 15px; text-align: center; }
219
+ .jp-btn { background: #f8fafc !important; border: 1px solid #cbd5e1 !important; color: #475569 !important; font-weight: 700 !important; border-radius: 10px !important; margin-bottom: 10px; font-size: 12px !important; width: 100%; }
220
+ .gen-btn { background: #1299ff !important; color: white !important; font-weight: 700 !important; border-radius: 12px !important; height: 45px !important; width: 100%; border: none !important; cursor: pointer; }
221
+ .info-header-custom { background: #1299ff !important; color: white !important; border: none !important; border-radius: 8px 8px 0 0 !important; padding: 12px 15px !important; width: 100% !important; cursor: pointer; font-weight: 800 !important; margin-top: 15px; }
222
+ .credit-footer { margin-top: 25px; padding: 15px; background: white; border-radius: 12px; text-align: center; border-bottom: 4px solid #1299ff; color: #94a3b8; font-weight: 700; font-size: 12px; letter-spacing: 2px; }
223
+ """
224
+
225
+ with gr.Blocks(css=css) as demo:
226
+ with gr.Column(elem_classes="slim-card"):
227
+ gr.HTML("""
228
+ <div class="ba-header-container">
229
+ <h1>Library Anime</h1>
230
+ <p>🍂 Style-Bert-VITS2 🍂</p>
231
+ </div>
232
+ <div class="status-container">
233
+ <div class="status-title">System Status</div>
234
+ <div class="status-item"><span style="color:#4a5568">Model :</span> <span class="text-green-bold">&nbsp;LOADED ✅</span></div>
235
+ <div class="status-item"><span style="color:#4a5568">System :</span> <span class="text-blue-status">&nbsp;Online</span></div>
236
+ </div>
237
+ """)
238
+
239
+ with gr.Tabs(elem_classes="tabs"):
240
+ for m_id in sorted(CLEAN_INFO.keys(), key=int):
241
+ with gr.Tab(f"Model {m_id}"):
242
+ gr.Markdown(f"### 📂 {CLEAN_INFO[m_id]['title']}")
243
+
244
+ m_data = get_vits_model(m_id)
245
+ chars = m_data[2] if m_data else []
246
+
247
+ m_p = os.path.join(LOCAL_ROOT, str(m_id))
248
+ cov = next((os.path.join(m_p, f"cover.{e}") for e in ['png','jpg','jpeg','webp'] if os.path.exists(os.path.join(m_p, f"cover.{e}"))), None)
249
+ if cov: gr.Image(cov, show_label=False, interactive=False, height=140)
250
+
251
+ sel_name = gr.State("")
252
+ char_display = gr.Markdown("📍 *Silakan pilih karakter...*")
253
+
254
+ with gr.Column(elem_classes="scroll-box"):
255
+ if chars:
256
+ for name in chars:
257
+ btn = gr.Button(f"👤 {name}", elem_classes="char-btn")
258
+ btn.click(fn=lambda n=name: (n, f"📍 Selected: **{n}**"), outputs=[sel_name, char_display])
259
+
260
+ gr.HTML("""
261
+ <div class="warning-card">
262
+ <div style="color:#f5a623;font-weight:800;font-size:13px;">🔖 PERINGATAN MINNA 🔖</div>
263
+ <div style="color:#855d1a;font-size:11px;font-weight:600;">
264
+ Cara pakai: klik character, masukkan text, lalu Generate! ✨
265
+ </div>
266
+ </div>
267
+ """)
268
+
269
+ ex_text = re.sub(r'\[[A-Z]{2}\]', '', CLEAN_INFO[m_id].get("example", "こんにちは。"))
270
+ txt_in = gr.TextArea(label="Input Text", value=ex_text, lines=3)
271
+ gr.Button("🎲 INPUTS RANDOM TEXT 🎲", elem_classes="jp-btn").click(get_random_jp, outputs=[txt_in])
272
+
273
+ spd = gr.Slider(0.5, 2.0, 1.0, step=0.1, label="Speed Audio")
274
+ btn_gen = gr.Button("🎐 GENERATE VOICE 🎐", elem_classes="gen-btn")
275
+ aud_out = gr.Audio(label="Voice Output")
276
+
277
+ gr.HTML(f"""
278
+ <button onclick="document.getElementById('info-content-{m_id}').style.display = (document.getElementById('info-content-{m_id}').style.display === 'none') ? 'grid' : 'none';" class="info-header-custom">
279
+ 📑 Character Information 📑
280
+ </button>
281
+ """)
282
+ gr.HTML(get_char_info_html(m_id))
283
+
284
+ status_log = gr.Textbox(visible=False)
285
+ btn_gen.click(fn=tts_execute, inputs=[gr.State(m_id), txt_in, sel_name, spd], outputs=[status_log, aud_out])
286
+
287
+ gr.HTML("""<div class="credit-footer">🌥️ CREATED BY MUTSUMI 🌥️</div>""")
288
+
289
+ # --- 7. LAUNCH ---
290
+ if __name__ == "__main__":
291
+ demo.queue().launch(
292
+ server_name="0.0.0.0",
293
+ server_port=7860,
294
+ show_api=False
295
+ )
MOE-TTS/attentions.py ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import torch
3
+ from torch import nn
4
+ from torch.nn import functional as F
5
+
6
+ import commons
7
+ from modules import LayerNorm
8
+
9
+
10
+ class Encoder(nn.Module):
11
+ def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., window_size=4, **kwargs):
12
+ super().__init__()
13
+ self.hidden_channels = hidden_channels
14
+ self.filter_channels = filter_channels
15
+ self.n_heads = n_heads
16
+ self.n_layers = n_layers
17
+ self.kernel_size = kernel_size
18
+ self.p_dropout = p_dropout
19
+ self.window_size = window_size
20
+
21
+ self.drop = nn.Dropout(p_dropout)
22
+ self.attn_layers = nn.ModuleList()
23
+ self.norm_layers_1 = nn.ModuleList()
24
+ self.ffn_layers = nn.ModuleList()
25
+ self.norm_layers_2 = nn.ModuleList()
26
+ for i in range(self.n_layers):
27
+ self.attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, window_size=window_size))
28
+ self.norm_layers_1.append(LayerNorm(hidden_channels))
29
+ self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout))
30
+ self.norm_layers_2.append(LayerNorm(hidden_channels))
31
+
32
+ def forward(self, x, x_mask):
33
+ attn_mask = x_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
34
+ x = x * x_mask
35
+ for i in range(self.n_layers):
36
+ y = self.attn_layers[i](x, x, attn_mask)
37
+ y = self.drop(y)
38
+ x = self.norm_layers_1[i](x + y)
39
+
40
+ y = self.ffn_layers[i](x, x_mask)
41
+ y = self.drop(y)
42
+ x = self.norm_layers_2[i](x + y)
43
+ x = x * x_mask
44
+ return x
45
+
46
+
47
+ class Decoder(nn.Module):
48
+ def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., proximal_bias=False, proximal_init=True, **kwargs):
49
+ super().__init__()
50
+ self.hidden_channels = hidden_channels
51
+ self.filter_channels = filter_channels
52
+ self.n_heads = n_heads
53
+ self.n_layers = n_layers
54
+ self.kernel_size = kernel_size
55
+ self.p_dropout = p_dropout
56
+ self.proximal_bias = proximal_bias
57
+ self.proximal_init = proximal_init
58
+
59
+ self.drop = nn.Dropout(p_dropout)
60
+ self.self_attn_layers = nn.ModuleList()
61
+ self.norm_layers_0 = nn.ModuleList()
62
+ self.encdec_attn_layers = nn.ModuleList()
63
+ self.norm_layers_1 = nn.ModuleList()
64
+ self.ffn_layers = nn.ModuleList()
65
+ self.norm_layers_2 = nn.ModuleList()
66
+ for i in range(self.n_layers):
67
+ self.self_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, proximal_bias=proximal_bias, proximal_init=proximal_init))
68
+ self.norm_layers_0.append(LayerNorm(hidden_channels))
69
+ self.encdec_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout))
70
+ self.norm_layers_1.append(LayerNorm(hidden_channels))
71
+ self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout, causal=True))
72
+ self.norm_layers_2.append(LayerNorm(hidden_channels))
73
+
74
+ def forward(self, x, x_mask, h, h_mask):
75
+ """
76
+ x: decoder input
77
+ h: encoder output
78
+ """
79
+ self_attn_mask = commons.subsequent_mask(x_mask.size(2)).to(device=x.device, dtype=x.dtype)
80
+ encdec_attn_mask = h_mask.unsqueeze(2) * x_mask.unsqueeze(-1)
81
+ x = x * x_mask
82
+ for i in range(self.n_layers):
83
+ y = self.self_attn_layers[i](x, x, self_attn_mask)
84
+ y = self.drop(y)
85
+ x = self.norm_layers_0[i](x + y)
86
+
87
+ y = self.encdec_attn_layers[i](x, h, encdec_attn_mask)
88
+ y = self.drop(y)
89
+ x = self.norm_layers_1[i](x + y)
90
+
91
+ y = self.ffn_layers[i](x, x_mask)
92
+ y = self.drop(y)
93
+ x = self.norm_layers_2[i](x + y)
94
+ x = x * x_mask
95
+ return x
96
+
97
+
98
+ class MultiHeadAttention(nn.Module):
99
+ def __init__(self, channels, out_channels, n_heads, p_dropout=0., window_size=None, heads_share=True, block_length=None, proximal_bias=False, proximal_init=False):
100
+ super().__init__()
101
+ assert channels % n_heads == 0
102
+
103
+ self.channels = channels
104
+ self.out_channels = out_channels
105
+ self.n_heads = n_heads
106
+ self.p_dropout = p_dropout
107
+ self.window_size = window_size
108
+ self.heads_share = heads_share
109
+ self.block_length = block_length
110
+ self.proximal_bias = proximal_bias
111
+ self.proximal_init = proximal_init
112
+ self.attn = None
113
+
114
+ self.k_channels = channels // n_heads
115
+ self.conv_q = nn.Conv1d(channels, channels, 1)
116
+ self.conv_k = nn.Conv1d(channels, channels, 1)
117
+ self.conv_v = nn.Conv1d(channels, channels, 1)
118
+ self.conv_o = nn.Conv1d(channels, out_channels, 1)
119
+ self.drop = nn.Dropout(p_dropout)
120
+
121
+ if window_size is not None:
122
+ n_heads_rel = 1 if heads_share else n_heads
123
+ rel_stddev = self.k_channels**-0.5
124
+ self.emb_rel_k = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)
125
+ self.emb_rel_v = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)
126
+
127
+ nn.init.xavier_uniform_(self.conv_q.weight)
128
+ nn.init.xavier_uniform_(self.conv_k.weight)
129
+ nn.init.xavier_uniform_(self.conv_v.weight)
130
+ if proximal_init:
131
+ with torch.no_grad():
132
+ self.conv_k.weight.copy_(self.conv_q.weight)
133
+ self.conv_k.bias.copy_(self.conv_q.bias)
134
+
135
+ def forward(self, x, c, attn_mask=None):
136
+ q = self.conv_q(x)
137
+ k = self.conv_k(c)
138
+ v = self.conv_v(c)
139
+
140
+ x, self.attn = self.attention(q, k, v, mask=attn_mask)
141
+
142
+ x = self.conv_o(x)
143
+ return x
144
+
145
+ def attention(self, query, key, value, mask=None):
146
+ # reshape [b, d, t] -> [b, n_h, t, d_k]
147
+ b, d, t_s, t_t = (*key.size(), query.size(2))
148
+ query = query.view(b, self.n_heads, self.k_channels, t_t).transpose(2, 3)
149
+ key = key.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
150
+ value = value.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)
151
+
152
+ scores = torch.matmul(query / math.sqrt(self.k_channels), key.transpose(-2, -1))
153
+ if self.window_size is not None:
154
+ assert t_s == t_t, "Relative attention is only available for self-attention."
155
+ key_relative_embeddings = self._get_relative_embeddings(self.emb_rel_k, t_s)
156
+ rel_logits = self._matmul_with_relative_keys(query /math.sqrt(self.k_channels), key_relative_embeddings)
157
+ scores_local = self._relative_position_to_absolute_position(rel_logits)
158
+ scores = scores + scores_local
159
+ if self.proximal_bias:
160
+ assert t_s == t_t, "Proximal bias is only available for self-attention."
161
+ scores = scores + self._attention_bias_proximal(t_s).to(device=scores.device, dtype=scores.dtype)
162
+ if mask is not None:
163
+ scores = scores.masked_fill(mask == 0, -1e4)
164
+ if self.block_length is not None:
165
+ assert t_s == t_t, "Local attention is only available for self-attention."
166
+ block_mask = torch.ones_like(scores).triu(-self.block_length).tril(self.block_length)
167
+ scores = scores.masked_fill(block_mask == 0, -1e4)
168
+ p_attn = F.softmax(scores, dim=-1) # [b, n_h, t_t, t_s]
169
+ p_attn = self.drop(p_attn)
170
+ output = torch.matmul(p_attn, value)
171
+ if self.window_size is not None:
172
+ relative_weights = self._absolute_position_to_relative_position(p_attn)
173
+ value_relative_embeddings = self._get_relative_embeddings(self.emb_rel_v, t_s)
174
+ output = output + self._matmul_with_relative_values(relative_weights, value_relative_embeddings)
175
+ output = output.transpose(2, 3).contiguous().view(b, d, t_t) # [b, n_h, t_t, d_k] -> [b, d, t_t]
176
+ return output, p_attn
177
+
178
+ def _matmul_with_relative_values(self, x, y):
179
+ """
180
+ x: [b, h, l, m]
181
+ y: [h or 1, m, d]
182
+ ret: [b, h, l, d]
183
+ """
184
+ ret = torch.matmul(x, y.unsqueeze(0))
185
+ return ret
186
+
187
+ def _matmul_with_relative_keys(self, x, y):
188
+ """
189
+ x: [b, h, l, d]
190
+ y: [h or 1, m, d]
191
+ ret: [b, h, l, m]
192
+ """
193
+ ret = torch.matmul(x, y.unsqueeze(0).transpose(-2, -1))
194
+ return ret
195
+
196
+ def _get_relative_embeddings(self, relative_embeddings, length):
197
+ max_relative_position = 2 * self.window_size + 1
198
+ # Pad first before slice to avoid using cond ops.
199
+ pad_length = max(length - (self.window_size + 1), 0)
200
+ slice_start_position = max((self.window_size + 1) - length, 0)
201
+ slice_end_position = slice_start_position + 2 * length - 1
202
+ if pad_length > 0:
203
+ padded_relative_embeddings = F.pad(
204
+ relative_embeddings,
205
+ commons.convert_pad_shape([[0, 0], [pad_length, pad_length], [0, 0]]))
206
+ else:
207
+ padded_relative_embeddings = relative_embeddings
208
+ used_relative_embeddings = padded_relative_embeddings[:,slice_start_position:slice_end_position]
209
+ return used_relative_embeddings
210
+
211
+ def _relative_position_to_absolute_position(self, x):
212
+ """
213
+ x: [b, h, l, 2*l-1]
214
+ ret: [b, h, l, l]
215
+ """
216
+ batch, heads, length, _ = x.size()
217
+ # Concat columns of pad to shift from relative to absolute indexing.
218
+ x = F.pad(x, commons.convert_pad_shape([[0,0],[0,0],[0,0],[0,1]]))
219
+
220
+ # Concat extra elements so to add up to shape (len+1, 2*len-1).
221
+ x_flat = x.view([batch, heads, length * 2 * length])
222
+ x_flat = F.pad(x_flat, commons.convert_pad_shape([[0,0],[0,0],[0,length-1]]))
223
+
224
+ # Reshape and slice out the padded elements.
225
+ x_final = x_flat.view([batch, heads, length+1, 2*length-1])[:, :, :length, length-1:]
226
+ return x_final
227
+
228
+ def _absolute_position_to_relative_position(self, x):
229
+ """
230
+ x: [b, h, l, l]
231
+ ret: [b, h, l, 2*l-1]
232
+ """
233
+ batch, heads, length, _ = x.size()
234
+ # padd along column
235
+ x = F.pad(x, commons.convert_pad_shape([[0, 0], [0, 0], [0, 0], [0, length-1]]))
236
+ x_flat = x.view([batch, heads, length**2 + length*(length -1)])
237
+ # add 0's in the beginning that will skew the elements after reshape
238
+ x_flat = F.pad(x_flat, commons.convert_pad_shape([[0, 0], [0, 0], [length, 0]]))
239
+ x_final = x_flat.view([batch, heads, length, 2*length])[:,:,:,1:]
240
+ return x_final
241
+
242
+ def _attention_bias_proximal(self, length):
243
+ """Bias for self-attention to encourage attention to close positions.
244
+ Args:
245
+ length: an integer scalar.
246
+ Returns:
247
+ a Tensor with shape [1, 1, length, length]
248
+ """
249
+ r = torch.arange(length, dtype=torch.float32)
250
+ diff = torch.unsqueeze(r, 0) - torch.unsqueeze(r, 1)
251
+ return torch.unsqueeze(torch.unsqueeze(-torch.log1p(torch.abs(diff)), 0), 0)
252
+
253
+
254
+ class FFN(nn.Module):
255
+ def __init__(self, in_channels, out_channels, filter_channels, kernel_size, p_dropout=0., activation=None, causal=False):
256
+ super().__init__()
257
+ self.in_channels = in_channels
258
+ self.out_channels = out_channels
259
+ self.filter_channels = filter_channels
260
+ self.kernel_size = kernel_size
261
+ self.p_dropout = p_dropout
262
+ self.activation = activation
263
+ self.causal = causal
264
+
265
+ if causal:
266
+ self.padding = self._causal_padding
267
+ else:
268
+ self.padding = self._same_padding
269
+
270
+ self.conv_1 = nn.Conv1d(in_channels, filter_channels, kernel_size)
271
+ self.conv_2 = nn.Conv1d(filter_channels, out_channels, kernel_size)
272
+ self.drop = nn.Dropout(p_dropout)
273
+
274
+ def forward(self, x, x_mask):
275
+ x = self.conv_1(self.padding(x * x_mask))
276
+ if self.activation == "gelu":
277
+ x = x * torch.sigmoid(1.702 * x)
278
+ else:
279
+ x = torch.relu(x)
280
+ x = self.drop(x)
281
+ x = self.conv_2(self.padding(x * x_mask))
282
+ return x * x_mask
283
+
284
+ def _causal_padding(self, x):
285
+ if self.kernel_size == 1:
286
+ return x
287
+ pad_l = self.kernel_size - 1
288
+ pad_r = 0
289
+ padding = [[0, 0], [0, 0], [pad_l, pad_r]]
290
+ x = F.pad(x, commons.convert_pad_shape(padding))
291
+ return x
292
+
293
+ def _same_padding(self, x):
294
+ if self.kernel_size == 1:
295
+ return x
296
+ pad_l = (self.kernel_size - 1) // 2
297
+ pad_r = self.kernel_size // 2
298
+ padding = [[0, 0], [0, 0], [pad_l, pad_r]]
299
+ x = F.pad(x, commons.convert_pad_shape(padding))
300
+ return x
MOE-TTS/chinese_dialect_lexicons/changzhou.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Changzhou dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "changzhou.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "changzhou.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/changzhou.ocd2 ADDED
Binary file (96.1 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/cixi.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Cixi dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "cixi.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "cixi.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/cixi.ocd2 ADDED
Binary file (98 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/fuyang.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Fuyang dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "fuyang.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "fuyang.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/fuyang.ocd2 ADDED
Binary file (83.7 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/hangzhou.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Hangzhounese to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "hangzhou.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [{
11
+ "dict": {
12
+ "type": "group",
13
+ "dicts": [{
14
+ "type": "ocd2",
15
+ "file": "hangzhou.ocd2"
16
+ }]
17
+ }
18
+ }]
19
+ }
MOE-TTS/chinese_dialect_lexicons/hangzhou.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c7a9eb5fbd3b8c91745dbb2734f2700b75a47c3821e381566afc567d7da4d9d5
3
+ size 427268
MOE-TTS/chinese_dialect_lexicons/jiading.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Jiading dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "jiading.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "jiading.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/jiading.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4f3ac33214e65e7223e8c561bc12ec90a2d87db3cf8d20e87a30bbd8eb788187
3
+ size 111144
MOE-TTS/chinese_dialect_lexicons/jiashan.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Jiashan dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "jiashan.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "jiashan.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/jiashan.ocd2 ADDED
Binary file (71.7 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/jingjiang.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Jingjiang dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "jingjiang.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "jingjiang.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/jingjiang.ocd2 ADDED
Binary file (86.1 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/jyutjyu.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Cantonese to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "jyutjyu.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [{
11
+ "dict": {
12
+ "type": "group",
13
+ "dicts": [{
14
+ "type": "ocd2",
15
+ "file": "jyutjyu.ocd2"
16
+ }]
17
+ }
18
+ }]
19
+ }
MOE-TTS/chinese_dialect_lexicons/jyutjyu.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aea11bfe51b184b3f000d20ab49757979b216219203839d2b2e3c1f990a13fa5
3
+ size 2432991
MOE-TTS/chinese_dialect_lexicons/linping.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Linping dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "linping.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "linping.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/linping.ocd2 ADDED
Binary file (65.4 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/ningbo.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Ningbonese to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "ningbo.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [{
11
+ "dict": {
12
+ "type": "group",
13
+ "dicts": [{
14
+ "type": "ocd2",
15
+ "file": "ningbo.ocd2"
16
+ }]
17
+ }
18
+ }]
19
+ }
MOE-TTS/chinese_dialect_lexicons/ningbo.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5876b000f611ea52bf18cda5bcbdd0cfcc55e1c09774d9a24e3b5c7d90002435
3
+ size 386414
MOE-TTS/chinese_dialect_lexicons/pinghu.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Pinghu dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "pinghu.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "pinghu.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/pinghu.ocd2 ADDED
Binary file (69.4 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/ruao.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Ruao dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "ruao.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "ruao.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/ruao.ocd2 ADDED
Binary file (58.8 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/sanmen.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Sanmen dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "sanmen.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "sanmen.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/sanmen.ocd2 ADDED
Binary file (80.2 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/shaoxing.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Shaoxing dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "shaoxing.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "shaoxing.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/shaoxing.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a347aa25bf435803727b4194cf34de4de3e61f03427ee21043a711cdb0b9d940
3
+ size 113108
MOE-TTS/chinese_dialect_lexicons/suichang.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Suichang dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "suichang.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "suichang.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/suichang.ocd2 ADDED
Binary file (81 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/suzhou.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Suzhounese to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "suzhou.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [{
11
+ "dict": {
12
+ "type": "group",
13
+ "dicts": [{
14
+ "type": "ocd2",
15
+ "file": "suzhou.ocd2"
16
+ }]
17
+ }
18
+ }]
19
+ }
MOE-TTS/chinese_dialect_lexicons/suzhou.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a8815595a248135874329e7f34662dd243a266be3e8375e8409f95da95d6d540
3
+ size 506184
MOE-TTS/chinese_dialect_lexicons/tiantai.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Tiantai dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "tiantai.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "tiantai.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/tiantai.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:339e0ba454444dbf8fbe75de6f49769d11dfe2f2f5ba7dea74ba20fba5d6d343
3
+ size 120951
MOE-TTS/chinese_dialect_lexicons/tongxiang.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Tongxiang dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "tongxiang.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "tongxiang.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/tongxiang.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7432d85588eb8ba34e7baea9f26af8d332572037ff7d41a6730f96c02e5fd063
3
+ size 137499
MOE-TTS/chinese_dialect_lexicons/wenzhou.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Wenzhou dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "wenzhou.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "wenzhou.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/wenzhou.ocd2 ADDED
Binary file (83.1 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/wuxi.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Wuxinese to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "wuxi.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [{
11
+ "dict": {
12
+ "type": "group",
13
+ "dicts": [{
14
+ "type": "ocd2",
15
+ "file": "wuxi.ocd2"
16
+ }]
17
+ }
18
+ }]
19
+ }
MOE-TTS/chinese_dialect_lexicons/wuxi.ocd2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64f27ffaa75e542e4464e53c4acf94607be1526a90922ac8b28870104aaebdff
3
+ size 358666
MOE-TTS/chinese_dialect_lexicons/xiaoshan.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Xiaoshan dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "xiaoshan.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [
11
+ {
12
+ "dict": {
13
+ "type": "group",
14
+ "dicts": [
15
+ {
16
+ "type": "ocd2",
17
+ "file": "xiaoshan.ocd2"
18
+ }
19
+ ]
20
+ }
21
+ }
22
+ ]
23
+ }
MOE-TTS/chinese_dialect_lexicons/xiaoshan.ocd2 ADDED
Binary file (77.1 kB). View file
 
MOE-TTS/chinese_dialect_lexicons/xiashi.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Xiashi dialect to IPA",
3
+ "segmentation": {
4
+ "type": "mmseg",
5
+ "dict": {
6
+ "type": "ocd2",
7
+ "file": "xiashi.ocd2"
8
+ }
9
+ },
10
+ "conversion_chain": [{
11
+ "dict": {
12
+ "type": "group",
13
+ "dicts": [{
14
+ "type": "ocd2",
15
+ "file": "xiashi.ocd2"
16
+ }]
17
+ }
18
+ }]
19
+ }