Skip to content

Commit ec7e2a1

Browse files
authored
Merge pull request #142 from Artrajz/dev
update bert_vits2 v2.4
2 parents 353a1ed + 88e8ea1 commit ec7e2a1

31 files changed

+290589
-33
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
**/pytorch_model.bin
77
**/spm.model
88
/**/*.pt
9+
/**/*.onnx
910
phrases_dict.txt
1011
/config.yml
1112
/config.yaml

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ tts_config:
175175
model_path: D://model3/G_1000.pth
176176
```
177177

178+
- models_path: This is the models folder relative to the data directory, with the default value being "models". When auto_load is set to true, all models in the models_path directory will be loaded.
179+
178180
#### Other Models
179181

180182
After downloading the BERT model and emotion model, place them in the `data/bert` and `data/emotional` folders respectively. Find the corresponding names and insert them accordingly.

README_zh.md

+2
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ tts_config:
178178
model_path: D://model3/G_1000.pth
179179
```
180180

181+
- models_path:是相对于data目录下的模型文件夹,默认为models,auto_load为true时将会加载models_path目录下的所有模型。
182+
181183
#### 其他模型
182184

183185
bert模型以及情感模型下载之后放在`data/bert`文件夹和`data/emotional`文件夹中,找到对应名字放入即可。

bert_vits2/bert_vits2.py

+19-4
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ def __init__(self, model_path, config, device=torch.device("cpu"), **kwargs):
3131
self.zh_bert_extra = False
3232
self.ja_bert_dim = 1024
3333
self.num_tones = num_tones
34+
self.pinyinPlus = None
3435

3536
# Compatible with legacy versions
36-
self.version = process_legacy_versions(self.hps_ms)
37+
self.version = process_legacy_versions(self.hps_ms).lower().replace("-", "_")
3738
self.text_extra_str_map = {"zh": "", "ja": "", "en": ""}
3839
self.bert_extra_str_map = {"zh": "", "ja": "", "en": ""}
3940
self.hps_ms.model.emotion_embedding = None
@@ -102,7 +103,7 @@ def __init__(self, model_path, config, device=torch.device("cpu"), **kwargs):
102103
if "ja" in self.lang: self.bert_model_names.update({"ja": "DEBERTA_V2_LARGE_JAPANESE_CHAR_WWM"})
103104
if "en" in self.lang: self.bert_model_names.update({"en": "DEBERTA_V3_LARGE"})
104105

105-
elif self.version is not None and self.version.lower().replace("-", "_") in ["extra", "zh_clap"]:
106+
elif self.version is not None and self.version in ["extra", "zh_clap"]:
106107
self.version = "extra"
107108
self.hps_ms.model.emotion_embedding = 2
108109
self.hps_ms.model.n_layers_trans_flow = 6
@@ -112,6 +113,17 @@ def __init__(self, model_path, config, device=torch.device("cpu"), **kwargs):
112113
self.bert_model_names.update({"zh": "Erlangshen_MegatronBert_1.3B_Chinese"})
113114
self.bert_extra_str_map.update({"zh": "_extra"})
114115

116+
elif self.version is not None and self.version in ["extra_fix", "2.4", "2.4.0"]:
117+
self.version = "2.4"
118+
self.hps_ms.model.emotion_embedding = 2
119+
self.hps_ms.model.n_layers_trans_flow = 6
120+
self.lang = ["zh"]
121+
self.num_tones = num_tones
122+
self.zh_bert_extra = True
123+
self.bert_model_names.update({"zh": "Erlangshen_MegatronBert_1.3B_Chinese"})
124+
self.bert_extra_str_map.update({"zh": "_extra"})
125+
self.text_extra_str_map.update({"zh": "_v240"})
126+
115127
else:
116128
logging.debug("Version information not found. Loaded as the newest version: v2.3.")
117129
self.version = "2.3"
@@ -131,10 +143,13 @@ def __init__(self, model_path, config, device=torch.device("cpu"), **kwargs):
131143
def load_model(self, model_handler):
132144
self.model_handler = model_handler
133145

