diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..5730da2e237d68c33702fb2bbad55a357abd9fbe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text +diffrhythm/g2p/sources/chinese_lexicon.txt filter=lfs diff=lfs merge=lfs -text diff --git a/diffrhythm/.DS_Store b/diffrhythm/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e7bf22c308ef70d139de8bdc449c65e7bcee840a Binary files /dev/null and b/diffrhythm/.DS_Store differ diff --git a/diffrhythm/config/defaults.ini b/diffrhythm/config/defaults.ini new file mode 100644 index 0000000000000000000000000000000000000000..ca6a8b08c28aa9fd058bee80b9a89d2592fd8be0 --- /dev/null +++ b/diffrhythm/config/defaults.ini @@ -0,0 +1,94 @@ + +[DEFAULTS] + +#name of the run +exp_name = F5 + +# the batch size +batch_size = 8 + +# the chunk size +max_frames = 3000 +min_frames = 10 + +# number of CPU workers for the DataLoader +num_workers = 4 + +# the random seed +seed = 42 + +# Batches for gradient accumulation +accum_batches = 1 + +# Number of steps between checkpoints +checkpoint_every = 10000 + +# trainer checkpoint file to restart training from +ckpt_path = '' + +# model checkpoint file to start a new training run from +pretrained_ckpt_path = '' + +# Checkpoint path for the pretransform model if needed +pretransform_ckpt_path = '' + +# configuration model specifying model hyperparameters +model_config = '' + +# configuration for datasets +dataset_config = '' + +# directory to save the checkpoints in +save_dir = '' + +# grad norm +max_grad_norm = 1.0 + +# grad accu +grad_accumulation_steps = 1 + +# lr +learning_rate = 7.5e-5 + +# epoch +epochs = 110 + +# warmup steps +num_warmup_updates = 2000 + +# save checkpoint per steps +save_per_updates = 5000 + +# save last checkpoint per steps +last_per_steps = 5000 + +prompt_path = "/mnt/sfs/music/lance/style-lance-full|/mnt/sfs/music/lance/style-lance-cnen-music-second" +lrc_path = "/mnt/sfs/music/lance/lrc-lance-emb-full|/mnt/sfs/music/lance/lrc-lance-cnen-second" +latent_path = "/mnt/sfs/music/lance/latent-lance|/mnt/sfs/music/lance/latent-lance-cnen-music-second-1|/mnt/sfs/music/lance/latent-lance-cnen-music-second-2" + +audio_drop_prob = 0.3 +cond_drop_prob = 0.0 +style_drop_prob = 0.1 +lrc_drop_prob = 0.1 + +align_lyrics = 0 +lyrics_slice = 0 +parse_lyrics = 1 +skip_empty_lyrics = 0 +lyrics_shift = -1 + +use_style_prompt = 1 + +tokenizer_type = gpt2 + +reset_lr = 0 + +resumable_with_seed = 666 + +downsample_rate = 2048 + +grad_ckpt = 0 + +dataset_path = "/mnt/sfs/music/hkchen/workspace/F5-TTS-HW/filelists/music123latent_asred_bpmstyle_cnen_pure1" + +pure_prob = 0.0 \ No newline at end of file diff --git a/diffrhythm/config/diffrhythm-1b.json b/diffrhythm/config/diffrhythm-1b.json new file mode 100644 index 0000000000000000000000000000000000000000..c83c317a84eae49ad2c811e7c59141b95894b2a3 --- /dev/null +++ b/diffrhythm/config/diffrhythm-1b.json @@ -0,0 +1,13 @@ +{ + "model_type": "diffrhythm", + "model": { + "dim": 2048, + "depth": 16, + "heads": 32, + "ff_mult": 4, + "text_dim": 512, + "conv_layers": 4, + "mel_dim": 64, + "text_num_embeds": 363 + } +} \ No newline at end of file diff --git a/diffrhythm/g2p/__pycache__/g2p_generation.cpython-310.pyc b/diffrhythm/g2p/__pycache__/g2p_generation.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2d2a9e187b65a0a2db6db23efbf8e772c6ebfac Binary files /dev/null and b/diffrhythm/g2p/__pycache__/g2p_generation.cpython-310.pyc differ diff --git a/diffrhythm/g2p/__pycache__/g2p_generation.cpython-311.pyc b/diffrhythm/g2p/__pycache__/g2p_generation.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49dd6f71526b374aaa8a7b83622983928985bd8e Binary files /dev/null and b/diffrhythm/g2p/__pycache__/g2p_generation.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__init__.py b/diffrhythm/g2p/g2p/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a926893b1b3473fbc8363238a517781e59092365 --- /dev/null +++ b/diffrhythm/g2p/g2p/__init__.py @@ -0,0 +1,87 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from diffrhythm.g2p.g2p import cleaners +from tokenizers import Tokenizer +from diffrhythm.g2p.g2p.text_tokenizers import TextTokenizer +import LangSegment +import json +import re + + +class PhonemeBpeTokenizer: + + def __init__(self, vacab_path="./diffrhythm/g2p/g2p/vocab.json"): + self.lang2backend = { + "zh": "cmn", + "ja": "ja", + "en": "en-us", + "fr": "fr-fr", + "ko": "ko", + "de": "de", + } + self.text_tokenizers = {} + self.int_text_tokenizers() + + with open(vacab_path, "r") as f: + json_data = f.read() + data = json.loads(json_data) + self.vocab = data["vocab"] + LangSegment.setfilters(["en", "zh", "ja", "ko", "fr", "de"]) + + def int_text_tokenizers(self): + for key, value in self.lang2backend.items(): + self.text_tokenizers[key] = TextTokenizer(language=value) + + def tokenize(self, text, sentence, language): + + # 1. convert text to phoneme + phonemes = [] + if language == "auto": + seglist = LangSegment.getTexts(text) + tmp_ph = [] + for seg in seglist: + tmp_ph.append( + self._clean_text( + seg["text"], sentence, seg["lang"], ["cjekfd_cleaners"] + ) + ) + phonemes = "|_|".join(tmp_ph) + else: + phonemes = self._clean_text(text, sentence, language, ["cjekfd_cleaners"]) + # print('clean text: ', phonemes) + + # 2. tokenize phonemes + phoneme_tokens = self.phoneme2token(phonemes) + # print('encode: ', phoneme_tokens) + + # # 3. decode tokens [optional] + # decoded_text = self.tokenizer.decode(phoneme_tokens) + # print('decoded: ', decoded_text) + + return phonemes, phoneme_tokens + + def _clean_text(self, text, sentence, language, cleaner_names): + for name in cleaner_names: + cleaner = getattr(cleaners, name) + if not cleaner: + raise Exception("Unknown cleaner: %s" % name) + text = cleaner(text, sentence, language, self.text_tokenizers) + return text + + def phoneme2token(self, phonemes): + tokens = [] + if isinstance(phonemes, list): + for phone in phonemes: + phone = phone.split("\t")[0] + phonemes_split = phone.split("|") + tokens.append( + [self.vocab[p] for p in phonemes_split if p in self.vocab] + ) + else: + phonemes = phonemes.split("\t")[0] + phonemes_split = phonemes.split("|") + tokens = [self.vocab[p] for p in phonemes_split if p in self.vocab] + return tokens diff --git a/diffrhythm/g2p/g2p/__pycache__/__init__.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9f11e88f64aa267f63c0a55ea587c137edaa21f Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/__init__.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/__init__.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b48242ecd85110a210928981ab4683307c3445d Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/__init__.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/chinese_model_g2p.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/chinese_model_g2p.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a453e7b28601651822d6ee4bd7d54899a75f1a8 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/chinese_model_g2p.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/chinese_model_g2p.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/chinese_model_g2p.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7bc70551aefff7b1c8cf326a9903fcd087463d3 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/chinese_model_g2p.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/cleaners.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/cleaners.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13e68c4fb67c3d5f3b2a7758c385717dd8b2ea93 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/cleaners.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/cleaners.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/cleaners.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..013bbe6b49d22b2bc36a02c6c2ce7179f06347d0 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/cleaners.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/english.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/english.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25a29618186dc529e1e0a27b10ba3c1016dbdf16 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/english.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/english.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/english.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ff432f97815a81eb6104fba4ed3e774ce5b47ec Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/english.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/french.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/french.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cffaf2e4a8c20080a29dc33d84db424c69215fc2 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/french.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/french.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/french.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c85b2081340a89747f74e1d05c1d89129af5e91c Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/french.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/german.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/german.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..feacd0edc5ba0d53ab5ee4d6f8ec3d5035f68c6e Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/german.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/german.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/german.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6017b5e4b7b8cca7d51bfd2d08a68e83997bf6ea Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/german.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/japanese.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/japanese.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f23f51ad05503c94f0277706dbc39353f03ebc2f Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/japanese.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/japanese.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/japanese.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe78662944ef5ba7e264c4511af8fa8b4b855174 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/japanese.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/korean.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/korean.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ee12460bd83adb04a0e1966823bd888b88567b5 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/korean.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/korean.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/korean.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2458bc061120b920262f8a4a6a2aaa764987bdb2 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/korean.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/mandarin.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/mandarin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cea802d2e6d35cffca794715c0fbea59fa9e584b Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/mandarin.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/mandarin.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/mandarin.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44db3a9278b916bed6f9e5530ed96600c8581854 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/mandarin.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/text_tokenizers.cpython-310.pyc b/diffrhythm/g2p/g2p/__pycache__/text_tokenizers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b5b20b7df77493fb9835124d8d44ef53f58a2a6 Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/text_tokenizers.cpython-310.pyc differ diff --git a/diffrhythm/g2p/g2p/__pycache__/text_tokenizers.cpython-311.pyc b/diffrhythm/g2p/g2p/__pycache__/text_tokenizers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..237338f5a6f9ec1fa776447c0585cc274d49a3bc Binary files /dev/null and b/diffrhythm/g2p/g2p/__pycache__/text_tokenizers.cpython-311.pyc differ diff --git a/diffrhythm/g2p/g2p/chinese_model_g2p.py b/diffrhythm/g2p/g2p/chinese_model_g2p.py new file mode 100644 index 0000000000000000000000000000000000000000..6502ae0cd0959de9b82c1049e3a9d34b3293934f --- /dev/null +++ b/diffrhythm/g2p/g2p/chinese_model_g2p.py @@ -0,0 +1,213 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import os +import numpy as np +import torch +from torch.utils.data import DataLoader +import json +from transformers import BertTokenizer +from torch.utils.data import Dataset +from transformers.models.bert.modeling_bert import * +import torch +import torch.nn.functional as F +from onnxruntime import InferenceSession, GraphOptimizationLevel, SessionOptions + + +class PolyDataset(Dataset): + def __init__(self, words, labels, word_pad_idx=0, label_pad_idx=-1): + self.dataset = self.preprocess(words, labels) + self.word_pad_idx = word_pad_idx + self.label_pad_idx = label_pad_idx + + def preprocess(self, origin_sentences, origin_labels): + """ + Maps tokens and tags to their indices and stores them in the dict data. + examples: + word:['[CLS]', '浙', '商', '银', '行', '企', '业', '信', '贷', '部'] + sentence:([101, 3851, 1555, 7213, 6121, 821, 689, 928, 6587, 6956], + array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) + label:[3, 13, 13, 13, 0, 0, 0, 0, 0] + """ + data = [] + labels = [] + sentences = [] + # tokenize + for line in origin_sentences: + # replace each token by its index + # we can not use encode_plus because our sentences are aligned to labels in list type + words = [] + word_lens = [] + for token in line: + words.append(token) + word_lens.append(1) + token_start_idxs = 1 + np.cumsum([0] + word_lens[:-1]) + sentences.append(((words, token_start_idxs), 0)) + ### + for tag in origin_labels: + labels.append(tag) + + for sentence, label in zip(sentences, labels): + data.append((sentence, label)) + return data + + def __getitem__(self, idx): + """sample data to get batch""" + word = self.dataset[idx][0] + label = self.dataset[idx][1] + return [word, label] + + def __len__(self): + """get dataset size""" + return len(self.dataset) + + def collate_fn(self, batch): + + sentences = [x[0][0] for x in batch] + ori_sents = [x[0][1] for x in batch] + labels = [x[1] for x in batch] + batch_len = len(sentences) + + # compute length of longest sentence in batch + max_len = max([len(s[0]) for s in sentences]) + max_label_len = 0 + batch_data = np.ones((batch_len, max_len)) + batch_label_starts = [] + + # padding and aligning + for j in range(batch_len): + cur_len = len(sentences[j][0]) + batch_data[j][:cur_len] = sentences[j][0] + label_start_idx = sentences[j][-1] + label_starts = np.zeros(max_len) + label_starts[[idx for idx in label_start_idx if idx < max_len]] = 1 + batch_label_starts.append(label_starts) + max_label_len = max(int(sum(label_starts)), max_label_len) + + # padding label + batch_labels = self.label_pad_idx * np.ones((batch_len, max_label_len)) + batch_pmasks = self.label_pad_idx * np.ones((batch_len, max_label_len)) + for j in range(batch_len): + cur_tags_len = len(labels[j]) + batch_labels[j][:cur_tags_len] = labels[j] + batch_pmasks[j][:cur_tags_len] = [ + 1 if item > 0 else 0 for item in labels[j] + ] + + # convert data to torch LongTensors + batch_data = torch.tensor(batch_data, dtype=torch.long) + batch_label_starts = torch.tensor(batch_label_starts, dtype=torch.long) + batch_labels = torch.tensor(batch_labels, dtype=torch.long) + batch_pmasks = torch.tensor(batch_pmasks, dtype=torch.long) + return [batch_data, batch_label_starts, batch_labels, batch_pmasks, ori_sents] + + +class BertPolyPredict: + def __init__(self, bert_model, jsonr_file, json_file): + self.tokenizer = BertTokenizer.from_pretrained(bert_model, do_lower_case=True) + with open(jsonr_file, "r", encoding="utf8") as fp: + self.pron_dict = json.load(fp) + with open(json_file, "r", encoding="utf8") as fp: + self.pron_dict_id_2_pinyin = json.load(fp) + self.num_polyphone = len(self.pron_dict) + self.device = "cpu" + self.polydataset = PolyDataset + options = SessionOptions() # initialize session options + options.graph_optimization_level = GraphOptimizationLevel.ORT_ENABLE_ALL + print(os.path.join(bert_model, "poly_bert_model.onnx")) + self.session = InferenceSession( + os.path.join(bert_model, "poly_bert_model.onnx"), + sess_options=options, + providers=[ + "CoreMLExecutionProvider", # Replace CUDA with CoreML + "CPUExecutionProvider", + ], # CPUExecutionProvider #CUDAExecutionProvider + ) + # self.session.set_providers(['CUDAExecutionProvider', "CPUExecutionProvider"], [ {'device_id': 0}]) + + # disable session.run() fallback mechanism, it prevents for a reset of the execution provider + self.session.disable_fallback() + + def predict_process(self, txt_list): + word_test, label_test, texts_test = self.get_examples_po(txt_list) + data = self.polydataset(word_test, label_test) + predict_loader = DataLoader( + data, batch_size=1, shuffle=False, collate_fn=data.collate_fn + ) + pred_tags = self.predict_onnx(predict_loader) + return pred_tags + + def predict_onnx(self, dev_loader): + pred_tags = [] + with torch.no_grad(): + for idx, batch_samples in enumerate(dev_loader): + # [batch_data, batch_label_starts, batch_labels, batch_pmasks, ori_sents] + batch_data, batch_label_starts, batch_labels, batch_pmasks, _ = ( + batch_samples + ) + # shift tensors to GPU if available + batch_data = batch_data.to(self.device) + batch_label_starts = batch_label_starts.to(self.device) + batch_labels = batch_labels.to(self.device) + batch_pmasks = batch_pmasks.to(self.device) + batch_data = np.asarray(batch_data, dtype=np.float32) + batch_pmasks = np.asarray(batch_pmasks, dtype=np.float32) + # batch_output = self.session.run(output_names=['outputs'], input_feed={"input_ids":batch_data, "input_pmasks": batch_pmasks})[0][0] + batch_output = self.session.run( + output_names=["outputs"], input_feed={"input_ids": batch_data} + )[0] + label_masks = batch_pmasks == 1 + batch_labels = batch_labels.to("cpu").numpy() + for i, indices in enumerate(np.argmax(batch_output, axis=2)): + for j, idx in enumerate(indices): + if label_masks[i][j]: + # pred_tag.append(idx) + pred_tags.append(self.pron_dict_id_2_pinyin[str(idx + 1)]) + return pred_tags + + def get_examples_po(self, text_list): + + word_list = [] + label_list = [] + sentence_list = [] + id = 0 + for line in [text_list]: + sentence = line[0] + words = [] + tokens = line[0] + index = line[-1] + front = index + back = len(tokens) - index - 1 + labels = [0] * front + [1] + [0] * back + words = ["[CLS]"] + [item for item in sentence] + words = self.tokenizer.convert_tokens_to_ids(words) + word_list.append(words) + label_list.append(labels) + sentence_list.append(sentence) + + id += 1 + # mask_list.append(masks) + assert len(labels) + 1 == len(words), print( + ( + poly, + sentence, + words, + labels, + sentence, + len(sentence), + len(words), + len(labels), + ) + ) + assert len(labels) + 1 == len( + words + ), "Number of labels does not match number of words" + assert len(labels) == len( + sentence + ), "Number of labels does not match number of sentences" + assert len(word_list) == len( + label_list + ), "Number of label sentences does not match number of word sentences" + return word_list, label_list, text_list diff --git a/diffrhythm/g2p/g2p/cleaners.py b/diffrhythm/g2p/g2p/cleaners.py new file mode 100644 index 0000000000000000000000000000000000000000..f9f6782eb01cef3a30fe0952ec262be6534d273a --- /dev/null +++ b/diffrhythm/g2p/g2p/cleaners.py @@ -0,0 +1,31 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import re +from diffrhythm.g2p.g2p.japanese import japanese_to_ipa +from diffrhythm.g2p.g2p.mandarin import chinese_to_ipa +from diffrhythm.g2p.g2p.english import english_to_ipa +from diffrhythm.g2p.g2p.french import french_to_ipa +from diffrhythm.g2p.g2p.korean import korean_to_ipa +from diffrhythm.g2p.g2p.german import german_to_ipa + + +def cjekfd_cleaners(text, sentence, language, text_tokenizers): + + if language == "zh": + return chinese_to_ipa(text, sentence, text_tokenizers["zh"]) + elif language == "ja": + return japanese_to_ipa(text, text_tokenizers["ja"]) + elif language == "en": + return english_to_ipa(text, text_tokenizers["en"]) + elif language == "fr": + return french_to_ipa(text, text_tokenizers["fr"]) + elif language == "ko": + return korean_to_ipa(text, text_tokenizers["ko"]) + elif language == "de": + return german_to_ipa(text, text_tokenizers["de"]) + else: + raise Exception("Unknown language: %s" % language) + return None diff --git a/diffrhythm/g2p/g2p/english.py b/diffrhythm/g2p/g2p/english.py new file mode 100644 index 0000000000000000000000000000000000000000..f8f349fd621ba3d6aa110f447238249642d80326 --- /dev/null +++ b/diffrhythm/g2p/g2p/english.py @@ -0,0 +1,202 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import re +from unidecode import unidecode +import inflect + +""" + Text clean time +""" +_inflect = inflect.engine() +_comma_number_re = re.compile(r"([0-9][0-9\,]+[0-9])") +_decimal_number_re = re.compile(r"([0-9]+\.[0-9]+)") +_percent_number_re = re.compile(r"([0-9\.\,]*[0-9]+%)") +_pounds_re = re.compile(r"£([0-9\,]*[0-9]+)") +_dollars_re = re.compile(r"\$([0-9\.\,]*[0-9]+)") +_fraction_re = re.compile(r"([0-9]+)/([0-9]+)") +_ordinal_re = re.compile(r"[0-9]+(st|nd|rd|th)") +_number_re = re.compile(r"[0-9]+") + +# List of (regular expression, replacement) pairs for abbreviations: +_abbreviations = [ + (re.compile("\\b%s\\b" % x[0], re.IGNORECASE), x[1]) + for x in [ + ("mrs", "misess"), + ("mr", "mister"), + ("dr", "doctor"), + ("st", "saint"), + ("co", "company"), + ("jr", "junior"), + ("maj", "major"), + ("gen", "general"), + ("drs", "doctors"), + ("rev", "reverend"), + ("lt", "lieutenant"), + ("hon", "honorable"), + ("sgt", "sergeant"), + ("capt", "captain"), + ("esq", "esquire"), + ("ltd", "limited"), + ("col", "colonel"), + ("ft", "fort"), + ("etc", "et cetera"), + ("btw", "by the way"), + ] +] + +_special_map = [ + ("t|ɹ", "tɹ"), + ("d|ɹ", "dɹ"), + ("t|s", "ts"), + ("d|z", "dz"), + ("ɪ|ɹ", "ɪɹ"), + ("ɐ", "ɚ"), + ("ᵻ", "ɪ"), + ("əl", "l"), + ("x", "k"), + ("ɬ", "l"), + ("ʔ", "t"), + ("n̩", "n"), + ("oː|ɹ", "oːɹ"), +] + + +def expand_abbreviations(text): + for regex, replacement in _abbreviations: + text = re.sub(regex, replacement, text) + return text + + +def _remove_commas(m): + return m.group(1).replace(",", "") + + +def _expand_decimal_point(m): + return m.group(1).replace(".", " point ") + + +def _expand_percent(m): + return m.group(1).replace("%", " percent ") + + +def _expand_dollars(m): + match = m.group(1) + parts = match.split(".") + if len(parts) > 2: + return " " + match + " dollars " # Unexpected format + dollars = int(parts[0]) if parts[0] else 0 + cents = int(parts[1]) if len(parts) > 1 and parts[1] else 0 + if dollars and cents: + dollar_unit = "dollar" if dollars == 1 else "dollars" + cent_unit = "cent" if cents == 1 else "cents" + return " %s %s, %s %s " % (dollars, dollar_unit, cents, cent_unit) + elif dollars: + dollar_unit = "dollar" if dollars == 1 else "dollars" + return " %s %s " % (dollars, dollar_unit) + elif cents: + cent_unit = "cent" if cents == 1 else "cents" + return " %s %s " % (cents, cent_unit) + else: + return " zero dollars " + + +def fraction_to_words(numerator, denominator): + if numerator == 1 and denominator == 2: + return " one half " + if numerator == 1 and denominator == 4: + return " one quarter " + if denominator == 2: + return " " + _inflect.number_to_words(numerator) + " halves " + if denominator == 4: + return " " + _inflect.number_to_words(numerator) + " quarters " + return ( + " " + + _inflect.number_to_words(numerator) + + " " + + _inflect.ordinal(_inflect.number_to_words(denominator)) + + " " + ) + + +def _expand_fraction(m): + numerator = int(m.group(1)) + denominator = int(m.group(2)) + return fraction_to_words(numerator, denominator) + + +def _expand_ordinal(m): + return " " + _inflect.number_to_words(m.group(0)) + " " + + +def _expand_number(m): + num = int(m.group(0)) + if num > 1000 and num < 3000: + if num == 2000: + return " two thousand " + elif num > 2000 and num < 2010: + return " two thousand " + _inflect.number_to_words(num % 100) + " " + elif num % 100 == 0: + return " " + _inflect.number_to_words(num // 100) + " hundred " + else: + return ( + " " + + _inflect.number_to_words(num, andword="", zero="oh", group=2).replace( + ", ", " " + ) + + " " + ) + else: + return " " + _inflect.number_to_words(num, andword="") + " " + + +# Normalize numbers pronunciation +def normalize_numbers(text): + text = re.sub(_comma_number_re, _remove_commas, text) + text = re.sub(_pounds_re, r"\1 pounds", text) + text = re.sub(_dollars_re, _expand_dollars, text) + text = re.sub(_fraction_re, _expand_fraction, text) + text = re.sub(_decimal_number_re, _expand_decimal_point, text) + text = re.sub(_percent_number_re, _expand_percent, text) + text = re.sub(_ordinal_re, _expand_ordinal, text) + text = re.sub(_number_re, _expand_number, text) + return text + + +def _english_to_ipa(text): + # text = unidecode(text).lower() + text = expand_abbreviations(text) + text = normalize_numbers(text) + return text + + +# special map +def special_map(text): + for regex, replacement in _special_map: + regex = regex.replace("|", "\|") + while re.search(r"(^|[_|]){}([_|]|$)".format(regex), text): + text = re.sub( + r"(^|[_|]){}([_|]|$)".format(regex), r"\1{}\2".format(replacement), text + ) + # text = re.sub(r'([,.!?])', r'|\1', text) + return text + + +# Add some special operation +def english_to_ipa(text, text_tokenizer): + if type(text) == str: + text = _english_to_ipa(text) + else: + text = [_english_to_ipa(t) for t in text] + phonemes = text_tokenizer(text) + if phonemes[-1] in "p⁼ʰmftnlkxʃs`ɹaoəɛɪeɑʊŋiuɥwæjː": + phonemes += "|_" + if type(text) == str: + return special_map(phonemes) + else: + result_ph = [] + for phone in phonemes: + result_ph.append(special_map(phone)) + return result_ph diff --git a/diffrhythm/g2p/g2p/french.py b/diffrhythm/g2p/g2p/french.py new file mode 100644 index 0000000000000000000000000000000000000000..bd9400cdfc6598e7d642480cbfc1f990fc78cddf --- /dev/null +++ b/diffrhythm/g2p/g2p/french.py @@ -0,0 +1,149 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import re + +""" + Text clean time +""" +# List of (regular expression, replacement) pairs for abbreviations in french: +_abbreviations = [ + (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) + for x in [ + ("M", "monsieur"), + ("Mlle", "mademoiselle"), + ("Mlles", "mesdemoiselles"), + ("Mme", "Madame"), + ("Mmes", "Mesdames"), + ("N.B", "nota bene"), + ("M", "monsieur"), + ("p.c.q", "parce que"), + ("Pr", "professeur"), + ("qqch", "quelque chose"), + ("rdv", "rendez-vous"), + ("max", "maximum"), + ("min", "minimum"), + ("no", "numéro"), + ("adr", "adresse"), + ("dr", "docteur"), + ("st", "saint"), + ("co", "companie"), + ("jr", "junior"), + ("sgt", "sergent"), + ("capt", "capitain"), + ("col", "colonel"), + ("av", "avenue"), + ("av. J.-C", "avant Jésus-Christ"), + ("apr. J.-C", "après Jésus-Christ"), + ("art", "article"), + ("boul", "boulevard"), + ("c.-à-d", "c’est-à-dire"), + ("etc", "et cetera"), + ("ex", "exemple"), + ("excl", "exclusivement"), + ("boul", "boulevard"), + ] +] + [ + (re.compile("\\b%s" % x[0]), x[1]) + for x in [ + ("Mlle", "mademoiselle"), + ("Mlles", "mesdemoiselles"), + ("Mme", "Madame"), + ("Mmes", "Mesdames"), + ] +] + +rep_map = { + ":": ",", + ";": ",", + ",": ",", + "。": ".", + "!": "!", + "?": "?", + "\n": ".", + "·": ",", + "、": ",", + "...": ".", + "…": ".", + "$": ".", + "“": "", + "”": "", + "‘": "", + "’": "", + "(": "", + ")": "", + "(": "", + ")": "", + "《": "", + "》": "", + "【": "", + "】": "", + "[": "", + "]": "", + "—": "", + "~": "-", + "~": "-", + "「": "", + "」": "", + "¿": "", + "¡": "", +} + + +def collapse_whitespace(text): + # Regular expression matching whitespace: + _whitespace_re = re.compile(r"\s+") + return re.sub(_whitespace_re, " ", text).strip() + + +def remove_punctuation_at_begin(text): + return re.sub(r"^[,.!?]+", "", text) + + +def remove_aux_symbols(text): + text = re.sub(r"[\<\>\(\)\[\]\"\«\»]+", "", text) + return text + + +def replace_symbols(text): + text = text.replace(";", ",") + text = text.replace("-", " ") + text = text.replace(":", ",") + text = text.replace("&", " et ") + return text + + +def expand_abbreviations(text): + for regex, replacement in _abbreviations: + text = re.sub(regex, replacement, text) + return text + + +def replace_punctuation(text): + pattern = re.compile("|".join(re.escape(p) for p in rep_map.keys())) + replaced_text = pattern.sub(lambda x: rep_map[x.group()], text) + return replaced_text + + +def text_normalize(text): + text = expand_abbreviations(text) + text = replace_punctuation(text) + text = replace_symbols(text) + text = remove_aux_symbols(text) + text = remove_punctuation_at_begin(text) + text = collapse_whitespace(text) + text = re.sub(r"([^\.,!\?\-…])$", r"\1", text) + return text + + +def french_to_ipa(text, text_tokenizer): + if type(text) == str: + text = text_normalize(text) + phonemes = text_tokenizer(text) + return phonemes + else: + for i, t in enumerate(text): + text[i] = text_normalize(t) + return text_tokenizer(text) diff --git a/diffrhythm/g2p/g2p/german.py b/diffrhythm/g2p/g2p/german.py new file mode 100644 index 0000000000000000000000000000000000000000..bd82eeabc44cc891acd98daa982cd2be1e991e3a --- /dev/null +++ b/diffrhythm/g2p/g2p/german.py @@ -0,0 +1,94 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import re + +""" + Text clean time +""" +rep_map = { + ":": ",", + ";": ",", + ",": ",", + "。": ".", + "!": "!", + "?": "?", + "\n": ".", + "·": ",", + "、": ",", + "...": ".", + "…": ".", + "$": ".", + "“": "", + "”": "", + "‘": "", + "’": "", + "(": "", + ")": "", + "(": "", + ")": "", + "《": "", + "》": "", + "【": "", + "】": "", + "[": "", + "]": "", + "—": "", + "~": "-", + "~": "-", + "「": "", + "」": "", + "¿": "", + "¡": "", +} + + +def collapse_whitespace(text): + # Regular expression matching whitespace: + _whitespace_re = re.compile(r"\s+") + return re.sub(_whitespace_re, " ", text).strip() + + +def remove_punctuation_at_begin(text): + return re.sub(r"^[,.!?]+", "", text) + + +def remove_aux_symbols(text): + text = re.sub(r"[\<\>\(\)\[\]\"\«\»]+", "", text) + return text + + +def replace_symbols(text): + text = text.replace(";", ",") + text = text.replace("-", " ") + text = text.replace(":", ",") + return text + + +def replace_punctuation(text): + pattern = re.compile("|".join(re.escape(p) for p in rep_map.keys())) + replaced_text = pattern.sub(lambda x: rep_map[x.group()], text) + return replaced_text + + +def text_normalize(text): + text = replace_punctuation(text) + text = replace_symbols(text) + text = remove_aux_symbols(text) + text = remove_punctuation_at_begin(text) + text = collapse_whitespace(text) + text = re.sub(r"([^\.,!\?\-…])$", r"\1", text) + return text + + +def german_to_ipa(text, text_tokenizer): + if type(text) == str: + text = text_normalize(text) + phonemes = text_tokenizer(text) + return phonemes + else: + for i, t in enumerate(text): + text[i] = text_normalize(t) + return text_tokenizer(text) diff --git a/diffrhythm/g2p/g2p/japanese.py b/diffrhythm/g2p/g2p/japanese.py new file mode 100644 index 0000000000000000000000000000000000000000..f01fec575214bb939834924e165f9df748a6a89a --- /dev/null +++ b/diffrhythm/g2p/g2p/japanese.py @@ -0,0 +1,816 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import io, re, os, sys, time, argparse, pdb, json +from io import StringIO +from typing import Optional +import numpy as np +import traceback +import pyopenjtalk +from pykakasi import kakasi + +punctuation = [",", ".", "!", "?", ":", ";", "'", "…"] + +jp_xphone2ipa = [ + " a a", + " i i", + " u ɯ", + " e e", + " o o", + " a: aː", + " i: iː", + " u: ɯː", + " e: eː", + " o: oː", + " k k", + " s s", + " t t", + " n n", + " h ç", + " f ɸ", + " m m", + " y j", + " r ɾ", + " w ɰᵝ", + " N ɴ", + " g g", + " j d ʑ", + " z z", + " d d", + " b b", + " p p", + " q q", + " v v", + " : :", + " by b j", + " ch t ɕ", + " dy d e j", + " ty t e j", + " gy g j", + " gw g ɯ", + " hy ç j", + " ky k j", + " kw k ɯ", + " my m j", + " ny n j", + " py p j", + " ry ɾ j", + " sh ɕ", + " ts t s ɯ", +] + +_mora_list_minimum: list[tuple[str, Optional[str], str]] = [ + ("ヴォ", "v", "o"), + ("ヴェ", "v", "e"), + ("ヴィ", "v", "i"), + ("ヴァ", "v", "a"), + ("ヴ", "v", "u"), + ("ン", None, "N"), + ("ワ", "w", "a"), + ("ロ", "r", "o"), + ("レ", "r", "e"), + ("ル", "r", "u"), + ("リョ", "ry", "o"), + ("リュ", "ry", "u"), + ("リャ", "ry", "a"), + ("リェ", "ry", "e"), + ("リ", "r", "i"), + ("ラ", "r", "a"), + ("ヨ", "y", "o"), + ("ユ", "y", "u"), + ("ヤ", "y", "a"), + ("モ", "m", "o"), + ("メ", "m", "e"), + ("ム", "m", "u"), + ("ミョ", "my", "o"), + ("ミュ", "my", "u"), + ("ミャ", "my", "a"), + ("ミェ", "my", "e"), + ("ミ", "m", "i"), + ("マ", "m", "a"), + ("ポ", "p", "o"), + ("ボ", "b", "o"), + ("ホ", "h", "o"), + ("ペ", "p", "e"), + ("ベ", "b", "e"), + ("ヘ", "h", "e"), + ("プ", "p", "u"), + ("ブ", "b", "u"), + ("フォ", "f", "o"), + ("フェ", "f", "e"), + ("フィ", "f", "i"), + ("ファ", "f", "a"), + ("フ", "f", "u"), + ("ピョ", "py", "o"), + ("ピュ", "py", "u"), + ("ピャ", "py", "a"), + ("ピェ", "py", "e"), + ("ピ", "p", "i"), + ("ビョ", "by", "o"), + ("ビュ", "by", "u"), + ("ビャ", "by", "a"), + ("ビェ", "by", "e"), + ("ビ", "b", "i"), + ("ヒョ", "hy", "o"), + ("ヒュ", "hy", "u"), + ("ヒャ", "hy", "a"), + ("ヒェ", "hy", "e"), + ("ヒ", "h", "i"), + ("パ", "p", "a"), + ("バ", "b", "a"), + ("ハ", "h", "a"), + ("ノ", "n", "o"), + ("ネ", "n", "e"), + ("ヌ", "n", "u"), + ("ニョ", "ny", "o"), + ("ニュ", "ny", "u"), + ("ニャ", "ny", "a"), + ("ニェ", "ny", "e"), + ("ニ", "n", "i"), + ("ナ", "n", "a"), + ("ドゥ", "d", "u"), + ("ド", "d", "o"), + ("トゥ", "t", "u"), + ("ト", "t", "o"), + ("デョ", "dy", "o"), + ("デュ", "dy", "u"), + ("デャ", "dy", "a"), + # ("デェ", "dy", "e"), + ("ディ", "d", "i"), + ("デ", "d", "e"), + ("テョ", "ty", "o"), + ("テュ", "ty", "u"), + ("テャ", "ty", "a"), + ("ティ", "t", "i"), + ("テ", "t", "e"), + ("ツォ", "ts", "o"), + ("ツェ", "ts", "e"), + ("ツィ", "ts", "i"), + ("ツァ", "ts", "a"), + ("ツ", "ts", "u"), + ("ッ", None, "q"), # 「cl」から「q」に変更 + ("チョ", "ch", "o"), + ("チュ", "ch", "u"), + ("チャ", "ch", "a"), + ("チェ", "ch", "e"), + ("チ", "ch", "i"), + ("ダ", "d", "a"), + ("タ", "t", "a"), + ("ゾ", "z", "o"), + ("ソ", "s", "o"), + ("ゼ", "z", "e"), + ("セ", "s", "e"), + ("ズィ", "z", "i"), + ("ズ", "z", "u"), + ("スィ", "s", "i"), + ("ス", "s", "u"), + ("ジョ", "j", "o"), + ("ジュ", "j", "u"), + ("ジャ", "j", "a"), + ("ジェ", "j", "e"), + ("ジ", "j", "i"), + ("ショ", "sh", "o"), + ("シュ", "sh", "u"), + ("シャ", "sh", "a"), + ("シェ", "sh", "e"), + ("シ", "sh", "i"), + ("ザ", "z", "a"), + ("サ", "s", "a"), + ("ゴ", "g", "o"), + ("コ", "k", "o"), + ("ゲ", "g", "e"), + ("ケ", "k", "e"), + ("グヮ", "gw", "a"), + ("グ", "g", "u"), + ("クヮ", "kw", "a"), + ("ク", "k", "u"), + ("ギョ", "gy", "o"), + ("ギュ", "gy", "u"), + ("ギャ", "gy", "a"), + ("ギェ", "gy", "e"), + ("ギ", "g", "i"), + ("キョ", "ky", "o"), + ("キュ", "ky", "u"), + ("キャ", "ky", "a"), + ("キェ", "ky", "e"), + ("キ", "k", "i"), + ("ガ", "g", "a"), + ("カ", "k", "a"), + ("オ", None, "o"), + ("エ", None, "e"), + ("ウォ", "w", "o"), + ("ウェ", "w", "e"), + ("ウィ", "w", "i"), + ("ウ", None, "u"), + ("イェ", "y", "e"), + ("イ", None, "i"), + ("ア", None, "a"), +] + +_mora_list_additional: list[tuple[str, Optional[str], str]] = [ + ("ヴョ", "by", "o"), + ("ヴュ", "by", "u"), + ("ヴャ", "by", "a"), + ("ヲ", None, "o"), + ("ヱ", None, "e"), + ("ヰ", None, "i"), + ("ヮ", "w", "a"), + ("ョ", "y", "o"), + ("ュ", "y", "u"), + ("ヅ", "z", "u"), + ("ヂ", "j", "i"), + ("ヶ", "k", "e"), + ("ャ", "y", "a"), + ("ォ", None, "o"), + ("ェ", None, "e"), + ("ゥ", None, "u"), + ("ィ", None, "i"), + ("ァ", None, "a"), +] + +# 例: "vo" -> "ヴォ", "a" -> "ア" +mora_phonemes_to_mora_kata: dict[str, str] = { + (consonant or "") + vowel: kana for [kana, consonant, vowel] in _mora_list_minimum +} + +# 例: "ヴォ" -> ("v", "o"), "ア" -> (None, "a") +mora_kata_to_mora_phonemes: dict[str, tuple[Optional[str], str]] = { + kana: (consonant, vowel) + for [kana, consonant, vowel] in _mora_list_minimum + _mora_list_additional +} + + +# 正規化で記号を変換するための辞書 +rep_map = { + ":": ":", + ";": ";", + ",": ",", + "。": ".", + "!": "!", + "?": "?", + "\n": ".", + ".": ".", + "⋯": "…", + "···": "…", + "・・・": "…", + "·": ",", + "・": ",", + "•": ",", + "、": ",", + "$": ".", + # "“": "'", + # "”": "'", + # '"': "'", + "‘": "'", + "’": "'", + # "(": "'", + # ")": "'", + # "(": "'", + # ")": "'", + # "《": "'", + # "》": "'", + # "【": "'", + # "】": "'", + # "[": "'", + # "]": "'", + # "——": "-", + # "−": "-", + # "-": "-", + # "『": "'", + # "』": "'", + # "〈": "'", + # "〉": "'", + # "«": "'", + # "»": "'", + # # "~": "-", # これは長音記号「ー」として扱うよう変更 + # # "~": "-", # これは長音記号「ー」として扱うよう変更 + # "「": "'", + # "」": "'", +} + + +def _numeric_feature_by_regex(regex, s): + match = re.search(regex, s) + if match is None: + return -50 + return int(match.group(1)) + + +def replace_punctuation(text: str) -> str: + """句読点等を「.」「,」「!」「?」「'」「-」に正規化し、OpenJTalkで読みが取得できるもののみ残す: + 漢字・平仮名・カタカナ、アルファベット、ギリシャ文字 + """ + pattern = re.compile("|".join(re.escape(p) for p in rep_map.keys())) + # print("before: ", text) + # 句読点を辞書で置換 + replaced_text = pattern.sub(lambda x: rep_map[x.group()], text) + + replaced_text = re.sub( + # ↓ ひらがな、カタカナ、漢字 + r"[^\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF\u3400-\u4DBF\u3005" + # ↓ 半角アルファベット(大文字と小文字) + + r"\u0041-\u005A\u0061-\u007A" + # ↓ 全角アルファベット(大文字と小文字) + + r"\uFF21-\uFF3A\uFF41-\uFF5A" + # ↓ ギリシャ文字 + + r"\u0370-\u03FF\u1F00-\u1FFF" + # ↓ "!", "?", "…", ",", ".", "'", "-", 但し`…`はすでに`...`に変換されている + + "".join(punctuation) + r"]+", + # 上述以外の文字を削除 + "", + replaced_text, + ) + # print("after: ", replaced_text) + return replaced_text + + +def fix_phone_tone(phone_tone_list: list[tuple[str, int]]) -> list[tuple[str, int]]: + """ + `phone_tone_list`のtone(アクセントの値)を0か1の範囲に修正する。 + 例: [(a, 0), (i, -1), (u, -1)] → [(a, 1), (i, 0), (u, 0)] + """ + tone_values = set(tone for _, tone in phone_tone_list) + if len(tone_values) == 1: + assert tone_values == {0}, tone_values + return phone_tone_list + elif len(tone_values) == 2: + if tone_values == {0, 1}: + return phone_tone_list + elif tone_values == {-1, 0}: + return [ + (letter, 0 if tone == -1 else 1) for letter, tone in phone_tone_list + ] + else: + raise ValueError(f"Unexpected tone values: {tone_values}") + else: + raise ValueError(f"Unexpected tone values: {tone_values}") + + +def fix_phone_tone_wplen(phone_tone_list, word_phone_length_list): + phones = [] + tones = [] + w_p_len = [] + p_len = len(phone_tone_list) + idx = 0 + w_idx = 0 + while idx < p_len: + offset = 0 + if phone_tone_list[idx] == "▁": + w_p_len.append(w_idx + 1) + + curr_w_p_len = word_phone_length_list[w_idx] + for i in range(curr_w_p_len): + p, t = phone_tone_list[idx] + if p == ":" and len(phones) > 0: + if phones[-1][-1] != ":": + phones[-1] += ":" + offset -= 1 + else: + phones.append(p) + tones.append(str(t)) + idx += 1 + if idx >= p_len: + break + w_p_len.append(curr_w_p_len + offset) + w_idx += 1 + # print(w_p_len) + return phones, tones, w_p_len + + +def g2phone_tone_wo_punct(prosodies) -> list[tuple[str, int]]: + """ + テキストに対して、音素とアクセント(0か1)のペアのリストを返す。 + ただし「!」「.」「?」等の非音素記号(punctuation)は全て消える(ポーズ記号も残さない)。 + 非音素記号を含める処理は`align_tones()`で行われる。 + また「っ」は「cl」でなく「q」に変換される(「ん」は「N」のまま)。 + 例: "こんにちは、世界ー。。元気?!" → + [('k', 0), ('o', 0), ('N', 1), ('n', 1), ('i', 1), ('ch', 1), ('i', 1), ('w', 1), ('a', 1), ('s', 1), ('e', 1), ('k', 0), ('a', 0), ('i', 0), ('i', 0), ('g', 1), ('e', 1), ('N', 0), ('k', 0), ('i', 0)] + """ + result: list[tuple[str, int]] = [] + current_phrase: list[tuple[str, int]] = [] + current_tone = 0 + last_accent = "" + for i, letter in enumerate(prosodies): + # 特殊記号の処理 + + # 文頭記号、無視する + if letter == "^": + assert i == 0, "Unexpected ^" + # アクセント句の終わりに来る記号 + elif letter in ("$", "?", "_", "#"): + # 保持しているフレーズを、アクセント数値を0-1に修正し結果に追加 + result.extend(fix_phone_tone(current_phrase)) + # 末尾に来る終了記号、無視(文中の疑問文は`_`になる) + if letter in ("$", "?"): + assert i == len(prosodies) - 1, f"Unexpected {letter}" + # あとは"_"(ポーズ)と"#"(アクセント句の境界)のみ + # これらは残さず、次のアクセント句に備える。 + + current_phrase = [] + # 0を基準点にしてそこから上昇・下降する(負の場合は上の`fix_phone_tone`で直る) + current_tone = 0 + last_accent = "" + # アクセント上昇記号 + elif letter == "[": + if last_accent != letter: + current_tone = current_tone + 1 + last_accent = letter + # アクセント下降記号 + elif letter == "]": + if last_accent != letter: + current_tone = current_tone - 1 + last_accent = letter + # それ以外は通常の音素 + else: + if letter == "cl": # 「っ」の処理 + letter = "q" + current_phrase.append((letter, current_tone)) + return result + + +def handle_long(sep_phonemes: list[list[str]]) -> list[list[str]]: + for i in range(len(sep_phonemes)): + if sep_phonemes[i][0] == "ー": + # sep_phonemes[i][0] = sep_phonemes[i - 1][-1] + sep_phonemes[i][0] = ":" + if "ー" in sep_phonemes[i]: + for j in range(len(sep_phonemes[i])): + if sep_phonemes[i][j] == "ー": + # sep_phonemes[i][j] = sep_phonemes[i][j - 1][-1] + sep_phonemes[i][j] = ":" + return sep_phonemes + + +def handle_long_word(sep_phonemes: list[list[str]]) -> list[list[str]]: + res = [] + for i in range(len(sep_phonemes)): + if sep_phonemes[i][0] == "ー": + sep_phonemes[i][0] = sep_phonemes[i - 1][-1] + # sep_phonemes[i][0] = ':' + if "ー" in sep_phonemes[i]: + for j in range(len(sep_phonemes[i])): + if sep_phonemes[i][j] == "ー": + sep_phonemes[i][j] = sep_phonemes[i][j - 1][-1] + # sep_phonemes[i][j] = ':' + res.append(sep_phonemes[i]) + res.append("▁") + return res + + +def align_tones( + phones_with_punct: list[str], phone_tone_list: list[tuple[str, int]] +) -> list[tuple[str, int]]: + """ + 例: + …私は、、そう思う。 + phones_with_punct: + [".", ".", ".", "w", "a", "t", "a", "sh", "i", "w", "a", ",", ",", "s", "o", "o", "o", "m", "o", "u", "."] + phone_tone_list: + [("w", 0), ("a", 0), ("t", 1), ("a", 1), ("sh", 1), ("i", 1), ("w", 1), ("a", 1), ("s", 0), ("o", 0), ("o", 1), ("o", 1), ("m", 1), ("o", 1), ("u", 0))] + Return: + [(".", 0), (".", 0), (".", 0), ("w", 0), ("a", 0), ("t", 1), ("a", 1), ("sh", 1), ("i", 1), ("w", 1), ("a", 1), (",", 0), (",", 0), ("s", 0), ("o", 0), ("o", 1), ("o", 1), ("m", 1), ("o", 1), ("u", 0), (".", 0)] + """ + result: list[tuple[str, int]] = [] + tone_index = 0 + for phone in phones_with_punct: + if tone_index >= len(phone_tone_list): + # 余ったpunctuationがある場合 → (punctuation, 0)を追加 + result.append((phone, 0)) + elif phone == phone_tone_list[tone_index][0]: + # phone_tone_listの現在の音素と一致する場合 → toneをそこから取得、(phone, tone)を追加 + result.append((phone, phone_tone_list[tone_index][1])) + # 探すindexを1つ進める + tone_index += 1 + elif phone in punctuation or phone == "▁": + # phoneがpunctuationの場合 → (phone, 0)を追加 + result.append((phone, 0)) + else: + print(f"phones: {phones_with_punct}") + print(f"phone_tone_list: {phone_tone_list}") + print(f"result: {result}") + print(f"tone_index: {tone_index}") + print(f"phone: {phone}") + raise ValueError(f"Unexpected phone: {phone}") + return result + + +def kata2phoneme_list(text: str) -> list[str]: + """ + 原則カタカナの`text`を受け取り、それをそのままいじらずに音素記号のリストに変換。 + 注意点: + - punctuationが来た場合(punctuationが1文字の場合がありうる)、処理せず1文字のリストを返す + - 冒頭に続く「ー」はそのまま「ー」のままにする(`handle_long()`で処理される) + - 文中の「ー」は前の音素記号の最後の音素記号に変換される。 + 例: + `ーーソーナノカーー` → ["ー", "ー", "s", "o", "o", "n", "a", "n", "o", "k", "a", "a", "a"] + `?` → ["?"] + """ + if text in punctuation: + return [text] + # `text`がカタカナ(`ー`含む)のみからなるかどうかをチェック + if re.fullmatch(r"[\u30A0-\u30FF]+", text) is None: + raise ValueError(f"Input must be katakana only: {text}") + sorted_keys = sorted(mora_kata_to_mora_phonemes.keys(), key=len, reverse=True) + pattern = "|".join(map(re.escape, sorted_keys)) + + def mora2phonemes(mora: str) -> str: + cosonant, vowel = mora_kata_to_mora_phonemes[mora] + if cosonant is None: + return f" {vowel}" + return f" {cosonant} {vowel}" + + spaced_phonemes = re.sub(pattern, lambda m: mora2phonemes(m.group()), text) + + # 長音記号「ー」の処理 + long_pattern = r"(\w)(ー*)" + long_replacement = lambda m: m.group(1) + (" " + m.group(1)) * len(m.group(2)) + spaced_phonemes = re.sub(long_pattern, long_replacement, spaced_phonemes) + # spaced_phonemes += ' ▁' + return spaced_phonemes.strip().split(" ") + + +def frontend2phoneme(labels, drop_unvoiced_vowels=False): + N = len(labels) + + phones = [] + for n in range(N): + lab_curr = labels[n] + # print(lab_curr) + # current phoneme + p3 = re.search(r"\-(.*?)\+", lab_curr).group(1) + + # deal unvoiced vowels as normal vowels + if drop_unvoiced_vowels and p3 in "AEIOU": + p3 = p3.lower() + + # deal with sil at the beginning and the end of text + if p3 == "sil": + # assert n == 0 or n == N - 1 + # if n == 0: + # phones.append("^") + # elif n == N - 1: + # # check question form or not + # e3 = _numeric_feature_by_regex(r"!(\d+)_", lab_curr) + # if e3 == 0: + # phones.append("$") + # elif e3 == 1: + # phones.append("?") + continue + elif p3 == "pau": + phones.append("_") + continue + else: + phones.append(p3) + + # accent type and position info (forward or backward) + a1 = _numeric_feature_by_regex(r"/A:([0-9\-]+)\+", lab_curr) + a2 = _numeric_feature_by_regex(r"\+(\d+)\+", lab_curr) + a3 = _numeric_feature_by_regex(r"\+(\d+)/", lab_curr) + + # number of mora in accent phrase + f1 = _numeric_feature_by_regex(r"/F:(\d+)_", lab_curr) + + a2_next = _numeric_feature_by_regex(r"\+(\d+)\+", labels[n + 1]) + # accent phrase border + # print(p3, a1, a2, a3, f1, a2_next, lab_curr) + if a3 == 1 and a2_next == 1 and p3 in "aeiouAEIOUNcl": + phones.append("#") + # pitch falling + elif a1 == 0 and a2_next == a2 + 1 and a2 != f1: + phones.append("]") + # pitch rising + elif a2 == 1 and a2_next == 2: + phones.append("[") + + # phones = ' '.join(phones) + return phones + + +class JapanesePhoneConverter(object): + def __init__(self, lexicon_path=None, ipa_dict_path=None): + # lexicon_lines = open(lexicon_path, 'r', encoding='utf-8').readlines() + # self.lexicon = {} + # self.single_dict = {} + # self.double_dict = {} + # for curr_line in lexicon_lines: + # k,v = curr_line.strip().split('+',1) + # self.lexicon[k] = v + # if len(k) == 2: + # self.double_dict[k] = v + # elif len(k) == 1: + # self.single_dict[k] = v + self.ipa_dict = {} + for curr_line in jp_xphone2ipa: + k, v = curr_line.strip().split(" ", 1) + self.ipa_dict[k] = re.sub("\s", "", v) + # kakasi1 = kakasi() + # kakasi1.setMode("H","K") + # kakasi1.setMode("J","K") + # kakasi1.setMode("r","Hepburn") + self.japan_JH2K = kakasi() + self.table = {ord(f): ord(t) for f, t in zip("67", "_¯")} + + def text2sep_kata(self, parsed) -> tuple[list[str], list[str]]: + """ + `text_normalize`で正規化済みの`norm_text`を受け取り、それを単語分割し、 + 分割された単語リストとその読み(カタカナor記号1文字)のリストのタプルを返す。 + 単語分割結果は、`g2p()`の`word2ph`で1文字あたりに割り振る音素記号の数を決めるために使う。 + 例: + `私はそう思う!って感じ?` → + ["私", "は", "そう", "思う", "!", "って", "感じ", "?"], ["ワタシ", "ワ", "ソー", "オモウ", "!", "ッテ", "カンジ", "?"] + """ + # parsed: OpenJTalkの解析結果 + sep_text: list[str] = [] + sep_kata: list[str] = [] + fix_parsed = [] + i = 0 + while i <= len(parsed) - 1: + # word: 実際の単語の文字列 + # yomi: その読み、但し無声化サインの`’`は除去 + # print(parsed) + yomi = parsed[i]["pron"] + tmp_parsed = parsed[i] + if i != len(parsed) - 1 and parsed[i + 1]["string"] in [ + "々", + "ゝ", + "ヽ", + "ゞ", + "ヾ", + "゛", + ]: + word = parsed[i]["string"] + parsed[i + 1]["string"] + i += 1 + else: + word = parsed[i]["string"] + word, yomi = replace_punctuation(word), yomi.replace("’", "") + """ + ここで`yomi`の取りうる値は以下の通りのはず。 + - `word`が通常単語 → 通常の読み(カタカナ) + (カタカナからなり、長音記号も含みうる、`アー` 等) + - `word`が`ー` から始まる → `ーラー` や `ーーー` など + - `word`が句読点や空白等 → `、` + - `word`が`?` → `?`(全角になる) + 他にも`word`が読めないキリル文字アラビア文字等が来ると`、`になるが、正規化でこの場合は起きないはず。 + また元のコードでは`yomi`が空白の場合の処理があったが、これは起きないはず。 + 処理すべきは`yomi`が`、`の場合のみのはず。 + """ + assert yomi != "", f"Empty yomi: {word}" + if yomi == "、": + # wordは正規化されているので、`.`, `,`, `!`, `'`, `-`のいずれか + if word not in ( + ".", + ",", + "!", + "'", + "-", + "?", + ":", + ";", + "…", + "", + ): + # ここはpyopenjtalkが読めない文字等のときに起こる + #print( + # "{}Cannot read:{}, yomi:{}, new_word:{};".format( + # parsed, word, yomi, self.japan_JH2K.convert(word)[0]["kana"] + # ) + #) + # raise ValueError(word) + word = self.japan_JH2K.convert(word)[0]["kana"] + # print(word, self.japan_JH2K.convert(word)[0]['kana'], kata2phoneme_list(self.japan_JH2K.convert(word)[0]['kana'])) + tmp_parsed["pron"] = word + # yomi = "-" + # word = ',' + # yomiは元の記号のままに変更 + # else: + # parsed[i]['pron'] = parsed[i]["string"] + yomi = word + elif yomi == "?": + assert word == "?", f"yomi `?` comes from: {word}" + yomi = "?" + if word == "": + i += 1 + continue + sep_text.append(word) + sep_kata.append(yomi) + # print(word, yomi, parts) + fix_parsed.append(tmp_parsed) + i += 1 + # print(sep_text, sep_kata) + return sep_text, sep_kata, fix_parsed + + def getSentencePhone(self, sentence, blank_mode=True, phoneme_mode=False): + # print("origin:", sentence) + words = [] + words_phone_len = [] + short_char_flag = False + output_duration_flag = [] + output_before_sil_flag = [] + normed_text = [] + sentence = sentence.strip().strip("'") + sentence = re.sub(r"\s+", "", sentence) + output_res = [] + failed_words = [] + last_long_pause = 4 + last_word = None + frontend_text = pyopenjtalk.run_frontend(sentence) + # print("frontend_text: ", frontend_text) + try: + frontend_text = pyopenjtalk.estimate_accent(frontend_text) + except: + pass + # print("estimate_accent: ", frontend_text) + # sep_text: 単語単位の単語のリスト + # sep_kata: 単語単位の単語のカタカナ読みのリスト + sep_text, sep_kata, frontend_text = self.text2sep_kata(frontend_text) + # print("sep_text: ", sep_text) + # print("sep_kata: ", sep_kata) + # print("frontend_text: ", frontend_text) + # sep_phonemes: 各単語ごとの音素のリストのリスト + sep_phonemes = handle_long_word([kata2phoneme_list(i) for i in sep_kata]) + # print("sep_phonemes: ", sep_phonemes) + + pron_text = [x["pron"].strip().replace("’", "") for x in frontend_text] + # pdb.set_trace() + prosodys = pyopenjtalk.make_label(frontend_text) + prosodys = frontend2phoneme(prosodys, drop_unvoiced_vowels=True) + # print("prosodys: ", ' '.join(prosodys)) + # print("pron_text: ", pron_text) + normed_text = [x["string"].strip() for x in frontend_text] + # punctuationがすべて消えた、音素とアクセントのタプルのリスト + phone_tone_list_wo_punct = g2phone_tone_wo_punct(prosodys) + # print("phone_tone_list_wo_punct: ", phone_tone_list_wo_punct) + + # phone_w_punct: sep_phonemesを結合した、punctuationを元のまま保持した音素列 + phone_w_punct: list[str] = [] + w_p_len = [] + for i in sep_phonemes: + phone_w_punct += i + w_p_len.append(len(i)) + phone_w_punct = phone_w_punct[:-1] + # punctuation無しのアクセント情報を使って、punctuationを含めたアクセント情報を作る + # print("phone_w_punct: ", phone_w_punct) + # print("phone_tone_list_wo_punct: ", phone_tone_list_wo_punct) + phone_tone_list = align_tones(phone_w_punct, phone_tone_list_wo_punct) + + jp_item = {} + jp_p = "" + jp_t = "" + # mye rye pye bye nye + # je she + # print(phone_tone_list) + for p, t in phone_tone_list: + if p in self.ipa_dict: + curr_p = self.ipa_dict[p] + jp_p += curr_p + jp_t += str(t + 6) * len(curr_p) + elif p in punctuation: + jp_p += p + jp_t += "0" + elif p == "▁": + jp_p += p + jp_t += " " + else: + print(p, t) + jp_p += "|" + jp_t += "0" + # return phones, tones, w_p_len + jp_p = jp_p.replace("▁", " ") + jp_t = jp_t.translate(self.table) + jp_l = "" + for t in jp_t: + if t == " ": + jp_l += " " + else: + jp_l += "2" + # print(jp_p) + # print(jp_t) + # print(jp_l) + # print(len(jp_p_len), sum(w_p_len), len(jp_p), sum(jp_p_len)) + assert len(jp_p) == len(jp_t) and len(jp_p) == len(jp_l) + + jp_item["jp_p"] = jp_p.replace("| |", "|").rstrip("|") + jp_item["jp_t"] = jp_t + jp_item["jp_l"] = jp_l + jp_item["jp_normed_text"] = " ".join(normed_text) + jp_item["jp_pron_text"] = " ".join(pron_text) + # jp_item['jp_ruoma'] = sep_phonemes + # print(len(normed_text), len(sep_phonemes)) + # print(normed_text) + return jp_item + + +jpc = JapanesePhoneConverter() + + +def japanese_to_ipa(text, text_tokenizer): + # phonemes = text_tokenizer(text) + if type(text) == str: + return jpc.getSentencePhone(text)["jp_p"] + else: + result_ph = [] + for t in text: + result_ph.append(jpc.getSentencePhone(t)["jp_p"]) + return result_ph diff --git a/diffrhythm/g2p/g2p/korean.py b/diffrhythm/g2p/g2p/korean.py new file mode 100644 index 0000000000000000000000000000000000000000..c7c540b47d98ccf6e0db5f938e52834abf679b59 --- /dev/null +++ b/diffrhythm/g2p/g2p/korean.py @@ -0,0 +1,81 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import re + +""" + Text clean time +""" +english_dictionary = { + "KOREA": "코리아", + "IDOL": "아이돌", + "IT": "아이티", + "IQ": "아이큐", + "UP": "업", + "DOWN": "다운", + "PC": "피씨", + "CCTV": "씨씨티비", + "SNS": "에스엔에스", + "AI": "에이아이", + "CEO": "씨이오", + "A": "에이", + "B": "비", + "C": "씨", + "D": "디", + "E": "이", + "F": "에프", + "G": "지", + "H": "에이치", + "I": "아이", + "J": "제이", + "K": "케이", + "L": "엘", + "M": "엠", + "N": "엔", + "O": "오", + "P": "피", + "Q": "큐", + "R": "알", + "S": "에스", + "T": "티", + "U": "유", + "V": "브이", + "W": "더블유", + "X": "엑스", + "Y": "와이", + "Z": "제트", +} + + +def normalize(text): + text = text.strip() + text = re.sub( + "[⺀-⺙⺛-⻳⼀-⿕々〇〡-〩〸-〺〻㐀-䶵一-鿃豈-鶴侮-頻並-龎]", "", text + ) + text = normalize_english(text) + text = text.lower() + return text + + +def normalize_english(text): + def fn(m): + word = m.group() + if word in english_dictionary: + return english_dictionary.get(word) + return word + + text = re.sub("([A-Za-z]+)", fn, text) + return text + + +def korean_to_ipa(text, text_tokenizer): + if type(text) == str: + text = normalize(text) + phonemes = text_tokenizer(text) + return phonemes + else: + for i, t in enumerate(text): + text[i] = normalize(t) + return text_tokenizer(text) diff --git a/diffrhythm/g2p/g2p/mandarin.py b/diffrhythm/g2p/g2p/mandarin.py new file mode 100644 index 0000000000000000000000000000000000000000..f52a80d88a736f1e41c83b58865ea3322a8623a2 --- /dev/null +++ b/diffrhythm/g2p/g2p/mandarin.py @@ -0,0 +1,600 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import re +import jieba +import cn2an +from pypinyin import lazy_pinyin, BOPOMOFO +from typing import List +from diffrhythm.g2p.g2p.chinese_model_g2p import BertPolyPredict +from diffrhythm.g2p.utils.front_utils import * +import os +from huggingface_hub import hf_hub_download + +# from g2pw import G2PWConverter + + +# set blank level, {0:"none",1:"char", 2:"word"} +BLANK_LEVEL = 0 + +# conv = G2PWConverter(style='pinyin', enable_non_tradional_chinese=True) +resource_path = r"./diffrhythm/g2p" +poly_all_class_path = os.path.join( + resource_path, "sources", "g2p_chinese_model", "polychar.txt" +) +if not os.path.exists(poly_all_class_path): + print( + "Incorrect path for polyphonic character class dictionary: {}, please check...".format( + poly_all_class_path + ) + ) + exit() +poly_dict = generate_poly_lexicon(poly_all_class_path) + +# Set up G2PW model parameters +g2pw_poly_model_path = os.path.join(resource_path, "sources", "g2p_chinese_model") +if not os.path.exists(g2pw_poly_model_path): + print( + "Incorrect path for g2pw polyphonic character model: {}, please check...".format( + g2pw_poly_model_path + ) + ) + exit() + +json_file_path = os.path.join( + resource_path, "sources", "g2p_chinese_model", "polydict.json" +) +if not os.path.exists(json_file_path): + print( + "Incorrect path for g2pw id to pinyin dictionary: {}, please check...".format( + json_file_path + ) + ) + exit() + +jsonr_file_path = os.path.join( + resource_path, "sources", "g2p_chinese_model", "polydict_r.json" +) +if not os.path.exists(jsonr_file_path): + print( + "Incorrect path for g2pw pinyin to id dictionary: {}, please check...".format( + jsonr_file_path + ) + ) + exit() + +g2pw_poly_predict = BertPolyPredict( + g2pw_poly_model_path, jsonr_file_path, json_file_path +) + + +""" + Text clean time +""" +# List of (Latin alphabet, bopomofo) pairs: +_latin_to_bopomofo = [ + (re.compile("%s" % x[0], re.IGNORECASE), x[1]) + for x in [ + ("a", "ㄟˉ"), + ("b", "ㄅㄧˋ"), + ("c", "ㄙㄧˉ"), + ("d", "ㄉㄧˋ"), + ("e", "ㄧˋ"), + ("f", "ㄝˊㄈㄨˋ"), + ("g", "ㄐㄧˋ"), + ("h", "ㄝˇㄑㄩˋ"), + ("i", "ㄞˋ"), + ("j", "ㄐㄟˋ"), + ("k", "ㄎㄟˋ"), + ("l", "ㄝˊㄛˋ"), + ("m", "ㄝˊㄇㄨˋ"), + ("n", "ㄣˉ"), + ("o", "ㄡˉ"), + ("p", "ㄆㄧˉ"), + ("q", "ㄎㄧㄡˉ"), + ("r", "ㄚˋ"), + ("s", "ㄝˊㄙˋ"), + ("t", "ㄊㄧˋ"), + ("u", "ㄧㄡˉ"), + ("v", "ㄨㄧˉ"), + ("w", "ㄉㄚˋㄅㄨˋㄌㄧㄡˋ"), + ("x", "ㄝˉㄎㄨˋㄙˋ"), + ("y", "ㄨㄞˋ"), + ("z", "ㄗㄟˋ"), + ] +] + +# List of (bopomofo, ipa) pairs: +_bopomofo_to_ipa = [ + (re.compile("%s" % x[0]), x[1]) + for x in [ + ("ㄅㄛ", "p⁼wo"), + ("ㄆㄛ", "pʰwo"), + ("ㄇㄛ", "mwo"), + ("ㄈㄛ", "fwo"), + ("ㄧㄢ", "|jɛn"), + ("ㄩㄢ", "|ɥæn"), + ("ㄧㄣ", "|in"), + ("ㄩㄣ", "|ɥn"), + ("ㄧㄥ", "|iŋ"), + ("ㄨㄥ", "|ʊŋ"), + ("ㄩㄥ", "|jʊŋ"), + # Add + ("ㄧㄚ", "|ia"), + ("ㄧㄝ", "|iɛ"), + ("ㄧㄠ", "|iɑʊ"), + ("ㄧㄡ", "|ioʊ"), + ("ㄧㄤ", "|iɑŋ"), + ("ㄨㄚ", "|ua"), + ("ㄨㄛ", "|uo"), + ("ㄨㄞ", "|uaɪ"), + ("ㄨㄟ", "|ueɪ"), + ("ㄨㄢ", "|uan"), + ("ㄨㄣ", "|uən"), + ("ㄨㄤ", "|uɑŋ"), + ("ㄩㄝ", "|ɥɛ"), + # End + ("ㄅ", "p⁼"), + ("ㄆ", "pʰ"), + ("ㄇ", "m"), + ("ㄈ", "f"), + ("ㄉ", "t⁼"), + ("ㄊ", "tʰ"), + ("ㄋ", "n"), + ("ㄌ", "l"), + ("ㄍ", "k⁼"), + ("ㄎ", "kʰ"), + ("ㄏ", "x"), + ("ㄐ", "tʃ⁼"), + ("ㄑ", "tʃʰ"), + ("ㄒ", "ʃ"), + ("ㄓ", "ts`⁼"), + ("ㄔ", "ts`ʰ"), + ("ㄕ", "s`"), + ("ㄖ", "ɹ`"), + ("ㄗ", "ts⁼"), + ("ㄘ", "tsʰ"), + ("ㄙ", "|s"), + ("ㄚ", "|a"), + ("ㄛ", "|o"), + ("ㄜ", "|ə"), + ("ㄝ", "|ɛ"), + ("ㄞ", "|aɪ"), + ("ㄟ", "|eɪ"), + ("ㄠ", "|ɑʊ"), + ("ㄡ", "|oʊ"), + ("ㄢ", "|an"), + ("ㄣ", "|ən"), + ("ㄤ", "|ɑŋ"), + ("ㄥ", "|əŋ"), + ("ㄦ", "əɹ"), + ("ㄧ", "|i"), + ("ㄨ", "|u"), + ("ㄩ", "|ɥ"), + ("ˉ", "→|"), + ("ˊ", "↑|"), + ("ˇ", "↓↑|"), + ("ˋ", "↓|"), + ("˙", "|"), + ] +] +must_not_er_words = {"女儿", "老儿", "男儿", "少儿", "小儿"} + + +chinese_lexicon_path = hf_hub_download( + repo_id="ASLP-lab/DiffRhythm", + filename="diffrhythm/g2p/sources/chinese_lexicon.txt", + repo_type="space" + ) +word_pinyin_dict = {} +with open(chinese_lexicon_path, "r", encoding="utf-8") as fread: + txt_list = fread.readlines() + for txt in txt_list: + word, pinyin = txt.strip().split("\t") + word_pinyin_dict[word] = pinyin + fread.close() + +pinyin_2_bopomofo_dict = {} +with open( + r"./diffrhythm/g2p/sources/pinyin_2_bpmf.txt", "r", encoding="utf-8" +) as fread: + txt_list = fread.readlines() + for txt in txt_list: + pinyin, bopomofo = txt.strip().split("\t") + pinyin_2_bopomofo_dict[pinyin] = bopomofo + fread.close() + +tone_dict = { + "0": "˙", + "5": "˙", + "1": "", + "2": "ˊ", + "3": "ˇ", + "4": "ˋ", +} + +bopomofos2pinyin_dict = {} +with open( + r"./diffrhythm/g2p/sources/bpmf_2_pinyin.txt", "r", encoding="utf-8" +) as fread: + txt_list = fread.readlines() + for txt in txt_list: + v, k = txt.strip().split("\t") + bopomofos2pinyin_dict[k] = v + fread.close() + + +def bpmf_to_pinyin(text): + bopomofo_list = text.split("|") + pinyin_list = [] + for info in bopomofo_list: + pinyin = "" + for c in info: + if c in bopomofos2pinyin_dict: + pinyin += bopomofos2pinyin_dict[c] + if len(pinyin) == 0: + continue + if pinyin[-1] not in "01234": + pinyin += "1" + if pinyin[:-1] == "ve": + pinyin = "y" + pinyin + if pinyin[:-1] == "sh": + pinyin = pinyin[:-1] + "i" + pinyin[-1] + if pinyin == "sh": + pinyin = pinyin[:-1] + "i" + if pinyin[:-1] == "s": + pinyin = "si" + pinyin[-1] + if pinyin[:-1] == "c": + pinyin = "ci" + pinyin[-1] + if pinyin[:-1] == "i": + pinyin = "yi" + pinyin[-1] + if pinyin[:-1] == "iou": + pinyin = "you" + pinyin[-1] + if pinyin[:-1] == "ien": + pinyin = "yin" + pinyin[-1] + if "iou" in pinyin and pinyin[-4:-1] == "iou": + pinyin = pinyin[:-4] + "iu" + pinyin[-1] + if "uei" in pinyin: + if pinyin[:-1] == "uei": + pinyin = "wei" + pinyin[-1] + elif pinyin[-4:-1] == "uei": + pinyin = pinyin[:-4] + "ui" + pinyin[-1] + if "uen" in pinyin and pinyin[-4:-1] == "uen": + if pinyin[:-1] == "uen": + pinyin = "wen" + pinyin[-1] + elif pinyin[-4:-1] == "uei": + pinyin = pinyin[:-4] + "un" + pinyin[-1] + if "van" in pinyin and pinyin[-4:-1] == "van": + if pinyin[:-1] == "van": + pinyin = "yuan" + pinyin[-1] + elif pinyin[-4:-1] == "van": + pinyin = pinyin[:-4] + "uan" + pinyin[-1] + if "ueng" in pinyin and pinyin[-5:-1] == "ueng": + pinyin = pinyin[:-5] + "ong" + pinyin[-1] + if pinyin[:-1] == "veng": + pinyin = "yong" + pinyin[-1] + if "veng" in pinyin and pinyin[-5:-1] == "veng": + pinyin = pinyin[:-5] + "iong" + pinyin[-1] + if pinyin[:-1] == "ieng": + pinyin = "ying" + pinyin[-1] + if pinyin[:-1] == "u": + pinyin = "wu" + pinyin[-1] + if pinyin[:-1] == "v": + pinyin = "yv" + pinyin[-1] + if pinyin[:-1] == "ing": + pinyin = "ying" + pinyin[-1] + if pinyin[:-1] == "z": + pinyin = "zi" + pinyin[-1] + if pinyin[:-1] == "zh": + pinyin = "zhi" + pinyin[-1] + if pinyin[0] == "u": + pinyin = "w" + pinyin[1:] + if pinyin[0] == "i": + pinyin = "y" + pinyin[1:] + pinyin = pinyin.replace("ien", "in") + + pinyin_list.append(pinyin) + return " ".join(pinyin_list) + + +# Convert numbers to Chinese pronunciation +def number_to_chinese(text): + # numbers = re.findall(r'\d+(?:\.?\d+)?', text) + # for number in numbers: + # text = text.replace(number, cn2an.an2cn(number), 1) + text = cn2an.transform(text, "an2cn") + return text + + +def normalization(text): + text = text.replace(",", ",") + text = text.replace("。", ".") + text = text.replace("!", "!") + text = text.replace("?", "?") + text = text.replace(";", ";") + text = text.replace(":", ":") + text = text.replace("、", ",") + text = text.replace("‘", "'") + text = text.replace("’", "'") + text = text.replace("⋯", "…") + text = text.replace("···", "…") + text = text.replace("・・・", "…") + text = text.replace("...", "…") + text = re.sub(r"\s+", "", text) + text = re.sub(r"[^\u4e00-\u9fff\s_,\.\?!;:\'…]", "", text) + text = re.sub(r"\s*([,\.\?!;:\'…])\s*", r"\1", text) + return text + + +def change_tone(bopomofo: str, tone: str) -> str: + if bopomofo[-1] not in "˙ˊˇˋ": + bopomofo = bopomofo + tone + else: + bopomofo = bopomofo[:-1] + tone + return bopomofo + + +def er_sandhi(word: str, bopomofos: List[str]) -> List[str]: + if len(word) > 1 and word[-1] == "儿" and word not in must_not_er_words: + bopomofos[-1] = change_tone(bopomofos[-1], "˙") + return bopomofos + + +def bu_sandhi(word: str, bopomofos: List[str]) -> List[str]: + valid_char = set(word) + if len(valid_char) == 1 and "不" in valid_char: + pass + elif word in ["不字"]: + pass + elif len(word) == 3 and word[1] == "不" and bopomofos[1][:-1] == "ㄅㄨ": + bopomofos[1] = bopomofos[1][:-1] + "˙" + else: + for i, char in enumerate(word): + if ( + i + 1 < len(bopomofos) + and char == "不" + and i + 1 < len(word) + and 0 < len(bopomofos[i + 1]) + and bopomofos[i + 1][-1] == "ˋ" + ): + bopomofos[i] = bopomofos[i][:-1] + "ˊ" + return bopomofos + + +def yi_sandhi(word: str, bopomofos: List[str]) -> List[str]: + punc = ":,;。?!“”‘’':,;.?!()(){}【】[]-~`、 " + if word.find("一") != -1 and any( + [item.isnumeric() for item in word if item != "一"] + ): + for i in range(len(word)): + if ( + i == 0 + and word[0] == "一" + and len(word) > 1 + and word[1] + not in [ + "零", + "一", + "二", + "三", + "四", + "五", + "六", + "七", + "八", + "九", + "十", + ] + ): + if len(bopomofos[0]) > 0 and bopomofos[1][-1] in ["ˋ", "˙"]: + bopomofos[0] = change_tone(bopomofos[0], "ˊ") + else: + bopomofos[0] = change_tone(bopomofos[0], "ˋ") + elif word[i] == "一": + bopomofos[i] = change_tone(bopomofos[i], "") + return bopomofos + elif len(word) == 3 and word[1] == "一" and word[0] == word[-1]: + bopomofos[1] = change_tone(bopomofos[1], "˙") + elif word.startswith("第一"): + bopomofos[1] = change_tone(bopomofos[1], "") + elif word.startswith("一月") or word.startswith("一日") or word.startswith("一号"): + bopomofos[0] = change_tone(bopomofos[0], "") + else: + for i, char in enumerate(word): + if char == "一" and i + 1 < len(word): + if ( + len(bopomofos) > i + 1 + and len(bopomofos[i + 1]) > 0 + and bopomofos[i + 1][-1] in {"ˋ"} + ): + bopomofos[i] = change_tone(bopomofos[i], "ˊ") + else: + if word[i + 1] not in punc: + bopomofos[i] = change_tone(bopomofos[i], "ˋ") + else: + pass + return bopomofos + + +def merge_bu(seg: List) -> List: + new_seg = [] + last_word = "" + for word in seg: + if word != "不": + if last_word == "不": + word = last_word + word + new_seg.append(word) + last_word = word + return new_seg + + +def merge_er(seg: List) -> List: + new_seg = [] + for i, word in enumerate(seg): + if i - 1 >= 0 and word == "儿": + new_seg[-1] = new_seg[-1] + seg[i] + else: + new_seg.append(word) + return new_seg + + +def merge_yi(seg: List) -> List: + new_seg = [] + # function 1 + for i, word in enumerate(seg): + if ( + i - 1 >= 0 + and word == "一" + and i + 1 < len(seg) + and seg[i - 1] == seg[i + 1] + ): + if i - 1 < len(new_seg): + new_seg[i - 1] = new_seg[i - 1] + "一" + new_seg[i - 1] + else: + new_seg.append(word) + new_seg.append(seg[i + 1]) + else: + if i - 2 >= 0 and seg[i - 1] == "一" and seg[i - 2] == word: + continue + else: + new_seg.append(word) + seg = new_seg + new_seg = [] + isnumeric_flag = False + for i, word in enumerate(seg): + if all([item.isnumeric() for item in word]) and not isnumeric_flag: + isnumeric_flag = True + new_seg.append(word) + else: + new_seg.append(word) + seg = new_seg + new_seg = [] + # function 2 + for i, word in enumerate(seg): + if new_seg and new_seg[-1] == "一": + new_seg[-1] = new_seg[-1] + word + else: + new_seg.append(word) + return new_seg + + +# Word Segmentation, and convert Chinese pronunciation to pinyin (bopomofo) +def chinese_to_bopomofo(text_short, sentence): + # bopomofos = conv(text_short) + words = jieba.lcut(text_short, cut_all=False) + words = merge_yi(words) + words = merge_bu(words) + words = merge_er(words) + text = "" + + char_index = 0 + for word in words: + bopomofos = [] + if word in word_pinyin_dict and word not in poly_dict: + pinyin = word_pinyin_dict[word] + for py in pinyin.split(" "): + if py[:-1] in pinyin_2_bopomofo_dict and py[-1] in tone_dict: + bopomofos.append( + pinyin_2_bopomofo_dict[py[:-1]] + tone_dict[py[-1]] + ) + if BLANK_LEVEL == 1: + bopomofos.append("_") + else: + bopomofos_lazy = lazy_pinyin(word, BOPOMOFO) + bopomofos += bopomofos_lazy + if BLANK_LEVEL == 1: + bopomofos.append("_") + else: + for i in range(len(word)): + c = word[i] + if c in poly_dict: + poly_pinyin = g2pw_poly_predict.predict_process( + [text_short, char_index + i] + )[0] + py = poly_pinyin[2:-1] + bopomofos.append( + pinyin_2_bopomofo_dict[py[:-1]] + tone_dict[py[-1]] + ) + if BLANK_LEVEL == 1: + bopomofos.append("_") + elif c in word_pinyin_dict: + py = word_pinyin_dict[c] + bopomofos.append( + pinyin_2_bopomofo_dict[py[:-1]] + tone_dict[py[-1]] + ) + if BLANK_LEVEL == 1: + bopomofos.append("_") + else: + bopomofos.append(c) + if BLANK_LEVEL == 1: + bopomofos.append("_") + if BLANK_LEVEL == 2: + bopomofos.append("_") + char_index += len(word) + + if ( + len(word) == 3 + and bopomofos[0][-1] == "ˇ" + and bopomofos[1][-1] == "ˇ" + and bopomofos[-1][-1] == "ˇ" + ): + bopomofos[0] = bopomofos[0] + "ˊ" + bopomofos[1] = bopomofos[1] + "ˊ" + if len(word) == 2 and bopomofos[0][-1] == "ˇ" and bopomofos[-1][-1] == "ˇ": + bopomofos[0] = bopomofos[0][:-1] + "ˊ" + bopomofos = bu_sandhi(word, bopomofos) + bopomofos = yi_sandhi(word, bopomofos) + bopomofos = er_sandhi(word, bopomofos) + if not re.search("[\u4e00-\u9fff]", word): + text += "|" + word + continue + for i in range(len(bopomofos)): + bopomofos[i] = re.sub(r"([\u3105-\u3129])$", r"\1ˉ", bopomofos[i]) + if text != "": + text += "|" + text += "|".join(bopomofos) + return text + + +# Convert latin pronunciation to pinyin (bopomofo) +def latin_to_bopomofo(text): + for regex, replacement in _latin_to_bopomofo: + text = re.sub(regex, replacement, text) + return text + + +# Convert pinyin (bopomofo) to IPA +def bopomofo_to_ipa(text): + for regex, replacement in _bopomofo_to_ipa: + text = re.sub(regex, replacement, text) + return text + + +def _chinese_to_ipa(text, sentence): + text = number_to_chinese(text.strip()) + text = normalization(text) + text = chinese_to_bopomofo(text, sentence) + # pinyin = bpmf_to_pinyin(text) + text = latin_to_bopomofo(text) + text = bopomofo_to_ipa(text) + text = re.sub("([sɹ]`[⁼ʰ]?)([→↓↑ ]+|$)", r"\1ɹ\2", text) + text = re.sub("([s][⁼ʰ]?)([→↓↑ ]+|$)", r"\1ɹ\2", text) + text = re.sub(r"^\||[^\w\s_,\.\?!;:\'…\|→↓↑⁼ʰ`]", "", text) + text = re.sub(r"([,\.\?!;:\'…])", r"|\1|", text) + text = re.sub(r"\|+", "|", text) + text = text.rstrip("|") + return text + + +# Convert Chinese to IPA +def chinese_to_ipa(text, sentence, text_tokenizer): + # phonemes = text_tokenizer(text.strip()) + if type(text) == str: + return _chinese_to_ipa(text, sentence) + else: + result_ph = [] + for t in text: + result_ph.append(_chinese_to_ipa(t, sentence)) + return result_ph diff --git a/diffrhythm/g2p/g2p/text_tokenizers.py b/diffrhythm/g2p/g2p/text_tokenizers.py new file mode 100644 index 0000000000000000000000000000000000000000..33d5752a98209393514cc6d6706f4f5ebd909d2c --- /dev/null +++ b/diffrhythm/g2p/g2p/text_tokenizers.py @@ -0,0 +1,85 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import re +import os +from typing import List, Pattern, Union +from phonemizer.utils import list2str, str2list +from phonemizer.backend import EspeakBackend +from phonemizer.backend.espeak.language_switch import LanguageSwitch +from phonemizer.backend.espeak.words_mismatch import WordMismatch +from phonemizer.punctuation import Punctuation +# from zer.separator import Separator +from phonemizer.separator import Separator + + +class TextTokenizer: + """Phonemize Text.""" + + def __init__( + self, + language="en-us", + backend="espeak", + separator=Separator(word="|_|", syllable="-", phone="|"), + preserve_punctuation=True, + with_stress: bool = False, + tie: Union[bool, str] = False, + language_switch: LanguageSwitch = "remove-flags", + words_mismatch: WordMismatch = "ignore", + ) -> None: + self.preserve_punctuation_marks = ",.?!;:'…" + self.backend = EspeakBackend( + language, + punctuation_marks=self.preserve_punctuation_marks, + preserve_punctuation=preserve_punctuation, + with_stress=with_stress, + tie=tie, + language_switch=language_switch, + words_mismatch=words_mismatch, + ) + + self.separator = separator + + # convert chinese punctuation to english punctuation + def convert_chinese_punctuation(self, text: str) -> str: + text = text.replace(",", ",") + text = text.replace("。", ".") + text = text.replace("!", "!") + text = text.replace("?", "?") + text = text.replace(";", ";") + text = text.replace(":", ":") + text = text.replace("、", ",") + text = text.replace("‘", "'") + text = text.replace("’", "'") + text = text.replace("⋯", "…") + text = text.replace("···", "…") + text = text.replace("・・・", "…") + text = text.replace("...", "…") + return text + + def __call__(self, text, strip=True) -> List[str]: + + text_type = type(text) + normalized_text = [] + for line in str2list(text): + line = self.convert_chinese_punctuation(line.strip()) + line = re.sub(r"[^\w\s_,\.\?!;:\'…]", "", line) + line = re.sub(r"\s*([,\.\?!;:\'…])\s*", r"\1", line) + line = re.sub(r"\s+", " ", line) + normalized_text.append(line) + # print("Normalized test: ", normalized_text[0]) + phonemized = self.backend.phonemize( + normalized_text, separator=self.separator, strip=strip, njobs=1 + ) + if text_type == str: + phonemized = re.sub(r"([,\.\?!;:\'…])", r"|\1|", list2str(phonemized)) + phonemized = re.sub(r"\|+", "|", phonemized) + phonemized = phonemized.rstrip("|") + else: + for i in range(len(phonemized)): + phonemized[i] = re.sub(r"([,\.\?!;:\'…])", r"|\1|", phonemized[i]) + phonemized[i] = re.sub(r"\|+", "|", phonemized[i]) + phonemized[i] = phonemized[i].rstrip("|") + return phonemized diff --git a/diffrhythm/g2p/g2p/vocab.json b/diffrhythm/g2p/g2p/vocab.json new file mode 100644 index 0000000000000000000000000000000000000000..28d32aaf01881c6ff5449aaaf942d94b753a4e91 --- /dev/null +++ b/diffrhythm/g2p/g2p/vocab.json @@ -0,0 +1,372 @@ +{ + "vocab": { + ",": 0, + ".": 1, + "?": 2, + "!": 3, + "_": 4, + "iː": 5, + "ɪ": 6, + "ɜː": 7, + "ɚ": 8, + "oːɹ": 9, + "ɔː": 10, + "ɔːɹ": 11, + "ɑː": 12, + "uː": 13, + "ʊ": 14, + "ɑːɹ": 15, + "ʌ": 16, + "ɛ": 17, + "æ": 18, + "eɪ": 19, + "aɪ": 20, + "ɔɪ": 21, + "aʊ": 22, + "oʊ": 23, + "ɪɹ": 24, + "ɛɹ": 25, + "ʊɹ": 26, + "p": 27, + "b": 28, + "t": 29, + "d": 30, + "k": 31, + "ɡ": 32, + "f": 33, + "v": 34, + "θ": 35, + "ð": 36, + "s": 37, + "z": 38, + "ʃ": 39, + "ʒ": 40, + "h": 41, + "tʃ": 42, + "dʒ": 43, + "m": 44, + "n": 45, + "ŋ": 46, + "j": 47, + "w": 48, + "ɹ": 49, + "l": 50, + "tɹ": 51, + "dɹ": 52, + "ts": 53, + "dz": 54, + "i": 55, + "ɔ": 56, + "ə": 57, + "ɾ": 58, + "iə": 59, + "r": 60, + "u": 61, + "oː": 62, + "ɛː": 63, + "ɪː": 64, + "aɪə": 65, + "aɪɚ": 66, + "ɑ̃": 67, + "ç": 68, + "ɔ̃": 69, + "ææ": 70, + "ɐɐ": 71, + "ɡʲ": 72, + "nʲ": 73, + "iːː": 74, + + "p⁼": 75, + "pʰ": 76, + "t⁼": 77, + "tʰ": 78, + "k⁼": 79, + "kʰ": 80, + "x": 81, + "tʃ⁼": 82, + "tʃʰ": 83, + "ts`⁼": 84, + "ts`ʰ": 85, + "s`": 86, + "ɹ`": 87, + "ts⁼": 88, + "tsʰ": 89, + "p⁼wo": 90, + "p⁼wo→": 91, + "p⁼wo↑": 92, + "p⁼wo↓↑": 93, + "p⁼wo↓": 94, + "pʰwo": 95, + "pʰwo→": 96, + "pʰwo↑": 97, + "pʰwo↓↑": 98, + "pʰwo↓": 99, + "mwo": 100, + "mwo→": 101, + "mwo↑": 102, + "mwo↓↑": 103, + "mwo↓": 104, + "fwo": 105, + "fwo→": 106, + "fwo↑": 107, + "fwo↓↑": 108, + "fwo↓": 109, + "jɛn": 110, + "jɛn→": 111, + "jɛn↑": 112, + "jɛn↓↑": 113, + "jɛn↓": 114, + "ɥæn": 115, + "ɥæn→": 116, + "ɥæn↑": 117, + "ɥæn↓↑": 118, + "ɥæn↓": 119, + "in": 120, + "in→": 121, + "in↑": 122, + "in↓↑": 123, + "in↓": 124, + "ɥn": 125, + "ɥn→": 126, + "ɥn↑": 127, + "ɥn↓↑": 128, + "ɥn↓": 129, + "iŋ": 130, + "iŋ→": 131, + "iŋ↑": 132, + "iŋ↓↑": 133, + "iŋ↓": 134, + "ʊŋ": 135, + "ʊŋ→": 136, + "ʊŋ↑": 137, + "ʊŋ↓↑": 138, + "ʊŋ↓": 139, + "jʊŋ": 140, + "jʊŋ→": 141, + "jʊŋ↑": 142, + "jʊŋ↓↑": 143, + "jʊŋ↓": 144, + "ia": 145, + "ia→": 146, + "ia↑": 147, + "ia↓↑": 148, + "ia↓": 149, + "iɛ": 150, + "iɛ→": 151, + "iɛ↑": 152, + "iɛ↓↑": 153, + "iɛ↓": 154, + "iɑʊ": 155, + "iɑʊ→": 156, + "iɑʊ↑": 157, + "iɑʊ↓↑": 158, + "iɑʊ↓": 159, + "ioʊ": 160, + "ioʊ→": 161, + "ioʊ↑": 162, + "ioʊ↓↑": 163, + "ioʊ↓": 164, + "iɑŋ": 165, + "iɑŋ→": 166, + "iɑŋ↑": 167, + "iɑŋ↓↑": 168, + "iɑŋ↓": 169, + "ua": 170, + "ua→": 171, + "ua↑": 172, + "ua↓↑": 173, + "ua↓": 174, + "uo": 175, + "uo→": 176, + "uo↑": 177, + "uo↓↑": 178, + "uo↓": 179, + "uaɪ": 180, + "uaɪ→": 181, + "uaɪ↑": 182, + "uaɪ↓↑": 183, + "uaɪ↓": 184, + "ueɪ": 185, + "ueɪ→": 186, + "ueɪ↑": 187, + "ueɪ↓↑": 188, + "ueɪ↓": 189, + "uan": 190, + "uan→": 191, + "uan↑": 192, + "uan↓↑": 193, + "uan↓": 194, + "uən": 195, + "uən→": 196, + "uən↑": 197, + "uən↓↑": 198, + "uən↓": 199, + "uɑŋ": 200, + "uɑŋ→": 201, + "uɑŋ↑": 202, + "uɑŋ↓↑": 203, + "uɑŋ↓": 204, + "ɥɛ": 205, + "ɥɛ→": 206, + "ɥɛ↑": 207, + "ɥɛ↓↑": 208, + "ɥɛ↓": 209, + "a": 210, + "a→": 211, + "a↑": 212, + "a↓↑": 213, + "a↓": 214, + "o": 215, + "o→": 216, + "o↑": 217, + "o↓↑": 218, + "o↓": 219, + "ə→": 220, + "ə↑": 221, + "ə↓↑": 222, + "ə↓": 223, + "ɛ→": 224, + "ɛ↑": 225, + "ɛ↓↑": 226, + "ɛ↓": 227, + "aɪ→": 228, + "aɪ↑": 229, + "aɪ↓↑": 230, + "aɪ↓": 231, + "eɪ→": 232, + "eɪ↑": 233, + "eɪ↓↑": 234, + "eɪ↓": 235, + "ɑʊ": 236, + "ɑʊ→": 237, + "ɑʊ↑": 238, + "ɑʊ↓↑": 239, + "ɑʊ↓": 240, + "oʊ→": 241, + "oʊ↑": 242, + "oʊ↓↑": 243, + "oʊ↓": 244, + "an": 245, + "an→": 246, + "an↑": 247, + "an↓↑": 248, + "an↓": 249, + "ən": 250, + "ən→": 251, + "ən↑": 252, + "ən↓↑": 253, + "ən↓": 254, + "ɑŋ": 255, + "ɑŋ→": 256, + "ɑŋ↑": 257, + "ɑŋ↓↑": 258, + "ɑŋ↓": 259, + "əŋ": 260, + "əŋ→": 261, + "əŋ↑": 262, + "əŋ↓↑": 263, + "əŋ↓": 264, + "əɹ": 265, + "əɹ→": 266, + "əɹ↑": 267, + "əɹ↓↑": 268, + "əɹ↓": 269, + "i→": 270, + "i↑": 271, + "i↓↑": 272, + "i↓": 273, + "u→": 274, + "u↑": 275, + "u↓↑": 276, + "u↓": 277, + "ɥ": 278, + "ɥ→": 279, + "ɥ↑": 280, + "ɥ↓↑": 281, + "ɥ↓": 282, + "ts`⁼ɹ": 283, + "ts`⁼ɹ→": 284, + "ts`⁼ɹ↑": 285, + "ts`⁼ɹ↓↑": 286, + "ts`⁼ɹ↓": 287, + "ts`ʰɹ": 288, + "ts`ʰɹ→": 289, + "ts`ʰɹ↑": 290, + "ts`ʰɹ↓↑": 291, + "ts`ʰɹ↓": 292, + "s`ɹ": 293, + "s`ɹ→": 294, + "s`ɹ↑": 295, + "s`ɹ↓↑": 296, + "s`ɹ↓": 297, + "ɹ`ɹ": 298, + "ɹ`ɹ→": 299, + "ɹ`ɹ↑": 300, + "ɹ`ɹ↓↑": 301, + "ɹ`ɹ↓": 302, + "ts⁼ɹ": 303, + "ts⁼ɹ→": 304, + "ts⁼ɹ↑": 305, + "ts⁼ɹ↓↑": 306, + "ts⁼ɹ↓": 307, + "tsʰɹ": 308, + "tsʰɹ→": 309, + "tsʰɹ↑": 310, + "tsʰɹ↓↑": 311, + "tsʰɹ↓": 312, + "sɹ": 313, + "sɹ→": 314, + "sɹ↑": 315, + "sɹ↓↑": 316, + "sɹ↓": 317, + + "ɯ": 318, + "e": 319, + "aː": 320, + "ɯː": 321, + "eː": 322, + "ç": 323, + "ɸ": 324, + "ɰᵝ": 325, + "ɴ": 326, + "g": 327, + "dʑ": 328, + "q": 329, + "ː": 330, + "bj": 331, + "tɕ": 332, + "dej": 333, + "tej": 334, + "gj": 335, + "gɯ": 336, + "çj": 337, + "kj": 338, + "kɯ": 339, + "mj": 340, + "nj": 341, + "pj": 342, + "ɾj": 343, + "ɕ": 344, + "tsɯ": 345, + + "ɐ": 346, + "ɑ": 347, + "ɒ": 348, + "ɜ": 349, + "ɫ": 350, + "ʑ": 351, + "ʲ": 352, + + "y": 353, + "ø": 354, + "œ": 355, + "ʁ": 356, + "̃": 357, + "ɲ": 358, + + ":": 359, + ";": 360, + "'": 361, + "…": 362 + } +} diff --git a/diffrhythm/g2p/g2p_generation.py b/diffrhythm/g2p/g2p_generation.py new file mode 100644 index 0000000000000000000000000000000000000000..e78f3e7076f8d55678d1705b13900950cd151adf --- /dev/null +++ b/diffrhythm/g2p/g2p_generation.py @@ -0,0 +1,133 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import os +import sys + +from diffrhythm.g2p.g2p import PhonemeBpeTokenizer +from diffrhythm.g2p.utils.g2p import phonemizer_g2p +import tqdm +from typing import List +import json +import os +import re + + +def ph_g2p(text, language): + + return phonemizer_g2p(text=text, language=language) + + +def g2p(text, sentence, language): + + return text_tokenizer.tokenize(text=text, sentence=sentence, language=language) + + +def is_chinese(char): + if char >= "\u4e00" and char <= "\u9fa5": + return True + else: + return False + + +def is_alphabet(char): + if (char >= "\u0041" and char <= "\u005a") or ( + char >= "\u0061" and char <= "\u007a" + ): + return True + else: + return False + + +def is_other(char): + if not (is_chinese(char) or is_alphabet(char)): + return True + else: + return False + + +def get_segment(text: str) -> List[str]: + # sentence --> [ch_part, en_part, ch_part, ...] + segments = [] + types = [] + flag = 0 + temp_seg = "" + temp_lang = "" + + # Determine the type of each character. type: blank, chinese, alphabet, number, unk and point. + for i, ch in enumerate(text): + if is_chinese(ch): + types.append("zh") + elif is_alphabet(ch): + types.append("en") + else: + types.append("other") + + assert len(types) == len(text) + + for i in range(len(types)): + # find the first char of the seg + if flag == 0: + temp_seg += text[i] + temp_lang = types[i] + flag = 1 + else: + if temp_lang == "other": + if types[i] == temp_lang: + temp_seg += text[i] + else: + temp_seg += text[i] + temp_lang = types[i] + else: + if types[i] == temp_lang: + temp_seg += text[i] + elif types[i] == "other": + temp_seg += text[i] + else: + segments.append((temp_seg, temp_lang)) + temp_seg = text[i] + temp_lang = types[i] + flag = 1 + + segments.append((temp_seg, temp_lang)) + return segments + + +def chn_eng_g2p(text: str): + # now only en and ch + segments = get_segment(text) + all_phoneme = "" + all_tokens = [] + + for index in range(len(segments)): + seg = segments[index] + phoneme, token = g2p(seg[0], text, seg[1]) + all_phoneme += phoneme + "|" + all_tokens += token + + if seg[1] == "en" and index == len(segments) - 1 and all_phoneme[-2] == "_": + all_phoneme = all_phoneme[:-2] + all_tokens = all_tokens[:-1] + return all_phoneme, all_tokens + + +text_tokenizer = PhonemeBpeTokenizer() +with open("./diffrhythm/g2p/g2p/vocab.json", "r") as f: + json_data = f.read() +data = json.loads(json_data) +vocab = data["vocab"] + +if __name__ == '__main__': + phone, token = chn_eng_g2p("你好,hello world") + phone, token = chn_eng_g2p("你好,hello world, Bonjour, 테스트 해 보겠습니다, 五月雨緑") + print(phone) + print(token) + + #phone, token = text_tokenizer.tokenize("你好,hello world, Bonjour, 테스트 해 보겠습니다, 五月雨緑", "", "auto") + phone, token = text_tokenizer.tokenize("緑", "", "auto") + #phone, token = text_tokenizer.tokenize("आइए इसका परीक्षण करें", "", "auto") + #phone, token = text_tokenizer.tokenize("आइए इसका परीक्षण करें", "", "other") + print(phone) + print(token) \ No newline at end of file diff --git a/diffrhythm/g2p/sources/bpmf_2_pinyin.txt b/diffrhythm/g2p/sources/bpmf_2_pinyin.txt new file mode 100644 index 0000000000000000000000000000000000000000..474529e5d347b94a80e5052de0065347ff14b95e --- /dev/null +++ b/diffrhythm/g2p/sources/bpmf_2_pinyin.txt @@ -0,0 +1,41 @@ +b ㄅ +p ㄆ +m ㄇ +f ㄈ +d ㄉ +t ㄊ +n ㄋ +l ㄌ +g ㄍ +k ㄎ +h ㄏ +j ㄐ +q ㄑ +x ㄒ +zh ㄓ +ch ㄔ +sh ㄕ +r ㄖ +z ㄗ +c ㄘ +s ㄙ +i ㄧ +u ㄨ +v ㄩ +a ㄚ +o ㄛ +e ㄜ +e ㄝ +ai ㄞ +ei ㄟ +ao ㄠ +ou ㄡ +an ㄢ +en ㄣ +ang ㄤ +eng ㄥ +er ㄦ +2 ˊ +3 ˇ +4 ˋ +0 ˙ diff --git a/diffrhythm/g2p/sources/chinese_lexicon.txt b/diffrhythm/g2p/sources/chinese_lexicon.txt new file mode 100644 index 0000000000000000000000000000000000000000..4d7dbf347a29d3b87c199d0e56ef7f1dbf28a6ee --- /dev/null +++ b/diffrhythm/g2p/sources/chinese_lexicon.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3a7685d1c3e68eb2fa304bfc63e90c90c3c1a1948839a5b1b507b2131b3e2fb +size 14779443 diff --git a/diffrhythm/g2p/sources/g2p_chinese_model/config.json b/diffrhythm/g2p/sources/g2p_chinese_model/config.json new file mode 100644 index 0000000000000000000000000000000000000000..5fb70ca91db27a4ad73b58a0c500a903be9bc1a9 --- /dev/null +++ b/diffrhythm/g2p/sources/g2p_chinese_model/config.json @@ -0,0 +1,819 @@ +{ + "_name_or_path": "/BERT-POLY-v2/pretrained_models/mini_bert", + "architectures": [ + "BertPoly" + ], + "attention_probs_dropout_prob": 0.1, + "classifier_dropout": null, + "directionality": "bidi", + "gradient_checkpointing": false, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.1, + "hidden_size": 384, + "id2label": { + "0": "LABEL_0", + "1": "LABEL_1", + "2": "LABEL_2", + "3": "LABEL_3", + "4": "LABEL_4", + "5": "LABEL_5", + "6": "LABEL_6", + "7": "LABEL_7", + "8": "LABEL_8", + "9": "LABEL_9", + "10": "LABEL_10", + "11": "LABEL_11", + "12": "LABEL_12", + "13": "LABEL_13", + "14": "LABEL_14", + "15": "LABEL_15", + "16": "LABEL_16", + "17": "LABEL_17", + "18": "LABEL_18", + "19": "LABEL_19", + "20": "LABEL_20", + "21": "LABEL_21", + "22": "LABEL_22", + "23": "LABEL_23", + "24": "LABEL_24", + "25": "LABEL_25", + "26": "LABEL_26", + "27": "LABEL_27", + "28": "LABEL_28", + "29": "LABEL_29", + "30": "LABEL_30", + "31": "LABEL_31", + "32": "LABEL_32", + "33": "LABEL_33", + "34": "LABEL_34", + "35": "LABEL_35", + "36": "LABEL_36", + "37": "LABEL_37", + "38": "LABEL_38", + "39": "LABEL_39", + "40": "LABEL_40", + "41": "LABEL_41", + "42": "LABEL_42", + "43": "LABEL_43", + "44": "LABEL_44", + "45": "LABEL_45", + "46": "LABEL_46", + "47": "LABEL_47", + "48": "LABEL_48", + "49": "LABEL_49", + "50": "LABEL_50", + "51": "LABEL_51", + "52": "LABEL_52", + "53": "LABEL_53", + "54": "LABEL_54", + "55": "LABEL_55", + "56": "LABEL_56", + "57": "LABEL_57", + "58": "LABEL_58", + "59": "LABEL_59", + "60": "LABEL_60", + "61": "LABEL_61", + "62": "LABEL_62", + "63": "LABEL_63", + "64": "LABEL_64", + "65": "LABEL_65", + "66": "LABEL_66", + "67": "LABEL_67", + "68": "LABEL_68", + "69": "LABEL_69", + "70": "LABEL_70", + "71": "LABEL_71", + "72": "LABEL_72", + "73": "LABEL_73", + "74": "LABEL_74", + "75": "LABEL_75", + "76": "LABEL_76", + "77": "LABEL_77", + "78": "LABEL_78", + "79": "LABEL_79", + "80": "LABEL_80", + "81": "LABEL_81", + "82": "LABEL_82", + "83": "LABEL_83", + "84": "LABEL_84", + "85": "LABEL_85", + "86": "LABEL_86", + "87": "LABEL_87", + "88": "LABEL_88", + "89": "LABEL_89", + "90": "LABEL_90", + "91": "LABEL_91", + "92": "LABEL_92", + "93": "LABEL_93", + "94": "LABEL_94", + "95": "LABEL_95", + "96": "LABEL_96", + "97": "LABEL_97", + "98": "LABEL_98", + "99": "LABEL_99", + "100": "LABEL_100", + "101": "LABEL_101", + "102": "LABEL_102", + "103": "LABEL_103", + "104": "LABEL_104", + "105": "LABEL_105", + "106": "LABEL_106", + "107": "LABEL_107", + "108": "LABEL_108", + "109": "LABEL_109", + "110": "LABEL_110", + "111": "LABEL_111", + "112": "LABEL_112", + "113": "LABEL_113", + "114": "LABEL_114", + "115": "LABEL_115", + "116": "LABEL_116", + "117": "LABEL_117", + "118": "LABEL_118", + "119": "LABEL_119", + "120": "LABEL_120", + "121": "LABEL_121", + "122": "LABEL_122", + "123": "LABEL_123", + "124": "LABEL_124", + "125": "LABEL_125", + "126": "LABEL_126", + "127": "LABEL_127", + "128": "LABEL_128", + "129": "LABEL_129", + "130": "LABEL_130", + "131": "LABEL_131", + "132": "LABEL_132", + "133": "LABEL_133", + "134": "LABEL_134", + "135": "LABEL_135", + "136": "LABEL_136", + "137": "LABEL_137", + "138": "LABEL_138", + "139": "LABEL_139", + "140": "LABEL_140", + "141": "LABEL_141", + "142": "LABEL_142", + "143": "LABEL_143", + "144": "LABEL_144", + "145": "LABEL_145", + "146": "LABEL_146", + "147": "LABEL_147", + "148": "LABEL_148", + "149": "LABEL_149", + "150": "LABEL_150", + "151": "LABEL_151", + "152": "LABEL_152", + "153": "LABEL_153", + "154": "LABEL_154", + "155": "LABEL_155", + "156": "LABEL_156", + "157": "LABEL_157", + "158": "LABEL_158", + "159": "LABEL_159", + "160": "LABEL_160", + "161": "LABEL_161", + "162": "LABEL_162", + "163": "LABEL_163", + "164": "LABEL_164", + "165": "LABEL_165", + "166": "LABEL_166", + "167": "LABEL_167", + "168": "LABEL_168", + "169": "LABEL_169", + "170": "LABEL_170", + "171": "LABEL_171", + "172": "LABEL_172", + "173": "LABEL_173", + "174": "LABEL_174", + "175": "LABEL_175", + "176": "LABEL_176", + "177": "LABEL_177", + "178": "LABEL_178", + "179": "LABEL_179", + "180": "LABEL_180", + "181": "LABEL_181", + "182": "LABEL_182", + "183": "LABEL_183", + "184": "LABEL_184", + "185": "LABEL_185", + "186": "LABEL_186", + "187": "LABEL_187", + "188": "LABEL_188", + "189": "LABEL_189", + "190": "LABEL_190", + "191": "LABEL_191", + "192": "LABEL_192", + "193": "LABEL_193", + "194": "LABEL_194", + "195": "LABEL_195", + "196": "LABEL_196", + "197": "LABEL_197", + "198": "LABEL_198", + "199": "LABEL_199", + "200": "LABEL_200", + "201": "LABEL_201", + "202": "LABEL_202", + "203": "LABEL_203", + "204": "LABEL_204", + "205": "LABEL_205", + "206": "LABEL_206", + "207": "LABEL_207", + "208": "LABEL_208", + "209": "LABEL_209", + "210": "LABEL_210", + "211": "LABEL_211", + "212": "LABEL_212", + "213": "LABEL_213", + "214": "LABEL_214", + "215": "LABEL_215", + "216": "LABEL_216", + "217": "LABEL_217", + "218": "LABEL_218", + "219": "LABEL_219", + "220": "LABEL_220", + "221": "LABEL_221", + "222": "LABEL_222", + "223": "LABEL_223", + "224": "LABEL_224", + "225": "LABEL_225", + "226": "LABEL_226", + "227": "LABEL_227", + "228": "LABEL_228", + "229": "LABEL_229", + "230": "LABEL_230", + "231": "LABEL_231", + "232": "LABEL_232", + "233": "LABEL_233", + "234": "LABEL_234", + "235": "LABEL_235", + "236": "LABEL_236", + "237": "LABEL_237", + "238": "LABEL_238", + "239": "LABEL_239", + "240": "LABEL_240", + "241": "LABEL_241", + "242": "LABEL_242", + "243": "LABEL_243", + "244": "LABEL_244", + "245": "LABEL_245", + "246": "LABEL_246", + "247": "LABEL_247", + "248": "LABEL_248", + "249": "LABEL_249", + "250": "LABEL_250", + "251": "LABEL_251", + "252": "LABEL_252", + "253": "LABEL_253", + "254": "LABEL_254", + "255": "LABEL_255", + "256": "LABEL_256", + "257": "LABEL_257", + "258": "LABEL_258", + "259": "LABEL_259", + "260": "LABEL_260", + "261": "LABEL_261", + "262": "LABEL_262", + "263": "LABEL_263", + "264": "LABEL_264", + "265": "LABEL_265", + "266": "LABEL_266", + "267": "LABEL_267", + "268": "LABEL_268", + "269": "LABEL_269", + "270": "LABEL_270", + "271": "LABEL_271", + "272": "LABEL_272", + "273": "LABEL_273", + "274": "LABEL_274", + "275": "LABEL_275", + "276": "LABEL_276", + "277": "LABEL_277", + "278": "LABEL_278", + "279": "LABEL_279", + "280": "LABEL_280", + "281": "LABEL_281", + "282": "LABEL_282", + "283": "LABEL_283", + "284": "LABEL_284", + "285": "LABEL_285", + "286": "LABEL_286", + "287": "LABEL_287", + "288": "LABEL_288", + "289": "LABEL_289", + "290": "LABEL_290", + "291": "LABEL_291", + "292": "LABEL_292", + "293": "LABEL_293", + "294": "LABEL_294", + "295": "LABEL_295", + "296": "LABEL_296", + "297": "LABEL_297", + "298": "LABEL_298", + "299": "LABEL_299", + "300": "LABEL_300", + "301": "LABEL_301", + "302": "LABEL_302", + "303": "LABEL_303", + "304": "LABEL_304", + "305": "LABEL_305", + "306": "LABEL_306", + "307": "LABEL_307", + "308": "LABEL_308", + "309": "LABEL_309", + "310": "LABEL_310", + "311": "LABEL_311", + "312": "LABEL_312", + "313": "LABEL_313", + "314": "LABEL_314", + "315": "LABEL_315", + "316": "LABEL_316", + "317": "LABEL_317", + "318": "LABEL_318", + "319": "LABEL_319", + "320": "LABEL_320", + "321": "LABEL_321", + "322": "LABEL_322", + "323": "LABEL_323", + "324": "LABEL_324", + "325": "LABEL_325", + "326": "LABEL_326", + "327": "LABEL_327", + "328": "LABEL_328", + "329": "LABEL_329", + "330": "LABEL_330", + "331": "LABEL_331", + "332": "LABEL_332", + "333": "LABEL_333", + "334": "LABEL_334", + "335": "LABEL_335", + "336": "LABEL_336", + "337": "LABEL_337", + "338": "LABEL_338", + "339": "LABEL_339", + "340": "LABEL_340", + "341": "LABEL_341", + "342": "LABEL_342", + "343": "LABEL_343", + "344": "LABEL_344", + "345": "LABEL_345", + "346": "LABEL_346", + "347": "LABEL_347", + "348": "LABEL_348", + "349": "LABEL_349", + "350": "LABEL_350", + "351": "LABEL_351", + "352": "LABEL_352", + "353": "LABEL_353", + "354": "LABEL_354", + "355": "LABEL_355", + "356": "LABEL_356", + "357": "LABEL_357", + "358": "LABEL_358", + "359": "LABEL_359", + "360": "LABEL_360", + "361": "LABEL_361", + "362": "LABEL_362", + "363": "LABEL_363", + "364": "LABEL_364", + "365": "LABEL_365", + "366": "LABEL_366", + "367": "LABEL_367", + "368": "LABEL_368", + "369": "LABEL_369", + "370": "LABEL_370", + "371": "LABEL_371", + "372": "LABEL_372", + "373": "LABEL_373", + "374": "LABEL_374", + "375": "LABEL_375", + "376": "LABEL_376", + "377": "LABEL_377", + "378": "LABEL_378", + "379": "LABEL_379", + "380": "LABEL_380", + "381": "LABEL_381", + "382": "LABEL_382", + "383": "LABEL_383", + "384": "LABEL_384", + "385": "LABEL_385", + "386": "LABEL_386", + "387": "LABEL_387", + "388": "LABEL_388", + "389": "LABEL_389", + "390": "LABEL_390" + }, + "initializer_range": 0.02, + "intermediate_size": 1536, + "label2id": { + "LABEL_0": 0, + "LABEL_1": 1, + "LABEL_10": 10, + "LABEL_100": 100, + "LABEL_101": 101, + "LABEL_102": 102, + "LABEL_103": 103, + "LABEL_104": 104, + "LABEL_105": 105, + "LABEL_106": 106, + "LABEL_107": 107, + "LABEL_108": 108, + "LABEL_109": 109, + "LABEL_11": 11, + "LABEL_110": 110, + "LABEL_111": 111, + "LABEL_112": 112, + "LABEL_113": 113, + "LABEL_114": 114, + "LABEL_115": 115, + "LABEL_116": 116, + "LABEL_117": 117, + "LABEL_118": 118, + "LABEL_119": 119, + "LABEL_12": 12, + "LABEL_120": 120, + "LABEL_121": 121, + "LABEL_122": 122, + "LABEL_123": 123, + "LABEL_124": 124, + "LABEL_125": 125, + "LABEL_126": 126, + "LABEL_127": 127, + "LABEL_128": 128, + "LABEL_129": 129, + "LABEL_13": 13, + "LABEL_130": 130, + "LABEL_131": 131, + "LABEL_132": 132, + "LABEL_133": 133, + "LABEL_134": 134, + "LABEL_135": 135, + "LABEL_136": 136, + "LABEL_137": 137, + "LABEL_138": 138, + "LABEL_139": 139, + "LABEL_14": 14, + "LABEL_140": 140, + "LABEL_141": 141, + "LABEL_142": 142, + "LABEL_143": 143, + "LABEL_144": 144, + "LABEL_145": 145, + "LABEL_146": 146, + "LABEL_147": 147, + "LABEL_148": 148, + "LABEL_149": 149, + "LABEL_15": 15, + "LABEL_150": 150, + "LABEL_151": 151, + "LABEL_152": 152, + "LABEL_153": 153, + "LABEL_154": 154, + "LABEL_155": 155, + "LABEL_156": 156, + "LABEL_157": 157, + "LABEL_158": 158, + "LABEL_159": 159, + "LABEL_16": 16, + "LABEL_160": 160, + "LABEL_161": 161, + "LABEL_162": 162, + "LABEL_163": 163, + "LABEL_164": 164, + "LABEL_165": 165, + "LABEL_166": 166, + "LABEL_167": 167, + "LABEL_168": 168, + "LABEL_169": 169, + "LABEL_17": 17, + "LABEL_170": 170, + "LABEL_171": 171, + "LABEL_172": 172, + "LABEL_173": 173, + "LABEL_174": 174, + "LABEL_175": 175, + "LABEL_176": 176, + "LABEL_177": 177, + "LABEL_178": 178, + "LABEL_179": 179, + "LABEL_18": 18, + "LABEL_180": 180, + "LABEL_181": 181, + "LABEL_182": 182, + "LABEL_183": 183, + "LABEL_184": 184, + "LABEL_185": 185, + "LABEL_186": 186, + "LABEL_187": 187, + "LABEL_188": 188, + "LABEL_189": 189, + "LABEL_19": 19, + "LABEL_190": 190, + "LABEL_191": 191, + "LABEL_192": 192, + "LABEL_193": 193, + "LABEL_194": 194, + "LABEL_195": 195, + "LABEL_196": 196, + "LABEL_197": 197, + "LABEL_198": 198, + "LABEL_199": 199, + "LABEL_2": 2, + "LABEL_20": 20, + "LABEL_200": 200, + "LABEL_201": 201, + "LABEL_202": 202, + "LABEL_203": 203, + "LABEL_204": 204, + "LABEL_205": 205, + "LABEL_206": 206, + "LABEL_207": 207, + "LABEL_208": 208, + "LABEL_209": 209, + "LABEL_21": 21, + "LABEL_210": 210, + "LABEL_211": 211, + "LABEL_212": 212, + "LABEL_213": 213, + "LABEL_214": 214, + "LABEL_215": 215, + "LABEL_216": 216, + "LABEL_217": 217, + "LABEL_218": 218, + "LABEL_219": 219, + "LABEL_22": 22, + "LABEL_220": 220, + "LABEL_221": 221, + "LABEL_222": 222, + "LABEL_223": 223, + "LABEL_224": 224, + "LABEL_225": 225, + "LABEL_226": 226, + "LABEL_227": 227, + "LABEL_228": 228, + "LABEL_229": 229, + "LABEL_23": 23, + "LABEL_230": 230, + "LABEL_231": 231, + "LABEL_232": 232, + "LABEL_233": 233, + "LABEL_234": 234, + "LABEL_235": 235, + "LABEL_236": 236, + "LABEL_237": 237, + "LABEL_238": 238, + "LABEL_239": 239, + "LABEL_24": 24, + "LABEL_240": 240, + "LABEL_241": 241, + "LABEL_242": 242, + "LABEL_243": 243, + "LABEL_244": 244, + "LABEL_245": 245, + "LABEL_246": 246, + "LABEL_247": 247, + "LABEL_248": 248, + "LABEL_249": 249, + "LABEL_25": 25, + "LABEL_250": 250, + "LABEL_251": 251, + "LABEL_252": 252, + "LABEL_253": 253, + "LABEL_254": 254, + "LABEL_255": 255, + "LABEL_256": 256, + "LABEL_257": 257, + "LABEL_258": 258, + "LABEL_259": 259, + "LABEL_26": 26, + "LABEL_260": 260, + "LABEL_261": 261, + "LABEL_262": 262, + "LABEL_263": 263, + "LABEL_264": 264, + "LABEL_265": 265, + "LABEL_266": 266, + "LABEL_267": 267, + "LABEL_268": 268, + "LABEL_269": 269, + "LABEL_27": 27, + "LABEL_270": 270, + "LABEL_271": 271, + "LABEL_272": 272, + "LABEL_273": 273, + "LABEL_274": 274, + "LABEL_275": 275, + "LABEL_276": 276, + "LABEL_277": 277, + "LABEL_278": 278, + "LABEL_279": 279, + "LABEL_28": 28, + "LABEL_280": 280, + "LABEL_281": 281, + "LABEL_282": 282, + "LABEL_283": 283, + "LABEL_284": 284, + "LABEL_285": 285, + "LABEL_286": 286, + "LABEL_287": 287, + "LABEL_288": 288, + "LABEL_289": 289, + "LABEL_29": 29, + "LABEL_290": 290, + "LABEL_291": 291, + "LABEL_292": 292, + "LABEL_293": 293, + "LABEL_294": 294, + "LABEL_295": 295, + "LABEL_296": 296, + "LABEL_297": 297, + "LABEL_298": 298, + "LABEL_299": 299, + "LABEL_3": 3, + "LABEL_30": 30, + "LABEL_300": 300, + "LABEL_301": 301, + "LABEL_302": 302, + "LABEL_303": 303, + "LABEL_304": 304, + "LABEL_305": 305, + "LABEL_306": 306, + "LABEL_307": 307, + "LABEL_308": 308, + "LABEL_309": 309, + "LABEL_31": 31, + "LABEL_310": 310, + "LABEL_311": 311, + "LABEL_312": 312, + "LABEL_313": 313, + "LABEL_314": 314, + "LABEL_315": 315, + "LABEL_316": 316, + "LABEL_317": 317, + "LABEL_318": 318, + "LABEL_319": 319, + "LABEL_32": 32, + "LABEL_320": 320, + "LABEL_321": 321, + "LABEL_322": 322, + "LABEL_323": 323, + "LABEL_324": 324, + "LABEL_325": 325, + "LABEL_326": 326, + "LABEL_327": 327, + "LABEL_328": 328, + "LABEL_329": 329, + "LABEL_33": 33, + "LABEL_330": 330, + "LABEL_331": 331, + "LABEL_332": 332, + "LABEL_333": 333, + "LABEL_334": 334, + "LABEL_335": 335, + "LABEL_336": 336, + "LABEL_337": 337, + "LABEL_338": 338, + "LABEL_339": 339, + "LABEL_34": 34, + "LABEL_340": 340, + "LABEL_341": 341, + "LABEL_342": 342, + "LABEL_343": 343, + "LABEL_344": 344, + "LABEL_345": 345, + "LABEL_346": 346, + "LABEL_347": 347, + "LABEL_348": 348, + "LABEL_349": 349, + "LABEL_35": 35, + "LABEL_350": 350, + "LABEL_351": 351, + "LABEL_352": 352, + "LABEL_353": 353, + "LABEL_354": 354, + "LABEL_355": 355, + "LABEL_356": 356, + "LABEL_357": 357, + "LABEL_358": 358, + "LABEL_359": 359, + "LABEL_36": 36, + "LABEL_360": 360, + "LABEL_361": 361, + "LABEL_362": 362, + "LABEL_363": 363, + "LABEL_364": 364, + "LABEL_365": 365, + "LABEL_366": 366, + "LABEL_367": 367, + "LABEL_368": 368, + "LABEL_369": 369, + "LABEL_37": 37, + "LABEL_370": 370, + "LABEL_371": 371, + "LABEL_372": 372, + "LABEL_373": 373, + "LABEL_374": 374, + "LABEL_375": 375, + "LABEL_376": 376, + "LABEL_377": 377, + "LABEL_378": 378, + "LABEL_379": 379, + "LABEL_38": 38, + "LABEL_380": 380, + "LABEL_381": 381, + "LABEL_382": 382, + "LABEL_383": 383, + "LABEL_384": 384, + "LABEL_385": 385, + "LABEL_386": 386, + "LABEL_387": 387, + "LABEL_388": 388, + "LABEL_389": 389, + "LABEL_39": 39, + "LABEL_390": 390, + "LABEL_4": 4, + "LABEL_40": 40, + "LABEL_41": 41, + "LABEL_42": 42, + "LABEL_43": 43, + "LABEL_44": 44, + "LABEL_45": 45, + "LABEL_46": 46, + "LABEL_47": 47, + "LABEL_48": 48, + "LABEL_49": 49, + "LABEL_5": 5, + "LABEL_50": 50, + "LABEL_51": 51, + "LABEL_52": 52, + "LABEL_53": 53, + "LABEL_54": 54, + "LABEL_55": 55, + "LABEL_56": 56, + "LABEL_57": 57, + "LABEL_58": 58, + "LABEL_59": 59, + "LABEL_6": 6, + "LABEL_60": 60, + "LABEL_61": 61, + "LABEL_62": 62, + "LABEL_63": 63, + "LABEL_64": 64, + "LABEL_65": 65, + "LABEL_66": 66, + "LABEL_67": 67, + "LABEL_68": 68, + "LABEL_69": 69, + "LABEL_7": 7, + "LABEL_70": 70, + "LABEL_71": 71, + "LABEL_72": 72, + "LABEL_73": 73, + "LABEL_74": 74, + "LABEL_75": 75, + "LABEL_76": 76, + "LABEL_77": 77, + "LABEL_78": 78, + "LABEL_79": 79, + "LABEL_8": 8, + "LABEL_80": 80, + "LABEL_81": 81, + "LABEL_82": 82, + "LABEL_83": 83, + "LABEL_84": 84, + "LABEL_85": 85, + "LABEL_86": 86, + "LABEL_87": 87, + "LABEL_88": 88, + "LABEL_89": 89, + "LABEL_9": 9, + "LABEL_90": 90, + "LABEL_91": 91, + "LABEL_92": 92, + "LABEL_93": 93, + "LABEL_94": 94, + "LABEL_95": 95, + "LABEL_96": 96, + "LABEL_97": 97, + "LABEL_98": 98, + "LABEL_99": 99 + }, + "layer_norm_eps": 1e-12, + "max_position_embeddings": 512, + "model_type": "bert", + "num_attention_heads": 12, + "num_hidden_layers": 6, + "num_relation_heads": 32, + "pad_token_id": 0, + "pooler_fc_size": 768, + "pooler_num_attention_heads": 12, + "pooler_num_fc_layers": 3, + "pooler_size_per_head": 128, + "pooler_type": "first_token_transform", + "position_embedding_type": "absolute", + "torch_dtype": "float32", + "transformers_version": "4.44.1", + "type_vocab_size": 2, + "use_cache": true, + "vocab_size": 21128 +} diff --git a/diffrhythm/g2p/sources/g2p_chinese_model/poly_bert_model.onnx b/diffrhythm/g2p/sources/g2p_chinese_model/poly_bert_model.onnx new file mode 100644 index 0000000000000000000000000000000000000000..6b952b9717eb71bb5a7aa2492478095f117858dd --- /dev/null +++ b/diffrhythm/g2p/sources/g2p_chinese_model/poly_bert_model.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8765d835ffdf9811c832d4dc7b6a552757aa8615c01d1184db716a50c20aebbc +size 76583333 diff --git a/diffrhythm/g2p/sources/g2p_chinese_model/polychar.txt b/diffrhythm/g2p/sources/g2p_chinese_model/polychar.txt new file mode 100644 index 0000000000000000000000000000000000000000..819f6249a661134128c7a4bc72a1059ebe133d20 --- /dev/null +++ b/diffrhythm/g2p/sources/g2p_chinese_model/polychar.txt @@ -0,0 +1,159 @@ +丧 +中 +为 +乌 +乐 +了 +什 +仔 +令 +任 +会 +传 +佛 +供 +便 +倒 +假 +兴 +冠 +冲 +几 +分 +切 +划 +创 +剥 +勒 +区 +华 +单 +卜 +占 +卡 +卷 +厦 +参 +发 +只 +号 +同 +吐 +和 +喝 +圈 +地 +塞 +壳 +处 +奇 +奔 +好 +宁 +宿 +将 +少 +尽 +岗 +差 +巷 +帖 +干 +应 +度 +弹 +强 +当 +待 +得 +恶 +扁 +扇 +扎 +扫 +担 +挑 +据 +撒 +教 +散 +数 +斗 +晃 +曝 +曲 +更 +曾 +朝 +朴 +杆 +查 +校 +模 +横 +没 +泡 +济 +混 +漂 +炸 +熟 +燕 +片 +率 +畜 +的 +盛 +相 +省 +看 +着 +矫 +禁 +种 +称 +空 +答 +粘 +糊 +系 +累 +纤 +结 +给 +缝 +肖 +背 +脏 +舍 +色 +落 +蒙 +薄 +藏 +血 +行 +要 +观 +觉 +角 +解 +说 +调 +踏 +车 +转 +载 +还 +遂 +都 +重 +量 +钻 +铺 +长 +间 +降 +难 +露 +鲜 diff --git a/diffrhythm/g2p/sources/g2p_chinese_model/polydict.json b/diffrhythm/g2p/sources/g2p_chinese_model/polydict.json new file mode 100644 index 0000000000000000000000000000000000000000..903fd018067b185c8cb8cd8a5b6cf07822512989 --- /dev/null +++ b/diffrhythm/g2p/sources/g2p_chinese_model/polydict.json @@ -0,0 +1,393 @@ +{ + "1": "丧{sang1}", + "2": "丧{sang4}", + "3": "中{zhong1}", + "4": "中{zhong4}", + "5": "为{wei2}", + "6": "为{wei4}", + "7": "乌{wu1}", + "8": "乌{wu4}", + "9": "乐{lao4}", + "10": "乐{le4}", + "11": "乐{le5}", + "12": "乐{yao4}", + "13": "乐{yve4}", + "14": "了{le5}", + "15": "了{liao3}", + "16": "了{liao5}", + "17": "什{shen2}", + "18": "什{shi2}", + "19": "仔{zai3}", + "20": "仔{zai5}", + "21": "仔{zi3}", + "22": "仔{zi5}", + "23": "令{ling2}", + "24": "令{ling4}", + "25": "任{ren2}", + "26": "任{ren4}", + "27": "会{hui4}", + "28": "会{hui5}", + "29": "会{kuai4}", + "30": "传{chuan2}", + "31": "传{zhuan4}", + "32": "佛{fo2}", + "33": "佛{fu2}", + "34": "供{gong1}", + "35": "供{gong4}", + "36": "便{bian4}", + "37": "便{pian2}", + "38": "倒{dao3}", + "39": "倒{dao4}", + "40": "假{jia3}", + "41": "假{jia4}", + "42": "兴{xing1}", + "43": "兴{xing4}", + "44": "冠{guan1}", + "45": "冠{guan4}", + "46": "冲{chong1}", + "47": "冲{chong4}", + "48": "几{ji1}", + "49": "几{ji2}", + "50": "几{ji3}", + "51": "分{fen1}", + "52": "分{fen4}", + "53": "分{fen5}", + "54": "切{qie1}", + "55": "切{qie4}", + "56": "划{hua2}", + "57": "划{hua4}", + "58": "划{hua5}", + "59": "创{chuang1}", + "60": "创{chuang4}", + "61": "剥{bao1}", + "62": "剥{bo1}", + "63": "勒{le4}", + "64": "勒{le5}", + "65": "勒{lei1}", + "66": "区{ou1}", + "67": "区{qu1}", + "68": "华{hua2}", + "69": "华{hua4}", + "70": "单{chan2}", + "71": "单{dan1}", + "72": "单{shan4}", + "73": "卜{bo5}", + "74": "卜{bu3}", + "75": "占{zhan1}", + "76": "占{zhan4}", + "77": "卡{ka2}", + "78": "卡{ka3}", + "79": "卡{qia3}", + "80": "卷{jvan3}", + "81": "卷{jvan4}", + "82": "厦{sha4}", + "83": "厦{xia4}", + "84": "参{can1}", + "85": "参{cen1}", + "86": "参{shen1}", + "87": "发{fa1}", + "88": "发{fa4}", + "89": "发{fa5}", + "90": "只{zhi1}", + "91": "只{zhi3}", + "92": "号{hao2}", + "93": "号{hao4}", + "94": "号{hao5}", + "95": "同{tong2}", + "96": "同{tong4}", + "97": "同{tong5}", + "98": "吐{tu2}", + "99": "吐{tu3}", + "100": "吐{tu4}", + "101": "和{he2}", + "102": "和{he4}", + "103": "和{he5}", + "104": "和{huo2}", + "105": "和{huo4}", + "106": "和{huo5}", + "107": "喝{he1}", + "108": "喝{he4}", + "109": "圈{jvan4}", + "110": "圈{qvan1}", + "111": "圈{qvan5}", + "112": "地{de5}", + "113": "地{di4}", + "114": "地{di5}", + "115": "塞{sai1}", + "116": "塞{sai2}", + "117": "塞{sai4}", + "118": "塞{se4}", + "119": "壳{ke2}", + "120": "壳{qiao4}", + "121": "处{chu3}", + "122": "处{chu4}", + "123": "奇{ji1}", + "124": "奇{qi2}", + "125": "奔{ben1}", + "126": "奔{ben4}", + "127": "好{hao3}", + "128": "好{hao4}", + "129": "好{hao5}", + "130": "宁{ning2}", + "131": "宁{ning4}", + "132": "宁{ning5}", + "133": "宿{su4}", + "134": "宿{xiu3}", + "135": "宿{xiu4}", + "136": "将{jiang1}", + "137": "将{jiang4}", + "138": "少{shao3}", + "139": "少{shao4}", + "140": "尽{jin3}", + "141": "尽{jin4}", + "142": "岗{gang1}", + "143": "岗{gang3}", + "144": "差{cha1}", + "145": "差{cha4}", + "146": "差{chai1}", + "147": "差{ci1}", + "148": "巷{hang4}", + "149": "巷{xiang4}", + "150": "帖{tie1}", + "151": "帖{tie3}", + "152": "帖{tie4}", + "153": "干{gan1}", + "154": "干{gan4}", + "155": "应{ying1}", + "156": "应{ying4}", + "157": "应{ying5}", + "158": "度{du4}", + "159": "度{du5}", + "160": "度{duo2}", + "161": "弹{dan4}", + "162": "弹{tan2}", + "163": "弹{tan5}", + "164": "强{jiang4}", + "165": "强{qiang2}", + "166": "强{qiang3}", + "167": "当{dang1}", + "168": "当{dang4}", + "169": "当{dang5}", + "170": "待{dai1}", + "171": "待{dai4}", + "172": "得{de2}", + "173": "得{de5}", + "174": "得{dei3}", + "175": "得{dei5}", + "176": "恶{e3}", + "177": "恶{e4}", + "178": "恶{wu4}", + "179": "扁{bian3}", + "180": "扁{pian1}", + "181": "扇{shan1}", + "182": "扇{shan4}", + "183": "扎{za1}", + "184": "扎{zha1}", + "185": "扎{zha2}", + "186": "扫{sao3}", + "187": "扫{sao4}", + "188": "担{dan1}", + "189": "担{dan4}", + "190": "担{dan5}", + "191": "挑{tiao1}", + "192": "挑{tiao3}", + "193": "据{jv1}", + "194": "据{jv4}", + "195": "撒{sa1}", + "196": "撒{sa3}", + "197": "撒{sa5}", + "198": "教{jiao1}", + "199": "教{jiao4}", + "200": "散{san3}", + "201": "散{san4}", + "202": "散{san5}", + "203": "数{shu3}", + "204": "数{shu4}", + "205": "数{shu5}", + "206": "斗{dou3}", + "207": "斗{dou4}", + "208": "晃{huang3}", + "209": "曝{bao4}", + "210": "曲{qu1}", + "211": "曲{qu3}", + "212": "更{geng1}", + "213": "更{geng4}", + "214": "曾{ceng1}", + "215": "曾{ceng2}", + "216": "曾{zeng1}", + "217": "朝{chao2}", + "218": "朝{zhao1}", + "219": "朴{piao2}", + "220": "朴{pu2}", + "221": "朴{pu3}", + "222": "杆{gan1}", + "223": "杆{gan3}", + "224": "查{cha2}", + "225": "查{zha1}", + "226": "校{jiao4}", + "227": "校{xiao4}", + "228": "模{mo2}", + "229": "模{mu2}", + "230": "横{heng2}", + "231": "横{heng4}", + "232": "没{mei2}", + "233": "没{mo4}", + "234": "泡{pao1}", + "235": "泡{pao4}", + "236": "泡{pao5}", + "237": "济{ji3}", + "238": "济{ji4}", + "239": "混{hun2}", + "240": "混{hun3}", + "241": "混{hun4}", + "242": "混{hun5}", + "243": "漂{piao1}", + "244": "漂{piao3}", + "245": "漂{piao4}", + "246": "炸{zha2}", + "247": "炸{zha4}", + "248": "熟{shou2}", + "249": "熟{shu2}", + "250": "燕{yan1}", + "251": "燕{yan4}", + "252": "片{pian1}", + "253": "片{pian4}", + "254": "率{lv4}", + "255": "率{shuai4}", + "256": "畜{chu4}", + "257": "畜{xu4}", + "258": "的{de5}", + "259": "的{di1}", + "260": "的{di2}", + "261": "的{di4}", + "262": "的{di5}", + "263": "盛{cheng2}", + "264": "盛{sheng4}", + "265": "相{xiang1}", + "266": "相{xiang4}", + "267": "相{xiang5}", + "268": "省{sheng3}", + "269": "省{xing3}", + "270": "看{kan1}", + "271": "看{kan4}", + "272": "看{kan5}", + "273": "着{zhao1}", + "274": "着{zhao2}", + "275": "着{zhao5}", + "276": "着{zhe5}", + "277": "着{zhuo2}", + "278": "着{zhuo5}", + "279": "矫{jiao3}", + "280": "禁{jin1}", + "281": "禁{jin4}", + "282": "种{zhong3}", + "283": "种{zhong4}", + "284": "称{chen4}", + "285": "称{cheng1}", + "286": "空{kong1}", + "287": "空{kong4}", + "288": "答{da1}", + "289": "答{da2}", + "290": "粘{nian2}", + "291": "粘{zhan1}", + "292": "糊{hu2}", + "293": "糊{hu5}", + "294": "系{ji4}", + "295": "系{xi4}", + "296": "系{xi5}", + "297": "累{lei2}", + "298": "累{lei3}", + "299": "累{lei4}", + "300": "累{lei5}", + "301": "纤{qian4}", + "302": "纤{xian1}", + "303": "结{jie1}", + "304": "结{jie2}", + "305": "结{jie5}", + "306": "给{gei3}", + "307": "给{gei5}", + "308": "给{ji3}", + "309": "缝{feng2}", + "310": "缝{feng4}", + "311": "缝{feng5}", + "312": "肖{xiao1}", + "313": "肖{xiao4}", + "314": "背{bei1}", + "315": "背{bei4}", + "316": "脏{zang1}", + "317": "脏{zang4}", + "318": "舍{she3}", + "319": "舍{she4}", + "320": "色{se4}", + "321": "色{shai3}", + "322": "落{lao4}", + "323": "落{luo4}", + "324": "蒙{meng1}", + "325": "蒙{meng2}", + "326": "蒙{meng3}", + "327": "薄{bao2}", + "328": "薄{bo2}", + "329": "薄{bo4}", + "330": "藏{cang2}", + "331": "藏{zang4}", + "332": "血{xie3}", + "333": "血{xue4}", + "334": "行{hang2}", + "335": "行{hang5}", + "336": "行{heng5}", + "337": "行{xing2}", + "338": "行{xing4}", + "339": "要{yao1}", + "340": "要{yao4}", + "341": "观{guan1}", + "342": "观{guan4}", + "343": "觉{jiao4}", + "344": "觉{jiao5}", + "345": "觉{jve2}", + "346": "角{jiao3}", + "347": "角{jve2}", + "348": "解{jie3}", + "349": "解{jie4}", + "350": "解{xie4}", + "351": "说{shui4}", + "352": "说{shuo1}", + "353": "调{diao4}", + "354": "调{tiao2}", + "355": "踏{ta1}", + "356": "踏{ta4}", + "357": "车{che1}", + "358": "车{jv1}", + "359": "转{zhuan3}", + "360": "转{zhuan4}", + "361": "载{zai3}", + "362": "载{zai4}", + "363": "还{hai2}", + "364": "还{huan2}", + "365": "遂{sui2}", + "366": "遂{sui4}", + "367": "都{dou1}", + "368": "都{du1}", + "369": "重{chong2}", + "370": "重{zhong4}", + "371": "量{liang2}", + "372": "量{liang4}", + "373": "量{liang5}", + "374": "钻{zuan1}", + "375": "钻{zuan4}", + "376": "铺{pu1}", + "377": "铺{pu4}", + "378": "长{chang2}", + "379": "长{chang3}", + "380": "长{zhang3}", + "381": "间{jian1}", + "382": "间{jian4}", + "383": "降{jiang4}", + "384": "降{xiang2}", + "385": "难{nan2}", + "386": "难{nan4}", + "387": "难{nan5}", + "388": "露{lou4}", + "389": "露{lu4}", + "390": "鲜{xian1}", + "391": "鲜{xian3}" +} \ No newline at end of file diff --git a/diffrhythm/g2p/sources/g2p_chinese_model/polydict_r.json b/diffrhythm/g2p/sources/g2p_chinese_model/polydict_r.json new file mode 100644 index 0000000000000000000000000000000000000000..aabbe6257493eaee7d3f0b77f78f0cb006e89fb6 --- /dev/null +++ b/diffrhythm/g2p/sources/g2p_chinese_model/polydict_r.json @@ -0,0 +1,393 @@ +{ + "丧{sang1}": 1, + "丧{sang4}": 2, + "中{zhong1}": 3, + "中{zhong4}": 4, + "为{wei2}": 5, + "为{wei4}": 6, + "乌{wu1}": 7, + "乌{wu4}": 8, + "乐{lao4}": 9, + "乐{le4}": 10, + "乐{le5}": 11, + "乐{yao4}": 12, + "乐{yve4}": 13, + "了{le5}": 14, + "了{liao3}": 15, + "了{liao5}": 16, + "什{shen2}": 17, + "什{shi2}": 18, + "仔{zai3}": 19, + "仔{zai5}": 20, + "仔{zi3}": 21, + "仔{zi5}": 22, + "令{ling2}": 23, + "令{ling4}": 24, + "任{ren2}": 25, + "任{ren4}": 26, + "会{hui4}": 27, + "会{hui5}": 28, + "会{kuai4}": 29, + "传{chuan2}": 30, + "传{zhuan4}": 31, + "佛{fo2}": 32, + "佛{fu2}": 33, + "供{gong1}": 34, + "供{gong4}": 35, + "便{bian4}": 36, + "便{pian2}": 37, + "倒{dao3}": 38, + "倒{dao4}": 39, + "假{jia3}": 40, + "假{jia4}": 41, + "兴{xing1}": 42, + "兴{xing4}": 43, + "冠{guan1}": 44, + "冠{guan4}": 45, + "冲{chong1}": 46, + "冲{chong4}": 47, + "几{ji1}": 48, + "几{ji2}": 49, + "几{ji3}": 50, + "分{fen1}": 51, + "分{fen4}": 52, + "分{fen5}": 53, + "切{qie1}": 54, + "切{qie4}": 55, + "划{hua2}": 56, + "划{hua4}": 57, + "划{hua5}": 58, + "创{chuang1}": 59, + "创{chuang4}": 60, + "剥{bao1}": 61, + "剥{bo1}": 62, + "勒{le4}": 63, + "勒{le5}": 64, + "勒{lei1}": 65, + "区{ou1}": 66, + "区{qu1}": 67, + "华{hua2}": 68, + "华{hua4}": 69, + "单{chan2}": 70, + "单{dan1}": 71, + "单{shan4}": 72, + "卜{bo5}": 73, + "卜{bu3}": 74, + "占{zhan1}": 75, + "占{zhan4}": 76, + "卡{ka2}": 77, + "卡{ka3}": 78, + "卡{qia3}": 79, + "卷{jvan3}": 80, + "卷{jvan4}": 81, + "厦{sha4}": 82, + "厦{xia4}": 83, + "参{can1}": 84, + "参{cen1}": 85, + "参{shen1}": 86, + "发{fa1}": 87, + "发{fa4}": 88, + "发{fa5}": 89, + "只{zhi1}": 90, + "只{zhi3}": 91, + "号{hao2}": 92, + "号{hao4}": 93, + "号{hao5}": 94, + "同{tong2}": 95, + "同{tong4}": 96, + "同{tong5}": 97, + "吐{tu2}": 98, + "吐{tu3}": 99, + "吐{tu4}": 100, + "和{he2}": 101, + "和{he4}": 102, + "和{he5}": 103, + "和{huo2}": 104, + "和{huo4}": 105, + "和{huo5}": 106, + "喝{he1}": 107, + "喝{he4}": 108, + "圈{jvan4}": 109, + "圈{qvan1}": 110, + "圈{qvan5}": 111, + "地{de5}": 112, + "地{di4}": 113, + "地{di5}": 114, + "塞{sai1}": 115, + "塞{sai2}": 116, + "塞{sai4}": 117, + "塞{se4}": 118, + "壳{ke2}": 119, + "壳{qiao4}": 120, + "处{chu3}": 121, + "处{chu4}": 122, + "奇{ji1}": 123, + "奇{qi2}": 124, + "奔{ben1}": 125, + "奔{ben4}": 126, + "好{hao3}": 127, + "好{hao4}": 128, + "好{hao5}": 129, + "宁{ning2}": 130, + "宁{ning4}": 131, + "宁{ning5}": 132, + "宿{su4}": 133, + "宿{xiu3}": 134, + "宿{xiu4}": 135, + "将{jiang1}": 136, + "将{jiang4}": 137, + "少{shao3}": 138, + "少{shao4}": 139, + "尽{jin3}": 140, + "尽{jin4}": 141, + "岗{gang1}": 142, + "岗{gang3}": 143, + "差{cha1}": 144, + "差{cha4}": 145, + "差{chai1}": 146, + "差{ci1}": 147, + "巷{hang4}": 148, + "巷{xiang4}": 149, + "帖{tie1}": 150, + "帖{tie3}": 151, + "帖{tie4}": 152, + "干{gan1}": 153, + "干{gan4}": 154, + "应{ying1}": 155, + "应{ying4}": 156, + "应{ying5}": 157, + "度{du4}": 158, + "度{du5}": 159, + "度{duo2}": 160, + "弹{dan4}": 161, + "弹{tan2}": 162, + "弹{tan5}": 163, + "强{jiang4}": 164, + "强{qiang2}": 165, + "强{qiang3}": 166, + "当{dang1}": 167, + "当{dang4}": 168, + "当{dang5}": 169, + "待{dai1}": 170, + "待{dai4}": 171, + "得{de2}": 172, + "得{de5}": 173, + "得{dei3}": 174, + "得{dei5}": 175, + "恶{e3}": 176, + "恶{e4}": 177, + "恶{wu4}": 178, + "扁{bian3}": 179, + "扁{pian1}": 180, + "扇{shan1}": 181, + "扇{shan4}": 182, + "扎{za1}": 183, + "扎{zha1}": 184, + "扎{zha2}": 185, + "扫{sao3}": 186, + "扫{sao4}": 187, + "担{dan1}": 188, + "担{dan4}": 189, + "担{dan5}": 190, + "挑{tiao1}": 191, + "挑{tiao3}": 192, + "据{jv1}": 193, + "据{jv4}": 194, + "撒{sa1}": 195, + "撒{sa3}": 196, + "撒{sa5}": 197, + "教{jiao1}": 198, + "教{jiao4}": 199, + "散{san3}": 200, + "散{san4}": 201, + "散{san5}": 202, + "数{shu3}": 203, + "数{shu4}": 204, + "数{shu5}": 205, + "斗{dou3}": 206, + "斗{dou4}": 207, + "晃{huang3}": 208, + "曝{bao4}": 209, + "曲{qu1}": 210, + "曲{qu3}": 211, + "更{geng1}": 212, + "更{geng4}": 213, + "曾{ceng1}": 214, + "曾{ceng2}": 215, + "曾{zeng1}": 216, + "朝{chao2}": 217, + "朝{zhao1}": 218, + "朴{piao2}": 219, + "朴{pu2}": 220, + "朴{pu3}": 221, + "杆{gan1}": 222, + "杆{gan3}": 223, + "查{cha2}": 224, + "查{zha1}": 225, + "校{jiao4}": 226, + "校{xiao4}": 227, + "模{mo2}": 228, + "模{mu2}": 229, + "横{heng2}": 230, + "横{heng4}": 231, + "没{mei2}": 232, + "没{mo4}": 233, + "泡{pao1}": 234, + "泡{pao4}": 235, + "泡{pao5}": 236, + "济{ji3}": 237, + "济{ji4}": 238, + "混{hun2}": 239, + "混{hun3}": 240, + "混{hun4}": 241, + "混{hun5}": 242, + "漂{piao1}": 243, + "漂{piao3}": 244, + "漂{piao4}": 245, + "炸{zha2}": 246, + "炸{zha4}": 247, + "熟{shou2}": 248, + "熟{shu2}": 249, + "燕{yan1}": 250, + "燕{yan4}": 251, + "片{pian1}": 252, + "片{pian4}": 253, + "率{lv4}": 254, + "率{shuai4}": 255, + "畜{chu4}": 256, + "畜{xu4}": 257, + "的{de5}": 258, + "的{di1}": 259, + "的{di2}": 260, + "的{di4}": 261, + "的{di5}": 262, + "盛{cheng2}": 263, + "盛{sheng4}": 264, + "相{xiang1}": 265, + "相{xiang4}": 266, + "相{xiang5}": 267, + "省{sheng3}": 268, + "省{xing3}": 269, + "看{kan1}": 270, + "看{kan4}": 271, + "看{kan5}": 272, + "着{zhao1}": 273, + "着{zhao2}": 274, + "着{zhao5}": 275, + "着{zhe5}": 276, + "着{zhuo2}": 277, + "着{zhuo5}": 278, + "矫{jiao3}": 279, + "禁{jin1}": 280, + "禁{jin4}": 281, + "种{zhong3}": 282, + "种{zhong4}": 283, + "称{chen4}": 284, + "称{cheng1}": 285, + "空{kong1}": 286, + "空{kong4}": 287, + "答{da1}": 288, + "答{da2}": 289, + "粘{nian2}": 290, + "粘{zhan1}": 291, + "糊{hu2}": 292, + "糊{hu5}": 293, + "系{ji4}": 294, + "系{xi4}": 295, + "系{xi5}": 296, + "累{lei2}": 297, + "累{lei3}": 298, + "累{lei4}": 299, + "累{lei5}": 300, + "纤{qian4}": 301, + "纤{xian1}": 302, + "结{jie1}": 303, + "结{jie2}": 304, + "结{jie5}": 305, + "给{gei3}": 306, + "给{gei5}": 307, + "给{ji3}": 308, + "缝{feng2}": 309, + "缝{feng4}": 310, + "缝{feng5}": 311, + "肖{xiao1}": 312, + "肖{xiao4}": 313, + "背{bei1}": 314, + "背{bei4}": 315, + "脏{zang1}": 316, + "脏{zang4}": 317, + "舍{she3}": 318, + "舍{she4}": 319, + "色{se4}": 320, + "色{shai3}": 321, + "落{lao4}": 322, + "落{luo4}": 323, + "蒙{meng1}": 324, + "蒙{meng2}": 325, + "蒙{meng3}": 326, + "薄{bao2}": 327, + "薄{bo2}": 328, + "薄{bo4}": 329, + "藏{cang2}": 330, + "藏{zang4}": 331, + "血{xie3}": 332, + "血{xue4}": 333, + "行{hang2}": 334, + "行{hang5}": 335, + "行{heng5}": 336, + "行{xing2}": 337, + "行{xing4}": 338, + "要{yao1}": 339, + "要{yao4}": 340, + "观{guan1}": 341, + "观{guan4}": 342, + "觉{jiao4}": 343, + "觉{jiao5}": 344, + "觉{jve2}": 345, + "角{jiao3}": 346, + "角{jve2}": 347, + "解{jie3}": 348, + "解{jie4}": 349, + "解{xie4}": 350, + "说{shui4}": 351, + "说{shuo1}": 352, + "调{diao4}": 353, + "调{tiao2}": 354, + "踏{ta1}": 355, + "踏{ta4}": 356, + "车{che1}": 357, + "车{jv1}": 358, + "转{zhuan3}": 359, + "转{zhuan4}": 360, + "载{zai3}": 361, + "载{zai4}": 362, + "还{hai2}": 363, + "还{huan2}": 364, + "遂{sui2}": 365, + "遂{sui4}": 366, + "都{dou1}": 367, + "都{du1}": 368, + "重{chong2}": 369, + "重{zhong4}": 370, + "量{liang2}": 371, + "量{liang4}": 372, + "量{liang5}": 373, + "钻{zuan1}": 374, + "钻{zuan4}": 375, + "铺{pu1}": 376, + "铺{pu4}": 377, + "长{chang2}": 378, + "长{chang3}": 379, + "长{zhang3}": 380, + "间{jian1}": 381, + "间{jian4}": 382, + "降{jiang4}": 383, + "降{xiang2}": 384, + "难{nan2}": 385, + "难{nan4}": 386, + "难{nan5}": 387, + "露{lou4}": 388, + "露{lu4}": 389, + "鲜{xian1}": 390, + "鲜{xian3}": 391 +} \ No newline at end of file diff --git a/diffrhythm/g2p/sources/g2p_chinese_model/vocab.txt b/diffrhythm/g2p/sources/g2p_chinese_model/vocab.txt new file mode 100644 index 0000000000000000000000000000000000000000..ca4f9781030019ab9b253c6dcb8c7878b6dc87a5 --- /dev/null +++ b/diffrhythm/g2p/sources/g2p_chinese_model/vocab.txt @@ -0,0 +1,21128 @@ +[PAD] +[unused1] +[unused2] +[unused3] +[unused4] +[unused5] +[unused6] +[unused7] +[unused8] +[unused9] +[unused10] +[unused11] +[unused12] +[unused13] +[unused14] +[unused15] +[unused16] +[unused17] +[unused18] +[unused19] +[unused20] +[unused21] +[unused22] +[unused23] +[unused24] +[unused25] +[unused26] +[unused27] +[unused28] +[unused29] +[unused30] +[unused31] +[unused32] +[unused33] +[unused34] +[unused35] +[unused36] +[unused37] +[unused38] +[unused39] +[unused40] +[unused41] +[unused42] +[unused43] +[unused44] +[unused45] +[unused46] +[unused47] +[unused48] +[unused49] +[unused50] +[unused51] +[unused52] +[unused53] +[unused54] +[unused55] +[unused56] +[unused57] +[unused58] +[unused59] +[unused60] +[unused61] +[unused62] +[unused63] +[unused64] +[unused65] +[unused66] +[unused67] +[unused68] +[unused69] +[unused70] +[unused71] +[unused72] +[unused73] +[unused74] +[unused75] +[unused76] +[unused77] +[unused78] +[unused79] +[unused80] +[unused81] +[unused82] +[unused83] +[unused84] +[unused85] +[unused86] +[unused87] +[unused88] +[unused89] +[unused90] +[unused91] +[unused92] +[unused93] +[unused94] +[unused95] +[unused96] +[unused97] +[unused98] +[unused99] +[UNK] +[CLS] +[SEP] +[MASK] + + +! +" +# +$ +% +& +' +( +) +* ++ +, +- +. +/ +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +: +; +< += +> +? +@ +[ +\ +] +^ +_ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z +{ +| +} +~ +£ +¤ +¥ +§ +© +« +® +° +± +² +³ +µ +· +¹ +º +» +¼ +× +ß +æ +÷ +ø +đ +ŋ +ɔ +ə +ɡ +ʰ +ˇ +ˈ +ˊ +ˋ +ˍ +ː +˙ +˚ +ˢ +α +β +γ +δ +ε +η +θ +ι +κ +λ +μ +ν +ο +π +ρ +ς +σ +τ +υ +φ +χ +ψ +ω +а +б +в +г +д +е +ж +з +и +к +л +м +н +о +п +р +с +т +у +ф +х +ц +ч +ш +ы +ь +я +і +ا +ب +ة +ت +د +ر +س +ع +ل +م +ن +ه +و +ي +۩ +ก +ง +น +ม +ย +ร +อ +า +เ +๑ +་ +ღ +ᄀ +ᄁ +ᄂ +ᄃ +ᄅ +ᄆ +ᄇ +ᄈ +ᄉ +ᄋ +ᄌ +ᄎ +ᄏ +ᄐ +ᄑ +ᄒ +ᅡ +ᅢ +ᅣ +ᅥ +ᅦ +ᅧ +ᅨ +ᅩ +ᅪ +ᅬ +ᅭ +ᅮ +ᅯ +ᅲ +ᅳ +ᅴ +ᅵ +ᆨ +ᆫ +ᆯ +ᆷ +ᆸ +ᆺ +ᆻ +ᆼ +ᗜ +ᵃ +ᵉ +ᵍ +ᵏ +ᵐ +ᵒ +ᵘ +‖ +„ +† +• +‥ +‧ +
 +‰ +′ +″ +‹ +› +※ +‿ +⁄ +ⁱ +⁺ +ⁿ +₁ +₂ +₃ +₄ +€ +℃ +№ +™ +ⅰ +ⅱ +ⅲ +ⅳ +ⅴ +← +↑ +→ +↓ +↔ +↗ +↘ +⇒ +∀ +− +∕ +∙ +√ +∞ +∟ +∠ +∣ +∥ +∩ +∮ +∶ +∼ +∽ +≈ +≒ +≡ +≤ +≥ +≦ +≧ +≪ +≫ +⊙ +⋅ +⋈ +⋯ +⌒ +① +② +③ +④ +⑤ +⑥ +⑦ +⑧ +⑨ +⑩ +⑴ +⑵ +⑶ +⑷ +⑸ +⒈ +⒉ +⒊ +⒋ +ⓒ +ⓔ +ⓘ +─ +━ +│ +┃ +┅ +┆ +┊ +┌ +└ +├ +┣ +═ +║ +╚ +╞ +╠ +╭ +╮ +╯ +╰ +╱ +╳ +▂ +▃ +▅ +▇ +█ +▉ +▋ +▌ +▍ +▎ +■ +□ +▪ +▫ +▬ +▲ +△ +▶ +► +▼ +▽ +◆ +◇ +○ +◎ +● +◕ +◠ +◢ +◤ +☀ +★ +☆ +☕ +☞ +☺ +☼ +♀ +♂ +♠ +♡ +♣ +♥ +♦ +♪ +♫ +♬ +✈ +✔ +✕ +✖ +✦ +✨ +✪ +✰ +✿ +❀ +❤ +➜ +➤ +⦿ +、 +。 +〃 +々 +〇 +〈 +〉 +《 +》 +「 +」 +『 +』 +【 +】 +〓 +〔 +〕 +〖 +〗 +〜 +〝 +〞 +ぁ +あ +ぃ +い +う +ぇ +え +お +か +き +く +け +こ +さ +し +す +せ +そ +た +ち +っ +つ +て +と +な +に +ぬ +ね +の +は +ひ +ふ +へ +ほ +ま +み +む +め +も +ゃ +や +ゅ +ゆ +ょ +よ +ら +り +る +れ +ろ +わ +を +ん +゜ +ゝ +ァ +ア +ィ +イ +ゥ +ウ +ェ +エ +ォ +オ +カ +キ +ク +ケ +コ +サ +シ +ス +セ +ソ +タ +チ +ッ +ツ +テ +ト +ナ +ニ +ヌ +ネ +ノ +ハ +ヒ +フ +ヘ +ホ +マ +ミ +ム +メ +モ +ャ +ヤ +ュ +ユ +ョ +ヨ +ラ +リ +ル +レ +ロ +ワ +ヲ +ン +ヶ +・ +ー +ヽ +ㄅ +ㄆ +ㄇ +ㄉ +ㄋ +ㄌ +ㄍ +ㄎ +ㄏ +ㄒ +ㄚ +ㄛ +ㄞ +ㄟ +ㄢ +ㄤ +ㄥ +ㄧ +ㄨ +ㆍ +㈦ +㊣ +㎡ +㗎 +一 +丁 +七 +万 +丈 +三 +上 +下 +不 +与 +丐 +丑 +专 +且 +丕 +世 +丘 +丙 +业 +丛 +东 +丝 +丞 +丟 +両 +丢 +两 +严 +並 +丧 +丨 +个 +丫 +中 +丰 +串 +临 +丶 +丸 +丹 +为 +主 +丼 +丽 +举 +丿 +乂 +乃 +久 +么 +义 +之 +乌 +乍 +乎 +乏 +乐 +乒 +乓 +乔 +乖 +乗 +乘 +乙 +乜 +九 +乞 +也 +习 +乡 +书 +乩 +买 +乱 +乳 +乾 +亀 +亂 +了 +予 +争 +事 +二 +于 +亏 +云 +互 +五 +井 +亘 +亙 +亚 +些 +亜 +亞 +亟 +亡 +亢 +交 +亥 +亦 +产 +亨 +亩 +享 +京 +亭 +亮 +亲 +亳 +亵 +人 +亿 +什 +仁 +仃 +仄 +仅 +仆 +仇 +今 +介 +仍 +从 +仏 +仑 +仓 +仔 +仕 +他 +仗 +付 +仙 +仝 +仞 +仟 +代 +令 +以 +仨 +仪 +们 +仮 +仰 +仲 +件 +价 +任 +份 +仿 +企 +伉 +伊 +伍 +伎 +伏 +伐 +休 +伕 +众 +优 +伙 +会 +伝 +伞 +伟 +传 +伢 +伤 +伦 +伪 +伫 +伯 +估 +伴 +伶 +伸 +伺 +似 +伽 +佃 +但 +佇 +佈 +位 +低 +住 +佐 +佑 +体 +佔 +何 +佗 +佘 +余 +佚 +佛 +作 +佝 +佞 +佟 +你 +佢 +佣 +佤 +佥 +佩 +佬 +佯 +佰 +佳 +併 +佶 +佻 +佼 +使 +侃 +侄 +來 +侈 +例 +侍 +侏 +侑 +侖 +侗 +供 +依 +侠 +価 +侣 +侥 +侦 +侧 +侨 +侬 +侮 +侯 +侵 +侶 +侷 +便 +係 +促 +俄 +俊 +俎 +俏 +俐 +俑 +俗 +俘 +俚 +保 +俞 +俟 +俠 +信 +俨 +俩 +俪 +俬 +俭 +修 +俯 +俱 +俳 +俸 +俺 +俾 +倆 +倉 +個 +倌 +倍 +倏 +們 +倒 +倔 +倖 +倘 +候 +倚 +倜 +借 +倡 +値 +倦 +倩 +倪 +倫 +倬 +倭 +倶 +债 +值 +倾 +偃 +假 +偈 +偉 +偌 +偎 +偏 +偕 +做 +停 +健 +側 +偵 +偶 +偷 +偻 +偽 +偿 +傀 +傅 +傍 +傑 +傘 +備 +傚 +傢 +傣 +傥 +储 +傩 +催 +傭 +傲 +傳 +債 +傷 +傻 +傾 +僅 +働 +像 +僑 +僕 +僖 +僚 +僥 +僧 +僭 +僮 +僱 +僵 +價 +僻 +儀 +儂 +億 +儆 +儉 +儋 +儒 +儕 +儘 +償 +儡 +優 +儲 +儷 +儼 +儿 +兀 +允 +元 +兄 +充 +兆 +兇 +先 +光 +克 +兌 +免 +児 +兑 +兒 +兔 +兖 +党 +兜 +兢 +入 +內 +全 +兩 +八 +公 +六 +兮 +兰 +共 +兲 +关 +兴 +兵 +其 +具 +典 +兹 +养 +兼 +兽 +冀 +内 +円 +冇 +冈 +冉 +冊 +册 +再 +冏 +冒 +冕 +冗 +写 +军 +农 +冠 +冢 +冤 +冥 +冨 +冪 +冬 +冯 +冰 +冲 +决 +况 +冶 +冷 +冻 +冼 +冽 +冾 +净 +凄 +准 +凇 +凈 +凉 +凋 +凌 +凍 +减 +凑 +凛 +凜 +凝 +几 +凡 +凤 +処 +凪 +凭 +凯 +凰 +凱 +凳 +凶 +凸 +凹 +出 +击 +函 +凿 +刀 +刁 +刃 +分 +切 +刈 +刊 +刍 +刎 +刑 +划 +列 +刘 +则 +刚 +创 +初 +删 +判 +別 +刨 +利 +刪 +别 +刮 +到 +制 +刷 +券 +刹 +刺 +刻 +刽 +剁 +剂 +剃 +則 +剉 +削 +剋 +剌 +前 +剎 +剐 +剑 +剔 +剖 +剛 +剜 +剝 +剣 +剤 +剥 +剧 +剩 +剪 +副 +割 +創 +剷 +剽 +剿 +劃 +劇 +劈 +劉 +劊 +劍 +劏 +劑 +力 +劝 +办 +功 +加 +务 +劣 +动 +助 +努 +劫 +劭 +励 +劲 +劳 +労 +劵 +効 +劾 +势 +勁 +勃 +勇 +勉 +勋 +勐 +勒 +動 +勖 +勘 +務 +勛 +勝 +勞 +募 +勢 +勤 +勧 +勳 +勵 +勸 +勺 +勻 +勾 +勿 +匀 +包 +匆 +匈 +匍 +匐 +匕 +化 +北 +匙 +匝 +匠 +匡 +匣 +匪 +匮 +匯 +匱 +匹 +区 +医 +匾 +匿 +區 +十 +千 +卅 +升 +午 +卉 +半 +卍 +华 +协 +卑 +卒 +卓 +協 +单 +卖 +南 +単 +博 +卜 +卞 +卟 +占 +卡 +卢 +卤 +卦 +卧 +卫 +卮 +卯 +印 +危 +即 +却 +卵 +卷 +卸 +卻 +卿 +厂 +厄 +厅 +历 +厉 +压 +厌 +厕 +厘 +厚 +厝 +原 +厢 +厥 +厦 +厨 +厩 +厭 +厮 +厲 +厳 +去 +县 +叁 +参 +參 +又 +叉 +及 +友 +双 +反 +収 +发 +叔 +取 +受 +变 +叙 +叛 +叟 +叠 +叡 +叢 +口 +古 +句 +另 +叨 +叩 +只 +叫 +召 +叭 +叮 +可 +台 +叱 +史 +右 +叵 +叶 +号 +司 +叹 +叻 +叼 +叽 +吁 +吃 +各 +吆 +合 +吉 +吊 +吋 +同 +名 +后 +吏 +吐 +向 +吒 +吓 +吕 +吖 +吗 +君 +吝 +吞 +吟 +吠 +吡 +否 +吧 +吨 +吩 +含 +听 +吭 +吮 +启 +吱 +吳 +吴 +吵 +吶 +吸 +吹 +吻 +吼 +吽 +吾 +呀 +呂 +呃 +呆 +呈 +告 +呋 +呎 +呐 +呓 +呕 +呗 +员 +呛 +呜 +呢 +呤 +呦 +周 +呱 +呲 +味 +呵 +呷 +呸 +呻 +呼 +命 +咀 +咁 +咂 +咄 +咆 +咋 +和 +咎 +咏 +咐 +咒 +咔 +咕 +咖 +咗 +咘 +咙 +咚 +咛 +咣 +咤 +咦 +咧 +咨 +咩 +咪 +咫 +咬 +咭 +咯 +咱 +咲 +咳 +咸 +咻 +咽 +咿 +哀 +品 +哂 +哄 +哆 +哇 +哈 +哉 +哋 +哌 +响 +哎 +哏 +哐 +哑 +哒 +哔 +哗 +哟 +員 +哥 +哦 +哧 +哨 +哩 +哪 +哭 +哮 +哲 +哺 +哼 +哽 +唁 +唄 +唆 +唇 +唉 +唏 +唐 +唑 +唔 +唠 +唤 +唧 +唬 +售 +唯 +唰 +唱 +唳 +唷 +唸 +唾 +啃 +啄 +商 +啉 +啊 +問 +啓 +啕 +啖 +啜 +啞 +啟 +啡 +啤 +啥 +啦 +啧 +啪 +啫 +啬 +啮 +啰 +啱 +啲 +啵 +啶 +啷 +啸 +啻 +啼 +啾 +喀 +喂 +喃 +善 +喆 +喇 +喉 +喊 +喋 +喎 +喏 +喔 +喘 +喙 +喚 +喜 +喝 +喟 +喧 +喪 +喫 +喬 +單 +喰 +喱 +喲 +喳 +喵 +営 +喷 +喹 +喺 +喻 +喽 +嗅 +嗆 +嗇 +嗎 +嗑 +嗒 +嗓 +嗔 +嗖 +嗚 +嗜 +嗝 +嗟 +嗡 +嗣 +嗤 +嗦 +嗨 +嗪 +嗬 +嗯 +嗰 +嗲 +嗳 +嗶 +嗷 +嗽 +嘀 +嘅 +嘆 +嘈 +嘉 +嘌 +嘍 +嘎 +嘔 +嘖 +嘗 +嘘 +嘚 +嘛 +嘜 +嘞 +嘟 +嘢 +嘣 +嘤 +嘧 +嘩 +嘭 +嘮 +嘯 +嘰 +嘱 +嘲 +嘴 +嘶 +嘸 +嘹 +嘻 +嘿 +噁 +噌 +噎 +噓 +噔 +噗 +噙 +噜 +噠 +噢 +噤 +器 +噩 +噪 +噬 +噱 +噴 +噶 +噸 +噹 +噻 +噼 +嚀 +嚇 +嚎 +嚏 +嚐 +嚓 +嚕 +嚟 +嚣 +嚥 +嚨 +嚮 +嚴 +嚷 +嚼 +囂 +囉 +囊 +囍 +囑 +囔 +囗 +囚 +四 +囝 +回 +囟 +因 +囡 +团 +団 +囤 +囧 +囪 +囫 +园 +困 +囱 +囲 +図 +围 +囹 +固 +国 +图 +囿 +圃 +圄 +圆 +圈 +國 +圍 +圏 +園 +圓 +圖 +團 +圜 +土 +圣 +圧 +在 +圩 +圭 +地 +圳 +场 +圻 +圾 +址 +坂 +均 +坊 +坍 +坎 +坏 +坐 +坑 +块 +坚 +坛 +坝 +坞 +坟 +坠 +坡 +坤 +坦 +坨 +坪 +坯 +坳 +坵 +坷 +垂 +垃 +垄 +型 +垒 +垚 +垛 +垠 +垢 +垣 +垦 +垩 +垫 +垭 +垮 +垵 +埂 +埃 +埋 +城 +埔 +埕 +埗 +域 +埠 +埤 +埵 +執 +埸 +培 +基 +埼 +堀 +堂 +堃 +堅 +堆 +堇 +堑 +堕 +堙 +堡 +堤 +堪 +堯 +堰 +報 +場 +堵 +堺 +堿 +塊 +塌 +塑 +塔 +塗 +塘 +塚 +塞 +塢 +塩 +填 +塬 +塭 +塵 +塾 +墀 +境 +墅 +墉 +墊 +墒 +墓 +増 +墘 +墙 +墜 +增 +墟 +墨 +墩 +墮 +墳 +墻 +墾 +壁 +壅 +壆 +壇 +壊 +壑 +壓 +壕 +壘 +壞 +壟 +壢 +壤 +壩 +士 +壬 +壮 +壯 +声 +売 +壳 +壶 +壹 +壺 +壽 +处 +备 +変 +复 +夏 +夔 +夕 +外 +夙 +多 +夜 +够 +夠 +夢 +夥 +大 +天 +太 +夫 +夭 +央 +夯 +失 +头 +夷 +夸 +夹 +夺 +夾 +奂 +奄 +奇 +奈 +奉 +奋 +奎 +奏 +奐 +契 +奔 +奕 +奖 +套 +奘 +奚 +奠 +奢 +奥 +奧 +奪 +奬 +奮 +女 +奴 +奶 +奸 +她 +好 +如 +妃 +妄 +妆 +妇 +妈 +妊 +妍 +妒 +妓 +妖 +妘 +妙 +妝 +妞 +妣 +妤 +妥 +妨 +妩 +妪 +妮 +妲 +妳 +妹 +妻 +妾 +姆 +姉 +姊 +始 +姍 +姐 +姑 +姒 +姓 +委 +姗 +姚 +姜 +姝 +姣 +姥 +姦 +姨 +姪 +姫 +姬 +姹 +姻 +姿 +威 +娃 +娄 +娅 +娆 +娇 +娉 +娑 +娓 +娘 +娛 +娜 +娟 +娠 +娣 +娥 +娩 +娱 +娲 +娴 +娶 +娼 +婀 +婁 +婆 +婉 +婊 +婕 +婚 +婢 +婦 +婧 +婪 +婭 +婴 +婵 +婶 +婷 +婺 +婿 +媒 +媚 +媛 +媞 +媧 +媲 +媳 +媽 +媾 +嫁 +嫂 +嫉 +嫌 +嫑 +嫔 +嫖 +嫘 +嫚 +嫡 +嫣 +嫦 +嫩 +嫲 +嫵 +嫻 +嬅 +嬉 +嬌 +嬗 +嬛 +嬢 +嬤 +嬪 +嬰 +嬴 +嬷 +嬸 +嬿 +孀 +孃 +子 +孑 +孔 +孕 +孖 +字 +存 +孙 +孚 +孛 +孜 +孝 +孟 +孢 +季 +孤 +学 +孩 +孪 +孫 +孬 +孰 +孱 +孳 +孵 +學 +孺 +孽 +孿 +宁 +它 +宅 +宇 +守 +安 +宋 +完 +宏 +宓 +宕 +宗 +官 +宙 +定 +宛 +宜 +宝 +实 +実 +宠 +审 +客 +宣 +室 +宥 +宦 +宪 +宫 +宮 +宰 +害 +宴 +宵 +家 +宸 +容 +宽 +宾 +宿 +寂 +寄 +寅 +密 +寇 +富 +寐 +寒 +寓 +寛 +寝 +寞 +察 +寡 +寢 +寥 +實 +寧 +寨 +審 +寫 +寬 +寮 +寰 +寵 +寶 +寸 +对 +寺 +寻 +导 +対 +寿 +封 +専 +射 +将 +將 +專 +尉 +尊 +尋 +對 +導 +小 +少 +尔 +尕 +尖 +尘 +尚 +尝 +尤 +尧 +尬 +就 +尴 +尷 +尸 +尹 +尺 +尻 +尼 +尽 +尾 +尿 +局 +屁 +层 +屄 +居 +屆 +屈 +屉 +届 +屋 +屌 +屍 +屎 +屏 +屐 +屑 +展 +屜 +属 +屠 +屡 +屢 +層 +履 +屬 +屯 +山 +屹 +屿 +岀 +岁 +岂 +岌 +岐 +岑 +岔 +岖 +岗 +岘 +岙 +岚 +岛 +岡 +岩 +岫 +岬 +岭 +岱 +岳 +岷 +岸 +峇 +峋 +峒 +峙 +峡 +峤 +峥 +峦 +峨 +峪 +峭 +峯 +峰 +峴 +島 +峻 +峽 +崁 +崂 +崆 +崇 +崎 +崑 +崔 +崖 +崗 +崙 +崛 +崧 +崩 +崭 +崴 +崽 +嵇 +嵊 +嵋 +嵌 +嵐 +嵘 +嵩 +嵬 +嵯 +嶂 +嶄 +嶇 +嶋 +嶙 +嶺 +嶼 +嶽 +巅 +巍 +巒 +巔 +巖 +川 +州 +巡 +巢 +工 +左 +巧 +巨 +巩 +巫 +差 +己 +已 +巳 +巴 +巷 +巻 +巽 +巾 +巿 +币 +市 +布 +帅 +帆 +师 +希 +帐 +帑 +帕 +帖 +帘 +帚 +帛 +帜 +帝 +帥 +带 +帧 +師 +席 +帮 +帯 +帰 +帳 +帶 +帷 +常 +帼 +帽 +幀 +幂 +幄 +幅 +幌 +幔 +幕 +幟 +幡 +幢 +幣 +幫 +干 +平 +年 +并 +幸 +幹 +幺 +幻 +幼 +幽 +幾 +广 +庁 +広 +庄 +庆 +庇 +床 +序 +庐 +库 +应 +底 +庖 +店 +庙 +庚 +府 +庞 +废 +庠 +度 +座 +庫 +庭 +庵 +庶 +康 +庸 +庹 +庾 +廁 +廂 +廃 +廈 +廉 +廊 +廓 +廖 +廚 +廝 +廟 +廠 +廢 +廣 +廬 +廳 +延 +廷 +建 +廿 +开 +弁 +异 +弃 +弄 +弈 +弊 +弋 +式 +弑 +弒 +弓 +弔 +引 +弗 +弘 +弛 +弟 +张 +弥 +弦 +弧 +弩 +弭 +弯 +弱 +張 +強 +弹 +强 +弼 +弾 +彅 +彆 +彈 +彌 +彎 +归 +当 +录 +彗 +彙 +彝 +形 +彤 +彥 +彦 +彧 +彩 +彪 +彫 +彬 +彭 +彰 +影 +彷 +役 +彻 +彼 +彿 +往 +征 +径 +待 +徇 +很 +徉 +徊 +律 +後 +徐 +徑 +徒 +従 +徕 +得 +徘 +徙 +徜 +從 +徠 +御 +徨 +復 +循 +徬 +微 +徳 +徴 +徵 +德 +徹 +徼 +徽 +心 +必 +忆 +忌 +忍 +忏 +忐 +忑 +忒 +忖 +志 +忘 +忙 +応 +忠 +忡 +忤 +忧 +忪 +快 +忱 +念 +忻 +忽 +忿 +怀 +态 +怂 +怅 +怆 +怎 +怏 +怒 +怔 +怕 +怖 +怙 +怜 +思 +怠 +怡 +急 +怦 +性 +怨 +怪 +怯 +怵 +总 +怼 +恁 +恃 +恆 +恋 +恍 +恐 +恒 +恕 +恙 +恚 +恢 +恣 +恤 +恥 +恨 +恩 +恪 +恫 +恬 +恭 +息 +恰 +恳 +恵 +恶 +恸 +恺 +恻 +恼 +恿 +悄 +悅 +悉 +悌 +悍 +悔 +悖 +悚 +悟 +悠 +患 +悦 +您 +悩 +悪 +悬 +悯 +悱 +悲 +悴 +悵 +悶 +悸 +悻 +悼 +悽 +情 +惆 +惇 +惊 +惋 +惑 +惕 +惘 +惚 +惜 +惟 +惠 +惡 +惦 +惧 +惨 +惩 +惫 +惬 +惭 +惮 +惯 +惰 +惱 +想 +惴 +惶 +惹 +惺 +愁 +愆 +愈 +愉 +愍 +意 +愕 +愚 +愛 +愜 +感 +愣 +愤 +愧 +愫 +愷 +愿 +慄 +慈 +態 +慌 +慎 +慑 +慕 +慘 +慚 +慟 +慢 +慣 +慧 +慨 +慫 +慮 +慰 +慳 +慵 +慶 +慷 +慾 +憂 +憊 +憋 +憎 +憐 +憑 +憔 +憚 +憤 +憧 +憨 +憩 +憫 +憬 +憲 +憶 +憾 +懂 +懇 +懈 +應 +懊 +懋 +懑 +懒 +懦 +懲 +懵 +懶 +懷 +懸 +懺 +懼 +懾 +懿 +戀 +戈 +戊 +戌 +戍 +戎 +戏 +成 +我 +戒 +戕 +或 +战 +戚 +戛 +戟 +戡 +戦 +截 +戬 +戮 +戰 +戲 +戳 +戴 +戶 +户 +戸 +戻 +戾 +房 +所 +扁 +扇 +扈 +扉 +手 +才 +扎 +扑 +扒 +打 +扔 +払 +托 +扛 +扣 +扦 +执 +扩 +扪 +扫 +扬 +扭 +扮 +扯 +扰 +扱 +扳 +扶 +批 +扼 +找 +承 +技 +抄 +抉 +把 +抑 +抒 +抓 +投 +抖 +抗 +折 +抚 +抛 +抜 +択 +抟 +抠 +抡 +抢 +护 +报 +抨 +披 +抬 +抱 +抵 +抹 +押 +抽 +抿 +拂 +拄 +担 +拆 +拇 +拈 +拉 +拋 +拌 +拍 +拎 +拐 +拒 +拓 +拔 +拖 +拗 +拘 +拙 +拚 +招 +拜 +拟 +拡 +拢 +拣 +拥 +拦 +拧 +拨 +择 +括 +拭 +拮 +拯 +拱 +拳 +拴 +拷 +拼 +拽 +拾 +拿 +持 +挂 +指 +挈 +按 +挎 +挑 +挖 +挙 +挚 +挛 +挝 +挞 +挟 +挠 +挡 +挣 +挤 +挥 +挨 +挪 +挫 +振 +挲 +挹 +挺 +挽 +挾 +捂 +捅 +捆 +捉 +捋 +捌 +捍 +捎 +捏 +捐 +捕 +捞 +损 +捡 +换 +捣 +捧 +捨 +捩 +据 +捱 +捲 +捶 +捷 +捺 +捻 +掀 +掂 +掃 +掇 +授 +掉 +掌 +掏 +掐 +排 +掖 +掘 +掙 +掛 +掠 +採 +探 +掣 +接 +控 +推 +掩 +措 +掬 +掰 +掲 +掳 +掴 +掷 +掸 +掺 +揀 +揃 +揄 +揆 +揉 +揍 +描 +提 +插 +揖 +揚 +換 +握 +揣 +揩 +揪 +揭 +揮 +援 +揶 +揸 +揹 +揽 +搀 +搁 +搂 +搅 +損 +搏 +搐 +搓 +搔 +搖 +搗 +搜 +搞 +搡 +搪 +搬 +搭 +搵 +搶 +携 +搽 +摀 +摁 +摄 +摆 +摇 +摈 +摊 +摒 +摔 +摘 +摞 +摟 +摧 +摩 +摯 +摳 +摸 +摹 +摺 +摻 +撂 +撃 +撅 +撇 +撈 +撐 +撑 +撒 +撓 +撕 +撚 +撞 +撤 +撥 +撩 +撫 +撬 +播 +撮 +撰 +撲 +撵 +撷 +撸 +撻 +撼 +撿 +擀 +擁 +擂 +擄 +擅 +擇 +擊 +擋 +操 +擎 +擒 +擔 +擘 +據 +擞 +擠 +擡 +擢 +擦 +擬 +擰 +擱 +擲 +擴 +擷 +擺 +擼 +擾 +攀 +攏 +攒 +攔 +攘 +攙 +攜 +攝 +攞 +攢 +攣 +攤 +攥 +攪 +攫 +攬 +支 +收 +攸 +改 +攻 +放 +政 +故 +效 +敌 +敍 +敎 +敏 +救 +敕 +敖 +敗 +敘 +教 +敛 +敝 +敞 +敢 +散 +敦 +敬 +数 +敲 +整 +敵 +敷 +數 +斂 +斃 +文 +斋 +斌 +斎 +斐 +斑 +斓 +斗 +料 +斛 +斜 +斟 +斡 +斤 +斥 +斧 +斩 +斫 +斬 +断 +斯 +新 +斷 +方 +於 +施 +旁 +旃 +旅 +旋 +旌 +旎 +族 +旖 +旗 +无 +既 +日 +旦 +旧 +旨 +早 +旬 +旭 +旮 +旱 +时 +旷 +旺 +旻 +昀 +昂 +昆 +昇 +昉 +昊 +昌 +明 +昏 +易 +昔 +昕 +昙 +星 +映 +春 +昧 +昨 +昭 +是 +昱 +昴 +昵 +昶 +昼 +显 +晁 +時 +晃 +晉 +晋 +晌 +晏 +晒 +晓 +晔 +晕 +晖 +晗 +晚 +晝 +晞 +晟 +晤 +晦 +晨 +晩 +普 +景 +晰 +晴 +晶 +晷 +智 +晾 +暂 +暄 +暇 +暈 +暉 +暌 +暐 +暑 +暖 +暗 +暝 +暢 +暧 +暨 +暫 +暮 +暱 +暴 +暸 +暹 +曄 +曆 +曇 +曉 +曖 +曙 +曜 +曝 +曠 +曦 +曬 +曰 +曲 +曳 +更 +書 +曹 +曼 +曾 +替 +最 +會 +月 +有 +朋 +服 +朐 +朔 +朕 +朗 +望 +朝 +期 +朦 +朧 +木 +未 +末 +本 +札 +朮 +术 +朱 +朴 +朵 +机 +朽 +杀 +杂 +权 +杆 +杈 +杉 +李 +杏 +材 +村 +杓 +杖 +杜 +杞 +束 +杠 +条 +来 +杨 +杭 +杯 +杰 +東 +杳 +杵 +杷 +杼 +松 +板 +极 +构 +枇 +枉 +枋 +析 +枕 +林 +枚 +果 +枝 +枢 +枣 +枪 +枫 +枭 +枯 +枰 +枱 +枳 +架 +枷 +枸 +柄 +柏 +某 +柑 +柒 +染 +柔 +柘 +柚 +柜 +柞 +柠 +柢 +查 +柩 +柬 +柯 +柱 +柳 +柴 +柵 +査 +柿 +栀 +栃 +栄 +栅 +标 +栈 +栉 +栋 +栎 +栏 +树 +栓 +栖 +栗 +校 +栩 +株 +样 +核 +根 +格 +栽 +栾 +桀 +桁 +桂 +桃 +桅 +框 +案 +桉 +桌 +桎 +桐 +桑 +桓 +桔 +桜 +桠 +桡 +桢 +档 +桥 +桦 +桧 +桨 +桩 +桶 +桿 +梁 +梅 +梆 +梏 +梓 +梗 +條 +梟 +梢 +梦 +梧 +梨 +梭 +梯 +械 +梳 +梵 +梶 +检 +棂 +棄 +棉 +棋 +棍 +棒 +棕 +棗 +棘 +棚 +棟 +棠 +棣 +棧 +森 +棱 +棲 +棵 +棹 +棺 +椁 +椅 +椋 +植 +椎 +椒 +検 +椪 +椭 +椰 +椹 +椽 +椿 +楂 +楊 +楓 +楔 +楚 +楝 +楞 +楠 +楣 +楨 +楫 +業 +楮 +極 +楷 +楸 +楹 +楼 +楽 +概 +榄 +榆 +榈 +榉 +榔 +榕 +榖 +榛 +榜 +榨 +榫 +榭 +榮 +榱 +榴 +榷 +榻 +槁 +槃 +構 +槌 +槍 +槎 +槐 +槓 +様 +槛 +槟 +槤 +槭 +槲 +槳 +槻 +槽 +槿 +樁 +樂 +樊 +樑 +樓 +標 +樞 +樟 +模 +樣 +権 +横 +樫 +樯 +樱 +樵 +樸 +樹 +樺 +樽 +樾 +橄 +橇 +橋 +橐 +橘 +橙 +機 +橡 +橢 +橫 +橱 +橹 +橼 +檀 +檄 +檎 +檐 +檔 +檗 +檜 +檢 +檬 +檯 +檳 +檸 +檻 +櫃 +櫚 +櫛 +櫥 +櫸 +櫻 +欄 +權 +欒 +欖 +欠 +次 +欢 +欣 +欧 +欲 +欸 +欺 +欽 +款 +歆 +歇 +歉 +歌 +歎 +歐 +歓 +歙 +歛 +歡 +止 +正 +此 +步 +武 +歧 +歩 +歪 +歯 +歲 +歳 +歴 +歷 +歸 +歹 +死 +歼 +殁 +殃 +殆 +殇 +殉 +殊 +残 +殒 +殓 +殖 +殘 +殞 +殡 +殤 +殭 +殯 +殲 +殴 +段 +殷 +殺 +殼 +殿 +毀 +毁 +毂 +毅 +毆 +毋 +母 +毎 +每 +毒 +毓 +比 +毕 +毗 +毘 +毙 +毛 +毡 +毫 +毯 +毽 +氈 +氏 +氐 +民 +氓 +气 +氖 +気 +氙 +氛 +氟 +氡 +氢 +氣 +氤 +氦 +氧 +氨 +氪 +氫 +氮 +氯 +氰 +氲 +水 +氷 +永 +氹 +氾 +汀 +汁 +求 +汆 +汇 +汉 +汎 +汐 +汕 +汗 +汙 +汛 +汝 +汞 +江 +池 +污 +汤 +汨 +汩 +汪 +汰 +汲 +汴 +汶 +汹 +決 +汽 +汾 +沁 +沂 +沃 +沅 +沈 +沉 +沌 +沏 +沐 +沒 +沓 +沖 +沙 +沛 +沟 +没 +沢 +沣 +沥 +沦 +沧 +沪 +沫 +沭 +沮 +沱 +河 +沸 +油 +治 +沼 +沽 +沾 +沿 +況 +泄 +泉 +泊 +泌 +泓 +法 +泗 +泛 +泞 +泠 +泡 +波 +泣 +泥 +注 +泪 +泫 +泮 +泯 +泰 +泱 +泳 +泵 +泷 +泸 +泻 +泼 +泽 +泾 +洁 +洄 +洋 +洒 +洗 +洙 +洛 +洞 +津 +洩 +洪 +洮 +洱 +洲 +洵 +洶 +洸 +洹 +活 +洼 +洽 +派 +流 +浃 +浄 +浅 +浆 +浇 +浊 +测 +济 +浏 +浑 +浒 +浓 +浔 +浙 +浚 +浜 +浣 +浦 +浩 +浪 +浬 +浮 +浯 +浴 +海 +浸 +涂 +涅 +涇 +消 +涉 +涌 +涎 +涓 +涔 +涕 +涙 +涛 +涝 +涞 +涟 +涠 +涡 +涣 +涤 +润 +涧 +涨 +涩 +涪 +涮 +涯 +液 +涵 +涸 +涼 +涿 +淀 +淄 +淅 +淆 +淇 +淋 +淌 +淑 +淒 +淖 +淘 +淙 +淚 +淞 +淡 +淤 +淦 +淨 +淩 +淪 +淫 +淬 +淮 +深 +淳 +淵 +混 +淹 +淺 +添 +淼 +清 +済 +渉 +渊 +渋 +渍 +渎 +渐 +渔 +渗 +渙 +渚 +減 +渝 +渠 +渡 +渣 +渤 +渥 +渦 +温 +測 +渭 +港 +渲 +渴 +游 +渺 +渾 +湃 +湄 +湊 +湍 +湖 +湘 +湛 +湟 +湧 +湫 +湮 +湯 +湳 +湾 +湿 +満 +溃 +溅 +溉 +溏 +源 +準 +溜 +溝 +溟 +溢 +溥 +溧 +溪 +溫 +溯 +溱 +溴 +溶 +溺 +溼 +滁 +滂 +滄 +滅 +滇 +滋 +滌 +滑 +滓 +滔 +滕 +滙 +滚 +滝 +滞 +滟 +满 +滢 +滤 +滥 +滦 +滨 +滩 +滬 +滯 +滲 +滴 +滷 +滸 +滾 +滿 +漁 +漂 +漆 +漉 +漏 +漓 +演 +漕 +漠 +漢 +漣 +漩 +漪 +漫 +漬 +漯 +漱 +漲 +漳 +漸 +漾 +漿 +潆 +潇 +潋 +潍 +潑 +潔 +潘 +潛 +潜 +潞 +潟 +潢 +潤 +潦 +潧 +潭 +潮 +潰 +潴 +潸 +潺 +潼 +澀 +澄 +澆 +澈 +澍 +澎 +澗 +澜 +澡 +澤 +澧 +澱 +澳 +澹 +激 +濁 +濂 +濃 +濑 +濒 +濕 +濘 +濛 +濟 +濠 +濡 +濤 +濫 +濬 +濮 +濯 +濱 +濺 +濾 +瀅 +瀆 +瀉 +瀋 +瀏 +瀑 +瀕 +瀘 +瀚 +瀛 +瀝 +瀞 +瀟 +瀧 +瀨 +瀬 +瀰 +瀾 +灌 +灏 +灑 +灘 +灝 +灞 +灣 +火 +灬 +灭 +灯 +灰 +灵 +灶 +灸 +灼 +災 +灾 +灿 +炀 +炁 +炅 +炉 +炊 +炎 +炒 +炔 +炕 +炖 +炙 +炜 +炫 +炬 +炭 +炮 +炯 +炳 +炷 +炸 +点 +為 +炼 +炽 +烁 +烂 +烃 +烈 +烊 +烏 +烘 +烙 +烛 +烟 +烤 +烦 +烧 +烨 +烩 +烫 +烬 +热 +烯 +烷 +烹 +烽 +焉 +焊 +焕 +焖 +焗 +焘 +焙 +焚 +焜 +無 +焦 +焯 +焰 +焱 +然 +焼 +煅 +煉 +煊 +煌 +煎 +煒 +煖 +煙 +煜 +煞 +煤 +煥 +煦 +照 +煨 +煩 +煮 +煲 +煸 +煽 +熄 +熊 +熏 +熒 +熔 +熙 +熟 +熠 +熨 +熬 +熱 +熵 +熹 +熾 +燁 +燃 +燄 +燈 +燉 +燊 +燎 +燒 +燔 +燕 +燙 +燜 +營 +燥 +燦 +燧 +燭 +燮 +燴 +燻 +燼 +燿 +爆 +爍 +爐 +爛 +爪 +爬 +爭 +爰 +爱 +爲 +爵 +父 +爷 +爸 +爹 +爺 +爻 +爽 +爾 +牆 +片 +版 +牌 +牍 +牒 +牙 +牛 +牝 +牟 +牠 +牡 +牢 +牦 +牧 +物 +牯 +牲 +牴 +牵 +特 +牺 +牽 +犀 +犁 +犄 +犊 +犍 +犒 +犢 +犧 +犬 +犯 +状 +犷 +犸 +犹 +狀 +狂 +狄 +狈 +狎 +狐 +狒 +狗 +狙 +狞 +狠 +狡 +狩 +独 +狭 +狮 +狰 +狱 +狸 +狹 +狼 +狽 +猎 +猕 +猖 +猗 +猙 +猛 +猜 +猝 +猥 +猩 +猪 +猫 +猬 +献 +猴 +猶 +猷 +猾 +猿 +獄 +獅 +獎 +獐 +獒 +獗 +獠 +獣 +獨 +獭 +獰 +獲 +獵 +獷 +獸 +獺 +獻 +獼 +獾 +玄 +率 +玉 +王 +玑 +玖 +玛 +玟 +玠 +玥 +玩 +玫 +玮 +环 +现 +玲 +玳 +玷 +玺 +玻 +珀 +珂 +珅 +珈 +珉 +珊 +珍 +珏 +珐 +珑 +珙 +珞 +珠 +珣 +珥 +珩 +珪 +班 +珮 +珲 +珺 +現 +球 +琅 +理 +琇 +琉 +琊 +琍 +琏 +琐 +琛 +琢 +琥 +琦 +琨 +琪 +琬 +琮 +琰 +琲 +琳 +琴 +琵 +琶 +琺 +琼 +瑀 +瑁 +瑄 +瑋 +瑕 +瑗 +瑙 +瑚 +瑛 +瑜 +瑞 +瑟 +瑠 +瑣 +瑤 +瑩 +瑪 +瑯 +瑰 +瑶 +瑾 +璀 +璁 +璃 +璇 +璉 +璋 +璎 +璐 +璜 +璞 +璟 +璧 +璨 +環 +璽 +璿 +瓊 +瓏 +瓒 +瓜 +瓢 +瓣 +瓤 +瓦 +瓮 +瓯 +瓴 +瓶 +瓷 +甄 +甌 +甕 +甘 +甙 +甚 +甜 +生 +產 +産 +甥 +甦 +用 +甩 +甫 +甬 +甭 +甯 +田 +由 +甲 +申 +电 +男 +甸 +町 +画 +甾 +畀 +畅 +界 +畏 +畑 +畔 +留 +畜 +畝 +畢 +略 +畦 +番 +畫 +異 +畲 +畳 +畴 +當 +畸 +畹 +畿 +疆 +疇 +疊 +疏 +疑 +疔 +疖 +疗 +疙 +疚 +疝 +疟 +疡 +疣 +疤 +疥 +疫 +疮 +疯 +疱 +疲 +疳 +疵 +疸 +疹 +疼 +疽 +疾 +痂 +病 +症 +痈 +痉 +痊 +痍 +痒 +痔 +痕 +痘 +痙 +痛 +痞 +痠 +痢 +痣 +痤 +痧 +痨 +痪 +痫 +痰 +痱 +痴 +痹 +痺 +痼 +痿 +瘀 +瘁 +瘋 +瘍 +瘓 +瘘 +瘙 +瘟 +瘠 +瘡 +瘢 +瘤 +瘦 +瘧 +瘩 +瘪 +瘫 +瘴 +瘸 +瘾 +療 +癇 +癌 +癒 +癖 +癜 +癞 +癡 +癢 +癣 +癥 +癫 +癬 +癮 +癱 +癲 +癸 +発 +登 +發 +白 +百 +皂 +的 +皆 +皇 +皈 +皋 +皎 +皑 +皓 +皖 +皙 +皚 +皮 +皰 +皱 +皴 +皺 +皿 +盂 +盃 +盅 +盆 +盈 +益 +盎 +盏 +盐 +监 +盒 +盔 +盖 +盗 +盘 +盛 +盜 +盞 +盟 +盡 +監 +盤 +盥 +盧 +盪 +目 +盯 +盱 +盲 +直 +相 +盹 +盼 +盾 +省 +眈 +眉 +看 +県 +眙 +眞 +真 +眠 +眦 +眨 +眩 +眯 +眶 +眷 +眸 +眺 +眼 +眾 +着 +睁 +睇 +睏 +睐 +睑 +睛 +睜 +睞 +睡 +睢 +督 +睥 +睦 +睨 +睪 +睫 +睬 +睹 +睽 +睾 +睿 +瞄 +瞅 +瞇 +瞋 +瞌 +瞎 +瞑 +瞒 +瞓 +瞞 +瞟 +瞠 +瞥 +瞧 +瞩 +瞪 +瞬 +瞭 +瞰 +瞳 +瞻 +瞼 +瞿 +矇 +矍 +矗 +矚 +矛 +矜 +矢 +矣 +知 +矩 +矫 +短 +矮 +矯 +石 +矶 +矽 +矾 +矿 +码 +砂 +砌 +砍 +砒 +研 +砖 +砗 +砚 +砝 +砣 +砥 +砧 +砭 +砰 +砲 +破 +砷 +砸 +砺 +砼 +砾 +础 +硅 +硐 +硒 +硕 +硝 +硫 +硬 +确 +硯 +硼 +碁 +碇 +碉 +碌 +碍 +碎 +碑 +碓 +碗 +碘 +碚 +碛 +碟 +碣 +碧 +碩 +碰 +碱 +碳 +碴 +確 +碼 +碾 +磁 +磅 +磊 +磋 +磐 +磕 +磚 +磡 +磨 +磬 +磯 +磲 +磷 +磺 +礁 +礎 +礙 +礡 +礦 +礪 +礫 +礴 +示 +礼 +社 +祀 +祁 +祂 +祇 +祈 +祉 +祎 +祐 +祕 +祖 +祗 +祚 +祛 +祜 +祝 +神 +祟 +祠 +祢 +祥 +票 +祭 +祯 +祷 +祸 +祺 +祿 +禀 +禁 +禄 +禅 +禍 +禎 +福 +禛 +禦 +禧 +禪 +禮 +禱 +禹 +禺 +离 +禽 +禾 +禿 +秀 +私 +秃 +秆 +秉 +秋 +种 +科 +秒 +秘 +租 +秣 +秤 +秦 +秧 +秩 +秭 +积 +称 +秸 +移 +秽 +稀 +稅 +程 +稍 +税 +稔 +稗 +稚 +稜 +稞 +稟 +稠 +稣 +種 +稱 +稲 +稳 +稷 +稹 +稻 +稼 +稽 +稿 +穀 +穂 +穆 +穌 +積 +穎 +穗 +穢 +穩 +穫 +穴 +究 +穷 +穹 +空 +穿 +突 +窃 +窄 +窈 +窍 +窑 +窒 +窓 +窕 +窖 +窗 +窘 +窜 +窝 +窟 +窠 +窥 +窦 +窨 +窩 +窪 +窮 +窯 +窺 +窿 +竄 +竅 +竇 +竊 +立 +竖 +站 +竜 +竞 +竟 +章 +竣 +童 +竭 +端 +競 +竹 +竺 +竽 +竿 +笃 +笆 +笈 +笋 +笏 +笑 +笔 +笙 +笛 +笞 +笠 +符 +笨 +第 +笹 +笺 +笼 +筆 +等 +筊 +筋 +筍 +筏 +筐 +筑 +筒 +答 +策 +筛 +筝 +筠 +筱 +筲 +筵 +筷 +筹 +签 +简 +箇 +箋 +箍 +箏 +箐 +箔 +箕 +算 +箝 +管 +箩 +箫 +箭 +箱 +箴 +箸 +節 +篁 +範 +篆 +篇 +築 +篑 +篓 +篙 +篝 +篠 +篡 +篤 +篩 +篪 +篮 +篱 +篷 +簇 +簌 +簍 +簡 +簦 +簧 +簪 +簫 +簷 +簸 +簽 +簾 +簿 +籁 +籃 +籌 +籍 +籐 +籟 +籠 +籤 +籬 +籮 +籲 +米 +类 +籼 +籽 +粄 +粉 +粑 +粒 +粕 +粗 +粘 +粟 +粤 +粥 +粧 +粪 +粮 +粱 +粲 +粳 +粵 +粹 +粼 +粽 +精 +粿 +糅 +糊 +糍 +糕 +糖 +糗 +糙 +糜 +糞 +糟 +糠 +糧 +糬 +糯 +糰 +糸 +系 +糾 +紀 +紂 +約 +紅 +紉 +紊 +紋 +納 +紐 +紓 +純 +紗 +紘 +紙 +級 +紛 +紜 +素 +紡 +索 +紧 +紫 +紮 +累 +細 +紳 +紹 +紺 +終 +絃 +組 +絆 +経 +結 +絕 +絞 +絡 +絢 +給 +絨 +絮 +統 +絲 +絳 +絵 +絶 +絹 +綁 +綏 +綑 +經 +継 +続 +綜 +綠 +綢 +綦 +綫 +綬 +維 +綱 +網 +綴 +綵 +綸 +綺 +綻 +綽 +綾 +綿 +緊 +緋 +総 +緑 +緒 +緘 +線 +緝 +緞 +締 +緣 +編 +緩 +緬 +緯 +練 +緹 +緻 +縁 +縄 +縈 +縛 +縝 +縣 +縫 +縮 +縱 +縴 +縷 +總 +績 +繁 +繃 +繆 +繇 +繋 +織 +繕 +繚 +繞 +繡 +繩 +繪 +繫 +繭 +繳 +繹 +繼 +繽 +纂 +續 +纍 +纏 +纓 +纔 +纖 +纜 +纠 +红 +纣 +纤 +约 +级 +纨 +纪 +纫 +纬 +纭 +纯 +纰 +纱 +纲 +纳 +纵 +纶 +纷 +纸 +纹 +纺 +纽 +纾 +线 +绀 +练 +组 +绅 +细 +织 +终 +绊 +绍 +绎 +经 +绑 +绒 +结 +绔 +绕 +绘 +给 +绚 +绛 +络 +绝 +绞 +统 +绡 +绢 +绣 +绥 +绦 +继 +绩 +绪 +绫 +续 +绮 +绯 +绰 +绳 +维 +绵 +绶 +绷 +绸 +绻 +综 +绽 +绾 +绿 +缀 +缄 +缅 +缆 +缇 +缈 +缉 +缎 +缓 +缔 +缕 +编 +缘 +缙 +缚 +缜 +缝 +缠 +缢 +缤 +缥 +缨 +缩 +缪 +缭 +缮 +缰 +缱 +缴 +缸 +缺 +缽 +罂 +罄 +罌 +罐 +网 +罔 +罕 +罗 +罚 +罡 +罢 +罩 +罪 +置 +罰 +署 +罵 +罷 +罹 +羁 +羅 +羈 +羊 +羌 +美 +羔 +羚 +羞 +羟 +羡 +羣 +群 +羥 +羧 +羨 +義 +羯 +羲 +羸 +羹 +羽 +羿 +翁 +翅 +翊 +翌 +翎 +習 +翔 +翘 +翟 +翠 +翡 +翦 +翩 +翰 +翱 +翳 +翹 +翻 +翼 +耀 +老 +考 +耄 +者 +耆 +耋 +而 +耍 +耐 +耒 +耕 +耗 +耘 +耙 +耦 +耨 +耳 +耶 +耷 +耸 +耻 +耽 +耿 +聂 +聆 +聊 +聋 +职 +聒 +联 +聖 +聘 +聚 +聞 +聪 +聯 +聰 +聲 +聳 +聴 +聶 +職 +聽 +聾 +聿 +肃 +肄 +肅 +肆 +肇 +肉 +肋 +肌 +肏 +肓 +肖 +肘 +肚 +肛 +肝 +肠 +股 +肢 +肤 +肥 +肩 +肪 +肮 +肯 +肱 +育 +肴 +肺 +肽 +肾 +肿 +胀 +胁 +胃 +胄 +胆 +背 +胍 +胎 +胖 +胚 +胛 +胜 +胝 +胞 +胡 +胤 +胥 +胧 +胫 +胭 +胯 +胰 +胱 +胳 +胴 +胶 +胸 +胺 +能 +脂 +脅 +脆 +脇 +脈 +脉 +脊 +脍 +脏 +脐 +脑 +脓 +脖 +脘 +脚 +脛 +脣 +脩 +脫 +脯 +脱 +脲 +脳 +脸 +脹 +脾 +腆 +腈 +腊 +腋 +腌 +腎 +腐 +腑 +腓 +腔 +腕 +腥 +腦 +腩 +腫 +腭 +腮 +腰 +腱 +腳 +腴 +腸 +腹 +腺 +腻 +腼 +腾 +腿 +膀 +膈 +膊 +膏 +膑 +膘 +膚 +膛 +膜 +膝 +膠 +膦 +膨 +膩 +膳 +膺 +膻 +膽 +膾 +膿 +臀 +臂 +臃 +臆 +臉 +臊 +臍 +臓 +臘 +臟 +臣 +臥 +臧 +臨 +自 +臬 +臭 +至 +致 +臺 +臻 +臼 +臾 +舀 +舂 +舅 +舆 +與 +興 +舉 +舊 +舌 +舍 +舎 +舐 +舒 +舔 +舖 +舗 +舛 +舜 +舞 +舟 +航 +舫 +般 +舰 +舱 +舵 +舶 +舷 +舸 +船 +舺 +舾 +艇 +艋 +艘 +艙 +艦 +艮 +良 +艰 +艱 +色 +艳 +艷 +艹 +艺 +艾 +节 +芃 +芈 +芊 +芋 +芍 +芎 +芒 +芙 +芜 +芝 +芡 +芥 +芦 +芩 +芪 +芫 +芬 +芭 +芮 +芯 +花 +芳 +芷 +芸 +芹 +芻 +芽 +芾 +苁 +苄 +苇 +苋 +苍 +苏 +苑 +苒 +苓 +苔 +苕 +苗 +苛 +苜 +苞 +苟 +苡 +苣 +若 +苦 +苫 +苯 +英 +苷 +苹 +苻 +茁 +茂 +范 +茄 +茅 +茉 +茎 +茏 +茗 +茜 +茧 +茨 +茫 +茬 +茭 +茯 +茱 +茲 +茴 +茵 +茶 +茸 +茹 +茼 +荀 +荃 +荆 +草 +荊 +荏 +荐 +荒 +荔 +荖 +荘 +荚 +荞 +荟 +荠 +荡 +荣 +荤 +荥 +荧 +荨 +荪 +荫 +药 +荳 +荷 +荸 +荻 +荼 +荽 +莅 +莆 +莉 +莊 +莎 +莒 +莓 +莖 +莘 +莞 +莠 +莢 +莧 +莪 +莫 +莱 +莲 +莴 +获 +莹 +莺 +莽 +莿 +菀 +菁 +菅 +菇 +菈 +菊 +菌 +菏 +菓 +菖 +菘 +菜 +菟 +菠 +菡 +菩 +華 +菱 +菲 +菸 +菽 +萁 +萃 +萄 +萊 +萋 +萌 +萍 +萎 +萘 +萝 +萤 +营 +萦 +萧 +萨 +萩 +萬 +萱 +萵 +萸 +萼 +落 +葆 +葉 +著 +葚 +葛 +葡 +董 +葦 +葩 +葫 +葬 +葭 +葯 +葱 +葳 +葵 +葷 +葺 +蒂 +蒋 +蒐 +蒔 +蒙 +蒜 +蒞 +蒟 +蒡 +蒨 +蒲 +蒸 +蒹 +蒻 +蒼 +蒿 +蓁 +蓄 +蓆 +蓉 +蓋 +蓑 +蓓 +蓖 +蓝 +蓟 +蓦 +蓬 +蓮 +蓼 +蓿 +蔑 +蔓 +蔔 +蔗 +蔘 +蔚 +蔡 +蔣 +蔥 +蔫 +蔬 +蔭 +蔵 +蔷 +蔺 +蔻 +蔼 +蔽 +蕁 +蕃 +蕈 +蕉 +蕊 +蕎 +蕙 +蕤 +蕨 +蕩 +蕪 +蕭 +蕲 +蕴 +蕻 +蕾 +薄 +薅 +薇 +薈 +薊 +薏 +薑 +薔 +薙 +薛 +薦 +薨 +薩 +薪 +薬 +薯 +薰 +薹 +藉 +藍 +藏 +藐 +藓 +藕 +藜 +藝 +藤 +藥 +藩 +藹 +藻 +藿 +蘆 +蘇 +蘊 +蘋 +蘑 +蘚 +蘭 +蘸 +蘼 +蘿 +虎 +虏 +虐 +虑 +虔 +處 +虚 +虛 +虜 +虞 +號 +虢 +虧 +虫 +虬 +虱 +虹 +虻 +虽 +虾 +蚀 +蚁 +蚂 +蚊 +蚌 +蚓 +蚕 +蚜 +蚝 +蚣 +蚤 +蚩 +蚪 +蚯 +蚱 +蚵 +蛀 +蛆 +蛇 +蛊 +蛋 +蛎 +蛐 +蛔 +蛙 +蛛 +蛟 +蛤 +蛭 +蛮 +蛰 +蛳 +蛹 +蛻 +蛾 +蜀 +蜂 +蜃 +蜆 +蜇 +蜈 +蜊 +蜍 +蜒 +蜓 +蜕 +蜗 +蜘 +蜚 +蜜 +蜡 +蜢 +蜥 +蜱 +蜴 +蜷 +蜻 +蜿 +蝇 +蝈 +蝉 +蝌 +蝎 +蝕 +蝗 +蝙 +蝟 +蝠 +蝦 +蝨 +蝴 +蝶 +蝸 +蝼 +螂 +螃 +融 +螞 +螢 +螨 +螯 +螳 +螺 +蟀 +蟄 +蟆 +蟋 +蟎 +蟑 +蟒 +蟠 +蟬 +蟲 +蟹 +蟻 +蟾 +蠅 +蠍 +蠔 +蠕 +蠛 +蠟 +蠡 +蠢 +蠣 +蠱 +蠶 +蠹 +蠻 +血 +衄 +衅 +衆 +行 +衍 +術 +衔 +街 +衙 +衛 +衝 +衞 +衡 +衢 +衣 +补 +表 +衩 +衫 +衬 +衮 +衰 +衲 +衷 +衹 +衾 +衿 +袁 +袂 +袄 +袅 +袈 +袋 +袍 +袒 +袖 +袜 +袞 +袤 +袪 +被 +袭 +袱 +裁 +裂 +装 +裆 +裊 +裏 +裔 +裕 +裘 +裙 +補 +裝 +裟 +裡 +裤 +裨 +裱 +裳 +裴 +裸 +裹 +製 +裾 +褂 +複 +褐 +褒 +褓 +褔 +褚 +褥 +褪 +褫 +褲 +褶 +褻 +襁 +襄 +襟 +襠 +襪 +襬 +襯 +襲 +西 +要 +覃 +覆 +覇 +見 +規 +覓 +視 +覚 +覦 +覧 +親 +覬 +観 +覷 +覺 +覽 +觀 +见 +观 +规 +觅 +视 +览 +觉 +觊 +觎 +觐 +觑 +角 +觞 +解 +觥 +触 +觸 +言 +訂 +計 +訊 +討 +訓 +訕 +訖 +託 +記 +訛 +訝 +訟 +訣 +訥 +訪 +設 +許 +訳 +訴 +訶 +診 +註 +証 +詆 +詐 +詔 +評 +詛 +詞 +詠 +詡 +詢 +詣 +試 +詩 +詫 +詬 +詭 +詮 +詰 +話 +該 +詳 +詹 +詼 +誅 +誇 +誉 +誌 +認 +誓 +誕 +誘 +語 +誠 +誡 +誣 +誤 +誥 +誦 +誨 +說 +説 +読 +誰 +課 +誹 +誼 +調 +諄 +談 +請 +諏 +諒 +論 +諗 +諜 +諡 +諦 +諧 +諫 +諭 +諮 +諱 +諳 +諷 +諸 +諺 +諾 +謀 +謁 +謂 +謄 +謊 +謎 +謐 +謔 +謗 +謙 +講 +謝 +謠 +謨 +謬 +謹 +謾 +譁 +證 +譎 +譏 +識 +譙 +譚 +譜 +警 +譬 +譯 +議 +譲 +譴 +護 +譽 +讀 +變 +讓 +讚 +讞 +计 +订 +认 +讥 +讧 +讨 +让 +讪 +讫 +训 +议 +讯 +记 +讲 +讳 +讴 +讶 +讷 +许 +讹 +论 +讼 +讽 +设 +访 +诀 +证 +诃 +评 +诅 +识 +诈 +诉 +诊 +诋 +词 +诏 +译 +试 +诗 +诘 +诙 +诚 +诛 +话 +诞 +诟 +诠 +诡 +询 +诣 +诤 +该 +详 +诧 +诩 +诫 +诬 +语 +误 +诰 +诱 +诲 +说 +诵 +诶 +请 +诸 +诺 +读 +诽 +课 +诿 +谀 +谁 +调 +谄 +谅 +谆 +谈 +谊 +谋 +谌 +谍 +谎 +谏 +谐 +谑 +谒 +谓 +谔 +谕 +谗 +谘 +谙 +谚 +谛 +谜 +谟 +谢 +谣 +谤 +谥 +谦 +谧 +谨 +谩 +谪 +谬 +谭 +谯 +谱 +谲 +谴 +谶 +谷 +豁 +豆 +豇 +豈 +豉 +豊 +豌 +豎 +豐 +豔 +豚 +象 +豢 +豪 +豫 +豬 +豹 +豺 +貂 +貅 +貌 +貓 +貔 +貘 +貝 +貞 +負 +財 +貢 +貧 +貨 +販 +貪 +貫 +責 +貯 +貰 +貳 +貴 +貶 +買 +貸 +費 +貼 +貽 +貿 +賀 +賁 +賂 +賃 +賄 +資 +賈 +賊 +賑 +賓 +賜 +賞 +賠 +賡 +賢 +賣 +賤 +賦 +質 +賬 +賭 +賴 +賺 +購 +賽 +贅 +贈 +贊 +贍 +贏 +贓 +贖 +贛 +贝 +贞 +负 +贡 +财 +责 +贤 +败 +账 +货 +质 +贩 +贪 +贫 +贬 +购 +贮 +贯 +贰 +贱 +贲 +贴 +贵 +贷 +贸 +费 +贺 +贻 +贼 +贾 +贿 +赁 +赂 +赃 +资 +赅 +赈 +赊 +赋 +赌 +赎 +赏 +赐 +赓 +赔 +赖 +赘 +赚 +赛 +赝 +赞 +赠 +赡 +赢 +赣 +赤 +赦 +赧 +赫 +赭 +走 +赳 +赴 +赵 +赶 +起 +趁 +超 +越 +趋 +趕 +趙 +趟 +趣 +趨 +足 +趴 +趵 +趸 +趺 +趾 +跃 +跄 +跆 +跋 +跌 +跎 +跑 +跖 +跚 +跛 +距 +跟 +跡 +跤 +跨 +跩 +跪 +路 +跳 +践 +跷 +跹 +跺 +跻 +踉 +踊 +踌 +踏 +踐 +踝 +踞 +踟 +踢 +踩 +踪 +踮 +踱 +踴 +踵 +踹 +蹂 +蹄 +蹇 +蹈 +蹉 +蹊 +蹋 +蹑 +蹒 +蹙 +蹟 +蹣 +蹤 +蹦 +蹩 +蹬 +蹭 +蹲 +蹴 +蹶 +蹺 +蹼 +蹿 +躁 +躇 +躉 +躊 +躋 +躍 +躏 +躪 +身 +躬 +躯 +躲 +躺 +軀 +車 +軋 +軌 +軍 +軒 +軟 +転 +軸 +軼 +軽 +軾 +較 +載 +輒 +輓 +輔 +輕 +輛 +輝 +輟 +輩 +輪 +輯 +輸 +輻 +輾 +輿 +轄 +轅 +轆 +轉 +轍 +轎 +轟 +车 +轧 +轨 +轩 +转 +轭 +轮 +软 +轰 +轲 +轴 +轶 +轻 +轼 +载 +轿 +较 +辄 +辅 +辆 +辇 +辈 +辉 +辊 +辍 +辐 +辑 +输 +辕 +辖 +辗 +辘 +辙 +辛 +辜 +辞 +辟 +辣 +辦 +辨 +辩 +辫 +辭 +辮 +辯 +辰 +辱 +農 +边 +辺 +辻 +込 +辽 +达 +迁 +迂 +迄 +迅 +过 +迈 +迎 +运 +近 +返 +还 +这 +进 +远 +违 +连 +迟 +迢 +迤 +迥 +迦 +迩 +迪 +迫 +迭 +述 +迴 +迷 +迸 +迹 +迺 +追 +退 +送 +适 +逃 +逅 +逆 +选 +逊 +逍 +透 +逐 +递 +途 +逕 +逗 +這 +通 +逛 +逝 +逞 +速 +造 +逢 +連 +逮 +週 +進 +逵 +逶 +逸 +逻 +逼 +逾 +遁 +遂 +遅 +遇 +遊 +運 +遍 +過 +遏 +遐 +遑 +遒 +道 +達 +違 +遗 +遙 +遛 +遜 +遞 +遠 +遢 +遣 +遥 +遨 +適 +遭 +遮 +遲 +遴 +遵 +遶 +遷 +選 +遺 +遼 +遽 +避 +邀 +邁 +邂 +邃 +還 +邇 +邈 +邊 +邋 +邏 +邑 +邓 +邕 +邛 +邝 +邢 +那 +邦 +邨 +邪 +邬 +邮 +邯 +邰 +邱 +邳 +邵 +邸 +邹 +邺 +邻 +郁 +郅 +郊 +郎 +郑 +郜 +郝 +郡 +郢 +郤 +郦 +郧 +部 +郫 +郭 +郴 +郵 +郷 +郸 +都 +鄂 +鄉 +鄒 +鄔 +鄙 +鄞 +鄢 +鄧 +鄭 +鄰 +鄱 +鄲 +鄺 +酉 +酊 +酋 +酌 +配 +酐 +酒 +酗 +酚 +酝 +酢 +酣 +酥 +酩 +酪 +酬 +酮 +酯 +酰 +酱 +酵 +酶 +酷 +酸 +酿 +醃 +醇 +醉 +醋 +醍 +醐 +醒 +醚 +醛 +醜 +醞 +醣 +醪 +醫 +醬 +醮 +醯 +醴 +醺 +釀 +釁 +采 +釉 +释 +釋 +里 +重 +野 +量 +釐 +金 +釗 +釘 +釜 +針 +釣 +釦 +釧 +釵 +鈀 +鈉 +鈍 +鈎 +鈔 +鈕 +鈞 +鈣 +鈦 +鈪 +鈴 +鈺 +鈾 +鉀 +鉄 +鉅 +鉉 +鉑 +鉗 +鉚 +鉛 +鉤 +鉴 +鉻 +銀 +銃 +銅 +銑 +銓 +銖 +銘 +銜 +銬 +銭 +銮 +銳 +銷 +銹 +鋁 +鋅 +鋒 +鋤 +鋪 +鋰 +鋸 +鋼 +錄 +錐 +錘 +錚 +錠 +錢 +錦 +錨 +錫 +錮 +錯 +録 +錳 +錶 +鍊 +鍋 +鍍 +鍛 +鍥 +鍰 +鍵 +鍺 +鍾 +鎂 +鎊 +鎌 +鎏 +鎔 +鎖 +鎗 +鎚 +鎧 +鎬 +鎮 +鎳 +鏈 +鏖 +鏗 +鏘 +鏞 +鏟 +鏡 +鏢 +鏤 +鏽 +鐘 +鐮 +鐲 +鐳 +鐵 +鐸 +鐺 +鑄 +鑊 +鑑 +鑒 +鑣 +鑫 +鑰 +鑲 +鑼 +鑽 +鑾 +鑿 +针 +钉 +钊 +钎 +钏 +钒 +钓 +钗 +钙 +钛 +钜 +钝 +钞 +钟 +钠 +钡 +钢 +钣 +钤 +钥 +钦 +钧 +钨 +钩 +钮 +钯 +钰 +钱 +钳 +钴 +钵 +钺 +钻 +钼 +钾 +钿 +铀 +铁 +铂 +铃 +铄 +铅 +铆 +铉 +铎 +铐 +铛 +铜 +铝 +铠 +铡 +铢 +铣 +铤 +铨 +铩 +铬 +铭 +铮 +铰 +铲 +铵 +银 +铸 +铺 +链 +铿 +销 +锁 +锂 +锄 +锅 +锆 +锈 +锉 +锋 +锌 +锏 +锐 +锑 +错 +锚 +锟 +锡 +锢 +锣 +锤 +锥 +锦 +锭 +键 +锯 +锰 +锲 +锵 +锹 +锺 +锻 +镀 +镁 +镂 +镇 +镉 +镌 +镍 +镐 +镑 +镕 +镖 +镗 +镛 +镜 +镣 +镭 +镯 +镰 +镳 +镶 +長 +长 +門 +閃 +閉 +開 +閎 +閏 +閑 +閒 +間 +閔 +閘 +閡 +関 +閣 +閥 +閨 +閩 +閱 +閲 +閹 +閻 +閾 +闆 +闇 +闊 +闌 +闍 +闔 +闕 +闖 +闘 +關 +闡 +闢 +门 +闪 +闫 +闭 +问 +闯 +闰 +闲 +间 +闵 +闷 +闸 +闹 +闺 +闻 +闽 +闾 +阀 +阁 +阂 +阅 +阆 +阇 +阈 +阉 +阎 +阐 +阑 +阔 +阕 +阖 +阙 +阚 +阜 +队 +阡 +阪 +阮 +阱 +防 +阳 +阴 +阵 +阶 +阻 +阿 +陀 +陂 +附 +际 +陆 +陇 +陈 +陋 +陌 +降 +限 +陕 +陛 +陝 +陞 +陟 +陡 +院 +陣 +除 +陨 +险 +陪 +陰 +陲 +陳 +陵 +陶 +陷 +陸 +険 +陽 +隅 +隆 +隈 +隊 +隋 +隍 +階 +随 +隐 +隔 +隕 +隘 +隙 +際 +障 +隠 +隣 +隧 +隨 +險 +隱 +隴 +隶 +隸 +隻 +隼 +隽 +难 +雀 +雁 +雄 +雅 +集 +雇 +雉 +雋 +雌 +雍 +雎 +雏 +雑 +雒 +雕 +雖 +雙 +雛 +雜 +雞 +離 +難 +雨 +雪 +雯 +雰 +雲 +雳 +零 +雷 +雹 +電 +雾 +需 +霁 +霄 +霆 +震 +霈 +霉 +霊 +霍 +霎 +霏 +霑 +霓 +霖 +霜 +霞 +霧 +霭 +霰 +露 +霸 +霹 +霽 +霾 +靂 +靄 +靈 +青 +靓 +靖 +静 +靚 +靛 +靜 +非 +靠 +靡 +面 +靥 +靦 +革 +靳 +靴 +靶 +靼 +鞅 +鞋 +鞍 +鞏 +鞑 +鞘 +鞠 +鞣 +鞦 +鞭 +韆 +韋 +韌 +韓 +韜 +韦 +韧 +韩 +韬 +韭 +音 +韵 +韶 +韻 +響 +頁 +頂 +頃 +項 +順 +須 +頌 +預 +頑 +頒 +頓 +頗 +領 +頜 +頡 +頤 +頫 +頭 +頰 +頷 +頸 +頹 +頻 +頼 +顆 +題 +額 +顎 +顏 +顔 +願 +顛 +類 +顧 +顫 +顯 +顱 +顴 +页 +顶 +顷 +项 +顺 +须 +顼 +顽 +顾 +顿 +颁 +颂 +预 +颅 +领 +颇 +颈 +颉 +颊 +颌 +颍 +颐 +频 +颓 +颔 +颖 +颗 +题 +颚 +颛 +颜 +额 +颞 +颠 +颡 +颢 +颤 +颦 +颧 +風 +颯 +颱 +颳 +颶 +颼 +飄 +飆 +风 +飒 +飓 +飕 +飘 +飙 +飚 +飛 +飞 +食 +飢 +飨 +飩 +飪 +飯 +飲 +飼 +飽 +飾 +餃 +餅 +餉 +養 +餌 +餐 +餒 +餓 +餘 +餚 +餛 +餞 +餡 +館 +餮 +餵 +餾 +饅 +饈 +饋 +饌 +饍 +饑 +饒 +饕 +饗 +饞 +饥 +饨 +饪 +饬 +饭 +饮 +饯 +饰 +饱 +饲 +饴 +饵 +饶 +饷 +饺 +饼 +饽 +饿 +馀 +馁 +馄 +馅 +馆 +馈 +馋 +馍 +馏 +馒 +馔 +首 +馗 +香 +馥 +馨 +馬 +馭 +馮 +馳 +馴 +駁 +駄 +駅 +駆 +駐 +駒 +駕 +駛 +駝 +駭 +駱 +駿 +騁 +騎 +騏 +験 +騙 +騨 +騰 +騷 +驀 +驅 +驊 +驍 +驒 +驕 +驗 +驚 +驛 +驟 +驢 +驥 +马 +驭 +驮 +驯 +驰 +驱 +驳 +驴 +驶 +驷 +驸 +驹 +驻 +驼 +驾 +驿 +骁 +骂 +骄 +骅 +骆 +骇 +骈 +骊 +骋 +验 +骏 +骐 +骑 +骗 +骚 +骛 +骜 +骞 +骠 +骡 +骤 +骥 +骧 +骨 +骯 +骰 +骶 +骷 +骸 +骼 +髂 +髅 +髋 +髏 +髒 +髓 +體 +髖 +高 +髦 +髪 +髮 +髯 +髻 +鬃 +鬆 +鬍 +鬓 +鬚 +鬟 +鬢 +鬣 +鬥 +鬧 +鬱 +鬼 +魁 +魂 +魄 +魅 +魇 +魍 +魏 +魔 +魘 +魚 +魯 +魷 +鮑 +鮨 +鮪 +鮭 +鮮 +鯉 +鯊 +鯖 +鯛 +鯨 +鯰 +鯽 +鰍 +鰓 +鰭 +鰲 +鰻 +鰾 +鱈 +鱉 +鱔 +鱗 +鱷 +鱸 +鱼 +鱿 +鲁 +鲈 +鲍 +鲑 +鲛 +鲜 +鲟 +鲢 +鲤 +鲨 +鲫 +鲱 +鲲 +鲶 +鲷 +鲸 +鳃 +鳄 +鳅 +鳌 +鳍 +鳕 +鳖 +鳗 +鳝 +鳞 +鳥 +鳩 +鳳 +鳴 +鳶 +鴉 +鴕 +鴛 +鴦 +鴨 +鴻 +鴿 +鵑 +鵜 +鵝 +鵡 +鵬 +鵰 +鵲 +鶘 +鶩 +鶯 +鶴 +鷗 +鷲 +鷹 +鷺 +鸚 +鸞 +鸟 +鸠 +鸡 +鸢 +鸣 +鸥 +鸦 +鸨 +鸪 +鸭 +鸯 +鸳 +鸵 +鸽 +鸾 +鸿 +鹂 +鹃 +鹄 +鹅 +鹈 +鹉 +鹊 +鹌 +鹏 +鹑 +鹕 +鹘 +鹜 +鹞 +鹤 +鹦 +鹧 +鹫 +鹭 +鹰 +鹳 +鹵 +鹹 +鹼 +鹽 +鹿 +麂 +麋 +麒 +麓 +麗 +麝 +麟 +麥 +麦 +麩 +麴 +麵 +麸 +麺 +麻 +麼 +麽 +麾 +黃 +黄 +黍 +黎 +黏 +黑 +黒 +黔 +默 +黛 +黜 +黝 +點 +黠 +黨 +黯 +黴 +鼋 +鼎 +鼐 +鼓 +鼠 +鼬 +鼹 +鼻 +鼾 +齁 +齊 +齋 +齐 +齒 +齡 +齢 +齣 +齦 +齿 +龄 +龅 +龈 +龊 +龋 +龌 +龍 +龐 +龔 +龕 +龙 +龚 +龛 +龜 +龟 +︰ +︱ +︶ +︿ +﹁ +﹂ +﹍ +﹏ +﹐ +﹑ +﹒ +﹔ +﹕ +﹖ +﹗ +﹙ +﹚ +﹝ +﹞ +﹡ +﹣ +! +" +# +$ +% +& +' +( +) +* ++ +, +- +. +/ +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +: +; +< += +> +? +@ +[ +\ +] +^ +_ +` +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z +{ +| +} +~ +。 +「 +」 +、 +・ +ッ +ー +イ +ク +シ +ス +ト +ノ +フ +ラ +ル +ン +゙ +゚ + ̄ +¥ +👍 +🔥 +😂 +😎 +... +yam +10 +2017 +12 +11 +2016 +20 +30 +15 +06 +lofter +##s +2015 +by +16 +14 +18 +13 +24 +17 +2014 +21 +##0 +22 +19 +25 +23 +com +100 +00 +05 +2013 +##a +03 +09 +08 +28 +##2 +50 +01 +04 +##1 +27 +02 +2012 +##3 +26 +##e +07 +##8 +##5 +##6 +##4 +##9 +##7 +29 +2011 +40 +##t +2010 +##o +##d +##i +2009 +##n +app +www +the +##m +31 +##c +##l +##y +##r +##g +2008 +60 +http +200 +qq +##p +80 +##f +google +pixnet +90 +cookies +tripadvisor +500 +##er +##k +35 +##h +facebook +2007 +2000 +70 +##b +of +##x +##u +45 +300 +iphone +32 +1000 +2006 +48 +ip +36 +in +38 +3d +##w +##ing +55 +ctrip +##on +##v +33 +##の +to +34 +400 +id +2005 +it +37 +windows +llc +top +99 +42 +39 +000 +led +at +##an +41 +51 +52 +46 +49 +43 +53 +44 +##z +android +58 +and +59 +2004 +56 +vr +##か +5000 +2003 +47 +blogthis +twitter +54 +##le +150 +ok +2018 +57 +75 +cn +no +ios +##in +##mm +##00 +800 +on +te +3000 +65 +2001 +360 +95 +ig +lv +120 +##ng +##を +##us +##に +pc +てす +── +600 +##te +85 +2002 +88 +##ed +html +ncc +wifi +email +64 +blog +is +##10 +##て +mail +online +##al +dvd +##ic +studio +##は +##℃ +##ia +##と +line +vip +72 +##q +98 +##ce +##en +for +##is +##ra +##es +##j +usb +net +cp +1999 +asia +4g +##cm +diy +new +3c +##お +ta +66 +language +vs +apple +tw +86 +web +##ne +ipad +62 +you +##re +101 +68 +##tion +ps +de +bt +pony +atm +##2017 +1998 +67 +##ch +ceo +##or +go +##na +av +pro +cafe +96 +pinterest +97 +63 +pixstyleme3c +##ta +more +said +##2016 +1997 +mp3 +700 +##ll +nba +jun +##20 +92 +tv +1995 +pm +61 +76 +nbsp +250 +##ie +linux +##ma +cd +110 +hd +##17 +78 +##ion +77 +6000 +am +##th +##st +94 +##se +##et +69 +180 +gdp +my +105 +81 +abc +89 +flash +79 +one +93 +1990 +1996 +##ck +gps +##も +##ly +web885 +106 +2020 +91 +##ge +4000 +1500 +xd +boss +isbn +1994 +org +##ry +me +love +##11 +0fork +73 +##12 +3g +##ter +##ar +71 +82 +##la +hotel +130 +1970 +pk +83 +87 +140 +ie +##os +##30 +##el +74 +##50 +seo +cpu +##ml +p2p +84 +may +##る +sun +tue +internet +cc +posted +youtube +##at +##ン +##man +ii +##ル +##15 +abs +nt +pdf +yahoo +ago +1980 +##it +news +mac +104 +##てす +##me +##り +java +1992 +spa +##de +##nt +hk +all +plus +la +1993 +##mb +##16 +##ve +west +##da +160 +air +##い +##ps +から +##to +1989 +logo +htc +php +https +fi +momo +##son +sat +##ke +##80 +ebd +suv +wi +day +apk +##88 +##um +mv +galaxy +wiki +or +brake +##ス +1200 +する +this +1991 +mon +##こ +❤2017 +po +##ない +javascript +life +home +june +##ss +system +900 +##ー +##0 +pp +1988 +world +fb +4k +br +##as +ic +ai +leonardo +safari +##60 +live +free +xx +wed +win7 +kiehl +##co +lg +o2o +##go +us +235 +1949 +mm +しい +vfm +kanye +##90 +##2015 +##id +jr +##ey +123 +rss +##sa +##ro +##am +##no +thu +fri +350 +##sh +##ki +103 +comments +name +##のて +##pe +##ine +max +1987 +8000 +uber +##mi +##ton +wordpress +office +1986 +1985 +##ment +107 +bd +win10 +##ld +##li +gmail +bb +dior +##rs +##ri +##rd +##ます +up +cad +##® +dr +して +read +##21 +をお +##io +##99 +url +1984 +pvc +paypal +show +policy +##40 +##ty +##18 +with +##★ +##01 +txt +102 +##ba +dna +from +post +mini +ar +taiwan +john +##ga +privacy +agoda +##13 +##ny +word +##24 +##22 +##by +##ur +##hz +1982 +##ang +265 +cookie +netscape +108 +##ka +##~ +##ad +house +share +note +ibm +code +hello +nike +sim +survey +##016 +1979 +1950 +wikia +##32 +##017 +5g +cbc +##tor +##kg +1983 +##rt +##14 +campaign +store +2500 +os +##ct +##ts +##° +170 +api +##ns +365 +excel +##な +##ao +##ら +##し +~~ +##nd +university +163 +には +518 +##70 +##ya +##il +##25 +pierre +ipo +0020 +897 +##23 +hotels +##ian +のお +125 +years +6606 +##ers +##26 +high +##day +time +##ay +bug +##line +##く +##す +##be +xp +talk2yam +yamservice +10000 +coco +##dy +sony +##ies +1978 +microsoft +david +people +##ha +1960 +instagram +intel +その +##ot +iso +1981 +##va +115 +##mo +##land +xxx +man +co +ltxsw +##ation +baby +220 +##pa +##ol +1945 +7000 +tag +450 +##ue +msn +##31 +oppo +##ト +##ca +control +##om +st +chrome +##ure +##ん +be +##き +lol +##19 +した +##bo +240 +lady +##100 +##way +##から +4600 +##ko +##do +##un +4s +corporation +168 +##ni +herme +##28 +cp +978 +##up +##06 +ui +##ds +ppt +admin +three +します +bbc +re +128 +##48 +ca +##015 +##35 +hp +##ee +tpp +##た +##ive +×× +root +##cc +##ました +##ble +##ity +adobe +park +114 +et +oled +city +##ex +##ler +##ap +china +##book +20000 +view +##ice +global +##km +your +hong +##mg +out +##ms +ng +ebay +##29 +menu +ubuntu +##cy +rom +##view +open +ktv +do +server +##lo +if +english +##ね +##5 +##oo +1600 +##02 +step1 +kong +club +135 +july +inc +1976 +mr +hi +##net +touch +##ls +##ii +michael +lcd +##05 +##33 +phone +james +step2 +1300 +ios9 +##box +dc +##2 +##ley +samsung +111 +280 +pokemon +css +##ent +##les +いいえ +##1 +s8 +atom +play +bmw +##said +sa +etf +ctrl +♥yoyo♥ +##55 +2025 +##2014 +##66 +adidas +amazon +1958 +##ber +##ner +visa +##77 +##der +1800 +connectivity +##hi +firefox +109 +118 +hr +so +style +mark +pop +ol +skip +1975 +as +##27 +##ir +##61 +190 +mba +##う +##ai +le +##ver +1900 +cafe2017 +lte +super +113 +129 +##ron +amd +like +##☆ +are +##ster +we +##sk +paul +data +international +##ft +longchamp +ssd +good +##ート +##ti +reply +##my +↓↓↓ +apr +star +##ker +source +136 +js +112 +get +force +photo +##one +126 +##2013 +##ow +link +bbs +1972 +goods +##lin +python +119 +##ip +game +##ics +##ません +blue +##● +520 +##45 +page +itunes +##03 +1955 +260 +1968 +gt +gif +618 +##ff +##47 +group +くたさい +about +bar +ganji +##nce +music +lee +not +1977 +1971 +1973 +##per +an +faq +comment +##って +days +##ock +116 +##bs +1974 +1969 +v1 +player +1956 +xbox +sql +fm +f1 +139 +##ah +210 +##lv +##mp +##000 +melody +1957 +##3 +550 +17life +199 +1966 +xml +market +##au +##71 +999 +##04 +what +gl +##95 +##age +tips +##68 +book +##ting +mysql +can +1959 +230 +##ung +wonderland +watch +10℃ +##ction +9000 +mar +mobile +1946 +1962 +article +##db +part +▲top +party +って +1967 +1964 +1948 +##07 +##ore +##op +この +dj +##78 +##38 +010 +main +225 +1965 +##ong +art +320 +ad +134 +020 +##73 +117 +pm2 +japan +228 +##08 +ts +1963 +##ica +der +sm +##36 +2019 +##wa +ct +##7 +##や +##64 +1937 +homemesh +search +##85 +##れは +##tv +##di +macbook +##9 +##くたさい +service +##♥ +type +った +750 +##ier +##si +##75 +##います +##ok +best +##ット +goris +lock +##った +cf +3m +big +##ut +ftp +carol +##vi +10 +1961 +happy +sd +##ac +122 +anti +pe +cnn +iii +1920 +138 +##ラ +1940 +esp +jan +tags +##98 +##51 +august +vol +##86 +154 +##™ +##fs +##れ +##sion +design +ac +##ム +press +jordan +ppp +that +key +check +##6 +##tt +##㎡ +1080p +##lt +power +##42 +1952 +##bc +vivi +##ック +he +133 +121 +jpg +##rry +201 +175 +3500 +1947 +nb +##ted +##rn +しています +1954 +usd +##t00 +master +##ンク +001 +model +##58 +al +##09 +1953 +##34 +ram +goo +ても +##ui +127 +1930 +red +##ary +rpg +item +##pm +##41 +270 +##za +project +##2012 +hot +td +blogabstract +##ger +##62 +650 +##44 +gr2 +##します +##m +black +electronic +nfc +year +asus +また +html5 +cindy +##hd +m3 +132 +esc +##od +booking +##53 +fed +tvb +##81 +##ina +mit +165 +##いる +chan +192 +distribution +next +になる +peter +bios +steam +cm +1941 +にも +pk10 +##ix +##65 +##91 +dec +nasa +##ana +icecat +00z +b1 +will +##46 +li +se +##ji +##み +##ard +oct +##ain +jp +##ze +##bi +cio +##56 +smart +h5 +##39 +##port +curve +vpn +##nm +##dia +utc +##あり +12345678910 +##52 +rmvb +chanel +a4 +miss +##and +##im +media +who +##63 +she +girl +5s +124 +vera +##して +class +vivo +king +##フ +##ei +national +ab +1951 +5cm +888 +145 +ipod +ap +1100 +5mm +211 +ms +2756 +##69 +mp4 +msci +##po +##89 +131 +mg +index +380 +##bit +##out +##zz +##97 +##67 +158 +apec +##8 +photoshop +opec +¥799 +ては +##96 +##tes +##ast +2g +○○ +##ール +¥2899 +##ling +##よ +##ory +1938 +##ical +kitty +content +##43 +step3 +##cn +win8 +155 +vc +1400 +iphone7 +robert +##した +tcl +137 +beauty +##87 +en +dollars +##ys +##oc +step +pay +yy +a1 +##2011 +##lly +##ks +##♪ +1939 +188 +download +1944 +sep +exe +ph +います +school +gb +center +pr +street +##board +uv +##37 +##lan +winrar +##que +##ua +##com +1942 +1936 +480 +gpu +##4 +ettoday +fu +tom +##54 +##ren +##via +149 +##72 +b2b +144 +##79 +##tch +rose +arm +mb +##49 +##ial +##nn +nvidia +step4 +mvp +00㎡ +york +156 +##イ +how +cpi +591 +2765 +gov +kg +joe +##xx +mandy +pa +##ser +copyright +fashion +1935 +don +##け +ecu +##ist +##art +erp +wap +have +##lm +talk +##ek +##ning +##if +ch +##ite +video +1943 +cs +san +iot +look +##84 +##2010 +##ku +october +##ux +trump +##hs +##ide +box +141 +first +##ins +april +##ight +##83 +185 +angel +protected +aa +151 +162 +x1 +m2 +##fe +##× +##ho +size +143 +min +ofo +fun +gomaji +ex +hdmi +food +dns +march +chris +kevin +##のか +##lla +##pp +##ec +ag +ems +6s +720p +##rm +##ham +off +##92 +asp +team +fandom +ed +299 +▌♥ +##ell +info +されています +##82 +sina +4066 +161 +##able +##ctor +330 +399 +315 +dll +rights +ltd +idc +jul +3kg +1927 +142 +ma +surface +##76 +##ク +~~~ +304 +mall +eps +146 +green +##59 +map +space +donald +v2 +sodu +##light +1931 +148 +1700 +まて +310 +reserved +htm +##han +##57 +2d +178 +mod +##ise +##tions +152 +ti +##shi +doc +1933 +icp +055 +wang +##ram +shopping +aug +##pi +##well +now +wam +b2 +からお +##hu +236 +1928 +##gb +266 +f2 +##93 +153 +mix +##ef +##uan +bwl +##plus +##res +core +##ess +tea +5℃ +hktvmall +nhk +##ate +list +##ese +301 +feb +4m +inn +ての +nov +159 +12345 +daniel +##ci +pass +##bet +##nk +coffee +202 +ssl +airbnb +##ute +fbi +woshipm +skype +ea +cg +sp +##fc +##www +yes +edge +alt +007 +##94 +fpga +##ght +##gs +iso9001 +さい +##ile +##wood +##uo +image +lin +icon +american +##em +1932 +set +says +##king +##tive +blogger +##74 +なと +256 +147 +##ox +##zy +##red +##ium +##lf +nokia +claire +##リ +##ding +november +lohas +##500 +##tic +##マ +##cs +##ある +##che +##ire +##gy +##ult +db +january +win +##カ +166 +road +ptt +##ま +##つ +198 +##fa +##mer +anna +pchome +はい +udn +ef +420 +##time +##tte +2030 +##ア +g20 +white +かかります +1929 +308 +garden +eleven +di +##おります +chen +309b +777 +172 +young +cosplay +ちてない +4500 +bat +##123 +##tra +##ては +kindle +npc +steve +etc +##ern +##| +call +xperia +ces +travel +sk +s7 +##ous +1934 +##int +みいたたけます +183 +edu +file +cho +qr +##car +##our +186 +##ant +##d +eric +1914 +rends +##jo +##する +mastercard +##2000 +kb +##min +290 +##ino +vista +##ris +##ud +jack +2400 +##set +169 +pos +1912 +##her +##ou +taipei +しく +205 +beta +##ませんか +232 +##fi +express +255 +body +##ill +aphojoy +user +december +meiki +##ick +tweet +richard +##av +##ᆫ +iphone6 +##dd +ちてすか +views +##mark +321 +pd +##00 +times +##▲ +level +##ash +10g +point +5l +##ome +208 +koreanmall +##ak +george +q2 +206 +wma +tcp +##200 +スタッフ +full +mlb +##lle +##watch +tm +run +179 +911 +smith +business +##und +1919 +color +##tal +222 +171 +##less +moon +4399 +##rl +update +pcb +shop +499 +157 +little +なし +end +##mhz +van +dsp +easy +660 +##house +##key +history +##o +oh +##001 +##hy +##web +oem +let +was +##2009 +##gg +review +##wan +182 +##°c +203 +uc +title +##val +united +233 +2021 +##ons +doi +trivago +overdope +sbs +##ance +##ち +grand +special +573032185 +imf +216 +wx17house +##so +##ーム +audi +##he +london +william +##rp +##ake +science +beach +cfa +amp +ps4 +880 +##800 +##link +##hp +crm +ferragamo +bell +make +##eng +195 +under +zh +photos +2300 +##style +##ント +via +176 +da +##gi +company +i7 +##ray +thomas +370 +ufo +i5 +##max +plc +ben +back +research +8g +173 +mike +##pc +##ッフ +september +189 +##ace +vps +february +167 +pantos +wp +lisa +1921 +★★ +jquery +night +long +offer +##berg +##news +1911 +##いて +ray +fks +wto +せます +over +164 +340 +##all +##rus +1924 +##888 +##works +blogtitle +loftpermalink +##→ +187 +martin +test +ling +km +##め +15000 +fda +v3 +##ja +##ロ +wedding +かある +outlet +family +##ea +をこ +##top +story +##ness +salvatore +##lu +204 +swift +215 +room +している +oracle +##ul +1925 +sam +b2c +week +pi +rock +##のは +##a +##けと +##ean +##300 +##gle +cctv +after +chinese +##back +powered +x2 +##tan +1918 +##nes +##イン +canon +only +181 +##zi +##las +say +##oe +184 +##sd +221 +##bot +##world +##zo +sky +made +top100 +just +1926 +pmi +802 +234 +gap +##vr +177 +les +174 +▲topoct +ball +vogue +vi +ing +ofweek +cos +##list +##ort +▲topmay +##なら +##lon +として +last +##tc +##of +##bus +##gen +real +eva +##コ +a3 +nas +##lie +##ria +##coin +##bt +▲topapr +his +212 +cat +nata +vive +health +⋯⋯ +drive +sir +▲topmar +du +cup +##カー +##ook +##よう +##sy +alex +msg +tour +しました +3ce +##word +193 +ebooks +r8 +block +318 +##より +2200 +nice +pvp +207 +months +1905 +rewards +##ther +1917 +0800 +##xi +##チ +##sc +micro +850 +gg +blogfp +op +1922 +daily +m1 +264 +true +##bb +ml +##tar +##のお +##ky +anthony +196 +253 +##yo +state +218 +##ara +##aa +##rc +##tz +##ston +より +gear +##eo +##ade +ge +see +1923 +##win +##ura +ss +heart +##den +##ita +down +##sm +el +png +2100 +610 +rakuten +whatsapp +bay +dream +add +##use +680 +311 +pad +gucci +mpv +##ode +##fo +island +▲topjun +##▼ +223 +jason +214 +chicago +##❤ +しの +##hone +io +##れる +##ことか +sogo +be2 +##ology +990 +cloud +vcd +##con +2~3 +##ford +##joy +##kb +##こさいます +##rade +but +##ach +docker +##ful +rfid +ul +##ase +hit +ford +##star +580 +##○ +11 +a2 +sdk +reading +edited +##are +cmos +##mc +238 +siri +light +##ella +##ため +bloomberg +##read +pizza +##ison +jimmy +##vm +college +node +journal +ba +18k +##play +245 +##cer +20 +magic +##yu +191 +jump +288 +tt +##ings +asr +##lia +3200 +step5 +network +##cd +mc +いします +1234 +pixstyleme +273 +##600 +2800 +money +★★★★★ +1280 +12 +430 +bl +みの +act +##tus +tokyo +##rial +##life +emba +##ae +saas +tcs +##rk +##wang +summer +##sp +ko +##ving +390 +premium +##その +netflix +##ヒ +uk +mt +##lton +right +frank +two +209 +える +##ple +##cal +021 +##んな +##sen +##ville +hold +nexus +dd +##ius +てお +##mah +##なく +tila +zero +820 +ce +##tin +resort +##ws +charles +old +p10 +5d +report +##360 +##ru +##には +bus +vans +lt +##est +pv +##レ +links +rebecca +##ツ +##dm +azure +##365 +きな +limited +bit +4gb +##mon +1910 +moto +##eam +213 +1913 +var +eos +なとの +226 +blogspot +された +699 +e3 +dos +dm +fc +##ments +##ik +##kw +boy +##bin +##ata +960 +er +##せ +219 +##vin +##tu +##ula +194 +##∥ +station +##ろ +##ature +835 +files +zara +hdr +top10 +nature +950 +magazine +s6 +marriott +##シ +avira +case +##っと +tab +##ran +tony +##home +oculus +im +##ral +jean +saint +cry +307 +rosie +##force +##ini +ice +##bert +のある +##nder +##mber +pet +2600 +##◆ +plurk +▲topdec +##sis +00kg +▲topnov +720 +##ence +tim +##ω +##nc +##ても +##name +log +ips +great +ikea +malaysia +unix +##イト +3600 +##ncy +##nie +12000 +akb48 +##ye +##oid +404 +##chi +##いた +oa +xuehai +##1000 +##orm +##rf +275 +さん +##ware +##リー +980 +ho +##pro +text +##era +560 +bob +227 +##ub +##2008 +8891 +scp +avi +##zen +2022 +mi +wu +museum +qvod +apache +lake +jcb +▲topaug +★★★ +ni +##hr +hill +302 +ne +weibo +490 +ruby +##ーシ +##ヶ +##row +4d +▲topjul +iv +##ish +github +306 +mate +312 +##スト +##lot +##ane +andrew +のハイト +##tina +t1 +rf +ed2k +##vel +##900 +way +final +りの +ns +5a +705 +197 +##メ +sweet +bytes +##ene +▲topjan +231 +##cker +##2007 +##px +100g +topapp +229 +helpapp +rs +low +14k +g4g +care +630 +ldquo +あり +##fork +leave +rm +edition +##gan +##zon +##qq +▲topsep +##google +##ism +gold +224 +explorer +##zer +toyota +category +select +visual +##labels +restaurant +##md +posts +s1 +##ico +もっと +angelababy +123456 +217 +sports +s3 +mbc +1915 +してくたさい +shell +x86 +candy +##new +kbs +face +xl +470 +##here +4a +swissinfo +v8 +▲topfeb +dram +##ual +##vice +3a +##wer +sport +q1 +ios10 +public +int +card +##c +ep +au +rt +##れた +1080 +bill +##mll +kim +30 +460 +wan +##uk +##ミ +x3 +298 +0t +scott +##ming +239 +e5 +##3d +h7n9 +worldcat +brown +##あります +##vo +##led +##580 +##ax +249 +410 +##ert +paris +##~6 +polo +925 +##lr +599 +##ナ +capital +##hing +bank +cv +1g +##chat +##s +##たい +adc +##ule +2m +##e +digital +hotmail +268 +##pad +870 +bbq +quot +##ring +before +wali +##まて +mcu +2k +2b +という +costco +316 +north +333 +switch +##city +##p +philips +##mann +management +panasonic +##cl +##vd +##ping +##rge +alice +##lk +##ましょう +css3 +##ney +vision +alpha +##ular +##400 +##tter +lz +にお +##ありません +mode +gre +1916 +pci +##tm +237 +1~2 +##yan +##そ +について +##let +##キ +work +war +coach +ah +mary +##ᅵ +huang +##pt +a8 +pt +follow +##berry +1895 +##ew +a5 +ghost +##ション +##wn +##og +south +##code +girls +##rid +action +villa +git +r11 +table +games +##cket +error +##anonymoussaid +##ag +here +##ame +##gc +qa +##■ +##lis +gmp +##gin +vmalife +##cher +yu +wedding +##tis +demo +dragon +530 +soho +social +bye +##rant +river +orz +acer +325 +##↑ +##ース +##ats +261 +del +##ven +440 +ups +##ように +##ター +305 +value +macd +yougou +##dn +661 +##ano +ll +##urt +##rent +continue +script +##wen +##ect +paper +263 +319 +shift +##chel +##フト +##cat +258 +x5 +fox +243 +##さん +car +aaa +##blog +loading +##yn +##tp +kuso +799 +si +sns +イカせるテンマ +ヒンクテンマ3 +rmb +vdc +forest +central +prime +help +ultra +##rmb +##ような +241 +square +688 +##しい +のないフロクに +##field +##reen +##ors +##ju +c1 +start +510 +##air +##map +cdn +##wo +cba +stephen +m8 +100km +##get +opera +##base +##ood +vsa +com™ +##aw +##ail +251 +なのて +count +t2 +##ᅡ +##een +2700 +hop +##gp +vsc +tree +##eg +##ose +816 +285 +##ories +##shop +alphago +v4 +1909 +simon +##ᆼ +fluke62max +zip +スホンサー +##sta +louis +cr +bas +##~10 +bc +##yer +hadoop +##ube +##wi +1906 +0755 +hola +##low +place +centre +5v +d3 +##fer +252 +##750 +##media +281 +540 +0l +exchange +262 +series +##ハー +##san +eb +##bank +##k +q3 +##nge +##mail +take +##lp +259 +1888 +client +east +cache +event +vincent +##ールを +きを +##nse +sui +855 +adchoice +##и +##stry +##なたの +246 +##zone +ga +apps +sea +##ab +248 +cisco +##タ +##rner +kymco +##care +dha +##pu +##yi +minkoff +royal +p1 +への +annie +269 +collection +kpi +playstation +257 +になります +866 +bh +##bar +queen +505 +radio +1904 +andy +armani +##xy +manager +iherb +##ery +##share +spring +raid +johnson +1908 +##ob +volvo +hall +##ball +v6 +our +taylor +##hk +bi +242 +##cp +kate +bo +water +technology +##rie +サイトは +277 +##ona +##sl +hpv +303 +gtx +hip +rdquo +jayz +stone +##lex +##rum +namespace +##やり +620 +##ale +##atic +des +##erson +##ql +##ves +##type +enter +##この +##てきます +d2 +##168 +##mix +##bian +との +a9 +jj +ky +##lc +access +movie +##hc +リストに +tower +##ration +##mit +ます +##nch +ua +tel +prefix +##o2 +1907 +##point +1901 +ott +~10 +##http +##ury +baidu +##ink +member +##logy +bigbang +nownews +##js +##shot +##tb +##こと +247 +eba +##tics +##lus +ける +v5 +spark +##ama +there +##ions +god +##lls +##down +hiv +##ress +burberry +day2 +##kv +◆◆ +jeff +related +film +edit +joseph +283 +##ark +cx +32gb +order +g9 +30000 +##ans +##tty +s5 +##bee +かあります +thread +xr +buy +sh +005 +land +spotify +mx +##ari +276 +##verse +×email +sf +why +##ことて +244 +7headlines +nego +sunny +dom +exo +401 +666 +positioning +fit +rgb +##tton +278 +kiss +alexa +adam +lp +みリストを +##g +mp +##ties +##llow +amy +##du +np +002 +institute +271 +##rth +##lar +2345 +590 +##des +sidebar +15 +imax +site +##cky +##kit +##ime +##009 +season +323 +##fun +##ンター +##ひ +gogoro +a7 +pu +lily +fire +twd600 +##ッセーシを +いて +##vis +30ml +##cture +##をお +information +##オ +close +friday +##くれる +yi +nick +てすか +##tta +##tel +6500 +##lock +cbd +economy +254 +かお +267 +tinker +double +375 +8gb +voice +##app +oops +channel +today +985 +##right +raw +xyz +##+ +jim +edm +##cent +7500 +supreme +814 +ds +##its +##asia +dropbox +##てすか +##tti +books +272 +100ml +##tle +##ller +##ken +##more +##boy +sex +309 +##dom +t3 +##ider +##なります +##unch +1903 +810 +feel +5500 +##かった +##put +により +s2 +mo +##gh +men +ka +amoled +div +##tr +##n1 +port +howard +##tags +ken +dnf +##nus +adsense +##а +ide +##へ +buff +thunder +##town +##ique +has +##body +auto +pin +##erry +tee +てした +295 +number +##the +##013 +object +psp +cool +udnbkk +16gb +##mic +miui +##tro +most +r2 +##alk +##nity +1880 +±0 +##いました +428 +s4 +law +version +##oa +n1 +sgs +docomo +##tf +##ack +henry +fc2 +##ded +##sco +##014 +##rite +286 +0mm +linkedin +##ada +##now +wii +##ndy +ucbug +##◎ +sputniknews +legalminer +##ika +##xp +2gb +##bu +q10 +oo +b6 +come +##rman +cheese +ming +maker +##gm +nikon +##fig +ppi +kelly +##ります +jchere +てきます +ted +md +003 +fgo +tech +##tto +dan +soc +##gl +##len +hair +earth +640 +521 +img +##pper +##a1 +##てきる +##ロク +acca +##ition +##ference +suite +##ig +outlook +##mond +##cation +398 +##pr +279 +101vip +358 +##999 +282 +64gb +3800 +345 +airport +##over +284 +##おり +jones +##ith +lab +##su +##いるのて +co2 +town +piece +##llo +no1 +vmware +24h +##qi +focus +reader +##admin +##ora +tb +false +##log +1898 +know +lan +838 +##ces +f4 +##ume +motel +stop +##oper +na +flickr +netcomponents +##af +##─ +pose +williams +local +##ound +##cg +##site +##iko +いお +274 +5m +gsm +con +##ath +1902 +friends +##hip +cell +317 +##rey +780 +cream +##cks +012 +##dp +facebooktwitterpinterestgoogle +sso +324 +shtml +song +swiss +##mw +##キンク +lumia +xdd +string +tiffany +522 +marc +られた +insee +russell +sc +dell +##ations +ok +camera +289 +##vs +##flow +##late +classic +287 +##nter +stay +g1 +mtv +512 +##ever +##lab +##nger +qe +sata +ryan +d1 +50ml +cms +##cing +su +292 +3300 +editor +296 +##nap +security +sunday +association +##ens +##700 +##bra +acg +##かり +sofascore +とは +mkv +##ign +jonathan +gary +build +labels +##oto +tesla +moba +qi +gohappy +general +ajax +1024 +##かる +サイト +society +##test +##urs +wps +fedora +##ich +mozilla +328 +##480 +##dr +usa +urn +##lina +##r +grace +##die +##try +##ader +1250 +##なり +elle +570 +##chen +##ᆯ +price +##ten +uhz +##ough +eq +##hen +states +push +session +balance +wow +506 +##cus +##py +when +##ward +##ep +34e +wong +library +prada +##サイト +##cle +running +##ree +313 +ck +date +q4 +##ctive +##ool +##> +mk +##ira +##163 +388 +die +secret +rq +dota +buffet +は1ヶ +e6 +##ez +pan +368 +ha +##card +##cha +2a +##さ +alan +day3 +eye +f3 +##end +france +keep +adi +rna +tvbs +##ala +solo +nova +##え +##tail +##ょう +support +##ries +##なる +##ved +base +copy +iis +fps +##ways +hero +hgih +profile +fish +mu +ssh +entertainment +chang +##wd +click +cake +##ond +pre +##tom +kic +pixel +##ov +##fl +product +6a +##pd +dear +##gate +es +yumi +audio +##² +##sky +echo +bin +where +##ture +329 +##ape +find +sap +isis +##なと +nand +##101 +##load +##ream +band +a6 +525 +never +##post +festival +50cm +##we +555 +guide +314 +zenfone +##ike +335 +gd +forum +jessica +strong +alexander +##ould +software +allen +##ious +program +360° +else +lohasthree +##gar +することかてきます +please +##れます +rc +##ggle +##ric +bim +50000 +##own +eclipse +355 +brian +3ds +##side +061 +361 +##other +##ける +##tech +##ator +485 +engine +##ged +##t +plaza +##fit +cia +ngo +westbrook +shi +tbs +50mm +##みませんか +sci +291 +reuters +##ily +contextlink +##hn +af +##cil +bridge +very +##cel +1890 +cambridge +##ize +15g +##aid +##data +790 +frm +##head +award +butler +##sun +meta +##mar +america +ps3 +puma +pmid +##すか +lc +670 +kitchen +##lic +オーフン5 +きなしソフトサーヒス +そして +day1 +future +★★★★ +##text +##page +##rris +pm1 +##ket +fans +##っています +1001 +christian +bot +kids +trackback +##hai +c3 +display +##hl +n2 +1896 +idea +さんも +##sent +airmail +##ug +##men +pwm +けます +028 +##lution +369 +852 +awards +schemas +354 +asics +wikipedia +font +##tional +##vy +c2 +293 +##れている +##dget +##ein +っている +contact +pepper +スキル +339 +##~5 +294 +##uel +##ument +730 +##hang +みてす +q5 +##sue +rain +##ndi +wei +swatch +##cept +わせ +331 +popular +##ste +##tag +p2 +501 +trc +1899 +##west +##live +justin +honda +ping +messenger +##rap +v9 +543 +##とは +unity +appqq +はすへて +025 +leo +##tone +##テ +##ass +uniqlo +##010 +502 +her +jane +memory +moneydj +##tical +human +12306 +していると +##m2 +coc +miacare +##mn +tmt +##core +vim +kk +##may +fan +target +use +too +338 +435 +2050 +867 +737 +fast +##2c +services +##ope +omega +energy +##わ +pinkoi +1a +##なから +##rain +jackson +##ement +##シャンルの +374 +366 +そんな +p9 +rd +##ᆨ +1111 +##tier +##vic +zone +##│ +385 +690 +dl +isofix +cpa +m4 +322 +kimi +めて +davis +##lay +lulu +##uck +050 +weeks +qs +##hop +920 +##n +ae +##ear +~5 +eia +405 +##fly +korea +jpeg +boost +##ship +small +##リア +1860 +eur +297 +425 +valley +##iel +simple +##ude +rn +k2 +##ena +されます +non +patrick +しているから +##ナー +feed +5757 +30g +process +well +qqmei +##thing +they +aws +lu +pink +##ters +##kin +または +board +##vertisement +wine +##ien +unicode +##dge +r1 +359 +##tant +いを +##twitter +##3c +cool1 +される +##れて +##l +isp +##012 +standard +45㎡2 +402 +##150 +matt +##fu +326 +##iner +googlemsn +pixnetfacebookyahoo +##ラン +x7 +886 +##uce +メーカー +sao +##ev +##きました +##file +9678 +403 +xddd +shirt +6l +##rio +##hat +3mm +givenchy +ya +bang +##lio +monday +crystal +ロクイン +##abc +336 +head +890 +ubuntuforumwikilinuxpastechat +##vc +##~20 +##rity +cnc +7866 +ipv6 +null +1897 +##ost +yang +imsean +tiger +##fet +##ンス +352 +##= +dji +327 +ji +maria +##come +##んて +foundation +3100 +##beth +##なった +1m +601 +active +##aft +##don +3p +sr +349 +emma +##khz +living +415 +353 +1889 +341 +709 +457 +sas +x6 +##face +pptv +x4 +##mate +han +sophie +##jing +337 +fifa +##mand +other +sale +inwedding +##gn +てきちゃいます +##mmy +##pmlast +bad +nana +nbc +してみてくたさいね +なとはお +##wu +##かあります +##あ +note7 +single +##340 +せからこ +してくたさい♪この +しにはとんとんワークケートを +するとあなたにもっとマッチした +ならワークケートへ +もみつかっちゃうかも +ワークケートの +##bel +window +##dio +##ht +union +age +382 +14 +##ivity +##y +コメント +domain +neo +##isa +##lter +5k +f5 +steven +##cts +powerpoint +tft +self +g2 +ft +##テル +zol +##act +mwc +381 +343 +もう +nbapop +408 +てある +eds +ace +##room +previous +author +tomtom +il +##ets +hu +financial +☆☆☆ +っています +bp +5t +chi +1gb +##hg +fairmont +cross +008 +gay +h2 +function +##けて +356 +also +1b +625 +##ータ +##raph +1894 +3~5 +##ils +i3 +334 +avenue +##host +による +##bon +##tsu +message +navigation +50g +fintech +h6 +##ことを +8cm +##ject +##vas +##firm +credit +##wf +xxxx +form +##nor +##space +huawei +plan +json +sbl +##dc +machine +921 +392 +wish +##120 +##sol +windows7 +edward +##ために +development +washington +##nsis +lo +818 +##sio +##ym +##bor +planet +##~8 +##wt +ieee +gpa +##めて +camp +ann +gm +##tw +##oka +connect +##rss +##work +##atus +wall +chicken +soul +2mm +##times +fa +##ather +##cord +009 +##eep +hitachi +gui +harry +##pan +e1 +disney +##press +##ーション +wind +386 +frigidaire +##tl +liu +hsu +332 +basic +von +ev +いた +てきる +スホンサーサイト +learning +##ull +expedia +archives +change +##wei +santa +cut +ins +6gb +turbo +brand +cf1 +508 +004 +return +747 +##rip +h1 +##nis +##をこ +128gb +##にお +3t +application +しており +emc +rx +##oon +384 +quick +412 +15058 +wilson +wing +chapter +##bug +beyond +##cms +##dar +##oh +zoom +e2 +trip +sb +##nba +rcep +342 +aspx +ci +080 +gc +gnu +める +##count +advanced +dance +dv +##url +##ging +367 +8591 +am09 +shadow +battle +346 +##i +##cia +##という +emily +##のてす +##tation +host +ff +techorz +sars +##mini +##mporary +##ering +nc +4200 +798 +##next +cma +##mbps +##gas +##ift +##dot +##ィ +455 +##~17 +amana +##りの +426 +##ros +ir +00㎡1 +##eet +##ible +##↓ +710 +ˋ▽ˊ +##aka +dcs +iq +##v +l1 +##lor +maggie +##011 +##iu +588 +##~1 +830 +##gt +1tb +articles +create +##burg +##iki +database +fantasy +##rex +##cam +dlc +dean +##you +hard +path +gaming +victoria +maps +cb +##lee +##itor +overchicstoretvhome +systems +##xt +416 +p3 +sarah +760 +##nan +407 +486 +x9 +install +second +626 +##ann +##ph +##rcle +##nic +860 +##nar +ec +##とう +768 +metro +chocolate +##rian +~4 +##table +##しています +skin +##sn +395 +mountain +##0mm +inparadise +6m +7x24 +ib +4800 +##jia +eeworld +creative +g5 +g3 +357 +parker +ecfa +village +からの +18000 +sylvia +サーヒス +hbl +##ques +##onsored +##x2 +##きます +##v4 +##tein +ie6 +383 +##stack +389 +ver +##ads +##baby +sound +bbe +##110 +##lone +##uid +ads +022 +gundam +351 +thinkpad +006 +scrum +match +##ave +mems +##470 +##oy +##なりました +##talk +glass +lamigo +span +##eme +job +##a5 +jay +wade +kde +498 +##lace +ocean +tvg +##covery +##r3 +##ners +##rea +junior +think +##aine +cover +##ision +##sia +↓↓ +##bow +msi +413 +458 +406 +##love +711 +801 +soft +z2 +##pl +456 +1840 +mobil +mind +##uy +427 +nginx +##oi +めた +##rr +6221 +##mple +##sson +##ーシてす +371 +##nts +91tv +comhd +crv3000 +##uard +1868 +397 +deep +lost +field +gallery +##bia +rate +spf +redis +traction +930 +icloud +011 +なら +fe +jose +372 +##tory +into +sohu +fx +899 +379 +kicstart2 +##hia +すく +##~3 +##sit +ra +24 +##walk +##xure +500g +##pact +pacific +xa +natural +carlo +##250 +##walker +1850 +##can +cto +gigi +516 +##サー +pen +##hoo +ob +matlab +##b +##yy +13913459 +##iti +mango +##bbs +sense +c5 +oxford +##ニア +walker +jennifer +##ola +course +##bre +701 +##pus +##rder +lucky +075 +##ぁ +ivy +なお +##nia +sotheby +side +##ugh +joy +##orage +##ush +##bat +##dt +364 +r9 +##2d +##gio +511 +country +wear +##lax +##~7 +##moon +393 +seven +study +411 +348 +lonzo +8k +##ェ +evolution +##イフ +##kk +gs +kd +##レス +arduino +344 +b12 +##lux +arpg +##rdon +cook +##x5 +dark +five +##als +##ida +とても +sign +362 +##ちの +something +20mm +##nda +387 +##posted +fresh +tf +1870 +422 +cam +##mine +##skip +##form +##ssion +education +394 +##tee +dyson +stage +##jie +want +##night +epson +pack +あります +##ppy +テリヘル +##█ +wd +##eh +##rence +left +##lvin +golden +mhz +discovery +##trix +##n2 +loft +##uch +##dra +##sse +speed +~1 +1mdb +sorry +welcome +##urn +wave +gaga +##lmer +teddy +##160 +トラックハック +せよ +611 +##f2016 +378 +rp +##sha +rar +##あなたに +##きた +840 +holiday +##ュー +373 +074 +##vg +##nos +##rail +gartner +gi +6p +##dium +kit +488 +b3 +eco +##ろう +20g +sean +##stone +autocad +nu +##np +f16 +write +029 +m5 +##ias +images +atp +##dk +fsm +504 +1350 +ve +52kb +##xxx +##のに +##cake +414 +unit +lim +ru +1v +##ification +published +angela +16g +analytics +ak +##q +##nel +gmt +##icon +again +##₂ +##bby +ios11 +445 +かこさいます +waze +いてす +##ハ +9985 +##ust +##ティー +framework +##007 +iptv +delete +52sykb +cl +wwdc +027 +30cm +##fw +##ての +1389 +##xon +brandt +##ses +##dragon +tc +vetements +anne +monte +modern +official +##へて +##ere +##nne +##oud +もちろん +50 +etnews +##a2 +##graphy +421 +863 +##ちゃん +444 +##rtex +##てお +l2 +##gma +mount +ccd +たと +archive +morning +tan +ddos +e7 +##ホ +day4 +##ウ +gis +453 +its +495 +factory +bruce +pg +##ito +ってくたさい +guest +cdma +##lling +536 +n3 +しかし +3~4 +mega +eyes +ro +13 +women +dac +church +##jun +singapore +##facebook +6991 +starbucks +##tos +##stin +##shine +zen +##mu +tina +20℃ +1893 +##たけて +503 +465 +request +##gence +qt +##っ +1886 +347 +363 +q7 +##zzi +diary +##tore +409 +##ead +468 +cst +##osa +canada +agent +va +##jiang +##ちは +##ーク +##lam +sg +##nix +##sday +##よって +g6 +##master +bing +##zl +charlie +16 +8mm +nb40 +##ーン +thai +##ルフ +ln284ct +##itz +##2f +bonnie +##food +##lent +originals +##stro +##lts +418 +∟∣ +##bscribe +children +ntd +yesstyle +##かも +hmv +##tment +d5 +2cm +arts +sms +##pn +##я +##いい +topios9 +539 +lifestyle +virtual +##ague +xz +##deo +muji +024 +unt +##nnis +##ᅩ +faq1 +1884 +396 +##ette +fly +64㎡ +はしめまして +441 +curry +##pop +のこ +release +##← +##◆◆ +##cast +073 +ありな +500ml +##ews +5c +##stle +ios7 +##ima +787 +dog +lenovo +##r4 +roger +013 +cbs +vornado +100m +417 +##desk +##クok +##ald +1867 +9595 +2900 +##van +oil +##x +some +break +common +##jy +##lines +g7 +twice +419 +ella +nano +belle +にこ +##mes +##self +##note +jb +##ことかてきます +benz +##との +##ova +451 +save +##wing +##ますのて +kai +りは +##hua +##rect +rainer +##unge +448 +##0m +adsl +##かな +guestname +##uma +##kins +##zu +tokichoi +##price +county +##med +##mus +rmk +391 +address +vm +えて +openload +##group +##hin +##iginal +amg +urban +##oz +jobs +emi +##public +beautiful +##sch +album +##dden +##bell +jerry +works +hostel +miller +##drive +##rmin +##10 +376 +boot +828 +##370 +##fx +##cm~ +1885 +##nome +##ctionary +##oman +##lish +##cr +##hm +433 +##how +432 +francis +xi +c919 +b5 +evernote +##uc +vga +##3000 +coupe +##urg +##cca +##uality +019 +6g +れる +multi +##また +##ett +em +hey +##ani +##tax +##rma +inside +than +740 +leonnhurt +##jin +ict +れた +bird +notes +200mm +くの +##dical +##lli +result +442 +iu +ee +438 +smap +gopro +##last +yin +pure +998 +32g +けた +5kg +##dan +##rame +mama +##oot +bean +marketing +##hur +2l +bella +sync +xuite +##ground +515 +discuz +##getrelax +##ince +##bay +##5s +cj +##イス +gmat +apt +##pass +jing +##rix +c4 +rich +##とても +niusnews +##ello +bag +770 +##eting +##mobile +18 +culture +015 +##のてすか +377 +1020 +area +##ience +616 +details +gp +universal +silver +dit +はお +private +ddd +u11 +kanshu +##ified +fung +##nny +dx +##520 +tai +475 +023 +##fr +##lean +3s +##pin +429 +##rin +25000 +ly +rick +##bility +usb3 +banner +##baru +##gion +metal +dt +vdf +1871 +karl +qualcomm +bear +1010 +oldid +ian +jo +##tors +population +##ernel +1882 +mmorpg +##mv +##bike +603 +##© +ww +friend +##ager +exhibition +##del +##pods +fpx +structure +##free +##tings +kl +##rley +##copyright +##mma +california +3400 +orange +yoga +4l +canmake +honey +##anda +##コメント +595 +nikkie +##ルハイト +dhl +publishing +##mall +##gnet +20cm +513 +##クセス +##┅ +e88 +970 +##dog +fishbase +##! +##" +### +##$ +##% +##& +##' +##( +##) +##* +##+ +##, +##- +##. +##/ +##: +##; +##< +##= +##> +##? +##@ +##[ +##\ +##] +##^ +##_ +##{ +##| +##} +##~ +##£ +##¤ +##¥ +##§ +##« +##± +##³ +##µ +##· +##¹ +##º +##» +##¼ +##ß +##æ +##÷ +##ø +##đ +##ŋ +##ɔ +##ə +##ɡ +##ʰ +##ˇ +##ˈ +##ˊ +##ˋ +##ˍ +##ː +##˙ +##˚ +##ˢ +##α +##β +##γ +##δ +##ε +##η +##θ +##ι +##κ +##λ +##μ +##ν +##ο +##π +##ρ +##ς +##σ +##τ +##υ +##φ +##χ +##ψ +##б +##в +##г +##д +##е +##ж +##з +##к +##л +##м +##н +##о +##п +##р +##с +##т +##у +##ф +##х +##ц +##ч +##ш +##ы +##ь +##і +##ا +##ب +##ة +##ت +##د +##ر +##س +##ع +##ل +##م +##ن +##ه +##و +##ي +##۩ +##ก +##ง +##น +##ม +##ย +##ร +##อ +##า +##เ +##๑ +##་ +##ღ +##ᄀ +##ᄁ +##ᄂ +##ᄃ +##ᄅ +##ᄆ +##ᄇ +##ᄈ +##ᄉ +##ᄋ +##ᄌ +##ᄎ +##ᄏ +##ᄐ +##ᄑ +##ᄒ +##ᅢ +##ᅣ +##ᅥ +##ᅦ +##ᅧ +##ᅨ +##ᅪ +##ᅬ +##ᅭ +##ᅮ +##ᅯ +##ᅲ +##ᅳ +##ᅴ +##ᆷ +##ᆸ +##ᆺ +##ᆻ +##ᗜ +##ᵃ +##ᵉ +##ᵍ +##ᵏ +##ᵐ +##ᵒ +##ᵘ +##‖ +##„ +##† +##• +##‥ +##‧ +##
 +##‰ +##′ +##″ +##‹ +##› +##※ +##‿ +##⁄ +##ⁱ +##⁺ +##ⁿ +##₁ +##₃ +##₄ +##€ +##№ +##ⅰ +##ⅱ +##ⅲ +##ⅳ +##ⅴ +##↔ +##↗ +##↘ +##⇒ +##∀ +##− +##∕ +##∙ +##√ +##∞ +##∟ +##∠ +##∣ +##∩ +##∮ +##∶ +##∼ +##∽ +##≈ +##≒ +##≡ +##≤ +##≥ +##≦ +##≧ +##≪ +##≫ +##⊙ +##⋅ +##⋈ +##⋯ +##⌒ +##① +##② +##③ +##④ +##⑤ +##⑥ +##⑦ +##⑧ +##⑨ +##⑩ +##⑴ +##⑵ +##⑶ +##⑷ +##⑸ +##⒈ +##⒉ +##⒊ +##⒋ +##ⓒ +##ⓔ +##ⓘ +##━ +##┃ +##┆ +##┊ +##┌ +##└ +##├ +##┣ +##═ +##║ +##╚ +##╞ +##╠ +##╭ +##╮ +##╯ +##╰ +##╱ +##╳ +##▂ +##▃ +##▅ +##▇ +##▉ +##▋ +##▌ +##▍ +##▎ +##□ +##▪ +##▫ +##▬ +##△ +##▶ +##► +##▽ +##◇ +##◕ +##◠ +##◢ +##◤ +##☀ +##☕ +##☞ +##☺ +##☼ +##♀ +##♂ +##♠ +##♡ +##♣ +##♦ +##♫ +##♬ +##✈ +##✔ +##✕ +##✖ +##✦ +##✨ +##✪ +##✰ +##✿ +##❀ +##➜ +##➤ +##⦿ +##、 +##。 +##〃 +##々 +##〇 +##〈 +##〉 +##《 +##》 +##「 +##」 +##『 +##』 +##【 +##】 +##〓 +##〔 +##〕 +##〖 +##〗 +##〜 +##〝 +##〞 +##ぃ +##ぇ +##ぬ +##ふ +##ほ +##む +##ゃ +##ゅ +##ゆ +##ょ +##゜ +##ゝ +##ァ +##ゥ +##エ +##ォ +##ケ +##サ +##セ +##ソ +##ッ +##ニ +##ヌ +##ネ +##ノ +##ヘ +##モ +##ャ +##ヤ +##ュ +##ユ +##ョ +##ヨ +##ワ +##ヲ +##・ +##ヽ +##ㄅ +##ㄆ +##ㄇ +##ㄉ +##ㄋ +##ㄌ +##ㄍ +##ㄎ +##ㄏ +##ㄒ +##ㄚ +##ㄛ +##ㄞ +##ㄟ +##ㄢ +##ㄤ +##ㄥ +##ㄧ +##ㄨ +##ㆍ +##㈦ +##㊣ +##㗎 +##一 +##丁 +##七 +##万 +##丈 +##三 +##上 +##下 +##不 +##与 +##丐 +##丑 +##专 +##且 +##丕 +##世 +##丘 +##丙 +##业 +##丛 +##东 +##丝 +##丞 +##丟 +##両 +##丢 +##两 +##严 +##並 +##丧 +##丨 +##个 +##丫 +##中 +##丰 +##串 +##临 +##丶 +##丸 +##丹 +##为 +##主 +##丼 +##丽 +##举 +##丿 +##乂 +##乃 +##久 +##么 +##义 +##之 +##乌 +##乍 +##乎 +##乏 +##乐 +##乒 +##乓 +##乔 +##乖 +##乗 +##乘 +##乙 +##乜 +##九 +##乞 +##也 +##习 +##乡 +##书 +##乩 +##买 +##乱 +##乳 +##乾 +##亀 +##亂 +##了 +##予 +##争 +##事 +##二 +##于 +##亏 +##云 +##互 +##五 +##井 +##亘 +##亙 +##亚 +##些 +##亜 +##亞 +##亟 +##亡 +##亢 +##交 +##亥 +##亦 +##产 +##亨 +##亩 +##享 +##京 +##亭 +##亮 +##亲 +##亳 +##亵 +##人 +##亿 +##什 +##仁 +##仃 +##仄 +##仅 +##仆 +##仇 +##今 +##介 +##仍 +##从 +##仏 +##仑 +##仓 +##仔 +##仕 +##他 +##仗 +##付 +##仙 +##仝 +##仞 +##仟 +##代 +##令 +##以 +##仨 +##仪 +##们 +##仮 +##仰 +##仲 +##件 +##价 +##任 +##份 +##仿 +##企 +##伉 +##伊 +##伍 +##伎 +##伏 +##伐 +##休 +##伕 +##众 +##优 +##伙 +##会 +##伝 +##伞 +##伟 +##传 +##伢 +##伤 +##伦 +##伪 +##伫 +##伯 +##估 +##伴 +##伶 +##伸 +##伺 +##似 +##伽 +##佃 +##但 +##佇 +##佈 +##位 +##低 +##住 +##佐 +##佑 +##体 +##佔 +##何 +##佗 +##佘 +##余 +##佚 +##佛 +##作 +##佝 +##佞 +##佟 +##你 +##佢 +##佣 +##佤 +##佥 +##佩 +##佬 +##佯 +##佰 +##佳 +##併 +##佶 +##佻 +##佼 +##使 +##侃 +##侄 +##來 +##侈 +##例 +##侍 +##侏 +##侑 +##侖 +##侗 +##供 +##依 +##侠 +##価 +##侣 +##侥 +##侦 +##侧 +##侨 +##侬 +##侮 +##侯 +##侵 +##侶 +##侷 +##便 +##係 +##促 +##俄 +##俊 +##俎 +##俏 +##俐 +##俑 +##俗 +##俘 +##俚 +##保 +##俞 +##俟 +##俠 +##信 +##俨 +##俩 +##俪 +##俬 +##俭 +##修 +##俯 +##俱 +##俳 +##俸 +##俺 +##俾 +##倆 +##倉 +##個 +##倌 +##倍 +##倏 +##們 +##倒 +##倔 +##倖 +##倘 +##候 +##倚 +##倜 +##借 +##倡 +##値 +##倦 +##倩 +##倪 +##倫 +##倬 +##倭 +##倶 +##债 +##值 +##倾 +##偃 +##假 +##偈 +##偉 +##偌 +##偎 +##偏 +##偕 +##做 +##停 +##健 +##側 +##偵 +##偶 +##偷 +##偻 +##偽 +##偿 +##傀 +##傅 +##傍 +##傑 +##傘 +##備 +##傚 +##傢 +##傣 +##傥 +##储 +##傩 +##催 +##傭 +##傲 +##傳 +##債 +##傷 +##傻 +##傾 +##僅 +##働 +##像 +##僑 +##僕 +##僖 +##僚 +##僥 +##僧 +##僭 +##僮 +##僱 +##僵 +##價 +##僻 +##儀 +##儂 +##億 +##儆 +##儉 +##儋 +##儒 +##儕 +##儘 +##償 +##儡 +##優 +##儲 +##儷 +##儼 +##儿 +##兀 +##允 +##元 +##兄 +##充 +##兆 +##兇 +##先 +##光 +##克 +##兌 +##免 +##児 +##兑 +##兒 +##兔 +##兖 +##党 +##兜 +##兢 +##入 +##內 +##全 +##兩 +##八 +##公 +##六 +##兮 +##兰 +##共 +##兲 +##关 +##兴 +##兵 +##其 +##具 +##典 +##兹 +##养 +##兼 +##兽 +##冀 +##内 +##円 +##冇 +##冈 +##冉 +##冊 +##册 +##再 +##冏 +##冒 +##冕 +##冗 +##写 +##军 +##农 +##冠 +##冢 +##冤 +##冥 +##冨 +##冪 +##冬 +##冯 +##冰 +##冲 +##决 +##况 +##冶 +##冷 +##冻 +##冼 +##冽 +##冾 +##净 +##凄 +##准 +##凇 +##凈 +##凉 +##凋 +##凌 +##凍 +##减 +##凑 +##凛 +##凜 +##凝 +##几 +##凡 +##凤 +##処 +##凪 +##凭 +##凯 +##凰 +##凱 +##凳 +##凶 +##凸 +##凹 +##出 +##击 +##函 +##凿 +##刀 +##刁 +##刃 +##分 +##切 +##刈 +##刊 +##刍 +##刎 +##刑 +##划 +##列 +##刘 +##则 +##刚 +##创 +##初 +##删 +##判 +##別 +##刨 +##利 +##刪 +##别 +##刮 +##到 +##制 +##刷 +##券 +##刹 +##刺 +##刻 +##刽 +##剁 +##剂 +##剃 +##則 +##剉 +##削 +##剋 +##剌 +##前 +##剎 +##剐 +##剑 +##剔 +##剖 +##剛 +##剜 +##剝 +##剣 +##剤 +##剥 +##剧 +##剩 +##剪 +##副 +##割 +##創 +##剷 +##剽 +##剿 +##劃 +##劇 +##劈 +##劉 +##劊 +##劍 +##劏 +##劑 +##力 +##劝 +##办 +##功 +##加 +##务 +##劣 +##动 +##助 +##努 +##劫 +##劭 +##励 +##劲 +##劳 +##労 +##劵 +##効 +##劾 +##势 +##勁 +##勃 +##勇 +##勉 +##勋 +##勐 +##勒 +##動 +##勖 +##勘 +##務 +##勛 +##勝 +##勞 +##募 +##勢 +##勤 +##勧 +##勳 +##勵 +##勸 +##勺 +##勻 +##勾 +##勿 +##匀 +##包 +##匆 +##匈 +##匍 +##匐 +##匕 +##化 +##北 +##匙 +##匝 +##匠 +##匡 +##匣 +##匪 +##匮 +##匯 +##匱 +##匹 +##区 +##医 +##匾 +##匿 +##區 +##十 +##千 +##卅 +##升 +##午 +##卉 +##半 +##卍 +##华 +##协 +##卑 +##卒 +##卓 +##協 +##单 +##卖 +##南 +##単 +##博 +##卜 +##卞 +##卟 +##占 +##卡 +##卢 +##卤 +##卦 +##卧 +##卫 +##卮 +##卯 +##印 +##危 +##即 +##却 +##卵 +##卷 +##卸 +##卻 +##卿 +##厂 +##厄 +##厅 +##历 +##厉 +##压 +##厌 +##厕 +##厘 +##厚 +##厝 +##原 +##厢 +##厥 +##厦 +##厨 +##厩 +##厭 +##厮 +##厲 +##厳 +##去 +##县 +##叁 +##参 +##參 +##又 +##叉 +##及 +##友 +##双 +##反 +##収 +##发 +##叔 +##取 +##受 +##变 +##叙 +##叛 +##叟 +##叠 +##叡 +##叢 +##口 +##古 +##句 +##另 +##叨 +##叩 +##只 +##叫 +##召 +##叭 +##叮 +##可 +##台 +##叱 +##史 +##右 +##叵 +##叶 +##号 +##司 +##叹 +##叻 +##叼 +##叽 +##吁 +##吃 +##各 +##吆 +##合 +##吉 +##吊 +##吋 +##同 +##名 +##后 +##吏 +##吐 +##向 +##吒 +##吓 +##吕 +##吖 +##吗 +##君 +##吝 +##吞 +##吟 +##吠 +##吡 +##否 +##吧 +##吨 +##吩 +##含 +##听 +##吭 +##吮 +##启 +##吱 +##吳 +##吴 +##吵 +##吶 +##吸 +##吹 +##吻 +##吼 +##吽 +##吾 +##呀 +##呂 +##呃 +##呆 +##呈 +##告 +##呋 +##呎 +##呐 +##呓 +##呕 +##呗 +##员 +##呛 +##呜 +##呢 +##呤 +##呦 +##周 +##呱 +##呲 +##味 +##呵 +##呷 +##呸 +##呻 +##呼 +##命 +##咀 +##咁 +##咂 +##咄 +##咆 +##咋 +##和 +##咎 +##咏 +##咐 +##咒 +##咔 +##咕 +##咖 +##咗 +##咘 +##咙 +##咚 +##咛 +##咣 +##咤 +##咦 +##咧 +##咨 +##咩 +##咪 +##咫 +##咬 +##咭 +##咯 +##咱 +##咲 +##咳 +##咸 +##咻 +##咽 +##咿 +##哀 +##品 +##哂 +##哄 +##哆 +##哇 +##哈 +##哉 +##哋 +##哌 +##响 +##哎 +##哏 +##哐 +##哑 +##哒 +##哔 +##哗 +##哟 +##員 +##哥 +##哦 +##哧 +##哨 +##哩 +##哪 +##哭 +##哮 +##哲 +##哺 +##哼 +##哽 +##唁 +##唄 +##唆 +##唇 +##唉 +##唏 +##唐 +##唑 +##唔 +##唠 +##唤 +##唧 +##唬 +##售 +##唯 +##唰 +##唱 +##唳 +##唷 +##唸 +##唾 +##啃 +##啄 +##商 +##啉 +##啊 +##問 +##啓 +##啕 +##啖 +##啜 +##啞 +##啟 +##啡 +##啤 +##啥 +##啦 +##啧 +##啪 +##啫 +##啬 +##啮 +##啰 +##啱 +##啲 +##啵 +##啶 +##啷 +##啸 +##啻 +##啼 +##啾 +##喀 +##喂 +##喃 +##善 +##喆 +##喇 +##喉 +##喊 +##喋 +##喎 +##喏 +##喔 +##喘 +##喙 +##喚 +##喜 +##喝 +##喟 +##喧 +##喪 +##喫 +##喬 +##單 +##喰 +##喱 +##喲 +##喳 +##喵 +##営 +##喷 +##喹 +##喺 +##喻 +##喽 +##嗅 +##嗆 +##嗇 +##嗎 +##嗑 +##嗒 +##嗓 +##嗔 +##嗖 +##嗚 +##嗜 +##嗝 +##嗟 +##嗡 +##嗣 +##嗤 +##嗦 +##嗨 +##嗪 +##嗬 +##嗯 +##嗰 +##嗲 +##嗳 +##嗶 +##嗷 +##嗽 +##嘀 +##嘅 +##嘆 +##嘈 +##嘉 +##嘌 +##嘍 +##嘎 +##嘔 +##嘖 +##嘗 +##嘘 +##嘚 +##嘛 +##嘜 +##嘞 +##嘟 +##嘢 +##嘣 +##嘤 +##嘧 +##嘩 +##嘭 +##嘮 +##嘯 +##嘰 +##嘱 +##嘲 +##嘴 +##嘶 +##嘸 +##嘹 +##嘻 +##嘿 +##噁 +##噌 +##噎 +##噓 +##噔 +##噗 +##噙 +##噜 +##噠 +##噢 +##噤 +##器 +##噩 +##噪 +##噬 +##噱 +##噴 +##噶 +##噸 +##噹 +##噻 +##噼 +##嚀 +##嚇 +##嚎 +##嚏 +##嚐 +##嚓 +##嚕 +##嚟 +##嚣 +##嚥 +##嚨 +##嚮 +##嚴 +##嚷 +##嚼 +##囂 +##囉 +##囊 +##囍 +##囑 +##囔 +##囗 +##囚 +##四 +##囝 +##回 +##囟 +##因 +##囡 +##团 +##団 +##囤 +##囧 +##囪 +##囫 +##园 +##困 +##囱 +##囲 +##図 +##围 +##囹 +##固 +##国 +##图 +##囿 +##圃 +##圄 +##圆 +##圈 +##國 +##圍 +##圏 +##園 +##圓 +##圖 +##團 +##圜 +##土 +##圣 +##圧 +##在 +##圩 +##圭 +##地 +##圳 +##场 +##圻 +##圾 +##址 +##坂 +##均 +##坊 +##坍 +##坎 +##坏 +##坐 +##坑 +##块 +##坚 +##坛 +##坝 +##坞 +##坟 +##坠 +##坡 +##坤 +##坦 +##坨 +##坪 +##坯 +##坳 +##坵 +##坷 +##垂 +##垃 +##垄 +##型 +##垒 +##垚 +##垛 +##垠 +##垢 +##垣 +##垦 +##垩 +##垫 +##垭 +##垮 +##垵 +##埂 +##埃 +##埋 +##城 +##埔 +##埕 +##埗 +##域 +##埠 +##埤 +##埵 +##執 +##埸 +##培 +##基 +##埼 +##堀 +##堂 +##堃 +##堅 +##堆 +##堇 +##堑 +##堕 +##堙 +##堡 +##堤 +##堪 +##堯 +##堰 +##報 +##場 +##堵 +##堺 +##堿 +##塊 +##塌 +##塑 +##塔 +##塗 +##塘 +##塚 +##塞 +##塢 +##塩 +##填 +##塬 +##塭 +##塵 +##塾 +##墀 +##境 +##墅 +##墉 +##墊 +##墒 +##墓 +##増 +##墘 +##墙 +##墜 +##增 +##墟 +##墨 +##墩 +##墮 +##墳 +##墻 +##墾 +##壁 +##壅 +##壆 +##壇 +##壊 +##壑 +##壓 +##壕 +##壘 +##壞 +##壟 +##壢 +##壤 +##壩 +##士 +##壬 +##壮 +##壯 +##声 +##売 +##壳 +##壶 +##壹 +##壺 +##壽 +##处 +##备 +##変 +##复 +##夏 +##夔 +##夕 +##外 +##夙 +##多 +##夜 +##够 +##夠 +##夢 +##夥 +##大 +##天 +##太 +##夫 +##夭 +##央 +##夯 +##失 +##头 +##夷 +##夸 +##夹 +##夺 +##夾 +##奂 +##奄 +##奇 +##奈 +##奉 +##奋 +##奎 +##奏 +##奐 +##契 +##奔 +##奕 +##奖 +##套 +##奘 +##奚 +##奠 +##奢 +##奥 +##奧 +##奪 +##奬 +##奮 +##女 +##奴 +##奶 +##奸 +##她 +##好 +##如 +##妃 +##妄 +##妆 +##妇 +##妈 +##妊 +##妍 +##妒 +##妓 +##妖 +##妘 +##妙 +##妝 +##妞 +##妣 +##妤 +##妥 +##妨 +##妩 +##妪 +##妮 +##妲 +##妳 +##妹 +##妻 +##妾 +##姆 +##姉 +##姊 +##始 +##姍 +##姐 +##姑 +##姒 +##姓 +##委 +##姗 +##姚 +##姜 +##姝 +##姣 +##姥 +##姦 +##姨 +##姪 +##姫 +##姬 +##姹 +##姻 +##姿 +##威 +##娃 +##娄 +##娅 +##娆 +##娇 +##娉 +##娑 +##娓 +##娘 +##娛 +##娜 +##娟 +##娠 +##娣 +##娥 +##娩 +##娱 +##娲 +##娴 +##娶 +##娼 +##婀 +##婁 +##婆 +##婉 +##婊 +##婕 +##婚 +##婢 +##婦 +##婧 +##婪 +##婭 +##婴 +##婵 +##婶 +##婷 +##婺 +##婿 +##媒 +##媚 +##媛 +##媞 +##媧 +##媲 +##媳 +##媽 +##媾 +##嫁 +##嫂 +##嫉 +##嫌 +##嫑 +##嫔 +##嫖 +##嫘 +##嫚 +##嫡 +##嫣 +##嫦 +##嫩 +##嫲 +##嫵 +##嫻 +##嬅 +##嬉 +##嬌 +##嬗 +##嬛 +##嬢 +##嬤 +##嬪 +##嬰 +##嬴 +##嬷 +##嬸 +##嬿 +##孀 +##孃 +##子 +##孑 +##孔 +##孕 +##孖 +##字 +##存 +##孙 +##孚 +##孛 +##孜 +##孝 +##孟 +##孢 +##季 +##孤 +##学 +##孩 +##孪 +##孫 +##孬 +##孰 +##孱 +##孳 +##孵 +##學 +##孺 +##孽 +##孿 +##宁 +##它 +##宅 +##宇 +##守 +##安 +##宋 +##完 +##宏 +##宓 +##宕 +##宗 +##官 +##宙 +##定 +##宛 +##宜 +##宝 +##实 +##実 +##宠 +##审 +##客 +##宣 +##室 +##宥 +##宦 +##宪 +##宫 +##宮 +##宰 +##害 +##宴 +##宵 +##家 +##宸 +##容 +##宽 +##宾 +##宿 +##寂 +##寄 +##寅 +##密 +##寇 +##富 +##寐 +##寒 +##寓 +##寛 +##寝 +##寞 +##察 +##寡 +##寢 +##寥 +##實 +##寧 +##寨 +##審 +##寫 +##寬 +##寮 +##寰 +##寵 +##寶 +##寸 +##对 +##寺 +##寻 +##导 +##対 +##寿 +##封 +##専 +##射 +##将 +##將 +##專 +##尉 +##尊 +##尋 +##對 +##導 +##小 +##少 +##尔 +##尕 +##尖 +##尘 +##尚 +##尝 +##尤 +##尧 +##尬 +##就 +##尴 +##尷 +##尸 +##尹 +##尺 +##尻 +##尼 +##尽 +##尾 +##尿 +##局 +##屁 +##层 +##屄 +##居 +##屆 +##屈 +##屉 +##届 +##屋 +##屌 +##屍 +##屎 +##屏 +##屐 +##屑 +##展 +##屜 +##属 +##屠 +##屡 +##屢 +##層 +##履 +##屬 +##屯 +##山 +##屹 +##屿 +##岀 +##岁 +##岂 +##岌 +##岐 +##岑 +##岔 +##岖 +##岗 +##岘 +##岙 +##岚 +##岛 +##岡 +##岩 +##岫 +##岬 +##岭 +##岱 +##岳 +##岷 +##岸 +##峇 +##峋 +##峒 +##峙 +##峡 +##峤 +##峥 +##峦 +##峨 +##峪 +##峭 +##峯 +##峰 +##峴 +##島 +##峻 +##峽 +##崁 +##崂 +##崆 +##崇 +##崎 +##崑 +##崔 +##崖 +##崗 +##崙 +##崛 +##崧 +##崩 +##崭 +##崴 +##崽 +##嵇 +##嵊 +##嵋 +##嵌 +##嵐 +##嵘 +##嵩 +##嵬 +##嵯 +##嶂 +##嶄 +##嶇 +##嶋 +##嶙 +##嶺 +##嶼 +##嶽 +##巅 +##巍 +##巒 +##巔 +##巖 +##川 +##州 +##巡 +##巢 +##工 +##左 +##巧 +##巨 +##巩 +##巫 +##差 +##己 +##已 +##巳 +##巴 +##巷 +##巻 +##巽 +##巾 +##巿 +##币 +##市 +##布 +##帅 +##帆 +##师 +##希 +##帐 +##帑 +##帕 +##帖 +##帘 +##帚 +##帛 +##帜 +##帝 +##帥 +##带 +##帧 +##師 +##席 +##帮 +##帯 +##帰 +##帳 +##帶 +##帷 +##常 +##帼 +##帽 +##幀 +##幂 +##幄 +##幅 +##幌 +##幔 +##幕 +##幟 +##幡 +##幢 +##幣 +##幫 +##干 +##平 +##年 +##并 +##幸 +##幹 +##幺 +##幻 +##幼 +##幽 +##幾 +##广 +##庁 +##広 +##庄 +##庆 +##庇 +##床 +##序 +##庐 +##库 +##应 +##底 +##庖 +##店 +##庙 +##庚 +##府 +##庞 +##废 +##庠 +##度 +##座 +##庫 +##庭 +##庵 +##庶 +##康 +##庸 +##庹 +##庾 +##廁 +##廂 +##廃 +##廈 +##廉 +##廊 +##廓 +##廖 +##廚 +##廝 +##廟 +##廠 +##廢 +##廣 +##廬 +##廳 +##延 +##廷 +##建 +##廿 +##开 +##弁 +##异 +##弃 +##弄 +##弈 +##弊 +##弋 +##式 +##弑 +##弒 +##弓 +##弔 +##引 +##弗 +##弘 +##弛 +##弟 +##张 +##弥 +##弦 +##弧 +##弩 +##弭 +##弯 +##弱 +##張 +##強 +##弹 +##强 +##弼 +##弾 +##彅 +##彆 +##彈 +##彌 +##彎 +##归 +##当 +##录 +##彗 +##彙 +##彝 +##形 +##彤 +##彥 +##彦 +##彧 +##彩 +##彪 +##彫 +##彬 +##彭 +##彰 +##影 +##彷 +##役 +##彻 +##彼 +##彿 +##往 +##征 +##径 +##待 +##徇 +##很 +##徉 +##徊 +##律 +##後 +##徐 +##徑 +##徒 +##従 +##徕 +##得 +##徘 +##徙 +##徜 +##從 +##徠 +##御 +##徨 +##復 +##循 +##徬 +##微 +##徳 +##徴 +##徵 +##德 +##徹 +##徼 +##徽 +##心 +##必 +##忆 +##忌 +##忍 +##忏 +##忐 +##忑 +##忒 +##忖 +##志 +##忘 +##忙 +##応 +##忠 +##忡 +##忤 +##忧 +##忪 +##快 +##忱 +##念 +##忻 +##忽 +##忿 +##怀 +##态 +##怂 +##怅 +##怆 +##怎 +##怏 +##怒 +##怔 +##怕 +##怖 +##怙 +##怜 +##思 +##怠 +##怡 +##急 +##怦 +##性 +##怨 +##怪 +##怯 +##怵 +##总 +##怼 +##恁 +##恃 +##恆 +##恋 +##恍 +##恐 +##恒 +##恕 +##恙 +##恚 +##恢 +##恣 +##恤 +##恥 +##恨 +##恩 +##恪 +##恫 +##恬 +##恭 +##息 +##恰 +##恳 +##恵 +##恶 +##恸 +##恺 +##恻 +##恼 +##恿 +##悄 +##悅 +##悉 +##悌 +##悍 +##悔 +##悖 +##悚 +##悟 +##悠 +##患 +##悦 +##您 +##悩 +##悪 +##悬 +##悯 +##悱 +##悲 +##悴 +##悵 +##悶 +##悸 +##悻 +##悼 +##悽 +##情 +##惆 +##惇 +##惊 +##惋 +##惑 +##惕 +##惘 +##惚 +##惜 +##惟 +##惠 +##惡 +##惦 +##惧 +##惨 +##惩 +##惫 +##惬 +##惭 +##惮 +##惯 +##惰 +##惱 +##想 +##惴 +##惶 +##惹 +##惺 +##愁 +##愆 +##愈 +##愉 +##愍 +##意 +##愕 +##愚 +##愛 +##愜 +##感 +##愣 +##愤 +##愧 +##愫 +##愷 +##愿 +##慄 +##慈 +##態 +##慌 +##慎 +##慑 +##慕 +##慘 +##慚 +##慟 +##慢 +##慣 +##慧 +##慨 +##慫 +##慮 +##慰 +##慳 +##慵 +##慶 +##慷 +##慾 +##憂 +##憊 +##憋 +##憎 +##憐 +##憑 +##憔 +##憚 +##憤 +##憧 +##憨 +##憩 +##憫 +##憬 +##憲 +##憶 +##憾 +##懂 +##懇 +##懈 +##應 +##懊 +##懋 +##懑 +##懒 +##懦 +##懲 +##懵 +##懶 +##懷 +##懸 +##懺 +##懼 +##懾 +##懿 +##戀 +##戈 +##戊 +##戌 +##戍 +##戎 +##戏 +##成 +##我 +##戒 +##戕 +##或 +##战 +##戚 +##戛 +##戟 +##戡 +##戦 +##截 +##戬 +##戮 +##戰 +##戲 +##戳 +##戴 +##戶 +##户 +##戸 +##戻 +##戾 +##房 +##所 +##扁 +##扇 +##扈 +##扉 +##手 +##才 +##扎 +##扑 +##扒 +##打 +##扔 +##払 +##托 +##扛 +##扣 +##扦 +##执 +##扩 +##扪 +##扫 +##扬 +##扭 +##扮 +##扯 +##扰 +##扱 +##扳 +##扶 +##批 +##扼 +##找 +##承 +##技 +##抄 +##抉 +##把 +##抑 +##抒 +##抓 +##投 +##抖 +##抗 +##折 +##抚 +##抛 +##抜 +##択 +##抟 +##抠 +##抡 +##抢 +##护 +##报 +##抨 +##披 +##抬 +##抱 +##抵 +##抹 +##押 +##抽 +##抿 +##拂 +##拄 +##担 +##拆 +##拇 +##拈 +##拉 +##拋 +##拌 +##拍 +##拎 +##拐 +##拒 +##拓 +##拔 +##拖 +##拗 +##拘 +##拙 +##拚 +##招 +##拜 +##拟 +##拡 +##拢 +##拣 +##拥 +##拦 +##拧 +##拨 +##择 +##括 +##拭 +##拮 +##拯 +##拱 +##拳 +##拴 +##拷 +##拼 +##拽 +##拾 +##拿 +##持 +##挂 +##指 +##挈 +##按 +##挎 +##挑 +##挖 +##挙 +##挚 +##挛 +##挝 +##挞 +##挟 +##挠 +##挡 +##挣 +##挤 +##挥 +##挨 +##挪 +##挫 +##振 +##挲 +##挹 +##挺 +##挽 +##挾 +##捂 +##捅 +##捆 +##捉 +##捋 +##捌 +##捍 +##捎 +##捏 +##捐 +##捕 +##捞 +##损 +##捡 +##换 +##捣 +##捧 +##捨 +##捩 +##据 +##捱 +##捲 +##捶 +##捷 +##捺 +##捻 +##掀 +##掂 +##掃 +##掇 +##授 +##掉 +##掌 +##掏 +##掐 +##排 +##掖 +##掘 +##掙 +##掛 +##掠 +##採 +##探 +##掣 +##接 +##控 +##推 +##掩 +##措 +##掬 +##掰 +##掲 +##掳 +##掴 +##掷 +##掸 +##掺 +##揀 +##揃 +##揄 +##揆 +##揉 +##揍 +##描 +##提 +##插 +##揖 +##揚 +##換 +##握 +##揣 +##揩 +##揪 +##揭 +##揮 +##援 +##揶 +##揸 +##揹 +##揽 +##搀 +##搁 +##搂 +##搅 +##損 +##搏 +##搐 +##搓 +##搔 +##搖 +##搗 +##搜 +##搞 +##搡 +##搪 +##搬 +##搭 +##搵 +##搶 +##携 +##搽 +##摀 +##摁 +##摄 +##摆 +##摇 +##摈 +##摊 +##摒 +##摔 +##摘 +##摞 +##摟 +##摧 +##摩 +##摯 +##摳 +##摸 +##摹 +##摺 +##摻 +##撂 +##撃 +##撅 +##撇 +##撈 +##撐 +##撑 +##撒 +##撓 +##撕 +##撚 +##撞 +##撤 +##撥 +##撩 +##撫 +##撬 +##播 +##撮 +##撰 +##撲 +##撵 +##撷 +##撸 +##撻 +##撼 +##撿 +##擀 +##擁 +##擂 +##擄 +##擅 +##擇 +##擊 +##擋 +##操 +##擎 +##擒 +##擔 +##擘 +##據 +##擞 +##擠 +##擡 +##擢 +##擦 +##擬 +##擰 +##擱 +##擲 +##擴 +##擷 +##擺 +##擼 +##擾 +##攀 +##攏 +##攒 +##攔 +##攘 +##攙 +##攜 +##攝 +##攞 +##攢 +##攣 +##攤 +##攥 +##攪 +##攫 +##攬 +##支 +##收 +##攸 +##改 +##攻 +##放 +##政 +##故 +##效 +##敌 +##敍 +##敎 +##敏 +##救 +##敕 +##敖 +##敗 +##敘 +##教 +##敛 +##敝 +##敞 +##敢 +##散 +##敦 +##敬 +##数 +##敲 +##整 +##敵 +##敷 +##數 +##斂 +##斃 +##文 +##斋 +##斌 +##斎 +##斐 +##斑 +##斓 +##斗 +##料 +##斛 +##斜 +##斟 +##斡 +##斤 +##斥 +##斧 +##斩 +##斫 +##斬 +##断 +##斯 +##新 +##斷 +##方 +##於 +##施 +##旁 +##旃 +##旅 +##旋 +##旌 +##旎 +##族 +##旖 +##旗 +##无 +##既 +##日 +##旦 +##旧 +##旨 +##早 +##旬 +##旭 +##旮 +##旱 +##时 +##旷 +##旺 +##旻 +##昀 +##昂 +##昆 +##昇 +##昉 +##昊 +##昌 +##明 +##昏 +##易 +##昔 +##昕 +##昙 +##星 +##映 +##春 +##昧 +##昨 +##昭 +##是 +##昱 +##昴 +##昵 +##昶 +##昼 +##显 +##晁 +##時 +##晃 +##晉 +##晋 +##晌 +##晏 +##晒 +##晓 +##晔 +##晕 +##晖 +##晗 +##晚 +##晝 +##晞 +##晟 +##晤 +##晦 +##晨 +##晩 +##普 +##景 +##晰 +##晴 +##晶 +##晷 +##智 +##晾 +##暂 +##暄 +##暇 +##暈 +##暉 +##暌 +##暐 +##暑 +##暖 +##暗 +##暝 +##暢 +##暧 +##暨 +##暫 +##暮 +##暱 +##暴 +##暸 +##暹 +##曄 +##曆 +##曇 +##曉 +##曖 +##曙 +##曜 +##曝 +##曠 +##曦 +##曬 +##曰 +##曲 +##曳 +##更 +##書 +##曹 +##曼 +##曾 +##替 +##最 +##會 +##月 +##有 +##朋 +##服 +##朐 +##朔 +##朕 +##朗 +##望 +##朝 +##期 +##朦 +##朧 +##木 +##未 +##末 +##本 +##札 +##朮 +##术 +##朱 +##朴 +##朵 +##机 +##朽 +##杀 +##杂 +##权 +##杆 +##杈 +##杉 +##李 +##杏 +##材 +##村 +##杓 +##杖 +##杜 +##杞 +##束 +##杠 +##条 +##来 +##杨 +##杭 +##杯 +##杰 +##東 +##杳 +##杵 +##杷 +##杼 +##松 +##板 +##极 +##构 +##枇 +##枉 +##枋 +##析 +##枕 +##林 +##枚 +##果 +##枝 +##枢 +##枣 +##枪 +##枫 +##枭 +##枯 +##枰 +##枱 +##枳 +##架 +##枷 +##枸 +##柄 +##柏 +##某 +##柑 +##柒 +##染 +##柔 +##柘 +##柚 +##柜 +##柞 +##柠 +##柢 +##查 +##柩 +##柬 +##柯 +##柱 +##柳 +##柴 +##柵 +##査 +##柿 +##栀 +##栃 +##栄 +##栅 +##标 +##栈 +##栉 +##栋 +##栎 +##栏 +##树 +##栓 +##栖 +##栗 +##校 +##栩 +##株 +##样 +##核 +##根 +##格 +##栽 +##栾 +##桀 +##桁 +##桂 +##桃 +##桅 +##框 +##案 +##桉 +##桌 +##桎 +##桐 +##桑 +##桓 +##桔 +##桜 +##桠 +##桡 +##桢 +##档 +##桥 +##桦 +##桧 +##桨 +##桩 +##桶 +##桿 +##梁 +##梅 +##梆 +##梏 +##梓 +##梗 +##條 +##梟 +##梢 +##梦 +##梧 +##梨 +##梭 +##梯 +##械 +##梳 +##梵 +##梶 +##检 +##棂 +##棄 +##棉 +##棋 +##棍 +##棒 +##棕 +##棗 +##棘 +##棚 +##棟 +##棠 +##棣 +##棧 +##森 +##棱 +##棲 +##棵 +##棹 +##棺 +##椁 +##椅 +##椋 +##植 +##椎 +##椒 +##検 +##椪 +##椭 +##椰 +##椹 +##椽 +##椿 +##楂 +##楊 +##楓 +##楔 +##楚 +##楝 +##楞 +##楠 +##楣 +##楨 +##楫 +##業 +##楮 +##極 +##楷 +##楸 +##楹 +##楼 +##楽 +##概 +##榄 +##榆 +##榈 +##榉 +##榔 +##榕 +##榖 +##榛 +##榜 +##榨 +##榫 +##榭 +##榮 +##榱 +##榴 +##榷 +##榻 +##槁 +##槃 +##構 +##槌 +##槍 +##槎 +##槐 +##槓 +##様 +##槛 +##槟 +##槤 +##槭 +##槲 +##槳 +##槻 +##槽 +##槿 +##樁 +##樂 +##樊 +##樑 +##樓 +##標 +##樞 +##樟 +##模 +##樣 +##権 +##横 +##樫 +##樯 +##樱 +##樵 +##樸 +##樹 +##樺 +##樽 +##樾 +##橄 +##橇 +##橋 +##橐 +##橘 +##橙 +##機 +##橡 +##橢 +##橫 +##橱 +##橹 +##橼 +##檀 +##檄 +##檎 +##檐 +##檔 +##檗 +##檜 +##檢 +##檬 +##檯 +##檳 +##檸 +##檻 +##櫃 +##櫚 +##櫛 +##櫥 +##櫸 +##櫻 +##欄 +##權 +##欒 +##欖 +##欠 +##次 +##欢 +##欣 +##欧 +##欲 +##欸 +##欺 +##欽 +##款 +##歆 +##歇 +##歉 +##歌 +##歎 +##歐 +##歓 +##歙 +##歛 +##歡 +##止 +##正 +##此 +##步 +##武 +##歧 +##歩 +##歪 +##歯 +##歲 +##歳 +##歴 +##歷 +##歸 +##歹 +##死 +##歼 +##殁 +##殃 +##殆 +##殇 +##殉 +##殊 +##残 +##殒 +##殓 +##殖 +##殘 +##殞 +##殡 +##殤 +##殭 +##殯 +##殲 +##殴 +##段 +##殷 +##殺 +##殼 +##殿 +##毀 +##毁 +##毂 +##毅 +##毆 +##毋 +##母 +##毎 +##每 +##毒 +##毓 +##比 +##毕 +##毗 +##毘 +##毙 +##毛 +##毡 +##毫 +##毯 +##毽 +##氈 +##氏 +##氐 +##民 +##氓 +##气 +##氖 +##気 +##氙 +##氛 +##氟 +##氡 +##氢 +##氣 +##氤 +##氦 +##氧 +##氨 +##氪 +##氫 +##氮 +##氯 +##氰 +##氲 +##水 +##氷 +##永 +##氹 +##氾 +##汀 +##汁 +##求 +##汆 +##汇 +##汉 +##汎 +##汐 +##汕 +##汗 +##汙 +##汛 +##汝 +##汞 +##江 +##池 +##污 +##汤 +##汨 +##汩 +##汪 +##汰 +##汲 +##汴 +##汶 +##汹 +##決 +##汽 +##汾 +##沁 +##沂 +##沃 +##沅 +##沈 +##沉 +##沌 +##沏 +##沐 +##沒 +##沓 +##沖 +##沙 +##沛 +##沟 +##没 +##沢 +##沣 +##沥 +##沦 +##沧 +##沪 +##沫 +##沭 +##沮 +##沱 +##河 +##沸 +##油 +##治 +##沼 +##沽 +##沾 +##沿 +##況 +##泄 +##泉 +##泊 +##泌 +##泓 +##法 +##泗 +##泛 +##泞 +##泠 +##泡 +##波 +##泣 +##泥 +##注 +##泪 +##泫 +##泮 +##泯 +##泰 +##泱 +##泳 +##泵 +##泷 +##泸 +##泻 +##泼 +##泽 +##泾 +##洁 +##洄 +##洋 +##洒 +##洗 +##洙 +##洛 +##洞 +##津 +##洩 +##洪 +##洮 +##洱 +##洲 +##洵 +##洶 +##洸 +##洹 +##活 +##洼 +##洽 +##派 +##流 +##浃 +##浄 +##浅 +##浆 +##浇 +##浊 +##测 +##济 +##浏 +##浑 +##浒 +##浓 +##浔 +##浙 +##浚 +##浜 +##浣 +##浦 +##浩 +##浪 +##浬 +##浮 +##浯 +##浴 +##海 +##浸 +##涂 +##涅 +##涇 +##消 +##涉 +##涌 +##涎 +##涓 +##涔 +##涕 +##涙 +##涛 +##涝 +##涞 +##涟 +##涠 +##涡 +##涣 +##涤 +##润 +##涧 +##涨 +##涩 +##涪 +##涮 +##涯 +##液 +##涵 +##涸 +##涼 +##涿 +##淀 +##淄 +##淅 +##淆 +##淇 +##淋 +##淌 +##淑 +##淒 +##淖 +##淘 +##淙 +##淚 +##淞 +##淡 +##淤 +##淦 +##淨 +##淩 +##淪 +##淫 +##淬 +##淮 +##深 +##淳 +##淵 +##混 +##淹 +##淺 +##添 +##淼 +##清 +##済 +##渉 +##渊 +##渋 +##渍 +##渎 +##渐 +##渔 +##渗 +##渙 +##渚 +##減 +##渝 +##渠 +##渡 +##渣 +##渤 +##渥 +##渦 +##温 +##測 +##渭 +##港 +##渲 +##渴 +##游 +##渺 +##渾 +##湃 +##湄 +##湊 +##湍 +##湖 +##湘 +##湛 +##湟 +##湧 +##湫 +##湮 +##湯 +##湳 +##湾 +##湿 +##満 +##溃 +##溅 +##溉 +##溏 +##源 +##準 +##溜 +##溝 +##溟 +##溢 +##溥 +##溧 +##溪 +##溫 +##溯 +##溱 +##溴 +##溶 +##溺 +##溼 +##滁 +##滂 +##滄 +##滅 +##滇 +##滋 +##滌 +##滑 +##滓 +##滔 +##滕 +##滙 +##滚 +##滝 +##滞 +##滟 +##满 +##滢 +##滤 +##滥 +##滦 +##滨 +##滩 +##滬 +##滯 +##滲 +##滴 +##滷 +##滸 +##滾 +##滿 +##漁 +##漂 +##漆 +##漉 +##漏 +##漓 +##演 +##漕 +##漠 +##漢 +##漣 +##漩 +##漪 +##漫 +##漬 +##漯 +##漱 +##漲 +##漳 +##漸 +##漾 +##漿 +##潆 +##潇 +##潋 +##潍 +##潑 +##潔 +##潘 +##潛 +##潜 +##潞 +##潟 +##潢 +##潤 +##潦 +##潧 +##潭 +##潮 +##潰 +##潴 +##潸 +##潺 +##潼 +##澀 +##澄 +##澆 +##澈 +##澍 +##澎 +##澗 +##澜 +##澡 +##澤 +##澧 +##澱 +##澳 +##澹 +##激 +##濁 +##濂 +##濃 +##濑 +##濒 +##濕 +##濘 +##濛 +##濟 +##濠 +##濡 +##濤 +##濫 +##濬 +##濮 +##濯 +##濱 +##濺 +##濾 +##瀅 +##瀆 +##瀉 +##瀋 +##瀏 +##瀑 +##瀕 +##瀘 +##瀚 +##瀛 +##瀝 +##瀞 +##瀟 +##瀧 +##瀨 +##瀬 +##瀰 +##瀾 +##灌 +##灏 +##灑 +##灘 +##灝 +##灞 +##灣 +##火 +##灬 +##灭 +##灯 +##灰 +##灵 +##灶 +##灸 +##灼 +##災 +##灾 +##灿 +##炀 +##炁 +##炅 +##炉 +##炊 +##炎 +##炒 +##炔 +##炕 +##炖 +##炙 +##炜 +##炫 +##炬 +##炭 +##炮 +##炯 +##炳 +##炷 +##炸 +##点 +##為 +##炼 +##炽 +##烁 +##烂 +##烃 +##烈 +##烊 +##烏 +##烘 +##烙 +##烛 +##烟 +##烤 +##烦 +##烧 +##烨 +##烩 +##烫 +##烬 +##热 +##烯 +##烷 +##烹 +##烽 +##焉 +##焊 +##焕 +##焖 +##焗 +##焘 +##焙 +##焚 +##焜 +##無 +##焦 +##焯 +##焰 +##焱 +##然 +##焼 +##煅 +##煉 +##煊 +##煌 +##煎 +##煒 +##煖 +##煙 +##煜 +##煞 +##煤 +##煥 +##煦 +##照 +##煨 +##煩 +##煮 +##煲 +##煸 +##煽 +##熄 +##熊 +##熏 +##熒 +##熔 +##熙 +##熟 +##熠 +##熨 +##熬 +##熱 +##熵 +##熹 +##熾 +##燁 +##燃 +##燄 +##燈 +##燉 +##燊 +##燎 +##燒 +##燔 +##燕 +##燙 +##燜 +##營 +##燥 +##燦 +##燧 +##燭 +##燮 +##燴 +##燻 +##燼 +##燿 +##爆 +##爍 +##爐 +##爛 +##爪 +##爬 +##爭 +##爰 +##爱 +##爲 +##爵 +##父 +##爷 +##爸 +##爹 +##爺 +##爻 +##爽 +##爾 +##牆 +##片 +##版 +##牌 +##牍 +##牒 +##牙 +##牛 +##牝 +##牟 +##牠 +##牡 +##牢 +##牦 +##牧 +##物 +##牯 +##牲 +##牴 +##牵 +##特 +##牺 +##牽 +##犀 +##犁 +##犄 +##犊 +##犍 +##犒 +##犢 +##犧 +##犬 +##犯 +##状 +##犷 +##犸 +##犹 +##狀 +##狂 +##狄 +##狈 +##狎 +##狐 +##狒 +##狗 +##狙 +##狞 +##狠 +##狡 +##狩 +##独 +##狭 +##狮 +##狰 +##狱 +##狸 +##狹 +##狼 +##狽 +##猎 +##猕 +##猖 +##猗 +##猙 +##猛 +##猜 +##猝 +##猥 +##猩 +##猪 +##猫 +##猬 +##献 +##猴 +##猶 +##猷 +##猾 +##猿 +##獄 +##獅 +##獎 +##獐 +##獒 +##獗 +##獠 +##獣 +##獨 +##獭 +##獰 +##獲 +##獵 +##獷 +##獸 +##獺 +##獻 +##獼 +##獾 +##玄 +##率 +##玉 +##王 +##玑 +##玖 +##玛 +##玟 +##玠 +##玥 +##玩 +##玫 +##玮 +##环 +##现 +##玲 +##玳 +##玷 +##玺 +##玻 +##珀 +##珂 +##珅 +##珈 +##珉 +##珊 +##珍 +##珏 +##珐 +##珑 +##珙 +##珞 +##珠 +##珣 +##珥 +##珩 +##珪 +##班 +##珮 +##珲 +##珺 +##現 +##球 +##琅 +##理 +##琇 +##琉 +##琊 +##琍 +##琏 +##琐 +##琛 +##琢 +##琥 +##琦 +##琨 +##琪 +##琬 +##琮 +##琰 +##琲 +##琳 +##琴 +##琵 +##琶 +##琺 +##琼 +##瑀 +##瑁 +##瑄 +##瑋 +##瑕 +##瑗 +##瑙 +##瑚 +##瑛 +##瑜 +##瑞 +##瑟 +##瑠 +##瑣 +##瑤 +##瑩 +##瑪 +##瑯 +##瑰 +##瑶 +##瑾 +##璀 +##璁 +##璃 +##璇 +##璉 +##璋 +##璎 +##璐 +##璜 +##璞 +##璟 +##璧 +##璨 +##環 +##璽 +##璿 +##瓊 +##瓏 +##瓒 +##瓜 +##瓢 +##瓣 +##瓤 +##瓦 +##瓮 +##瓯 +##瓴 +##瓶 +##瓷 +##甄 +##甌 +##甕 +##甘 +##甙 +##甚 +##甜 +##生 +##產 +##産 +##甥 +##甦 +##用 +##甩 +##甫 +##甬 +##甭 +##甯 +##田 +##由 +##甲 +##申 +##电 +##男 +##甸 +##町 +##画 +##甾 +##畀 +##畅 +##界 +##畏 +##畑 +##畔 +##留 +##畜 +##畝 +##畢 +##略 +##畦 +##番 +##畫 +##異 +##畲 +##畳 +##畴 +##當 +##畸 +##畹 +##畿 +##疆 +##疇 +##疊 +##疏 +##疑 +##疔 +##疖 +##疗 +##疙 +##疚 +##疝 +##疟 +##疡 +##疣 +##疤 +##疥 +##疫 +##疮 +##疯 +##疱 +##疲 +##疳 +##疵 +##疸 +##疹 +##疼 +##疽 +##疾 +##痂 +##病 +##症 +##痈 +##痉 +##痊 +##痍 +##痒 +##痔 +##痕 +##痘 +##痙 +##痛 +##痞 +##痠 +##痢 +##痣 +##痤 +##痧 +##痨 +##痪 +##痫 +##痰 +##痱 +##痴 +##痹 +##痺 +##痼 +##痿 +##瘀 +##瘁 +##瘋 +##瘍 +##瘓 +##瘘 +##瘙 +##瘟 +##瘠 +##瘡 +##瘢 +##瘤 +##瘦 +##瘧 +##瘩 +##瘪 +##瘫 +##瘴 +##瘸 +##瘾 +##療 +##癇 +##癌 +##癒 +##癖 +##癜 +##癞 +##癡 +##癢 +##癣 +##癥 +##癫 +##癬 +##癮 +##癱 +##癲 +##癸 +##発 +##登 +##發 +##白 +##百 +##皂 +##的 +##皆 +##皇 +##皈 +##皋 +##皎 +##皑 +##皓 +##皖 +##皙 +##皚 +##皮 +##皰 +##皱 +##皴 +##皺 +##皿 +##盂 +##盃 +##盅 +##盆 +##盈 +##益 +##盎 +##盏 +##盐 +##监 +##盒 +##盔 +##盖 +##盗 +##盘 +##盛 +##盜 +##盞 +##盟 +##盡 +##監 +##盤 +##盥 +##盧 +##盪 +##目 +##盯 +##盱 +##盲 +##直 +##相 +##盹 +##盼 +##盾 +##省 +##眈 +##眉 +##看 +##県 +##眙 +##眞 +##真 +##眠 +##眦 +##眨 +##眩 +##眯 +##眶 +##眷 +##眸 +##眺 +##眼 +##眾 +##着 +##睁 +##睇 +##睏 +##睐 +##睑 +##睛 +##睜 +##睞 +##睡 +##睢 +##督 +##睥 +##睦 +##睨 +##睪 +##睫 +##睬 +##睹 +##睽 +##睾 +##睿 +##瞄 +##瞅 +##瞇 +##瞋 +##瞌 +##瞎 +##瞑 +##瞒 +##瞓 +##瞞 +##瞟 +##瞠 +##瞥 +##瞧 +##瞩 +##瞪 +##瞬 +##瞭 +##瞰 +##瞳 +##瞻 +##瞼 +##瞿 +##矇 +##矍 +##矗 +##矚 +##矛 +##矜 +##矢 +##矣 +##知 +##矩 +##矫 +##短 +##矮 +##矯 +##石 +##矶 +##矽 +##矾 +##矿 +##码 +##砂 +##砌 +##砍 +##砒 +##研 +##砖 +##砗 +##砚 +##砝 +##砣 +##砥 +##砧 +##砭 +##砰 +##砲 +##破 +##砷 +##砸 +##砺 +##砼 +##砾 +##础 +##硅 +##硐 +##硒 +##硕 +##硝 +##硫 +##硬 +##确 +##硯 +##硼 +##碁 +##碇 +##碉 +##碌 +##碍 +##碎 +##碑 +##碓 +##碗 +##碘 +##碚 +##碛 +##碟 +##碣 +##碧 +##碩 +##碰 +##碱 +##碳 +##碴 +##確 +##碼 +##碾 +##磁 +##磅 +##磊 +##磋 +##磐 +##磕 +##磚 +##磡 +##磨 +##磬 +##磯 +##磲 +##磷 +##磺 +##礁 +##礎 +##礙 +##礡 +##礦 +##礪 +##礫 +##礴 +##示 +##礼 +##社 +##祀 +##祁 +##祂 +##祇 +##祈 +##祉 +##祎 +##祐 +##祕 +##祖 +##祗 +##祚 +##祛 +##祜 +##祝 +##神 +##祟 +##祠 +##祢 +##祥 +##票 +##祭 +##祯 +##祷 +##祸 +##祺 +##祿 +##禀 +##禁 +##禄 +##禅 +##禍 +##禎 +##福 +##禛 +##禦 +##禧 +##禪 +##禮 +##禱 +##禹 +##禺 +##离 +##禽 +##禾 +##禿 +##秀 +##私 +##秃 +##秆 +##秉 +##秋 +##种 +##科 +##秒 +##秘 +##租 +##秣 +##秤 +##秦 +##秧 +##秩 +##秭 +##积 +##称 +##秸 +##移 +##秽 +##稀 +##稅 +##程 +##稍 +##税 +##稔 +##稗 +##稚 +##稜 +##稞 +##稟 +##稠 +##稣 +##種 +##稱 +##稲 +##稳 +##稷 +##稹 +##稻 +##稼 +##稽 +##稿 +##穀 +##穂 +##穆 +##穌 +##積 +##穎 +##穗 +##穢 +##穩 +##穫 +##穴 +##究 +##穷 +##穹 +##空 +##穿 +##突 +##窃 +##窄 +##窈 +##窍 +##窑 +##窒 +##窓 +##窕 +##窖 +##窗 +##窘 +##窜 +##窝 +##窟 +##窠 +##窥 +##窦 +##窨 +##窩 +##窪 +##窮 +##窯 +##窺 +##窿 +##竄 +##竅 +##竇 +##竊 +##立 +##竖 +##站 +##竜 +##竞 +##竟 +##章 +##竣 +##童 +##竭 +##端 +##競 +##竹 +##竺 +##竽 +##竿 +##笃 +##笆 +##笈 +##笋 +##笏 +##笑 +##笔 +##笙 +##笛 +##笞 +##笠 +##符 +##笨 +##第 +##笹 +##笺 +##笼 +##筆 +##等 +##筊 +##筋 +##筍 +##筏 +##筐 +##筑 +##筒 +##答 +##策 +##筛 +##筝 +##筠 +##筱 +##筲 +##筵 +##筷 +##筹 +##签 +##简 +##箇 +##箋 +##箍 +##箏 +##箐 +##箔 +##箕 +##算 +##箝 +##管 +##箩 +##箫 +##箭 +##箱 +##箴 +##箸 +##節 +##篁 +##範 +##篆 +##篇 +##築 +##篑 +##篓 +##篙 +##篝 +##篠 +##篡 +##篤 +##篩 +##篪 +##篮 +##篱 +##篷 +##簇 +##簌 +##簍 +##簡 +##簦 +##簧 +##簪 +##簫 +##簷 +##簸 +##簽 +##簾 +##簿 +##籁 +##籃 +##籌 +##籍 +##籐 +##籟 +##籠 +##籤 +##籬 +##籮 +##籲 +##米 +##类 +##籼 +##籽 +##粄 +##粉 +##粑 +##粒 +##粕 +##粗 +##粘 +##粟 +##粤 +##粥 +##粧 +##粪 +##粮 +##粱 +##粲 +##粳 +##粵 +##粹 +##粼 +##粽 +##精 +##粿 +##糅 +##糊 +##糍 +##糕 +##糖 +##糗 +##糙 +##糜 +##糞 +##糟 +##糠 +##糧 +##糬 +##糯 +##糰 +##糸 +##系 +##糾 +##紀 +##紂 +##約 +##紅 +##紉 +##紊 +##紋 +##納 +##紐 +##紓 +##純 +##紗 +##紘 +##紙 +##級 +##紛 +##紜 +##素 +##紡 +##索 +##紧 +##紫 +##紮 +##累 +##細 +##紳 +##紹 +##紺 +##終 +##絃 +##組 +##絆 +##経 +##結 +##絕 +##絞 +##絡 +##絢 +##給 +##絨 +##絮 +##統 +##絲 +##絳 +##絵 +##絶 +##絹 +##綁 +##綏 +##綑 +##經 +##継 +##続 +##綜 +##綠 +##綢 +##綦 +##綫 +##綬 +##維 +##綱 +##網 +##綴 +##綵 +##綸 +##綺 +##綻 +##綽 +##綾 +##綿 +##緊 +##緋 +##総 +##緑 +##緒 +##緘 +##線 +##緝 +##緞 +##締 +##緣 +##編 +##緩 +##緬 +##緯 +##練 +##緹 +##緻 +##縁 +##縄 +##縈 +##縛 +##縝 +##縣 +##縫 +##縮 +##縱 +##縴 +##縷 +##總 +##績 +##繁 +##繃 +##繆 +##繇 +##繋 +##織 +##繕 +##繚 +##繞 +##繡 +##繩 +##繪 +##繫 +##繭 +##繳 +##繹 +##繼 +##繽 +##纂 +##續 +##纍 +##纏 +##纓 +##纔 +##纖 +##纜 +##纠 +##红 +##纣 +##纤 +##约 +##级 +##纨 +##纪 +##纫 +##纬 +##纭 +##纯 +##纰 +##纱 +##纲 +##纳 +##纵 +##纶 +##纷 +##纸 +##纹 +##纺 +##纽 +##纾 +##线 +##绀 +##练 +##组 +##绅 +##细 +##织 +##终 +##绊 +##绍 +##绎 +##经 +##绑 +##绒 +##结 +##绔 +##绕 +##绘 +##给 +##绚 +##绛 +##络 +##绝 +##绞 +##统 +##绡 +##绢 +##绣 +##绥 +##绦 +##继 +##绩 +##绪 +##绫 +##续 +##绮 +##绯 +##绰 +##绳 +##维 +##绵 +##绶 +##绷 +##绸 +##绻 +##综 +##绽 +##绾 +##绿 +##缀 +##缄 +##缅 +##缆 +##缇 +##缈 +##缉 +##缎 +##缓 +##缔 +##缕 +##编 +##缘 +##缙 +##缚 +##缜 +##缝 +##缠 +##缢 +##缤 +##缥 +##缨 +##缩 +##缪 +##缭 +##缮 +##缰 +##缱 +##缴 +##缸 +##缺 +##缽 +##罂 +##罄 +##罌 +##罐 +##网 +##罔 +##罕 +##罗 +##罚 +##罡 +##罢 +##罩 +##罪 +##置 +##罰 +##署 +##罵 +##罷 +##罹 +##羁 +##羅 +##羈 +##羊 +##羌 +##美 +##羔 +##羚 +##羞 +##羟 +##羡 +##羣 +##群 +##羥 +##羧 +##羨 +##義 +##羯 +##羲 +##羸 +##羹 +##羽 +##羿 +##翁 +##翅 +##翊 +##翌 +##翎 +##習 +##翔 +##翘 +##翟 +##翠 +##翡 +##翦 +##翩 +##翰 +##翱 +##翳 +##翹 +##翻 +##翼 +##耀 +##老 +##考 +##耄 +##者 +##耆 +##耋 +##而 +##耍 +##耐 +##耒 +##耕 +##耗 +##耘 +##耙 +##耦 +##耨 +##耳 +##耶 +##耷 +##耸 +##耻 +##耽 +##耿 +##聂 +##聆 +##聊 +##聋 +##职 +##聒 +##联 +##聖 +##聘 +##聚 +##聞 +##聪 +##聯 +##聰 +##聲 +##聳 +##聴 +##聶 +##職 +##聽 +##聾 +##聿 +##肃 +##肄 +##肅 +##肆 +##肇 +##肉 +##肋 +##肌 +##肏 +##肓 +##肖 +##肘 +##肚 +##肛 +##肝 +##肠 +##股 +##肢 +##肤 +##肥 +##肩 +##肪 +##肮 +##肯 +##肱 +##育 +##肴 +##肺 +##肽 +##肾 +##肿 +##胀 +##胁 +##胃 +##胄 +##胆 +##背 +##胍 +##胎 +##胖 +##胚 +##胛 +##胜 +##胝 +##胞 +##胡 +##胤 +##胥 +##胧 +##胫 +##胭 +##胯 +##胰 +##胱 +##胳 +##胴 +##胶 +##胸 +##胺 +##能 +##脂 +##脅 +##脆 +##脇 +##脈 +##脉 +##脊 +##脍 +##脏 +##脐 +##脑 +##脓 +##脖 +##脘 +##脚 +##脛 +##脣 +##脩 +##脫 +##脯 +##脱 +##脲 +##脳 +##脸 +##脹 +##脾 +##腆 +##腈 +##腊 +##腋 +##腌 +##腎 +##腐 +##腑 +##腓 +##腔 +##腕 +##腥 +##腦 +##腩 +##腫 +##腭 +##腮 +##腰 +##腱 +##腳 +##腴 +##腸 +##腹 +##腺 +##腻 +##腼 +##腾 +##腿 +##膀 +##膈 +##膊 +##膏 +##膑 +##膘 +##膚 +##膛 +##膜 +##膝 +##膠 +##膦 +##膨 +##膩 +##膳 +##膺 +##膻 +##膽 +##膾 +##膿 +##臀 +##臂 +##臃 +##臆 +##臉 +##臊 +##臍 +##臓 +##臘 +##臟 +##臣 +##臥 +##臧 +##臨 +##自 +##臬 +##臭 +##至 +##致 +##臺 +##臻 +##臼 +##臾 +##舀 +##舂 +##舅 +##舆 +##與 +##興 +##舉 +##舊 +##舌 +##舍 +##舎 +##舐 +##舒 +##舔 +##舖 +##舗 +##舛 +##舜 +##舞 +##舟 +##航 +##舫 +##般 +##舰 +##舱 +##舵 +##舶 +##舷 +##舸 +##船 +##舺 +##舾 +##艇 +##艋 +##艘 +##艙 +##艦 +##艮 +##良 +##艰 +##艱 +##色 +##艳 +##艷 +##艹 +##艺 +##艾 +##节 +##芃 +##芈 +##芊 +##芋 +##芍 +##芎 +##芒 +##芙 +##芜 +##芝 +##芡 +##芥 +##芦 +##芩 +##芪 +##芫 +##芬 +##芭 +##芮 +##芯 +##花 +##芳 +##芷 +##芸 +##芹 +##芻 +##芽 +##芾 +##苁 +##苄 +##苇 +##苋 +##苍 +##苏 +##苑 +##苒 +##苓 +##苔 +##苕 +##苗 +##苛 +##苜 +##苞 +##苟 +##苡 +##苣 +##若 +##苦 +##苫 +##苯 +##英 +##苷 +##苹 +##苻 +##茁 +##茂 +##范 +##茄 +##茅 +##茉 +##茎 +##茏 +##茗 +##茜 +##茧 +##茨 +##茫 +##茬 +##茭 +##茯 +##茱 +##茲 +##茴 +##茵 +##茶 +##茸 +##茹 +##茼 +##荀 +##荃 +##荆 +##草 +##荊 +##荏 +##荐 +##荒 +##荔 +##荖 +##荘 +##荚 +##荞 +##荟 +##荠 +##荡 +##荣 +##荤 +##荥 +##荧 +##荨 +##荪 +##荫 +##药 +##荳 +##荷 +##荸 +##荻 +##荼 +##荽 +##莅 +##莆 +##莉 +##莊 +##莎 +##莒 +##莓 +##莖 +##莘 +##莞 +##莠 +##莢 +##莧 +##莪 +##莫 +##莱 +##莲 +##莴 +##获 +##莹 +##莺 +##莽 +##莿 +##菀 +##菁 +##菅 +##菇 +##菈 +##菊 +##菌 +##菏 +##菓 +##菖 +##菘 +##菜 +##菟 +##菠 +##菡 +##菩 +##華 +##菱 +##菲 +##菸 +##菽 +##萁 +##萃 +##萄 +##萊 +##萋 +##萌 +##萍 +##萎 +##萘 +##萝 +##萤 +##营 +##萦 +##萧 +##萨 +##萩 +##萬 +##萱 +##萵 +##萸 +##萼 +##落 +##葆 +##葉 +##著 +##葚 +##葛 +##葡 +##董 +##葦 +##葩 +##葫 +##葬 +##葭 +##葯 +##葱 +##葳 +##葵 +##葷 +##葺 +##蒂 +##蒋 +##蒐 +##蒔 +##蒙 +##蒜 +##蒞 +##蒟 +##蒡 +##蒨 +##蒲 +##蒸 +##蒹 +##蒻 +##蒼 +##蒿 +##蓁 +##蓄 +##蓆 +##蓉 +##蓋 +##蓑 +##蓓 +##蓖 +##蓝 +##蓟 +##蓦 +##蓬 +##蓮 +##蓼 +##蓿 +##蔑 +##蔓 +##蔔 +##蔗 +##蔘 +##蔚 +##蔡 +##蔣 +##蔥 +##蔫 +##蔬 +##蔭 +##蔵 +##蔷 +##蔺 +##蔻 +##蔼 +##蔽 +##蕁 +##蕃 +##蕈 +##蕉 +##蕊 +##蕎 +##蕙 +##蕤 +##蕨 +##蕩 +##蕪 +##蕭 +##蕲 +##蕴 +##蕻 +##蕾 +##薄 +##薅 +##薇 +##薈 +##薊 +##薏 +##薑 +##薔 +##薙 +##薛 +##薦 +##薨 +##薩 +##薪 +##薬 +##薯 +##薰 +##薹 +##藉 +##藍 +##藏 +##藐 +##藓 +##藕 +##藜 +##藝 +##藤 +##藥 +##藩 +##藹 +##藻 +##藿 +##蘆 +##蘇 +##蘊 +##蘋 +##蘑 +##蘚 +##蘭 +##蘸 +##蘼 +##蘿 +##虎 +##虏 +##虐 +##虑 +##虔 +##處 +##虚 +##虛 +##虜 +##虞 +##號 +##虢 +##虧 +##虫 +##虬 +##虱 +##虹 +##虻 +##虽 +##虾 +##蚀 +##蚁 +##蚂 +##蚊 +##蚌 +##蚓 +##蚕 +##蚜 +##蚝 +##蚣 +##蚤 +##蚩 +##蚪 +##蚯 +##蚱 +##蚵 +##蛀 +##蛆 +##蛇 +##蛊 +##蛋 +##蛎 +##蛐 +##蛔 +##蛙 +##蛛 +##蛟 +##蛤 +##蛭 +##蛮 +##蛰 +##蛳 +##蛹 +##蛻 +##蛾 +##蜀 +##蜂 +##蜃 +##蜆 +##蜇 +##蜈 +##蜊 +##蜍 +##蜒 +##蜓 +##蜕 +##蜗 +##蜘 +##蜚 +##蜜 +##蜡 +##蜢 +##蜥 +##蜱 +##蜴 +##蜷 +##蜻 +##蜿 +##蝇 +##蝈 +##蝉 +##蝌 +##蝎 +##蝕 +##蝗 +##蝙 +##蝟 +##蝠 +##蝦 +##蝨 +##蝴 +##蝶 +##蝸 +##蝼 +##螂 +##螃 +##融 +##螞 +##螢 +##螨 +##螯 +##螳 +##螺 +##蟀 +##蟄 +##蟆 +##蟋 +##蟎 +##蟑 +##蟒 +##蟠 +##蟬 +##蟲 +##蟹 +##蟻 +##蟾 +##蠅 +##蠍 +##蠔 +##蠕 +##蠛 +##蠟 +##蠡 +##蠢 +##蠣 +##蠱 +##蠶 +##蠹 +##蠻 +##血 +##衄 +##衅 +##衆 +##行 +##衍 +##術 +##衔 +##街 +##衙 +##衛 +##衝 +##衞 +##衡 +##衢 +##衣 +##补 +##表 +##衩 +##衫 +##衬 +##衮 +##衰 +##衲 +##衷 +##衹 +##衾 +##衿 +##袁 +##袂 +##袄 +##袅 +##袈 +##袋 +##袍 +##袒 +##袖 +##袜 +##袞 +##袤 +##袪 +##被 +##袭 +##袱 +##裁 +##裂 +##装 +##裆 +##裊 +##裏 +##裔 +##裕 +##裘 +##裙 +##補 +##裝 +##裟 +##裡 +##裤 +##裨 +##裱 +##裳 +##裴 +##裸 +##裹 +##製 +##裾 +##褂 +##複 +##褐 +##褒 +##褓 +##褔 +##褚 +##褥 +##褪 +##褫 +##褲 +##褶 +##褻 +##襁 +##襄 +##襟 +##襠 +##襪 +##襬 +##襯 +##襲 +##西 +##要 +##覃 +##覆 +##覇 +##見 +##規 +##覓 +##視 +##覚 +##覦 +##覧 +##親 +##覬 +##観 +##覷 +##覺 +##覽 +##觀 +##见 +##观 +##规 +##觅 +##视 +##览 +##觉 +##觊 +##觎 +##觐 +##觑 +##角 +##觞 +##解 +##觥 +##触 +##觸 +##言 +##訂 +##計 +##訊 +##討 +##訓 +##訕 +##訖 +##託 +##記 +##訛 +##訝 +##訟 +##訣 +##訥 +##訪 +##設 +##許 +##訳 +##訴 +##訶 +##診 +##註 +##証 +##詆 +##詐 +##詔 +##評 +##詛 +##詞 +##詠 +##詡 +##詢 +##詣 +##試 +##詩 +##詫 +##詬 +##詭 +##詮 +##詰 +##話 +##該 +##詳 +##詹 +##詼 +##誅 +##誇 +##誉 +##誌 +##認 +##誓 +##誕 +##誘 +##語 +##誠 +##誡 +##誣 +##誤 +##誥 +##誦 +##誨 +##說 +##説 +##読 +##誰 +##課 +##誹 +##誼 +##調 +##諄 +##談 +##請 +##諏 +##諒 +##論 +##諗 +##諜 +##諡 +##諦 +##諧 +##諫 +##諭 +##諮 +##諱 +##諳 +##諷 +##諸 +##諺 +##諾 +##謀 +##謁 +##謂 +##謄 +##謊 +##謎 +##謐 +##謔 +##謗 +##謙 +##講 +##謝 +##謠 +##謨 +##謬 +##謹 +##謾 +##譁 +##證 +##譎 +##譏 +##識 +##譙 +##譚 +##譜 +##警 +##譬 +##譯 +##議 +##譲 +##譴 +##護 +##譽 +##讀 +##變 +##讓 +##讚 +##讞 +##计 +##订 +##认 +##讥 +##讧 +##讨 +##让 +##讪 +##讫 +##训 +##议 +##讯 +##记 +##讲 +##讳 +##讴 +##讶 +##讷 +##许 +##讹 +##论 +##讼 +##讽 +##设 +##访 +##诀 +##证 +##诃 +##评 +##诅 +##识 +##诈 +##诉 +##诊 +##诋 +##词 +##诏 +##译 +##试 +##诗 +##诘 +##诙 +##诚 +##诛 +##话 +##诞 +##诟 +##诠 +##诡 +##询 +##诣 +##诤 +##该 +##详 +##诧 +##诩 +##诫 +##诬 +##语 +##误 +##诰 +##诱 +##诲 +##说 +##诵 +##诶 +##请 +##诸 +##诺 +##读 +##诽 +##课 +##诿 +##谀 +##谁 +##调 +##谄 +##谅 +##谆 +##谈 +##谊 +##谋 +##谌 +##谍 +##谎 +##谏 +##谐 +##谑 +##谒 +##谓 +##谔 +##谕 +##谗 +##谘 +##谙 +##谚 +##谛 +##谜 +##谟 +##谢 +##谣 +##谤 +##谥 +##谦 +##谧 +##谨 +##谩 +##谪 +##谬 +##谭 +##谯 +##谱 +##谲 +##谴 +##谶 +##谷 +##豁 +##豆 +##豇 +##豈 +##豉 +##豊 +##豌 +##豎 +##豐 +##豔 +##豚 +##象 +##豢 +##豪 +##豫 +##豬 +##豹 +##豺 +##貂 +##貅 +##貌 +##貓 +##貔 +##貘 +##貝 +##貞 +##負 +##財 +##貢 +##貧 +##貨 +##販 +##貪 +##貫 +##責 +##貯 +##貰 +##貳 +##貴 +##貶 +##買 +##貸 +##費 +##貼 +##貽 +##貿 +##賀 +##賁 +##賂 +##賃 +##賄 +##資 +##賈 +##賊 +##賑 +##賓 +##賜 +##賞 +##賠 +##賡 +##賢 +##賣 +##賤 +##賦 +##質 +##賬 +##賭 +##賴 +##賺 +##購 +##賽 +##贅 +##贈 +##贊 +##贍 +##贏 +##贓 +##贖 +##贛 +##贝 +##贞 +##负 +##贡 +##财 +##责 +##贤 +##败 +##账 +##货 +##质 +##贩 +##贪 +##贫 +##贬 +##购 +##贮 +##贯 +##贰 +##贱 +##贲 +##贴 +##贵 +##贷 +##贸 +##费 +##贺 +##贻 +##贼 +##贾 +##贿 +##赁 +##赂 +##赃 +##资 +##赅 +##赈 +##赊 +##赋 +##赌 +##赎 +##赏 +##赐 +##赓 +##赔 +##赖 +##赘 +##赚 +##赛 +##赝 +##赞 +##赠 +##赡 +##赢 +##赣 +##赤 +##赦 +##赧 +##赫 +##赭 +##走 +##赳 +##赴 +##赵 +##赶 +##起 +##趁 +##超 +##越 +##趋 +##趕 +##趙 +##趟 +##趣 +##趨 +##足 +##趴 +##趵 +##趸 +##趺 +##趾 +##跃 +##跄 +##跆 +##跋 +##跌 +##跎 +##跑 +##跖 +##跚 +##跛 +##距 +##跟 +##跡 +##跤 +##跨 +##跩 +##跪 +##路 +##跳 +##践 +##跷 +##跹 +##跺 +##跻 +##踉 +##踊 +##踌 +##踏 +##踐 +##踝 +##踞 +##踟 +##踢 +##踩 +##踪 +##踮 +##踱 +##踴 +##踵 +##踹 +##蹂 +##蹄 +##蹇 +##蹈 +##蹉 +##蹊 +##蹋 +##蹑 +##蹒 +##蹙 +##蹟 +##蹣 +##蹤 +##蹦 +##蹩 +##蹬 +##蹭 +##蹲 +##蹴 +##蹶 +##蹺 +##蹼 +##蹿 +##躁 +##躇 +##躉 +##躊 +##躋 +##躍 +##躏 +##躪 +##身 +##躬 +##躯 +##躲 +##躺 +##軀 +##車 +##軋 +##軌 +##軍 +##軒 +##軟 +##転 +##軸 +##軼 +##軽 +##軾 +##較 +##載 +##輒 +##輓 +##輔 +##輕 +##輛 +##輝 +##輟 +##輩 +##輪 +##輯 +##輸 +##輻 +##輾 +##輿 +##轄 +##轅 +##轆 +##轉 +##轍 +##轎 +##轟 +##车 +##轧 +##轨 +##轩 +##转 +##轭 +##轮 +##软 +##轰 +##轲 +##轴 +##轶 +##轻 +##轼 +##载 +##轿 +##较 +##辄 +##辅 +##辆 +##辇 +##辈 +##辉 +##辊 +##辍 +##辐 +##辑 +##输 +##辕 +##辖 +##辗 +##辘 +##辙 +##辛 +##辜 +##辞 +##辟 +##辣 +##辦 +##辨 +##辩 +##辫 +##辭 +##辮 +##辯 +##辰 +##辱 +##農 +##边 +##辺 +##辻 +##込 +##辽 +##达 +##迁 +##迂 +##迄 +##迅 +##过 +##迈 +##迎 +##运 +##近 +##返 +##还 +##这 +##进 +##远 +##违 +##连 +##迟 +##迢 +##迤 +##迥 +##迦 +##迩 +##迪 +##迫 +##迭 +##述 +##迴 +##迷 +##迸 +##迹 +##迺 +##追 +##退 +##送 +##适 +##逃 +##逅 +##逆 +##选 +##逊 +##逍 +##透 +##逐 +##递 +##途 +##逕 +##逗 +##這 +##通 +##逛 +##逝 +##逞 +##速 +##造 +##逢 +##連 +##逮 +##週 +##進 +##逵 +##逶 +##逸 +##逻 +##逼 +##逾 +##遁 +##遂 +##遅 +##遇 +##遊 +##運 +##遍 +##過 +##遏 +##遐 +##遑 +##遒 +##道 +##達 +##違 +##遗 +##遙 +##遛 +##遜 +##遞 +##遠 +##遢 +##遣 +##遥 +##遨 +##適 +##遭 +##遮 +##遲 +##遴 +##遵 +##遶 +##遷 +##選 +##遺 +##遼 +##遽 +##避 +##邀 +##邁 +##邂 +##邃 +##還 +##邇 +##邈 +##邊 +##邋 +##邏 +##邑 +##邓 +##邕 +##邛 +##邝 +##邢 +##那 +##邦 +##邨 +##邪 +##邬 +##邮 +##邯 +##邰 +##邱 +##邳 +##邵 +##邸 +##邹 +##邺 +##邻 +##郁 +##郅 +##郊 +##郎 +##郑 +##郜 +##郝 +##郡 +##郢 +##郤 +##郦 +##郧 +##部 +##郫 +##郭 +##郴 +##郵 +##郷 +##郸 +##都 +##鄂 +##鄉 +##鄒 +##鄔 +##鄙 +##鄞 +##鄢 +##鄧 +##鄭 +##鄰 +##鄱 +##鄲 +##鄺 +##酉 +##酊 +##酋 +##酌 +##配 +##酐 +##酒 +##酗 +##酚 +##酝 +##酢 +##酣 +##酥 +##酩 +##酪 +##酬 +##酮 +##酯 +##酰 +##酱 +##酵 +##酶 +##酷 +##酸 +##酿 +##醃 +##醇 +##醉 +##醋 +##醍 +##醐 +##醒 +##醚 +##醛 +##醜 +##醞 +##醣 +##醪 +##醫 +##醬 +##醮 +##醯 +##醴 +##醺 +##釀 +##釁 +##采 +##釉 +##释 +##釋 +##里 +##重 +##野 +##量 +##釐 +##金 +##釗 +##釘 +##釜 +##針 +##釣 +##釦 +##釧 +##釵 +##鈀 +##鈉 +##鈍 +##鈎 +##鈔 +##鈕 +##鈞 +##鈣 +##鈦 +##鈪 +##鈴 +##鈺 +##鈾 +##鉀 +##鉄 +##鉅 +##鉉 +##鉑 +##鉗 +##鉚 +##鉛 +##鉤 +##鉴 +##鉻 +##銀 +##銃 +##銅 +##銑 +##銓 +##銖 +##銘 +##銜 +##銬 +##銭 +##銮 +##銳 +##銷 +##銹 +##鋁 +##鋅 +##鋒 +##鋤 +##鋪 +##鋰 +##鋸 +##鋼 +##錄 +##錐 +##錘 +##錚 +##錠 +##錢 +##錦 +##錨 +##錫 +##錮 +##錯 +##録 +##錳 +##錶 +##鍊 +##鍋 +##鍍 +##鍛 +##鍥 +##鍰 +##鍵 +##鍺 +##鍾 +##鎂 +##鎊 +##鎌 +##鎏 +##鎔 +##鎖 +##鎗 +##鎚 +##鎧 +##鎬 +##鎮 +##鎳 +##鏈 +##鏖 +##鏗 +##鏘 +##鏞 +##鏟 +##鏡 +##鏢 +##鏤 +##鏽 +##鐘 +##鐮 +##鐲 +##鐳 +##鐵 +##鐸 +##鐺 +##鑄 +##鑊 +##鑑 +##鑒 +##鑣 +##鑫 +##鑰 +##鑲 +##鑼 +##鑽 +##鑾 +##鑿 +##针 +##钉 +##钊 +##钎 +##钏 +##钒 +##钓 +##钗 +##钙 +##钛 +##钜 +##钝 +##钞 +##钟 +##钠 +##钡 +##钢 +##钣 +##钤 +##钥 +##钦 +##钧 +##钨 +##钩 +##钮 +##钯 +##钰 +##钱 +##钳 +##钴 +##钵 +##钺 +##钻 +##钼 +##钾 +##钿 +##铀 +##铁 +##铂 +##铃 +##铄 +##铅 +##铆 +##铉 +##铎 +##铐 +##铛 +##铜 +##铝 +##铠 +##铡 +##铢 +##铣 +##铤 +##铨 +##铩 +##铬 +##铭 +##铮 +##铰 +##铲 +##铵 +##银 +##铸 +##铺 +##链 +##铿 +##销 +##锁 +##锂 +##锄 +##锅 +##锆 +##锈 +##锉 +##锋 +##锌 +##锏 +##锐 +##锑 +##错 +##锚 +##锟 +##锡 +##锢 +##锣 +##锤 +##锥 +##锦 +##锭 +##键 +##锯 +##锰 +##锲 +##锵 +##锹 +##锺 +##锻 +##镀 +##镁 +##镂 +##镇 +##镉 +##镌 +##镍 +##镐 +##镑 +##镕 +##镖 +##镗 +##镛 +##镜 +##镣 +##镭 +##镯 +##镰 +##镳 +##镶 +##長 +##长 +##門 +##閃 +##閉 +##開 +##閎 +##閏 +##閑 +##閒 +##間 +##閔 +##閘 +##閡 +##関 +##閣 +##閥 +##閨 +##閩 +##閱 +##閲 +##閹 +##閻 +##閾 +##闆 +##闇 +##闊 +##闌 +##闍 +##闔 +##闕 +##闖 +##闘 +##關 +##闡 +##闢 +##门 +##闪 +##闫 +##闭 +##问 +##闯 +##闰 +##闲 +##间 +##闵 +##闷 +##闸 +##闹 +##闺 +##闻 +##闽 +##闾 +##阀 +##阁 +##阂 +##阅 +##阆 +##阇 +##阈 +##阉 +##阎 +##阐 +##阑 +##阔 +##阕 +##阖 +##阙 +##阚 +##阜 +##队 +##阡 +##阪 +##阮 +##阱 +##防 +##阳 +##阴 +##阵 +##阶 +##阻 +##阿 +##陀 +##陂 +##附 +##际 +##陆 +##陇 +##陈 +##陋 +##陌 +##降 +##限 +##陕 +##陛 +##陝 +##陞 +##陟 +##陡 +##院 +##陣 +##除 +##陨 +##险 +##陪 +##陰 +##陲 +##陳 +##陵 +##陶 +##陷 +##陸 +##険 +##陽 +##隅 +##隆 +##隈 +##隊 +##隋 +##隍 +##階 +##随 +##隐 +##隔 +##隕 +##隘 +##隙 +##際 +##障 +##隠 +##隣 +##隧 +##隨 +##險 +##隱 +##隴 +##隶 +##隸 +##隻 +##隼 +##隽 +##难 +##雀 +##雁 +##雄 +##雅 +##集 +##雇 +##雉 +##雋 +##雌 +##雍 +##雎 +##雏 +##雑 +##雒 +##雕 +##雖 +##雙 +##雛 +##雜 +##雞 +##離 +##難 +##雨 +##雪 +##雯 +##雰 +##雲 +##雳 +##零 +##雷 +##雹 +##電 +##雾 +##需 +##霁 +##霄 +##霆 +##震 +##霈 +##霉 +##霊 +##霍 +##霎 +##霏 +##霑 +##霓 +##霖 +##霜 +##霞 +##霧 +##霭 +##霰 +##露 +##霸 +##霹 +##霽 +##霾 +##靂 +##靄 +##靈 +##青 +##靓 +##靖 +##静 +##靚 +##靛 +##靜 +##非 +##靠 +##靡 +##面 +##靥 +##靦 +##革 +##靳 +##靴 +##靶 +##靼 +##鞅 +##鞋 +##鞍 +##鞏 +##鞑 +##鞘 +##鞠 +##鞣 +##鞦 +##鞭 +##韆 +##韋 +##韌 +##韓 +##韜 +##韦 +##韧 +##韩 +##韬 +##韭 +##音 +##韵 +##韶 +##韻 +##響 +##頁 +##頂 +##頃 +##項 +##順 +##須 +##頌 +##預 +##頑 +##頒 +##頓 +##頗 +##領 +##頜 +##頡 +##頤 +##頫 +##頭 +##頰 +##頷 +##頸 +##頹 +##頻 +##頼 +##顆 +##題 +##額 +##顎 +##顏 +##顔 +##願 +##顛 +##類 +##顧 +##顫 +##顯 +##顱 +##顴 +##页 +##顶 +##顷 +##项 +##顺 +##须 +##顼 +##顽 +##顾 +##顿 +##颁 +##颂 +##预 +##颅 +##领 +##颇 +##颈 +##颉 +##颊 +##颌 +##颍 +##颐 +##频 +##颓 +##颔 +##颖 +##颗 +##题 +##颚 +##颛 +##颜 +##额 +##颞 +##颠 +##颡 +##颢 +##颤 +##颦 +##颧 +##風 +##颯 +##颱 +##颳 +##颶 +##颼 +##飄 +##飆 +##风 +##飒 +##飓 +##飕 +##飘 +##飙 +##飚 +##飛 +##飞 +##食 +##飢 +##飨 +##飩 +##飪 +##飯 +##飲 +##飼 +##飽 +##飾 +##餃 +##餅 +##餉 +##養 +##餌 +##餐 +##餒 +##餓 +##餘 +##餚 +##餛 +##餞 +##餡 +##館 +##餮 +##餵 +##餾 +##饅 +##饈 +##饋 +##饌 +##饍 +##饑 +##饒 +##饕 +##饗 +##饞 +##饥 +##饨 +##饪 +##饬 +##饭 +##饮 +##饯 +##饰 +##饱 +##饲 +##饴 +##饵 +##饶 +##饷 +##饺 +##饼 +##饽 +##饿 +##馀 +##馁 +##馄 +##馅 +##馆 +##馈 +##馋 +##馍 +##馏 +##馒 +##馔 +##首 +##馗 +##香 +##馥 +##馨 +##馬 +##馭 +##馮 +##馳 +##馴 +##駁 +##駄 +##駅 +##駆 +##駐 +##駒 +##駕 +##駛 +##駝 +##駭 +##駱 +##駿 +##騁 +##騎 +##騏 +##験 +##騙 +##騨 +##騰 +##騷 +##驀 +##驅 +##驊 +##驍 +##驒 +##驕 +##驗 +##驚 +##驛 +##驟 +##驢 +##驥 +##马 +##驭 +##驮 +##驯 +##驰 +##驱 +##驳 +##驴 +##驶 +##驷 +##驸 +##驹 +##驻 +##驼 +##驾 +##驿 +##骁 +##骂 +##骄 +##骅 +##骆 +##骇 +##骈 +##骊 +##骋 +##验 +##骏 +##骐 +##骑 +##骗 +##骚 +##骛 +##骜 +##骞 +##骠 +##骡 +##骤 +##骥 +##骧 +##骨 +##骯 +##骰 +##骶 +##骷 +##骸 +##骼 +##髂 +##髅 +##髋 +##髏 +##髒 +##髓 +##體 +##髖 +##高 +##髦 +##髪 +##髮 +##髯 +##髻 +##鬃 +##鬆 +##鬍 +##鬓 +##鬚 +##鬟 +##鬢 +##鬣 +##鬥 +##鬧 +##鬱 +##鬼 +##魁 +##魂 +##魄 +##魅 +##魇 +##魍 +##魏 +##魔 +##魘 +##魚 +##魯 +##魷 +##鮑 +##鮨 +##鮪 +##鮭 +##鮮 +##鯉 +##鯊 +##鯖 +##鯛 +##鯨 +##鯰 +##鯽 +##鰍 +##鰓 +##鰭 +##鰲 +##鰻 +##鰾 +##鱈 +##鱉 +##鱔 +##鱗 +##鱷 +##鱸 +##鱼 +##鱿 +##鲁 +##鲈 +##鲍 +##鲑 +##鲛 +##鲜 +##鲟 +##鲢 +##鲤 +##鲨 +##鲫 +##鲱 +##鲲 +##鲶 +##鲷 +##鲸 +##鳃 +##鳄 +##鳅 +##鳌 +##鳍 +##鳕 +##鳖 +##鳗 +##鳝 +##鳞 +##鳥 +##鳩 +##鳳 +##鳴 +##鳶 +##鴉 +##鴕 +##鴛 +##鴦 +##鴨 +##鴻 +##鴿 +##鵑 +##鵜 +##鵝 +##鵡 +##鵬 +##鵰 +##鵲 +##鶘 +##鶩 +##鶯 +##鶴 +##鷗 +##鷲 +##鷹 +##鷺 +##鸚 +##鸞 +##鸟 +##鸠 +##鸡 +##鸢 +##鸣 +##鸥 +##鸦 +##鸨 +##鸪 +##鸭 +##鸯 +##鸳 +##鸵 +##鸽 +##鸾 +##鸿 +##鹂 +##鹃 +##鹄 +##鹅 +##鹈 +##鹉 +##鹊 +##鹌 +##鹏 +##鹑 +##鹕 +##鹘 +##鹜 +##鹞 +##鹤 +##鹦 +##鹧 +##鹫 +##鹭 +##鹰 +##鹳 +##鹵 +##鹹 +##鹼 +##鹽 +##鹿 +##麂 +##麋 +##麒 +##麓 +##麗 +##麝 +##麟 +##麥 +##麦 +##麩 +##麴 +##麵 +##麸 +##麺 +##麻 +##麼 +##麽 +##麾 +##黃 +##黄 +##黍 +##黎 +##黏 +##黑 +##黒 +##黔 +##默 +##黛 +##黜 +##黝 +##點 +##黠 +##黨 +##黯 +##黴 +##鼋 +##鼎 +##鼐 +##鼓 +##鼠 +##鼬 +##鼹 +##鼻 +##鼾 +##齁 +##齊 +##齋 +##齐 +##齒 +##齡 +##齢 +##齣 +##齦 +##齿 +##龄 +##龅 +##龈 +##龊 +##龋 +##龌 +##龍 +##龐 +##龔 +##龕 +##龙 +##龚 +##龛 +##龜 +##龟 +##︰ +##︱ +##︶ +##︿ +##﹁ +##﹂ +##﹍ +##﹏ +##﹐ +##﹑ +##﹒ +##﹔ +##﹕ +##﹖ +##﹗ +##﹙ +##﹚ +##﹝ +##﹞ +##﹡ +##﹣ +##! +##" +### +##$ +##% +##& +##' +##( +##) +##* +##, +##- +##. +##/ +##: +##; +##< +##? +##@ +##[ +##\ +##] +##^ +##_ +##` +##f +##h +##j +##u +##w +##z +##{ +##} +##。 +##「 +##」 +##、 +##・ +##ッ +##ー +##イ +##ク +##シ +##ス +##ト +##ノ +##フ +##ラ +##ル +##ン +##゙ +##゚ +## ̄ +##¥ +##👍 +##🔥 +##😂 +##😎 diff --git a/diffrhythm/g2p/sources/pinyin_2_bpmf.txt b/diffrhythm/g2p/sources/pinyin_2_bpmf.txt new file mode 100644 index 0000000000000000000000000000000000000000..af74dc687a547ed7822dacc77b7491924a8dcf1b --- /dev/null +++ b/diffrhythm/g2p/sources/pinyin_2_bpmf.txt @@ -0,0 +1,429 @@ +a ㄚ +ai ㄞ +an ㄢ +ang ㄤ +ao ㄠ +ba ㄅㄚ +bai ㄅㄞ +ban ㄅㄢ +bang ㄅㄤ +bao ㄅㄠ +bei ㄅㄟ +ben ㄅㄣ +beng ㄅㄥ +bi ㄅㄧ +bian ㄅㄧㄢ +biang ㄅㄧㄤ +biao ㄅㄧㄠ +bie ㄅㄧㄝ +bin ㄅㄧㄣ +bing ㄅㄧㄥ +bo ㄅㄛ +bu ㄅㄨ +ca ㄘㄚ +cai ㄘㄞ +can ㄘㄢ +cang ㄘㄤ +cao ㄘㄠ +ce ㄘㄜ +cen ㄘㄣ +ceng ㄘㄥ +cha ㄔㄚ +chai ㄔㄞ +chan ㄔㄢ +chang ㄔㄤ +chao ㄔㄠ +che ㄔㄜ +chen ㄔㄣ +cheng ㄔㄥ +chi ㄔ +chong ㄔㄨㄥ +chou ㄔㄡ +chu ㄔㄨ +chua ㄔㄨㄚ +chuai ㄔㄨㄞ +chuan ㄔㄨㄢ +chuang ㄔㄨㄤ +chui ㄔㄨㄟ +chun ㄔㄨㄣ +chuo ㄔㄨㄛ +ci ㄘ +cong ㄘㄨㄥ +cou ㄘㄡ +cu ㄘㄨ +cuan ㄘㄨㄢ +cui ㄘㄨㄟ +cun ㄘㄨㄣ +cuo ㄘㄨㄛ +da ㄉㄚ +dai ㄉㄞ +dan ㄉㄢ +dang ㄉㄤ +dao ㄉㄠ +de ㄉㄜ +dei ㄉㄟ +den ㄉㄣ +deng ㄉㄥ +di ㄉㄧ +dia ㄉㄧㄚ +dian ㄉㄧㄢ +diao ㄉㄧㄠ +die ㄉㄧㄝ +din ㄉㄧㄣ +ding ㄉㄧㄥ +diu ㄉㄧㄡ +dong ㄉㄨㄥ +dou ㄉㄡ +du ㄉㄨ +duan ㄉㄨㄢ +dui ㄉㄨㄟ +dun ㄉㄨㄣ +duo ㄉㄨㄛ +e ㄜ +ei ㄟ +en ㄣ +eng ㄥ +er ㄦ +fa ㄈㄚ +fan ㄈㄢ +fang ㄈㄤ +fei ㄈㄟ +fen ㄈㄣ +feng ㄈㄥ +fo ㄈㄛ +fou ㄈㄡ +fu ㄈㄨ +ga ㄍㄚ +gai ㄍㄞ +gan ㄍㄢ +gang ㄍㄤ +gao ㄍㄠ +ge ㄍㄜ +gei ㄍㄟ +gen ㄍㄣ +geng ㄍㄥ +gong ㄍㄨㄥ +gou ㄍㄡ +gu ㄍㄨ +gua ㄍㄨㄚ +guai ㄍㄨㄞ +guan ㄍㄨㄢ +guang ㄍㄨㄤ +gui ㄍㄨㄟ +gun ㄍㄨㄣ +guo ㄍㄨㄛ +ha ㄏㄚ +hai ㄏㄞ +han ㄏㄢ +hang ㄏㄤ +hao ㄏㄠ +he ㄏㄜ +hei ㄏㄟ +hen ㄏㄣ +heng ㄏㄥ +hm ㄏㄇ +hong ㄏㄨㄥ +hou ㄏㄡ +hu ㄏㄨ +hua ㄏㄨㄚ +huai ㄏㄨㄞ +huan ㄏㄨㄢ +huang ㄏㄨㄤ +hui ㄏㄨㄟ +hun ㄏㄨㄣ +huo ㄏㄨㄛ +ji ㄐㄧ +jia ㄐㄧㄚ +jian ㄐㄧㄢ +jiang ㄐㄧㄤ +jiao ㄐㄧㄠ +jie ㄐㄧㄝ +jin ㄐㄧㄣ +jing ㄐㄧㄥ +jiong ㄐㄩㄥ +jiu ㄐㄧㄡ +ju ㄐㄩ +jv ㄐㄩ +juan ㄐㄩㄢ +jvan ㄐㄩㄢ +jue ㄐㄩㄝ +jve ㄐㄩㄝ +jun ㄐㄩㄣ +ka ㄎㄚ +kai ㄎㄞ +kan ㄎㄢ +kang ㄎㄤ +kao ㄎㄠ +ke ㄎㄜ +kei ㄎㄟ +ken ㄎㄣ +keng ㄎㄥ +kong ㄎㄨㄥ +kou ㄎㄡ +ku ㄎㄨ +kua ㄎㄨㄚ +kuai ㄎㄨㄞ +kuan ㄎㄨㄢ +kuang ㄎㄨㄤ +kui ㄎㄨㄟ +kun ㄎㄨㄣ +kuo ㄎㄨㄛ +la ㄌㄚ +lai ㄌㄞ +lan ㄌㄢ +lang ㄌㄤ +lao ㄌㄠ +le ㄌㄜ +lei ㄌㄟ +leng ㄌㄥ +li ㄌㄧ +lia ㄌㄧㄚ +lian ㄌㄧㄢ +liang ㄌㄧㄤ +liao ㄌㄧㄠ +lie ㄌㄧㄝ +lin ㄌㄧㄣ +ling ㄌㄧㄥ +liu ㄌㄧㄡ +lo ㄌㄛ +long ㄌㄨㄥ +lou ㄌㄡ +lu ㄌㄨ +luan ㄌㄨㄢ +lue ㄌㄩㄝ +lun ㄌㄨㄣ +luo ㄌㄨㄛ +lv ㄌㄩ +lve ㄌㄩㄝ +m ㄇㄨ +ma ㄇㄚ +mai ㄇㄞ +man ㄇㄢ +mang ㄇㄤ +mao ㄇㄠ +me ㄇㄜ +mei ㄇㄟ +men ㄇㄣ +meng ㄇㄥ +mi ㄇㄧ +mian ㄇㄧㄢ +miao ㄇㄧㄠ +mie ㄇㄧㄝ +min ㄇㄧㄣ +ming ㄇㄧㄥ +miu ㄇㄧㄡ +mo ㄇㄛ +mou ㄇㄡ +mu ㄇㄨ +n ㄣ +na ㄋㄚ +nai ㄋㄞ +nan ㄋㄢ +nang ㄋㄤ +nao ㄋㄠ +ne ㄋㄜ +nei ㄋㄟ +nen ㄋㄣ +neng ㄋㄥ +ng ㄣ +ni ㄋㄧ +nian ㄋㄧㄢ +niang ㄋㄧㄤ +niao ㄋㄧㄠ +nie ㄋㄧㄝ +nin ㄋㄧㄣ +ning ㄋㄧㄥ +niu ㄋㄧㄡ +nong ㄋㄨㄥ +nou ㄋㄡ +nu ㄋㄨ +nuan ㄋㄨㄢ +nue ㄋㄩㄝ +nun ㄋㄨㄣ +nuo ㄋㄨㄛ +nv ㄋㄩ +nve ㄋㄩㄝ +o ㄛ +ou ㄡ +pa ㄆㄚ +pai ㄆㄞ +pan ㄆㄢ +pang ㄆㄤ +pao ㄆㄠ +pei ㄆㄟ +pen ㄆㄣ +peng ㄆㄥ +pi ㄆㄧ +pian ㄆㄧㄢ +piao ㄆㄧㄠ +pie ㄆㄧㄝ +pin ㄆㄧㄣ +ping ㄆㄧㄥ +po ㄆㄛ +pou ㄆㄡ +pu ㄆㄨ +qi ㄑㄧ +qia ㄑㄧㄚ +qian ㄑㄧㄢ +qiang ㄑㄧㄤ +qiao ㄑㄧㄠ +qie ㄑㄧㄝ +qin ㄑㄧㄣ +qing ㄑㄧㄥ +qiong ㄑㄩㄥ +qiu ㄑㄧㄡ +qu ㄑㄩ +quan ㄑㄩㄢ +qvan ㄑㄩㄢ +que ㄑㄩㄝ +qun ㄑㄩㄣ +ran ㄖㄢ +rang ㄖㄤ +rao ㄖㄠ +re ㄖㄜ +ren ㄖㄣ +reng ㄖㄥ +ri ㄖ +rong ㄖㄨㄥ +rou ㄖㄡ +ru ㄖㄨ +rua ㄖㄨㄚ +ruan ㄖㄨㄢ +rui ㄖㄨㄟ +run ㄖㄨㄣ +ruo ㄖㄨㄛ +sa ㄙㄚ +sai ㄙㄞ +san ㄙㄢ +sang ㄙㄤ +sao ㄙㄠ +se ㄙㄜ +sen ㄙㄣ +seng ㄙㄥ +sha ㄕㄚ +shai ㄕㄞ +shan ㄕㄢ +shang ㄕㄤ +shao ㄕㄠ +she ㄕㄜ +shei ㄕㄟ +shen ㄕㄣ +sheng ㄕㄥ +shi ㄕ +shou ㄕㄡ +shu ㄕㄨ +shua ㄕㄨㄚ +shuai ㄕㄨㄞ +shuan ㄕㄨㄢ +shuang ㄕㄨㄤ +shui ㄕㄨㄟ +shun ㄕㄨㄣ +shuo ㄕㄨㄛ +si ㄙ +song ㄙㄨㄥ +sou ㄙㄡ +su ㄙㄨ +suan ㄙㄨㄢ +sui ㄙㄨㄟ +sun ㄙㄨㄣ +suo ㄙㄨㄛ +ta ㄊㄚ +tai ㄊㄞ +tan ㄊㄢ +tang ㄊㄤ +tao ㄊㄠ +te ㄊㄜ +tei ㄊㄟ +teng ㄊㄥ +ti ㄊㄧ +tian ㄊㄧㄢ +tiao ㄊㄧㄠ +tie ㄊㄧㄝ +ting ㄊㄧㄥ +tong ㄊㄨㄥ +tou ㄊㄡ +tsuo ㄘㄨㄛ +tu ㄊㄨ +tuan ㄊㄨㄢ +tui ㄊㄨㄟ +tun ㄊㄨㄣ +tuo ㄊㄨㄛ +tzan ㄗㄢ +wa ㄨㄚ +wai ㄨㄞ +wan ㄨㄢ +wang ㄨㄤ +wei ㄨㄟ +wen ㄨㄣ +weng ㄨㄥ +wo ㄨㄛ +wong ㄨㄥ +wu ㄨ +xi ㄒㄧ +xia ㄒㄧㄚ +xian ㄒㄧㄢ +xiang ㄒㄧㄤ +xiao ㄒㄧㄠ +xie ㄒㄧㄝ +xin ㄒㄧㄣ +xing ㄒㄧㄥ +xiong ㄒㄩㄥ +xiu ㄒㄧㄡ +xu ㄒㄩ +xuan ㄒㄩㄢ +xue ㄒㄩㄝ +xun ㄒㄩㄣ +ya ㄧㄚ +yai ㄧㄞ +yan ㄧㄢ +yang ㄧㄤ +yao ㄧㄠ +ye ㄧㄝ +yi ㄧ +yin ㄧㄣ +ying ㄧㄥ +yo ㄧㄛ +yong ㄩㄥ +you ㄧㄡ +yu ㄩ +yuan ㄩㄢ +yue ㄩㄝ +yve ㄩㄝ +yun ㄩㄣ +za ㄗㄚ +zai ㄗㄞ +zan ㄗㄢ +zang ㄗㄤ +zao ㄗㄠ +ze ㄗㄜ +zei ㄗㄟ +zen ㄗㄣ +zeng ㄗㄥ +zha ㄓㄚ +zhai ㄓㄞ +zhan ㄓㄢ +zhang ㄓㄤ +zhao ㄓㄠ +zhe ㄓㄜ +zhei ㄓㄟ +zhen ㄓㄣ +zheng ㄓㄥ +zhi ㄓ +zhong ㄓㄨㄥ +zhou ㄓㄡ +zhu ㄓㄨ +zhua ㄓㄨㄚ +zhuai ㄓㄨㄞ +zhuan ㄓㄨㄢ +zhuang ㄓㄨㄤ +zhui ㄓㄨㄟ +zhun ㄓㄨㄣ +zhuo ㄓㄨㄛ +zi ㄗ +zong ㄗㄨㄥ +zou ㄗㄡ +zu ㄗㄨ +zuan ㄗㄨㄢ +zui ㄗㄨㄟ +zun ㄗㄨㄣ +zuo ㄗㄨㄛ diff --git a/diffrhythm/g2p/utils/__pycache__/front_utils.cpython-310.pyc b/diffrhythm/g2p/utils/__pycache__/front_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22df02bd4faa79d79cee382fcd0ea2d69beba53b Binary files /dev/null and b/diffrhythm/g2p/utils/__pycache__/front_utils.cpython-310.pyc differ diff --git a/diffrhythm/g2p/utils/__pycache__/front_utils.cpython-311.pyc b/diffrhythm/g2p/utils/__pycache__/front_utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12204d177ec80d9ff8e455aa5f58d9f284d03661 Binary files /dev/null and b/diffrhythm/g2p/utils/__pycache__/front_utils.cpython-311.pyc differ diff --git a/diffrhythm/g2p/utils/__pycache__/g2p.cpython-310.pyc b/diffrhythm/g2p/utils/__pycache__/g2p.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..145397ccf24aaf1e80529c95bc2729ea52401165 Binary files /dev/null and b/diffrhythm/g2p/utils/__pycache__/g2p.cpython-310.pyc differ diff --git a/diffrhythm/g2p/utils/__pycache__/g2p.cpython-311.pyc b/diffrhythm/g2p/utils/__pycache__/g2p.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aab89697039771ecb2c1507222aa6c4ecafdcc8f Binary files /dev/null and b/diffrhythm/g2p/utils/__pycache__/g2p.cpython-311.pyc differ diff --git a/diffrhythm/g2p/utils/front_utils.py b/diffrhythm/g2p/utils/front_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..de9f878b5ea87868aee62b3eed5c29e3e95776b7 --- /dev/null +++ b/diffrhythm/g2p/utils/front_utils.py @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import os + + +def generate_poly_lexicon(file_path: str): + """Generate poly char lexicon for Mandarin Chinese.""" + poly_dict = {} + + with open(file_path, "r", encoding="utf-8") as readf: + txt_list = readf.readlines() + for txt in txt_list: + word = txt.strip("\n") + if word not in poly_dict: + poly_dict[word] = 1 + readf.close() + return poly_dict diff --git a/diffrhythm/g2p/utils/g2p.py b/diffrhythm/g2p/utils/g2p.py new file mode 100644 index 0000000000000000000000000000000000000000..aba5e2f3fd217dd0f018ba49fa0aa298863740c8 --- /dev/null +++ b/diffrhythm/g2p/utils/g2p.py @@ -0,0 +1,139 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from phonemizer.backend import EspeakBackend +from phonemizer.separator import Separator +from phonemizer.utils import list2str, str2list +from typing import List, Union +import os +import json +import sys + +# separator=Separator(phone=' ', word=' _ ', syllable='|'), +separator = Separator(word=" _ ", syllable="|", phone=" ") + +phonemizer_zh = EspeakBackend( + "cmn", preserve_punctuation=False, with_stress=False, language_switch="remove-flags" +) +# phonemizer_zh.separator = separator + +phonemizer_en = EspeakBackend( + "en-us", + preserve_punctuation=False, + with_stress=False, + language_switch="remove-flags", +) +# phonemizer_en.separator = separator + +phonemizer_ja = EspeakBackend( + "ja", preserve_punctuation=False, with_stress=False, language_switch="remove-flags" +) +# phonemizer_ja.separator = separator + +phonemizer_ko = EspeakBackend( + "ko", preserve_punctuation=False, with_stress=False, language_switch="remove-flags" +) +# phonemizer_ko.separator = separator + +phonemizer_fr = EspeakBackend( + "fr-fr", + preserve_punctuation=False, + with_stress=False, + language_switch="remove-flags", +) +# phonemizer_fr.separator = separator + +phonemizer_de = EspeakBackend( + "de", preserve_punctuation=False, with_stress=False, language_switch="remove-flags" +) +# phonemizer_de.separator = separator + + +lang2backend = { + "zh": phonemizer_zh, + "ja": phonemizer_ja, + "en": phonemizer_en, + "fr": phonemizer_fr, + "ko": phonemizer_ko, + "de": phonemizer_de, +} + +with open("./diffrhythm/g2p/utils/mls_en.json", "r") as f: + json_data = f.read() +token = json.loads(json_data) + + +def phonemizer_g2p(text, language): + langbackend = lang2backend[language] + phonemes = _phonemize( + langbackend, + text, + separator, + strip=True, + njobs=1, + prepend_text=False, + preserve_empty_lines=False, + ) + token_id = [] + if isinstance(phonemes, list): + for phone in phonemes: + phonemes_split = phone.split(" ") + token_id.append([token[p] for p in phonemes_split if p in token]) + else: + phonemes_split = phonemes.split(" ") + token_id = [token[p] for p in phonemes_split if p in token] + return phonemes, token_id + + +def _phonemize( # pylint: disable=too-many-arguments + backend, + text: Union[str, List[str]], + separator: Separator, + strip: bool, + njobs: int, + prepend_text: bool, + preserve_empty_lines: bool, +): + """Auxiliary function to phonemize() + + Does the phonemization and returns the phonemized text. Raises a + RuntimeError on error. + + """ + # remember the text type for output (either list or string) + text_type = type(text) + + # force the text as a list + text = [line.strip(os.linesep) for line in str2list(text)] + + # if preserving empty lines, note the index of each empty line + if preserve_empty_lines: + empty_lines = [n for n, line in enumerate(text) if not line.strip()] + + # ignore empty lines + text = [line for line in text if line.strip()] + + if text: + # phonemize the text + phonemized = backend.phonemize( + text, separator=separator, strip=strip, njobs=njobs + ) + else: + phonemized = [] + + # if preserving empty lines, reinsert them into text and phonemized lists + if preserve_empty_lines: + for i in empty_lines: # noqa + if prepend_text: + text.insert(i, "") + phonemized.insert(i, "") + + # at that point, the phonemized text is a list of str. Format it as + # expected by the parameters + if prepend_text: + return list(zip(text, phonemized)) + if text_type == str: + return list2str(phonemized) + return phonemized diff --git a/diffrhythm/g2p/utils/log.py b/diffrhythm/g2p/utils/log.py new file mode 100644 index 0000000000000000000000000000000000000000..d10b887ef2e9292bd79c628e9ed7881c7a91bf52 --- /dev/null +++ b/diffrhythm/g2p/utils/log.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Amphion. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + + +import functools +import logging + +__all__ = [ + "logger", +] + + +class Logger(object): + def __init__(self, name: str = None): + name = "PaddleSpeech" if not name else name + self.logger = logging.getLogger(name) + + log_config = { + "DEBUG": 10, + "INFO": 20, + "TRAIN": 21, + "EVAL": 22, + "WARNING": 30, + "ERROR": 40, + "CRITICAL": 50, + "EXCEPTION": 100, + } + for key, level in log_config.items(): + logging.addLevelName(level, key) + if key == "EXCEPTION": + self.__dict__[key.lower()] = self.logger.exception + else: + self.__dict__[key.lower()] = functools.partial(self.__call__, level) + + self.format = logging.Formatter( + fmt="[%(asctime)-15s] [%(levelname)8s] - %(message)s" + ) + + self.handler = logging.StreamHandler() + self.handler.setFormatter(self.format) + + self.logger.addHandler(self.handler) + self.logger.setLevel(logging.INFO) + self.logger.propagate = False + + def __call__(self, log_level: str, msg: str): + self.logger.log(log_level, msg) + + +logger = Logger() diff --git a/diffrhythm/g2p/utils/mls_en.json b/diffrhythm/g2p/utils/mls_en.json new file mode 100644 index 0000000000000000000000000000000000000000..f3aadbf144427af10ec06ca3cab8c4a2c461925d --- /dev/null +++ b/diffrhythm/g2p/utils/mls_en.json @@ -0,0 +1,335 @@ +{ + "[UNK]": 0, + "_": 1, + "b": 2, + "d": 3, + "f": 4, + "h": 5, + "i": 6, + "j": 7, + "k": 8, + "l": 9, + "m": 10, + "n": 11, + "p": 12, + "r": 13, + "s": 14, + "t": 15, + "v": 16, + "w": 17, + "x": 18, + "z": 19, + "æ": 20, + "ç": 21, + "ð": 22, + "ŋ": 23, + "ɐ": 24, + "ɔ": 25, + "ə": 26, + "ɚ": 27, + "ɛ": 28, + "ɡ": 29, + "ɪ": 30, + "ɬ": 31, + "ɹ": 32, + "ɾ": 33, + "ʃ": 34, + "ʊ": 35, + "ʌ": 36, + "ʒ": 37, + "ʔ": 38, + "θ": 39, + "ᵻ": 40, + "aɪ": 41, + "aʊ": 42, + "dʒ": 43, + "eɪ": 44, + "iə": 45, + "iː": 46, + "n̩": 47, + "oʊ": 48, + "oː": 49, + "tʃ": 50, + "uː": 51, + "ææ": 52, + "ɐɐ": 53, + "ɑː": 54, + "ɑ̃": 55, + "ɔɪ": 56, + "ɔː": 57, + "ɔ̃": 58, + "əl": 59, + "ɛɹ": 60, + "ɜː": 61, + "ɡʲ": 62, + "ɪɹ": 63, + "ʊɹ": 64, + "aɪə": 65, + "aɪɚ": 66, + "iːː": 67, + "oːɹ": 68, + "ɑːɹ": 69, + "ɔːɹ": 70, + + "1": 71, + "a": 72, + "e": 73, + "o": 74, + "q": 75, + "u": 76, + "y": 77, + "ɑ": 78, + "ɒ": 79, + "ɕ": 80, + "ɣ": 81, + "ɫ": 82, + "ɯ": 83, + "ʐ": 84, + "ʲ": 85, + "a1": 86, + "a2": 87, + "a5": 88, + "ai": 89, + "aɜ": 90, + "aː": 91, + "ei": 92, + "eə": 93, + "i.": 94, + "i1": 95, + "i2": 96, + "i5": 97, + "io": 98, + "iɑ": 99, + "iɛ": 100, + "iɜ": 101, + "i̪": 102, + "kh": 103, + "nʲ": 104, + "o1": 105, + "o2": 106, + "o5": 107, + "ou": 108, + "oɜ": 109, + "ph": 110, + "s.": 111, + "th": 112, + "ts": 113, + "tɕ": 114, + "u1": 115, + "u2": 116, + "u5": 117, + "ua": 118, + "uo": 119, + "uə": 120, + "uɜ": 121, + "y1": 122, + "y2": 123, + "y5": 124, + "yu": 125, + "yæ": 126, + "yə": 127, + "yɛ": 128, + "yɜ": 129, + "ŋɜ": 130, + "ŋʲ": 131, + "ɑ1": 132, + "ɑ2": 133, + "ɑ5": 134, + "ɑu": 135, + "ɑɜ": 136, + "ɑʲ": 137, + "ə1": 138, + "ə2": 139, + "ə5": 140, + "ər": 141, + "əɜ": 142, + "əʊ": 143, + "ʊə": 144, + "ai1": 145, + "ai2": 146, + "ai5": 147, + "aiɜ": 148, + "ei1": 149, + "ei2": 150, + "ei5": 151, + "eiɜ": 152, + "i.1": 153, + "i.2": 154, + "i.5": 155, + "i.ɜ": 156, + "io5": 157, + "iou": 158, + "iɑ1": 159, + "iɑ2": 160, + "iɑ5": 161, + "iɑɜ": 162, + "iɛ1": 163, + "iɛ2": 164, + "iɛ5": 165, + "iɛɜ": 166, + "i̪1": 167, + "i̪2": 168, + "i̪5": 169, + "i̪ɜ": 170, + "onɡ": 171, + "ou1": 172, + "ou2": 173, + "ou5": 174, + "ouɜ": 175, + "ts.": 176, + "tsh": 177, + "tɕh": 178, + "u5ʲ": 179, + "ua1": 180, + "ua2": 181, + "ua5": 182, + "uai": 183, + "uaɜ": 184, + "uei": 185, + "uo1": 186, + "uo2": 187, + "uo5": 188, + "uoɜ": 189, + "uə1": 190, + "uə2": 191, + "uə5": 192, + "uəɜ": 193, + "yiɜ": 194, + "yu2": 195, + "yu5": 196, + "yæ2": 197, + "yæ5": 198, + "yæɜ": 199, + "yə2": 200, + "yə5": 201, + "yəɜ": 202, + "yɛ1": 203, + "yɛ2": 204, + "yɛ5": 205, + "yɛɜ": 206, + "ɑu1": 207, + "ɑu2": 208, + "ɑu5": 209, + "ɑuɜ": 210, + "ər1": 211, + "ər2": 212, + "ər5": 213, + "ərɜ": 214, + "əː1": 215, + "iou1": 216, + "iou2": 217, + "iou5": 218, + "iouɜ": 219, + "onɡ1": 220, + "onɡ2": 221, + "onɡ5": 222, + "onɡɜ": 223, + "ts.h": 224, + "uai2": 225, + "uai5": 226, + "uaiɜ": 227, + "uei1": 228, + "uei2": 229, + "uei5": 230, + "ueiɜ": 231, + "uoɜʲ": 232, + "yɛ5ʲ": 233, + "ɑu2ʲ": 234, + + "2": 235, + "5": 236, + "ɜ": 237, + "ʂ": 238, + "dʑ": 239, + "iɪ": 240, + "uɪ": 241, + "xʲ": 242, + "ɑt": 243, + "ɛɜ": 244, + "ɛː": 245, + "ɪː": 246, + "phʲ": 247, + "ɑ5ʲ": 248, + "ɑuʲ": 249, + "ərə": 250, + "uozʰ": 251, + "ər1ʲ": 252, + "tɕhtɕh": 253, + + "c": 254, + "ʋ": 255, + "ʍ": 256, + "ʑ": 257, + "ː": 258, + "aə": 259, + "eː": 260, + "hʲ": 261, + "iʊ": 262, + "kʲ": 263, + "lʲ": 264, + "oə": 265, + "oɪ": 266, + "oʲ": 267, + "pʲ": 268, + "sʲ": 269, + "u4": 270, + "uʲ": 271, + "yi": 272, + "yʲ": 273, + "ŋ2": 274, + "ŋ5": 275, + "ŋ̩": 276, + "ɑɪ": 277, + "ɑʊ": 278, + "ɕʲ": 279, + "ət": 280, + "əə": 281, + "əɪ": 282, + "əʲ": 283, + "ɛ1": 284, + "ɛ5": 285, + "aiə": 286, + "aiɪ": 287, + "azʰ": 288, + "eiə": 289, + "eiɪ": 290, + "eiʊ": 291, + "i.ə": 292, + "i.ɪ": 293, + "i.ʊ": 294, + "ioɜ": 295, + "izʰ": 296, + "iɑə": 297, + "iɑʊ": 298, + "iɑʲ": 299, + "iɛə": 300, + "iɛɪ": 301, + "iɛʊ": 302, + "i̪ə": 303, + "i̪ʊ": 304, + "khʲ": 305, + "ouʲ": 306, + "tsʲ": 307, + "u2ʲ": 308, + "uoɪ": 309, + "uzʰ": 310, + "uɜʲ": 311, + "yæɪ": 312, + "yəʊ": 313, + "ərt": 314, + "ərɪ": 315, + "ərʲ": 316, + "əːt": 317, + "iouə": 318, + "iouʊ": 319, + "iouʲ": 320, + "iɛzʰ": 321, + "onɡə": 322, + "onɡɪ": 323, + "onɡʊ": 324, + "ouzʰ": 325, + "uai1": 326, + "ueiɪ": 327, + "ɑuzʰ": 328, + "iouzʰ": 329 +} \ No newline at end of file diff --git a/diffrhythm/infer/__pycache__/infer.cpython-310.pyc b/diffrhythm/infer/__pycache__/infer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82ed018e6424401469f03702c77fbcb28789f526 Binary files /dev/null and b/diffrhythm/infer/__pycache__/infer.cpython-310.pyc differ diff --git a/diffrhythm/infer/__pycache__/infer.cpython-311.pyc b/diffrhythm/infer/__pycache__/infer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9701993d954e8397fe3c3ca3ff73f3572e1c9ad6 Binary files /dev/null and b/diffrhythm/infer/__pycache__/infer.cpython-311.pyc differ diff --git a/diffrhythm/infer/__pycache__/infer_utils.cpython-310.pyc b/diffrhythm/infer/__pycache__/infer_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31d791fdd48001cbae9f39e80cd801a5877fd6fd Binary files /dev/null and b/diffrhythm/infer/__pycache__/infer_utils.cpython-310.pyc differ diff --git a/diffrhythm/infer/__pycache__/infer_utils.cpython-311.pyc b/diffrhythm/infer/__pycache__/infer_utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5a04dcb0d6177fbc9c7aa0401d4cc244049f322 Binary files /dev/null and b/diffrhythm/infer/__pycache__/infer_utils.cpython-311.pyc differ diff --git a/diffrhythm/infer/infer.py b/diffrhythm/infer/infer.py new file mode 100644 index 0000000000000000000000000000000000000000..2440c1df1490f20d42f64b49b977f8c5d57f0a15 --- /dev/null +++ b/diffrhythm/infer/infer.py @@ -0,0 +1,162 @@ +import torch +import torchaudio +from einops import rearrange +import argparse +import json +import os +from tqdm import tqdm +import random +import numpy as np +import time +import io +import pydub + +from diffrhythm.infer.infer_utils import ( + get_reference_latent, + get_lrc_token, + get_audio_style_prompt, + prepare_model, + get_negative_style_prompt +) + +def decode_audio(latents, vae_model, chunked=False, overlap=32, chunk_size=128): + downsampling_ratio = 2048 + io_channels = 2 + if not chunked: + # default behavior. Decode the entire latent in parallel + return vae_model.decode_export(latents) + else: + # chunked decoding + hop_size = chunk_size - overlap + total_size = latents.shape[2] + batch_size = latents.shape[0] + chunks = [] + i = 0 + for i in range(0, total_size - chunk_size + 1, hop_size): + chunk = latents[:,:,i:i+chunk_size] + chunks.append(chunk) + if i+chunk_size != total_size: + # Final chunk + chunk = latents[:,:,-chunk_size:] + chunks.append(chunk) + chunks = torch.stack(chunks) + num_chunks = chunks.shape[0] + # samples_per_latent is just the downsampling ratio + samples_per_latent = downsampling_ratio + # Create an empty waveform, we will populate it with chunks as decode them + y_size = total_size * samples_per_latent + y_final = torch.zeros((batch_size,io_channels,y_size)).to(latents.device) + for i in range(num_chunks): + x_chunk = chunks[i,:] + # decode the chunk + y_chunk = vae_model.decode_export(x_chunk) + # figure out where to put the audio along the time domain + if i == num_chunks-1: + # final chunk always goes at the end + t_end = y_size + t_start = t_end - y_chunk.shape[2] + else: + t_start = i * hop_size * samples_per_latent + t_end = t_start + chunk_size * samples_per_latent + # remove the edges of the overlaps + ol = (overlap//2) * samples_per_latent + chunk_start = 0 + chunk_end = y_chunk.shape[2] + if i > 0: + # no overlap for the start of the first chunk + t_start += ol + chunk_start += ol + if i < num_chunks-1: + # no overlap for the end of the last chunk + t_end -= ol + chunk_end -= ol + # paste the chunked audio into our y_final output audio + y_final[:,:,t_start:t_end] = y_chunk[:,:,chunk_start:chunk_end] + return y_final + +def inference(cfm_model, vae_model, cond, text, duration, style_prompt, negative_style_prompt, steps, cfg_strength, sway_sampling_coef, start_time, file_type, vocal_flag, odeint_method): + + with torch.inference_mode(): + generated, _ = cfm_model.sample( + cond=cond, + text=text, + duration=duration, + style_prompt=style_prompt, + negative_style_prompt=negative_style_prompt, + steps=steps, + cfg_strength=cfg_strength, + sway_sampling_coef=sway_sampling_coef, + start_time=start_time, + vocal_flag=vocal_flag, + odeint_method=odeint_method, + ) + + generated = generated.to(torch.float32) + latent = generated.transpose(1, 2) # [b d t] + output = decode_audio(latent, vae_model, chunked=False) + + # Rearrange audio batch to a single sequence + output = rearrange(output, "b d n -> d (b n)") + output_tensor = output.to(torch.float32).div(torch.max(torch.abs(output))).clamp(-1, 1).cpu() + output_np = output_tensor.numpy().T.astype(np.float32) + + if file_type == 'wav': + return (44100, output_np) + else: + buffer = io.BytesIO() + output_np = np.int16(output_np * 2**15) + song = pydub.AudioSegment(output_np.tobytes(), frame_rate=44100, sample_width=2, channels=2) + if file_type == 'mp3': + song.export(buffer, format="mp3", bitrate="320k") + else: + song.export(buffer, format="ogg", bitrate="320k") + return buffer.getvalue() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('--lrc-path', type=str, default="example/eg.lrc") # lyrics of target song + parser.add_argument('--ref-audio-path', type=str, default="example/eg.mp3") # reference audio as style prompt for target song + parser.add_argument('--audio-length', type=int, default=95) # length of target song + parser.add_argument('--output-dir', type=str, default="example/output") + args = parser.parse_args() + + device = 'cuda' + + audio_length = args.audio_length + if audio_length == 95: + max_frames = 2048 + elif audio_length == 285: + max_frames = 6144 + + cfm, tokenizer, muq, vae = prepare_model(device) + + with open(args.lrc_path, 'r') as f: + lrc = f.read() + lrc_prompt, start_time = get_lrc_token(lrc, tokenizer, device) + + style_prompt = get_audio_style_prompt(muq, args.ref_audio_path) + + negative_style_prompt = get_negative_style_prompt(device) + + latent_prompt = get_reference_latent(device, max_frames) + + s_t = time.time() + generated_song = inference(cfm_model=cfm, + vae_model=vae, + cond=latent_prompt, + text=lrc_prompt, + duration=max_frames, + style_prompt=style_prompt, + negative_style_prompt=negative_style_prompt, + start_time=start_time + ) + e_t = time.time() - s_t + print(f"inference cost {e_t} seconds") + + output_dir = args.output_dir + os.makedirs(output_dir, exist_ok=True) + + output_path = os.path.join(output_dir, "output.wav") + torchaudio.save(output_path, generated_song, sample_rate=44100) + \ No newline at end of file diff --git a/diffrhythm/infer/infer_utils.py b/diffrhythm/infer/infer_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..53e85cd192b41c528331501ed8fd013a33cdbe70 --- /dev/null +++ b/diffrhythm/infer/infer_utils.py @@ -0,0 +1,211 @@ +import torch +import librosa +import random +import json +from muq import MuQMuLan +from mutagen.mp3 import MP3 +import os +import numpy as np +from huggingface_hub import hf_hub_download +from diffrhythm.model import DiT, CFM + + +def prepare_model(device): + # prepare cfm model + dit_ckpt_path = hf_hub_download(repo_id="ASLP-lab/DiffRhythm-base", filename="cfm_model.pt") + dit_full_ckpt_path = hf_hub_download(repo_id="ASLP-lab/DiffRhythm-full", filename="cfm_model.pt") + dit_config_path = "./diffrhythm/config/diffrhythm-1b.json" + with open(dit_config_path) as f: + model_config = json.load(f) + dit_model_cls = DiT + cfm = CFM( + transformer=dit_model_cls(**model_config["model"], use_style_prompt=True, max_pos=2048), + num_channels=model_config["model"]['mel_dim'], + use_style_prompt=True + ) + cfm = cfm.to(device) + cfm = load_checkpoint(cfm, dit_ckpt_path, device=device, use_ema=False) + + cfm_full = CFM( + transformer=dit_model_cls(**model_config["model"], use_style_prompt=True, max_pos=6144), + num_channels=model_config["model"]['mel_dim'], + use_style_prompt=True + ) + cfm_full = cfm_full.to(device) + cfm_full = load_checkpoint(cfm_full, dit_full_ckpt_path, device=device, use_ema=False) + + # prepare tokenizer + tokenizer = CNENTokenizer() + + # prepare muq + muq = MuQMuLan.from_pretrained("OpenMuQ/MuQ-MuLan-large") + muq = muq.to(device).eval() + + # prepare vae + vae_ckpt_path = hf_hub_download(repo_id="ASLP-lab/DiffRhythm-vae", filename="vae_model.pt") + vae = torch.jit.load(vae_ckpt_path, map_location='cpu').to(device) + + return cfm, cfm_full, tokenizer, muq, vae + + +# for song edit, will be added in the future +def get_reference_latent(device, max_frames): + return torch.zeros(1, max_frames, 64).to(device) + +def get_negative_style_prompt(device): + file_path = "./src/negative_prompt.npy" + vocal_stlye = np.load(file_path) + + vocal_stlye = torch.from_numpy(vocal_stlye).to(device) # [1, 512] + vocal_stlye = vocal_stlye.half() + + return vocal_stlye + +def get_audio_style_prompt(model, wav_path): + vocal_flag = False + mulan = model + audio, _ = librosa.load(wav_path, sr=24000) + audio_len = librosa.get_duration(y=audio, sr=24000) + + if audio_len <= 1: + vocal_flag = True + + if audio_len > 10: + start_time = int(audio_len // 2 - 5) + wav = audio[start_time*24000:(start_time+10)*24000] + + else: + wav = audio + wav= torch.tensor(wav, dtype=torch.float32).unsqueeze(0).to(model.device) + + + with torch.no_grad(): + audio_emb = mulan(wavs = wav) # [1, 512] + + audio_emb = audio_emb.half() + + return audio_emb, vocal_flag + +def get_text_style_prompt(model, text_prompt): + mulan = model + + with torch.no_grad(): + text_emb = mulan(texts = text_prompt) # [1, 512] + text_emb = text_emb.half() + + return text_emb + + + +def parse_lyrics(lyrics: str): + lyrics_with_time = [] + lyrics = lyrics.strip() + for line in lyrics.split('\n'): + try: + time, lyric = line[1:9], line[10:] + lyric = lyric.strip() + mins, secs = time.split(':') + secs = int(mins) * 60 + float(secs) + lyrics_with_time.append((secs, lyric)) + except: + continue + return lyrics_with_time + +class CNENTokenizer(): + def __init__(self): + with open('./diffrhythm/g2p/g2p/vocab.json', 'r') as file: + self.phone2id:dict = json.load(file)['vocab'] + self.id2phone = {v:k for (k, v) in self.phone2id.items()} + from diffrhythm.g2p.g2p_generation import chn_eng_g2p + self.tokenizer = chn_eng_g2p + def encode(self, text): + phone, token = self.tokenizer(text) + token = [x+1 for x in token] + return token + def decode(self, token): + return "|".join([self.id2phone[x-1] for x in token]) + +def get_lrc_token(max_frames, text, tokenizer, device): + + lyrics_shift = 0 + sampling_rate = 44100 + downsample_rate = 2048 + max_secs = max_frames / (sampling_rate / downsample_rate) + + pad_token_id = 0 + comma_token_id = 1 + period_token_id = 2 + if text == "": + return torch.zeros((max_frames,), dtype=torch.long).unsqueeze(0).to(device), torch.tensor(0.).unsqueeze(0).to(device).half() + + lrc_with_time = parse_lyrics(text) + + modified_lrc_with_time = [] + for i in range(len(lrc_with_time)): + time, line = lrc_with_time[i] + line_token = tokenizer.encode(line) + modified_lrc_with_time.append((time, line_token)) + lrc_with_time = modified_lrc_with_time + + lrc_with_time = [(time_start, line) for (time_start, line) in lrc_with_time if time_start < max_secs] + # lrc_with_time = lrc_with_time[:-1] if len(lrc_with_time) >= 1 else lrc_with_time + + normalized_start_time = 0. + + lrc = torch.zeros((max_frames,), dtype=torch.long) + + tokens_count = 0 + last_end_pos = 0 + for time_start, line in lrc_with_time: + tokens = [token if token != period_token_id else comma_token_id for token in line] + [period_token_id] + tokens = torch.tensor(tokens, dtype=torch.long) + num_tokens = tokens.shape[0] + + gt_frame_start = int(time_start * sampling_rate / downsample_rate) + + frame_shift = random.randint(int(lyrics_shift), int(lyrics_shift)) + + frame_start = max(gt_frame_start - frame_shift, last_end_pos) + frame_len = min(num_tokens, max_frames - frame_start) + + + + lrc[frame_start:frame_start + frame_len] = tokens[:frame_len] + + tokens_count += num_tokens + last_end_pos = frame_start + frame_len + + lrc_emb = lrc.unsqueeze(0).to(device) + + normalized_start_time = torch.tensor(normalized_start_time).unsqueeze(0).to(device) + normalized_start_time = normalized_start_time.half() + + return lrc_emb, normalized_start_time + +def load_checkpoint(model, ckpt_path, device, use_ema=True): + if device == "cuda": + model = model.half() + + ckpt_type = ckpt_path.split(".")[-1] + if ckpt_type == "safetensors": + from safetensors.torch import load_file + + checkpoint = load_file(ckpt_path) + else: + checkpoint = torch.load(ckpt_path, weights_only=True) + + if use_ema: + if ckpt_type == "safetensors": + checkpoint = {"ema_model_state_dict": checkpoint} + checkpoint["model_state_dict"] = { + k.replace("ema_model.", ""): v + for k, v in checkpoint["ema_model_state_dict"].items() + if k not in ["initted", "step"] + } + model.load_state_dict(checkpoint["model_state_dict"], strict=False) + else: + if ckpt_type == "safetensors": + checkpoint = {"model_state_dict": checkpoint} + model.load_state_dict(checkpoint["model_state_dict"], strict=False) + + return model.to(device) \ No newline at end of file diff --git a/diffrhythm/model/__init__.py b/diffrhythm/model/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..645131cd34aeb6c64c92d6b5125bdd073b235a28 --- /dev/null +++ b/diffrhythm/model/__init__.py @@ -0,0 +1,6 @@ +from diffrhythm.model.cfm import CFM + +from diffrhythm.model.dit import DiT + + +__all__ = ["CFM"] diff --git a/diffrhythm/model/__pycache__/__init__.cpython-310.pyc b/diffrhythm/model/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48feebd0569f7a2efee244ec45aea497cc816f1e Binary files /dev/null and b/diffrhythm/model/__pycache__/__init__.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/__init__.cpython-311.pyc b/diffrhythm/model/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd0197c5f9a6cfcb0e6ffcff596c944f03000408 Binary files /dev/null and b/diffrhythm/model/__pycache__/__init__.cpython-311.pyc differ diff --git a/diffrhythm/model/__pycache__/__init__.cpython-312.pyc b/diffrhythm/model/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c050bc941601bddae2642f552063c354c895684e Binary files /dev/null and b/diffrhythm/model/__pycache__/__init__.cpython-312.pyc differ diff --git a/diffrhythm/model/__pycache__/cfm.cpython-310.pyc b/diffrhythm/model/__pycache__/cfm.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6e3e4ff45d2d73513e28e52c786a7e00190f171 Binary files /dev/null and b/diffrhythm/model/__pycache__/cfm.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/cfm.cpython-311.pyc b/diffrhythm/model/__pycache__/cfm.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..578a5edbb8852e1a0b1e65ba92a04b56f6691713 Binary files /dev/null and b/diffrhythm/model/__pycache__/cfm.cpython-311.pyc differ diff --git a/diffrhythm/model/__pycache__/cfm.cpython-312.pyc b/diffrhythm/model/__pycache__/cfm.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b180f0ab626cbffc4557cc66dfffecebdaf14186 Binary files /dev/null and b/diffrhythm/model/__pycache__/cfm.cpython-312.pyc differ diff --git a/diffrhythm/model/__pycache__/custom_dataset.cpython-310.pyc b/diffrhythm/model/__pycache__/custom_dataset.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..055f599a512620335fbc1e576d30261a6b3dea39 Binary files /dev/null and b/diffrhythm/model/__pycache__/custom_dataset.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/custom_dataset_lrc_emb.cpython-310.pyc b/diffrhythm/model/__pycache__/custom_dataset_lrc_emb.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..466181288a3b91c2c9c8574a32fc341dbf024728 Binary files /dev/null and b/diffrhythm/model/__pycache__/custom_dataset_lrc_emb.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/dataset.cpython-310.pyc b/diffrhythm/model/__pycache__/dataset.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67f5221ddd7c5dbf9d72d32acf8714459ce4cdb9 Binary files /dev/null and b/diffrhythm/model/__pycache__/dataset.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/dit.cpython-310.pyc b/diffrhythm/model/__pycache__/dit.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..670ca2f905aaf72ed4789e01eb858c80b44d391c Binary files /dev/null and b/diffrhythm/model/__pycache__/dit.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/dit.cpython-311.pyc b/diffrhythm/model/__pycache__/dit.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d119f4e9138ada1ab7c325bf72152b36e615278 Binary files /dev/null and b/diffrhythm/model/__pycache__/dit.cpython-311.pyc differ diff --git a/diffrhythm/model/__pycache__/modules.cpython-310.pyc b/diffrhythm/model/__pycache__/modules.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f0a72279f888754647fe95fb21ffd0a10fe8163 Binary files /dev/null and b/diffrhythm/model/__pycache__/modules.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/modules.cpython-311.pyc b/diffrhythm/model/__pycache__/modules.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54686fe963a568f6883e8d2de05c19a9f33c6d84 Binary files /dev/null and b/diffrhythm/model/__pycache__/modules.cpython-311.pyc differ diff --git a/diffrhythm/model/__pycache__/trainer.cpython-310.pyc b/diffrhythm/model/__pycache__/trainer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52c61e853f7618412fcae17ed54da2e48a7bc134 Binary files /dev/null and b/diffrhythm/model/__pycache__/trainer.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/utils.cpython-310.pyc b/diffrhythm/model/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f8891652038a2d1ecd36178eba1e5edeb954408 Binary files /dev/null and b/diffrhythm/model/__pycache__/utils.cpython-310.pyc differ diff --git a/diffrhythm/model/__pycache__/utils.cpython-311.pyc b/diffrhythm/model/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd4b78851c279e95eb4b65499138c22aea776fce Binary files /dev/null and b/diffrhythm/model/__pycache__/utils.cpython-311.pyc differ diff --git a/diffrhythm/model/cfm.py b/diffrhythm/model/cfm.py new file mode 100644 index 0000000000000000000000000000000000000000..28019d5a9b2d704fe505e6fbe79ea70ac2e18ac5 --- /dev/null +++ b/diffrhythm/model/cfm.py @@ -0,0 +1,312 @@ +""" +ein notation: +b - batch +n - sequence +nt - text sequence +nw - raw wave length +d - dimension +""" + +from __future__ import annotations +from typing import Callable +from random import random + +import torch +from torch import nn +import torch +import torch.nn.functional as F +from torch.nn.utils.rnn import pad_sequence + +from torchdiffeq import odeint + +from diffrhythm.model.modules import MelSpec +from diffrhythm.model.utils import ( + default, + exists, + list_str_to_idx, + list_str_to_tensor, + lens_to_mask, + mask_from_frac_lengths, +) + +def custom_mask_from_start_end_indices(seq_len: int["b"], start: int["b"], end: int["b"], device, max_seq_len): # noqa: F722 F821 + max_seq_len = max_seq_len + seq = torch.arange(max_seq_len, device=device).long() + start_mask = seq[None, :] >= start[:, None] + end_mask = seq[None, :] < end[:, None] + return start_mask & end_mask + +class CFM(nn.Module): + def __init__( + self, + transformer: nn.Module, + sigma=0.0, + odeint_kwargs: dict = dict( + method="euler" # 'midpoint' + ), + odeint_options: dict = dict( + min_step=0.05 + ), + audio_drop_prob=0.3, + cond_drop_prob=0.2, + style_drop_prob=0.1, + lrc_drop_prob=0.1, + num_channels=None, + frac_lengths_mask: tuple[float, float] = (0.7, 1.0), + vocab_char_map: dict[str:int] | None = None, + use_style_prompt: bool = False + ): + super().__init__() + + self.frac_lengths_mask = frac_lengths_mask + + self.num_channels = num_channels + + # classifier-free guidance + self.audio_drop_prob = audio_drop_prob + self.cond_drop_prob = cond_drop_prob + self.style_drop_prob = style_drop_prob + self.lrc_drop_prob = lrc_drop_prob + + # transformer + self.transformer = transformer + dim = transformer.dim + self.dim = dim + + # conditional flow related + self.sigma = sigma + + # sampling related + self.odeint_kwargs = odeint_kwargs + + self.odeint_options = odeint_options + + # vocab map for tokenization + self.vocab_char_map = vocab_char_map + + self.use_style_prompt = use_style_prompt + + @property + def device(self): + return next(self.parameters()).device + + @torch.no_grad() + def sample( + self, + cond: float["b n d"] | float["b nw"], # noqa: F722 + text: int["b nt"] | list[str], # noqa: F722 + duration: int | int["b"], # noqa: F821 + *, + style_prompt = None, + style_prompt_lens = None, + negative_style_prompt = None, + lens: int["b"] | None = None, # noqa: F821 + steps=32, + cfg_strength=4.0, + sway_sampling_coef=None, + seed: int | None = None, + max_duration=6144, + vocoder: Callable[[float["b d n"]], float["b nw"]] | None = None, # noqa: F722 + no_ref_audio=False, + duplicate_test=False, + t_inter=0.1, + edit_mask=None, + start_time=None, + latent_pred_start_frame=0, + latent_pred_end_frame=2048, + vocal_flag=False, + odeint_method="euler" + ): + self.eval() + + self.odeint_kwargs = dict(method=odeint_method) + + if next(self.parameters()).dtype == torch.float16: + cond = cond.to(torch.float32) + else: + cond = cond.to(torch.float32) + # raw wave + + if cond.shape[1] > duration: + cond = cond[:, :duration, :] + + if cond.ndim == 2: + cond = self.mel_spec(cond) + cond = cond.permute(0, 2, 1) + assert cond.shape[-1] == self.num_channels + + batch, cond_seq_len, device = *cond.shape[:2], cond.device + if not exists(lens): + lens = torch.full((batch,), cond_seq_len, device=device, dtype=torch.long) + + # text + + if isinstance(text, list): + if exists(self.vocab_char_map): + text = list_str_to_idx(text, self.vocab_char_map).to(device) + else: + text = list_str_to_tensor(text).to(device) + assert text.shape[0] == batch + + if exists(text): + text_lens = (text != -1).sum(dim=-1) + + + # duration + cond_mask = lens_to_mask(lens) + if edit_mask is not None: + cond_mask = cond_mask & edit_mask + + latent_pred_start_frame = torch.tensor([latent_pred_start_frame]).to(cond.device) + latent_pred_end_frame = duration + latent_pred_end_frame = torch.tensor([latent_pred_end_frame]).to(cond.device) + fixed_span_mask = custom_mask_from_start_end_indices(cond_seq_len, latent_pred_start_frame, latent_pred_end_frame, device=cond.device, max_seq_len=duration) + + fixed_span_mask = fixed_span_mask.unsqueeze(-1) + step_cond = torch.where(fixed_span_mask, torch.zeros_like(cond), cond) + + if isinstance(duration, int): + duration = torch.full((batch,), duration, device=device, dtype=torch.long) + + + duration = duration.clamp(max=max_duration) + max_duration = duration.amax() + + # duplicate test corner for inner time step oberservation + if duplicate_test: + test_cond = F.pad(cond, (0, 0, cond_seq_len, max_duration - 2 * cond_seq_len), value=0.0) + + + if batch > 1: + mask = lens_to_mask(duration) + else: # save memory and speed up, as single inference need no mask currently + mask = None + + # test for no ref audio + if no_ref_audio: + cond = torch.zeros_like(cond) + + start_time_embed, positive_text_embed, positive_text_residuals = self.transformer.forward_timestep_invariant(text, step_cond.shape[1], drop_text=False, start_time=start_time) + _, negative_text_embed, negative_text_residuals = self.transformer.forward_timestep_invariant(text, step_cond.shape[1], drop_text=True, start_time=start_time) + + if vocal_flag: + style_prompt = negative_style_prompt + negative_style_prompt = torch.zeros_like(style_prompt) + + text_embed = torch.cat([positive_text_embed, negative_text_embed], 0) + text_residuals = [torch.cat([a, b], 0) for a, b in zip(positive_text_residuals, negative_text_residuals)] + step_cond = torch.cat([step_cond, step_cond], 0) + style_prompt = torch.cat([style_prompt, negative_style_prompt], 0) + start_time_embed = torch.cat([start_time_embed, start_time_embed], 0) + + + def fn(t, x): + x = torch.cat([x, x], 0) + pred = self.transformer( + x=x, text_embed=text_embed, text_residuals=text_residuals, cond=step_cond, time=t, + drop_audio_cond=True, drop_prompt=False, style_prompt=style_prompt, start_time=start_time_embed + ) + + positive_pred, negative_pred = pred.chunk(2, 0) + cfg_pred = positive_pred + (positive_pred - negative_pred) * cfg_strength + + return cfg_pred + + # noise input + # to make sure batch inference result is same with different batch size, and for sure single inference + # still some difference maybe due to convolutional layers + y0 = [] + for dur in duration: + if exists(seed): + torch.manual_seed(seed) + y0.append(torch.randn(dur, self.num_channels, device=self.device, dtype=step_cond.dtype)) + y0 = pad_sequence(y0, padding_value=0, batch_first=True) + + t_start = 0 + + # duplicate test corner for inner time step oberservation + if duplicate_test: + t_start = t_inter + y0 = (1 - t_start) * y0 + t_start * test_cond + steps = int(steps * (1 - t_start)) + + t = torch.linspace(t_start, 1, steps, device=self.device, dtype=step_cond.dtype) + if sway_sampling_coef is not None: + t = t + sway_sampling_coef * (torch.cos(torch.pi / 2 * t) - 1 + t) + + trajectory = odeint(fn, y0, t, **self.odeint_kwargs) + + sampled = trajectory[-1] + out = sampled + out = torch.where(fixed_span_mask, out, cond) + + if exists(vocoder): + out = out.permute(0, 2, 1) + out = vocoder(out) + + return out, trajectory + + def forward( + self, + inp: float["b n d"] | float["b nw"], # mel or raw wave # noqa: F722 + text: int["b nt"] | list[str], # noqa: F722 + style_prompt = None, + style_prompt_lens = None, + lens: int["b"] | None = None, # noqa: F821 + noise_scheduler: str | None = None, + grad_ckpt = False, + start_time = None, + ): + + batch, seq_len, dtype, device, _σ1 = *inp.shape[:2], inp.dtype, self.device, self.sigma + + # lens and mask + if not exists(lens): + lens = torch.full((batch,), seq_len, device=device) + + mask = lens_to_mask(lens, length=seq_len) # useless here, as collate_fn will pad to max length in batch + + # get a random span to mask out for training conditionally + frac_lengths = torch.zeros((batch,), device=self.device).float().uniform_(*self.frac_lengths_mask) + rand_span_mask = mask_from_frac_lengths(lens, frac_lengths) + + if exists(mask): + rand_span_mask = mask + # rand_span_mask &= mask + + # mel is x1 + x1 = inp + + # x0 is gaussian noise + x0 = torch.randn_like(x1) + + # time step + time = torch.normal(mean=0, std=1, size=(batch,), device=self.device) + time = torch.nn.functional.sigmoid(time) + # TODO. noise_scheduler + + # sample xt (φ_t(x) in the paper) + t = time.unsqueeze(-1).unsqueeze(-1) + φ = (1 - t) * x0 + t * x1 + flow = x1 - x0 + + # only predict what is within the random mask span for infilling + cond = torch.where(rand_span_mask[..., None], torch.zeros_like(x1), x1) + + # transformer and cfg training with a drop rate + drop_audio_cond = random() < self.audio_drop_prob # p_drop in voicebox paper + drop_text = random() < self.lrc_drop_prob + drop_prompt = random() < self.style_drop_prob + + # if want rigourously mask out padding, record in collate_fn in dataset.py, and pass in here + # adding mask will use more memory, thus also need to adjust batchsampler with scaled down threshold for long sequences + pred = self.transformer( + x=φ, cond=cond, text=text, time=time, drop_audio_cond=drop_audio_cond, drop_text=drop_text, drop_prompt=drop_prompt, + style_prompt=style_prompt, style_prompt_lens=style_prompt_lens, grad_ckpt=grad_ckpt, start_time=start_time + ) + + # flow matching loss + loss = F.mse_loss(pred, flow, reduction="none") + loss = loss[rand_span_mask] + + return loss.mean(), cond, pred diff --git a/diffrhythm/model/dit.py b/diffrhythm/model/dit.py new file mode 100644 index 0000000000000000000000000000000000000000..c417902f2180826fae0baba47004eed356dcc016 --- /dev/null +++ b/diffrhythm/model/dit.py @@ -0,0 +1,202 @@ +""" +ein notation: +b - batch +n - sequence +nt - text sequence +nw - raw wave length +d - dimension +""" + +from __future__ import annotations + +import torch +from torch import nn +import torch +import torch.nn.functional as F +from transformers.models.llama.modeling_llama import LlamaDecoderLayer, LlamaRotaryEmbedding +from transformers.models.llama import LlamaConfig +from torch.utils.checkpoint import checkpoint + +from diffrhythm.model.modules import ( + TimestepEmbedding, + ConvNeXtV2Block, + ConvPositionEmbedding, + DiTBlock, + AdaLayerNormZero_Final, + precompute_freqs_cis, + get_pos_embed_indices, +) +# from liger_kernel.transformers import apply_liger_kernel_to_llama +# apply_liger_kernel_to_llama() + +# Text embedding +class TextEmbedding(nn.Module): + def __init__(self, text_num_embeds, text_dim, max_pos, conv_layers=0, conv_mult=2): + super().__init__() + self.text_embed = nn.Embedding(text_num_embeds + 1, text_dim) # use 0 as filler token + + if conv_layers > 0: + self.extra_modeling = True + self.precompute_max_pos = max_pos # ~44s of 24khz audio + self.register_buffer("freqs_cis", precompute_freqs_cis(text_dim, self.precompute_max_pos), persistent=False) + self.text_blocks = nn.Sequential( + *[ConvNeXtV2Block(text_dim, text_dim * conv_mult) for _ in range(conv_layers)] + ) + else: + self.extra_modeling = False + + def forward(self, text: int["b nt"], seq_len, drop_text=False): # noqa: F722 + batch, text_len = text.shape[0], text.shape[1] + + if drop_text: # cfg for text + text = torch.zeros_like(text) + + text = self.text_embed(text) # b n -> b n d + + # possible extra modeling + if self.extra_modeling: + # sinus pos emb + batch_start = torch.zeros((batch,), dtype=torch.long) + pos_idx = get_pos_embed_indices(batch_start, seq_len, max_pos=self.precompute_max_pos) + text_pos_embed = self.freqs_cis[pos_idx] + text = text + text_pos_embed + + # convnextv2 blocks + text = self.text_blocks(text) + + return text + + +# noised input audio and context mixing embedding +class InputEmbedding(nn.Module): + def __init__(self, mel_dim, text_dim, out_dim, cond_dim): + super().__init__() + self.proj = nn.Linear(mel_dim * 2 + text_dim + cond_dim * 2, out_dim) + self.conv_pos_embed = ConvPositionEmbedding(dim=out_dim) + + def forward(self, x: float["b n d"], cond: float["b n d"], text_embed: float["b n d"], style_emb, time_emb, drop_audio_cond=False): # noqa: F722 + if drop_audio_cond: # cfg for cond audio + cond = torch.zeros_like(cond) + + style_emb = style_emb.unsqueeze(1).repeat(1, x.shape[1], 1) + time_emb = time_emb.unsqueeze(1).repeat(1, x.shape[1], 1) + x = self.proj(torch.cat((x, cond, text_embed, style_emb, time_emb), dim=-1)) + x = self.conv_pos_embed(x) + x + return x + + +# Transformer backbone using DiT blocks + + +class DiT(nn.Module): + def __init__( + self, + *, + dim, + depth=8, + heads=8, + dim_head=64, + dropout=0.1, + ff_mult=4, + mel_dim=100, + text_num_embeds=256, + text_dim=None, + conv_layers=0, + long_skip_connection=False, + use_style_prompt=False, + max_pos=2048, + ): + super().__init__() + + cond_dim = 512 + self.time_embed = TimestepEmbedding(cond_dim) + self.start_time_embed = TimestepEmbedding(cond_dim) + if text_dim is None: + text_dim = mel_dim + self.text_embed = TextEmbedding(text_num_embeds, text_dim, conv_layers=conv_layers, max_pos=max_pos) + self.input_embed = InputEmbedding(mel_dim, text_dim, dim, cond_dim=cond_dim) + + + self.dim = dim + self.depth = depth + + llama_config = LlamaConfig(hidden_size=dim, intermediate_size=dim * ff_mult, hidden_act='silu', max_position_embeddings=max_pos) + llama_config._attn_implementation = 'sdpa' + + self.transformer_blocks = nn.ModuleList( + [LlamaDecoderLayer(llama_config, layer_idx=i) for i in range(depth)] + ) + self.rotary_emb = LlamaRotaryEmbedding(config=llama_config) + self.long_skip_connection = nn.Linear(dim * 2, dim, bias=False) if long_skip_connection else None + + self.text_fusion_linears = nn.ModuleList( + [ + nn.Sequential( + nn.Linear(cond_dim, dim), + nn.SiLU() + ) for i in range(depth // 2) + ] + ) + for layer in self.text_fusion_linears: + for p in layer.parameters(): + p.detach().zero_() + + self.norm_out = AdaLayerNormZero_Final(dim, cond_dim) # final modulation + self.proj_out = nn.Linear(dim, mel_dim) + + + def forward_timestep_invariant(self, text, seq_len, drop_text, start_time): + s_t = self.start_time_embed(start_time) + text_embed = self.text_embed(text, seq_len, drop_text=drop_text) + text_residuals = [] + for layer in self.text_fusion_linears: + text_residual = layer(text_embed) + text_residuals.append(text_residual) + return s_t, text_embed, text_residuals + + + def forward( + self, + x: float["b n d"], # nosied input audio # noqa: F722 + text_embed: int["b nt"], # text # noqa: F722 + text_residuals, + cond: float["b n d"], # masked cond audio # noqa: F722 + time: float["b"] | float[""], # time step # noqa: F821 F722 + drop_audio_cond, # cfg for cond audio + drop_prompt=False, + style_prompt=None, # [b d t] + start_time=None, + ): + batch, seq_len = x.shape[0], x.shape[1] + if time.ndim == 0: + time = time.repeat(batch) + + t = self.time_embed(time) + c = t + start_time + + if drop_prompt: + style_prompt = torch.zeros_like(style_prompt) + + style_embed = style_prompt # [b, 512] + + x = self.input_embed(x, cond, text_embed, style_embed, c, drop_audio_cond=drop_audio_cond) + + if self.long_skip_connection is not None: + residual = x + + pos_ids = torch.arange(x.shape[1], device=x.device) + pos_ids = pos_ids.unsqueeze(0).repeat(x.shape[0], 1) + rotary_embed = self.rotary_emb(x, pos_ids) + + for i, block in enumerate(self.transformer_blocks): + x, *_ = block(x, position_embeddings=rotary_embed) + if i < self.depth // 2: + x = x + text_residuals[i] + + if self.long_skip_connection is not None: + x = self.long_skip_connection(torch.cat((x, residual), dim=-1)) + + x = self.norm_out(x, c) + output = self.proj_out(x) + + return output diff --git a/diffrhythm/model/modules.py b/diffrhythm/model/modules.py new file mode 100644 index 0000000000000000000000000000000000000000..c217332715bc1b665f9378ec6f88fd619b9329cd --- /dev/null +++ b/diffrhythm/model/modules.py @@ -0,0 +1,612 @@ +""" +ein notation: +b - batch +n - sequence +nt - text sequence +nw - raw wave length +d - dimension +""" + +from __future__ import annotations +from typing import Optional +import math + +import torch +from torch import nn +import torch +import torch.nn.functional as F +import torchaudio + +from x_transformers.x_transformers import apply_rotary_pos_emb + + + +class FiLMLayer(nn.Module): + """ + Feature-wise Linear Modulation (FiLM) layer + Reference: https://arxiv.org/abs/1709.07871 + """ + def __init__(self, in_channels, cond_channels): + + super(FiLMLayer, self).__init__() + self.in_channels = in_channels + self.film = nn.Conv1d(cond_channels, in_channels * 2, 1) + + def forward(self, x, c): + gamma, beta = torch.chunk(self.film(c.unsqueeze(2)), chunks=2, dim=1) + gamma = gamma.transpose(1, 2) + beta = beta.transpose(1, 2) + # print(gamma.shape, beta.shape) + return gamma * x + beta + +# raw wav to mel spec + + +class MelSpec(nn.Module): + def __init__( + self, + filter_length=1024, + hop_length=256, + win_length=1024, + n_mel_channels=100, + target_sample_rate=24_000, + normalize=False, + power=1, + norm=None, + center=True, + ): + super().__init__() + self.n_mel_channels = n_mel_channels + + self.mel_stft = torchaudio.transforms.MelSpectrogram( + sample_rate=target_sample_rate, + n_fft=filter_length, + win_length=win_length, + hop_length=hop_length, + n_mels=n_mel_channels, + power=power, + center=center, + normalized=normalize, + norm=norm, + ) + + self.register_buffer("dummy", torch.tensor(0), persistent=False) + + def forward(self, inp): + if len(inp.shape) == 3: + inp = inp.squeeze(1) # 'b 1 nw -> b nw' + + assert len(inp.shape) == 2 + + if self.dummy.device != inp.device: + self.to(inp.device) + + mel = self.mel_stft(inp) + mel = mel.clamp(min=1e-5).log() + return mel + + +# sinusoidal position embedding + + +class SinusPositionEmbedding(nn.Module): + def __init__(self, dim): + super().__init__() + self.dim = dim + + def forward(self, x, scale=1000): + device = x.device + half_dim = self.dim // 2 + emb = math.log(10000) / (half_dim - 1) + emb = torch.exp(torch.arange(half_dim, device=device).float() * -emb) + emb = scale * x.unsqueeze(1) * emb.unsqueeze(0) + emb = torch.cat((emb.sin(), emb.cos()), dim=-1) + return emb + + +# convolutional position embedding + + +class ConvPositionEmbedding(nn.Module): + def __init__(self, dim, kernel_size=31, groups=16): + super().__init__() + assert kernel_size % 2 != 0 + self.conv1d = nn.Sequential( + nn.Conv1d(dim, dim, kernel_size, groups=groups, padding=kernel_size // 2), + nn.Mish(), + nn.Conv1d(dim, dim, kernel_size, groups=groups, padding=kernel_size // 2), + nn.Mish(), + ) + + def forward(self, x: float["b n d"], mask: bool["b n"] | None = None): # noqa: F722 + if mask is not None: + mask = mask[..., None] + x = x.masked_fill(~mask, 0.0) + + x = x.permute(0, 2, 1) + x = self.conv1d(x) + out = x.permute(0, 2, 1) + + if mask is not None: + out = out.masked_fill(~mask, 0.0) + + return out + + +# rotary positional embedding related + + +def precompute_freqs_cis(dim: int, end: int, theta: float = 10000.0, theta_rescale_factor=1.0): + # proposed by reddit user bloc97, to rescale rotary embeddings to longer sequence length without fine-tuning + # has some connection to NTK literature + # https://www.reddit.com/r/LocalLLaMA/comments/14lz7j5/ntkaware_scaled_rope_allows_llama_models_to_have/ + # https://github.com/lucidrains/rotary-embedding-torch/blob/main/rotary_embedding_torch/rotary_embedding_torch.py + theta *= theta_rescale_factor ** (dim / (dim - 2)) + freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim)) + t = torch.arange(end, device=freqs.device) # type: ignore + freqs = torch.outer(t, freqs).float() # type: ignore + freqs_cos = torch.cos(freqs) # real part + freqs_sin = torch.sin(freqs) # imaginary part + return torch.cat([freqs_cos, freqs_sin], dim=-1) + + +def get_pos_embed_indices(start, length, max_pos, scale=1.0): + # length = length if isinstance(length, int) else length.max() + scale = scale * torch.ones_like(start, dtype=torch.float32) # in case scale is a scalar + pos = ( + start.unsqueeze(1) + + (torch.arange(length, device=start.device, dtype=torch.float32).unsqueeze(0) * scale.unsqueeze(1)).long() + ) + # avoid extra long error. + pos = torch.where(pos < max_pos, pos, max_pos - 1) + return pos + + +# Global Response Normalization layer (Instance Normalization ?) + + +class GRN(nn.Module): + def __init__(self, dim): + super().__init__() + self.gamma = nn.Parameter(torch.zeros(1, 1, dim)) + self.beta = nn.Parameter(torch.zeros(1, 1, dim)) + + def forward(self, x): + Gx = torch.norm(x, p=2, dim=1, keepdim=True) + Nx = Gx / (Gx.mean(dim=-1, keepdim=True) + 1e-6) + return self.gamma * (x * Nx) + self.beta + x + + +# ConvNeXt-V2 Block https://github.com/facebookresearch/ConvNeXt-V2/blob/main/models/convnextv2.py +# ref: https://github.com/bfs18/e2_tts/blob/main/rfwave/modules.py#L108 + + +class ConvNeXtV2Block(nn.Module): + def __init__( + self, + dim: int, + intermediate_dim: int, + dilation: int = 1, + ): + super().__init__() + padding = (dilation * (7 - 1)) // 2 + self.dwconv = nn.Conv1d( + dim, dim, kernel_size=7, padding=padding, groups=dim, dilation=dilation + ) # depthwise conv + self.norm = nn.LayerNorm(dim, eps=1e-6) + self.pwconv1 = nn.Linear(dim, intermediate_dim) # pointwise/1x1 convs, implemented with linear layers + self.act = nn.GELU() + self.grn = GRN(intermediate_dim) + self.pwconv2 = nn.Linear(intermediate_dim, dim) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + residual = x + x = x.transpose(1, 2) # b n d -> b d n + x = self.dwconv(x) + x = x.transpose(1, 2) # b d n -> b n d + x = self.norm(x) + x = self.pwconv1(x) + x = self.act(x) + x = self.grn(x) + x = self.pwconv2(x) + return residual + x + + +# AdaLayerNormZero +# return with modulated x for attn input, and params for later mlp modulation + + +class AdaLayerNormZero(nn.Module): + def __init__(self, dim): + super().__init__() + + self.silu = nn.SiLU() + self.linear = nn.Linear(dim, dim * 6) + + self.norm = nn.LayerNorm(dim, elementwise_affine=False, eps=1e-6) + + def forward(self, x, emb=None): + emb = self.linear(self.silu(emb)) + shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = torch.chunk(emb, 6, dim=1) + + x = self.norm(x) * (1 + scale_msa[:, None]) + shift_msa[:, None] + return x, gate_msa, shift_mlp, scale_mlp, gate_mlp + + +# AdaLayerNormZero for final layer +# return only with modulated x for attn input, cuz no more mlp modulation + + +class AdaLayerNormZero_Final(nn.Module): + def __init__(self, dim, cond_dim): + super().__init__() + + self.silu = nn.SiLU() + self.linear = nn.Linear(cond_dim, dim * 2) + + self.norm = nn.LayerNorm(dim, elementwise_affine=False, eps=1e-6) + + def forward(self, x, emb): + emb = self.linear(self.silu(emb)) + scale, shift = torch.chunk(emb, 2, dim=1) + + x = self.norm(x) * (1 + scale)[:, None, :] + shift[:, None, :] + return x + + +# FeedForward + + +class FeedForward(nn.Module): + def __init__(self, dim, dim_out=None, mult=4, dropout=0.0, approximate: str = "none"): + super().__init__() + inner_dim = int(dim * mult) + dim_out = dim_out if dim_out is not None else dim + + activation = nn.GELU(approximate=approximate) + #activation = nn.SiLU() + project_in = nn.Sequential(nn.Linear(dim, inner_dim), activation) + self.ff = nn.Sequential(project_in, nn.Dropout(dropout), nn.Linear(inner_dim, dim_out)) + + def forward(self, x): + return self.ff(x) + + +# Attention with possible joint part +# modified from diffusers/src/diffusers/models/attention_processor.py + + +class Attention(nn.Module): + def __init__( + self, + processor: JointAttnProcessor | AttnProcessor, + dim: int, + heads: int = 8, + dim_head: int = 64, + dropout: float = 0.0, + context_dim: Optional[int] = None, # if not None -> joint attention + context_pre_only=None, + ): + super().__init__() + + if not hasattr(F, "scaled_dot_product_attention"): + raise ImportError("Attention equires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.") + + self.processor = processor + + self.dim = dim + self.heads = heads + self.inner_dim = dim_head * heads + self.dropout = dropout + + self.context_dim = context_dim + self.context_pre_only = context_pre_only + + self.to_q = nn.Linear(dim, self.inner_dim) + self.to_k = nn.Linear(dim, self.inner_dim) + self.to_v = nn.Linear(dim, self.inner_dim) + + if self.context_dim is not None: + self.to_k_c = nn.Linear(context_dim, self.inner_dim) + self.to_v_c = nn.Linear(context_dim, self.inner_dim) + if self.context_pre_only is not None: + self.to_q_c = nn.Linear(context_dim, self.inner_dim) + + self.to_out = nn.ModuleList([]) + self.to_out.append(nn.Linear(self.inner_dim, dim)) + self.to_out.append(nn.Dropout(dropout)) + + if self.context_pre_only is not None and not self.context_pre_only: + self.to_out_c = nn.Linear(self.inner_dim, dim) + + def forward( + self, + x: float["b n d"], # noised input x # noqa: F722 + c: float["b n d"] = None, # context c # noqa: F722 + mask: bool["b n"] | None = None, # noqa: F722 + rope=None, # rotary position embedding for x + c_rope=None, # rotary position embedding for c + ) -> torch.Tensor: + if c is not None: + return self.processor(self, x, c=c, mask=mask, rope=rope, c_rope=c_rope) + else: + return self.processor(self, x, mask=mask, rope=rope) + + +# Attention processor + + +class AttnProcessor: + def __init__(self): + pass + + def __call__( + self, + attn: Attention, + x: float["b n d"], # noised input x # noqa: F722 + mask: bool["b n"] | None = None, # noqa: F722 + rope=None, # rotary position embedding + ) -> torch.FloatTensor: + batch_size = x.shape[0] + + # `sample` projections. + query = attn.to_q(x) + key = attn.to_k(x) + value = attn.to_v(x) + + # apply rotary position embedding + if rope is not None: + freqs, xpos_scale = rope + q_xpos_scale, k_xpos_scale = (xpos_scale, xpos_scale**-1.0) if xpos_scale is not None else (1.0, 1.0) + + query = apply_rotary_pos_emb(query, freqs, q_xpos_scale) + key = apply_rotary_pos_emb(key, freqs, k_xpos_scale) + + # attention + inner_dim = key.shape[-1] + head_dim = inner_dim // attn.heads + query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + + # mask. e.g. inference got a batch with different target durations, mask out the padding + if mask is not None: + attn_mask = mask + attn_mask = attn_mask.unsqueeze(1).unsqueeze(1) # 'b n -> b 1 1 n' + attn_mask = attn_mask.expand(batch_size, attn.heads, query.shape[-2], key.shape[-2]) + else: + attn_mask = None + + x = F.scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=0.0, is_causal=False) + x = x.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim) + x = x.to(query.dtype) + + # linear proj + x = attn.to_out[0](x) + # dropout + x = attn.to_out[1](x) + + if mask is not None: + mask = mask.unsqueeze(-1) + x = x.masked_fill(~mask, 0.0) + + return x + + +# Joint Attention processor for MM-DiT +# modified from diffusers/src/diffusers/models/attention_processor.py + + +class JointAttnProcessor: + def __init__(self): + pass + + def __call__( + self, + attn: Attention, + x: float["b n d"], # noised input x # noqa: F722 + c: float["b nt d"] = None, # context c, here text # noqa: F722 + mask: bool["b n"] | None = None, # noqa: F722 + rope=None, # rotary position embedding for x + c_rope=None, # rotary position embedding for c + ) -> torch.FloatTensor: + residual = x + + batch_size = c.shape[0] + + # `sample` projections. + query = attn.to_q(x) + key = attn.to_k(x) + value = attn.to_v(x) + + # `context` projections. + c_query = attn.to_q_c(c) + c_key = attn.to_k_c(c) + c_value = attn.to_v_c(c) + + # apply rope for context and noised input independently + if rope is not None: + freqs, xpos_scale = rope + q_xpos_scale, k_xpos_scale = (xpos_scale, xpos_scale**-1.0) if xpos_scale is not None else (1.0, 1.0) + query = apply_rotary_pos_emb(query, freqs, q_xpos_scale) + key = apply_rotary_pos_emb(key, freqs, k_xpos_scale) + if c_rope is not None: + freqs, xpos_scale = c_rope + q_xpos_scale, k_xpos_scale = (xpos_scale, xpos_scale**-1.0) if xpos_scale is not None else (1.0, 1.0) + c_query = apply_rotary_pos_emb(c_query, freqs, q_xpos_scale) + c_key = apply_rotary_pos_emb(c_key, freqs, k_xpos_scale) + + # attention + query = torch.cat([query, c_query], dim=1) + key = torch.cat([key, c_key], dim=1) + value = torch.cat([value, c_value], dim=1) + + inner_dim = key.shape[-1] + head_dim = inner_dim // attn.heads + query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + + # mask. e.g. inference got a batch with different target durations, mask out the padding + if mask is not None: + attn_mask = F.pad(mask, (0, c.shape[1]), value=True) # no mask for c (text) + attn_mask = attn_mask.unsqueeze(1).unsqueeze(1) # 'b n -> b 1 1 n' + attn_mask = attn_mask.expand(batch_size, attn.heads, query.shape[-2], key.shape[-2]) + else: + attn_mask = None + + x = F.scaled_dot_product_attention(query, key, value, attn_mask=attn_mask, dropout_p=0.0, is_causal=False) + x = x.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim) + x = x.to(query.dtype) + + # Split the attention outputs. + x, c = ( + x[:, : residual.shape[1]], + x[:, residual.shape[1] :], + ) + + # linear proj + x = attn.to_out[0](x) + # dropout + x = attn.to_out[1](x) + if not attn.context_pre_only: + c = attn.to_out_c(c) + + if mask is not None: + mask = mask.unsqueeze(-1) + x = x.masked_fill(~mask, 0.0) + # c = c.masked_fill(~mask, 0.) # no mask for c (text) + + return x, c + + +# DiT Block + + +class DiTBlock(nn.Module): + def __init__(self, dim, heads, dim_head, ff_mult=4, dropout=0.1, use_style_prompt=False): + super().__init__() + + self.attn_norm = AdaLayerNormZero(dim) + self.attn = Attention( + processor=AttnProcessor(), + dim=dim, + heads=heads, + dim_head=dim_head, + dropout=dropout, + ) + + self.ff_norm = nn.LayerNorm(dim, elementwise_affine=False, eps=1e-6) + self.ff = FeedForward(dim=dim, mult=ff_mult, dropout=dropout, approximate="tanh") + + self.use_style_prompt = use_style_prompt + if use_style_prompt: + #self.film = FiLMLayer(dim, dim) + self.prompt_norm = AdaLayerNormZero_Final(dim) + + def forward(self, x, t, c=None, mask=None, rope=None): # x: noised input, t: time embedding + if c is not None and self.use_style_prompt: + #x = self.film(x, c) + x = self.prompt_norm(x, c) + + # pre-norm & modulation for attention input + norm, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.attn_norm(x, emb=t) + + # attention + attn_output = self.attn(x=norm, mask=mask, rope=rope) + + # process attention output for input x + x = x + gate_msa.unsqueeze(1) * attn_output + + norm = self.ff_norm(x) * (1 + scale_mlp[:, None]) + shift_mlp[:, None] + ff_output = self.ff(norm) + x = x + gate_mlp.unsqueeze(1) * ff_output + + return x + + +# MMDiT Block https://arxiv.org/abs/2403.03206 + + +class MMDiTBlock(nn.Module): + r""" + modified from diffusers/src/diffusers/models/attention.py + + notes. + _c: context related. text, cond, etc. (left part in sd3 fig2.b) + _x: noised input related. (right part) + context_pre_only: last layer only do prenorm + modulation cuz no more ffn + """ + + def __init__(self, dim, heads, dim_head, ff_mult=4, dropout=0.1, context_pre_only=False): + super().__init__() + + self.context_pre_only = context_pre_only + + self.attn_norm_c = AdaLayerNormZero_Final(dim) if context_pre_only else AdaLayerNormZero(dim) + self.attn_norm_x = AdaLayerNormZero(dim) + self.attn = Attention( + processor=JointAttnProcessor(), + dim=dim, + heads=heads, + dim_head=dim_head, + dropout=dropout, + context_dim=dim, + context_pre_only=context_pre_only, + ) + + if not context_pre_only: + self.ff_norm_c = nn.LayerNorm(dim, elementwise_affine=False, eps=1e-6) + self.ff_c = FeedForward(dim=dim, mult=ff_mult, dropout=dropout, approximate="tanh") + else: + self.ff_norm_c = None + self.ff_c = None + self.ff_norm_x = nn.LayerNorm(dim, elementwise_affine=False, eps=1e-6) + self.ff_x = FeedForward(dim=dim, mult=ff_mult, dropout=dropout, approximate="tanh") + + def forward(self, x, c, t, mask=None, rope=None, c_rope=None): # x: noised input, c: context, t: time embedding + # pre-norm & modulation for attention input + if self.context_pre_only: + norm_c = self.attn_norm_c(c, t) + else: + norm_c, c_gate_msa, c_shift_mlp, c_scale_mlp, c_gate_mlp = self.attn_norm_c(c, emb=t) + norm_x, x_gate_msa, x_shift_mlp, x_scale_mlp, x_gate_mlp = self.attn_norm_x(x, emb=t) + + # attention + x_attn_output, c_attn_output = self.attn(x=norm_x, c=norm_c, mask=mask, rope=rope, c_rope=c_rope) + + # process attention output for context c + if self.context_pre_only: + c = None + else: # if not last layer + c = c + c_gate_msa.unsqueeze(1) * c_attn_output + + norm_c = self.ff_norm_c(c) * (1 + c_scale_mlp[:, None]) + c_shift_mlp[:, None] + c_ff_output = self.ff_c(norm_c) + c = c + c_gate_mlp.unsqueeze(1) * c_ff_output + + # process attention output for input x + x = x + x_gate_msa.unsqueeze(1) * x_attn_output + + norm_x = self.ff_norm_x(x) * (1 + x_scale_mlp[:, None]) + x_shift_mlp[:, None] + x_ff_output = self.ff_x(norm_x) + x = x + x_gate_mlp.unsqueeze(1) * x_ff_output + + return c, x + + +# time step conditioning embedding + + +class TimestepEmbedding(nn.Module): + def __init__(self, dim, freq_embed_dim=256): + super().__init__() + self.time_embed = SinusPositionEmbedding(freq_embed_dim) + self.time_mlp = nn.Sequential(nn.Linear(freq_embed_dim, dim), nn.SiLU(), nn.Linear(dim, dim)) + + def forward(self, timestep: float["b"]): # noqa: F821 + time_hidden = self.time_embed(timestep) + time_hidden = time_hidden.to(timestep.dtype) + time = self.time_mlp(time_hidden.to(torch.float32)) # Ensures dtype match + # b d + return time diff --git a/diffrhythm/model/trainer.py b/diffrhythm/model/trainer.py new file mode 100644 index 0000000000000000000000000000000000000000..a1777475b579097fec75b8e24590f58a9c7af8f8 --- /dev/null +++ b/diffrhythm/model/trainer.py @@ -0,0 +1,350 @@ +from __future__ import annotations + +import os +import gc +from tqdm import tqdm +import wandb + +import torch +from torch.optim import AdamW +from torch.optim.lr_scheduler import LinearLR, SequentialLR, ConstantLR + +from accelerate import Accelerator +from accelerate.utils import DistributedDataParallelKwargs +from diffrhythm.dataset.custom_dataset_align2f5 import LanceDiffusionDataset + +from torch.utils.data import DataLoader, DistributedSampler + +from ema_pytorch import EMA + +from diffrhythm.model import CFM +from diffrhythm.model.utils import exists, default + +import time + +# from apex.optimizers.fused_adam import FusedAdam + +# trainer + + +class Trainer: + def __init__( + self, + model: CFM, + args, + epochs, + learning_rate, + #dataloader, + num_warmup_updates=20000, + save_per_updates=1000, + checkpoint_path=None, + batch_size=32, + batch_size_type: str = "sample", + max_samples=32, + grad_accumulation_steps=1, + max_grad_norm=1.0, + noise_scheduler: str | None = None, + duration_predictor: torch.nn.Module | None = None, + wandb_project="test_e2-tts", + wandb_run_name="test_run", + wandb_resume_id: str = None, + last_per_steps=None, + accelerate_kwargs: dict = dict(), + ema_kwargs: dict = dict(), + bnb_optimizer: bool = False, + reset_lr: bool = False, + use_style_prompt: bool = False, + grad_ckpt: bool = False + ): + self.args = args + + ddp_kwargs = DistributedDataParallelKwargs(find_unused_parameters=False, ) + + logger = "wandb" if wandb.api.api_key else None + #logger = None + print(f"Using logger: {logger}") + # print("-----------1-------------") + import tbe.common + # print("-----------2-------------") + self.accelerator = Accelerator( + log_with=logger, + kwargs_handlers=[ddp_kwargs], + gradient_accumulation_steps=grad_accumulation_steps, + **accelerate_kwargs, + ) + # print("-----------3-------------") + + if logger == "wandb": + if exists(wandb_resume_id): + init_kwargs = {"wandb": {"resume": "allow", "name": wandb_run_name, "id": wandb_resume_id}} + else: + init_kwargs = {"wandb": {"resume": "allow", "name": wandb_run_name}} + self.accelerator.init_trackers( + project_name=wandb_project, + init_kwargs=init_kwargs, + config={ + "epochs": epochs, + "learning_rate": learning_rate, + "num_warmup_updates": num_warmup_updates, + "batch_size": batch_size, + "batch_size_type": batch_size_type, + "max_samples": max_samples, + "grad_accumulation_steps": grad_accumulation_steps, + "max_grad_norm": max_grad_norm, + "gpus": self.accelerator.num_processes, + "noise_scheduler": noise_scheduler, + }, + ) + + self.precision = self.accelerator.state.mixed_precision + self.precision = self.precision.replace("no", "fp32") + print("!!!!!!!!!!!!!!!!!", self.precision) + + self.model = model + #self.model = torch.compile(model) + + #self.dataloader = dataloader + + if self.is_main: + self.ema_model = EMA(model, include_online_model=False, **ema_kwargs) + + self.ema_model.to(self.accelerator.device) + if self.accelerator.state.distributed_type in ["DEEPSPEED", "FSDP"]: + self.ema_model.half() + + self.epochs = epochs + self.num_warmup_updates = num_warmup_updates + self.save_per_updates = save_per_updates + self.last_per_steps = default(last_per_steps, save_per_updates * grad_accumulation_steps) + self.checkpoint_path = default(checkpoint_path, "ckpts/test_e2-tts") + + self.max_samples = max_samples + self.grad_accumulation_steps = grad_accumulation_steps + self.max_grad_norm = max_grad_norm + + self.noise_scheduler = noise_scheduler + + self.duration_predictor = duration_predictor + + self.reset_lr = reset_lr + + self.use_style_prompt = use_style_prompt + + self.grad_ckpt = grad_ckpt + + if bnb_optimizer: + import bitsandbytes as bnb + + self.optimizer = bnb.optim.AdamW8bit(model.parameters(), lr=learning_rate) + else: + self.optimizer = AdamW(model.parameters(), lr=learning_rate) + #self.optimizer = FusedAdam(model.parameters(), lr=learning_rate) + + #self.model = torch.compile(self.model) + if self.accelerator.state.distributed_type == "DEEPSPEED": + self.accelerator.state.deepspeed_plugin.deepspeed_config['train_micro_batch_size_per_gpu'] = batch_size + + self.get_dataloader() + self.get_scheduler() + # self.get_constant_scheduler() + + self.model, self.optimizer, self.scheduler, self.train_dataloader = self.accelerator.prepare(self.model, self.optimizer, self.scheduler, self.train_dataloader) + + def get_scheduler(self): + warmup_steps = ( + self.num_warmup_updates * self.accelerator.num_processes + ) # consider a fixed warmup steps while using accelerate multi-gpu ddp + total_steps = len(self.train_dataloader) * self.epochs / self.grad_accumulation_steps + decay_steps = total_steps - warmup_steps + warmup_scheduler = LinearLR(self.optimizer, start_factor=1e-8, end_factor=1.0, total_iters=warmup_steps) + decay_scheduler = LinearLR(self.optimizer, start_factor=1.0, end_factor=1e-8, total_iters=decay_steps) + # constant_scheduler = ConstantLR(self.optimizer, factor=1, total_iters=decay_steps) + self.scheduler = SequentialLR( + self.optimizer, schedulers=[warmup_scheduler, decay_scheduler], milestones=[warmup_steps] + ) + + def get_constant_scheduler(self): + total_steps = len(self.train_dataloader) * self.epochs / self.grad_accumulation_steps + self.scheduler = ConstantLR(self.optimizer, factor=1, total_iters=total_steps) + + def get_dataloader(self): + prompt_path = self.args.prompt_path.split('|') + lrc_path = self.args.lrc_path.split('|') + latent_path = self.args.latent_path.split('|') + ldd = LanceDiffusionDataset(*LanceDiffusionDataset.init_data(self.args.dataset_path), \ + max_frames=self.args.max_frames, min_frames=self.args.min_frames, \ + align_lyrics=self.args.align_lyrics, lyrics_slice=self.args.lyrics_slice, \ + use_style_prompt=self.args.use_style_prompt, parse_lyrics=self.args.parse_lyrics, + lyrics_shift=self.args.lyrics_shift, downsample_rate=self.args.downsample_rate, \ + skip_empty_lyrics=self.args.skip_empty_lyrics, tokenizer_type=self.args.tokenizer_type, precision=self.precision, \ + start_time=time.time(), pure_prob=self.args.pure_prob) + + # start_time = time.time() + self.train_dataloader = DataLoader( + dataset=ldd, + batch_size=self.args.batch_size, # 每个批次的样本数 + shuffle=True, # 是否随机打乱数据 + num_workers=4, # 用于加载数据的子进程数 + pin_memory=True, # 加速GPU训练 + collate_fn=ldd.custom_collate_fn, + persistent_workers=True + ) + + + @property + def is_main(self): + return self.accelerator.is_main_process + + def save_checkpoint(self, step, last=False): + self.accelerator.wait_for_everyone() + if self.is_main: + checkpoint = dict( + model_state_dict=self.accelerator.unwrap_model(self.model).state_dict(), + optimizer_state_dict=self.accelerator.unwrap_model(self.optimizer).state_dict(), + ema_model_state_dict=self.ema_model.state_dict(), + scheduler_state_dict=self.scheduler.state_dict(), + step=step, + ) + if not os.path.exists(self.checkpoint_path): + os.makedirs(self.checkpoint_path) + if last: + self.accelerator.save(checkpoint, f"{self.checkpoint_path}/model_last.pt") + print(f"Saved last checkpoint at step {step}") + else: + self.accelerator.save(checkpoint, f"{self.checkpoint_path}/model_{step}.pt") + + def load_checkpoint(self): + if ( + not exists(self.checkpoint_path) + or not os.path.exists(self.checkpoint_path) + or not os.listdir(self.checkpoint_path) + ): + return 0 + + self.accelerator.wait_for_everyone() + if "model_last.pt" in os.listdir(self.checkpoint_path): + latest_checkpoint = "model_last.pt" + else: + latest_checkpoint = sorted( + [f for f in os.listdir(self.checkpoint_path) if f.endswith(".pt")], + key=lambda x: int("".join(filter(str.isdigit, x))), + )[-1] + + checkpoint = torch.load(f"{self.checkpoint_path}/{latest_checkpoint}", map_location="cpu") + + ### **1. 过滤 `ema_model` 的不匹配参数** + if self.is_main: + ema_dict = self.ema_model.state_dict() + ema_checkpoint_dict = checkpoint["ema_model_state_dict"] + + filtered_ema_dict = { + k: v for k, v in ema_checkpoint_dict.items() + if k in ema_dict and ema_dict[k].shape == v.shape # 仅加载 shape 匹配的参数 + } + + print(f"Loading {len(filtered_ema_dict)} / {len(ema_checkpoint_dict)} ema_model params") + self.ema_model.load_state_dict(filtered_ema_dict, strict=False) + + ### **2. 过滤 `model` 的不匹配参数** + model_dict = self.accelerator.unwrap_model(self.model).state_dict() + checkpoint_model_dict = checkpoint["model_state_dict"] + + filtered_model_dict = { + k: v for k, v in checkpoint_model_dict.items() + if k in model_dict and model_dict[k].shape == v.shape # 仅加载 shape 匹配的参数 + } + + print(f"Loading {len(filtered_model_dict)} / {len(checkpoint_model_dict)} model params") + self.accelerator.unwrap_model(self.model).load_state_dict(filtered_model_dict, strict=False) + + ### **3. 加载优化器、调度器和步数** + if "step" in checkpoint: + if self.scheduler and not self.reset_lr: + self.scheduler.load_state_dict(checkpoint["scheduler_state_dict"]) + step = checkpoint["step"] + else: + step = 0 + + del checkpoint + gc.collect() + print("Checkpoint loaded at step", step) + return step + + def train(self, resumable_with_seed: int = None): + train_dataloader = self.train_dataloader + + start_step = self.load_checkpoint() + global_step = start_step + + if resumable_with_seed > 0: + orig_epoch_step = len(train_dataloader) + skipped_epoch = int(start_step // orig_epoch_step) + skipped_batch = start_step % orig_epoch_step + skipped_dataloader = self.accelerator.skip_first_batches(train_dataloader, num_batches=skipped_batch) + else: + skipped_epoch = 0 + + for epoch in range(skipped_epoch, self.epochs): + self.model.train() + if resumable_with_seed > 0 and epoch == skipped_epoch: + progress_bar = tqdm( + skipped_dataloader, + desc=f"Epoch {epoch+1}/{self.epochs}", + unit="step", + disable=not self.accelerator.is_local_main_process, + initial=skipped_batch, + total=orig_epoch_step, + smoothing=0.15 + ) + else: + progress_bar = tqdm( + train_dataloader, + desc=f"Epoch {epoch+1}/{self.epochs}", + unit="step", + disable=not self.accelerator.is_local_main_process, + smoothing=0.15 + ) + + for batch in progress_bar: + with self.accelerator.accumulate(self.model): + text_inputs = batch["lrc"] + mel_spec = batch["latent"].permute(0, 2, 1) + mel_lengths = batch["latent_lengths"] + style_prompt = batch["prompt"] + style_prompt_lens = batch["prompt_lengths"] + start_time = batch["start_time"] + + loss, cond, pred = self.model( + mel_spec, text=text_inputs, lens=mel_lengths, noise_scheduler=self.noise_scheduler, + style_prompt=style_prompt if self.use_style_prompt else None, + style_prompt_lens=style_prompt_lens if self.use_style_prompt else None, + grad_ckpt=self.grad_ckpt, start_time=start_time + ) + self.accelerator.backward(loss) + + if self.max_grad_norm > 0 and self.accelerator.sync_gradients: + self.accelerator.clip_grad_norm_(self.model.parameters(), self.max_grad_norm) + + self.optimizer.step() + self.scheduler.step() + self.optimizer.zero_grad() + + if self.is_main: + self.ema_model.update() + + global_step += 1 + + if self.accelerator.is_local_main_process: + self.accelerator.log({"loss": loss.item(), "lr": self.scheduler.get_last_lr()[0]}, step=global_step) + + progress_bar.set_postfix(step=str(global_step), loss=loss.item()) + + if global_step % (self.save_per_updates * self.grad_accumulation_steps) == 0: + self.save_checkpoint(global_step) + + if global_step % self.last_per_steps == 0: + self.save_checkpoint(global_step, last=True) + + self.save_checkpoint(global_step, last=True) + + self.accelerator.end_training() diff --git a/diffrhythm/model/utils.py b/diffrhythm/model/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..f34ea04a54a9fd4070cb72ee73ffb880ecbfc340 --- /dev/null +++ b/diffrhythm/model/utils.py @@ -0,0 +1,182 @@ +from __future__ import annotations + +import os +import random +from collections import defaultdict +from importlib.resources import files + +import torch +from torch.nn.utils.rnn import pad_sequence + + +# seed everything + + +def seed_everything(seed=0): + random.seed(seed) + os.environ["PYTHONHASHSEED"] = str(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False + + +# helpers + + +def exists(v): + return v is not None + + +def default(v, d): + return v if exists(v) else d + + +# tensor helpers + + +def lens_to_mask(t: int["b"], length: int | None = None) -> bool["b n"]: # noqa: F722 F821 + if not exists(length): + length = t.amax() + + seq = torch.arange(length, device=t.device) + return seq[None, :] < t[:, None] + + +def mask_from_start_end_indices(seq_len: int["b"], start: int["b"], end: int["b"]): # noqa: F722 F821 + max_seq_len = 2048 + seq = torch.arange(max_seq_len, device=start.device).long() + start_mask = seq[None, :] >= start[:, None] + end_mask = seq[None, :] < end[:, None] + return start_mask & end_mask + + +def mask_from_frac_lengths(seq_len: int["b"], frac_lengths: float["b"]): # noqa: F722 F821 + lengths = (frac_lengths * seq_len).long() + max_start = seq_len - lengths + + rand = torch.rand_like(frac_lengths) + start = (max_start * rand).long().clamp(min=0) + end = start + lengths + + return mask_from_start_end_indices(seq_len, start, end) + + +def maybe_masked_mean(t: float["b n d"], mask: bool["b n"] = None) -> float["b d"]: # noqa: F722 + if not exists(mask): + return t.mean(dim=1) + + t = torch.where(mask[:, :, None], t, torch.tensor(0.0, device=t.device)) + num = t.sum(dim=1) + den = mask.float().sum(dim=1) + + return num / den.clamp(min=1.0) + + +# simple utf-8 tokenizer, since paper went character based +def list_str_to_tensor(text: list[str], padding_value=-1) -> int["b nt"]: # noqa: F722 + list_tensors = [torch.tensor([*bytes(t, "UTF-8")]) for t in text] # ByT5 style + text = pad_sequence(list_tensors, padding_value=padding_value, batch_first=True) + return text + + +# char tokenizer, based on custom dataset's extracted .txt file +def list_str_to_idx( + text: list[str] | list[list[str]], + vocab_char_map: dict[str, int], # {char: idx} + padding_value=-1, +) -> int["b nt"]: # noqa: F722 + list_idx_tensors = [torch.tensor([vocab_char_map.get(c, 0) for c in t]) for t in text] # pinyin or char style + text = pad_sequence(list_idx_tensors, padding_value=padding_value, batch_first=True) + return text + + +# Get tokenizer + + +def get_tokenizer(dataset_name, tokenizer: str = "pinyin"): + """ + tokenizer - "pinyin" do g2p for only chinese characters, need .txt vocab_file + - "char" for char-wise tokenizer, need .txt vocab_file + - "byte" for utf-8 tokenizer + - "custom" if you're directly passing in a path to the vocab.txt you want to use + vocab_size - if use "pinyin", all available pinyin types, common alphabets (also those with accent) and symbols + - if use "char", derived from unfiltered character & symbol counts of custom dataset + - if use "byte", set to 256 (unicode byte range) + """ + if tokenizer in ["pinyin", "char"]: + tokenizer_path = os.path.join(files("diffrhythm").joinpath("../../data"), f"{dataset_name}_{tokenizer}/vocab.txt") + with open(tokenizer_path, "r", encoding="utf-8") as f: + vocab_char_map = {} + for i, char in enumerate(f): + vocab_char_map[char[:-1]] = i + vocab_size = len(vocab_char_map) + assert vocab_char_map[" "] == 0, "make sure space is of idx 0 in vocab.txt, cuz 0 is used for unknown char" + + elif tokenizer == "byte": + vocab_char_map = None + vocab_size = 256 + + elif tokenizer == "custom": + with open(dataset_name, "r", encoding="utf-8") as f: + vocab_char_map = {} + for i, char in enumerate(f): + vocab_char_map[char[:-1]] = i + vocab_size = len(vocab_char_map) + + return vocab_char_map, vocab_size + + +# convert char to pinyin + + +def convert_char_to_pinyin(text_list, polyphone=True): + final_text_list = [] + god_knows_why_en_testset_contains_zh_quote = str.maketrans( + {"“": '"', "”": '"', "‘": "'", "’": "'"} + ) # in case librispeech (orig no-pc) test-clean + custom_trans = str.maketrans({";": ","}) # add custom trans here, to address oov + for text in text_list: + char_list = [] + text = text.translate(god_knows_why_en_testset_contains_zh_quote) + text = text.translate(custom_trans) + for seg in jieba.cut(text): + seg_byte_len = len(bytes(seg, "UTF-8")) + if seg_byte_len == len(seg): # if pure alphabets and symbols + if char_list and seg_byte_len > 1 and char_list[-1] not in " :'\"": + char_list.append(" ") + char_list.extend(seg) + elif polyphone and seg_byte_len == 3 * len(seg): # if pure chinese characters + seg = lazy_pinyin(seg, style=Style.TONE3, tone_sandhi=True) + for c in seg: + if c not in "。,、;:?!《》【】—…": + char_list.append(" ") + char_list.append(c) + else: # if mixed chinese characters, alphabets and symbols + for c in seg: + if ord(c) < 256: + char_list.extend(c) + else: + if c not in "。,、;:?!《》【】—…": + char_list.append(" ") + char_list.extend(lazy_pinyin(c, style=Style.TONE3, tone_sandhi=True)) + else: # if is zh punc + char_list.append(c) + final_text_list.append(char_list) + + return final_text_list + + +# filter func for dirty data with many repetitions + + +def repetition_found(text, length=2, tolerance=10): + pattern_count = defaultdict(int) + for i in range(len(text) - length + 1): + pattern = text[i : i + length] + pattern_count[pattern] += 1 + for pattern, count in pattern_count.items(): + if count > tolerance: + return True + return False