134-
if self.version in ["2.3", "extra"]:
146+
if self.version in ["2.3", "extra", "2.4"]:
135147
Synthesizer = SynthesizerTrn_v230
136148
else:
137149
Synthesizer = SynthesizerTrn
150+
151+
if self.version == "2.4":
152+
self.pinyinPlus = self.model_handler.get_pinyinPlus()
138153
self.net_g = Synthesizer(
139154
len(self.symbols),
140155
self.hps_ms.data.filter_length // 2 + 1,
@@ -157,7 +172,7 @@ def get_text(self, text, language_str, hps, style_text=None, style_weight=0.7):
157172

158173
tokenizer, _ = self.model_handler.get_bert_model(self.bert_model_names[language_str])
159174

160-
norm_text, phone, tone, word2ph = clean_text(text, clean_text_lang_str, tokenizer)
175+
norm_text, phone, tone, word2ph = clean_text(text, clean_text_lang_str, tokenizer, self.pinyinPlus)
161176

162177
phone, tone, language = cleaned_text_to_sequence(phone, tone, language_str, self._symbol_to_id)
163178

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from .g2pw import G2PWPinyin
4+
5+
__all__ = ["G2PWPinyin"]
+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from pypinyin.constants import RE_HANS
4+
from pypinyin.core import Pinyin, Style
5+
from pypinyin.seg.simpleseg import simple_seg
6+
from pypinyin.converter import UltimateConverter
7+
from pypinyin.contrib.tone_convert import to_tone
8+
from .g2pw1.onnx_api import G2PWOnnxConverter
9+
10+
class G2PWPinyin(Pinyin):
11+
def __init__(
12+
self,
13+
model_dir="G2PWModel/",
14+
model_source=None,
15+
num_workers=None,
16+
batch_size=None,
17+
turnoff_tqdm=True,
18+
enable_non_tradional_chinese=True,
19+
v_to_u=False,
20+
neutral_tone_with_five=False,
21+
tone_sandhi=False,
22+
**kwargs
23+
):
24+
self._g2pw = G2PWOnnxConverter(
25+
model_dir=model_dir,
26+
style="pinyin",
27+
model_source=model_source,
28+
enable_non_tradional_chinese=enable_non_tradional_chinese,
29+
)
30+
self._converter = Converter(
31+
self._g2pw,
32+
v_to_u=v_to_u,
33+
neutral_tone_with_five=neutral_tone_with_five,
34+
tone_sandhi=tone_sandhi,
35+
)
36+
37+
def get_seg(self, **kwargs):
38+
return simple_seg
39+
40+
41+
class Converter(UltimateConverter):
42+
def __init__(
43+
self,
44+
g2pw_instance,
45+
v_to_u=False,
46+
neutral_tone_with_five=False,
47+
tone_sandhi=False,
48+
**kwargs
49+
):
50+
super(Converter, self).__init__(
51+
v_to_u=v_to_u,
52+
neutral_tone_with_five=neutral_tone_with_five,
53+
tone_sandhi=tone_sandhi,
54+
**kwargs
55+
)
56+
57+
self._g2pw = g2pw_instance
58+
59+
def convert(self, words, style, heteronym, errors, strict, **kwargs):
60+
pys = []
61+
if RE_HANS.match(words):
62+
pys = self._to_pinyin(
63+
words, style=style, heteronym=heteronym, errors=errors, strict=strict
64+
)
65+
post_data = self.post_pinyin(words, heteronym, pys)
66+
if post_data is not None:
67+
pys = post_data
68+
69+
pys = self.convert_styles(pys, words, style, heteronym, errors, strict)
70+
71+
else:
72+
py = self.handle_nopinyin(
73+
words, style=style, errors=errors, heteronym=heteronym, strict=strict
74+
)
75+
if py:
76+
pys.extend(py)
77+
78+
return _remove_dup_and_empty(pys)
79+
80+
def _to_pinyin(self, han, style, heteronym, errors, strict, **kwargs):
81+
g2pw_pinyin = self._g2pw(han)
82+
83+
if not g2pw_pinyin: # g2pw 不支持的汉字改为使用 pypinyin 原有逻辑
84+
return super(Converter, self).convert(
85+
han, Style.TONE, heteronym, errors, strict, **kwargs
86+
)
87+
88+
pinyins = []
89+
90+
for i, item in enumerate(g2pw_pinyin[0]):
91+
if item is None: # g2pw 不支持的汉字改为使用 pypinyin 原有逻辑
92+
py = super(Converter, self).convert(
93+
han[i], Style.TONE, heteronym, errors, strict, **kwargs
94+
)
95+
pinyins.extend(py)
96+
else:
97+
pinyins.append([to_tone(item)])
98+
99+
return pinyins
100+
101+
102+
def _remove_dup_items(lst, remove_empty=False):
103+
new_lst = []
104+
for item in lst:
105+
if remove_empty and not item:
106+
continue
107+
if item not in new_lst:
108+
new_lst.append(item)
109+
return new_lst
110+
111+
112+
def _remove_dup_and_empty(lst_list):
113+
new_lst_list = []
114+
for lst in lst_list:
115+
lst = _remove_dup_items(lst, remove_empty=True)
116+
if lst:
117+
new_lst_list.append(lst)
118+
else:
119+
new_lst_list.append([""])
120+
121+
return new_lst_list

bert_vits2/g2pW/pypinyin_G2pW_bv2/g2pw1/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"ㄌㄧㄥ": "ling", "ㄩㄢ": "yuan", "ㄒㄧㄥ": "xing", "ㄑㄧㄡ": "qiu", "ㄊㄧㄢ": "tian", "ㄎㄨㄚ": "kua", "ㄨ": "wu", "ㄧㄣ": "yin", "ㄧ": "yi", "ㄒㄧㄝ": "xie", "ㄔㄡ": "chou", "ㄋㄨㄛ": "nuo", "ㄉㄢ": "dan", "ㄒㄩ": "xu", "ㄒㄩㄥ": "xiong", "ㄌㄧㄡ": "liu", "ㄌㄧㄣ": "lin", "ㄒㄧㄤ": "xiang", "ㄩㄥ": "yong", "ㄒㄧㄣ": "xin", "ㄓㄣ": "zhen", "ㄉㄞ": "dai", "ㄆㄢ": "pan", "ㄖㄨ": "ru", "ㄇㄚ": "ma", "ㄑㄧㄢ": "qian", "ㄘ": "ci", "ㄓㄨㄥ": "zhong", "ㄋㄟ": "nei", "ㄔㄥ": "cheng", "ㄈㄥ": "feng", "ㄓㄨㄛ": "zhuo", "ㄈㄤ": "fang", "ㄠ": "ao", "ㄗㄨㄛ": "zuo", "ㄓㄡ": "zhou", "ㄉㄨㄥ": "dong", "ㄙㄨ": "su", "ㄑㄩㄥ": "qiong", "ㄎㄨㄤ": "kuang", "ㄨㄤ": "wang", "ㄌㄟ": "lei", "ㄋㄠ": "nao", "ㄓㄨ": "zhu", "ㄕㄨ": "shu", "ㄕㄣ": "shen", "ㄐㄧㄝ": "jie", "ㄉㄧㄝ": "die", "ㄔ": "chi", "ㄌㄨㄥ": "long", "ㄧㄥ": "ying", "ㄅㄥ": "beng", "ㄌㄢ": "lan", "ㄇㄧㄠ": "miao", "ㄌㄧ": "li", "ㄐㄧ": "ji", "ㄩ": "yu", "ㄌㄨㄛ": "luo", "ㄔㄞ": "chai", "ㄏㄨㄣ": "hun", "ㄏㄨㄟ": "hui", "ㄖㄠ": "rao", "ㄏㄢ": "han", "ㄒㄧ": "xi", "ㄊㄞ": "tai", "ㄧㄠ": "yao", "ㄐㄩㄣ": "jun", "ㄌㄩㄝ": "lve", "ㄊㄤ": "tang", "ㄓㄠ": "zhao", "ㄓㄞ": "zhai", "ㄓㄚ": "zha", "ㄦ": "er", "ㄖㄢ": "ran", "ㄑㄧ": "qi", "ㄙㄜ": "se", "ㄙ": "si", "ㄙㄚ": "sa", "ㄎㄨㄟ": "kui", "ㄆㄨ": "pu", "ㄊㄚ": "ta", "ㄉㄨ": "du", "ㄊㄨ": "tu", "ㄧㄤ": "yang", "ㄡ": "ou", "ㄇㄧㄢ": "mian", "ㄨㄣ": "wen", "ㄉㄧㄠ": "diao", "ㄇㄧㄝ": "mie", "ㄨㄚ": "wa", "ㄋㄧㄠ": "niao", "ㄧㄡ": "you", "ㄔㄜ": "che", "ㄑㄩㄢ": "quan", "ㄘㄞ": "cai", "ㄌㄧㄤ": "liang", "ㄍㄨ": "gu", "ㄇㄠ": "mao", "ㄍㄨㄚ": "gua", "ㄙㄨㄟ": "sui", "ㄇㄢ": "man", "ㄕ": "shi", "ㄎㄡ": "kou", "ㄊㄧㄥ": "ting", "ㄅㄧㄥ": "bing", "ㄏㄨㄛ": "huo", "ㄍㄨㄥ": "gong", "ㄑㄧㄣ": "qin", "ㄐㄩㄥ": "jiong", "ㄌㄨ": "lu", "ㄋㄢ": "nan", "ㄅㄧ": "bi", "ㄑㄧㄚ": "qia", "ㄆㄧ": "pi", "ㄉㄧㄢ": "dian", "ㄈㄨ": "fu", "ㄍㄜ": "ge", "ㄅㄞ": "bai", "ㄍㄢ": "gan", "ㄒㄩㄢ": "xuan", "ㄌㄤ": "lang", "ㄕㄜ": "she", "ㄏㄨㄚ": "hua", "ㄊㄡ": "tou", "ㄆㄧㄢ": "pian", "ㄉㄧ": "di", "ㄖㄨㄢ": "ruan", "ㄜ": "e", "ㄑㄧㄝ": "qie", "ㄉㄡ": "dou", "ㄖㄨㄟ": "rui", "ㄘㄨㄟ": "cui", "ㄐㄧㄢ": "jian", "ㄔㄨㄥ": "chong", "ㄉㄥ": "deng", "ㄐㄩㄝ": "jue", "ㄒㄩㄝ": "xue", "ㄒㄧㄠ": "xiao", "ㄗㄢ": "zan", "ㄓㄢ": "zhan", "ㄗㄡ": "zou", "ㄘㄡ": "cou", "ㄔㄨㄚ": "chua", "ㄈㄟ": "fei", "ㄅㄟ": "bei", "ㄔㄨ": "chu", "ㄅㄚ": "ba", "ㄎㄨㄞ": "kuai", "ㄒㄧㄚ": "xia", "ㄏㄜ": "he", "ㄅㄧㄝ": "bie", "ㄌㄩ": "lv", "ㄙㄨㄢ": "suan", "ㄏㄥ": "heng", "ㄍㄨㄟ": "gui", "ㄌㄡ": "lou", "ㄊㄧ": "ti", "ㄌㄜ": "le", "ㄙㄨㄣ": "sun", "ㄒㄧㄢ": "xian", "ㄑㄩㄝ": "que", "ㄓ": "zhi", "ㄐㄧㄚ": "jia", "ㄏㄨ": "hu", "ㄌㄚ": "la", "ㄎㄜ": "ke", "ㄞ": "ai", "ㄨㄟ": "wei", "ㄏㄨㄢ": "huan", "ㄕㄨㄚ": "shua", "ㄕㄨㄤ": "shuang", "ㄍㄞ": "gai", "ㄏㄞ": "hai", "ㄧㄢ": "yan", "ㄈㄢ": "fan", "ㄆㄤ": "pang", "ㄙㄨㄥ": "song", "ㄋㄜ": "ne", "ㄔㄣ": "chen", "ㄍㄨㄛ": "guo", "ㄣ": "en", "ㄋㄍ": "ng", "ㄆㄚ": "pa", "ㄈㄚ": "fa", "ㄆㄡ": "pou", "ㄏㄡ": "hou", "ㄑㄩ": "qu", "ㄒㄩㄣ": "xun", "ㄋㄧㄝ": "nie", "ㄏㄨㄥ": "hong", "ㄊㄨㄣ": "tun", "ㄨㄞ": "wai", "ㄕㄡ": "shou", "ㄧㄝ": "ye", "ㄐㄩ": "ju", "ㄙㄡ": "sou", "ㄌㄨㄣ": "lun", "ㄋㄧㄚ": "nia", "ㄆㄣ": "pen", "ㄈㄣ": "fen", "ㄔㄨㄣ": "chun", "ㄋㄧㄡ": "niu", "ㄖㄡ": "rou", "ㄉㄨㄛ": "duo", "ㄗㄜ": "ze", "ㄕㄥ": "sheng", "ㄎㄨ": "ku", "ㄧㄚ": "ya", "ㄓㄨㄟ": "zhui", "ㄍㄡ": "gou", "ㄅㄛ": "bo", "ㄋㄚ": "na", "ㄒㄧㄡ": "xiu", "ㄘㄨ": "cu", "ㄎㄨㄛ": "kuo", "ㄌㄠ": "lao", "ㄘㄨㄥ": "cong", "ㄉㄚ": "da", "ㄆㄛ": "po", "ㄙㄞ": "sai", "ㄌㄥ": "leng", "ㄖㄨㄥ": "rong", "ㄋㄧ": "ni", "ㄆㄠ": "pao", "ㄎㄢ": "kan", "ㄨㄥ": "weng", "ㄨㄢ": "wan", "ㄏㄠ": "hao", "ㄐㄧㄥ": "jing", "ㄊㄢ": "tan", "ㄅㄨ": "bu", "ㄗㄤ": "zang", "ㄐㄧㄡ": "jiu", "ㄇㄟ": "mei", "ㄇㄨ": "mu", "ㄉㄨㄟ": "dui", "ㄅㄤ": "bang", "ㄅㄠ": "bao", "ㄔㄤ": "chang", "ㄓㄤ": "zhang", "ㄗㄨㄥ": "zong", "ㄍㄨㄣ": "gun", "ㄌㄧㄠ": "liao", "ㄔㄢ": "chan", "ㄓㄜ": "zhe", "ㄇㄥ": "meng", "ㄑㄧㄠ": "qiao", "ㄋㄤ": "nang", "ㄩㄣ": "yun", "ㄎㄞ": "kai", "ㄍㄠ": "gao", "ㄊㄠ": "tao", "ㄕㄢ": "shan", "ㄌㄞ": "lai", "ㄅㄢ": "ban", "ㄎㄨㄥ": "kong", "ㄔㄨㄛ": "chuo", "ㄋㄨ": "nu", "ㄆㄟ": "pei", "ㄆㄥ": "peng", "ㄘㄢ": "can", "ㄙㄨㄛ": "suo", "ㄊㄨㄥ": "tong", "ㄑㄧㄤ": "qiang", "ㄙㄠ": "sao", "ㄓㄨㄢ": "zhuan", "ㄢ": "an", "ㄔㄚ": "cha", "ㄕㄚ": "sha", "ㄌㄧㄢ": "lian", "ㄇㄧ": "mi", "ㄋㄡ": "nou", "ㄘㄠ": "cao", "ㄙㄣ": "sen", "ㄋㄣ": "nen", "ㄋㄧㄢ": "nian", "ㄇㄞ": "mai", "ㄩㄝ": "yue", "ㄋㄞ": "nai", "ㄏㄨㄞ": "huai", "ㄗ": "zi", "ㄌㄨㄢ": "luan", "ㄉㄧㄥ": "ding", "ㄇㄤ": "mang", "ㄋㄧㄥ": "ning", "ㄇㄧㄥ": "ming", "ㄗㄨㄟ": "zui", "ㄎㄤ": "kang", "ㄉㄜ": "de", "ㄅㄧㄢ": "bian", "ㄐㄧㄣ": "jin", "ㄔㄨㄟ": "chui", "ㄊㄨㄟ": "tui", "ㄗㄚ": "za", "ㄘㄣ": "cen", "ㄇㄧㄣ": "min", "ㄏㄨㄤ": "huang", "ㄗㄨ": "zu", "ㄘㄨㄛ": "cuo", "ㄊㄨㄛ": "tuo", "ㄑㄩㄣ": "qun", "ㄅㄧㄣ": "bin", "ㄊㄧㄠ": "tiao", "ㄍㄤ": "gang", "ㄉㄨㄢ": "duan", "ㄅㄧㄠ": "biao", "ㄉㄠ": "dao", "ㄖㄨㄣ": "run", "ㄐㄧㄠ": "jiao", "ㄨㄛ": "wo", "ㄘㄨㄢ": "cuan", "ㄖㄣ": "ren", "ㄇㄣ": "men", "ㄓㄨㄣ": "zhun", "ㄎㄨㄣ": "kun", "ㄔㄨㄤ": "chuang", "ㄗㄠ": "zao", "ㄓㄥ": "zheng", "ㄆㄧㄣ": "pin", "ㄅㄣ": "ben", "ㄐㄧㄤ": "jiang", "ㄐㄩㄢ": "juan", "ㄘㄥ": "ceng", "ㄏㄤ": "hang", "ㄋㄧㄣ": "nin", "ㄌㄧㄝ": "lie", "ㄍㄨㄤ": "guang", "ㄙㄢ": "san", "ㄊㄜ": "te", "ㄕㄨㄣ": "shun", "ㄕㄨㄟ": "shui", "ㄔㄠ": "chao", "ㄘㄜ": "ce", "ㄍㄨㄞ": "guai", "ㄎㄥ": "keng", "ㄕㄞ": "shai", "ㄉㄣ": "den", "ㄊㄨㄢ": "tuan", "ㄆㄧㄠ": "piao", "ㄑㄧㄥ": "qing", "ㄍㄥ": "geng", "ㄔㄨㄞ": "chuai", "ㄕㄠ": "shao", "ㄍㄣ": "gen", "ㄋㄨㄢ": "nuan", "ㄖㄥ": "reng", "ㄇㄡ": "mou", "ㄆㄞ": "pai", "ㄤ": "ang", "ㄎㄚ": "ka", "ㄍㄨㄢ": "guan", "ㄕㄨㄛ": "shuo", "ㄏㄣ": "hen", "ㄔㄨㄢ": "chuan", "ㄎㄨㄢ": "kuan", "ㄏㄟ": "hei", "ㄇㄛ": "mo", "ㄗㄞ": "zai", "ㄋㄥ": "neng", "ㄕㄨㄞ": "shuai", "ㄖㄜ": "re", "ㄋㄩ": "nv", "ㄆㄧㄥ": "ping", "ㄘㄤ": "cang", "ㄋㄨㄥ": "nong", "ㄎㄠ": "kao", "ㄗㄨㄢ": "zuan", "ㄎㄣ": "ken", "ㄍㄚ": "ga", "ㄗㄣ": "zen", "ㄉㄤ": "dang", "ㄗㄥ": "zeng", "ㄉㄨㄣ": "dun", "ㄘㄚ": "ca", "ㄖㄤ": "rang", "ㄘㄨㄣ": "cun", "ㄖㄨㄛ": "ruo", "ㄊㄧㄝ": "tie", "ㄊㄥ": "teng", "ㄙㄥ": "seng", "ㄖ": "ri", "ㄗㄨㄣ": "zun", "ㄋㄧㄤ": "niang", "ㄋㄩㄝ": "nve", "ㄙㄤ": "sang", "ㄓㄨㄤ": "zhuang", "ㄕㄤ": "shang", "ㄆㄧㄝ": "pie", "ㄕㄨㄢ": "shuan", "ㄈㄡ": "fou", "ㄉㄧㄡ": "diu", "ㄇㄜ": "me", "ㄈㄛ": "fo", "ㄌㄧㄚ": "lia", "ㄎㄟ": "kei", "ㄏㄚ": "ha", "ㄚ": "a", "ㄌㄛ": "lo", "ㄧㄛ": "yo", "ㄛ": "o", "ㄏㄋㄍ": "hng", "ㄋ": "n", "ㄌㄣ": "len", "ㄉㄧㄚ": "dia", "ㄇㄧㄡ": "miu", "ㄉㄟ": "dei", "ㄏㄇ": "hm", "ㄋㄨㄣ": "nun", "ㄓㄨㄞ": "zhuai", "ㄊㄟ": "tei", "ㄗㄟ": "zei", "ㄓㄨㄚ": "zhua", "ㄖㄨㄚ": "rua", "ê": "ê", "ㄟ": "ei", "ㄍㄟ": "gei", "ㄈㄧㄠ": "fiao", "ㄕㄟ": "shei", "ㄓㄟ": "zhei", "ㄥ": "eng", "ㄘㄟ": "cei", "ㄉㄧㄣ": "din", "ㄅㄧㄤ": "biang", "ㄧㄞ": "yai"}

0 commit comments

Comments
 (0)