diff --git a/.gitignore b/.gitignore index 505be3f9bb72734d4eaa8ff560d2b075466325c2..f9c0d9ed5e1553e8468aa8abf9cd7fd385904813 100644 --- a/.gitignore +++ b/.gitignore @@ -200,3 +200,6 @@ app_demo.py ui/components_demo.py data_sampler_demo.py pipeline_ace_step_demo.py + +.vs +venv diff --git a/README.md b/README.md index 480e756ebfa9b53bc5547e971ad2a607d65fa3a7..aeb066c03076259c40610a3787e668606242e2ae 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ emoji: 😻 colorFrom: blue colorTo: pink sdk: gradio -sdk_version: 5.27.0 +sdk_version: 5.29.1 app_file: app.py -pinned: false +pinned: true license: apache-2.0 short_description: A Step Towards Music Generation Foundation Model --- diff --git a/apg_guidance.py b/apg_guidance.py deleted file mode 100644 index 95ba4f6f7c7832ef78b6fcff5a42ec3136d2f9cc..0000000000000000000000000000000000000000 --- a/apg_guidance.py +++ /dev/null @@ -1,95 +0,0 @@ -import torch - - -class MomentumBuffer: - def __init__(self, momentum: float = -0.75): - self.momentum = momentum - self.running_average = 0 - - def update(self, update_value: torch.Tensor): - new_average = self.momentum * self.running_average - self.running_average = update_value + new_average - - -def project( - v0: torch.Tensor, # [B, C, H, W] - v1: torch.Tensor, # [B, C, H, W] - dims=[-1, -2], -): - dtype = v0.dtype - device_type = v0.device.type - if device_type == "mps": - v0, v1 = v0.cpu(), v1.cpu() - - v0, v1 = v0.double(), v1.double() - v1 = torch.nn.functional.normalize(v1, dim=dims) - v0_parallel = (v0 * v1).sum(dim=dims, keepdim=True) * v1 - v0_orthogonal = v0 - v0_parallel - return v0_parallel.to(dtype).to(device_type), v0_orthogonal.to(dtype).to(device_type) - - -def apg_forward( - pred_cond: torch.Tensor, # [B, C, H, W] - pred_uncond: torch.Tensor, # [B, C, H, W] - guidance_scale: float, - momentum_buffer: MomentumBuffer = None, - eta: float = 0.0, - norm_threshold: float = 2.5, - dims=[-1, -2], -): - diff = pred_cond - pred_uncond - if momentum_buffer is not None: - momentum_buffer.update(diff) - diff = momentum_buffer.running_average - - if norm_threshold > 0: - ones = torch.ones_like(diff) - diff_norm = diff.norm(p=2, dim=dims, keepdim=True) - scale_factor = torch.minimum(ones, norm_threshold / diff_norm) - diff = diff * scale_factor - - diff_parallel, diff_orthogonal = project(diff, pred_cond, dims) - normalized_update = diff_orthogonal + eta * diff_parallel - pred_guided = pred_cond + (guidance_scale - 1) * normalized_update - return pred_guided - - -def cfg_forward(cond_output, uncond_output, cfg_strength): - return uncond_output + cfg_strength * (cond_output - uncond_output) - - -def cfg_double_condition_forward( - cond_output, - uncond_output, - only_text_cond_output, - guidance_scale_text, - guidance_scale_lyric, -): - return (1 - guidance_scale_text) * uncond_output + (guidance_scale_text - guidance_scale_lyric) * only_text_cond_output + guidance_scale_lyric * cond_output - - -def optimized_scale(positive_flat, negative_flat): - - # Calculate dot production - dot_product = torch.sum(positive_flat * negative_flat, dim=1, keepdim=True) - - # Squared norm of uncondition - squared_norm = torch.sum(negative_flat ** 2, dim=1, keepdim=True) + 1e-8 - - # st_star = v_cond^T * v_uncond / ||v_uncond||^2 - st_star = dot_product / squared_norm - - return st_star - - -def cfg_zero_star(noise_pred_with_cond, noise_pred_uncond, guidance_scale, i, zero_steps=1, use_zero_init=True): - bsz = noise_pred_with_cond.shape[0] - positive_flat = noise_pred_with_cond.view(bsz, -1) - negative_flat = noise_pred_uncond.view(bsz, -1) - alpha = optimized_scale(positive_flat, negative_flat) - alpha = alpha.view(bsz, 1, 1, 1) - if (i <= zero_steps) and use_zero_init: - noise_pred = noise_pred_with_cond * 0. - else: - noise_pred = noise_pred_uncond * alpha + guidance_scale * (noise_pred_with_cond - noise_pred_uncond * alpha) - return noise_pred diff --git a/app.py b/app.py index a0d930f612f4a8aa6b483def5d061282ff01a350..0bde80e089769917b73e7657a94dca4f88661f92 100644 --- a/app.py +++ b/app.py @@ -1,33 +1,69 @@ -import argparse -from ui.components import create_main_demo_ui -from pipeline_ace_step import ACEStepPipeline -from data_sampler import DataSampler -import os - +""" +ACE-Step: A Step Towards Music Generation Foundation Model -parser = argparse.ArgumentParser() -parser.add_argument("--checkpoint_path", type=str, default=None) -parser.add_argument("--server_name", type=str, default="0.0.0.0") -parser.add_argument("--port", type=int, default=7860) -parser.add_argument("--device_id", type=int, default=0) -parser.add_argument("--share", action='store_true', default=False) -parser.add_argument("--bf16", action='store_true', default=True) -parser.add_argument("--torch_compile", type=bool, default=False) +https://github.com/ace-step/ACE-Step -args = parser.parse_args() -os.environ["CUDA_VISIBLE_DEVICES"] = str(args.device_id) +Apache 2.0 License +""" +import os +import click -persistent_storage_path = "/data" +@click.command() +@click.option( + "--checkpoint_path", + type=str, + default="", + help="Path to the checkpoint directory. Downloads automatically if empty.", +) +@click.option( + "--server_name", + type=str, + default="127.0.0.1", + help="The server name to use for the Gradio app.", +) +@click.option( + "--port", type=int, default=None, help="The port to use for the Gradio app." +) +@click.option("--device_id", type=int, default=0, help="The CUDA device ID to use.") +@click.option( + "--share", + type=click.BOOL, + default=False, + help="Whether to create a public, shareable link for the Gradio app.", +) +@click.option( + "--bf16", + type=click.BOOL, + default=True, + help="Whether to use bfloat16 precision. Turn off if using MPS.", +) +@click.option( + "--torch_compile", type=click.BOOL, default=False, help="Whether to use torch.compile." +) +@click.option( + "--cpu_offload", type=bool, default=False, help="Whether to use CPU offloading (only load current stage's model to GPU)" +) +@click.option( + "--overlapped_decode", type=bool, default=False, help="Whether to use overlapped decoding (run dcae and vocoder using sliding windows)" +) +def main(checkpoint_path, server_name, port, device_id, share, bf16, torch_compile, cpu_offload, overlapped_decode): + """ + Main function to launch the ACE Step pipeline demo. + """ + os.environ["CUDA_VISIBLE_DEVICES"] = str(device_id) -def main(args): + from acestep.ui.components import create_main_demo_ui + from acestep.pipeline_ace_step import ACEStepPipeline + from acestep.data_sampler import DataSampler model_demo = ACEStepPipeline( - checkpoint_dir=args.checkpoint_path, - dtype="bfloat16" if args.bf16 else "float32", - persistent_storage_path=persistent_storage_path, - torch_compile=args.torch_compile + checkpoint_dir=checkpoint_path, + dtype="bfloat16" if bf16 else "float32", + torch_compile=torch_compile, + cpu_offload=cpu_offload, + overlapped_decode=overlapped_decode ) data_sampler = DataSampler() @@ -36,10 +72,8 @@ def main(args): sample_data_func=data_sampler.sample, load_data_func=data_sampler.load_json, ) - demo.queue(default_concurrency_limit=8).launch( - - ) + demo.queue().launch(inbrowser=True) if __name__ == "__main__": - main(args) + main() diff --git a/config/zh_rap_lora_config.json b/config/zh_rap_lora_config.json deleted file mode 100644 index 6057c90418919689cdb1f55c604fc921656e4847..0000000000000000000000000000000000000000 --- a/config/zh_rap_lora_config.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "r": 256, - "lora_alpha": 32, - "target_modules": [ - "speaker_embedder", - "linear_q", - "linear_k", - "linear_v", - "to_q", - "to_k", - "to_v", - "to_out.0" - ], - "use_rslora": true -} \ No newline at end of file diff --git a/data_sampler.py b/data_sampler.py deleted file mode 100644 index f80d5b9e08a0b3564d2323178091dd47ce4b2780..0000000000000000000000000000000000000000 --- a/data_sampler.py +++ /dev/null @@ -1,30 +0,0 @@ -import json -from pathlib import Path -import random - - -DEFAULT_ROOT_DIR = "examples/default/input_params" -ZH_RAP_LORA_ROOT_DIR = "examples/zh_rap_lora/input_params" - -class DataSampler: - def __init__(self, root_dir=DEFAULT_ROOT_DIR): - self.root_dir = root_dir - self.input_params_files = list(Path(self.root_dir).glob("*.json")) - self.zh_rap_lora_input_params_files = list(Path(ZH_RAP_LORA_ROOT_DIR).glob("*.json")) - self.zh_rap_lora_input_params_files += list(Path(ZH_RAP_LORA_ROOT_DIR).glob("*.json")) - - def load_json(self, file_path): - with open(file_path, "r", encoding="utf-8") as f: - return json.load(f) - - def sample(self, lora_name_or_path=None): - if lora_name_or_path is None or lora_name_or_path == "none": - json_path = random.choice(self.input_params_files) - json_data = self.load_json(json_path) - else: - json_path = random.choice(self.zh_rap_lora_input_params_files) - json_data = self.load_json(json_path) - # Update the lora_name in the json_data - json_data["lora_name_or_path"] = lora_name_or_path - - return json_data diff --git a/examples/default/input_params/output_20250426071706_0_input_params.json b/examples/default/input_params/output_20250426071706_0_input_params.json deleted file mode 100644 index 6a3b9cb011c9aae05fe85a4e54862f36cea940e1..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426071706_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "pop, rap, electronic, blues, hip-house, rhythm and blues", - "lyrics": "[verse]\n我走过深夜的街道\n冷风吹乱思念的漂亮外套\n你的微笑像星光很炫耀\n照亮了我孤独的每分每秒\n\n[chorus]\n愿你是风吹过我的脸\n带我飞过最远最遥远的山间\n愿你是风轻触我的梦\n停在心头不再飘散无迹无踪\n\n[verse]\n一起在喧哗避开世俗的骚动\n独自在天台探望月色的朦胧\n你说爱像音乐带点重节奏\n一拍一跳让我忘了心的温度多空洞\n\n[bridge]\n唱起对你的想念不隐藏\n像诗又像画写满藏不了的渴望\n你的影子挥不掉像风的倔强\n追着你飞扬穿越云海一样泛光\n\n[chorus]\n愿你是风吹过我的手\n暖暖的触碰像春日细雨温柔\n愿你是风盘绕我的身\n深情万万重不会有一天走远走\n\n[verse]\n深夜的钢琴弹起动人的旋律\n低音鼓砸进心底的每一次呼吸\n要是能将爱化作歌声传递\n你是否会听见我心里的真心实意", - "audio_duration": 170.63997916666668, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 3.191075086593628, - "diffusion": 17.459356784820557, - "latent2audio": 1.7095518112182617 - }, - "actual_seeds": [ - 3299954530 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426071812_0_input_params.json b/examples/default/input_params/output_20250426071812_0_input_params.json deleted file mode 100644 index 96c2dfe18271688d288be3656000c4e2b49251a0..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426071812_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "country rock, folk rock, southern rock, bluegrass, country pop", - "lyrics": "[verse]\nWoke up to the sunrise glow\nTook my heart and hit the road\nWheels hummin' the only tune I know\nStraight to where the wildflowers grow\n\n[verse]\nGot that old map all wrinkled and torn\nDestination unknown but I'm reborn\nWith a smile that the wind has worn\nChasin' dreams that can't be sworn\n\n[chorus]\nRidin' on a highway to sunshine\nGot my shades and my radio on fine\nLeave the shadows in the rearview rhyme\nHeart's racing as we chase the time\n\n[verse]\nMet a girl with a heart of gold\nTold stories that never get old\nHer laugh like a tale that's been told\nA melody so bold yet uncontrolled\n\n[bridge]\nClouds roll by like silent ghosts\nAs we drive along the coast\nWe toast to the days we love the most\nFreedom's song is what we post\n\n[chorus]\nRidin' on a highway to sunshine\nGot my shades and my radio on fine\nLeave the shadows in the rearview rhyme\nHeart's racing as we chase the time", - "audio_duration": 224.23997916666667, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 4.262240648269653, - "diffusion": 15.380569219589233, - "latent2audio": 2.3227272033691406 - }, - "actual_seeds": [ - 401640 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426072346_0_input_params.json b/examples/default/input_params/output_20250426072346_0_input_params.json deleted file mode 100644 index c819f8d6edc4b39246ae2a3d1aee20c5b5633b6f..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426072346_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "hip-house, funk", - "lyrics": "[verse]\n哎呀跳起来,脚尖踩节拍 (oo-yeah!)\n灯光闪烁像星星盛开 (uh-huh!)\n人人都醒来,把烦恼踹开 (get it!)\n热血沸腾,汗水自己安排\n\n[chorus]\n嘿,你还等啥?快抓住节拍 (come on!)\n光芒指引,让心都不存在 (whoa!)\n点燃热火,我们一起飙high (let’s go!)\n跳入午夜的狂欢时代\n\n[bridge]\n咚咚鼓声啊,让你的灵魂起飞 (woo!)\n手心拍一拍,能量翻倍 (ah-hah!)\n键盘响起来,如宇宙的交汇 (oh yeah!)\n就是这感觉,兄弟姐妹都陶醉\n\n[verse]\n灵魂从不睡,只想继续燃烧 (woo!)\n节奏像热浪,席卷这街道 (ow!)\n大伙儿涌上楼台,满面微笑 (yeah!)\n这一刻属于我们,无可替代\n\n[chorus]\n嘿,你还等啥?快抓住节拍 (come on!)\n光芒指引,让心都不存在 (whoa!)\n点燃热火,我们一起飙high (let’s go!)\n跳入午夜的狂欢时代\n\n[verse]\n世界多精彩,握紧把它打开 (alright!)\n每一步都像星球在摇摆 (uh-huh!)\n无边无际的律动像大海 (oo-yeah!)\n跟着光芒之舞,一起澎湃", - "audio_duration": 204.19997916666668, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.05196118354797363, - "diffusion": 15.530808210372925, - "latent2audio": 2.5604095458984375 - }, - "actual_seeds": [ - 401640 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426072508_0_input_params.json b/examples/default/input_params/output_20250426072508_0_input_params.json deleted file mode 100644 index ead4bb1c3e690d8a581fc4ddbd5f46a5dfc92179..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426072508_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "funk, pop, soul, rock, melodic, guitar, drums, bass, keyboard, percussion, 105 BPM, energetic, upbeat, groovy, vibrant, dynamic", - "lyrics": "[verse]\nNeon lights they flicker bright\nCity hums in dead of night\nRhythms pulse through concrete veins\nLost in echoes of refrains\n\n[verse]\nBassline groovin' in my chest\nHeartbeats match the city's zest\nElectric whispers fill the air\nSynthesized dreams everywhere\n\n[chorus]\nTurn it up and let it flow\nFeel the fire let it grow\nIn this rhythm we belong\nHear the night sing out our song\n\n[verse]\nGuitar strings they start to weep\nWake the soul from silent sleep\nEvery note a story told\nIn this night we’re bold and gold\n\n[bridge]\nVoices blend in harmony\nLost in pure cacophony\nTimeless echoes timeless cries\nSoulful shouts beneath the skies\n\n[verse]\nKeyboard dances on the keys\nMelodies on evening breeze\nCatch the tune and hold it tight\nIn this moment we take flight", - "audio_duration": 178.87997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.02882218360900879, - "diffusion": 16.91233205795288, - "latent2audio": 1.7794082164764404 - }, - "actual_seeds": [ - 401640 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426073829_0_input_params.json b/examples/default/input_params/output_20250426073829_0_input_params.json deleted file mode 100644 index b633a441b05ce2aac4a7360e7662bda3711354b6..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426073829_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "electronic rap", - "lyrics": "[verse]\nWaves on the bass, pulsing in the speakers,\nTurn the dial up, we chasing six-figure features,\nGrinding on the beats, codes in the creases,\nDigital hustler, midnight in sneakers.\n\n[chorus]\nElectro vibes, hearts beat with the hum,\nUrban legends ride, we ain't ever numb,\nCircuits sparking live, tapping on the drum,\nLiving on the edge, never succumb.\n\n[verse]\nSynthesizers blaze, city lights a glow,\nRhythm in the haze, moving with the flow,\nSwagger on stage, energy to blow,\nFrom the blocks to the booth, you already know.\n\n[bridge]\nNight's electric, streets full of dreams,\nBass hits collective, bursting at seams,\nHustle perspective, all in the schemes,\nRise and reflective, ain't no in-betweens.\n\n[verse]\nVibin' with the crew, sync in the wire,\nGot the dance moves, fire in the attire,\nRhythm and blues, soul's our supplier,\nRun the digital zoo, higher and higher.\n\n[chorus]\nElectro vibes, hearts beat with the hum,\nUrban legends ride, we ain't ever numb,\nCircuits sparking live, tapping on the drum,\nLiving on the edge, never succumb.", - "audio_duration": 221.42547916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.024875164031982422, - "diffusion": 20.566852569580078, - "latent2audio": 2.2281734943389893 - }, - "actual_seeds": [ - 401640 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426074037_0_input_params.json b/examples/default/input_params/output_20250426074037_0_input_params.json deleted file mode 100644 index e8f0ce40706a347acaa0c97870a125c622621766..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426074037_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "electronic, house, electro house, synthesizer, drums, bass, percussion, fast, energetic, uplifting, exciting", - "lyrics": "[verse]\n霓虹灯下我们追逐\n人群跃动像潮水满布\n热浪袭来吹散孤独\n跳进节奏不如停下脚步\n\n[pre-chorus]\n脚尖触电快点感受\n迎着风声释放自由\n心跳节拍配合节奏\n一切烦恼请靠边游\n\n[chorus]\n夏夜狂奔没有尽头\n星光闪烁舞池不朽\n尽情挥洒所有节奏\n无边热情把你包裹哦\n\n[verse]\n天空翻滚黑云入夜\n每颗星星像音乐律贴\n耳边回响那低音线\n环绕耳际如梦境般甜\n\n[pre-chorus]\n脚尖触电快点感受\n迎着风声释放自由\n心跳节拍配合节奏\n一切烦恼请靠边游\n\n[chorus]\n夏夜狂奔没有尽头\n星光闪烁舞池不朽\n尽情挥洒所有节奏\n无边热情把你包裹哦", - "audio_duration": 221.47997916666668, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.028400182723999023, - "diffusion": 13.195815324783325, - "latent2audio": 2.1679723262786865 - }, - "actual_seeds": [ - 3440445703 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426074214_0_input_params.json b/examples/default/input_params/output_20250426074214_0_input_params.json deleted file mode 100644 index e6ed70fc2793bd554c9d148aa30c5cd528a91749..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426074214_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "synth-pop, electronic, pop, synthesizer, drums, bass, piano, 128 BPM, energetic, uplifting, modern", - "lyrics": "[verse]\nWoke up in a city that's always alive\nNeon lights they shimmer they thrive\nElectric pulses beat they drive\nMy heart races just to survive\n\n[chorus]\nOh electric dreams they keep me high\nThrough the wires I soar and fly\nMidnight rhythms in the sky\nElectric dreams together we’ll defy\n\n[verse]\nLost in the labyrinth of screens\nVirtual love or so it seems\nIn the night the city gleams\nDigital faces haunted by memes\n\n[chorus]\nOh electric dreams they keep me high\nThrough the wires I soar and fly\nMidnight rhythms in the sky\nElectric dreams together we’ll defy\n\n[bridge]\nSilent whispers in my ear\nPixelated love serene and clear\nThrough the chaos find you near\nIn electric dreams no fear\n\n[verse]\nBound by circuits intertwined\nLove like ours is hard to find\nIn this world we’re truly blind\nBut electric dreams free the mind", - "audio_duration": 221.27997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.025463581085205078, - "diffusion": 15.243804454803467, - "latent2audio": 2.170398473739624 - }, - "actual_seeds": [ - 3400270027 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426074413_0_input_params.json b/examples/default/input_params/output_20250426074413_0_input_params.json deleted file mode 100644 index 796a8da3d438084959da029e885171168493f29f..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426074413_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "Cuban music, salsa, son, Afro-Cuban, traditional Cuban", - "lyrics": "[verse]\nSun dips low the night ignites\nBassline hums with gleaming lights\nElectric guitar singing tales so fine\nIn the rhythm we all intertwine\n\n[verse]\nDrums beat steady calling out\nPercussion guides no room for doubt\nElectric pulse through every vein\nDance away every ounce of pain\n\n[chorus]\nFeel the rhythm feel the flow\nLet the music take control\nBassline deep electric hum\nIn this night we're never numb\n\n[bridge]\nStars above they start to glow\nEchoes of the night's soft glow\nElectric strings weave through the air\nIn this moment none compare\n\n[verse]\nHeartbeats sync with every tone\nLost in music never alone\nElectric tales of love and peace\nIn this groove we find release\n\n[chorus]\nFeel the rhythm feel the flow\nLet the music take control\nBassline deep electric hum\nIn this night we're never numb", - "audio_duration": 208.27997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.026132583618164062, - "diffusion": 15.139378070831299, - "latent2audio": 2.2071540355682373 - }, - "actual_seeds": [ - 3358899399 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426075107_0_input_params.json b/examples/default/input_params/output_20250426075107_0_input_params.json deleted file mode 100644 index 2c7dcf74d59118736bfd1639f8a76afa7fcd3f69..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426075107_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "pop, piano, rap, dark, atmospheric", - "lyrics": "[verse]\n月光爬上窗 染白冷的床\n心跳的方向 带我入迷惘\n黑夜吞噬光 命运的纸张\n爱是血色霜 邪恶又芬芳\n\n[chorus]\n你是猎人的欲望 我是迷途的小羊\n深陷你眼眸的荒 唐突献出心脏\n我在夜里回荡 是谁给我希望\n黑暗风中飘荡 假装不再受伤\n\n[verse]\n心锁在门外 谁会解开关怀\n温柔的手拍 藏着冷酷杀害\n思绪如尘埃 撞击爱的霹雳\n灵魂的独白 为你沾满血迹\n\n[bridge]\n你是噩梦的歌唱 是灵魂的捆绑\n绝望中带着光 悬崖边的渴望\n心跳被你鼓掌 恶魔也痴痴想\n渐渐没了抵抗 古老诡计流淌\n\n[chorus]\n你是猎人的欲望 我是迷途的小羊\n深陷你眼眸的荒 唐突献出心脏\n我在夜里回荡 是谁给我希望\n黑暗风中飘荡 假装不再受伤\n\n[outro]\n爱如月黑无光 渗进梦的战场\n逃入无声的场 放手或心嚷嚷\n隐秘的极端 爱是极致风浪\n灵魂彻底交偿 你是终极虚妄", - "audio_duration": 146.91997916666668, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.03876018524169922, - "diffusion": 15.962624549865723, - "latent2audio": 1.4594337940216064 - }, - "actual_seeds": [ - 2065110378 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426075537_0_input_params.json b/examples/default/input_params/output_20250426075537_0_input_params.json deleted file mode 100644 index 8446629056eba103f0c691f3cb9aa8cee9eabecf..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426075537_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "surf music", - "lyrics": "[verse]\nSunshine on the boulevard the beach is calling loud\nWaves are dancing golden sand under a cotton cloud\nElectric heartbeat pounding fast the tide is on our side\nCatch a wave and feel alive we’ll take it for a ride\n\n[verse]\nPalm trees swaying left to right they know where we belong\nFeel the rhythm of the night it keeps us moving strong\nSea spray kisses salty air we’re flying with the breeze\nChampagne states of mind we ride we do just as we please\n\n[chorus]\nWe’re riding waves of life together hand in hand\nWith every beat we chase the beat it’s our own wonderland\nFeel the music take you higher as the shorelines blur\nThis is our world our endless summer as we live and learn\n\n[bridge]\nMoonlight paints the ocean blue reflections in our eyes\nStars align to light our path we’re surfing through the skies\nEvery moment like a song we sing it loud and clear\nEvery day’s a new adventure with you always near\n\n[verse]\nNeon lights and city sounds they blend with ocean views\nWe’re unstoppable tonight no way that we can lose\nDreams are written in the sand they sparkle in the sun\nTogether we’re a masterpiece our story’s just begun\n\n[chorus]\nWe’re riding waves of life together hand in hand\nWith every beat we chase the beat it’s our own wonderland\nFeel the music take you higher as the shorelines blur\nThis is our world our endless summer as we live and learn", - "audio_duration": 236.55997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.033666133880615234, - "diffusion": 16.291455507278442, - "latent2audio": 2.3726775646209717 - }, - "actual_seeds": [ - 508630535 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426075843_0_input_params.json b/examples/default/input_params/output_20250426075843_0_input_params.json deleted file mode 100644 index 12a60cf63234adebb43ec488199f005c7ae63d28..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426075843_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "alternative rock, pop, rock", - "lyrics": "[verse]\nBright lights flashing in the city sky\nRunning fast and we don't know why\nElectric nights got our hearts on fire\nChasing dreams we'll never tire\n\n[verse]\nGrit in our eyes wind in our hair\nBreaking rules we don't even care\nShouting loud above the crowd\nLiving life like we're unbowed\n\n[chorus]\nRunning wild in the night so free\nFeel the beat pumping endlessly\nHearts collide in the midnight air\nWe belong we don't have a care\n\n[verse]\nPiercing through like a lightning strike\nEvery moment feels like a hike\nDaring bold never backing down\nKings and queens without a crown\n\n[chorus]\nRunning wild in the night so free\nFeel the beat pumping endlessly\nHearts collide in the midnight air\nWe belong we don't have a care\n\n[bridge]\nClose your eyes let your spirit soar\nWe are the ones who wanted more\nBreaking chains of the mundane\nIn this world we'll make our claim", - "audio_duration": 202.19997916666668, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.02512216567993164, - "diffusion": 18.860822677612305, - "latent2audio": 2.0361969470977783 - }, - "actual_seeds": [ - 1255121549 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426080234_0_input_params.json b/examples/default/input_params/output_20250426080234_0_input_params.json deleted file mode 100644 index 4ed1f6bbc9d3720e80b78699f9b34a6a390b9639..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426080234_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "rock, hip - hop, orchestral, bass, drums, electric guitar, piano, synthesizer, violin, viola, cello, fast, energetic, motivational, inspirational, empowering", - "lyrics": "### **[Intro – Spoken]** \n*\"The streets whisper, their echoes never fade. \nEvery step I take leaves a mark—this ain't just a game.\"* \n\n### **[Hook/Chorus]** \nBorn in the chaos, I weather the storm, \nRising from ashes where warriors are born. \nChains couldn't hold me, the system’s a maze, \nI rewrite the rules, set the city ablaze! \n\n### **[Verse 1]** \nCold nights, empty pockets, dreams laced with fight, \nEvery loss made me sharper, cut deep like a knife. \nThey said I wouldn’t make it, now they watch in despair, \nFrom the curb to the throne, took the pain, made it rare. \nEvery siren’s a melody, every alley holds a tale, \nRose from the shadows, left my name on the trail. \nStreetlights flicker like warnings in the haze, \nBut I move like a phantom, unfazed by the blaze. \n\n### **[Hook/Chorus]** \nBorn in the chaos, I weather the storm, \nRising from ashes where warriors are born. \nChains couldn't hold me, the system’s a maze, \nI rewrite the rules, set the city ablaze! \n\n### **[Verse 2]** \nBarbed wire fences couldn't lock in my mind, \nEvery cage they designed, I left broken behind. \nThey want control, but I’m destined to roam, \nWhere the lost find their voice, where the heart sets the tone. \nSteel and concrete, where the lessons run deep, \nEvery crack in the pavement tells a story of heat. \nBut I rise, undefeated, like a king with no throne, \nWriting scripts in the struggle, my legacy’s stone. \n\n### **[Bridge]** \nFeel the rhythm of the underground roar, \nEvery wound tells a story of the battles before. \nBlood, sweat, and echoes fill the cold midnight, \nBut we move with the fire—unshaken, upright. \n\n### **[Verse 3]** \nNo regrets, no retreat, this game has no pause, \nEvery step that I take is a win for the lost. \nI took lessons from hustlers, wisdom from pain, \nNow the echoes of struggle carve power in my name. \nThey built walls, but I walk through the cracks, \nTurned dirt into gold, never looked back. \nThrough the struggle we rise, through the fire we claim, \nThis is more than just music—it's life in the frame. \n\n### **[Hook/Chorus – Reprise]** \nBorn in the chaos, I weather the storm, \nRising from ashes where warriors are born. \nChains couldn't hold me, the system’s a maze, \nI rewrite the rules, set the city ablaze! \n\n### **[Outro – Spoken]** \n*\"The scars, the struggle, the grind—it’s all part of the rhythm. \nWe never break, we never fold. We rise.\"*", - "audio_duration": 153.95997916666667, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.04368758201599121, - "diffusion": 17.16369390487671, - "latent2audio": 1.5405471324920654 - }, - "actual_seeds": [ - 2659225017 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426080407_0_input_params.json b/examples/default/input_params/output_20250426080407_0_input_params.json deleted file mode 100644 index 1e71a27d574d762f34df1a47277aeff143e9669d..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426080407_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "tango finlandés, campanas, disco, dark pop, electro, guitarra clásica, corridos tumba", - "lyrics": "[inst]", - "audio_duration": 162.79997916666667, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.011058568954467773, - "diffusion": 9.924944400787354, - "latent2audio": 1.6034839153289795 - }, - "actual_seeds": [ - 780297686 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426080601_0_input_params.json b/examples/default/input_params/output_20250426080601_0_input_params.json deleted file mode 100644 index d205d2396722060d23af56bb9dca713d4dd23b0f..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426080601_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "Nightclubs, dance parties, workout playlists, radio broadcasts", - "lyrics": "Burning in motion, set me alight!\nEvery heartbeat turns into a fight!\nCaged in rhythm, chained in time!\nLove’s a battle— You're Mine! You're Mine!", - "audio_duration": 221.83997916666667, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.012485980987548828, - "diffusion": 14.345409154891968, - "latent2audio": 2.174558639526367 - }, - "actual_seeds": [ - 1318394052 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426081134_0_input_params.json b/examples/default/input_params/output_20250426081134_0_input_params.json deleted file mode 100644 index b6c4d14e7848325b3f6c29da9c56e63f8abec8a9..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426081134_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "melancholic, world, sad, medieval, soulful", - "lyrics": "[Verse]\nIn a world so grand he roams the skies alone\nHis heart a heavy stone a tale untold\nWhispers of his past echo through the night\nA lonely dragon searching for the light\n\n[Verse 2]\nOnce a mighty force now he drifts in pain\nHis scales once shimmered now they're dark with shame\nCast out by his kin in shadows he does hide\nA haunting sorrow burns deep inside\n\n[Chorus]\nRoaming endless fields with no friend in sight\nHis roar a mournful cry beneath the moon's pale light\nTears fall like stars as he flies on his way\nA lonely dragon yearning for the break of day\n\n[Bridge]\nThe world turns cold the nights grow long\nIn his heart he carries an ancient song\nOf battles fought and love long gone\nA legend now but his soul is torn\n\n[Verse 3]\nHoping for a day he'll find a kindred soul\nTo share his pain and make him whole\nTill then he drifts a shadow in the sky\nA lonely dragon with tears in his eye\n\n[Chorus]\nRoaming endless fields with no friend in sight\nHis roar a mournful cry beneath the moon's pale light\nTears fall like stars as he flies on his way\nA lonely dragon yearning for the break of day", - "audio_duration": 239.99997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.029100656509399414, - "diffusion": 22.503791570663452, - "latent2audio": 2.3603708744049072 - }, - "actual_seeds": [ - 2166832218 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426091716_0_input_params.json b/examples/default/input_params/output_20250426091716_0_input_params.json deleted file mode 100644 index 540c8508b51b1601c00d80b282e58c070d051083..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426091716_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "anime, cute female vocals, kawaii pop, j-pop, childish, piano, guitar, synthesizer, fast, happy, cheerful, lighthearted", - "lyrics": "[Chorus]\nねぇ、顔が赤いよ?\nどうしたの? 熱があるの?\nそれとも怒ってるの?\nねぇ、言ってよ!\n\nどうしてそんな目で見るの?\n私、悪いことした?\n何か間違えたの?\nお願い、やめて… 怖いから…\nだから、やめてよ…\n\n[Bridge]\n目を閉じて、くるっと背を向けて、\n何も見なかったフリするから、\n怒らないで… 許してよ…\n\n[Chorus]\nねぇ、顔が赤いよ?\nどうしたの? 熱があるの?\nそれとも怒ってるの?\nねぇ、言ってよ!\n\nどうしてそんな目で見るの?\n私、悪いことした?\n何か間違えたの?\nお願い、やめて… 怖いから…\nだから、やめてよ…\n\n[Bridge 2]\n待って、もし私が悪いなら、\nごめんなさいって言うから、\nアイスクリームあげるから、\nもう怒らないで?\n\nOoooh… 言ってよ!", - "audio_duration": 160, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.0282442569732666, - "diffusion": 12.104875326156616, - "latent2audio": 1.587641954421997 - }, - "actual_seeds": [ - 4028738662 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426092025_0_input_params.json b/examples/default/input_params/output_20250426092025_0_input_params.json deleted file mode 100644 index a0a8279a0fd74b9b1bc5133d22ee6bab103daf7b..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426092025_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "dark, death rock, metal, hardcore, electric guitar, powerful, bass, drums, 110 bpm, G major", - "lyrics": "[Verse]\nMy lovers betray me\nThe snake in my garden is hissing\nIn the air is the sweetness of roses\nAnd under my skin\nThere's a thorn\n\n[Verse 2]\nI should have known\nThat God sends his angel in shadows\nWith blood in his veins\nI watch the enemy\nGivin' me the hand of my savior\n\n[Chorus]\nAnd I can't love again\nWith the echo of your name in my head\nWith the demons in my bed\nWith the memories\nYour ghost\nI see it\n'Cause it comes to haunt me\nJust to taunt me\nIt comes to haunt me\nJust to taunt me\n\n[Verse 3]\nWith sugar and spice\nIt's hard to ignore the nostalgia\nWith the men on their knees\nAt the gates of my heart\nHow they beg me\n\n[Verse 4]\nThey say\n\"No one will ever love you\nThe way that I do\nNo one will ever touch you\nThe way that I do\"\n\n[Chorus]\nAnd I can't love again\nWith the echo of your name in my head\nWith the demons in my bed\nWith the memories\nYour ghost\nI see it\n'Cause it comes to haunt me\nJust to taunt me\nIt comes to haunt me\nJust to taunt me", - "audio_duration": 174.27997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 3.8372838497161865, - "diffusion": 13.039669275283813, - "latent2audio": 1.7923030853271484 - }, - "actual_seeds": [ - 4064916393 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426093007_0_input_params.json b/examples/default/input_params/output_20250426093007_0_input_params.json deleted file mode 100644 index 93d9d1571ed9801530b2e2c9233eb84a0f224c43..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426093007_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "aggressive, Heavy Riffs, Blast Beats, Satanic Black Metal", - "lyrics": "[verse]\nFloating through the galaxy on a midnight ride\nStars are dancing all around in cosmic tides\nFeel the pulse of space and time beneath our feet\nEvery beat a heartbeat in this endless suite\n\n[chorus]\nGalactic dreams under neon lights\nSailing through the velvet nights\nWe are echoes in a cosmic sea\nIn a universe where we are free\n\n[verse]\nPlanetary whispers in the sky tonight\nEvery constellation's got a secret sight\nDistant worlds and moons we have yet to see\nIn the void of space where we can just be\n\n[bridge]\nAsteroids and comets in a ballet they spin\nLost in the rhythm of where our dreams begin\nClose your eyes and let the synths take flight\nWe're voyagers on an electric night\n\n[verse]\nLet the piano keys unlock the stars above\nEvery chord a memory every note is love\nIn this synth symphony we find our grace\nDrifting forever in this boundless space\n\n[chorus]\nGalactic dreams under neon lights\nSailing through the velvet nights\nWe are echoes in a cosmic sea\nIn a universe where we are free", - "audio_duration": 181.99997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.025065898895263672, - "diffusion": 17.176705837249756, - "latent2audio": 1.8225171566009521 - }, - "actual_seeds": [ - 1132623236 - ] -} \ No newline at end of file diff --git a/examples/default/input_params/output_20250426093146_0_input_params.json b/examples/default/input_params/output_20250426093146_0_input_params.json deleted file mode 100644 index 94740bcd3ebc232d04cc08e77d6b3dbdeb54bc39..0000000000000000000000000000000000000000 --- a/examples/default/input_params/output_20250426093146_0_input_params.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "prompt": "r&b, soul, funk/soul", - "lyrics": "[verse]\nDancing through electric fires\nHeart is buzzing like live wires\nIn your arms I find desire\nFeel the beat as we get higher\n\n[chorus]\nElectric love in the night sky\nWe’re gonna soar baby you and I\nDrop the bass let the rhythm fly\nFeel the heat and don't ask why\n\n[verse]\nWhisper secrets that make me blush\nUnder the neon city hush\nYour touch gives me such a rush\nTurn it up we're feeling lush\n\n[chorus]\nElectric love in the night sky\nWe’re gonna soar baby you and I\nDrop the bass let the rhythm fly\nFeel the heat and don't ask why\n\n[bridge]\nThrough the lights and the smoky haze\nI see you in a thousand ways\nLove's a script and we’re the play\nTurn the page stay till we sway\n\n[chorus]\nElectric love in the night sky\nWe’re gonna soar baby you and I\nDrop the bass let the rhythm fly\nFeel the heat and don't ask why", - "audio_duration": 195.15997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": true, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.025553464889526367, - "diffusion": 18.250118494033813, - "latent2audio": 1.9400627613067627 - }, - "actual_seeds": [ - 2853131993 - ] -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512101839_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512101839_0_input_params.json deleted file mode 100644 index 85b2fdfab1c26662b397cab3f36520e9669983ef..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512101839_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora", - "task": "text2music", - "prompt": "Rap, adult, male, spoken word, singing, bright, energetic, clear", - "lyrics": "[Intro]\n他们说我来自阴影里\n说我的肤色是原罪的印记\n\n[Verse]\n眼神像刀子刮过 穿透我的皮肤\n带着审判和偏见 让我无处可逃处\n你没听过我的故事 没走过我的路\n凭什么就下一个判决 把我划出你的版图\n你说我威胁到你 抢走了你的机会\n可你可知我付出的 是你不敢想象的血泪\n被贴上标签 被区别对待\n呼吸都是错的 只因我生来就不一样态\n\n[Chorus]\n看不见的墙 把我阻隔在外面\n听不见的声音 屏蔽了我的呼唤\n他们制造偏见 他们散播谎言\n只因为我的存在 让他们觉得不安\n\n[Verse]\n每一次努力争取 都会被审视被放大\n每一个细微的错误 都变成攻击的靶\n他们选择性失明 看不见我的汗水\n只看见他们想看的 带着恶意的定位\n系统性的歧视 像一张无形的网\n把我困在原地 无法自由地翱翔\n他们在享受特权 却指责我的贫困\n嘲笑我的口音 我的名字 我的出身\n\n[Chorus]\n看不见的墙 把我阻隔在外面\n听不见的声音 屏蔽了我的呼唤\n他们制造偏见 他们散播谎言\n只因为我的存在 让他们觉得不安\n\n[Bridge]\n我不想寻求同情 只想被公平对待\n不想被定义被束缚 有选择自己未来的权利\n什么时候 才能放下心中的成见\n看到真正的我 而不是你脑海里的画面\n\n[Outro]\n画面... 不安...\n偏见... 歧视...\n什么时候能停止...", - "audio_duration": 134.64, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.3, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.032018184661865234, - "diffusion": 13.275121927261353, - "latent2audio": 1.291429042816162 - }, - "actual_seeds": [ - 3826585269 - ], - "retake_seeds": [ - 2907904223 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512101839_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512114703_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512114703_0_input_params.json deleted file mode 100644 index 8fb3c869c400e68ddb2908b2bf0f5fe0ba390801..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512114703_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora", - "task": "text2music", - "prompt": "Chorus Hook, Melodic Rap, Ambient Synth Pads, adult, rap, Very Fast, Storytelling, Chinese Rap, male, spoken word, bright, energetic, Melodic Flow, clear, clarity, 130 bpm", - "lyrics": "[Intro]\n舌 头 打 结 了... 快 念 快 念...\n\n[Verse 1]\n这 个 赌 鬼 蹲 在 柜 台 啃 着 苦 瓜 干 快 很 干\n赌 桌 堆 满 骨 牌 古 怪 股 票 和 五 块 钢 镚 儿 钢 镚\n他 甩 出 扑 克 牌 啪 啪 啪 拍 扁 螃 蟹 壳 哦 壳 扁\n又 摸 摸 麻 将 摸 出 幺 鸡 摸 出 发 财 摸 出 一 条 蛇 蛇 蛇\n庄 家 咳 嗽 咳 破 锣 嗓 子 喊 开 开 开 快 开 开\n赌 鬼 咕 嘟 咕 嘟 灌 咖 啡 灌 到 筷 子 戳 穿 碗 快 戳 穿\n空 气 里 飘 着 锅 巴 味 混 合 隔 夜 的 酸 奶 罐 哦 酸\n输 光 裤 带 还 想 翻 盘 翻 成 煎 饼 摊 老 板 快 翻 盘\n\n[Chorus]\n赌 鬼 赌 鬼 哦 赌 鬼 赌 鬼 快 很 快\n舌 头 打 结 着 念 这 段 哦 这 段 绕 口 令 牌\n若 念 错 一 字 就 罚 你 哦 罚 你 吞 十 斤 海 带\n赌 场 规 矩 就 是 绕 晕 你 哦 绕 晕 你 快 很 快\n\n[Verse 2]\n他 掏 出 铜 板 抠 出 口 袋 最 后 一 颗 快 很 颗\n庄 家 哗 啦 哗 啦 摇 骰 子 摇 出 三 点 又 三 点 哦 三 点\n赌 鬼 急 得 咬 牙 切 齿 咬 到 舌 头 打 蝴 蝶 结 快 打 结\n还 想 押 上 祖 传 的 拖 鞋 拖 把 铁 锅 和 半 包 盐 盐 盐\n突 然 警 笛 嘀 嘟 嘀 嘟 吓 得 他 钻 进 垃 圾 罐 哦 垃 圾\n警 察 咔 嚓 咔 嚓 拍 照 拍 到 他 头 顶 菠 菜 叶 快 拍 照\n最 后 赌 鬼 蹲 监 狱 天 天 背 这 首 绕 口 令 哦 背 不 完\n若 背 错 一 句 就 加 刑 十 年 再 加 十 年 快 加 刑\n\n[Outro]\n舌 头 打 结 了... 赌 鬼 哭 了 哦...\n这 首 歌... 绕 死 人 了 哦...", - "audio_duration": 186.59997916666666, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.7, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.03011012077331543, - "diffusion": 21.696259260177612, - "latent2audio": 1.7648537158966064 - }, - "actual_seeds": [ - 3776541388 - ], - "retake_seeds": [ - 4274500599 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512114703_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512115409_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512115409_0_input_params.json deleted file mode 100644 index ec829e892c875b95eb66d7dd87e8251f16739ab8..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512115409_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora", - "task": "text2music", - "prompt": "electronic, hip-hop, rap, synthesizer, drums, vocals, fast, energetic, modern, uplifting, young adult, male, spoken word, singing, bright, energetic, clear, 140 bpm, female", - "lyrics": "[Verse 1]\n红鲤鱼绿鲤鱼,驴在河里追鲤鱼,\n驴追鲤鱼鱼躲驴,气得驴子直喘气。\n扁担长板凳宽,扁担绑在板凳边,\n扁担要绑板凳不让绑,扁担偏要绑上板凳面!\n\n[Chorus]\n绕口令,练嘴皮,\n说快说慢别迟疑,\n红鲤鱼驴扁担板凳,\n一口气念完算你赢!\n\n[Verse 2]\n四是四十是十,十四是十四四十是四十,\n谁说四十是十四,舌头打结别放肆。\n黑化肥会挥发,灰化肥也发黑,\n化肥混一起,黑灰不分嘴发废!\n\n[Chorus]\n绕口令,练嘴皮,\n说快说慢别迟疑,\n四十十四化肥灰,\n念错罚你唱十回!\n\n[Bridge]\n坡上立着一只鹅,坡下流着一条河,\n鹅要过河河渡鹅,河要渡鹅鹅笑河——\n到底谁更啰嗦?!\n\n[Outro]\n嘴皮子功夫别小瞧,\n绕口令rap我最飙,\n下次挑战准备好,\n舌头打结别求饶!", - "audio_duration": 123.2, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.7, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.026150941848754883, - "diffusion": 12.212433099746704, - "latent2audio": 1.1857895851135254 - }, - "actual_seeds": [ - 1415752189 - ], - "retake_seeds": [ - 685932970 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512115409_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512120348_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512120348_0_input_params.json deleted file mode 100644 index fdd420e283ef53a4fb489c0e1c591b1de18e218f..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512120348_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora", - "task": "text2music", - "prompt": "singing, bright, slightly nasal, energetic, spoken word, young adult, male, rap music", - "lyrics": "[Intro]\nYo, check it—speed demon, lyrical heat, uh!\nRatatat like a drum when the beat bumps, uh!\n\n[Verse 1]\nRapatapa tap tap, flash like a snap,\nRap tap tap, I don’t chat, I clap clap clap!\nFingers snap, flow don’t slack, rapataptaptap,\nSpit it fast, hit the gas, rap tap tap rap!\n\n[Pre-Chorus]\nBoom-bap, zoom past, leave ’em flat,\nRap taptaprapataptaptap—where ya at?\n\n[Chorus]\nRapatapa tap tap, yeah, I go brrrr,\nRap tap tap, make the crowd stir!\nRapataptaptap, no lag, just spit,\nRap taptaprapataptaptap—I’m lit!\n\n[Verse 2]\nTongue-twist, quick wrist, rapatapa boom,\nTap tap rap, leave ya stuck like glue-gum!\nNo slow-mo, turbo, rapataptaptap,\nRap tap rap, yeah, I clap clap clap!\n\n[Outro]\nRapatapa—TAP! Mic drop—that’s that.", - "audio_duration": 60, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.018491744995117188, - "diffusion": 8.084580898284912, - "latent2audio": 0.5694489479064941 - }, - "actual_seeds": [ - 226581098 - ], - "retake_seeds": [ - 1603201617 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512120348_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512143242_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512143242_0_input_params.json deleted file mode 100644 index 561c80f4189a1f340dc684d06b04210dd9c82ffc..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512143242_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "ACE-Step/ACE-Step-v1-chinese-rap-LoRA", - "task": "text2music", - "prompt": "G-Funk, Hip Hop, Rap, Female Vocals, Melodic Rap, Summer, Laid-back Groove, Smooth Rhythm, Synthesizer Lead, Heavy Bassline, Groovy, West Coast Hip Hop", - "lyrics": "(Intro)\nOh yeah... \n\n(Verse 1)\n阳光下,沙滩排球场,一个身影跳跃\n小麦色,运动背心,闪耀活力四射\n她跳起扣杀,动作利落又巧妙\n汗水浸湿发梢,笑容比阳光更美好\n摇摆的节奏,是她的背景配乐\n每一次移动,都踩在鼓点上那么和谐\n我不由自主地停下脚步\n目光被她紧紧锁住\n\n(Chorus)\n沙滩排球女孩, 摇摆节拍下的身材\n无忧无虑的笑容,把我的心都填满\n想走上前去搭讪,嫌自己笨拙呆板\n这青春的气息,耀眼,灿烂!\n\n(Verse 3)\n她和队友击掌庆祝,笑声清脆悦耳\n拿起毛巾擦汗,不经意间瞥我一眼\n鼓起勇气走上前,假装问问时间\n她友好地回答,笑容灿烂没有敷衍\n聊了几句,发现彼此爱这摇摆音乐\n她眼中也闪过惊喜和亲切\n这共同点,让气氛变得融洽又热烈!\n夏天的故事,就这样开始了感觉真切!\n\n(Chorus)\n沙滩排球女孩, 摇摆节拍下的身材\n无忧无虑的笑容,把我的心都填满\n不再犹豫和等待,勇敢把脚步迈开\n这夏天的感觉,心跳,不断!", - "audio_duration": 93.93038, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.03020024299621582, - "diffusion": 9.942127704620361, - "latent2audio": 0.9470341205596924 - }, - "actual_seeds": [ - 3826585299 - ], - "retake_seeds": [ - 2519711205 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512143242_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512145057_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512145057_0_input_params.json deleted file mode 100644 index ca9b006347a30a264a08e5cbd1d4e1ee54930098..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512145057_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_80k", - "task": "text2music", - "prompt": "lyrical rap, young adult, female, rap flow, spoken word, ad-libs, bright, energetic, eat, Fast, Engaging, Energetic", - "lyrics": "[Intro]\n扁擔寬 板凳長 扁擔想綁在板凳上\n扁擔寬 板凳長 扁擔想綁在板凳上\n\n[Verse]\n倫敦 瑪莉蓮 買了 件 旗袍 送 媽媽\n莫斯科 的 夫司基 愛上 牛肉 麵 疙瘩\n各種 顏色 的 皮膚 各種 顏色 的 頭髮\n嘴裡念的 說的 開始 流行 中國話 (中國話)\n\n[Bridge]\n多少年 我們 苦練 英文 發音 和 文法 (yeah)\n這幾年 換他們 捲著 舌頭 學 平上去入 的 變化\n平平 仄仄 平平 仄\n好聰明 的 中國人 好優美 的 中國話\n\n[Verse]\n扁擔寬 板凳長 扁擔想綁在板凳上\n板凳不讓扁擔綁在板凳上 扁擔偏要綁在板凳上\n板凳偏偏不讓扁擔綁在那板凳上\n到底扁擔寬 還是板凳長?\n\n[Verse]\n哥哥弟弟坡前坐\n坡上臥著一隻鵝 坡下流著一條河\n哥哥說 寬寬的河 弟弟說 白白的鵝\n鵝要過河 河要渡鵝\n不知是那鵝過河 還是河渡鵝\n\n[Chorus]\n全世界都在學中國話\n孔夫子的話 越來越國際化\n全世界都在講中國話\n我們說的話 讓世界都認真聽話\n\n[Verse]\n紐約蘇珊娜開了間禪風 lounge bar\n柏林來的沃夫岡拿胡琴配著電吉他\n各種顏色的皮膚 各種顏色的頭髮\n嘴裡念的 說的 開始流行中國話 (中國話)\n\n[Bridge]\n多少年我們苦練英文發音和文法 (yeah)\n這幾年換他們捲著舌頭學平上去入的變化\n仄仄平平仄仄平\n好聰明的中國人 好優美的中國話\n\n[Verse]\n有個小孩叫小杜 上街打醋又買布\n買了布 打了醋 回頭看見鷹抓兔\n放下布 擱下醋 上前去追鷹和兔\n飛了鷹 跑了兔 灑了醋 濕了布\n\n[Verse]\n嘴說腿 腿說嘴\n嘴說腿 愛跑腿\n腿說嘴 愛賣嘴\n光動嘴 不動腿\n光動腿 不動嘴\n不如不長腿和嘴\n到底是那嘴說腿 還是腿說嘴?\n\n[Chorus]\n全世界都在學中國話\n孔夫子的話 越來越國際化\n全世界都在講中國話\n我們說的話 讓世界都認真聽話\n\n[outro]\n全世界都在學中國話 (在學中國話)\n孔夫子的話 越來越國際化\n全世界都在講中國話\n我們說的話 (讓他) 讓世界 (認真) 都認真聽話", - "audio_duration": 239.8355625, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.04363536834716797, - "diffusion": 18.706920385360718, - "latent2audio": 2.1645781993865967 - }, - "actual_seeds": [ - 2364345905 - ], - "retake_seeds": [ - 2100914041 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512145057_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512152217_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512152217_0_input_params.json deleted file mode 100644 index 8d40a78ef0e9c0b47e54a260aa9b0f644af450e5..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512152217_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_80k", - "task": "text2music", - "prompt": "articulate, spoken word, young adult, warm, rap music, male, clear, street, dark, rap flow, hardcore rap", - "lyrics": "[verse]\n球场 的 橡胶味 弥漫 隔壁 是 健身房\n场 边上 的 老教练 战术 有 三套\n教 交叉 运球 的 大叔 会 欧洲步 耍 背后 传\n硬 身板 对抗 最 擅长 还 会 急停跳 后仰 投\n他们 徒弟 我 习惯 从小 就 耳濡目染\n什么 胯下 跟 变向 我 都 玩 的 有模有样\n什么 招式 最 喜欢 转身 过 人 柔中 带 刚\n想要 去 纽约 街头 斗 洛克 公园 场\n\n[chorus]\n看什么 看什么\n变速 突破 心 自在\n看什么 看什么\n假动作 晃 开 防守 来\n看什么 看什么\n每日 训练 绑 沙袋\n空中拉杆 莫 奇怪\n唰唰 入袋\n\n[verse]\n一个 试探 步后 一记 左 变向 右 变向\n一句 挑衅 我 的 人 别 嚣张\n一再 重演 一颗 我 不 投 的 球\n悬在 篮筐 上 它 一直 在 摇晃\n\n[chorus]\n看什么 看什么\n我 激活 小宇宙 来\n看什么 看什么\n菜鸟 新人 的 名号\n看什么 看什么\n已 被 我 一球 击倒\n\n[chorus]\n快 秀出 指尖 转球 砰砰 啪嗒\n快 秀出 指尖 转球 砰砰 啪嗒\n篮球 之 人 切记 勇者 无惧\n是 谁 在 玩 花式 引爆 空气\n快 秀出 指尖 转球 砰砰 啪嗒\n快 秀出 指尖 转球 砰砰 啪嗒\n如果 我 有 滞空 逆天 补扣\n为人 热血 不怂 一生 傲骨 吼\n\n[verse]\n他们 徒弟 我 习惯 从小 就 耳濡目染\n什么 胯下 跟 变向 我 都 玩 的 有模有样\n什么 招式 最 喜欢 转身 过 人 柔中 带 刚\n想要 去 纽约 街头 斗 洛克 公园 场\n\n[outro]\n快 秀出 指尖 转球 砰\n快 秀出 指尖 转球 砰\n如果 我 有 滞空 吼\n为人 热血 不怂 一生 傲骨 吼\n快 秀出 指尖 转球 砰\n我 用 背传 助攻 吼\n压哨 的 三分 球", - "audio_duration": 239.8355625, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.05357813835144043, - "diffusion": 25.644447326660156, - "latent2audio": 2.1787476539611816 - }, - "actual_seeds": [ - 3246571430 - ], - "retake_seeds": [ - 1352325167 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512152217_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512153616_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512153616_0_input_params.json deleted file mode 100644 index a365f13a95ad6dcd90e254c067b5f7c44a62b8b7..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512153616_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_80k", - "task": "text2music", - "prompt": "articulate, spoken word, young adult, warm, rap music, male, clear, street, dark, rap flow, hardcore rap, fast", - "lyrics": "[verse]\n球场 的 橡胶味 弥漫 隔壁 是 健身房\n场 边上 的 老教练 战术 有 三套\n教 交叉 运球 的 大叔 会 欧洲步 耍 背后 传\n硬 身板 对抗 最 擅长 还 会 急停跳 后仰 投\n他们 徒弟 我 习惯 从小 就 耳濡目染\n什么 胯下 跟 变向 我 都 玩 的 有模有样\n什么 招式 最 喜欢 转身 过 人 柔中 带 刚\n想要 去 纽约 街头 斗 洛克 公园 场\n\n[chorus]\n看什么 看什么\n变速 突破 心 自在\n看什么 看什么\n假动作 晃 开 防守 来\n看什么 看什么\n每日 训练 绑 沙袋\n空中拉杆 莫 奇怪\n唰唰 入袋\n\n[verse]\n一个 试探 步后 一记 左 变向 右 变向\n一句 挑衅 我 的 人 别 嚣张\n一再 重演 一颗 我 不 投 的 球\n悬在 篮筐 上 它 一直 在 摇晃\n\n[chorus]\n看什么 看什么\n我 激活 小宇宙 来\n看什么 看什么\n菜鸟 新人 的 名号\n看什么 看什么\n已 被 我 一球 击倒\n\n[chorus]\n快 秀出 指尖 转球 砰砰 啪嗒\n快 秀出 指尖 转球 砰砰 啪嗒\n篮球 之 人 切记 勇者 无惧\n是 谁 在 玩 花式 引爆 空气\n快 秀出 指尖 转球 砰砰 啪嗒\n快 秀出 指尖 转球 砰砰 啪嗒\n如果 我 有 滞空 逆天 补扣\n为人 热血 不怂 一生 傲骨 吼\n\n[verse]\n他们 徒弟 我 习惯 从小 就 耳濡目染\n什么 胯下 跟 变向 我 都 玩 的 有模有样\n什么 招式 最 喜欢 转身 过 人 柔中 带 刚\n想要 去 纽约 街头 斗 洛克 公园 场\n\n[outro]\n快 秀出 指尖 转球 砰\n快 秀出 指尖 转球 砰\n如果 我 有 滞空 吼\n为人 热血 不怂 一生 傲骨 吼\n快 秀出 指尖 转球 砰\n我 用 背传 助攻 吼\n压哨 的 三分 球", - "audio_duration": 183.23, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.046170711517333984, - "diffusion": 14.21678113937378, - "latent2audio": 2.685957193374634 - }, - "actual_seeds": [ - 3072005931 - ], - "retake_seeds": [ - 562842491 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512153616_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512154907_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512154907_0_input_params.json deleted file mode 100644 index 87abdf84397939a5e8b3c06b97884808ce64a6ea..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512154907_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_80k", - "task": "text2music", - "prompt": "articulate, spoken word, young adult, rap music, female, clear, energetic, warm", - "lyrics": "[Intro]\n\"System booting... 语言 模型 loading...\"\n\n[Verse 1]\n硅谷 那个 coder 调试 neural network\n北京 的 极客 训练 A I 写 report\n不同 架构 的 chip 不同 算法 的 war\n屏幕上 跑的 全是 machine learning (learning)\n\n[Bridge]\n多少年 我们 chase 摩尔 定律 的 trend (yeah)\n这两年 换他们 study 中文 N L P\nConvolution L S T M\n好烧脑 的 backprop 好暴力 的 big data\n\n[Verse 2]\nPython 强 say加加 刚 Python 调用 C++ 的 A P I\nsay加加 嫌 Python 太 slow Python 笑 C++ 太 hardcore\nL L V M 默默 generate 中间 code\n到底 interpreter 还是 compiler 屌?\n\n[Verse 3]\nP M 和 engineer\n白板 画满 flow chart 服务器 闪着 red light\nP M 说 add feature engineer 说 no way\n需求 变更 code 重构\n不知 是 P M 太 fly 还是 deadline 太 high\n\n[Chorus]\n全世界 都在 train neural network\nTransformer 的 paper 越来越 难 go through\n全世界 都在 tune 超参数\n我们 写的 bug 让 G P U 都 say no\n\n[Verse 4]\n柏林 hackathon demo blockchain contract\n上海 的 dev 用 federated learning 破 data wall\n各种 语言 的 error 各种 框架 的 doc\nterminal 里 滚的 全是 dependency 冲突\n\n[Bridge]\n曾以为 English 才是 coding 的 language (yeah)\n直到见 G P T 用 文言文 generate 正则 expression\nGradient explode\n好硬核 的 prompt 好头秃 的 debug road\n\n[Verse 5]\n有个 bug 叫 quantum\n测试 环境 run perfect 上线 立即就 crash\n查 log 看 monitor 发现是 thread 不同步\n改 sync 加 lock 慢 deadlock 更难办\n量子 computer 也解不开 这 chaos chain\n\n[Verse 6]\n你说 996 我说 007\n你说 福报 我说 burnout\nProduct 要 agile Boss 要 KPI\nCode 要 elegant deadline 是 tomorrow\n不如 直接 script 自动 submit 离职信\n\n[Outro]\n\"Warning: 内存 leak...core dumping...\"\n全世界 都在 train neural network (neural network)\nLoss 还没 converge 天已经亮\n全世界 都在 tune 超参数\n我们 写的 code (让它) 让 world (reboot) 都 reboot 无效", - "audio_duration": 179.12, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.062120914459228516, - "diffusion": 13.499217987060547, - "latent2audio": 1.6430137157440186 - }, - "actual_seeds": [ - 1637990575 - ], - "retake_seeds": [ - 101283039 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512154907_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512161832_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512161832_0_input_params.json deleted file mode 100644 index 5fbaf1037f424eac015ef98423e1f6522d0deb45..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512161832_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_80k", - "task": "text2music", - "prompt": "articulate, spoken word, young adult, rap music, male, clear, energetic, warm, relaxed, breathy, night club, auto-tune, mumble rap, trap", - "lyrics": "[verse]\n这 这 谁 又 在 派 对 喝 多\n我 的 脑 袋\n像 被 驴 踢 过\n不 对 劲\n舌 头 打 结 不 会 说\n你 来 挑 战 我 就 跪\n开 局 直 接 崩 溃\n\n[chorus]\n就 咪 乱 咪 念 咪 错 咪\n嘴 咪 瓢 咪 成 咪 狗 咪\n脑 咪 袋 咪 像 咪 浆 咪 糊 咪\n跟 咪 着 咪 节 咪 奏 咪\n把 咪 歌 咪 词 咪 全 咪 忘 咪\n一 咪 张 咪 嘴 咪 就 咪 废 咪\n只 咪 剩 咪 下 咪 尴 咪 尬 咪 回 咪 忆\n草!\n\n[verse]\n错 错 错 错 了\n一 口 气 全 念 错\n错 错 错 错 了\n舌 头 打 结 甩 锅\n甩 甩 甩 甩 锅\n甩 锅 甩 锅\n拍 子 全 部 乱 套\n观 众 笑 到 吐 血\n\n[verse]\n你 的 歌 词 我 的 噩 梦\n唱 完 直 接 社 死\n调 跑 到 外 太 空\n观 众 表 情 裂 开\n你 笑 我 菜\n我 笑 你 不 懂\n这 叫 艺 术 表 演\n不 服 你 来!\n\n[verse]\n这 这 谁 又 在 派 对 丢 人\n我 的 世 界\n已 经 彻 底 崩 溃\n没 有 完 美\n只 有 翻 车 现 场\n以 及 观 众 的 嘲 讽\n\n[chorus]\n就 咪 乱 咪 念 咪 错 咪\n嘴 咪 瓢 咪 成 咪 狗 咪\n脑 咪 袋 咪 像 咪 浆 咪 糊 咪\n跟 咪 着 咪 节 咪 奏 咪\n把 咪 歌 咪 词 咪 全 咪 忘 咪\n一 咪 张 咪 嘴 咪 就 咪 废 咪\n只 咪 剩 咪 下 咪 尴 咪 尬 咪 回 咪 忆\n草!\n\n[verse]\n错 错 错 错 了\n一 口 气 全 念 错\n错 错 错 错 了\n舌 头 打 结 甩 锅\n甩 甩 甩 甩 锅\n甩 锅 甩 锅\n拍 子 全 部 乱 套\n观 众 笑 到 吐 血\n\n[verse]\n你 的 歌 词 我 的 噩 梦\n唱 完 直 接 社 死\n调 跑 到 外 太 空\n观 众 表 情 裂 开\n你 笑 我 菜\n我 笑 你 不 懂\n这 叫 艺 术 表 演\n不 服 你 来!", - "audio_duration": 169.12, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.04321885108947754, - "diffusion": 14.026689767837524, - "latent2audio": 1.5587565898895264 - }, - "actual_seeds": [ - 1905941472 - ], - "retake_seeds": [ - 3018484796 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512161832_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512164224_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512164224_0_input_params.json deleted file mode 100644 index 9cbc1f4c2840b081f1f701344a640529c6e9bd60..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512164224_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_80k", - "task": "text2music", - "prompt": "四川话, spoken word, male, Tempo - Fast, Elements - Chorus Hook, Subgenre-Satirical Hip Hop, Rap, Chinese-language music, energetic, slightly nasal, Instrument - Live Bass Guitar, adult, Vocals - Syncopated Flow, Genre - Hip-Hop, rapping, bright", - "lyrics": "[chorus]\n黑 墨镜 金 链子 越 低调 越 霸气\n玩 街机 泡 吧里 再 野的 场子 都 不 怯气\n上海 滩 老 江湖 外滩 钟声 敲 胜负\n陆家嘴 黄浦江 财路 宽 给 你 开 扇窗\n\n[verse]\n老子 在 弄堂 斜起 走 想 拦路 的 先 报 名号\n我 早看透 你们 手抖 脚软\n只敢 网上 吠 现实 怂成 猫\n看 你们 混的 真 可怜 整天 蹲在 网吧 蹭 烟\n钱 赚不到 架 不敢打 还 学人 摆 大哥 脸\n\n[verse]\n叫 我 沪上 老 克勒 不是 拉菲 我 不 碰杯\n规矩 我 懒得 讲 太多 钞票 直接 拍 你 脸上 飞\n老子 耐心 差 门槛 高 你 找茬 等于 自 寻 烦恼\n要么 跪 要么 爬 最后 警告 只 说 一 遭\n\n[chorus]\n黑 墨镜 金 链子 越 低调 越 霸气\n玩 街机 泡 吧里 再 野的 场子 都 不 怯气\n上海 滩 老 江湖 外滩 钟声 敲 胜负\n陆家嘴 黄浦江 财路 宽 给 你 开 扇窗\n\n[verse]\n古巴 雪茄 在 指间 绕 代表 魔都 格调 必须 顶\nOG 在 你 够不到 的 高度 My bro 永远 在 顶层 盯\nCheck my vibe 不靠 大 金劳 留声机 放 周璇 和 白光\n爹妈 太 宠你 养出 巨婴 症 早晚 社会 教你 做人 经\n\n[verse]\n玩 说唱 小囡 太 年轻 要 比 flow 先去 练 气功\n廿年 磨 枪 才 亮 锋芒 我 三十六 招 收 你 入 瓮\n老子 存在 就是 打假 标\n多少 人 眼红 又 不敢 挑\n键盘 侠 的 狠话 像 棉花 糖\n见 真人 秒变 Hello Kitty 叫\n\n[chorus]\n黑 墨镜 金 链子 越 低调 越 霸气\n玩 街机 泡 吧里 再 野的 场子 都 不 怯气\n上海 滩 老 江湖 外滩 钟声 敲 胜负\n陆家嘴 黄浦江 财路 宽 给 你 开 扇窗\n\n[chorus]\n黑 墨镜 金 链子 越 低调 越 霸气\n玩 街机 泡 吧里 再 野的 场子 都 不 怯气\n上海 滩 老 江湖 外滩 钟声 敲 胜负\n陆家嘴 黄浦江 财路 宽 给 你 开 扇窗", - "audio_duration": 135.92, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.038518667221069336, - "diffusion": 16.47420620918274, - "latent2audio": 2.5094873905181885 - }, - "actual_seeds": [ - 2159904788 - ], - "retake_seeds": [ - 2403013980 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512164224_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512171227_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512171227_0_input_params.json deleted file mode 100644 index c906cf47c1096301923763609b840f7bc39ee4ae..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512171227_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "ACE-Step/ACE-Step-v1-chinese-rap-LoRA", - "task": "text2music", - "prompt": "Rap, Chinese Rap, J-Pop, Anime, kawaii pop, EDM, Aggressive, Intense, Crisp Snare, Super Fast, Clear", - "lyrics": "(Intro)\nLet's drift away...\n\n(Verse 1)\n现实是灰色的格子间,重复的工作,枯燥的报表 \n敲打着键盘,眼神却放空,意识早已挣脱了肉体的镣铐\n飘向窗外,飞过拥挤的街道,穿过云层,到达想象的群岛\n那里色彩斑斓,形状奇异,逻辑失效,一切都随心所欲地飘摇\n迷幻的鼓点,像心跳的变奏,忽快忽慢,难以预料\n抽象的采样,扭曲的人声,构建一个超现实的音景环绕\n我变成一只鸟,一条鱼,一束光,自由地变换形态和奔跑\n在这白日梦里,我无所不能,摆脱了所有现实的烦恼, feeling the afterglow\n\n(Chorus)\n意识漫游,逃离乏味的轨道 \n迷幻嘻哈的节拍,是白日梦的引导 \n抽象的世界,逻辑被重新构造\nMind wandering free, where reality starts to fade slow\n\n(Verse 2)\n会议室里老板在讲话,声音模糊,像隔着水听不清道\n我的思绪,早已潜入深海,与发光的水母一起舞蹈\n或者飞向外太空,在星云间穿梭,探索未知的星球和轨道\n现实的规则,在这里被打破,物理定律也失去效劳\n白日梦是我的避难所,是精神的氧气罩\n在乏味的现实里,为我注入一点色彩和奇妙\n虽然短暂,虽然虚幻,但它让我能够喘息,重新把能量找到\n然后回到现实,继续扮演那个,循规蹈矩的角色,把梦藏好, keep the dream aglow\n\n(Chorus)\n意识漫游,逃离乏味的轨道\n迷幻嘻哈的节拍,是白日梦的引导\n抽象的世界,逻辑被重新构造\nMind wandering free, where reality starts to fade slow\n", - "audio_duration": 153.7148, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.04823446273803711, - "diffusion": 13.158645629882812, - "latent2audio": 1.493880033493042 - }, - "actual_seeds": [ - 2945962357 - ], - "retake_seeds": [ - 2676242300 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0.7, - "guidance_scale_lyric": 1.5, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512171227_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512171809_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512171809_0_input_params.json deleted file mode 100644 index 89deb563e9f5da2879527040ecf8d1d52a1d95a9..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512171809_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora", - "task": "text2music", - "prompt": "J-Pop, Anime, kawaii future bass, Femal vocals, EDM, Boombap, Aggressive, Intense, Crisp Snare, Super Fast, Rap", - "lyrics": "[Intro]\nYo, 这是来自深渊的怒吼\n\n[Verse]\n指尖飞快刷新,屏幕又亮起\n渴望那点赞,像致命的氧气\n精心修饰的脸庞,完美到诡异\n背后隐藏的疲惫,谁又会在意\n光鲜亮丽的橱窗,贩卖着焦虑\n每个人都在表演,戴着虚伪面具\n比较的游戏,让人逐渐窒息\n迷失在数据洪流,找不到自己\n\n[Chorus]\n这流量的时代,真假早已分不清\n盲目追随潮流,丢掉了初心\n为了那点虚荣,灵魂在沉沦\n看不见的锁链,捆绑每个灵魂\n\n[Verse]\n滤镜下的生活,美得不切实际\n营造虚假繁荣,掩盖内心空虚\n他人的光环下,显得自己多余\n嫉妒和自卑,交织成悲剧\n\n[Chorus]\n朋友圈里炫耀,现实中却叹气\n刷着别人的故事,忘记了呼吸\n算法推荐着你,想看的一切东西\n不知不觉间,你已不再是你\n他们说这是进步,我看是种病\n精神鸦片侵蚀,慢慢要了你的命\n\n[Bridge]\n屏幕亮了又暗,一天又过去\n究竟得到了什么,还是失去了自己\n那真实的连接,在何处寻觅\n困在这迷宫里,找不到出口的轨迹\n\n[Outro]\n我想挣脱,我想呼吸\n这虚拟的繁华,让我喘不过气\n谁能告诉我,这到底有什么意义\n一切都像泡沫,一触就破裂没余地", - "audio_duration": 119.44348, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.04764962196350098, - "diffusion": 10.94297981262207, - "latent2audio": 1.1815783977508545 - }, - "actual_seeds": [ - 3826585273 - ], - "retake_seeds": [ - 2527594022 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512171809_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250512172941_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250512172941_0_input_params.json deleted file mode 100644 index 965117978ce08ae51504141bd7c0671deed731dc..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250512172941_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_80k", - "task": "text2music", - "prompt": "Hip Hop, Hi-hat Rolls, spoken word, Melodic Flow, articulate, Female Rap, 120 BPM, clear, warm, female, melodic Rap, adult, super fast", - "lyrics": "[Verse 1]\n打南边来了个喇嘛,手里提拉着五斤鳎目,\n打北边来了个哑巴,腰里别着个喇叭。\n喇嘛想换哑巴的喇叭,哑巴摇头不说话,\n鳎目一甩像道闪电,喇叭一响震天涯!\n\n[Chorus]\n丁丁当当,乒乓乓乓,\n话赶话,舌绕梁,\n东边的钉,西边的墙,\n绕不完的弯,唱不完的慌!\n\n[Verse 2]\n墙上一根钉,钉下绳摇晃,\n绳吊着瓶,瓶碰碎了光。\n灯骂瓶,瓶怪绳,绳怨钉,\n稀里哗啦,一场荒唐!\n\n[Chorus]\n丁丁当当,乒乓乓乓,\n话赶话,舌绕梁,\n东边的钉,西边的墙,\n绕不完的弯,唱不完的慌!\n\n[Verse 3]\n板凳宽,扁担长,\n一个偏要绑,一个偏不让。\n青龙洞里龙翻身,\n千年大梦变稻香!\n\n[Bridge]\n麻婆婆的狗,咬破麻叉口,\n麻线穿针眼,补丁也风流。\n左一句,右一句,\n舌头打结心自由!\n\n[Chorus]\n丁丁当当,乒乓乓乓,\n话赶话,舌绕梁,\n东边的钉,西边的墙,\n绕不完的弯,唱不完的慌!", - "audio_duration": 214.12, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.031190156936645508, - "diffusion": 20.130417823791504, - "latent2audio": 1.9650826454162598 - }, - "actual_seeds": [ - 1946426111 - ], - "retake_seeds": [ - 331383387 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250512172941_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250513044511_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250513044511_0_input_params.json deleted file mode 100644 index 66d0fc50daf3f5e6915b8a6e632b2bf86f9ec865..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250513044511_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_100k", - "task": "text2music", - "prompt": "东北话, spoken word, male, Tempo - Fast, Elements - Chorus Hook, Subgenre-Satirical Hip Hop, Rap, Chinese-language music, energetic, slightly nasal, Instrument - Live Bass Guitar, adult, Vocals - Syncopated Flow, Genre - Hip-Hop, rapping, bright", - "lyrics": "[verse]\n挣着 憋屈的 工资 还得 装乐呵\n猫着 怂样儿 还搁 朋友圈 嘚瑟\n扛着 傻逼的 指标 没人 搭把手\n这儿 不是 托儿所 少整 那出儿 哭唧尿嚎\n\n俺们 就像 一条条 老板的 裤衩子\n陪着 笑脸 接他 每一回 突突\n哎呦 老板 今儿个 穿我呗\n他 撅个腚 眼角 瞟你 那熊样\n\n[chorus]\n他们 骂我 打工仔 太多人 没睡醒\n寻思 抠搜 老板 一天天 穷折腾\n不想 俺的 人生 烂在 这嘎达\n不想 俺的 将来 折在 这破棚\n\n老子 不想 上班 老子 是外星人\n你都 把俺 骂急眼了 俺还 这么淡定\n现实 才是 梦 啥时候 能醒啊\n那 糟践人的 答案 在西北风 里飘\n\n[verse]\n瞅见 二愣子 同事 给老板 舔腚沟子\n瞅见 浪蹄子 女同事 在老板 胯骨轴 扭搭\n瞅见 白瞎的 光阴 耗在 没亮儿的 道儿\n瞅见 公交车上 一帮 僵尸 吐酸水\n\n瞅见 俺的 命 定在 苦逼的 坑里\n瞅见 俺的 爱情 被轮了 成了 老处女\n瞅见 好事儿 全归 高富帅\n还有 那些 臭不要脸 扭腚的 货色\n\n[chorus](重复)\n他们 骂我 打工仔 太多人 没睡醒...\n\n[bridge]\n加班 没补助 俺认了\n欠薪 揍员工 把俺 当牲口\n去你妈 的小姘头\n\n[verse]\n破逼 管理制度 净整 娱乐八卦\n撸管式 管理 也就 你自己 嗨\n出点儿 屁事儿 就往 下属 脑瓜子 扣\n挣俩 钢镚儿 立马 牛逼 不分 公母\n\n你挖个 大坑 把俺们 往里 踹\n说这 叫梦想 你当年 多能耐\n俺们 就当 听传销 洗脑课\n可怜 连骗人 你都 就会 这一套\n\n[outro]\n老子 不想 上班\n老子 不想 上班\n老子 不想 上班", - "audio_duration": 135.92, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.06204533576965332, - "diffusion": 35.75483560562134, - "latent2audio": 1.5193355083465576 - }, - "actual_seeds": [ - 4176354214 - ], - "retake_seeds": [ - 601086915 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250513044511_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250513050200_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250513050200_0_input_params.json deleted file mode 100644 index 99382880615d59ac90b14ff2145915b192ac8c0b..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250513050200_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_100k", - "task": "text2music", - "prompt": "Rap, J-Pop, Anime, kawaii pop, EDM, Aggressive, Intense, Crisp Snare, Super Fast, Clear", - "lyrics": "[Intro]\nNya.\n\n[Verse]\n我 在 五 点 二 十 早 起,十 三 点 十 四 弹 会儿 琴\n习 惯 了 坐 班,习惯了 隔夜 的 剩 饭,\n习 惯 了 没有 你\n\n[Verse]\n怕 你 想 不 开,拦 在 你 的 面 前\n那 时 候 摔 得 差 点 住 院\n东 京 的 春 天 莺 莺 燕 燕\n我 说 想 不 想 来 跟 我 玩 音乐\n\n[Verse]\n带 着 我 的 朋 友 守 在 你 的 门 口\n弹 着 我 的 钢 琴 当 伴 奏\n等 你 放 学 后,陪 你 K T V\n端 着 我 的 红 茶 跟 你 碰 杯\n\n[Pre-Chorus]\n忽然间现实淹没了远方\n万家灯火,盖住月光\n奔走,忍受,变成了人偶\n别再对我伸出你的 双 手,会 受 伤\n\n[Chorus]\n明明都向前走,方向却渐渐不同\n时间让你我越走越近,却越来越陌生\n春 天 在 滂 沱 的 大 雨 里 飘 落\n得 了 心 太 高 脸 太 薄 的病\n\n[Bridge]\n我越难过,春日影越顶\n眼泪晃得我看不清\n埋葬了懦弱还有矫情\n却还是会在半夜摸眼睛\n\n青春期大部分时间在工 作\n用微笑换来余额几个零\n戴上了面具也明白了生活\n拼的是数字和脸更是命\n\n[Verse]\n我在五点二十早起,十三点十四弹会琴\n早上要做饭,回家时满地的瓶罐\n\n师 徒 二 人 站 在 我 的 面 前\n台 词 很 熟 练,照 着 就 念\n\n背 后 的 小 睦 扭 扭 捏 捏\n我 说 我 还 有 点 事 要 不 改 天 见\n\n然 后 你 的 双手 握 住 我 的 袖 口\n开 始 哭 着 求 我 不 要 走\n\n[Verse]\n我在下班后,忙活柴米油\n你和你的姐妹住着高楼\n\n苦 来 兮 苦,早 就 没 了\n现 实 扬 鞭,赶 着 我 向 前\n没有时间跟你分辨什么对与错\n\n[Bridge]\n没有什么对错,没有罪过\n谁不曾天真,是我太早看破\n生活一片狼藉,却又不想放弃\n一 边 聚 光 灯 下 绽 放,一 边 坠 落\n故作坚强,筑起心的墙\n越是委屈的伤口,越要藏\nLet it all out, it’s all right\n\n[Outro]\n俺 是 东 京 嘞,东 京 打 工 妹\n\n从虎之门带你转到浅草\n再从新宿转到竹桥\n\n俺 是 东 京 嘞,东 京 打 工 妹\n\n带 你 转 羽田 成田 蒲田 神田\n做 你 嘞 小 甜 甜!\n\n俺 是 东 京 嘞,东 京 打 工 妹\n带 你 转 赤 坂,带 你 转 霞 关\n恁 咋 不 早 说,今 天 不 管 饭\n", - "audio_duration": 147.62212, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.5, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.052134037017822266, - "diffusion": 17.909283876419067, - "latent2audio": 1.4904146194458008 - }, - "actual_seeds": [ - 2945962357 - ], - "retake_seeds": [ - 2252292438 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0.7, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250513050200_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250513055451_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250513055451_0_input_params.json deleted file mode 100644 index 7d66bcaffd25d5925409c93ef2065e18e3c79397..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250513055451_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_100k", - "task": "text2music", - "prompt": "Rap, adult, male, spoken word, rapping, clear, warm, articulate, Lo-Fi Hip Hop, 100-120 BPM, Keyboard Chords, Male Rap, Lazy Rhythm, Melancholy, Rap", - "lyrics": "[Intro]\n夜色 很 淡 像 褪色 的 照片 \n但 记忆 却 像 刀锋 一样 锐利 \n\n[Verse 1]\n你 说过 的 甜言蜜语 现在 听来 像 最 恶毒 的 咒骂 \n你 刺进 我 心里 的 刀 现在 还 在 滴血 未 干 哪 \n慵懒 的 旋律 像 我 的 脚步 拖着 沉重 的 躯壳 \n脑海 里 循环 播放 那 画面 快 把 我 逼疯 了 \n键盘 和弦 低沉 又 忧伤 弹奏 着 我 的 绝望 \n我 曾经 的 信任 像 玻璃 一样 被 你 狠狠 地 摔 在 地上 \n不想 振作 不想 原谅 只 想 让 这 一切 都 停止 \n可 心底 有 个 声音 嘶吼 着 要 你 付出 该 有 的 代价 \n\n[Chorus]\n背叛 像 毒药 渗透 我 的 血液 \n复仇 的 火焰 在 我 眼中 燃起 \n哪怕 遍体鳞伤 哪怕 万劫不复 \n我 也 要 亲手 撕碎 你 的 幸福 \n这 是 我 的 哀歌 也 是 我 的 战书 \n键盘 的 音符 每 一下 都 带着 恨意 和 痛苦 \n\n[Verse 2]\n曾经 的 兄弟 现在 面目全非 像 个 陌生人 \n你 的 自私 像 癌细胞 一点点 吞噬 我 的 纯真 \n我 学着 你 的 样子 把 心 锁 起来 不再 轻易 相信 \n让 懒散 的 节奏 包裹 我 给 自己 一点 喘息 \n键盘 的 音色 变得 更加 阴冷 像 秋天 的 雨滴 \n冲刷 掉 所有 温情 只 剩下 彻骨 的 寒意 \n我 不会 大喊大叫 只是 默默 地 计划 \n每 一步 都 走向 让 你 后悔 的 那 一 刹那 \n\n[Chorus]\n背叛 像 毒药 渗透 我 的 血液 \n复仇 的 火焰 在 我 眼中 燃起 \n哪怕 遍体鳞伤 哪怕 万劫不复 \n我 也 要 亲手 撕碎 你 的 幸福 \n这 是 我 的 哀歌 也 是 我 的 战书 \n键盘 的 音符 每 一下 都 带着 恨意 和 痛苦 \n\n[Bridge]\n也许 复仇 不能 带来 平静 \n也许 只 会 让 我 更 堕落 \n但 如果 不 这样 做 \n我 连 活下去 的 勇气 都 没有 \n\n[Outro]\n复仇 复仇 复仇 \n直到 最后 一刻 \n懒散 地 复仇 着 ", - "audio_duration": 202.64, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.65, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 0.036400794982910156, - "diffusion": 23.055809259414673, - "latent2audio": 1.8787360191345215 - }, - "actual_seeds": [ - 3900061002 - ], - "retake_seeds": [ - 3037373819 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250513055451_0.wav" -} \ No newline at end of file diff --git a/examples/zh_rap_lora/input_params/output_20250513060150_0_input_params.json b/examples/zh_rap_lora/input_params/output_20250513060150_0_input_params.json deleted file mode 100644 index a881dc97dee7dbd238ce72c471d706fc166be1a8..0000000000000000000000000000000000000000 --- a/examples/zh_rap_lora/input_params/output_20250513060150_0_input_params.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lora_name_or_path": "/root/sag_train/data/ace_step_v1_chinese_rap_lora_100k", - "task": "text2music", - "prompt": "Orchestra, Symphony, Sonata, Opera, Concerto, Rap, Beat, DJ, MC, StreetCulture", - "lyrics": "[verse1]\n羊皮卷轴 墨香飘 莫扎特 熬 安魂曲 通宵 \n和弦齿轮 咔哒转 比 瑞士 手表 更 精密 律动 \n八轨磁带 玩叠叠乐 披头士 炸 录音棚 天花板 \nAI 卷起 新风暴 像 灭霸 打响指 般 简单 \n\n[chorus]\n琴弦 到 代码 进化论 狂飙(skr) \n象牙塔 被 鼠标 点爆 像 泡泡(boom) \n灵感 加 算法 等于 王炸 大招 \n人类 心跳 才是 终极 混音 调料 \n\n[verse2]\n春之祭 召唤 百人 乐团 才够 燥 \n合成器 极客 玩电焊 焊出 赛博 神庙 \nDAW 解放 双手 钢琴卷帘 变 乐高 \n音色库 开挂 像 吃 金币 的 马里奥 \n\nAI 拆解 爵士乐 黑话 像 庖丁 解牛 \nCityPop 复古 滤镜 直接 参数 调油 \n神经网络 偷师 贝多芬 半夜 翻墙头 \n音乐 基因库 被 改写成 超频 万花筒 \n\n[chorus] \n琴弦 到 代码 进化论 狂飙(skr) \n象牙塔 被 鼠标 点爆 像 泡泡(boom) \n灵感 加 算法 等于 王炸 大招 \n人类 心跳 才是 终极 混音 调料 \n\n[verse3] \n电子琴 被 吐槽 塑料 味 超标 \n卧室 制作人 用 鼠标 单挑 整个 乐团 编制 \nAI 伴奏 刚上线 就被 键盘侠 集火 \n却 忘了 电吉他 曾被 说 是 魔鬼 的 副歌 \n\n现在 我 指尖 蹦迪 在 数据 炼丹炉 \n提示词 召唤 莫扎特 跨次元 碰杯 珍珠奶茶 \n当 比特 海洋 淹没 所有 物理 琴柱 \n最后 的 音轨 永远 连着 心脏 的 跳针 \n\n[bridge] \n鹅毛笔 蘸着 银河 当 墨汁(绝了) \n音浪 在 元宇宙 开 分店(疯了) \n技术 迷雾 散成 像素 烟花 \n而 我们 始终 带着 老派 的 心跳 混搭 \n\n[chorus] \n琴弦 到 代码 进化论 狂飙(skr) \n象牙塔 被 鼠标 点爆 像 泡泡(boom) \n灵感 加 算法 等于 王炸 大招 \n人类 心跳 才是 终极 混音 调料 \n\n[outro] \n从 蒸汽 到 硅基 浪潮 我 冲浪(yo) \n用 脑洞 接住 每个 技术 暴击(叮) \n当 所有 设备 没电 的 凌晨 三点钟 \n最 原始 的 旋律 在 胸腔 敲击 成 龙卷风 ", - "audio_duration": 172.64, - "infer_step": 60, - "guidance_scale": 15, - "scheduler_type": "euler", - "cfg_type": "apg", - "omega_scale": 10, - "guidance_interval": 0.65, - "guidance_interval_decay": 0, - "min_guidance_scale": 3, - "use_erg_tag": true, - "use_erg_lyric": false, - "use_erg_diffusion": true, - "oss_steps": [], - "timecosts": { - "preprocess": 3.648996353149414, - "diffusion": 16.44967818260193, - "latent2audio": 1.614703893661499 - }, - "actual_seeds": [ - 1198023141 - ], - "retake_seeds": [ - 3389016134 - ], - "retake_variance": 0.5, - "guidance_scale_text": 0, - "guidance_scale_lyric": 0, - "repaint_start": 0, - "repaint_end": 0, - "edit_n_min": 0.0, - "edit_n_max": 1.0, - "edit_n_avg": 1, - "src_audio_path": null, - "edit_target_prompt": null, - "edit_target_lyrics": null, - "audio2audio_enable": false, - "ref_audio_strength": 0.5, - "ref_audio_input": null, - "audio_path": "./outputs/output_20250513060150_0.wav" -} \ No newline at end of file diff --git a/language_segmentation/LangSegment.py b/language_segmentation/LangSegment.py deleted file mode 100644 index 033a4d32527178d79576d508380d13cc07cef676..0000000000000000000000000000000000000000 --- a/language_segmentation/LangSegment.py +++ /dev/null @@ -1,866 +0,0 @@ -""" -This file bundles language identification functions. - -Modifications (fork): Copyright (c) 2021, Adrien Barbaresi. - -Original code: Copyright (c) 2011 Marco Lui . -Based on research by Marco Lui and Tim Baldwin. - -See LICENSE file for more info. -https://github.com/adbar/py3langid - -Projects: -https://github.com/juntaosun/LangSegment -""" - -import os -import re -import sys -import numpy as np -from collections import Counter -from collections import defaultdict - -# import langid -# import py3langid as langid -# pip install py3langid==0.2.2 - -# 启用语言预测概率归一化,概率预测的分数。因此,实现重新规范化 产生 0-1 范围内的输出。 -# langid disables probability normalization by default. For command-line usages of , it can be enabled by passing the flag. -# For probability normalization in library use, the user must instantiate their own . An example of such usage is as follows: -from py3langid.langid import LanguageIdentifier, MODEL_FILE - -# Digital processing -try:from .utils.num import num2str -except ImportError: - try:from utils.num import num2str - except ImportError as e: - raise e - -# ----------------------------------- -# 更新日志:新版本分词更加精准。 -# Changelog: The new version of the word segmentation is more accurate. -# チェンジログ:新しいバージョンの単語セグメンテーションはより正確です。 -# Changelog: 분할이라는 단어의 새로운 버전이 더 정확합니다. -# ----------------------------------- - - -# Word segmentation function: -# automatically identify and split the words (Chinese/English/Japanese/Korean) in the article or sentence according to different languages, -# making it more suitable for TTS processing. -# This code is designed for front-end text multi-lingual mixed annotation distinction, multi-language mixed training and inference of various TTS projects. -# This processing result is mainly for (Chinese = zh, Japanese = ja, English = en, Korean = ko), and can actually support up to 97 different language mixing processing. - -#=========================================================================================================== -#分かち書き機能:文章や文章の中の例えば(中国語/英語/日本語/韓国語)を、異なる言語で自動的に認識して分割し、TTS処理により適したものにします。 -#このコードは、さまざまなTTSプロジェクトのフロントエンドテキストの多言語混合注釈区別、多言語混合トレーニング、および推論のために特別に作成されています。 -#=========================================================================================================== -#(1)自動分詞:「韓国語では何を読むのですかあなたの体育の先生は誰ですか?今回の発表会では、iPhone 15シリーズの4機種が登場しました」 -#(2)手动分词:“あなたの名前は佐々木ですか?ですか?” -#この処理結果は主に(中国語=ja、日本語=ja、英語=en、韓国語=ko)を対象としており、実際には最大97の異なる言語の混合処理をサポートできます。 -#=========================================================================================================== - -#=========================================================================================================== -# 단어 분할 기능: 기사 또는 문장에서 단어(중국어/영어/일본어/한국어)를 다른 언어에 따라 자동으로 식별하고 분할하여 TTS 처리에 더 적합합니다. -# 이 코드는 프런트 엔드 텍스트 다국어 혼합 주석 분화, 다국어 혼합 교육 및 다양한 TTS 프로젝트의 추론을 위해 설계되었습니다. -#=========================================================================================================== -# (1) 자동 단어 분할: "한국어로 무엇을 읽습니까? 스포츠 씨? 이 컨퍼런스는 4개의 iPhone 15 시리즈 모델을 제공합니다." -# (2) 수동 참여: "이름이 Saki입니까? ?" -# 이 처리 결과는 주로 (중국어 = zh, 일본어 = ja, 영어 = en, 한국어 = ko)를 위한 것이며 실제로 혼합 처리를 위해 최대 97개의 언어를 지원합니다. -#=========================================================================================================== - -# =========================================================================================================== -# 分词功能:将文章或句子里的例如(中/英/日/韩),按不同语言自动识别并拆分,让它更适合TTS处理。 -# 本代码专为各种 TTS 项目的前端文本多语种混合标注区分,多语言混合训练和推理而编写。 -# =========================================================================================================== -# (1)自动分词:“韩语中的오빠读什么呢?あなたの体育の先生は誰ですか? 此次发布会带来了四款iPhone 15系列机型” -# (2)手动分词:“你的名字叫佐々木?吗?” -# 本处理结果主要针对(中文=zh , 日文=ja , 英文=en , 韩语=ko), 实际上可支持多达 97 种不同的语言混合处理。 -# =========================================================================================================== - - -# 手动分词标签规范:<语言标签>文本内容 -# 수동 단어 분할 태그 사양: <언어 태그> 텍스트 내용 -# Manual word segmentation tag specification: text content -# 手動分詞タグ仕様:<言語タグ>テキスト内容 -# =========================================================================================================== -# For manual word segmentation, labels need to appear in pairs, such as: -# 如需手动分词,标签需要成对出现,例如:“佐々木” 或者 “佐々木” -# 错误示范:“你的名字叫佐々木。” 此句子中出现的单个标签将被忽略,不会处理。 -# Error demonstration: "Your name is 佐々木。" Single tags that appear in this sentence will be ignored and will not be processed. -# =========================================================================================================== - - -# =========================================================================================================== -# 语音合成标记语言 SSML , 这里只支持它的标签(非 XML)Speech Synthesis Markup Language SSML, only its tags are supported here (not XML) -# 想支持更多的 SSML 标签?欢迎 PR! Want to support more SSML tags? PRs are welcome! -# 说明:除了中文以外,它也可改造成支持多语种 SSML ,不仅仅是中文。 -# Note: In addition to Chinese, it can also be modified to support multi-language SSML, not just Chinese. -# =========================================================================================================== -# 中文实现:Chinese implementation: -# 【SSML】=中文大写数字读法(单字) -# 【SSML】=数字转成中文电话号码大写汉字(单字) -# 【SSML】=按金额发音。 -# 【SSML】=按日期发音。支持 2024年08月24, 2024/8/24, 2024-08, 08-24, 24 等输入。 -# =========================================================================================================== -class LangSSML: - - def __init__(self): - # 纯数字 - self._zh_numerals_number = { - '0': '零', - '1': '一', - '2': '二', - '3': '三', - '4': '四', - '5': '五', - '6': '六', - '7': '七', - '8': '八', - '9': '九' - } - - # 将2024/8/24, 2024-08, 08-24, 24 标准化“年月日” - # Standardize 2024/8/24, 2024-08, 08-24, 24 to "year-month-day" - def _format_chinese_data(self, date_str:str): - # 处理日期格式 - input_date = date_str - if date_str is None or date_str.strip() == "":return "" - date_str = re.sub(r"[\/\._|年|月]","-",date_str) - date_str = re.sub(r"日",r"",date_str) - date_arrs = date_str.split(' ') - if len(date_arrs) == 1 and ":" in date_arrs[0]: - time_str = date_arrs[0] - date_arrs = [] - else: - time_str = date_arrs[1] if len(date_arrs) >=2 else "" - def nonZero(num,cn,func=None): - if func is not None:num=func(num) - return f"{num}{cn}" if num is not None and num != "" and num != "0" else "" - f_number = self.to_chinese_number - f_currency = self.to_chinese_currency - # year, month, day - year_month_day = "" - if len(date_arrs) > 0: - year, month, day = "","","" - parts = date_arrs[0].split('-') - if len(parts) == 3: # 格式为 YYYY-MM-DD - year, month, day = parts - elif len(parts) == 2: # 格式为 MM-DD 或 YYYY-MM - if len(parts[0]) == 4: # 年-月 - year, month = parts - else:month, day = parts # 月-日 - elif len(parts[0]) > 0: # 仅有月-日或年 - if len(parts[0]) == 4: - year = parts[0] - else:day = parts[0] - year,month,day = nonZero(year,"年",f_number),nonZero(month,"月",f_currency),nonZero(day,"日",f_currency) - year_month_day = re.sub(r"([年|月|日])+",r"\1",f"{year}{month}{day}") - # hours, minutes, seconds - time_str = re.sub(r"[\/\.\-:_]",":",time_str) - time_arrs = time_str.split(":") - hours, minutes, seconds = "","","" - if len(time_arrs) == 3: # H/M/S - hours, minutes, seconds = time_arrs - elif len(time_arrs) == 2:# H/M - hours, minutes = time_arrs - elif len(time_arrs[0]) > 0:hours = f'{time_arrs[0]}点' # H - if len(time_arrs) > 1: - hours, minutes, seconds = nonZero(hours,"点",f_currency),nonZero(minutes,"分",f_currency),nonZero(seconds,"秒",f_currency) - hours_minutes_seconds = re.sub(r"([点|分|秒])+",r"\1",f"{hours}{minutes}{seconds}") - output_date = f"{year_month_day}{hours_minutes_seconds}" - return output_date - - # 【SSML】number=中文大写数字读法(单字) - # Chinese Numbers(single word) - def to_chinese_number(self, num:str): - pattern = r'(\d+)' - zh_numerals = self._zh_numerals_number - arrs = re.split(pattern, num) - output = "" - for item in arrs: - if re.match(pattern,item): - output += ''.join(zh_numerals[digit] if digit in zh_numerals else "" for digit in str(item)) - else:output += item - output = output.replace(".","点") - return output - - # 【SSML】telephone=数字转成中文电话号码大写汉字(单字) - # Convert numbers to Chinese phone numbers in uppercase Chinese characters(single word) - def to_chinese_telephone(self, num:str): - output = self.to_chinese_number(num.replace("+86","")) # zh +86 - output = output.replace("一","幺") - return output - - # 【SSML】currency=按金额发音。 - # Digital processing from GPT_SoVITS num.py (thanks) - def to_chinese_currency(self, num:str): - pattern = r'(\d+)' - arrs = re.split(pattern, num) - output = "" - for item in arrs: - if re.match(pattern,item): - output += num2str(item) - else:output += item - output = output.replace(".","点") - return output - - # 【SSML】date=按日期发音。支持 2024年08月24, 2024/8/24, 2024-08, 08-24, 24 等输入。 - def to_chinese_date(self, num:str): - chinese_date = self._format_chinese_data(num) - return chinese_date - - -class LangSegment: - - def __init__(self): - - self.langid = LanguageIdentifier.from_pickled_model(MODEL_FILE, norm_probs=True) - - self._text_cache = None - self._text_lasts = None - self._text_langs = None - self._lang_count = None - self._lang_eos = None - - # 可自定义语言匹配标签:カスタマイズ可能な言語対応タグ:사용자 지정 가능한 언어 일치 태그: - # Customizable language matching tags: These are supported,이 표현들은 모두 지지합니다 - # 你好 , 佐々木 , OK , 오빠 这些写法均支持 - self.SYMBOLS_PATTERN = r'(<([a-zA-Z|-]*)>(.*?)<\/*[a-zA-Z|-]*>)' - - # 语言过滤组功能, 可以指定保留语言。不在过滤组中的语言将被清除。您可随心搭配TTS语音合成所支持的语言。 - # 언어 필터 그룹 기능을 사용하면 예약된 언어를 지정할 수 있습니다. 필터 그룹에 없는 언어는 지워집니다. TTS 텍스트에서 지원하는 언어를 원하는 대로 일치시킬 수 있습니다. - # 言語フィルターグループ機能では、予約言語を指定できます。フィルターグループに含まれていない言語はクリアされます。TTS音声合成がサポートする言語を自由に組み合わせることができます。 - # The language filter group function allows you to specify reserved languages. - # Languages not in the filter group will be cleared. You can match the languages supported by TTS Text To Speech as you like. - # 排名越前,优先级越高,The higher the ranking, the higher the priority,ランキングが上位になるほど、優先度が高くなります。 - - # 系统默认过滤器。System default filter。(ISO 639-1 codes given) - # ---------------------------------------------------------------------------------------------------------------------------------- - # "zh"中文=Chinese ,"en"英语=English ,"ja"日语=Japanese ,"ko"韩语=Korean ,"fr"法语=French ,"vi"越南语=Vietnamese , "ru"俄语=Russian - # "th"泰语=Thai - # ---------------------------------------------------------------------------------------------------------------------------------- - self.DEFAULT_FILTERS = ["zh", "ja", "ko", "en"] - - # 用户可自定义过滤器。User-defined filters - self.Langfilters = self.DEFAULT_FILTERS[:] # 创建副本 - - # 合并文本 - self.isLangMerge = True - - # 试验性支持:您可自定义添加:"fr"法语 , "vi"越南语。Experimental: You can customize to add: "fr" French, "vi" Vietnamese. - # 请使用API启用:self.setfilters(["zh", "en", "ja", "ko", "fr", "vi" , "ru" , "th"]) # 您可自定义添加,如:"fr"法语 , "vi"越南语。 - - # 预览版功能,自动启用或禁用,无需设置 - # Preview feature, automatically enabled or disabled, no settings required - self.EnablePreview = False - - # 除此以外,它支持简写过滤器,只需按不同语种任意组合即可。 - # In addition to that, it supports abbreviation filters, allowing for any combination of different languages. - # 示例:您可以任意指定多种组合,进行过滤 - # Example: You can specify any combination to filter - - # 中/日语言优先级阀值(评分范围为 0 ~ 1):评分低于设定阀值 <0.89 时,启用 filters 中的优先级。\n - # 중/일본어 우선 순위 임계값(점수 범위 0-1): 점수가 설정된 임계값 <0.89보다 낮을 때 필터에서 우선 순위를 활성화합니다. - # 中国語/日本語の優先度しきい値(スコア範囲0〜1):スコアが設定されたしきい値<0.89未満の場合、フィルターの優先度が有効になります。\n - # Chinese and Japanese language priority threshold (score range is 0 ~ 1): The default threshold is 0.89. \n - # Only the common characters between Chinese and Japanese are processed with confidence and priority. \n - self.LangPriorityThreshold = 0.89 - - # Langfilters = ["zh"] # 按中文识别 - # Langfilters = ["en"] # 按英文识别 - # Langfilters = ["ja"] # 按日文识别 - # Langfilters = ["ko"] # 按韩文识别 - # Langfilters = ["zh_ja"] # 中日混合识别 - # Langfilters = ["zh_en"] # 中英混合识别 - # Langfilters = ["ja_en"] # 日英混合识别 - # Langfilters = ["zh_ko"] # 中韩混合识别 - # Langfilters = ["ja_ko"] # 日韩混合识别 - # Langfilters = ["en_ko"] # 英韩混合识别 - # Langfilters = ["zh_ja_en"] # 中日英混合识别 - # Langfilters = ["zh_ja_en_ko"] # 中日英韩混合识别 - - # 更多过滤组合,请您随意。。。For more filter combinations, please feel free to...... - # より多くのフィルターの組み合わせ、お気軽に。。。더 많은 필터 조합을 원하시면 자유롭게 해주세요. ..... - - # 可选保留:支持中文数字拼音格式,更方便前端实现拼音音素修改和推理,默认关闭 False 。 - # 开启后 True ,括号内的数字拼音格式均保留,并识别输出为:"zh"中文。 - self.keepPinyin = False - - # DEFINITION - self.PARSE_TAG = re.compile(r'(⑥\$*\d+[\d]{6,}⑥)') - - self.LangSSML = LangSSML() - - def _clears(self): - self._text_cache = None - self._text_lasts = None - self._text_langs = None - self._text_waits = None - self._lang_count = None - self._lang_eos = None - - def _is_english_word(self, word): - return bool(re.match(r'^[a-zA-Z]+$', word)) - - def _is_chinese(self, word): - for char in word: - if '\u4e00' <= char <= '\u9fff': - return True - return False - - def _is_japanese_kana(self, word): - pattern = re.compile(r'[\u3040-\u309F\u30A0-\u30FF]+') - matches = pattern.findall(word) - return len(matches) > 0 - - def _insert_english_uppercase(self, word): - modified_text = re.sub(r'(? 0 else None - if symbol is not None:pass - elif preData is not None and preData["symbol"] is None: - if len(clear_text) == 0:language = preData["lang"] - elif is_number == True:language = preData["lang"] - _ , pre_is_number = self._clear_text_number(preData["text"]) - if (preData["lang"] == language): - self._statistics(preData["lang"],text) - text = preData["text"] + text - preData["text"] = text - return preData - elif pre_is_number == True: - text = f'{preData["text"]}{text}' - words.pop() - elif is_number == True: - priority_language = self._get_filters_string()[:2] - if priority_language in "ja-zh-en-ko-fr-vi":language = priority_language - data = {"lang":language,"text": text,"score":score,"symbol":symbol} - filters = self.Langfilters - if filters is None or len(filters) == 0 or "?" in language or \ - language in filters or language in filters[0] or \ - filters[0] == "*" or filters[0] in "alls-mixs-autos": - words.append(data) - self._statistics(data["lang"],data["text"]) - return data - - def _addwords(self, words,language,text,score,symbol=None): - if text == "\n":pass # Keep Line Breaks - elif text is None or len(text.strip()) == 0:return True - if language is None:language = "" - language = language.lower() - if language == 'en':text = self._insert_english_uppercase(text) - # text = re.sub(r'[(())]', ',' , text) # Keep it. - text_waits = self._text_waits - ispre_waits = len(text_waits)>0 - preResult = text_waits.pop() if ispre_waits else None - if preResult is None:preResult = words[-1] if len(words) > 0 else None - if preResult and ("|" in preResult["lang"]): - pre_lang = preResult["lang"] - if language in pre_lang:preResult["lang"] = language = language.split("|")[0] - else:preResult["lang"]=pre_lang.split("|")[0] - if ispre_waits:preResult = self._saveData(words,preResult["lang"],preResult["text"],preResult["score"],preResult["symbol"]) - pre_lang = preResult["lang"] if preResult else None - if ("|" in language) and (pre_lang and not pre_lang in language and not "…" in language):language = language.split("|")[0] - if "|" in language:self._text_waits.append({"lang":language,"text": text,"score":score,"symbol":symbol}) - else:self._saveData(words,language,text,score,symbol) - return False - - def _get_prev_data(self, words): - data = words[-1] if words and len(words) > 0 else None - if data:return (data["lang"] , data["text"]) - return (None,"") - - def _match_ending(self, input , index): - if input is None or len(input) == 0:return False,None - input = re.sub(r'\s+', '', input) - if len(input) == 0 or abs(index) > len(input):return False,None - ending_pattern = re.compile(r'([「」“”‘’"\'::。.!!?.?])') - return ending_pattern.match(input[index]),input[index] - - def _cleans_text(self, cleans_text): - cleans_text = re.sub(r'(.*?)([^\w]+)', r'\1 ', cleans_text) - cleans_text = re.sub(r'(.)\1+', r'\1', cleans_text) - return cleans_text.strip() - - def _mean_processing(self, text:str): - if text is None or (text.strip()) == "":return None , 0.0 - arrs = self._split_camel_case(text).split(" ") - langs = [] - for t in arrs: - if len(t.strip()) <= 3:continue - language, score = self.langid.classify(t) - langs.append({"lang":language}) - if len(langs) == 0:return None , 0.0 - return Counter([item['lang'] for item in langs]).most_common(1)[0][0],1.0 - - def _lang_classify(self, cleans_text): - language, score = self.langid.classify(cleans_text) - # fix: Huggingface is np.float32 - if score is not None and isinstance(score, np.generic) and hasattr(score,"item"): - score = score.item() - score = round(score , 3) - return language, score - - def _get_filters_string(self): - filters = self.Langfilters - return "-".join(filters).lower().strip() if filters is not None else "" - - def _parse_language(self, words , segment): - LANG_JA = "ja" - LANG_ZH = "zh" - LANG_ZH_JA = f'{LANG_ZH}|{LANG_JA}' - LANG_JA_ZH = f'{LANG_JA}|{LANG_ZH}' - language = LANG_ZH - regex_pattern = re.compile(r'([^\w\s]+)') - lines = regex_pattern.split(segment) - lines_max = len(lines) - LANG_EOS =self._lang_eos - for index, text in enumerate(lines): - if len(text) == 0:continue - EOS = index >= (lines_max - 1) - nextId = index + 1 - nextText = lines[nextId] if not EOS else "" - nextPunc = len(re.sub(regex_pattern,'',re.sub(r'\n+','',nextText)).strip()) == 0 - textPunc = len(re.sub(regex_pattern,'',re.sub(r'\n+','',text)).strip()) == 0 - if not EOS and (textPunc == True or ( len(nextText.strip()) >= 0 and nextPunc == True)): - lines[nextId] = f'{text}{nextText}' - continue - number_tags = re.compile(r'(⑥\d{6,}⑥)') - cleans_text = re.sub(number_tags, '' ,text) - cleans_text = re.sub(r'\d+', '' ,cleans_text) - cleans_text = self._cleans_text(cleans_text) - # fix:Langid's recognition of short sentences is inaccurate, and it is spliced longer. - if not EOS and len(cleans_text) <= 2: - lines[nextId] = f'{text}{nextText}' - continue - language,score = self._lang_classify(cleans_text) - prev_language , prev_text = self._get_prev_data(words) - if language != LANG_ZH and all('\u4e00' <= c <= '\u9fff' for c in re.sub(r'\s','',cleans_text)):language,score = LANG_ZH,1 - if len(cleans_text) <= 5 and self._is_chinese(cleans_text): - filters_string = self._get_filters_string() - if score < self.LangPriorityThreshold and len(filters_string) > 0: - index_ja , index_zh = filters_string.find(LANG_JA) , filters_string.find(LANG_ZH) - if index_ja != -1 and index_ja < index_zh:language = LANG_JA - elif index_zh != -1 and index_zh < index_ja:language = LANG_ZH - if self._is_japanese_kana(cleans_text):language = LANG_JA - elif len(cleans_text) > 2 and score > 0.90:pass - elif EOS and LANG_EOS:language = LANG_ZH if len(cleans_text) <= 1 else language - else: - LANG_UNKNOWN = LANG_ZH_JA if language == LANG_ZH or (len(cleans_text) <=2 and prev_language == LANG_ZH) else LANG_JA_ZH - match_end,match_char = self._match_ending(text, -1) - referen = prev_language in LANG_UNKNOWN or LANG_UNKNOWN in prev_language if prev_language else False - if match_char in "。.": language = prev_language if referen and len(words) > 0 else language - else:language = f"{LANG_UNKNOWN}|…" - text,*_ = re.subn(number_tags , self._restore_number , text ) - self._addwords(words,language,text,score) - - # ---------------------------------------------------------- - # 【SSML】中文数字处理:Chinese Number Processing (SSML support) - # 这里默认都是中文,用于处理 SSML 中文标签。当然可以支持任意语言,例如: - # The default here is Chinese, which is used to process SSML Chinese tags. Of course, any language can be supported, for example: - # 中文电话号码:1234567 - # 中文数字号码:1234567 - def _process_symbol_SSML(self, words,data): - tag , match = data - language = SSML = match[1] - text = match[2] - score = 1.0 - if SSML == "telephone": - # 中文-电话号码 - language = "zh" - text = self.LangSSML.to_chinese_telephone(text) - elif SSML == "number": - # 中文-数字读法 - language = "zh" - text = self.LangSSML.to_chinese_number(text) - elif SSML == "currency": - # 中文-按金额发音 - language = "zh" - text = self.LangSSML.to_chinese_currency(text) - elif SSML == "date": - # 中文-按金额发音 - language = "zh" - text = self.LangSSML.to_chinese_date(text) - self._addwords(words,language,text,score,SSML) - - # ---------------------------------------------------------- - def _restore_number(self, matche): - value = matche.group(0) - text_cache = self._text_cache - if value in text_cache: - process , data = text_cache[value] - tag , match = data - value = match - return value - - def _pattern_symbols(self, item , text): - if text is None:return text - tag , pattern , process = item - matches = pattern.findall(text) - if len(matches) == 1 and "".join(matches[0]) == text: - return text - for i , match in enumerate(matches): - key = f"⑥{tag}{i:06d}⑥" - text = re.sub(pattern , key , text , count=1) - self._text_cache[key] = (process , (tag , match)) - return text - - def _process_symbol(self, words,data): - tag , match = data - language = match[1] - text = match[2] - score = 1.0 - filters = self._get_filters_string() - if language not in filters: - self._process_symbol_SSML(words,data) - else: - self._addwords(words,language,text,score,True) - - def _process_english(self, words,data): - tag , match = data - text = match[0] - filters = self._get_filters_string() - priority_language = filters[:2] - # Preview feature, other language segmentation processing - enablePreview = self.EnablePreview - if enablePreview == True: - # Experimental: Other language support - regex_pattern = re.compile(r'(.*?[。.??!!]+[\n]{,1})') - lines = regex_pattern.split(text) - for index , text in enumerate(lines): - if len(text.strip()) == 0:continue - cleans_text = self._cleans_text(text) - language,score = self._lang_classify(cleans_text) - if language not in filters: - language,score = self._mean_processing(cleans_text) - if language is None or score <= 0.0:continue - elif language in filters:pass # pass - elif score >= 0.95:continue # High score, but not in the filter, excluded. - elif score <= 0.15 and filters[:2] == "fr":language = priority_language - else:language = "en" - self._addwords(words,language,text,score) - else: - # Default is English - language, score = "en", 1.0 - self._addwords(words,language,text,score) - - def _process_Russian(self, words,data): - tag , match = data - text = match[0] - language = "ru" - score = 1.0 - self._addwords(words,language,text,score) - - def _process_Thai(self, words,data): - tag , match = data - text = match[0] - language = "th" - score = 1.0 - self._addwords(words,language,text,score) - - def _process_korean(self, words,data): - tag , match = data - text = match[0] - language = "ko" - score = 1.0 - self._addwords(words,language,text,score) - - def _process_quotes(self, words,data): - tag , match = data - text = "".join(match) - childs = self.PARSE_TAG.findall(text) - if len(childs) > 0: - self._process_tags(words , text , False) - else: - cleans_text = self._cleans_text(match[1]) - if len(cleans_text) <= 5: - self._parse_language(words,text) - else: - language,score = self._lang_classify(cleans_text) - self._addwords(words,language,text,score) - - def _process_pinyin(self, words,data): - tag , match = data - text = match - language = "zh" - score = 1.0 - self._addwords(words,language,text,score) - - def _process_number(self, words,data): # "$0" process only - """ - Numbers alone cannot accurately identify language. - Because numbers are universal in all languages. - So it won't be executed here, just for testing. - """ - tag , match = data - language = words[0]["lang"] if len(words) > 0 else "zh" - text = match - score = 0.0 - self._addwords(words,language,text,score) - - def _process_tags(self, words , text , root_tag): - text_cache = self._text_cache - segments = re.split(self.PARSE_TAG, text) - segments_len = len(segments) - 1 - for index , text in enumerate(segments): - if root_tag:self._lang_eos = index >= segments_len - if self.PARSE_TAG.match(text): - process , data = text_cache[text] - if process:process(words , data) - else: - self._parse_language(words , text) - return words - - def _merge_results(self, words): - new_word = [] - for index , cur_data in enumerate(words): - if "symbol" in cur_data:del cur_data["symbol"] - if index == 0:new_word.append(cur_data) - else: - pre_data = new_word[-1] - if cur_data["lang"] == pre_data["lang"]: - pre_data["text"] = f'{pre_data["text"]}{cur_data["text"]}' - else:new_word.append(cur_data) - return new_word - - def _parse_symbols(self, text): - TAG_NUM = "00" # "00" => default channels , "$0" => testing channel - TAG_S1,TAG_S2,TAG_P1,TAG_P2,TAG_EN,TAG_KO,TAG_RU,TAG_TH = "$1" ,"$2" ,"$3" ,"$4" ,"$5" ,"$6" ,"$7","$8" - TAG_BASE = re.compile(fr'(([【《((“‘"\']*[LANGUAGE]+[\W\s]*)+)') - # Get custom language filter - filters = self.Langfilters - filters = filters if filters is not None else "" - # ======================================================================================================= - # Experimental: Other language support.Thử nghiệm: Hỗ trợ ngôn ngữ khác.Expérimental : prise en charge d’autres langues. - # 相关语言字符如有缺失,熟悉相关语言的朋友,可以提交把缺失的发音符号补全。 - # If relevant language characters are missing, friends who are familiar with the relevant languages can submit a submission to complete the missing pronunciation symbols. - # S'il manque des caractères linguistiques pertinents, les amis qui connaissent les langues concernées peuvent soumettre une soumission pour compléter les symboles de prononciation manquants. - # Nếu thiếu ký tự ngôn ngữ liên quan, những người bạn quen thuộc với ngôn ngữ liên quan có thể gửi bài để hoàn thành các ký hiệu phát âm còn thiếu. - # ------------------------------------------------------------------------------------------------------- - # Preview feature, other language support - enablePreview = self.EnablePreview - if "fr" in filters or \ - "vi" in filters:enablePreview = True - self.EnablePreview = enablePreview - # 实验性:法语字符支持。Prise en charge des caractères français - RE_FR = "" if not enablePreview else "àáâãäåæçèéêëìíîïðñòóôõöùúûüýþÿ" - # 实验性:越南语字符支持。Hỗ trợ ký tự tiếng Việt - RE_VI = "" if not enablePreview else "đơưăáàảãạắằẳẵặấầẩẫậéèẻẽẹếềểễệíìỉĩịóòỏõọốồổỗộớờởỡợúùủũụứừửữựôâêơưỷỹ" - # ------------------------------------------------------------------------------------------------------- - # Basic options: - process_list = [ - ( TAG_S1 , re.compile(self.SYMBOLS_PATTERN) , self._process_symbol ), # Symbol Tag - ( TAG_KO , re.compile(re.sub(r'LANGUAGE',f'\uac00-\ud7a3',TAG_BASE.pattern)) , self._process_korean ), # Korean words - ( TAG_TH , re.compile(re.sub(r'LANGUAGE',f'\u0E00-\u0E7F',TAG_BASE.pattern)) , self._process_Thai ), # Thai words support. - ( TAG_RU , re.compile(re.sub(r'LANGUAGE',f'А-Яа-яЁё',TAG_BASE.pattern)) , self._process_Russian ), # Russian words support. - ( TAG_NUM , re.compile(r'(\W*\d+\W+\d*\W*\d*)') , self._process_number ), # Number words, Universal in all languages, Ignore it. - ( TAG_EN , re.compile(re.sub(r'LANGUAGE',f'a-zA-Z{RE_FR}{RE_VI}',TAG_BASE.pattern)) , self._process_english ), # English words + Other language support. - ( TAG_P1 , re.compile(r'(["\'])(.*?)(\1)') , self._process_quotes ), # Regular quotes - ( TAG_P2 , re.compile(r'([\n]*[【《((“‘])([^【《((“‘’”))》】]{3,})([’”))》】][\W\s]*[\n]{,1})') , self._process_quotes ), # Special quotes, There are left and right. - ] - # Extended options: Default False - if self.keepPinyin == True:process_list.insert(1 , - ( TAG_S2 , re.compile(r'([\(({](?:\s*\w*\d\w*\s*)+[})\)])') , self._process_pinyin ), # Chinese Pinyin Tag. - ) - # ------------------------------------------------------------------------------------------------------- - words = [] - lines = re.findall(r'.*\n*', re.sub(self.PARSE_TAG, '' ,text)) - for index , text in enumerate(lines): - if len(text.strip()) == 0:continue - self._lang_eos = False - self._text_cache = {} - for item in process_list: - text = self._pattern_symbols(item , text) - cur_word = self._process_tags([] , text , True) - if len(cur_word) == 0:continue - cur_data = cur_word[0] if len(cur_word) > 0 else None - pre_data = words[-1] if len(words) > 0 else None - if cur_data and pre_data and cur_data["lang"] == pre_data["lang"] \ - and cur_data["symbol"] == False and pre_data["symbol"] : - cur_data["text"] = f'{pre_data["text"]}{cur_data["text"]}' - words.pop() - words += cur_word - if self.isLangMerge == True:words = self._merge_results(words) - lang_count = self._lang_count - if lang_count and len(lang_count) > 0: - lang_count = dict(sorted(lang_count.items(), key=lambda x: x[1], reverse=True)) - lang_count = list(lang_count.items()) - self._lang_count = lang_count - return words - - def setfilters(self, filters): - # 当过滤器更改时,清除缓存 - # 필터가 변경되면 캐시를 지웁니다. - # フィルタが変更されると、キャッシュがクリアされます - # When the filter changes, clear the cache - if self.Langfilters != filters: - self._clears() - self.Langfilters = filters - - def getfilters(self): - return self.Langfilters - - def setPriorityThreshold(self, threshold:float): - self.LangPriorityThreshold = threshold - - def getPriorityThreshold(self): - return self.LangPriorityThreshold - - def getCounts(self): - lang_count = self._lang_count - if lang_count is not None:return lang_count - text_langs = self._text_langs - if text_langs is None or len(text_langs) == 0:return [("zh",0)] - lang_counts = defaultdict(int) - for d in text_langs:lang_counts[d['lang']] += int(len(d['text'])*2) if d['lang'] == "zh" else len(d['text']) - lang_counts = dict(sorted(lang_counts.items(), key=lambda x: x[1], reverse=True)) - lang_counts = list(lang_counts.items()) - self._lang_count = lang_counts - return lang_counts - - def getTexts(self, text:str): - if text is None or len(text.strip()) == 0: - self._clears() - return [] - # lasts - text_langs = self._text_langs - if self._text_lasts == text and text_langs is not None:return text_langs - # parse - self._text_waits = [] - self._lang_count = None - self._text_lasts = text - text = self._parse_symbols(text) - self._text_langs = text - return text - - def classify(self, text:str): - return self.getTexts(text) - -def printList(langlist): - """ - 功能:打印数组结果 - 기능: 어레이 결과 인쇄 - 機能:配列結果を印刷 - Function: Print array results - """ - print("\n===================【打印结果】===================") - if langlist is None or len(langlist) == 0: - print("无内容结果,No content result") - return - for line in langlist: - print(line) - pass - - - -def main(): - - # ----------------------------------- - # 更新日志:新版本分词更加精准。 - # Changelog: The new version of the word segmentation is more accurate. - # チェンジログ:新しいバージョンの単語セグメンテーションはより正確です。 - # Changelog: 분할이라는 단어의 새로운 버전이 더 정확합니다. - # ----------------------------------- - - # 输入示例1:(包含日文,中文)Input Example 1: (including Japanese, Chinese) - # text = "“昨日は雨が降った,音楽、映画。。。”你今天学习日语了吗?春は桜の季節です。语种分词是语音合成必不可少的环节。言語分詞は音声合成に欠かせない環節である!" - - # 输入示例2:(包含日文,中文)Input Example 1: (including Japanese, Chinese) - # text = "欢迎来玩。東京,は日本の首都です。欢迎来玩. 太好了!" - - # 输入示例3:(包含日文,中文)Input Example 1: (including Japanese, Chinese) - # text = "明日、私たちは海辺にバカンスに行きます。你会说日语吗:“中国語、話せますか” 你的日语真好啊!" - - - # 输入示例4:(包含日文,中文,韩语,英文)Input Example 4: (including Japanese, Chinese, Korean, English) - # text = "你的名字叫佐々木?吗?韩语中的안녕 오빠读什么呢?あなたの体育の先生は誰ですか? 此次发布会带来了四款iPhone 15系列机型和三款Apple Watch等一系列新品,这次的iPad Air采用了LCD屏幕" - - - # 试验性支持:"fr"法语 , "vi"越南语 , "ru"俄语 , "th"泰语。Experimental: Other language support. - langsegment = LangSegment() - langsegment.setfilters(["fr", "vi" , "ja", "zh", "ko", "en" , "ru" , "th"]) - text = """ -我喜欢在雨天里听音乐。 -I enjoy listening to music on rainy days. -雨の日に音楽を聴くのが好きです。 -비 오는 날에 음악을 듣는 것을 즐깁니다。 -J'aime écouter de la musique les jours de pluie. -Tôi thích nghe nhạc vào những ngày mưa. -Мне нравится слушать музыку в дождливую погоду. -ฉันชอบฟังเพลงในวันที่ฝนตก -""" - - - - # 进行分词:(接入TTS项目仅需一行代码调用)Segmentation: (Only one line of code is required to access the TTS project) - langlist = langsegment.getTexts(text) - printList(langlist) - - - # 语种统计:Language statistics: - print("\n===================【语种统计】===================") - # 获取所有语种数组结果,根据内容字数降序排列 - # Get the array results in all languages, sorted in descending order according to the number of content words - langCounts = langsegment.getCounts() - print(langCounts , "\n") - - # 根据结果获取内容的主要语种 (语言,字数含标点) - # Get the main language of content based on the results (language, word count including punctuation) - lang , count = langCounts[0] - print(f"输入内容的主要语言为 = {lang} ,字数 = {count}") - print("==================================================\n") - - - # 分词输出:lang=语言,text=内容。Word output: lang = language, text = content - # ===================【打印结果】=================== - # {'lang': 'zh', 'text': '你的名字叫'} - # {'lang': 'ja', 'text': '佐々木?'} - # {'lang': 'zh', 'text': '吗?韩语中的'} - # {'lang': 'ko', 'text': '안녕 오빠'} - # {'lang': 'zh', 'text': '读什么呢?'} - # {'lang': 'ja', 'text': 'あなたの体育の先生は誰ですか?'} - # {'lang': 'zh', 'text': ' 此次发布会带来了四款'} - # {'lang': 'en', 'text': 'i Phone '} - # {'lang': 'zh', 'text': '15系列机型和三款'} - # {'lang': 'en', 'text': 'Apple Watch '} - # {'lang': 'zh', 'text': '等一系列新品,这次的'} - # {'lang': 'en', 'text': 'i Pad Air '} - # {'lang': 'zh', 'text': '采用了'} - # {'lang': 'en', 'text': 'L C D '} - # {'lang': 'zh', 'text': '屏幕'} - # ===================【语种统计】=================== - - # ===================【语种统计】=================== - # [('zh', 51), ('ja', 19), ('en', 18), ('ko', 5)] - - # 输入内容的主要语言为 = zh ,字数 = 51 - # ================================================== - # The main language of the input content is = zh, word count = 51 - - -if __name__ == "__main__": - main() diff --git a/language_segmentation/__init__.py b/language_segmentation/__init__.py deleted file mode 100644 index 476e8e413cf1dcdf7c2ae11c662b523c0a8b3fc0..0000000000000000000000000000000000000000 --- a/language_segmentation/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from .LangSegment import LangSegment - - -# release -__version__ = '0.3.5' - - -# develop -__develop__ = 'dev-0.0.1' \ No newline at end of file diff --git a/language_segmentation/utils/__init__.py b/language_segmentation/utils/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/language_segmentation/utils/num.py b/language_segmentation/utils/num.py deleted file mode 100644 index 05a5f70cec507df9a68c45023c22cda822e8d921..0000000000000000000000000000000000000000 --- a/language_segmentation/utils/num.py +++ /dev/null @@ -1,327 +0,0 @@ -# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Digital processing from GPT_SoVITS num.py (thanks) -""" -Rules to verbalize numbers into Chinese characters. -https://zh.wikipedia.org/wiki/中文数字#現代中文 -""" - -import re -from collections import OrderedDict -from typing import List - -DIGITS = {str(i): tran for i, tran in enumerate('零一二三四五六七八九')} -UNITS = OrderedDict({ - 1: '十', - 2: '百', - 3: '千', - 4: '万', - 8: '亿', -}) - -COM_QUANTIFIERS = '(处|台|架|枚|趟|幅|平|方|堵|间|床|株|批|项|例|列|篇|栋|注|亩|封|艘|把|目|套|段|人|所|朵|匹|张|座|回|场|尾|条|个|首|阙|阵|网|炮|顶|丘|棵|只|支|袭|辆|挑|担|颗|壳|窠|曲|墙|群|腔|砣|座|客|贯|扎|捆|刀|令|打|手|罗|坡|山|岭|江|溪|钟|队|单|双|对|出|口|头|脚|板|跳|枝|件|贴|针|线|管|名|位|身|堂|课|本|页|家|户|层|丝|毫|厘|分|钱|两|斤|担|铢|石|钧|锱|忽|(千|毫|微)克|毫|厘|(公)分|分|寸|尺|丈|里|寻|常|铺|程|(千|分|厘|毫|微)米|米|撮|勺|合|升|斗|石|盘|碗|碟|叠|桶|笼|盆|盒|杯|钟|斛|锅|簋|篮|盘|桶|罐|瓶|壶|卮|盏|箩|箱|煲|啖|袋|钵|年|月|日|季|刻|时|周|天|秒|分|小时|旬|纪|岁|世|更|夜|春|夏|秋|冬|代|伏|辈|丸|泡|粒|颗|幢|堆|条|根|支|道|面|片|张|颗|块|元|(亿|千万|百万|万|千|百)|(亿|千万|百万|万|千|百|美|)元|(亿|千万|百万|万|千|百|十|)吨|(亿|千万|百万|万|千|百|)块|角|毛|分)' - -# 分数表达式 -RE_FRAC = re.compile(r'(-?)(\d+)/(\d+)') - - -def replace_frac(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - sign = match.group(1) - nominator = match.group(2) - denominator = match.group(3) - sign: str = "负" if sign else "" - nominator: str = num2str(nominator) - denominator: str = num2str(denominator) - result = f"{sign}{denominator}分之{nominator}" - return result - - -# 百分数表达式 -RE_PERCENTAGE = re.compile(r'(-?)(\d+(\.\d+)?)%') - - -def replace_percentage(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - sign = match.group(1) - percent = match.group(2) - sign: str = "负" if sign else "" - percent: str = num2str(percent) - result = f"{sign}百分之{percent}" - return result - - -# 整数表达式 -# 带负号的整数 -10 -RE_INTEGER = re.compile(r'(-)' r'(\d+)') - - -def replace_negative_num(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - sign = match.group(1) - number = match.group(2) - sign: str = "负" if sign else "" - number: str = num2str(number) - result = f"{sign}{number}" - return result - - -# 编号-无符号整形 -# 00078 -RE_DEFAULT_NUM = re.compile(r'\d{3}\d*') - - -def replace_default_num(match): - """ - Args: - match (re.Match) - Returns: - str - """ - number = match.group(0) - return verbalize_digit(number, alt_one=True) - - -# 加减乘除 -# RE_ASMD = re.compile( -# r'((-?)((\d+)(\.\d+)?)|(\.(\d+)))([\+\-\×÷=])((-?)((\d+)(\.\d+)?)|(\.(\d+)))') -RE_ASMD = re.compile( - r'((-?)((\d+)(\.\d+)?[⁰¹²³⁴⁵⁶⁷⁸⁹ˣʸⁿ]*)|(\.\d+[⁰¹²³⁴⁵⁶⁷⁸⁹ˣʸⁿ]*)|([A-Za-z][⁰¹²³⁴⁵⁶⁷⁸⁹ˣʸⁿ]*))([\+\-\×÷=])((-?)((\d+)(\.\d+)?[⁰¹²³⁴⁵⁶⁷⁸⁹ˣʸⁿ]*)|(\.\d+[⁰¹²³⁴⁵⁶⁷⁸⁹ˣʸⁿ]*)|([A-Za-z][⁰¹²³⁴⁵⁶⁷⁸⁹ˣʸⁿ]*))') - -asmd_map = { - '+': '加', - '-': '减', - '×': '乘', - '÷': '除', - '=': '等于' -} - -def replace_asmd(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - result = match.group(1) + asmd_map[match.group(8)] + match.group(9) - return result - - -# 次方专项 -RE_POWER = re.compile(r'[⁰¹²³⁴⁵⁶⁷⁸⁹ˣʸⁿ]+') - -power_map = { - '⁰': '0', - '¹': '1', - '²': '2', - '³': '3', - '⁴': '4', - '⁵': '5', - '⁶': '6', - '⁷': '7', - '⁸': '8', - '⁹': '9', - 'ˣ': 'x', - 'ʸ': 'y', - 'ⁿ': 'n' -} - -def replace_power(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - power_num = "" - for m in match.group(0): - power_num += power_map[m] - result = "的" + power_num + "次方" - return result - - -# 数字表达式 -# 纯小数 -RE_DECIMAL_NUM = re.compile(r'(-?)((\d+)(\.\d+))' r'|(\.(\d+))') -# 正整数 + 量词 -RE_POSITIVE_QUANTIFIERS = re.compile(r"(\d+)([多余几\+])?" + COM_QUANTIFIERS) -RE_NUMBER = re.compile(r'(-?)((\d+)(\.\d+)?)' r'|(\.(\d+))') - - -def replace_positive_quantifier(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - number = match.group(1) - match_2 = match.group(2) - if match_2 == "+": - match_2 = "多" - match_2: str = match_2 if match_2 else "" - quantifiers: str = match.group(3) - number: str = num2str(number) - result = f"{number}{match_2}{quantifiers}" - return result - - -def replace_number(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - sign = match.group(1) - number = match.group(2) - pure_decimal = match.group(5) - if pure_decimal: - result = num2str(pure_decimal) - else: - sign: str = "负" if sign else "" - number: str = num2str(number) - result = f"{sign}{number}" - return result - - -# 范围表达式 -# match.group(1) and match.group(8) are copy from RE_NUMBER - -RE_RANGE = re.compile( - r""" - (? str: - """ - Args: - match (re.Match) - Returns: - str - """ - first, second = match.group(1), match.group(6) - first = RE_NUMBER.sub(replace_number, first) - second = RE_NUMBER.sub(replace_number, second) - result = f"{first}到{second}" - return result - - -# ~至表达式 -RE_TO_RANGE = re.compile( - r'((-?)((\d+)(\.\d+)?)|(\.(\d+)))(%|°C|℃|度|摄氏度|cm2|cm²|cm3|cm³|cm|db|ds|kg|km|m2|m²|m³|m3|ml|m|mm|s)[~]((-?)((\d+)(\.\d+)?)|(\.(\d+)))(%|°C|℃|度|摄氏度|cm2|cm²|cm3|cm³|cm|db|ds|kg|km|m2|m²|m³|m3|ml|m|mm|s)') - -def replace_to_range(match) -> str: - """ - Args: - match (re.Match) - Returns: - str - """ - result = match.group(0).replace('~', '至') - return result - - -def _get_value(value_string: str, use_zero: bool=True) -> List[str]: - stripped = value_string.lstrip('0') - if len(stripped) == 0: - return [] - elif len(stripped) == 1: - if use_zero and len(stripped) < len(value_string): - return [DIGITS['0'], DIGITS[stripped]] - else: - return [DIGITS[stripped]] - else: - largest_unit = next( - power for power in reversed(UNITS.keys()) if power < len(stripped)) - first_part = value_string[:-largest_unit] - second_part = value_string[-largest_unit:] - return _get_value(first_part) + [UNITS[largest_unit]] + _get_value( - second_part) - - -def verbalize_cardinal(value_string: str) -> str: - if not value_string: - return '' - - # 000 -> '零' , 0 -> '零' - value_string = value_string.lstrip('0') - if len(value_string) == 0: - return DIGITS['0'] - - result_symbols = _get_value(value_string) - # verbalized number starting with '一十*' is abbreviated as `十*` - if len(result_symbols) >= 2 and result_symbols[0] == DIGITS[ - '1'] and result_symbols[1] == UNITS[1]: - result_symbols = result_symbols[1:] - return ''.join(result_symbols) - - -def verbalize_digit(value_string: str, alt_one=False) -> str: - result_symbols = [DIGITS[digit] for digit in value_string] - result = ''.join(result_symbols) - if alt_one: - result = result.replace("一", "幺") - return result - - -def num2str(value_string: str) -> str: - integer_decimal = value_string.split('.') - if len(integer_decimal) == 1: - integer = integer_decimal[0] - decimal = '' - elif len(integer_decimal) == 2: - integer, decimal = integer_decimal - else: - raise ValueError( - f"The value string: '${value_string}' has more than one point in it." - ) - - result = verbalize_cardinal(integer) - - decimal = decimal.rstrip('0') - if decimal: - # '.22' is verbalized as '零点二二' - # '3.20' is verbalized as '三点二 - result = result if result else "零" - result += '点' + verbalize_digit(decimal) - return result - - -if __name__ == "__main__": - - text = "" - text = num2str(text) - print(text) - pass \ No newline at end of file diff --git a/models/ace_step_transformer.py b/models/ace_step_transformer.py deleted file mode 100644 index 5bac5ad469833043bd0685ada2bc56dc528daf4f..0000000000000000000000000000000000000000 --- a/models/ace_step_transformer.py +++ /dev/null @@ -1,475 +0,0 @@ -# Copyright 2024 The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from dataclasses import dataclass -from typing import Any, Dict, Optional, Tuple, List, Union - -import torch -import torch.nn.functional as F -from torch import nn - -from diffusers.configuration_utils import ConfigMixin, register_to_config -from diffusers.utils import BaseOutput, is_torch_version -from diffusers.models.modeling_utils import ModelMixin -from diffusers.models.embeddings import TimestepEmbedding, Timesteps -from diffusers.loaders import FromOriginalModelMixin, PeftAdapterMixin - - -from .attention import LinearTransformerBlock, t2i_modulate -from .lyrics_utils.lyric_encoder import ConformerEncoder as LyricEncoder - - -def cross_norm(hidden_states, controlnet_input): - # input N x T x c - mean_hidden_states, std_hidden_states = hidden_states.mean(dim=(1,2), keepdim=True), hidden_states.std(dim=(1,2), keepdim=True) - mean_controlnet_input, std_controlnet_input = controlnet_input.mean(dim=(1,2), keepdim=True), controlnet_input.std(dim=(1,2), keepdim=True) - controlnet_input = (controlnet_input - mean_controlnet_input) * (std_hidden_states / (std_controlnet_input + 1e-12)) + mean_hidden_states - return controlnet_input - - -# Copied from transformers.models.mixtral.modeling_mixtral.MixtralRotaryEmbedding with Mixtral->Qwen2 -class Qwen2RotaryEmbedding(nn.Module): - def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None): - super().__init__() - - self.dim = dim - self.max_position_embeddings = max_position_embeddings - self.base = base - inv_freq = 1.0 / (self.base ** (torch.arange(0, self.dim, 2, dtype=torch.int64).float().to(device) / self.dim)) - self.register_buffer("inv_freq", inv_freq, persistent=False) - - # Build here to make `torch.jit.trace` work. - self._set_cos_sin_cache( - seq_len=max_position_embeddings, device=self.inv_freq.device, dtype=torch.get_default_dtype() - ) - - def _set_cos_sin_cache(self, seq_len, device, dtype): - self.max_seq_len_cached = seq_len - t = torch.arange(self.max_seq_len_cached, device=device, dtype=torch.int64).type_as(self.inv_freq) - - freqs = torch.outer(t, self.inv_freq) - # Different from paper, but it uses a different permutation in order to obtain the same calculation - emb = torch.cat((freqs, freqs), dim=-1) - self.register_buffer("cos_cached", emb.cos().to(dtype), persistent=False) - self.register_buffer("sin_cached", emb.sin().to(dtype), persistent=False) - - def forward(self, x, seq_len=None): - # x: [bs, num_attention_heads, seq_len, head_size] - if seq_len > self.max_seq_len_cached: - self._set_cos_sin_cache(seq_len=seq_len, device=x.device, dtype=x.dtype) - - return ( - self.cos_cached[:seq_len].to(dtype=x.dtype), - self.sin_cached[:seq_len].to(dtype=x.dtype), - ) - - -class T2IFinalLayer(nn.Module): - """ - The final layer of Sana. - """ - - def __init__(self, hidden_size, patch_size=[16, 1], out_channels=256): - super().__init__() - self.norm_final = nn.RMSNorm(hidden_size, elementwise_affine=False, eps=1e-6) - self.linear = nn.Linear(hidden_size, patch_size[0] * patch_size[1] * out_channels, bias=True) - self.scale_shift_table = nn.Parameter(torch.randn(2, hidden_size) / hidden_size**0.5) - self.out_channels = out_channels - self.patch_size = patch_size - - def unpatchfy( - self, - hidden_states: torch.Tensor, - width: int, - ): - # 4 unpatchify - new_height, new_width = 1, hidden_states.size(1) - hidden_states = hidden_states.reshape( - shape=(hidden_states.shape[0], new_height, new_width, self.patch_size[0], self.patch_size[1], self.out_channels) - ).contiguous() - hidden_states = torch.einsum("nhwpqc->nchpwq", hidden_states) - output = hidden_states.reshape( - shape=(hidden_states.shape[0], self.out_channels, new_height * self.patch_size[0], new_width * self.patch_size[1]) - ).contiguous() - if width > new_width: - output = torch.nn.functional.pad(output, (0, width - new_width, 0, 0), 'constant', 0) - elif width < new_width: - output = output[:, :, :, :width] - return output - - def forward(self, x, t, output_length): - shift, scale = (self.scale_shift_table[None] + t[:, None]).chunk(2, dim=1) - x = t2i_modulate(self.norm_final(x), shift, scale) - x = self.linear(x) - # unpatchify - output = self.unpatchfy(x, output_length) - return output - - -class PatchEmbed(nn.Module): - """2D Image to Patch Embedding""" - - def __init__( - self, - height=16, - width=4096, - patch_size=(16, 1), - in_channels=8, - embed_dim=1152, - bias=True, - ): - super().__init__() - patch_size_h, patch_size_w = patch_size - self.early_conv_layers = nn.Sequential( - nn.Conv2d(in_channels, in_channels*256, kernel_size=patch_size, stride=patch_size, padding=0, bias=bias), - torch.nn.GroupNorm(num_groups=32, num_channels=in_channels*256, eps=1e-6, affine=True), - nn.Conv2d(in_channels*256, embed_dim, kernel_size=1, stride=1, padding=0, bias=bias) - ) - self.patch_size = patch_size - self.height, self.width = height // patch_size_h, width // patch_size_w - self.base_size = self.width - - def forward(self, latent): - # early convolutions, N x C x H x W -> N x 256 * sqrt(patch_size) x H/patch_size x W/patch_size - latent = self.early_conv_layers(latent) - latent = latent.flatten(2).transpose(1, 2) # BCHW -> BNC - return latent - - -@dataclass -class Transformer2DModelOutput(BaseOutput): - - sample: torch.FloatTensor - proj_losses: Optional[Tuple[Tuple[str, torch.Tensor]]] = None - - -class ACEStepTransformer2DModel(ModelMixin, ConfigMixin, PeftAdapterMixin, FromOriginalModelMixin): - _supports_gradient_checkpointing = True - - @register_to_config - def __init__( - self, - in_channels: Optional[int] = 8, - num_layers: int = 28, - inner_dim: int = 1536, - attention_head_dim: int = 64, - num_attention_heads: int = 24, - mlp_ratio: float = 4.0, - out_channels: int = 8, - max_position: int = 32768, - rope_theta: float = 1000000.0, - speaker_embedding_dim: int = 512, - text_embedding_dim: int = 768, - ssl_encoder_depths: List[int] = [9, 9], - ssl_names: List[str] = ["mert", "m-hubert"], - ssl_latent_dims: List[int] = [1024, 768], - lyric_encoder_vocab_size: int = 6681, - lyric_hidden_size: int = 1024, - patch_size: List[int] = [16, 1], - max_height: int = 16, - max_width: int = 4096, - **kwargs, - ): - super().__init__() - - self.num_attention_heads = num_attention_heads - self.attention_head_dim = attention_head_dim - inner_dim = num_attention_heads * attention_head_dim - self.inner_dim = inner_dim - self.out_channels = out_channels - self.max_position = max_position - self.patch_size = patch_size - - self.rope_theta = rope_theta - - self.rotary_emb = Qwen2RotaryEmbedding( - dim=self.attention_head_dim, - max_position_embeddings=self.max_position, - base=self.rope_theta, - ) - - # 2. Define input layers - self.in_channels = in_channels - - # 3. Define transformers blocks - self.transformer_blocks = nn.ModuleList( - [ - LinearTransformerBlock( - dim=self.inner_dim, - num_attention_heads=self.num_attention_heads, - attention_head_dim=attention_head_dim, - mlp_ratio=mlp_ratio, - add_cross_attention=True, - add_cross_attention_dim=self.inner_dim, - ) - for i in range(self.config.num_layers) - ] - ) - self.num_layers = num_layers - - self.time_proj = Timesteps(num_channels=256, flip_sin_to_cos=True, downscale_freq_shift=0) - self.timestep_embedder = TimestepEmbedding(in_channels=256, time_embed_dim=self.inner_dim) - self.t_block = nn.Sequential(nn.SiLU(), nn.Linear(self.inner_dim, 6 * self.inner_dim, bias=True)) - - # speaker - self.speaker_embedder = nn.Linear(speaker_embedding_dim, self.inner_dim) - - # genre - self.genre_embedder = nn.Linear(text_embedding_dim, self.inner_dim) - - # lyric - self.lyric_embs = nn.Embedding(lyric_encoder_vocab_size, lyric_hidden_size) - self.lyric_encoder = LyricEncoder(input_size=lyric_hidden_size, static_chunk_size=0) - self.lyric_proj = nn.Linear(lyric_hidden_size, self.inner_dim) - - projector_dim = 2 * self.inner_dim - - self.projectors = nn.ModuleList([ - nn.Sequential( - nn.Linear(self.inner_dim, projector_dim), - nn.SiLU(), - nn.Linear(projector_dim, projector_dim), - nn.SiLU(), - nn.Linear(projector_dim, ssl_dim), - ) for ssl_dim in ssl_latent_dims - ]) - - self.ssl_latent_dims = ssl_latent_dims - self.ssl_encoder_depths = ssl_encoder_depths - - self.cosine_loss = torch.nn.CosineEmbeddingLoss(margin=0.0, reduction='mean') - self.ssl_names = ssl_names - - self.proj_in = PatchEmbed( - height=max_height, - width=max_width, - patch_size=patch_size, - embed_dim=self.inner_dim, - bias=True, - ) - - self.final_layer = T2IFinalLayer(self.inner_dim, patch_size=patch_size, out_channels=out_channels) - self.gradient_checkpointing = False - - # Copied from diffusers.models.unets.unet_3d_condition.UNet3DConditionModel.enable_forward_chunking - def enable_forward_chunking(self, chunk_size: Optional[int] = None, dim: int = 0) -> None: - """ - Sets the attention processor to use [feed forward - chunking](https://huggingface.co/blog/reformer#2-chunked-feed-forward-layers). - - Parameters: - chunk_size (`int`, *optional*): - The chunk size of the feed-forward layers. If not specified, will run feed-forward layer individually - over each tensor of dim=`dim`. - dim (`int`, *optional*, defaults to `0`): - The dimension over which the feed-forward computation should be chunked. Choose between dim=0 (batch) - or dim=1 (sequence length). - """ - if dim not in [0, 1]: - raise ValueError(f"Make sure to set `dim` to either 0 or 1, not {dim}") - - # By default chunk size is 1 - chunk_size = chunk_size or 1 - - def fn_recursive_feed_forward(module: torch.nn.Module, chunk_size: int, dim: int): - if hasattr(module, "set_chunk_feed_forward"): - module.set_chunk_feed_forward(chunk_size=chunk_size, dim=dim) - - for child in module.children(): - fn_recursive_feed_forward(child, chunk_size, dim) - - for module in self.children(): - fn_recursive_feed_forward(module, chunk_size, dim) - - def _set_gradient_checkpointing(self, module, value=False): - if hasattr(module, "gradient_checkpointing"): - module.gradient_checkpointing = value - - def forward_lyric_encoder( - self, - lyric_token_idx: Optional[torch.LongTensor] = None, - lyric_mask: Optional[torch.LongTensor] = None, - ): - # N x T x D - lyric_embs = self.lyric_embs(lyric_token_idx) - prompt_prenet_out, _mask = self.lyric_encoder(lyric_embs, lyric_mask, decoding_chunk_size=1, num_decoding_left_chunks=-1) - prompt_prenet_out = self.lyric_proj(prompt_prenet_out) - return prompt_prenet_out - - def encode( - self, - encoder_text_hidden_states: Optional[torch.Tensor] = None, - text_attention_mask: Optional[torch.LongTensor] = None, - speaker_embeds: Optional[torch.FloatTensor] = None, - lyric_token_idx: Optional[torch.LongTensor] = None, - lyric_mask: Optional[torch.LongTensor] = None, - ): - - bs = encoder_text_hidden_states.shape[0] - device = encoder_text_hidden_states.device - - # speaker embedding - encoder_spk_hidden_states = self.speaker_embedder(speaker_embeds).unsqueeze(1) - speaker_mask = torch.ones(bs, 1, device=device) - - # genre embedding - encoder_text_hidden_states = self.genre_embedder(encoder_text_hidden_states) - - # lyric - encoder_lyric_hidden_states = self.forward_lyric_encoder( - lyric_token_idx=lyric_token_idx, - lyric_mask=lyric_mask, - ) - - encoder_hidden_states = torch.cat([encoder_spk_hidden_states, encoder_text_hidden_states, encoder_lyric_hidden_states], dim=1) - encoder_hidden_mask = torch.cat([speaker_mask, text_attention_mask, lyric_mask], dim=1) - return encoder_hidden_states, encoder_hidden_mask - - def decode( - self, - hidden_states: torch.Tensor, - attention_mask: torch.Tensor, - encoder_hidden_states: torch.Tensor, - encoder_hidden_mask: torch.Tensor, - timestep: Optional[torch.Tensor], - ssl_hidden_states: Optional[List[torch.Tensor]] = None, - output_length: int = 0, - block_controlnet_hidden_states: Optional[Union[List[torch.Tensor], torch.Tensor]] = None, - controlnet_scale: Union[float, torch.Tensor] = 1.0, - return_dict: bool = True, - ): - - embedded_timestep = self.timestep_embedder(self.time_proj(timestep).to(dtype=hidden_states.dtype)) - temb = self.t_block(embedded_timestep) - - hidden_states = self.proj_in(hidden_states) - - # controlnet logic - if block_controlnet_hidden_states is not None: - control_condi = cross_norm(hidden_states, block_controlnet_hidden_states) - hidden_states = hidden_states + control_condi * controlnet_scale - - inner_hidden_states = [] - - rotary_freqs_cis = self.rotary_emb(hidden_states, seq_len=hidden_states.shape[1]) - encoder_rotary_freqs_cis = self.rotary_emb(encoder_hidden_states, seq_len=encoder_hidden_states.shape[1]) - - for index_block, block in enumerate(self.transformer_blocks): - - if self.training and self.gradient_checkpointing: - - def create_custom_forward(module, return_dict=None): - def custom_forward(*inputs): - if return_dict is not None: - return module(*inputs, return_dict=return_dict) - else: - return module(*inputs) - - return custom_forward - - ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {} - hidden_states = torch.utils.checkpoint.checkpoint( - create_custom_forward(block), - hidden_states=hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_hidden_mask, - rotary_freqs_cis=rotary_freqs_cis, - rotary_freqs_cis_cross=encoder_rotary_freqs_cis, - temb=temb, - **ckpt_kwargs, - ) - - else: - hidden_states = block( - hidden_states=hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_hidden_mask, - rotary_freqs_cis=rotary_freqs_cis, - rotary_freqs_cis_cross=encoder_rotary_freqs_cis, - temb=temb, - ) - - for ssl_encoder_depth in self.ssl_encoder_depths: - if index_block == ssl_encoder_depth: - inner_hidden_states.append(hidden_states) - - proj_losses = [] - if len(inner_hidden_states) > 0 and ssl_hidden_states is not None and len(ssl_hidden_states) > 0: - - for inner_hidden_state, projector, ssl_hidden_state, ssl_name in zip(inner_hidden_states, self.projectors, ssl_hidden_states, self.ssl_names): - if ssl_hidden_state is None: - continue - # 1. N x T x D1 -> N x D x D2 - est_ssl_hidden_state = projector(inner_hidden_state) - # 3. projection loss - bs = inner_hidden_state.shape[0] - proj_loss = 0.0 - for i, (z, z_tilde) in enumerate(zip(ssl_hidden_state, est_ssl_hidden_state)): - # 2. interpolate - z_tilde = F.interpolate(z_tilde.unsqueeze(0).transpose(1, 2), size=len(z), mode='linear', align_corners=False).transpose(1, 2).squeeze(0) - - z_tilde = torch.nn.functional.normalize(z_tilde, dim=-1) - z = torch.nn.functional.normalize(z, dim=-1) - # T x d -> T x 1 -> 1 - target = torch.ones(z.shape[0], device=z.device) - proj_loss += self.cosine_loss(z, z_tilde, target) - proj_losses.append((ssl_name, proj_loss / bs)) - - output = self.final_layer(hidden_states, embedded_timestep, output_length) - if not return_dict: - return (output, proj_losses) - - return Transformer2DModelOutput(sample=output, proj_losses=proj_losses) - - # @torch.compile - def forward( - self, - hidden_states: torch.Tensor, - attention_mask: torch.Tensor, - encoder_text_hidden_states: Optional[torch.Tensor] = None, - text_attention_mask: Optional[torch.LongTensor] = None, - speaker_embeds: Optional[torch.FloatTensor] = None, - lyric_token_idx: Optional[torch.LongTensor] = None, - lyric_mask: Optional[torch.LongTensor] = None, - timestep: Optional[torch.Tensor] = None, - ssl_hidden_states: Optional[List[torch.Tensor]] = None, - block_controlnet_hidden_states: Optional[Union[List[torch.Tensor], torch.Tensor]] = None, - controlnet_scale: Union[float, torch.Tensor] = 1.0, - return_dict: bool = True, - ): - encoder_hidden_states, encoder_hidden_mask = self.encode( - encoder_text_hidden_states=encoder_text_hidden_states, - text_attention_mask=text_attention_mask, - speaker_embeds=speaker_embeds, - lyric_token_idx=lyric_token_idx, - lyric_mask=lyric_mask, - ) - - output_length = hidden_states.shape[-1] - - output = self.decode( - hidden_states=hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_hidden_mask=encoder_hidden_mask, - timestep=timestep, - ssl_hidden_states=ssl_hidden_states, - output_length=output_length, - block_controlnet_hidden_states=block_controlnet_hidden_states, - controlnet_scale=controlnet_scale, - return_dict=return_dict, - ) - - return output diff --git a/models/attention.py b/models/attention.py deleted file mode 100644 index 3c1aa89ac3d8662acbabd45662eda75f72e102d3..0000000000000000000000000000000000000000 --- a/models/attention.py +++ /dev/null @@ -1,319 +0,0 @@ -# Copyright 2024 The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from typing import Tuple, Union - -import torch -import torch.nn.functional as F -from torch import nn - -from diffusers.utils import logging -from diffusers.models.normalization import RMSNorm - - -try: - # from .dcformer import DCMHAttention - from .customer_attention_processor import Attention, CustomLiteLAProcessor2_0, CustomerAttnProcessor2_0 -except ImportError: - # from dcformer import DCMHAttention - from customer_attention_processor import Attention, CustomLiteLAProcessor2_0, CustomerAttnProcessor2_0 - - -logger = logging.get_logger(__name__) - - -def val2list(x: list or tuple or any, repeat_time=1) -> list: # type: ignore - """Repeat `val` for `repeat_time` times and return the list or val if list/tuple.""" - if isinstance(x, (list, tuple)): - return list(x) - return [x for _ in range(repeat_time)] - - -def val2tuple(x: list or tuple or any, min_len: int = 1, idx_repeat: int = -1) -> tuple: # type: ignore - """Return tuple with min_len by repeating element at idx_repeat.""" - # convert to list first - x = val2list(x) - - # repeat elements if necessary - if len(x) > 0: - x[idx_repeat:idx_repeat] = [x[idx_repeat] for _ in range(min_len - len(x))] - - return tuple(x) - - -def t2i_modulate(x, shift, scale): - return x * (1 + scale) + shift - - -def get_same_padding(kernel_size: Union[int, Tuple[int, ...]]) -> Union[int, Tuple[int, ...]]: - if isinstance(kernel_size, tuple): - return tuple([get_same_padding(ks) for ks in kernel_size]) - else: - assert kernel_size % 2 > 0, f"kernel size {kernel_size} should be odd number" - return kernel_size // 2 - -class ConvLayer(nn.Module): - def __init__( - self, - in_dim: int, - out_dim: int, - kernel_size=3, - stride=1, - dilation=1, - groups=1, - padding: Union[int, None] = None, - use_bias=False, - norm=None, - act=None, - ): - super().__init__() - if padding is None: - padding = get_same_padding(kernel_size) - padding *= dilation - - self.in_dim = in_dim - self.out_dim = out_dim - self.kernel_size = kernel_size - self.stride = stride - self.dilation = dilation - self.groups = groups - self.padding = padding - self.use_bias = use_bias - - self.conv = nn.Conv1d( - in_dim, - out_dim, - kernel_size=kernel_size, - stride=stride, - padding=padding, - dilation=dilation, - groups=groups, - bias=use_bias, - ) - if norm is not None: - self.norm = RMSNorm(out_dim, elementwise_affine=False) - else: - self.norm = None - if act is not None: - self.act = nn.SiLU(inplace=True) - else: - self.act = None - - def forward(self, x: torch.Tensor) -> torch.Tensor: - x = self.conv(x) - if self.norm: - x = self.norm(x) - if self.act: - x = self.act(x) - return x - - -class GLUMBConv(nn.Module): - def __init__( - self, - in_features: int, - hidden_features: int, - out_feature=None, - kernel_size=3, - stride=1, - padding: Union[int, None] = None, - use_bias=False, - norm=(None, None, None), - act=("silu", "silu", None), - dilation=1, - ): - out_feature = out_feature or in_features - super().__init__() - use_bias = val2tuple(use_bias, 3) - norm = val2tuple(norm, 3) - act = val2tuple(act, 3) - - self.glu_act = nn.SiLU(inplace=False) - self.inverted_conv = ConvLayer( - in_features, - hidden_features * 2, - 1, - use_bias=use_bias[0], - norm=norm[0], - act=act[0], - ) - self.depth_conv = ConvLayer( - hidden_features * 2, - hidden_features * 2, - kernel_size, - stride=stride, - groups=hidden_features * 2, - padding=padding, - use_bias=use_bias[1], - norm=norm[1], - act=None, - dilation=dilation, - ) - self.point_conv = ConvLayer( - hidden_features, - out_feature, - 1, - use_bias=use_bias[2], - norm=norm[2], - act=act[2], - ) - - def forward(self, x: torch.Tensor) -> torch.Tensor: - x = x.transpose(1, 2) - x = self.inverted_conv(x) - x = self.depth_conv(x) - - x, gate = torch.chunk(x, 2, dim=1) - gate = self.glu_act(gate) - x = x * gate - - x = self.point_conv(x) - x = x.transpose(1, 2) - - return x - - -class LinearTransformerBlock(nn.Module): - """ - A Sana block with global shared adaptive layer norm (adaLN-single) conditioning. - """ - def __init__( - self, - dim, - num_attention_heads, - attention_head_dim, - use_adaln_single=True, - cross_attention_dim=None, - added_kv_proj_dim=None, - context_pre_only=False, - mlp_ratio=4.0, - add_cross_attention=False, - add_cross_attention_dim=None, - qk_norm=None, - ): - super().__init__() - - self.norm1 = RMSNorm(dim, elementwise_affine=False, eps=1e-6) - self.attn = Attention( - query_dim=dim, - cross_attention_dim=cross_attention_dim, - added_kv_proj_dim=added_kv_proj_dim, - dim_head=attention_head_dim, - heads=num_attention_heads, - out_dim=dim, - bias=True, - qk_norm=qk_norm, - processor=CustomLiteLAProcessor2_0(), - ) - - self.add_cross_attention = add_cross_attention - self.context_pre_only = context_pre_only - - if add_cross_attention and add_cross_attention_dim is not None: - self.cross_attn = Attention( - query_dim=dim, - cross_attention_dim=add_cross_attention_dim, - added_kv_proj_dim=add_cross_attention_dim, - dim_head=attention_head_dim, - heads=num_attention_heads, - out_dim=dim, - context_pre_only=context_pre_only, - bias=True, - qk_norm=qk_norm, - processor=CustomerAttnProcessor2_0(), - ) - - self.norm2 = RMSNorm(dim, 1e-06, elementwise_affine=False) - - self.ff = GLUMBConv( - in_features=dim, - hidden_features=int(dim * mlp_ratio), - use_bias=(True, True, False), - norm=(None, None, None), - act=("silu", "silu", None), - ) - self.use_adaln_single = use_adaln_single - if use_adaln_single: - self.scale_shift_table = nn.Parameter(torch.randn(6, dim) / dim**0.5) - - def forward( - self, - hidden_states: torch.FloatTensor, - encoder_hidden_states: torch.FloatTensor = None, - attention_mask: torch.FloatTensor = None, - encoder_attention_mask: torch.FloatTensor = None, - rotary_freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]] = None, - rotary_freqs_cis_cross: Union[torch.Tensor, Tuple[torch.Tensor]] = None, - temb: torch.FloatTensor = None, - ): - - N = hidden_states.shape[0] - - # step 1: AdaLN single - if self.use_adaln_single: - shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = ( - self.scale_shift_table[None] + temb.reshape(N, 6, -1) - ).chunk(6, dim=1) - - norm_hidden_states = self.norm1(hidden_states) - if self.use_adaln_single: - norm_hidden_states = norm_hidden_states * (1 + scale_msa) + shift_msa - - # step 2: attention - if not self.add_cross_attention: - attn_output, encoder_hidden_states = self.attn( - hidden_states=norm_hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - rotary_freqs_cis=rotary_freqs_cis, - rotary_freqs_cis_cross=rotary_freqs_cis_cross, - ) - else: - attn_output, _ = self.attn( - hidden_states=norm_hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=None, - encoder_attention_mask=None, - rotary_freqs_cis=rotary_freqs_cis, - rotary_freqs_cis_cross=None, - ) - - if self.use_adaln_single: - attn_output = gate_msa * attn_output - hidden_states = attn_output + hidden_states - - if self.add_cross_attention: - attn_output = self.cross_attn( - hidden_states=hidden_states, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_attention_mask=encoder_attention_mask, - rotary_freqs_cis=rotary_freqs_cis, - rotary_freqs_cis_cross=rotary_freqs_cis_cross, - ) - hidden_states = attn_output + hidden_states - - # step 3: add norm - norm_hidden_states = self.norm2(hidden_states) - if self.use_adaln_single: - norm_hidden_states = norm_hidden_states * (1 + scale_mlp) + shift_mlp - - # step 4: feed forward - ff_output = self.ff(norm_hidden_states) - if self.use_adaln_single: - ff_output = gate_mlp * ff_output - - hidden_states = hidden_states + ff_output - - return hidden_states diff --git a/models/config.json b/models/config.json deleted file mode 100644 index e99ec4e06304e8c1c7e87e302d36d84b81b5cd4a..0000000000000000000000000000000000000000 --- a/models/config.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "_class_name": "Transformer2DModel", - "_diffusers_version": "0.27.2", - "in_channels": 8, - "num_layers": 24, - "inner_dim": 2560, - "attention_head_dim": 128, - "num_attention_heads": 20, - "mlp_ratio": 2.5, - "out_channels": 8, - "max_position": 32768, - "rope_theta": 1000000.0, - "speaker_embedding_dim": 512, - "text_embedding_dim": 768, - "ssl_encoder_depths": [8, 8], - "ssl_names": ["mert", "m-hubert"], - "ssl_latent_dims": [1024, 768], - "patch_size": [16, 1], - "max_height": 16, - "max_width": 32768, - "lyric_encoder_vocab_size": 6693, - "lyric_hidden_size": 1024 -} diff --git a/models/customer_attention_processor.py b/models/customer_attention_processor.py deleted file mode 100644 index b97779bcabf66322c295efeafac82e615aaa7811..0000000000000000000000000000000000000000 --- a/models/customer_attention_processor.py +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright 2024 The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from typing import Optional, Union, Tuple - -import torch -import torch.nn.functional as F -from torch import nn - -from diffusers.utils import logging -from diffusers.models.attention_processor import Attention - -logger = logging.get_logger(__name__) # pylint: disable=invalid-name - - -class CustomLiteLAProcessor2_0: - """Attention processor used typically in processing the SD3-like self-attention projections. add rms norm for query and key and apply RoPE""" - - def __init__(self): - self.kernel_func = nn.ReLU(inplace=False) - self.eps = 1e-15 - self.pad_val = 1.0 - - def apply_rotary_emb( - self, - x: torch.Tensor, - freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]], - ) -> Tuple[torch.Tensor, torch.Tensor]: - """ - Apply rotary embeddings to input tensors using the given frequency tensor. This function applies rotary embeddings - to the given query or key 'x' tensors using the provided frequency tensor 'freqs_cis'. The input tensors are - reshaped as complex numbers, and the frequency tensor is reshaped for broadcasting compatibility. The resulting - tensors contain rotary embeddings and are returned as real tensors. - - Args: - x (`torch.Tensor`): - Query or key tensor to apply rotary embeddings. [B, H, S, D] xk (torch.Tensor): Key tensor to apply - freqs_cis (`Tuple[torch.Tensor]`): Precomputed frequency tensor for complex exponentials. ([S, D], [S, D],) - - Returns: - Tuple[torch.Tensor, torch.Tensor]: Tuple of modified query tensor and key tensor with rotary embeddings. - """ - cos, sin = freqs_cis # [S, D] - cos = cos[None, None] - sin = sin[None, None] - cos, sin = cos.to(x.device), sin.to(x.device) - - x_real, x_imag = x.reshape(*x.shape[:-1], -1, 2).unbind(-1) # [B, S, H, D//2] - x_rotated = torch.stack([-x_imag, x_real], dim=-1).flatten(3) - out = (x.float() * cos + x_rotated.float() * sin).to(x.dtype) - - return out - - def __call__( - self, - attn: Attention, - hidden_states: torch.FloatTensor, - encoder_hidden_states: torch.FloatTensor = None, - attention_mask: Optional[torch.FloatTensor] = None, - encoder_attention_mask: Optional[torch.FloatTensor] = None, - rotary_freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]] = None, - rotary_freqs_cis_cross: Union[torch.Tensor, Tuple[torch.Tensor]] = None, - *args, - **kwargs, - ) -> torch.FloatTensor: - hidden_states_len = hidden_states.shape[1] - - input_ndim = hidden_states.ndim - if input_ndim == 4: - batch_size, channel, height, width = hidden_states.shape - hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2) - if encoder_hidden_states is not None: - context_input_ndim = encoder_hidden_states.ndim - if context_input_ndim == 4: - batch_size, channel, height, width = encoder_hidden_states.shape - encoder_hidden_states = encoder_hidden_states.view(batch_size, channel, height * width).transpose(1, 2) - - batch_size = hidden_states.shape[0] - - # `sample` projections. - dtype = hidden_states.dtype - query = attn.to_q(hidden_states) - key = attn.to_k(hidden_states) - value = attn.to_v(hidden_states) - - # `context` projections. - has_encoder_hidden_state_proj = hasattr(attn, "add_q_proj") and hasattr(attn, "add_k_proj") and hasattr(attn, "add_v_proj") - if encoder_hidden_states is not None and has_encoder_hidden_state_proj: - encoder_hidden_states_query_proj = attn.add_q_proj(encoder_hidden_states) - encoder_hidden_states_key_proj = attn.add_k_proj(encoder_hidden_states) - encoder_hidden_states_value_proj = attn.add_v_proj(encoder_hidden_states) - - # attention - if not attn.is_cross_attention: - query = torch.cat([query, encoder_hidden_states_query_proj], dim=1) - key = torch.cat([key, encoder_hidden_states_key_proj], dim=1) - value = torch.cat([value, encoder_hidden_states_value_proj], dim=1) - else: - query = hidden_states - key = encoder_hidden_states - value = encoder_hidden_states - - inner_dim = key.shape[-1] - head_dim = inner_dim // attn.heads - - query = query.transpose(-1, -2).reshape(batch_size, attn.heads, head_dim, -1) - key = key.transpose(-1, -2).reshape(batch_size, attn.heads, head_dim, -1).transpose(-1, -2) - value = value.transpose(-1, -2).reshape(batch_size, attn.heads, head_dim, -1) - - # RoPE需要 [B, H, S, D] 输入 - # 此时 query是 [B, H, D, S], 需要转成 [B, H, S, D] 才能应用RoPE - query = query.permute(0, 1, 3, 2) # [B, H, S, D] (从 [B, H, D, S]) - - # Apply query and key normalization if needed - if attn.norm_q is not None: - query = attn.norm_q(query) - if attn.norm_k is not None: - key = attn.norm_k(key) - - # Apply RoPE if needed - if rotary_freqs_cis is not None: - query = self.apply_rotary_emb(query, rotary_freqs_cis) - if not attn.is_cross_attention: - key = self.apply_rotary_emb(key, rotary_freqs_cis) - elif rotary_freqs_cis_cross is not None and has_encoder_hidden_state_proj: - key = self.apply_rotary_emb(key, rotary_freqs_cis_cross) - - # 此时 query是 [B, H, S, D],需要还原成 [B, H, D, S] - query = query.permute(0, 1, 3, 2) # [B, H, D, S] - - if attention_mask is not None: - # attention_mask: [B, S] -> [B, 1, S, 1] - attention_mask = attention_mask[:, None, :, None].to(key.dtype) # [B, 1, S, 1] - query = query * attention_mask.permute(0, 1, 3, 2) # [B, H, S, D] * [B, 1, S, 1] - if not attn.is_cross_attention: - key = key * attention_mask # key: [B, h, S, D] 与 mask [B, 1, S, 1] 相乘 - value = value * attention_mask.permute(0, 1, 3, 2) # 如果 value 是 [B, h, D, S],那么需调整mask以匹配S维度 - - if attn.is_cross_attention and encoder_attention_mask is not None and has_encoder_hidden_state_proj: - encoder_attention_mask = encoder_attention_mask[:, None, :, None].to(key.dtype) # [B, 1, S_enc, 1] - # 此时 key: [B, h, S_enc, D], value: [B, h, D, S_enc] - key = key * encoder_attention_mask # [B, h, S_enc, D] * [B, 1, S_enc, 1] - value = value * encoder_attention_mask.permute(0, 1, 3, 2) # [B, h, D, S_enc] * [B, 1, 1, S_enc] - - query = self.kernel_func(query) - key = self.kernel_func(key) - - query, key, value = query.float(), key.float(), value.float() - - value = F.pad(value, (0, 0, 0, 1), mode="constant", value=self.pad_val) - - vk = torch.matmul(value, key) - - hidden_states = torch.matmul(vk, query) - - if hidden_states.dtype in [torch.float16, torch.bfloat16]: - hidden_states = hidden_states.float() - - hidden_states = hidden_states[:, :, :-1] / (hidden_states[:, :, -1:] + self.eps) - - hidden_states = hidden_states.view(batch_size, attn.heads * head_dim, -1).permute(0, 2, 1) - - hidden_states = hidden_states.to(dtype) - if encoder_hidden_states is not None: - encoder_hidden_states = encoder_hidden_states.to(dtype) - - # Split the attention outputs. - if encoder_hidden_states is not None and not attn.is_cross_attention and has_encoder_hidden_state_proj: - hidden_states, encoder_hidden_states = ( - hidden_states[:, : hidden_states_len], - hidden_states[:, hidden_states_len:], - ) - - # linear proj - hidden_states = attn.to_out[0](hidden_states) - # dropout - hidden_states = attn.to_out[1](hidden_states) - if encoder_hidden_states is not None and not attn.context_pre_only and not attn.is_cross_attention and hasattr(attn, "to_add_out"): - encoder_hidden_states = attn.to_add_out(encoder_hidden_states) - - if input_ndim == 4: - hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width) - if encoder_hidden_states is not None and context_input_ndim == 4: - encoder_hidden_states = encoder_hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width) - - if torch.get_autocast_gpu_dtype() == torch.float16: - hidden_states = hidden_states.clip(-65504, 65504) - if encoder_hidden_states is not None: - encoder_hidden_states = encoder_hidden_states.clip(-65504, 65504) - - return hidden_states, encoder_hidden_states - - -class CustomerAttnProcessor2_0: - r""" - Processor for implementing scaled dot-product attention (enabled by default if you're using PyTorch 2.0). - """ - - def __init__(self): - if not hasattr(F, "scaled_dot_product_attention"): - raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.") - - def apply_rotary_emb( - self, - x: torch.Tensor, - freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]], - ) -> Tuple[torch.Tensor, torch.Tensor]: - """ - Apply rotary embeddings to input tensors using the given frequency tensor. This function applies rotary embeddings - to the given query or key 'x' tensors using the provided frequency tensor 'freqs_cis'. The input tensors are - reshaped as complex numbers, and the frequency tensor is reshaped for broadcasting compatibility. The resulting - tensors contain rotary embeddings and are returned as real tensors. - - Args: - x (`torch.Tensor`): - Query or key tensor to apply rotary embeddings. [B, H, S, D] xk (torch.Tensor): Key tensor to apply - freqs_cis (`Tuple[torch.Tensor]`): Precomputed frequency tensor for complex exponentials. ([S, D], [S, D],) - - Returns: - Tuple[torch.Tensor, torch.Tensor]: Tuple of modified query tensor and key tensor with rotary embeddings. - """ - cos, sin = freqs_cis # [S, D] - cos = cos[None, None] - sin = sin[None, None] - cos, sin = cos.to(x.device), sin.to(x.device) - - x_real, x_imag = x.reshape(*x.shape[:-1], -1, 2).unbind(-1) # [B, S, H, D//2] - x_rotated = torch.stack([-x_imag, x_real], dim=-1).flatten(3) - out = (x.float() * cos + x_rotated.float() * sin).to(x.dtype) - - return out - - def __call__( - self, - attn: Attention, - hidden_states: torch.FloatTensor, - encoder_hidden_states: torch.FloatTensor = None, - attention_mask: Optional[torch.FloatTensor] = None, - encoder_attention_mask: Optional[torch.FloatTensor] = None, - rotary_freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]] = None, - rotary_freqs_cis_cross: Union[torch.Tensor, Tuple[torch.Tensor]] = None, - *args, - **kwargs, - ) -> torch.Tensor: - - residual = hidden_states - input_ndim = hidden_states.ndim - - if input_ndim == 4: - batch_size, channel, height, width = hidden_states.shape - hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2) - - batch_size, sequence_length, _ = ( - hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape - ) - - has_encoder_hidden_state_proj = hasattr(attn, "add_q_proj") and hasattr(attn, "add_k_proj") and hasattr(attn, "add_v_proj") - - if attn.group_norm is not None: - hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2) - - query = attn.to_q(hidden_states) - - if encoder_hidden_states is None: - encoder_hidden_states = hidden_states - elif attn.norm_cross: - encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) - - key = attn.to_k(encoder_hidden_states) - value = attn.to_v(encoder_hidden_states) - - 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) - - if attn.norm_q is not None: - query = attn.norm_q(query) - if attn.norm_k is not None: - key = attn.norm_k(key) - - # Apply RoPE if needed - if rotary_freqs_cis is not None: - query = self.apply_rotary_emb(query, rotary_freqs_cis) - if not attn.is_cross_attention: - key = self.apply_rotary_emb(key, rotary_freqs_cis) - elif rotary_freqs_cis_cross is not None and has_encoder_hidden_state_proj: - key = self.apply_rotary_emb(key, rotary_freqs_cis_cross) - - if attn.is_cross_attention and encoder_attention_mask is not None and has_encoder_hidden_state_proj: - # attention_mask: N x S1 - # encoder_attention_mask: N x S2 - # cross attention 整合attention_mask和encoder_attention_mask - combined_mask = attention_mask[:, :, None] * encoder_attention_mask[:, None, :] - attention_mask = torch.where(combined_mask == 1, 0.0, -torch.inf) - attention_mask = attention_mask[:, None, :, :].expand(-1, attn.heads, -1, -1).to(query.dtype) - - elif not attn.is_cross_attention and attention_mask is not None: - attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size) - # scaled_dot_product_attention expects attention_mask shape to be - # (batch, heads, source_length, target_length) - attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1]) - - # the output of sdp = (batch, num_heads, seq_len, head_dim) - # TODO: add support for attn.scale when we move to Torch 2.1 - hidden_states = F.scaled_dot_product_attention( - query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False - ) - - hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim) - hidden_states = hidden_states.to(query.dtype) - - # linear proj - hidden_states = attn.to_out[0](hidden_states) - # dropout - hidden_states = attn.to_out[1](hidden_states) - - if input_ndim == 4: - hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width) - - if attn.residual_connection: - hidden_states = hidden_states + residual - - hidden_states = hidden_states / attn.rescale_output_factor - - return hidden_states diff --git a/models/lyrics_utils/lyric_encoder.py b/models/lyrics_utils/lyric_encoder.py deleted file mode 100644 index 3b80aebe8af06601fd58ab47b2867493be2eafc0..0000000000000000000000000000000000000000 --- a/models/lyrics_utils/lyric_encoder.py +++ /dev/null @@ -1,1070 +0,0 @@ -from typing import Optional, Tuple, Union -import math -import torch -from torch import nn - -class ConvolutionModule(nn.Module): - """ConvolutionModule in Conformer model.""" - - def __init__(self, - channels: int, - kernel_size: int = 15, - activation: nn.Module = nn.ReLU(), - norm: str = "batch_norm", - causal: bool = False, - bias: bool = True): - """Construct an ConvolutionModule object. - Args: - channels (int): The number of channels of conv layers. - kernel_size (int): Kernel size of conv layers. - causal (int): Whether use causal convolution or not - """ - super().__init__() - - self.pointwise_conv1 = nn.Conv1d( - channels, - 2 * channels, - kernel_size=1, - stride=1, - padding=0, - bias=bias, - ) - # self.lorder is used to distinguish if it's a causal convolution, - # if self.lorder > 0: it's a causal convolution, the input will be - # padded with self.lorder frames on the left in forward. - # else: it's a symmetrical convolution - if causal: - padding = 0 - self.lorder = kernel_size - 1 - else: - # kernel_size should be an odd number for none causal convolution - assert (kernel_size - 1) % 2 == 0 - padding = (kernel_size - 1) // 2 - self.lorder = 0 - self.depthwise_conv = nn.Conv1d( - channels, - channels, - kernel_size, - stride=1, - padding=padding, - groups=channels, - bias=bias, - ) - - assert norm in ['batch_norm', 'layer_norm'] - if norm == "batch_norm": - self.use_layer_norm = False - self.norm = nn.BatchNorm1d(channels) - else: - self.use_layer_norm = True - self.norm = nn.LayerNorm(channels) - - self.pointwise_conv2 = nn.Conv1d( - channels, - channels, - kernel_size=1, - stride=1, - padding=0, - bias=bias, - ) - self.activation = activation - - def forward( - self, - x: torch.Tensor, - mask_pad: torch.Tensor = torch.ones((0, 0, 0), dtype=torch.bool), - cache: torch.Tensor = torch.zeros((0, 0, 0)), - ) -> Tuple[torch.Tensor, torch.Tensor]: - """Compute convolution module. - Args: - x (torch.Tensor): Input tensor (#batch, time, channels). - mask_pad (torch.Tensor): used for batch padding (#batch, 1, time), - (0, 0, 0) means fake mask. - cache (torch.Tensor): left context cache, it is only - used in causal convolution (#batch, channels, cache_t), - (0, 0, 0) meas fake cache. - Returns: - torch.Tensor: Output tensor (#batch, time, channels). - """ - # exchange the temporal dimension and the feature dimension - x = x.transpose(1, 2) # (#batch, channels, time) - - # mask batch padding - if mask_pad.size(2) > 0: # time > 0 - x.masked_fill_(~mask_pad, 0.0) - - if self.lorder > 0: - if cache.size(2) == 0: # cache_t == 0 - x = nn.functional.pad(x, (self.lorder, 0), 'constant', 0.0) - else: - assert cache.size(0) == x.size(0) # equal batch - assert cache.size(1) == x.size(1) # equal channel - x = torch.cat((cache, x), dim=2) - assert (x.size(2) > self.lorder) - new_cache = x[:, :, -self.lorder:] - else: - # It's better we just return None if no cache is required, - # However, for JIT export, here we just fake one tensor instead of - # None. - new_cache = torch.zeros((0, 0, 0), dtype=x.dtype, device=x.device) - - # GLU mechanism - x = self.pointwise_conv1(x) # (batch, 2*channel, dim) - x = nn.functional.glu(x, dim=1) # (batch, channel, dim) - - # 1D Depthwise Conv - x = self.depthwise_conv(x) - if self.use_layer_norm: - x = x.transpose(1, 2) - x = self.activation(self.norm(x)) - if self.use_layer_norm: - x = x.transpose(1, 2) - x = self.pointwise_conv2(x) - # mask batch padding - if mask_pad.size(2) > 0: # time > 0 - x.masked_fill_(~mask_pad, 0.0) - - return x.transpose(1, 2), new_cache - -class PositionwiseFeedForward(torch.nn.Module): - """Positionwise feed forward layer. - - FeedForward are appied on each position of the sequence. - The output dim is same with the input dim. - - Args: - idim (int): Input dimenstion. - hidden_units (int): The number of hidden units. - dropout_rate (float): Dropout rate. - activation (torch.nn.Module): Activation function - """ - - def __init__( - self, - idim: int, - hidden_units: int, - dropout_rate: float, - activation: torch.nn.Module = torch.nn.ReLU(), - ): - """Construct a PositionwiseFeedForward object.""" - super(PositionwiseFeedForward, self).__init__() - self.w_1 = torch.nn.Linear(idim, hidden_units) - self.activation = activation - self.dropout = torch.nn.Dropout(dropout_rate) - self.w_2 = torch.nn.Linear(hidden_units, idim) - - def forward(self, xs: torch.Tensor) -> torch.Tensor: - """Forward function. - - Args: - xs: input tensor (B, L, D) - Returns: - output tensor, (B, L, D) - """ - return self.w_2(self.dropout(self.activation(self.w_1(xs)))) - -class Swish(torch.nn.Module): - """Construct an Swish object.""" - - def forward(self, x: torch.Tensor) -> torch.Tensor: - """Return Swish activation function.""" - return x * torch.sigmoid(x) - -class MultiHeadedAttention(nn.Module): - """Multi-Head Attention layer. - - Args: - n_head (int): The number of heads. - n_feat (int): The number of features. - dropout_rate (float): Dropout rate. - - """ - - def __init__(self, - n_head: int, - n_feat: int, - dropout_rate: float, - key_bias: bool = True): - """Construct an MultiHeadedAttention object.""" - super().__init__() - assert n_feat % n_head == 0 - # We assume d_v always equals d_k - self.d_k = n_feat // n_head - self.h = n_head - self.linear_q = nn.Linear(n_feat, n_feat) - self.linear_k = nn.Linear(n_feat, n_feat, bias=key_bias) - self.linear_v = nn.Linear(n_feat, n_feat) - self.linear_out = nn.Linear(n_feat, n_feat) - self.dropout = nn.Dropout(p=dropout_rate) - - def forward_qkv( - self, query: torch.Tensor, key: torch.Tensor, value: torch.Tensor - ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: - """Transform query, key and value. - - Args: - query (torch.Tensor): Query tensor (#batch, time1, size). - key (torch.Tensor): Key tensor (#batch, time2, size). - value (torch.Tensor): Value tensor (#batch, time2, size). - - Returns: - torch.Tensor: Transformed query tensor, size - (#batch, n_head, time1, d_k). - torch.Tensor: Transformed key tensor, size - (#batch, n_head, time2, d_k). - torch.Tensor: Transformed value tensor, size - (#batch, n_head, time2, d_k). - - """ - n_batch = query.size(0) - q = self.linear_q(query).view(n_batch, -1, self.h, self.d_k) - k = self.linear_k(key).view(n_batch, -1, self.h, self.d_k) - v = self.linear_v(value).view(n_batch, -1, self.h, self.d_k) - q = q.transpose(1, 2) # (batch, head, time1, d_k) - k = k.transpose(1, 2) # (batch, head, time2, d_k) - v = v.transpose(1, 2) # (batch, head, time2, d_k) - return q, k, v - - def forward_attention( - self, - value: torch.Tensor, - scores: torch.Tensor, - mask: torch.Tensor = torch.ones((0, 0, 0), dtype=torch.bool) - ) -> torch.Tensor: - """Compute attention context vector. - - Args: - value (torch.Tensor): Transformed value, size - (#batch, n_head, time2, d_k). - scores (torch.Tensor): Attention score, size - (#batch, n_head, time1, time2). - mask (torch.Tensor): Mask, size (#batch, 1, time2) or - (#batch, time1, time2), (0, 0, 0) means fake mask. - - Returns: - torch.Tensor: Transformed value (#batch, time1, d_model) - weighted by the attention score (#batch, time1, time2). - - """ - n_batch = value.size(0) - - if mask.size(2) > 0: # time2 > 0 - mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - # For last chunk, time2 might be larger than scores.size(-1) - mask = mask[:, :, :, :scores.size(-1)] # (batch, 1, *, time2) - scores = scores.masked_fill(mask, -float('inf')) - attn = torch.softmax(scores, dim=-1).masked_fill( - mask, 0.0) # (batch, head, time1, time2) - - else: - attn = torch.softmax(scores, dim=-1) # (batch, head, time1, time2) - - p_attn = self.dropout(attn) - x = torch.matmul(p_attn, value) # (batch, head, time1, d_k) - x = (x.transpose(1, 2).contiguous().view(n_batch, -1, - self.h * self.d_k) - ) # (batch, time1, d_model) - - return self.linear_out(x) # (batch, time1, d_model) - - def forward( - self, - query: torch.Tensor, - key: torch.Tensor, - value: torch.Tensor, - mask: torch.Tensor = torch.ones((0, 0, 0), dtype=torch.bool), - pos_emb: torch.Tensor = torch.empty(0), - cache: torch.Tensor = torch.zeros((0, 0, 0, 0)) - ) -> Tuple[torch.Tensor, torch.Tensor]: - """Compute scaled dot product attention. - - Args: - query (torch.Tensor): Query tensor (#batch, time1, size). - key (torch.Tensor): Key tensor (#batch, time2, size). - value (torch.Tensor): Value tensor (#batch, time2, size). - mask (torch.Tensor): Mask tensor (#batch, 1, time2) or - (#batch, time1, time2). - 1.When applying cross attention between decoder and encoder, - the batch padding mask for input is in (#batch, 1, T) shape. - 2.When applying self attention of encoder, - the mask is in (#batch, T, T) shape. - 3.When applying self attention of decoder, - the mask is in (#batch, L, L) shape. - 4.If the different position in decoder see different block - of the encoder, such as Mocha, the passed in mask could be - in (#batch, L, T) shape. But there is no such case in current - CosyVoice. - cache (torch.Tensor): Cache tensor (1, head, cache_t, d_k * 2), - where `cache_t == chunk_size * num_decoding_left_chunks` - and `head * d_k == size` - - - Returns: - torch.Tensor: Output tensor (#batch, time1, d_model). - torch.Tensor: Cache tensor (1, head, cache_t + time1, d_k * 2) - where `cache_t == chunk_size * num_decoding_left_chunks` - and `head * d_k == size` - - """ - q, k, v = self.forward_qkv(query, key, value) - if cache.size(0) > 0: - key_cache, value_cache = torch.split(cache, - cache.size(-1) // 2, - dim=-1) - k = torch.cat([key_cache, k], dim=2) - v = torch.cat([value_cache, v], dim=2) - new_cache = torch.cat((k, v), dim=-1) - - scores = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(self.d_k) - return self.forward_attention(v, scores, mask), new_cache - - -class RelPositionMultiHeadedAttention(MultiHeadedAttention): - """Multi-Head Attention layer with relative position encoding. - Paper: https://arxiv.org/abs/1901.02860 - Args: - n_head (int): The number of heads. - n_feat (int): The number of features. - dropout_rate (float): Dropout rate. - """ - - def __init__(self, - n_head: int, - n_feat: int, - dropout_rate: float, - key_bias: bool = True): - """Construct an RelPositionMultiHeadedAttention object.""" - super().__init__(n_head, n_feat, dropout_rate, key_bias) - # linear transformation for positional encoding - self.linear_pos = nn.Linear(n_feat, n_feat, bias=False) - # these two learnable bias are used in matrix c and matrix d - # as described in https://arxiv.org/abs/1901.02860 Section 3.3 - self.pos_bias_u = nn.Parameter(torch.Tensor(self.h, self.d_k)) - self.pos_bias_v = nn.Parameter(torch.Tensor(self.h, self.d_k)) - torch.nn.init.xavier_uniform_(self.pos_bias_u) - torch.nn.init.xavier_uniform_(self.pos_bias_v) - - def rel_shift(self, x: torch.Tensor) -> torch.Tensor: - """Compute relative positional encoding. - - Args: - x (torch.Tensor): Input tensor (batch, head, time1, 2*time1-1). - time1 means the length of query vector. - - Returns: - torch.Tensor: Output tensor. - - """ - zero_pad = torch.zeros((x.size()[0], x.size()[1], x.size()[2], 1), - device=x.device, - dtype=x.dtype) - x_padded = torch.cat([zero_pad, x], dim=-1) - - x_padded = x_padded.view(x.size()[0], - x.size()[1], - x.size(3) + 1, x.size(2)) - x = x_padded[:, :, 1:].view_as(x)[ - :, :, :, : x.size(-1) // 2 + 1 - ] # only keep the positions from 0 to time2 - return x - - def forward( - self, - query: torch.Tensor, - key: torch.Tensor, - value: torch.Tensor, - mask: torch.Tensor = torch.ones((0, 0, 0), dtype=torch.bool), - pos_emb: torch.Tensor = torch.empty(0), - cache: torch.Tensor = torch.zeros((0, 0, 0, 0)) - ) -> Tuple[torch.Tensor, torch.Tensor]: - """Compute 'Scaled Dot Product Attention' with rel. positional encoding. - Args: - query (torch.Tensor): Query tensor (#batch, time1, size). - key (torch.Tensor): Key tensor (#batch, time2, size). - value (torch.Tensor): Value tensor (#batch, time2, size). - mask (torch.Tensor): Mask tensor (#batch, 1, time2) or - (#batch, time1, time2), (0, 0, 0) means fake mask. - pos_emb (torch.Tensor): Positional embedding tensor - (#batch, time2, size). - cache (torch.Tensor): Cache tensor (1, head, cache_t, d_k * 2), - where `cache_t == chunk_size * num_decoding_left_chunks` - and `head * d_k == size` - Returns: - torch.Tensor: Output tensor (#batch, time1, d_model). - torch.Tensor: Cache tensor (1, head, cache_t + time1, d_k * 2) - where `cache_t == chunk_size * num_decoding_left_chunks` - and `head * d_k == size` - """ - q, k, v = self.forward_qkv(query, key, value) - q = q.transpose(1, 2) # (batch, time1, head, d_k) - - if cache.size(0) > 0: - key_cache, value_cache = torch.split(cache, - cache.size(-1) // 2, - dim=-1) - k = torch.cat([key_cache, k], dim=2) - v = torch.cat([value_cache, v], dim=2) - # NOTE(xcsong): We do cache slicing in encoder.forward_chunk, since it's - # non-trivial to calculate `next_cache_start` here. - new_cache = torch.cat((k, v), dim=-1) - - n_batch_pos = pos_emb.size(0) - p = self.linear_pos(pos_emb).view(n_batch_pos, -1, self.h, self.d_k) - p = p.transpose(1, 2) # (batch, head, time1, d_k) - - # (batch, head, time1, d_k) - q_with_bias_u = (q + self.pos_bias_u).transpose(1, 2) - # (batch, head, time1, d_k) - q_with_bias_v = (q + self.pos_bias_v).transpose(1, 2) - - # compute attention score - # first compute matrix a and matrix c - # as described in https://arxiv.org/abs/1901.02860 Section 3.3 - # (batch, head, time1, time2) - matrix_ac = torch.matmul(q_with_bias_u, k.transpose(-2, -1)) - - # compute matrix b and matrix d - # (batch, head, time1, time2) - matrix_bd = torch.matmul(q_with_bias_v, p.transpose(-2, -1)) - # NOTE(Xiang Lyu): Keep rel_shift since espnet rel_pos_emb is used - if matrix_ac.shape != matrix_bd.shape: - matrix_bd = self.rel_shift(matrix_bd) - - scores = (matrix_ac + matrix_bd) / math.sqrt( - self.d_k) # (batch, head, time1, time2) - - return self.forward_attention(v, scores, mask), new_cache - - - -def subsequent_mask( - size: int, - device: torch.device = torch.device("cpu"), -) -> torch.Tensor: - """Create mask for subsequent steps (size, size). - - This mask is used only in decoder which works in an auto-regressive mode. - This means the current step could only do attention with its left steps. - - In encoder, fully attention is used when streaming is not necessary and - the sequence is not long. In this case, no attention mask is needed. - - When streaming is need, chunk-based attention is used in encoder. See - subsequent_chunk_mask for the chunk-based attention mask. - - Args: - size (int): size of mask - str device (str): "cpu" or "cuda" or torch.Tensor.device - dtype (torch.device): result dtype - - Returns: - torch.Tensor: mask - - Examples: - >>> subsequent_mask(3) - [[1, 0, 0], - [1, 1, 0], - [1, 1, 1]] - """ - arange = torch.arange(size, device=device) - mask = arange.expand(size, size) - arange = arange.unsqueeze(-1) - mask = mask <= arange - return mask - - -def subsequent_chunk_mask( - size: int, - chunk_size: int, - num_left_chunks: int = -1, - device: torch.device = torch.device("cpu"), - ) -> torch.Tensor: - """Create mask for subsequent steps (size, size) with chunk size, - this is for streaming encoder - - Args: - size (int): size of mask - chunk_size (int): size of chunk - num_left_chunks (int): number of left chunks - <0: use full chunk - >=0: use num_left_chunks - device (torch.device): "cpu" or "cuda" or torch.Tensor.device - - Returns: - torch.Tensor: mask - - Examples: - >>> subsequent_chunk_mask(4, 2) - [[1, 1, 0, 0], - [1, 1, 0, 0], - [1, 1, 1, 1], - [1, 1, 1, 1]] - """ - ret = torch.zeros(size, size, device=device, dtype=torch.bool) - for i in range(size): - if num_left_chunks < 0: - start = 0 - else: - start = max((i // chunk_size - num_left_chunks) * chunk_size, 0) - ending = min((i // chunk_size + 1) * chunk_size, size) - ret[i, start:ending] = True - return ret - -def add_optional_chunk_mask(xs: torch.Tensor, - masks: torch.Tensor, - use_dynamic_chunk: bool, - use_dynamic_left_chunk: bool, - decoding_chunk_size: int, - static_chunk_size: int, - num_decoding_left_chunks: int, - enable_full_context: bool = True): - """ Apply optional mask for encoder. - - Args: - xs (torch.Tensor): padded input, (B, L, D), L for max length - mask (torch.Tensor): mask for xs, (B, 1, L) - use_dynamic_chunk (bool): whether to use dynamic chunk or not - use_dynamic_left_chunk (bool): whether to use dynamic left chunk for - training. - decoding_chunk_size (int): decoding chunk size for dynamic chunk, it's - 0: default for training, use random dynamic chunk. - <0: for decoding, use full chunk. - >0: for decoding, use fixed chunk size as set. - static_chunk_size (int): chunk size for static chunk training/decoding - if it's greater than 0, if use_dynamic_chunk is true, - this parameter will be ignored - num_decoding_left_chunks: number of left chunks, this is for decoding, - the chunk size is decoding_chunk_size. - >=0: use num_decoding_left_chunks - <0: use all left chunks - enable_full_context (bool): - True: chunk size is either [1, 25] or full context(max_len) - False: chunk size ~ U[1, 25] - - Returns: - torch.Tensor: chunk mask of the input xs. - """ - # Whether to use chunk mask or not - if use_dynamic_chunk: - max_len = xs.size(1) - if decoding_chunk_size < 0: - chunk_size = max_len - num_left_chunks = -1 - elif decoding_chunk_size > 0: - chunk_size = decoding_chunk_size - num_left_chunks = num_decoding_left_chunks - else: - # chunk size is either [1, 25] or full context(max_len). - # Since we use 4 times subsampling and allow up to 1s(100 frames) - # delay, the maximum frame is 100 / 4 = 25. - chunk_size = torch.randint(1, max_len, (1, )).item() - num_left_chunks = -1 - if chunk_size > max_len // 2 and enable_full_context: - chunk_size = max_len - else: - chunk_size = chunk_size % 25 + 1 - if use_dynamic_left_chunk: - max_left_chunks = (max_len - 1) // chunk_size - num_left_chunks = torch.randint(0, max_left_chunks, - (1, )).item() - chunk_masks = subsequent_chunk_mask(xs.size(1), chunk_size, - num_left_chunks, - xs.device) # (L, L) - chunk_masks = chunk_masks.unsqueeze(0) # (1, L, L) - chunk_masks = masks & chunk_masks # (B, L, L) - elif static_chunk_size > 0: - num_left_chunks = num_decoding_left_chunks - chunk_masks = subsequent_chunk_mask(xs.size(1), static_chunk_size, - num_left_chunks, - xs.device) # (L, L) - chunk_masks = chunk_masks.unsqueeze(0) # (1, L, L) - chunk_masks = masks & chunk_masks # (B, L, L) - else: - chunk_masks = masks - return chunk_masks - - -class ConformerEncoderLayer(nn.Module): - """Encoder layer module. - Args: - size (int): Input dimension. - self_attn (torch.nn.Module): Self-attention module instance. - `MultiHeadedAttention` or `RelPositionMultiHeadedAttention` - instance can be used as the argument. - feed_forward (torch.nn.Module): Feed-forward module instance. - `PositionwiseFeedForward` instance can be used as the argument. - feed_forward_macaron (torch.nn.Module): Additional feed-forward module - instance. - `PositionwiseFeedForward` instance can be used as the argument. - conv_module (torch.nn.Module): Convolution module instance. - `ConvlutionModule` instance can be used as the argument. - dropout_rate (float): Dropout rate. - normalize_before (bool): - True: use layer_norm before each sub-block. - False: use layer_norm after each sub-block. - """ - - def __init__( - self, - size: int, - self_attn: torch.nn.Module, - feed_forward: Optional[nn.Module] = None, - feed_forward_macaron: Optional[nn.Module] = None, - conv_module: Optional[nn.Module] = None, - dropout_rate: float = 0.1, - normalize_before: bool = True, - ): - """Construct an EncoderLayer object.""" - super().__init__() - self.self_attn = self_attn - self.feed_forward = feed_forward - self.feed_forward_macaron = feed_forward_macaron - self.conv_module = conv_module - self.norm_ff = nn.LayerNorm(size, eps=1e-5) # for the FNN module - self.norm_mha = nn.LayerNorm(size, eps=1e-5) # for the MHA module - if feed_forward_macaron is not None: - self.norm_ff_macaron = nn.LayerNorm(size, eps=1e-5) - self.ff_scale = 0.5 - else: - self.ff_scale = 1.0 - if self.conv_module is not None: - self.norm_conv = nn.LayerNorm(size, eps=1e-5) # for the CNN module - self.norm_final = nn.LayerNorm( - size, eps=1e-5) # for the final output of the block - self.dropout = nn.Dropout(dropout_rate) - self.size = size - self.normalize_before = normalize_before - - def forward( - self, - x: torch.Tensor, - mask: torch.Tensor, - pos_emb: torch.Tensor, - mask_pad: torch.Tensor = torch.ones((0, 0, 0), dtype=torch.bool), - att_cache: torch.Tensor = torch.zeros((0, 0, 0, 0)), - cnn_cache: torch.Tensor = torch.zeros((0, 0, 0, 0)), - ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: - """Compute encoded features. - - Args: - x (torch.Tensor): (#batch, time, size) - mask (torch.Tensor): Mask tensor for the input (#batch, time,time), - (0, 0, 0) means fake mask. - pos_emb (torch.Tensor): positional encoding, must not be None - for ConformerEncoderLayer. - mask_pad (torch.Tensor): batch padding mask used for conv module. - (#batch, 1,time), (0, 0, 0) means fake mask. - att_cache (torch.Tensor): Cache tensor of the KEY & VALUE - (#batch=1, head, cache_t1, d_k * 2), head * d_k == size. - cnn_cache (torch.Tensor): Convolution cache in conformer layer - (#batch=1, size, cache_t2) - Returns: - torch.Tensor: Output tensor (#batch, time, size). - torch.Tensor: Mask tensor (#batch, time, time). - torch.Tensor: att_cache tensor, - (#batch=1, head, cache_t1 + time, d_k * 2). - torch.Tensor: cnn_cahce tensor (#batch, size, cache_t2). - """ - - # whether to use macaron style - if self.feed_forward_macaron is not None: - residual = x - if self.normalize_before: - x = self.norm_ff_macaron(x) - x = residual + self.ff_scale * self.dropout( - self.feed_forward_macaron(x)) - if not self.normalize_before: - x = self.norm_ff_macaron(x) - - # multi-headed self-attention module - residual = x - if self.normalize_before: - x = self.norm_mha(x) - x_att, new_att_cache = self.self_attn(x, x, x, mask, pos_emb, - att_cache) - x = residual + self.dropout(x_att) - if not self.normalize_before: - x = self.norm_mha(x) - - # convolution module - # Fake new cnn cache here, and then change it in conv_module - new_cnn_cache = torch.zeros((0, 0, 0), dtype=x.dtype, device=x.device) - if self.conv_module is not None: - residual = x - if self.normalize_before: - x = self.norm_conv(x) - x, new_cnn_cache = self.conv_module(x, mask_pad, cnn_cache) - x = residual + self.dropout(x) - - if not self.normalize_before: - x = self.norm_conv(x) - - # feed forward module - residual = x - if self.normalize_before: - x = self.norm_ff(x) - - x = residual + self.ff_scale * self.dropout(self.feed_forward(x)) - if not self.normalize_before: - x = self.norm_ff(x) - - if self.conv_module is not None: - x = self.norm_final(x) - - return x, mask, new_att_cache, new_cnn_cache - - - -class EspnetRelPositionalEncoding(torch.nn.Module): - """Relative positional encoding module (new implementation). - - Details can be found in https://github.com/espnet/espnet/pull/2816. - - See : Appendix B in https://arxiv.org/abs/1901.02860 - - Args: - d_model (int): Embedding dimension. - dropout_rate (float): Dropout rate. - max_len (int): Maximum input length. - - """ - - def __init__(self, d_model: int, dropout_rate: float, max_len: int = 5000): - """Construct an PositionalEncoding object.""" - super(EspnetRelPositionalEncoding, self).__init__() - self.d_model = d_model - self.xscale = math.sqrt(self.d_model) - self.dropout = torch.nn.Dropout(p=dropout_rate) - self.pe = None - self.extend_pe(torch.tensor(0.0).expand(1, max_len)) - - def extend_pe(self, x: torch.Tensor): - """Reset the positional encodings.""" - if self.pe is not None: - # self.pe contains both positive and negative parts - # the length of self.pe is 2 * input_len - 1 - if self.pe.size(1) >= x.size(1) * 2 - 1: - if self.pe.dtype != x.dtype or self.pe.device != x.device: - self.pe = self.pe.to(dtype=x.dtype, device=x.device) - return - # Suppose `i` means to the position of query vecotr and `j` means the - # position of key vector. We use position relative positions when keys - # are to the left (i>j) and negative relative positions otherwise (i Tuple[torch.Tensor, torch.Tensor]: - """Add positional encoding. - - Args: - x (torch.Tensor): Input tensor (batch, time, `*`). - - Returns: - torch.Tensor: Encoded tensor (batch, time, `*`). - - """ - self.extend_pe(x) - x = x * self.xscale - pos_emb = self.position_encoding(size=x.size(1), offset=offset) - return self.dropout(x), self.dropout(pos_emb) - - def position_encoding(self, - offset: Union[int, torch.Tensor], - size: int) -> torch.Tensor: - """ For getting encoding in a streaming fashion - - Attention!!!!! - we apply dropout only once at the whole utterance level in a none - streaming way, but will call this function several times with - increasing input size in a streaming scenario, so the dropout will - be applied several times. - - Args: - offset (int or torch.tensor): start offset - size (int): required size of position encoding - - Returns: - torch.Tensor: Corresponding encoding - """ - pos_emb = self.pe[ - :, - self.pe.size(1) // 2 - size + 1: self.pe.size(1) // 2 + size, - ] - return pos_emb - - - -class LinearEmbed(torch.nn.Module): - """Linear transform the input without subsampling - - Args: - idim (int): Input dimension. - odim (int): Output dimension. - dropout_rate (float): Dropout rate. - - """ - - def __init__(self, idim: int, odim: int, dropout_rate: float, - pos_enc_class: torch.nn.Module): - """Construct an linear object.""" - super().__init__() - self.out = torch.nn.Sequential( - torch.nn.Linear(idim, odim), - torch.nn.LayerNorm(odim, eps=1e-5), - torch.nn.Dropout(dropout_rate), - ) - self.pos_enc = pos_enc_class #rel_pos_espnet - - def position_encoding(self, offset: Union[int, torch.Tensor], - size: int) -> torch.Tensor: - return self.pos_enc.position_encoding(offset, size) - - def forward( - self, - x: torch.Tensor, - offset: Union[int, torch.Tensor] = 0 - ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: - """Input x. - - Args: - x (torch.Tensor): Input tensor (#batch, time, idim). - x_mask (torch.Tensor): Input mask (#batch, 1, time). - - Returns: - torch.Tensor: linear input tensor (#batch, time', odim), - where time' = time . - torch.Tensor: linear input mask (#batch, 1, time'), - where time' = time . - - """ - x = self.out(x) - x, pos_emb = self.pos_enc(x, offset) - return x, pos_emb - - -ATTENTION_CLASSES = { - "selfattn": MultiHeadedAttention, - "rel_selfattn": RelPositionMultiHeadedAttention, -} - -ACTIVATION_CLASSES = { - "hardtanh": torch.nn.Hardtanh, - "tanh": torch.nn.Tanh, - "relu": torch.nn.ReLU, - "selu": torch.nn.SELU, - "swish": getattr(torch.nn, "SiLU", Swish), - "gelu": torch.nn.GELU, -} - - -def make_pad_mask(lengths: torch.Tensor, max_len: int = 0) -> torch.Tensor: - """Make mask tensor containing indices of padded part. - - See description of make_non_pad_mask. - - Args: - lengths (torch.Tensor): Batch of lengths (B,). - Returns: - torch.Tensor: Mask tensor containing indices of padded part. - - Examples: - >>> lengths = [5, 3, 2] - >>> make_pad_mask(lengths) - masks = [[0, 0, 0, 0 ,0], - [0, 0, 0, 1, 1], - [0, 0, 1, 1, 1]] - """ - batch_size = lengths.size(0) - max_len = max_len if max_len > 0 else lengths.max().item() - seq_range = torch.arange(0, - max_len, - dtype=torch.int64, - device=lengths.device) - seq_range_expand = seq_range.unsqueeze(0).expand(batch_size, max_len) - seq_length_expand = lengths.unsqueeze(-1) - mask = seq_range_expand >= seq_length_expand - return mask - -#https://github.com/FunAudioLLM/CosyVoice/blob/main/examples/magicdata-read/cosyvoice/conf/cosyvoice.yaml -class ConformerEncoder(torch.nn.Module): - """Conformer encoder module.""" - - def __init__( - self, - input_size: int, - output_size: int = 1024, - attention_heads: int = 16, - linear_units: int = 4096, - num_blocks: int = 6, - dropout_rate: float = 0.1, - positional_dropout_rate: float = 0.1, - attention_dropout_rate: float = 0.0, - input_layer: str = 'linear', - pos_enc_layer_type: str = 'rel_pos_espnet', - normalize_before: bool = True, - static_chunk_size: int = 1, # 1: causal_mask; 0: full_mask - use_dynamic_chunk: bool = False, - use_dynamic_left_chunk: bool = False, - positionwise_conv_kernel_size: int = 1, - macaron_style: bool =False, - selfattention_layer_type: str = "rel_selfattn", - activation_type: str = "swish", - use_cnn_module: bool = False, - cnn_module_kernel: int = 15, - causal: bool = False, - cnn_module_norm: str = "batch_norm", - key_bias: bool = True, - gradient_checkpointing: bool = False, - ): - """Construct ConformerEncoder - - Args: - input_size to use_dynamic_chunk, see in BaseEncoder - positionwise_conv_kernel_size (int): Kernel size of positionwise - conv1d layer. - macaron_style (bool): Whether to use macaron style for - positionwise layer. - selfattention_layer_type (str): Encoder attention layer type, - the parameter has no effect now, it's just for configure - compatibility. #'rel_selfattn' - activation_type (str): Encoder activation function type. - use_cnn_module (bool): Whether to use convolution module. - cnn_module_kernel (int): Kernel size of convolution module. - causal (bool): whether to use causal convolution or not. - key_bias: whether use bias in attention.linear_k, False for whisper models. - """ - super().__init__() - self.output_size = output_size - self.embed = LinearEmbed(input_size, output_size, dropout_rate, - EspnetRelPositionalEncoding(output_size, positional_dropout_rate)) - self.normalize_before = normalize_before - self.after_norm = torch.nn.LayerNorm(output_size, eps=1e-5) - self.gradient_checkpointing = gradient_checkpointing - self.use_dynamic_chunk = use_dynamic_chunk - - self.static_chunk_size = static_chunk_size - self.use_dynamic_chunk = use_dynamic_chunk - self.use_dynamic_left_chunk = use_dynamic_left_chunk - activation = ACTIVATION_CLASSES[activation_type]() - - # self-attention module definition - encoder_selfattn_layer_args = ( - attention_heads, - output_size, - attention_dropout_rate, - key_bias, - ) - # feed-forward module definition - positionwise_layer_args = ( - output_size, - linear_units, - dropout_rate, - activation, - ) - # convolution module definition - convolution_layer_args = (output_size, cnn_module_kernel, activation, - cnn_module_norm, causal) - - self.encoders = torch.nn.ModuleList([ - ConformerEncoderLayer( - output_size, - RelPositionMultiHeadedAttention( - *encoder_selfattn_layer_args), - PositionwiseFeedForward(*positionwise_layer_args), - PositionwiseFeedForward( - *positionwise_layer_args) if macaron_style else None, - ConvolutionModule( - *convolution_layer_args) if use_cnn_module else None, - dropout_rate, - normalize_before, - ) for _ in range(num_blocks) - ]) - - def forward_layers(self, xs: torch.Tensor, chunk_masks: torch.Tensor, - pos_emb: torch.Tensor, - mask_pad: torch.Tensor) -> torch.Tensor: - for layer in self.encoders: - xs, chunk_masks, _, _ = layer(xs, chunk_masks, pos_emb, mask_pad) - return xs - - @torch.jit.unused - def forward_layers_checkpointed(self, xs: torch.Tensor, - chunk_masks: torch.Tensor, - pos_emb: torch.Tensor, - mask_pad: torch.Tensor) -> torch.Tensor: - for layer in self.encoders: - xs, chunk_masks, _, _ = ckpt.checkpoint(layer.__call__, xs, - chunk_masks, pos_emb, - mask_pad) - return xs - - def forward( - self, - xs: torch.Tensor, - pad_mask: torch.Tensor, - decoding_chunk_size: int = 0, - num_decoding_left_chunks: int = -1, - ) -> Tuple[torch.Tensor, torch.Tensor]: - """Embed positions in tensor. - - Args: - xs: padded input tensor (B, T, D) - xs_lens: input length (B) - decoding_chunk_size: decoding chunk size for dynamic chunk - 0: default for training, use random dynamic chunk. - <0: for decoding, use full chunk. - >0: for decoding, use fixed chunk size as set. - num_decoding_left_chunks: number of left chunks, this is for decoding, - the chunk size is decoding_chunk_size. - >=0: use num_decoding_left_chunks - <0: use all left chunks - Returns: - encoder output tensor xs, and subsampled masks - xs: padded output tensor (B, T' ~= T/subsample_rate, D) - masks: torch.Tensor batch padding mask after subsample - (B, 1, T' ~= T/subsample_rate) - NOTE(xcsong): - We pass the `__call__` method of the modules instead of `forward` to the - checkpointing API because `__call__` attaches all the hooks of the module. - https://discuss.pytorch.org/t/any-different-between-model-input-and-model-forward-input/3690/2 - """ - T = xs.size(1) - masks = pad_mask.to(torch.bool).unsqueeze(1) # (B, 1, T) - xs, pos_emb = self.embed(xs) - mask_pad = masks # (B, 1, T/subsample_rate) - chunk_masks = add_optional_chunk_mask(xs, masks, - self.use_dynamic_chunk, - self.use_dynamic_left_chunk, - decoding_chunk_size, - self.static_chunk_size, - num_decoding_left_chunks) - if self.gradient_checkpointing and self.training: - xs = self.forward_layers_checkpointed(xs, chunk_masks, pos_emb, - mask_pad) - else: - xs = self.forward_layers(xs, chunk_masks, pos_emb, mask_pad) - if self.normalize_before: - xs = self.after_norm(xs) - # Here we assume the mask is not changed in encoder layers, so just - # return the masks before encoder layers, and the masks will be used - # for cross attention with decoder later - return xs, masks - diff --git a/models/lyrics_utils/lyric_normalizer.py b/models/lyrics_utils/lyric_normalizer.py deleted file mode 100644 index 153cb79db3add5f23376543d6855bf0452dc470a..0000000000000000000000000000000000000000 --- a/models/lyrics_utils/lyric_normalizer.py +++ /dev/null @@ -1,66 +0,0 @@ -import re -from opencc import OpenCC - - -t2s_converter = OpenCC('t2s') -s2t_converter = OpenCC('s2t') - - -EMOJI_PATTERN = re.compile( - "[" - "\U0001F600-\U0001F64F" # Emoticons - "]+", flags=re.UNICODE -) - -# 创建一个翻译表,用于替换和移除字符 -TRANSLATION_TABLE = str.maketrans({ - '-': ' ', # 将 '-' 替换为空格 - ',': None, - '.': None, - ',': None, - '。': None, - '!': None, - '!': None, - '?': None, - '?': None, - '…': None, - ';': None, - ';': None, - ':': None, - ':': None, - '\u3000': ' ', # 将全角空格替换为空格 -}) - -# 替换括号中的内容,包括中括号和小括号 -BACKSLASH_PATTERN = re.compile(r'\(.*?\)|\[.*?\]') - -SPACE_PATTERN = re.compile('(?= text_split_length: - text_splits.append("") - nlp = get_spacy_lang(lang) - nlp.add_pipe("sentencizer") - doc = nlp(text) - for sentence in doc.sents: - if len(text_splits[-1]) + len(str(sentence)) <= text_split_length: - # if the last sentence + the current sentence is less than the text_split_length - # then add the current sentence to the last sentence - text_splits[-1] += " " + str(sentence) - text_splits[-1] = text_splits[-1].lstrip() - elif len(str(sentence)) > text_split_length: - # if the current sentence is greater than the text_split_length - for line in textwrap.wrap( - str(sentence), - width=text_split_length, - drop_whitespace=True, - break_on_hyphens=False, - tabsize=1, - ): - text_splits.append(str(line)) - else: - text_splits.append(str(sentence)) - - if len(text_splits) > 1: - if text_splits[0] == "": - del text_splits[0] - else: - text_splits = [text.lstrip()] - - return text_splits - - -_whitespace_re = re.compile(r"\s+") - -# List of (regular expression, replacement) pairs for abbreviations: -_abbreviations = { - "en": [ - (re.compile("\\b%s\\." % 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"), - ] - ], - "es": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("sra", "señora"), - ("sr", "señor"), - ("dr", "doctor"), - ("dra", "doctora"), - ("st", "santo"), - ("co", "compañía"), - ("jr", "junior"), - ("ltd", "limitada"), - ] - ], - "fr": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("mme", "madame"), - ("mr", "monsieur"), - ("dr", "docteur"), - ("st", "saint"), - ("co", "compagnie"), - ("jr", "junior"), - ("ltd", "limitée"), - ] - ], - "de": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("fr", "frau"), - ("dr", "doktor"), - ("st", "sankt"), - ("co", "firma"), - ("jr", "junior"), - ] - ], - "pt": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("sra", "senhora"), - ("sr", "senhor"), - ("dr", "doutor"), - ("dra", "doutora"), - ("st", "santo"), - ("co", "companhia"), - ("jr", "júnior"), - ("ltd", "limitada"), - ] - ], - "it": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - # ("sig.ra", "signora"), - ("sig", "signore"), - ("dr", "dottore"), - ("st", "santo"), - ("co", "compagnia"), - ("jr", "junior"), - ("ltd", "limitata"), - ] - ], - "pl": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("p", "pani"), - ("m", "pan"), - ("dr", "doktor"), - ("sw", "święty"), - ("jr", "junior"), - ] - ], - "ar": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - # There are not many common abbreviations in Arabic as in English. - ] - ], - "zh": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - # Chinese doesn't typically use abbreviations in the same way as Latin-based scripts. - ] - ], - "cs": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("dr", "doktor"), # doctor - ("ing", "inženýr"), # engineer - ("p", "pan"), # Could also map to pani for woman but no easy way to do it - # Other abbreviations would be specialized and not as common. - ] - ], - "ru": [ - (re.compile("\\b%s\\b" % x[0], re.IGNORECASE), x[1]) - for x in [ - ("г-жа", "госпожа"), # Mrs. - ("г-н", "господин"), # Mr. - ("д-р", "доктор"), # doctor - # Other abbreviations are less common or specialized. - ] - ], - "nl": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("dhr", "de heer"), # Mr. - ("mevr", "mevrouw"), # Mrs. - ("dr", "dokter"), # doctor - ("jhr", "jonkheer"), # young lord or nobleman - # Dutch uses more abbreviations, but these are the most common ones. - ] - ], - "tr": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("b", "bay"), # Mr. - ("byk", "büyük"), # büyük - ("dr", "doktor"), # doctor - # Add other Turkish abbreviations here if needed. - ] - ], - "hu": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - ("dr", "doktor"), # doctor - ("b", "bácsi"), # Mr. - ("nőv", "nővér"), # nurse - # Add other Hungarian abbreviations here if needed. - ] - ], - "ko": [ - (re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1]) - for x in [ - # Korean doesn't typically use abbreviations in the same way as Latin-based scripts. - ] - ], -} - - -def expand_abbreviations_multilingual(text, lang="en"): - for regex, replacement in _abbreviations[lang]: - text = re.sub(regex, replacement, text) - return text - - -_symbols_multilingual = { - "en": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " and "), - ("@", " at "), - ("%", " percent "), - ("#", " hash "), - ("$", " dollar "), - ("£", " pound "), - ("°", " degree "), - ] - ], - "es": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " y "), - ("@", " arroba "), - ("%", " por ciento "), - ("#", " numeral "), - ("$", " dolar "), - ("£", " libra "), - ("°", " grados "), - ] - ], - "fr": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " et "), - ("@", " arobase "), - ("%", " pour cent "), - ("#", " dièse "), - ("$", " dollar "), - ("£", " livre "), - ("°", " degrés "), - ] - ], - "de": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " und "), - ("@", " at "), - ("%", " prozent "), - ("#", " raute "), - ("$", " dollar "), - ("£", " pfund "), - ("°", " grad "), - ] - ], - "pt": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " e "), - ("@", " arroba "), - ("%", " por cento "), - ("#", " cardinal "), - ("$", " dólar "), - ("£", " libra "), - ("°", " graus "), - ] - ], - "it": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " e "), - ("@", " chiocciola "), - ("%", " per cento "), - ("#", " cancelletto "), - ("$", " dollaro "), - ("£", " sterlina "), - ("°", " gradi "), - ] - ], - "pl": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " i "), - ("@", " małpa "), - ("%", " procent "), - ("#", " krzyżyk "), - ("$", " dolar "), - ("£", " funt "), - ("°", " stopnie "), - ] - ], - "ar": [ - # Arabic - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " و "), - ("@", " على "), - ("%", " في المئة "), - ("#", " رقم "), - ("$", " دولار "), - ("£", " جنيه "), - ("°", " درجة "), - ] - ], - "zh": [ - # Chinese - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " 和 "), - ("@", " 在 "), - ("%", " 百分之 "), - ("#", " 号 "), - ("$", " 美元 "), - ("£", " 英镑 "), - ("°", " 度 "), - ] - ], - "cs": [ - # Czech - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " a "), - ("@", " na "), - ("%", " procento "), - ("#", " křížek "), - ("$", " dolar "), - ("£", " libra "), - ("°", " stupně "), - ] - ], - "ru": [ - # Russian - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " и "), - ("@", " собака "), - ("%", " процентов "), - ("#", " номер "), - ("$", " доллар "), - ("£", " фунт "), - ("°", " градус "), - ] - ], - "nl": [ - # Dutch - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " en "), - ("@", " bij "), - ("%", " procent "), - ("#", " hekje "), - ("$", " dollar "), - ("£", " pond "), - ("°", " graden "), - ] - ], - "tr": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " ve "), - ("@", " at "), - ("%", " yüzde "), - ("#", " diyez "), - ("$", " dolar "), - ("£", " sterlin "), - ("°", " derece "), - ] - ], - "hu": [ - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " és "), - ("@", " kukac "), - ("%", " százalék "), - ("#", " kettőskereszt "), - ("$", " dollár "), - ("£", " font "), - ("°", " fok "), - ] - ], - "ko": [ - # Korean - (re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1]) - for x in [ - ("&", " 그리고 "), - ("@", " 에 "), - ("%", " 퍼센트 "), - ("#", " 번호 "), - ("$", " 달러 "), - ("£", " 파운드 "), - ("°", " 도 "), - ] - ], -} - - -def expand_symbols_multilingual(text, lang="en"): - for regex, replacement in _symbols_multilingual[lang]: - text = re.sub(regex, replacement, text) - text = text.replace(" ", " ") # Ensure there are no double spaces - return text.strip() - - -_ordinal_re = { - "en": re.compile(r"([0-9]+)(st|nd|rd|th)"), - "es": re.compile(r"([0-9]+)(º|ª|er|o|a|os|as)"), - "fr": re.compile(r"([0-9]+)(º|ª|er|re|e|ème)"), - "de": re.compile(r"([0-9]+)(st|nd|rd|th|º|ª|\.(?=\s|$))"), - "pt": re.compile(r"([0-9]+)(º|ª|o|a|os|as)"), - "it": re.compile(r"([0-9]+)(º|°|ª|o|a|i|e)"), - "pl": re.compile(r"([0-9]+)(º|ª|st|nd|rd|th)"), - "ar": re.compile(r"([0-9]+)(ون|ين|ث|ر|ى)"), - "cs": re.compile(r"([0-9]+)\.(?=\s|$)"), # In Czech, a dot is often used after the number to indicate ordinals. - "ru": re.compile(r"([0-9]+)(-й|-я|-е|-ое|-ье|-го)"), - "nl": re.compile(r"([0-9]+)(de|ste|e)"), - "tr": re.compile(r"([0-9]+)(\.|inci|nci|uncu|üncü|\.)"), - "hu": re.compile(r"([0-9]+)(\.|adik|edik|odik|edik|ödik|ödike|ik)"), - "ko": re.compile(r"([0-9]+)(번째|번|차|째)"), -} -_number_re = re.compile(r"[0-9]+") -_currency_re = { - "USD": re.compile(r"((\$[0-9\.\,]*[0-9]+)|([0-9\.\,]*[0-9]+\$))"), - "GBP": re.compile(r"((£[0-9\.\,]*[0-9]+)|([0-9\.\,]*[0-9]+£))"), - "EUR": re.compile(r"(([0-9\.\,]*[0-9]+€)|((€[0-9\.\,]*[0-9]+)))"), -} - -_comma_number_re = re.compile(r"\b\d{1,3}(,\d{3})*(\.\d+)?\b") -_dot_number_re = re.compile(r"\b\d{1,3}(.\d{3})*(\,\d+)?\b") -_decimal_number_re = re.compile(r"([0-9]+[.,][0-9]+)") - - -def _remove_commas(m): - text = m.group(0) - if "," in text: - text = text.replace(",", "") - return text - - -def _remove_dots(m): - text = m.group(0) - if "." in text: - text = text.replace(".", "") - return text - - -def _expand_decimal_point(m, lang="en"): - amount = m.group(1).replace(",", ".") - return num2words(float(amount), lang=lang if lang != "cs" else "cz") - - -def _expand_currency(m, lang="en", currency="USD"): - amount = float((re.sub(r"[^\d.]", "", m.group(0).replace(",", ".")))) - full_amount = num2words(amount, to="currency", currency=currency, lang=lang if lang != "cs" else "cz") - - and_equivalents = { - "en": ", ", - "es": " con ", - "fr": " et ", - "de": " und ", - "pt": " e ", - "it": " e ", - "pl": ", ", - "cs": ", ", - "ru": ", ", - "nl": ", ", - "ar": ", ", - "tr": ", ", - "hu": ", ", - "ko": ", ", - } - - if amount.is_integer(): - last_and = full_amount.rfind(and_equivalents[lang]) - if last_and != -1: - full_amount = full_amount[:last_and] - - return full_amount - - -def _expand_ordinal(m, lang="en"): - return num2words(int(m.group(1)), ordinal=True, lang=lang if lang != "cs" else "cz") - - -def _expand_number(m, lang="en"): - return num2words(int(m.group(0)), lang=lang if lang != "cs" else "cz") - - -def expand_numbers_multilingual(text, lang="en"): - if lang == "zh": - text = zh_num2words()(text) - else: - if lang in ["en", "ru"]: - text = re.sub(_comma_number_re, _remove_commas, text) - else: - text = re.sub(_dot_number_re, _remove_dots, text) - try: - text = re.sub(_currency_re["GBP"], lambda m: _expand_currency(m, lang, "GBP"), text) - text = re.sub(_currency_re["USD"], lambda m: _expand_currency(m, lang, "USD"), text) - text = re.sub(_currency_re["EUR"], lambda m: _expand_currency(m, lang, "EUR"), text) - except: - pass - if lang != "tr": - text = re.sub(_decimal_number_re, lambda m: _expand_decimal_point(m, lang), text) - text = re.sub(_ordinal_re[lang], lambda m: _expand_ordinal(m, lang), text) - text = re.sub(_number_re, lambda m: _expand_number(m, lang), text) - return text - - -def lowercase(text): - return text.lower() - - -def collapse_whitespace(text): - return re.sub(_whitespace_re, " ", text) - - -def multilingual_cleaners(text, lang): - text = text.replace('"', "") - if lang == "tr": - text = text.replace("İ", "i") - text = text.replace("Ö", "ö") - text = text.replace("Ü", "ü") - text = lowercase(text) - try: - text = expand_numbers_multilingual(text, lang) - except: - pass - try: - text = expand_abbreviations_multilingual(text, lang) - except: - pass - try: - text = expand_symbols_multilingual(text, lang=lang) - except: - pass - text = collapse_whitespace(text) - return text - - -def basic_cleaners(text): - """Basic pipeline that lowercases and collapses whitespace without transliteration.""" - text = lowercase(text) - text = collapse_whitespace(text) - return text - - -def chinese_transliterate(text): - return "".join( - [p[0] for p in pypinyin.pinyin(text, style=pypinyin.Style.TONE3, heteronym=False, neutral_tone_with_five=True)] - ) - - -def japanese_cleaners(text, katsu): - text = katsu.romaji(text) - text = lowercase(text) - return text - - -def korean_transliterate(text): - r = Transliter(academic) - return r.translit(text) - - -DEFAULT_VOCAB_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "vocab.json") - - -class VoiceBpeTokenizer: - def __init__(self, vocab_file=DEFAULT_VOCAB_FILE): - self.tokenizer = None - if vocab_file is not None: - self.tokenizer = Tokenizer.from_file(vocab_file) - self.char_limits = { - "en": 10000, - "de": 253, - "fr": 273, - "es": 239, - "it": 213, - "pt": 203, - "pl": 224, - "zh": 82, - "ar": 166, - "cs": 186, - "ru": 182, - "nl": 251, - "tr": 226, - "ja": 71, - "hu": 224, - "ko": 95, - } - - @cached_property - def katsu(self): - import cutlet - - return cutlet.Cutlet() - - def check_input_length(self, txt, lang): - lang = lang.split("-")[0] # remove the region - limit = self.char_limits.get(lang, 250) - # if len(txt) > limit: - # print( - # f"[!] Warning: The text length exceeds the character limit of {limit} for language '{lang}', this might cause truncated audio." - # ) - - def preprocess_text(self, txt, lang): - if lang in {"ar", "cs", "de", "en", "es", "fr", "hu", "it", "nl", "pl", "pt", "ru", "tr", "zh", "ko"}: - txt = multilingual_cleaners(txt, lang) - if lang == "zh": - txt = chinese_transliterate(txt) - if lang == "ko": - txt = korean_transliterate(txt) - elif lang == "ja": - txt = japanese_cleaners(txt, self.katsu) - elif lang == "hi": - # @manmay will implement this - txt = basic_cleaners(txt) - else: - raise NotImplementedError(f"Language '{lang}' is not supported.") - return txt - - def encode(self, txt, lang): - lang = lang.split("-")[0] # remove the region - self.check_input_length(txt, lang) - txt = self.preprocess_text(txt, lang) - lang = "zh-cn" if lang == "zh" else lang - txt = f"[{lang}]{txt}" - txt = txt.replace(" ", "[SPACE]") - return self.tokenizer.encode(txt).ids - - def decode(self, seq, skip_special_tokens=False): - if isinstance(seq, torch.Tensor): - seq = seq.cpu().numpy() - txt = self.tokenizer.decode(seq, skip_special_tokens=False).replace(" ", "") - txt = txt.replace("[SPACE]", " ") - txt = txt.replace("[STOP]", "") - # txt = txt.replace("[UNK]", "") - return txt - - - #copy from https://github.com/huggingface/transformers/blob/main/src/transformers/tokenization_utils_base.py#L3936 - def batch_decode( - self, - sequences: Union[List[int], List[List[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"], - skip_special_tokens: bool = False, - ) -> List[str]: - """ - Convert a list of lists of token ids into a list of strings by calling decode. - - Args: - sequences (`Union[List[int], List[List[int]], np.ndarray, torch.Tensor, tf.Tensor]`): - List of tokenized input ids. Can be obtained using the `__call__` method. - skip_special_tokens (`bool`, *optional*, defaults to `False`): - Whether or not to remove special tokens in the decoding. - kwargs (additional keyword arguments, *optional*): - Will be passed to the underlying model specific decode method. - - Returns: - `List[str]`: The list of decoded sentences. - """ - return [ - self.decode(seq) - for seq in sequences - ] - - #https://github.com/coqui-ai/TTS/blob/dev/TTS/tts/layers/xtts/trainer/dataset.py#L202 - # def pad(self): - - def __len__(self): - return self.tokenizer.get_vocab_size() - - def get_number_tokens(self): - return max(self.tokenizer.get_vocab().values()) + 1 - - -def test_expand_numbers_multilingual(): - test_cases = [ - # English - ("In 12.5 seconds.", "In twelve point five seconds.", "en"), - ("There were 50 soldiers.", "There were fifty soldiers.", "en"), - ("This is a 1st test", "This is a first test", "en"), - ("That will be $20 sir.", "That will be twenty dollars sir.", "en"), - ("That will be 20€ sir.", "That will be twenty euro sir.", "en"), - ("That will be 20.15€ sir.", "That will be twenty euro, fifteen cents sir.", "en"), - ("That's 100,000.5.", "That's one hundred thousand point five.", "en"), - # French - ("En 12,5 secondes.", "En douze virgule cinq secondes.", "fr"), - ("Il y avait 50 soldats.", "Il y avait cinquante soldats.", "fr"), - ("Ceci est un 1er test", "Ceci est un premier test", "fr"), - ("Cela vous fera $20 monsieur.", "Cela vous fera vingt dollars monsieur.", "fr"), - ("Cela vous fera 20€ monsieur.", "Cela vous fera vingt euros monsieur.", "fr"), - ("Cela vous fera 20,15€ monsieur.", "Cela vous fera vingt euros et quinze centimes monsieur.", "fr"), - ("Ce sera 100.000,5.", "Ce sera cent mille virgule cinq.", "fr"), - # German - ("In 12,5 Sekunden.", "In zwölf Komma fünf Sekunden.", "de"), - ("Es gab 50 Soldaten.", "Es gab fünfzig Soldaten.", "de"), - ("Dies ist ein 1. Test", "Dies ist ein erste Test", "de"), # Issue with gender - ("Das macht $20 Herr.", "Das macht zwanzig Dollar Herr.", "de"), - ("Das macht 20€ Herr.", "Das macht zwanzig Euro Herr.", "de"), - ("Das macht 20,15€ Herr.", "Das macht zwanzig Euro und fünfzehn Cent Herr.", "de"), - # Spanish - ("En 12,5 segundos.", "En doce punto cinco segundos.", "es"), - ("Había 50 soldados.", "Había cincuenta soldados.", "es"), - ("Este es un 1er test", "Este es un primero test", "es"), - ("Eso le costará $20 señor.", "Eso le costará veinte dólares señor.", "es"), - ("Eso le costará 20€ señor.", "Eso le costará veinte euros señor.", "es"), - ("Eso le costará 20,15€ señor.", "Eso le costará veinte euros con quince céntimos señor.", "es"), - # Italian - ("In 12,5 secondi.", "In dodici virgola cinque secondi.", "it"), - ("C'erano 50 soldati.", "C'erano cinquanta soldati.", "it"), - ("Questo è un 1° test", "Questo è un primo test", "it"), - ("Ti costerà $20 signore.", "Ti costerà venti dollari signore.", "it"), - ("Ti costerà 20€ signore.", "Ti costerà venti euro signore.", "it"), - ("Ti costerà 20,15€ signore.", "Ti costerà venti euro e quindici centesimi signore.", "it"), - # Portuguese - ("Em 12,5 segundos.", "Em doze vírgula cinco segundos.", "pt"), - ("Havia 50 soldados.", "Havia cinquenta soldados.", "pt"), - ("Este é um 1º teste", "Este é um primeiro teste", "pt"), - ("Isso custará $20 senhor.", "Isso custará vinte dólares senhor.", "pt"), - ("Isso custará 20€ senhor.", "Isso custará vinte euros senhor.", "pt"), - ( - "Isso custará 20,15€ senhor.", - "Isso custará vinte euros e quinze cêntimos senhor.", - "pt", - ), # "cêntimos" should be "centavos" num2words issue - # Polish - ("W 12,5 sekundy.", "W dwanaście przecinek pięć sekundy.", "pl"), - ("Było 50 żołnierzy.", "Było pięćdziesiąt żołnierzy.", "pl"), - ("To będzie kosztować 20€ panie.", "To będzie kosztować dwadzieścia euro panie.", "pl"), - ("To będzie kosztować 20,15€ panie.", "To będzie kosztować dwadzieścia euro, piętnaście centów panie.", "pl"), - # Arabic - ("في الـ 12,5 ثانية.", "في الـ اثنا عشر , خمسون ثانية.", "ar"), - ("كان هناك 50 جنديًا.", "كان هناك خمسون جنديًا.", "ar"), - # ("ستكون النتيجة $20 يا سيد.", 'ستكون النتيجة عشرون دولار يا سيد.', 'ar'), # $ and € are mising from num2words - # ("ستكون النتيجة 20€ يا سيد.", 'ستكون النتيجة عشرون يورو يا سيد.', 'ar'), - # Czech - ("Za 12,5 vteřiny.", "Za dvanáct celá pět vteřiny.", "cs"), - ("Bylo tam 50 vojáků.", "Bylo tam padesát vojáků.", "cs"), - ("To bude stát 20€ pane.", "To bude stát dvacet euro pane.", "cs"), - ("To bude 20.15€ pane.", "To bude dvacet euro, patnáct centů pane.", "cs"), - # Russian - ("Через 12.5 секунды.", "Через двенадцать запятая пять секунды.", "ru"), - ("Там было 50 солдат.", "Там было пятьдесят солдат.", "ru"), - ("Это будет 20.15€ сэр.", "Это будет двадцать евро, пятнадцать центов сэр.", "ru"), - ("Это будет стоить 20€ господин.", "Это будет стоить двадцать евро господин.", "ru"), - # Dutch - ("In 12,5 seconden.", "In twaalf komma vijf seconden.", "nl"), - ("Er waren 50 soldaten.", "Er waren vijftig soldaten.", "nl"), - ("Dat wordt dan $20 meneer.", "Dat wordt dan twintig dollar meneer.", "nl"), - ("Dat wordt dan 20€ meneer.", "Dat wordt dan twintig euro meneer.", "nl"), - # Chinese (Simplified) - ("在12.5秒内", "在十二点五秒内", "zh"), - ("有50名士兵", "有五十名士兵", "zh"), - # ("那将是$20先生", '那将是二十美元先生', 'zh'), currency doesn't work - # ("那将是20€先生", '那将是二十欧元先生', 'zh'), - # Turkish - # ("12,5 saniye içinde.", 'On iki virgül beş saniye içinde.', 'tr'), # decimal doesn't work for TR - ("50 asker vardı.", "elli asker vardı.", "tr"), - ("Bu 1. test", "Bu birinci test", "tr"), - # ("Bu 100.000,5.", 'Bu yüz bin virgül beş.', 'tr'), - # Hungarian - ("12,5 másodperc alatt.", "tizenkettő egész öt tized másodperc alatt.", "hu"), - ("50 katona volt.", "ötven katona volt.", "hu"), - ("Ez az 1. teszt", "Ez az első teszt", "hu"), - # Korean - ("12.5 초 안에.", "십이 점 다섯 초 안에.", "ko"), - ("50 명의 병사가 있었다.", "오십 명의 병사가 있었다.", "ko"), - ("이것은 1 번째 테스트입니다", "이것은 첫 번째 테스트입니다", "ko"), - ] - for a, b, lang in test_cases: - out = expand_numbers_multilingual(a, lang=lang) - assert out == b, f"'{out}' vs '{b}'" - - -def test_abbreviations_multilingual(): - test_cases = [ - # English - ("Hello Mr. Smith.", "Hello mister Smith.", "en"), - ("Dr. Jones is here.", "doctor Jones is here.", "en"), - # Spanish - ("Hola Sr. Garcia.", "Hola señor Garcia.", "es"), - ("La Dra. Martinez es muy buena.", "La doctora Martinez es muy buena.", "es"), - # French - ("Bonjour Mr. Dupond.", "Bonjour monsieur Dupond.", "fr"), - ("Mme. Moreau est absente aujourd'hui.", "madame Moreau est absente aujourd'hui.", "fr"), - # German - ("Frau Dr. Müller ist sehr klug.", "Frau doktor Müller ist sehr klug.", "de"), - # Portuguese - ("Olá Sr. Silva.", "Olá senhor Silva.", "pt"), - ("Dra. Costa, você está disponível?", "doutora Costa, você está disponível?", "pt"), - # Italian - ("Buongiorno, Sig. Rossi.", "Buongiorno, signore Rossi.", "it"), - # ("Sig.ra Bianchi, posso aiutarti?", 'signora Bianchi, posso aiutarti?', 'it'), # Issue with matching that pattern - # Polish - ("Dzień dobry, P. Kowalski.", "Dzień dobry, pani Kowalski.", "pl"), - ("M. Nowak, czy mogę zadać pytanie?", "pan Nowak, czy mogę zadać pytanie?", "pl"), - # Czech - ("P. Novák", "pan Novák", "cs"), - ("Dr. Vojtěch", "doktor Vojtěch", "cs"), - # Dutch - ("Dhr. Jansen", "de heer Jansen", "nl"), - ("Mevr. de Vries", "mevrouw de Vries", "nl"), - # Russian - ("Здравствуйте Г-н Иванов.", "Здравствуйте господин Иванов.", "ru"), - ("Д-р Смирнов здесь, чтобы увидеть вас.", "доктор Смирнов здесь, чтобы увидеть вас.", "ru"), - # Turkish - ("Merhaba B. Yılmaz.", "Merhaba bay Yılmaz.", "tr"), - ("Dr. Ayşe burada.", "doktor Ayşe burada.", "tr"), - # Hungarian - ("Dr. Szabó itt van.", "doktor Szabó itt van.", "hu"), - ] - - for a, b, lang in test_cases: - out = expand_abbreviations_multilingual(a, lang=lang) - assert out == b, f"'{out}' vs '{b}'" - - -def test_symbols_multilingual(): - test_cases = [ - ("I have 14% battery", "I have 14 percent battery", "en"), - ("Te veo @ la fiesta", "Te veo arroba la fiesta", "es"), - ("J'ai 14° de fièvre", "J'ai 14 degrés de fièvre", "fr"), - ("Die Rechnung beträgt £ 20", "Die Rechnung beträgt pfund 20", "de"), - ("O meu email é ana&joao@gmail.com", "O meu email é ana e joao arroba gmail.com", "pt"), - ("linguaggio di programmazione C#", "linguaggio di programmazione C cancelletto", "it"), - ("Moja temperatura to 36.6°", "Moja temperatura to 36.6 stopnie", "pl"), - ("Mám 14% baterie", "Mám 14 procento baterie", "cs"), - ("Těším se na tebe @ party", "Těším se na tebe na party", "cs"), - ("У меня 14% заряда", "У меня 14 процентов заряда", "ru"), - ("Я буду @ дома", "Я буду собака дома", "ru"), - ("Ik heb 14% batterij", "Ik heb 14 procent batterij", "nl"), - ("Ik zie je @ het feest", "Ik zie je bij het feest", "nl"), - ("لدي 14% في البطارية", "لدي 14 في المئة في البطارية", "ar"), - ("我的电量为 14%", "我的电量为 14 百分之", "zh"), - ("Pilim %14 dolu.", "Pilim yüzde 14 dolu.", "tr"), - ("Az akkumulátorom töltöttsége 14%", "Az akkumulátorom töltöttsége 14 százalék", "hu"), - ("배터리 잔량이 14%입니다.", "배터리 잔량이 14 퍼센트입니다.", "ko"), - ] - - for a, b, lang in test_cases: - out = expand_symbols_multilingual(a, lang=lang) - assert out == b, f"'{out}' vs '{b}'" - - -if __name__ == "__main__": - test_expand_numbers_multilingual() - test_abbreviations_multilingual() - test_symbols_multilingual() \ No newline at end of file diff --git a/models/lyrics_utils/vocab.json b/models/lyrics_utils/vocab.json deleted file mode 100644 index 519ed340c36e19dfe15ccffd7aa5a31a261d70a5..0000000000000000000000000000000000000000 --- a/models/lyrics_utils/vocab.json +++ /dev/null @@ -1,15535 +0,0 @@ -{ - "version": "1.0", - "truncation": null, - "padding": null, - "added_tokens": [ - { - "id": 0, - "special": true, - "content": "[STOP]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 1, - "special": true, - "content": "[UNK]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 2, - "special": true, - "content": "[SPACE]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 259, - "special": true, - "content": "[en]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 260, - "special": true, - "content": "[de]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 261, - "special": true, - "content": "[START]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 262, - "special": true, - "content": "[fr]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 284, - "special": true, - "content": "[es]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 285, - "special": true, - "content": "[it]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 286, - "special": true, - "content": "[pt]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 294, - "special": true, - "content": "[pl]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 295, - "special": true, - "content": "[tr]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 267, - "special": true, - "content": "[ru]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 293, - "special": true, - "content": "[cs]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 297, - "special": true, - "content": "[nl]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 5022, - "special": true, - "content": "[ar]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 5023, - "special": true, - "content": "[zh-cn]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 5412, - "special": true, - "content": "[ja]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 5753, - "special": true, - "content": "[hu]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6152, - "special": true, - "content": "[ko]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6680, - "special": true, - "content": "[hi]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6681, - "special": true, - "content": "[start]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6682, - "special": true, - "content": "[intro]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6683, - "special": true, - "content": "[verse]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6684, - "special": true, - "content": "[chorus]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6685, - "special": true, - "content": "[bridge]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6686, - "special": true, - "content": "[outro]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6687, - "special": true, - "content": "[end]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6688, - "special": true, - "content": "[inst]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6689, - "special": true, - "content": "[solo]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6690, - "special": true, - "content": "[hook]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6691, - "special": true, - "content": "[pre-chorus]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - }, - { - "id": 6692, - "special": true, - "content": "[break]", - "single_word": false, - "lstrip": false, - "rstrip": false, - "normalized": false - } - ], - "normalizer": null, - "pre_tokenizer": { - "type": "Whitespace" - }, - "post_processor": null, - "decoder": null, - "model": { - "type": "BPE", - "dropout": null, - "unk_token": "[UNK]", - "continuing_subword_prefix": null, - "end_of_word_suffix": null, - "fuse_unk": false, - "vocab": { - "[STOP]": 0, - "[UNK]": 1, - "[SPACE]": 2, - "!": 3, - "'": 4, - "(": 5, - ")": 6, - ",": 7, - "-": 8, - ".": 9, - "/": 10, - ":": 11, - ";": 12, - "?": 13, - "a": 14, - "b": 15, - "c": 16, - "d": 17, - "e": 18, - "f": 19, - "g": 20, - "h": 21, - "i": 22, - "j": 23, - "k": 24, - "l": 25, - "m": 26, - "n": 27, - "o": 28, - "p": 29, - "q": 30, - "r": 31, - "s": 32, - "t": 33, - "u": 34, - "v": 35, - "w": 36, - "x": 37, - "y": 38, - "z": 39, - "th": 40, - "in": 41, - "the": 42, - "an": 43, - "er": 44, - "ou": 45, - "re": 46, - "on": 47, - "at": 48, - "ed": 49, - "en": 50, - "to": 51, - "ing": 52, - "and": 53, - "is": 54, - "as": 55, - "al": 56, - "or": 57, - "of": 58, - "ar": 59, - "it": 60, - "es": 61, - "he": 62, - "st": 63, - "le": 64, - "om": 65, - "se": 66, - "be": 67, - "ad": 68, - "ow": 69, - "ly": 70, - "ch": 71, - "wh": 72, - "that": 73, - "you": 74, - "li": 75, - "ve": 76, - "ac": 77, - "ti": 78, - "ld": 79, - "me": 80, - "was": 81, - "gh": 82, - "id": 83, - "ll": 84, - "wi": 85, - "ent": 86, - "for": 87, - "ay": 88, - "ro": 89, - "ver": 90, - "ic": 91, - "her": 92, - "ke": 93, - "his": 94, - "no": 95, - "ut": 96, - "un": 97, - "ir": 98, - "lo": 99, - "we": 100, - "ri": 101, - "ha": 102, - "with": 103, - "ght": 104, - "out": 105, - "im": 106, - "ion": 107, - "all": 108, - "ab": 109, - "one": 110, - "ne": 111, - "ge": 112, - "ould": 113, - "ter": 114, - "mo": 115, - "had": 116, - "ce": 117, - "she": 118, - "go": 119, - "sh": 120, - "ur": 121, - "am": 122, - "so": 123, - "pe": 124, - "my": 125, - "de": 126, - "are": 127, - "but": 128, - "ome": 129, - "fr": 130, - "ther": 131, - "fe": 132, - "su": 133, - "do": 134, - "con": 135, - "te": 136, - "ain": 137, - "ere": 138, - "po": 139, - "if": 140, - "they": 141, - "us": 142, - "ag": 143, - "tr": 144, - "now": 145, - "oun": 146, - "this": 147, - "have": 148, - "not": 149, - "sa": 150, - "il": 151, - "up": 152, - "thing": 153, - "from": 154, - "ap": 155, - "him": 156, - "ack": 157, - "ation": 158, - "ant": 159, - "our": 160, - "op": 161, - "like": 162, - "ust": 163, - "ess": 164, - "bo": 165, - "ok": 166, - "ul": 167, - "ind": 168, - "ex": 169, - "com": 170, - "some": 171, - "there": 172, - "ers": 173, - "co": 174, - "res": 175, - "man": 176, - "ard": 177, - "pl": 178, - "wor": 179, - "way": 180, - "tion": 181, - "fo": 182, - "ca": 183, - "were": 184, - "by": 185, - "ate": 186, - "pro": 187, - "ted": 188, - "ound": 189, - "own": 190, - "would": 191, - "ts": 192, - "what": 193, - "qu": 194, - "ally": 195, - "ight": 196, - "ck": 197, - "gr": 198, - "when": 199, - "ven": 200, - "can": 201, - "ough": 202, - "ine": 203, - "end": 204, - "per": 205, - "ous": 206, - "od": 207, - "ide": 208, - "know": 209, - "ty": 210, - "very": 211, - "si": 212, - "ak": 213, - "who": 214, - "about": 215, - "ill": 216, - "them": 217, - "est": 218, - "red": 219, - "ye": 220, - "could": 221, - "ong": 222, - "your": 223, - "their": 224, - "em": 225, - "just": 226, - "other": 227, - "into": 228, - "any": 229, - "whi": 230, - "um": 231, - "tw": 232, - "ast": 233, - "der": 234, - "did": 235, - "ie": 236, - "been": 237, - "ace": 238, - "ink": 239, - "ity": 240, - "back": 241, - "ting": 242, - "br": 243, - "more": 244, - "ake": 245, - "pp": 246, - "then": 247, - "sp": 248, - "el": 249, - "use": 250, - "bl": 251, - "said": 252, - "over": 253, - "get": 254, - "ß": 255, - "ä": 256, - "ö": 257, - "ü": 258, - "[en]": 259, - "[de]": 260, - "[START]": 261, - "[fr]": 262, - "œ": 263, - "ï": 264, - "ê": 265, - "â": 266, - "[ru]": 267, - "ÿ": 268, - "è": 269, - "à": 270, - "ë": 271, - "ù": 272, - "î": 273, - "ç": 274, - "æ": 275, - "ô": 276, - "û": 277, - "á": 278, - "é": 279, - "í": 280, - "ó": 281, - "ú": 282, - "ñ": 283, - "[es]": 284, - "[it]": 285, - "[pt]": 286, - "ń": 287, - "ś": 288, - "ę": 289, - "ą": 290, - "ż": 291, - "ć": 292, - "[cs]": 293, - "[pl]": 294, - "[tr]": 295, - "ã": 296, - "[nl]": 297, - "ş": 298, - "ğ": 299, - "ı": 300, - "ò": 301, - "ì": 302, - "¿": 303, - "…": 304, - "i̇": 305, - "õ": 306, - "\"": 307, - "´": 308, - "ø": 309, - "č": 310, - "ō": 311, - "š": 312, - "ž": 313, - "̇": 314, - "ei": 315, - "ich": 316, - "ein": 317, - "au": 318, - "sch": 319, - "und": 320, - "die": 321, - "da": 322, - "den": 323, - "gen": 324, - "zu": 325, - "hr": 326, - "ten": 327, - "mi": 328, - "sie": 329, - "das": 330, - "eine": 331, - "icht": 332, - "ber": 333, - "ach": 334, - "auf": 335, - "lich": 336, - "nicht": 337, - "mm": 338, - "ben": 339, - "war": 340, - "mit": 341, - "sich": 342, - "ig": 343, - "aus": 344, - "ist": 345, - "wie": 346, - "och": 347, - "ung": 348, - "ann": 349, - "ür": 350, - "hn": 351, - "ihr": 352, - "sen": 353, - "tz": 354, - "dem": 355, - "eit": 356, - "hat": 357, - "wir": 358, - "von": 359, - "wei": 360, - "ier": 361, - "ra": 362, - "einen": 363, - "vor": 364, - "als": 365, - "wo": 366, - "rei": 367, - "ste": 368, - "lie": 369, - "auch": 370, - "du": 371, - "des": 372, - "ko": 373, - "über": 374, - "bei": 375, - "hen": 376, - "hm": 377, - "lei": 378, - "aber": 379, - "wen": 380, - "hl": 381, - "ger": 382, - "nach": 383, - "ft": 384, - "imm": 385, - "je": 386, - "schen": 387, - "wer": 388, - "ser": 389, - "än": 390, - "sein": 391, - "ol": 392, - "cht": 393, - "für": 394, - "kl": 395, - "ff": 396, - "einem": 397, - "nen": 398, - "ja": 399, - "noch": 400, - "hatte": 401, - "pf": 402, - "hin": 403, - "di": 404, - "chen": 405, - "rü": 406, - "iel": 407, - "sel": 408, - "dass": 409, - "ihn": 410, - "mir": 411, - "schl": 412, - "ön": 413, - "gan": 414, - "gt": 415, - "einer": 416, - "sten": 417, - "mich": 418, - "wenn": 419, - "ell": 420, - "gte": 421, - "mal": 422, - "gel": 423, - "ken": 424, - "nur": 425, - "mmen": 426, - "fü": 427, - "ern": 428, - "ör": 429, - "unter": 430, - "ander": 431, - "dur": 432, - "uch": 433, - "ta": 434, - "men": 435, - "mach": 436, - "doch": 437, - "durch": 438, - "os": 439, - "gl": 440, - "hal": 441, - "ihre": 442, - "wä": 443, - "immer": 444, - "ihm": 445, - "kann": 446, - "ort": 447, - "dann": 448, - "lan": 449, - "tzt": 450, - "oder": 451, - "hren": 452, - "et": 453, - "kön": 454, - "ick": 455, - "fa": 456, - "wieder": 457, - "daß": 458, - "mein": 459, - "fen": 460, - "ganz": 461, - "diese": 462, - "ster": 463, - "dar": 464, - "wa": 465, - "ges": 466, - "na": 467, - "fl": 468, - "igen": 469, - "sche": 470, - "ungen": 471, - "mehr": 472, - "ßen": 473, - "ot": 474, - "kon": 475, - "gew": 476, - "haben": 477, - "geh": 478, - "ät": 479, - "sind": 480, - "dr": 481, - "wel": 482, - "uns": 483, - "vo": 484, - "ma": 485, - "ute": 486, - "schon": 487, - "bes": 488, - "gesch": 489, - "bt": 490, - "che": 491, - "son": 492, - "ob": 493, - "la": 494, - "rück": 495, - "seine": 496, - "kr": 497, - "fre": 498, - "eil": 499, - "zum": 500, - "hier": 501, - "kt": 502, - "ige": 503, - "spr": 504, - "leben": 505, - "bst": 506, - "zeit": 507, - "gro": 508, - "denn": 509, - "ho": 510, - "scha": 511, - "bar": 512, - "alle": 513, - "gegen": 514, - "wür": 515, - "mü": 516, - "ze": 517, - "werden": 518, - "jetzt": 519, - "kommen": 520, - "nie": 521, - "sei": 522, - "heit": 523, - "soll": 524, - "glei": 525, - "meine": 526, - "woll": 527, - "ner": 528, - "habe": 529, - "wur": 530, - "lichen": 531, - "assen": 532, - "nte": 533, - "sehen": 534, - "wird": 535, - "bis": 536, - "gar": 537, - "ien": 538, - "mus": 539, - "uß": 540, - "är": 541, - "stell": 542, - "keit": 543, - "zwei": 544, - "selbst": 545, - "sta": 546, - "pa": 547, - "sagte": 548, - "tet": 549, - "kam": 550, - "ssen": 551, - "viel": 552, - "ug": 553, - "zen": 554, - "hei": 555, - "mann": 556, - "will": 557, - "geb": 558, - "waren": 559, - "ück": 560, - "äch": 561, - "mer": 562, - "ru": 563, - "hau": 564, - "eigen": 565, - "ang": 566, - "weg": 567, - "blick": 568, - "fra": 569, - "alles": 570, - "ka": 571, - "augen": 572, - "fin": 573, - "liche": 574, - "unser": 575, - "dern": 576, - "herr": 577, - "nun": 578, - "vie": 579, - "chte": 580, - "wohl": 581, - "fall": 582, - "ht": 583, - "ün": 584, - "etwas": 585, - "stand": 586, - "äu": 587, - "mö": 588, - "tel": 589, - "rie": 590, - "dich": 591, - "dies": 592, - "hand": 593, - "bin": 594, - "ffen": 595, - "nichts": 596, - "dan": 597, - "hne": 598, - "ihnen": 599, - "esen": 600, - "dieser": 601, - "frau": 602, - "art": 603, - "dir": 604, - "isch": 605, - "erst": 606, - "gleich": 607, - "komm": 608, - "hör": 609, - "ße": 610, - "dig": 611, - "sehr": 612, - "zei": 613, - "sam": 614, - "aum": 615, - "hät": 616, - "ingen": 617, - "gut": 618, - "mut": 619, - "cken": 620, - "konnte": 621, - "stimm": 622, - "zur": 623, - "itz": 624, - "weil": 625, - "würde": 626, - "fä": 627, - "können": 628, - "keine": 629, - "fer": 630, - "ischen": 631, - "voll": 632, - "eines": 633, - "setz": 634, - "zie": 635, - "del": 636, - "tete": 637, - "seiner": 638, - "ieren": 639, - "gest": 640, - "zurück": 641, - "wurde": 642, - "schn": 643, - "pr": 644, - "ließ": 645, - "tra": 646, - "mä": 647, - "gend": 648, - "fol": 649, - "ik": 650, - "schla": 651, - "schaft": 652, - "ater": 653, - "weiß": 654, - "seinen": 655, - "lassen": 656, - "lu": 657, - "unden": 658, - "teil": 659, - "neu": 660, - "iert": 661, - "menschen": 662, - "hmen": 663, - "str": 664, - "gi": 665, - "sah": 666, - "ihren": 667, - "eln": 668, - "weiter": 669, - "gehen": 670, - "iger": 671, - "macht": 672, - "tag": 673, - "also": 674, - "halten": 675, - "nis": 676, - "acht": 677, - "geben": 678, - "og": 679, - "nat": 680, - "mar": 681, - "det": 682, - "ohne": 683, - "haus": 684, - "tro": 685, - "ange": 686, - "lau": 687, - "spiel": 688, - "tre": 689, - "schr": 690, - "inn": 691, - "los": 692, - "machen": 693, - "hätte": 694, - "beg": 695, - "wirk": 696, - "alt": 697, - "glich": 698, - "tes": 699, - "richt": 700, - "freund": 701, - "ihrer": 702, - "fel": 703, - "bel": 704, - "sol": 705, - "einmal": 706, - "eben": 707, - "hol": 708, - "hän": 709, - "tern": 710, - "hö": 711, - "schw": 712, - "recht": 713, - "wahr": 714, - "seinem": 715, - "stehen": 716, - "hlen": 717, - "ins": 718, - "ging": 719, - "wollte": 720, - "wissen": 721, - "ungs": 722, - "ald": 723, - "ass": 724, - "jahr": 725, - "mor": 726, - "welt": 727, - "under": 728, - "zusa": 729, - "kopf": 730, - "lang": 731, - "hinter": 732, - "atz": 733, - "stra": 734, - "angen": 735, - "ank": 736, - "ade": 737, - "glau": 738, - "fach": 739, - "hatten": 740, - "fort": 741, - "eicht": 742, - "iff": 743, - "ler": 744, - "mei": 745, - "diesem": 746, - "kein": 747, - "frei": 748, - "führ": 749, - "vom": 750, - "β": 751, - "ai": 752, - "ait": 753, - "que": 754, - "les": 755, - "av": 756, - "ais": 757, - "oi": 758, - "eu": 759, - "lle": 760, - "par": 761, - "ans": 762, - "ment": 763, - "ét": 764, - "une": 765, - "pas": 766, - "qui": 767, - "elle": 768, - "dé": 769, - "pour": 770, - "dans": 771, - "ré": 772, - "tou": 773, - "vous": 774, - "vi": 775, - "ouv": 776, - "mon": 777, - "sur": 778, - "ci": 779, - "plu": 780, - "ère": 781, - "mais": 782, - "ois": 783, - "plus": 784, - "ée": 785, - "aient": 786, - "mp": 787, - "lui": 788, - "ave": 789, - "était": 790, - "ses": 791, - "tout": 792, - "oir": 793, - "avait": 794, - "és": 795, - "mes": 796, - "nous": 797, - "eux": 798, - "bi": 799, - "ons": 800, - "pu": 801, - "ces": 802, - "tu": 803, - "leur": 804, - "don": 805, - "eur": 806, - "ette": 807, - "aire": 808, - "avec": 809, - "dit": 810, - "té": 811, - "ille": 812, - "comme": 813, - "cr": 814, - "ux": 815, - "ès": 816, - "aux": 817, - "jour": 818, - "ils": 819, - "bien": 820, - "cou": 821, - "quel": 822, - "peu": 823, - "cette": 824, - "cu": 825, - "mê": 826, - "fait": 827, - "gu": 828, - "être": 829, - "ité": 830, - "ens": 831, - "ni": 832, - "lé": 833, - "dis": 834, - "ble": 835, - "né": 836, - "puis": 837, - "même": 838, - "ques": 839, - "fi": 840, - "age": 841, - "moi": 842, - "ence": 843, - "ont": 844, - "main": 845, - "ors": 846, - "aut": 847, - "ance": 848, - "mé": 849, - "sans": 850, - "sé": 851, - "lon": 852, - "hom": 853, - "car": 854, - "able": 855, - "cher": 856, - "deux": 857, - "enf": 858, - "où": 859, - "ph": 860, - "ure": 861, - "temp": 862, - "pos": 863, - "rent": 864, - "pé": 865, - "faire": 866, - "pi": 867, - "tres": 868, - "ça": 869, - "endre": 870, - "bon": 871, - "sou": 872, - "int": 873, - "pré": 874, - "sent": 875, - "tant": 876, - "cer": 877, - "là": 878, - "lais": 879, - "près": 880, - "bre": 881, - "cour": 882, - "pet": 883, - "comp": 884, - "lait": 885, - "trouv": 886, - "entre": 887, - "sont": 888, - "dev": 889, - "nu": 890, - "temps": 891, - "dou": 892, - "rait": 893, - "bou": 894, - "quand": 895, - "jours": 896, - "avoir": 897, - "été": 898, - "ale": 899, - "pre": 900, - "fois": 901, - "orte": 902, - "vé": 903, - "non": 904, - "tous": 905, - "jus": 906, - "coup": 907, - "homme": 908, - "ête": 909, - "aussi": 910, - "urs": 911, - "seu": 912, - "ord": 913, - "min": 914, - "gé": 915, - "core": 916, - "va": 917, - "vre": 918, - "encore": 919, - "sem": 920, - "ite": 921, - "autre": 922, - "pris": 923, - "peut": 924, - "ue": 925, - "ante": 926, - "gn": 927, - "rép": 928, - "hu": 929, - "sion": 930, - "votre": 931, - "dire": 932, - "ez": 933, - "fem": 934, - "leurs": 935, - "met": 936, - "cri": 937, - "mis": 938, - "tour": 939, - "rai": 940, - "jam": 941, - "regar": 942, - "rien": 943, - "vers": 944, - "suis": 945, - "pouv": 946, - "vis": 947, - "grand": 948, - "ants": 949, - "cor": 950, - "rer": 951, - "cé": 952, - "tent": 953, - "pres": 954, - "vou": 955, - "alors": 956, - "sieur": 957, - "aine": 958, - "quoi": 959, - "fon": 960, - "endant": 961, - "arri": 962, - "eure": 963, - "après": 964, - "donc": 965, - "itu": 966, - "lè": 967, - "sait": 968, - "toi": 969, - "cha": 970, - "ail": 971, - "asse": 972, - "imp": 973, - "voy": 974, - "conn": 975, - "pla": 976, - "petit": 977, - "avant": 978, - "nom": 979, - "tin": 980, - "dont": 981, - "sous": 982, - "emp": 983, - "person": 984, - "elles": 985, - "beau": 986, - "parti": 987, - "cho": 988, - "prit": 989, - "toujours": 990, - "rais": 991, - "jamais": 992, - "trav": 993, - "tions": 994, - "très": 995, - "voi": 996, - "ren": 997, - "yeux": 998, - "voir": 999, - "premi": 1000, - "gne": 1001, - "heure": 1002, - "rou": 1003, - "eff": 1004, - "notre": 1005, - "ments": 1006, - "ton": 1007, - "fais": 1008, - "cela": 1009, - "répon": 1010, - "cons": 1011, - "air": 1012, - "ôt": 1013, - "pendant": 1014, - "ici": 1015, - "toute": 1016, - "jet": 1017, - "port": 1018, - "étaient": 1019, - "pen": 1020, - "hé": 1021, - "autres": 1022, - "père": 1023, - "oc": 1024, - "quelques": 1025, - "ique": 1026, - "lis": 1027, - "femme": 1028, - "jou": 1029, - "teur": 1030, - "monde": 1031, - "nes": 1032, - "dre": 1033, - "aff": 1034, - "rap": 1035, - "part": 1036, - "lement": 1037, - "cla": 1038, - "fut": 1039, - "quelque": 1040, - "prendre": 1041, - "rê": 1042, - "aille": 1043, - "sais": 1044, - "ches": 1045, - "let": 1046, - "char": 1047, - "ères": 1048, - "ents": 1049, - "moins": 1050, - "eau": 1051, - "aî": 1052, - "jeu": 1053, - "heur": 1054, - "ées": 1055, - "tri": 1056, - "point": 1057, - "mom": 1058, - "vent": 1059, - "nouv": 1060, - "gran": 1061, - "trois": 1062, - "sant": 1063, - "toutes": 1064, - "contre": 1065, - "èrent": 1066, - "chez": 1067, - "avez": 1068, - "ût": 1069, - "att": 1070, - "pau": 1071, - "porte": 1072, - "ouver": 1073, - "lit": 1074, - "prés": 1075, - "chose": 1076, - "vit": 1077, - "monsieur": 1078, - "hab": 1079, - "tête": 1080, - "ju": 1081, - "tement": 1082, - "ction": 1083, - "vrai": 1084, - "lar": 1085, - "cet": 1086, - "regard": 1087, - "lant": 1088, - "som": 1089, - "moment": 1090, - "illes": 1091, - "ple": 1092, - "ps": 1093, - "mère": 1094, - "cl": 1095, - "sour": 1096, - "ys": 1097, - "trop": 1098, - "enne": 1099, - "jusqu": 1100, - "avaient": 1101, - "avais": 1102, - "jeune": 1103, - "depuis": 1104, - "personne": 1105, - "fit": 1106, - "cert": 1107, - "jo": 1108, - "oui": 1109, - "rest": 1110, - "semb": 1111, - "cap": 1112, - "mat": 1113, - "mu": 1114, - "long": 1115, - "fran": 1116, - "faut": 1117, - "iti": 1118, - "bli": 1119, - "chev": 1120, - "pri": 1121, - "ente": 1122, - "ainsi": 1123, - "cham": 1124, - "lors": 1125, - "cas": 1126, - "ili": 1127, - "bé": 1128, - "nos": 1129, - "sui": 1130, - "rit": 1131, - "cro": 1132, - "gue": 1133, - "ía": 1134, - "por": 1135, - "las": 1136, - "ón": 1137, - "una": 1138, - "aba": 1139, - "dos": 1140, - "era": 1141, - "mb": 1142, - "para": 1143, - "ás": 1144, - "mos": 1145, - "ando": 1146, - "como": 1147, - "más": 1148, - "ción": 1149, - "tan": 1150, - "dad": 1151, - "ado": 1152, - "fu": 1153, - "cia": 1154, - "mente": 1155, - "sus": 1156, - "tar": 1157, - "za": 1158, - "ba": 1159, - "pero": 1160, - "sin": 1161, - "lla": 1162, - "án": 1163, - "ia": 1164, - "ran": 1165, - "ga": 1166, - "yo": 1167, - "tos": 1168, - "cos": 1169, - "ya": 1170, - "ones": 1171, - "había": 1172, - "hi": 1173, - "esta": 1174, - "mas": 1175, - "tor": 1176, - "aban": 1177, - "dor": 1178, - "ían": 1179, - "tas": 1180, - "én": 1181, - "endo": 1182, - "aque": 1183, - "ero": 1184, - "io": 1185, - "qué": 1186, - "cab": 1187, - "tal": 1188, - "señ": 1189, - "ora": 1190, - "todo": 1191, - "sal": 1192, - "cuando": 1193, - "gun": 1194, - "bu": 1195, - "ras": 1196, - "esto": 1197, - "pare": 1198, - "él": 1199, - "tras": 1200, - "jos": 1201, - "mien": 1202, - "pue": 1203, - "cre": 1204, - "pon": 1205, - "día": 1206, - "tros": 1207, - "sab": 1208, - "sobre": 1209, - "ese": 1210, - "mbre": 1211, - "eron": 1212, - "añ": 1213, - "ido": 1214, - "porque": 1215, - "ella": 1216, - "cen": 1217, - "muy": 1218, - "cal": 1219, - "este": 1220, - "has": 1221, - "có": 1222, - "gra": 1223, - "ros": 1224, - "aquel": 1225, - "dijo": 1226, - "cía": 1227, - "zo": 1228, - "ciones": 1229, - "mbi": 1230, - "elo": 1231, - "tó": 1232, - "ina": 1233, - "todos": 1234, - "tien": 1235, - "estaba": 1236, - "deci": 1237, - "cio": 1238, - "ño": 1239, - "lor": 1240, - "nues": 1241, - "medi": 1242, - "len": 1243, - "vida": 1244, - "ali": 1245, - "pues": 1246, - "ales": 1247, - "vol": 1248, - "mí": 1249, - "rar": 1250, - "cion": 1251, - "hasta": 1252, - "señor": 1253, - "cono": 1254, - "ah": 1255, - "dios": 1256, - "esa": 1257, - "ún": 1258, - "var": 1259, - "san": 1260, - "gui": 1261, - "otros": 1262, - "tado": 1263, - "buen": 1264, - "ña": 1265, - "tiemp": 1266, - "hacer": 1267, - "jer": 1268, - "vu": 1269, - "ana": 1270, - "así": 1271, - "antes": 1272, - "vez": 1273, - "miento": 1274, - "jar": 1275, - "lab": 1276, - "casa": 1277, - "eso": 1278, - "ego": 1279, - "dió": 1280, - "está": 1281, - "encia": 1282, - "eli": 1283, - "ías": 1284, - "tiempo": 1285, - "zar": 1286, - "van": 1287, - "mun": 1288, - "erta": 1289, - "tambi": 1290, - "sí": 1291, - "aun": 1292, - "mismo": 1293, - "entes": 1294, - "mano": 1295, - "ele": 1296, - "nada": 1297, - "segu": 1298, - "mej": 1299, - "erra": 1300, - "tir": 1301, - "uno": 1302, - "donde": 1303, - "toda": 1304, - "desde": 1305, - "también": 1306, - "cuer": 1307, - "hombre": 1308, - "otro": 1309, - "lib": 1310, - "trar": 1311, - "cual": 1312, - "hay": 1313, - "cada": 1314, - "taba": 1315, - "mento": 1316, - "tenía": 1317, - "quer": 1318, - "eran": 1319, - "siemp": 1320, - "siempre": 1321, - "erto": 1322, - "quí": 1323, - "gos": 1324, - "pués": 1325, - "ellos": 1326, - "después": 1327, - "nue": 1328, - "llo": 1329, - "inter": 1330, - "cómo": 1331, - "ahora": 1332, - "uste": 1333, - "traba": 1334, - "lado": 1335, - "ino": 1336, - "poco": 1337, - "erte": 1338, - "mujer": 1339, - "quier": 1340, - "algun": 1341, - "fue": 1342, - "ojos": 1343, - "enton": 1344, - "vos": 1345, - "esper": 1346, - "much": 1347, - "otra": 1348, - "az": 1349, - "eza": 1350, - "aquí": 1351, - "cias": 1352, - "gua": 1353, - "mucho": 1354, - "decir": 1355, - "esti": 1356, - "idad": 1357, - "algo": 1358, - "ocu": 1359, - "entonces": 1360, - "dido": 1361, - "entos": 1362, - "gri": 1363, - "dado": 1364, - "ios": 1365, - "dose": 1366, - "usted": 1367, - "quien": 1368, - "ami": 1369, - "unto": 1370, - "mejor": 1371, - "bas": 1372, - "solo": 1373, - "pregun": 1374, - "tur": 1375, - "alg": 1376, - "todas": 1377, - "parte": 1378, - "emb": 1379, - "cto": 1380, - "mundo": 1381, - "tiene": 1382, - "tante": 1383, - "palab": 1384, - "tran": 1385, - "aquella": 1386, - "cios": 1387, - "aunque": 1388, - "cuen": 1389, - "tener": 1390, - "fun": 1391, - "respon": 1392, - "allí": 1393, - "xi": 1394, - "han": 1395, - "pens": 1396, - "contra": 1397, - "tura": 1398, - "val": 1399, - "dio": 1400, - "tanto": 1401, - "camin": 1402, - "mó": 1403, - "esp": 1404, - "ada": 1405, - "ío": 1406, - "hacia": 1407, - "dej": 1408, - "estar": 1409, - "ión": 1410, - "gas": 1411, - "vas": 1412, - "noche": 1413, - "ér": 1414, - "años": 1415, - "padre": 1416, - "gus": 1417, - "ár": 1418, - "sino": 1419, - "manos": 1420, - "cido": 1421, - "estu": 1422, - "hubi": 1423, - "vir": 1424, - "bri": 1425, - "raz": 1426, - "chi": 1427, - "puede": 1428, - "menos": 1429, - "habi": 1430, - "homb": 1431, - "neces": 1432, - "may": 1433, - "eros": 1434, - "ría": 1435, - "hecho": 1436, - "escu": 1437, - "lti": 1438, - "ándo": 1439, - "bus": 1440, - "cosas": 1441, - "tú": 1442, - "espa": 1443, - "reci": 1444, - "ctor": 1445, - "prim": 1446, - "dia": 1447, - "dese": 1448, - "mientras": 1449, - "hor": 1450, - "fuer": 1451, - "ida": 1452, - "posi": 1453, - "lante": 1454, - "ano": 1455, - "estas": 1456, - "pli": 1457, - "luego": 1458, - "sión": 1459, - "cin": 1460, - "tierra": 1461, - "guar": 1462, - "cado": 1463, - "encon": 1464, - "pren": 1465, - "mayor": 1466, - "fal": 1467, - "ð": 1468, - "ħ": 1469, - "ň": 1470, - "ə": 1471, - "θ": 1472, - "’": 1473, - "“": 1474, - "”": 1475, - "zi": 1476, - "gli": 1477, - "tto": 1478, - "ono": 1479, - "nel": 1480, - "tti": 1481, - "della": 1482, - "zione": 1483, - "tta": 1484, - "tà": 1485, - "uo": 1486, - "come": 1487, - "alla": 1488, - "oni": 1489, - "ggi": 1490, - "ssi": 1491, - "più": 1492, - "ini": 1493, - "bb": 1494, - "sto": 1495, - "sono": 1496, - "eri": 1497, - "sse": 1498, - "sc": 1499, - "sul": 1500, - "vano": 1501, - "sti": 1502, - "suo": 1503, - "cchi": 1504, - "zza": 1505, - "anche": 1506, - "tte": 1507, - "sci": 1508, - "col": 1509, - "sso": 1510, - "ssa": 1511, - "dei": 1512, - "aveva": 1513, - "zz": 1514, - "amo": 1515, - "gno": 1516, - "sua": 1517, - "ria": 1518, - "sì": 1519, - "ché": 1520, - "dal": 1521, - "ona": 1522, - "spe": 1523, - "gni": 1524, - "tt": 1525, - "delle": 1526, - "questo": 1527, - "nella": 1528, - "dere": 1529, - "anno": 1530, - "dell": 1531, - "uni": 1532, - "bbe": 1533, - "anti": 1534, - "ene": 1535, - "gio": 1536, - "uto": 1537, - "qual": 1538, - "glia": 1539, - "quando": 1540, - "tutto": 1541, - "glio": 1542, - "zioni": 1543, - "cam": 1544, - "esso": 1545, - "ss": 1546, - "mol": 1547, - "loro": 1548, - "perché": 1549, - "cosa": 1550, - "due": 1551, - "poi": 1552, - "sco": 1553, - "cco": 1554, - "gna": 1555, - "tem": 1556, - "prima": 1557, - "così": 1558, - "essere": 1559, - "ani": 1560, - "bra": 1561, - "rio": 1562, - "anco": 1563, - "cui": 1564, - "spi": 1565, - "via": 1566, - "gior": 1567, - "bile": 1568, - "ggio": 1569, - "mai": 1570, - "tare": 1571, - "indi": 1572, - "rebbe": 1573, - "senza": 1574, - "zio": 1575, - "tutti": 1576, - "stato": 1577, - "zia": 1578, - "dalla": 1579, - "mia": 1580, - "vita": 1581, - "quella": 1582, - "qua": 1583, - "dove": 1584, - "allo": 1585, - "sempre": 1586, - "zzo": 1587, - "sia": 1588, - "dopo": 1589, - "porta": 1590, - "ccia": 1591, - "erano": 1592, - "anni": 1593, - "chia": 1594, - "enza": 1595, - "propri": 1596, - "anda": 1597, - "cca": 1598, - "occhi": 1599, - "questa": 1600, - "ffi": 1601, - "ron": 1602, - "mio": 1603, - "ris": 1604, - "ogni": 1605, - "rin": 1606, - "far": 1607, - "menti": 1608, - "ancora": 1609, - "fatto": 1610, - "mani": 1611, - "senti": 1612, - "pra": 1613, - "tempo": 1614, - "essi": 1615, - "bbi": 1616, - "lare": 1617, - "pers": 1618, - "sor": 1619, - "anza": 1620, - "pie": 1621, - "verso": 1622, - "altro": 1623, - "tato": 1624, - "cato": 1625, - "ato": 1626, - "volta": 1627, - "cc": 1628, - "fare": 1629, - "ciò": 1630, - "bili": 1631, - "nuo": 1632, - "quello": 1633, - "colo": 1634, - "ppo": 1635, - "trova": 1636, - "ore": 1637, - "rono": 1638, - "molto": 1639, - "almente": 1640, - "sca": 1641, - "vole": 1642, - "tali": 1643, - "sulla": 1644, - "sce": 1645, - "meno": 1646, - "anto": 1647, - "pun": 1648, - "stu": 1649, - "capi": 1650, - "giu": 1651, - "mini": 1652, - "pia": 1653, - "lavo": 1654, - "vero": 1655, - "rsi": 1656, - "altri": 1657, - "scia": 1658, - "suoi": 1659, - "glie": 1660, - "sotto": 1661, - "bene": 1662, - "scri": 1663, - "tale": 1664, - "degli": 1665, - "alc": 1666, - "uomo": 1667, - "pel": 1668, - "pote": 1669, - "essa": 1670, - "scu": 1671, - "signo": 1672, - "stro": 1673, - "uti": 1674, - "sione": 1675, - "gre": 1676, - "fini": 1677, - "lun": 1678, - "esi": 1679, - "passa": 1680, - "rà": 1681, - "mentre": 1682, - "hanno": 1683, - "usci": 1684, - "gia": 1685, - "già": 1686, - "mina": 1687, - "tica": 1688, - "giorno": 1689, - "esse": 1690, - "modo": 1691, - "spa": 1692, - "proprio": 1693, - "ori": 1694, - "contro": 1695, - "stru": 1696, - "diven": 1697, - "disse": 1698, - "rato": 1699, - "noi": 1700, - "vere": 1701, - "può": 1702, - "dice": 1703, - "cci": 1704, - "secon": 1705, - "ccio": 1706, - "qualche": 1707, - "tutta": 1708, - "gg": 1709, - "mondo": 1710, - "forma": 1711, - "mma": 1712, - "pensa": 1713, - "deva": 1714, - "fosse": 1715, - "sopra": 1716, - "tamente": 1717, - "ness": 1718, - "quanto": 1719, - "raga": 1720, - "unque": 1721, - "care": 1722, - "stre": 1723, - "grande": 1724, - "picco": 1725, - "guarda": 1726, - "nell": 1727, - "possi": 1728, - "presen": 1729, - "rò": 1730, - "paro": 1731, - "tua": 1732, - "vin": 1733, - "ane": 1734, - "stesso": 1735, - "dav": 1736, - "nei": 1737, - "nelle": 1738, - "ghi": 1739, - "pio": 1740, - "lato": 1741, - "sid": 1742, - "fine": 1743, - "fuo": 1744, - "quasi": 1745, - "ulti": 1746, - "ito": 1747, - "sue": 1748, - "fil": 1749, - "allora": 1750, - "veni": 1751, - "tano": 1752, - "ello": 1753, - "ão": 1754, - "não": 1755, - "uma": 1756, - "ela": 1757, - "lh": 1758, - "ção": 1759, - "cê": 1760, - "inha": 1761, - "você": 1762, - "ec": 1763, - "dade": 1764, - "ao": 1765, - "ram": 1766, - "vel": 1767, - "ém": 1768, - "pode": 1769, - "estava": 1770, - "isso": 1771, - "mui": 1772, - "faz": 1773, - "ões": 1774, - "pes": 1775, - "ix": 1776, - "sim": 1777, - "olh": 1778, - "isa": 1779, - "ên": 1780, - "tinha": 1781, - "meu": 1782, - "são": 1783, - "minha": 1784, - "muito": 1785, - "foi": 1786, - "bem": 1787, - "diz": 1788, - "parec": 1789, - "ço": 1790, - "pesso": 1791, - "pois": 1792, - "mesmo": 1793, - "ções": 1794, - "seus": 1795, - "até": 1796, - "ência": 1797, - "lhe": 1798, - "tiv": 1799, - "mã": 1800, - "só": 1801, - "tão": 1802, - "tudo": 1803, - "então": 1804, - "inda": 1805, - "bal": 1806, - "indo": 1807, - "ndo": 1808, - "já": 1809, - "vam": 1810, - "eito": 1811, - "depois": 1812, - "mel": 1813, - "lha": 1814, - "ainda": 1815, - "fazer": 1816, - "pou": 1817, - "pergun": 1818, - "deix": 1819, - "tamb": 1820, - "ala": 1821, - "pelo": 1822, - "também": 1823, - "fica": 1824, - "prec": 1825, - "eles": 1826, - "havia": 1827, - "lá": 1828, - "nas": 1829, - "gem": 1830, - "mem": 1831, - "ós": 1832, - "deu": 1833, - "eiro": 1834, - "..": 1835, - "assim": 1836, - "ior": 1837, - "har": 1838, - "aqui": 1839, - "cul": 1840, - "sar": 1841, - "outra": 1842, - "olhos": 1843, - "ima": 1844, - "mim": 1845, - "ago": 1846, - "pessoas": 1847, - "eram": 1848, - "eira": 1849, - "pela": 1850, - "coisa": 1851, - "mão": 1852, - "conh": 1853, - "agora": 1854, - "iam": 1855, - "há": 1856, - "suas": 1857, - "guém": 1858, - "cabe": 1859, - "nem": 1860, - "ível": 1861, - "consegu": 1862, - "trabal": 1863, - "lev": 1864, - "lem": 1865, - "vai": 1866, - "tei": 1867, - "pró": 1868, - "quem": 1869, - "onde": 1870, - "cabeça": 1871, - "nunca": 1872, - "mentos": 1873, - "hum": 1874, - "dele": 1875, - "verdade": 1876, - "tá": 1877, - "hos": 1878, - "algum": 1879, - "dizer": 1880, - "penas": 1881, - "nós": 1882, - "enquanto": 1883, - "outro": 1884, - "lho": 1885, - "melhor": 1886, - "primei": 1887, - "iu": 1888, - "apenas": 1889, - "estou": 1890, - "conte": 1891, - "homem": 1892, - "dois": 1893, - "ças": 1894, - "pouco": 1895, - "senhor": 1896, - "tando": 1897, - "espera": 1898, - "pai": 1899, - "rios": 1900, - "baix": 1901, - "ase": 1902, - "isas": 1903, - "hora": 1904, - "ficar": 1905, - "seja": 1906, - "ân": 1907, - "clar": 1908, - "inc": 1909, - "fos": 1910, - "ouvi": 1911, - "vem": 1912, - "tava": 1913, - "ário": 1914, - "sos": 1915, - "inho": 1916, - "rando": 1917, - "ês": 1918, - "coisas": 1919, - "aconte": 1920, - "lher": 1921, - "anos": 1922, - "talvez": 1923, - "estão": 1924, - "liv": 1925, - "outros": 1926, - "qualquer": 1927, - "gou": 1928, - "lí": 1929, - "tivesse": 1930, - "rado": 1931, - "precisa": 1932, - "mãe": 1933, - "dela": 1934, - "entra": 1935, - "maior": 1936, - "noite": 1937, - "tiva": 1938, - "pala": 1939, - "ração": 1940, - "deus": 1941, - "sas": 1942, - "inte": 1943, - "fei": 1944, - "palav": 1945, - "trás": 1946, - "cidade": 1947, - "lugar": 1948, - "vezes": 1949, - "encontra": 1950, - "tru": 1951, - "eci": 1952, - "ın": 1953, - "bir": 1954, - "yor": 1955, - "ek": 1956, - "dı": 1957, - "ey": 1958, - "tı": 1959, - "mı": 1960, - "iz": 1961, - "ır": 1962, - "gö": 1963, - "sı": 1964, - "bil": 1965, - "lı": 1966, - "üz": 1967, - "iç": 1968, - "iy": 1969, - "ım": 1970, - "uz": 1971, - "cak": 1972, - "iş": 1973, - "ını": 1974, - "iyor": 1975, - "baş": 1976, - "dü": 1977, - "değ": 1978, - "kar": 1979, - "ev": 1980, - "öy": 1981, - "bun": 1982, - "yap": 1983, - "sun": 1984, - "gör": 1985, - "yı": 1986, - "ki": 1987, - "ara": 1988, - "alı": 1989, - "onu": 1990, - "çı": 1991, - "şey": 1992, - "sın": 1993, - "kı": 1994, - "kad": 1995, - "ağ": 1996, - "değil": 1997, - "ük": 1998, - "çok": 1999, - "şı": 2000, - "ül": 2001, - "için": 2002, - "eye": 2003, - "oldu": 2004, - "mış": 2005, - "kal": 2006, - "mek": 2007, - "öyle": 2008, - "yordu": 2009, - "yüz": 2010, - "miş": 2011, - "mak": 2012, - "ola": 2013, - "yan": 2014, - "cek": 2015, - "yorum": 2016, - "bak": 2017, - "üm": 2018, - "ları": 2019, - "oğ": 2020, - "kadar": 2021, - "arı": 2022, - "ında": 2023, - "gün": 2024, - "yok": 2025, - "yer": 2026, - "dım": 2027, - "daha": 2028, - "ına": 2029, - "dim": 2030, - "bilir": 2031, - "iki": 2032, - "siz": 2033, - "diğ": 2034, - "bü": 2035, - "düş": 2036, - "üç": 2037, - "unu": 2038, - "aman": 2039, - "fak": 2040, - "ede": 2041, - "sonra": 2042, - "hiç": 2043, - "aki": 2044, - "ğı": 2045, - "bul": 2046, - "maz": 2047, - "anla": 2048, - "bura": 2049, - "geç": 2050, - "maya": 2051, - "konu": 2052, - "din": 2053, - "tek": 2054, - "zaman": 2055, - "eler": 2056, - "öz": 2057, - "dır": 2058, - "gibi": 2059, - "şa": 2060, - "leri": 2061, - "kim": 2062, - "ku": 2063, - "fakat": 2064, - "yar": 2065, - "göz": 2066, - "cı": 2067, - "yorsun": 2068, - "bek": 2069, - "inde": 2070, - "pek": 2071, - "bunu": 2072, - "lik": 2073, - "iler": 2074, - "edi": 2075, - "öl": 2076, - "sür": 2077, - "sır": 2078, - "çık": 2079, - "sıl": 2080, - "alar": 2081, - "kes": 2082, - "yak": 2083, - "çek": 2084, - "yıl": 2085, - "ecek": 2086, - "ız": 2087, - "git": 2088, - "kap": 2089, - "ama": 2090, - "ıl": 2091, - "ların": 2092, - "biz": 2093, - "tır": 2094, - "oy": 2095, - "ancak": 2096, - "doğ": 2097, - "bana": 2098, - "şim": 2099, - "başla": 2100, - "lü": 2101, - "madı": 2102, - "beni": 2103, - "yük": 2104, - "lık": 2105, - "beş": 2106, - "nasıl": 2107, - "tık": 2108, - "tür": 2109, - "daki": 2110, - "ceğ": 2111, - "zı": 2112, - "iyi": 2113, - "dok": 2114, - "benim": 2115, - "cağ": 2116, - "yen": 2117, - "şu": 2118, - "mez": 2119, - "düşün": 2120, - "kendi": 2121, - "şimdi": 2122, - "yol": 2123, - "yu": 2124, - "iste": 2125, - "sek": 2126, - "mam": 2127, - "söyle": 2128, - "dik": 2129, - "kur": 2130, - "olduğ": 2131, - "sını": 2132, - "biliyor": 2133, - "kan": 2134, - "yal": 2135, - "meye": 2136, - "muş": 2137, - "kaç": 2138, - "iye": 2139, - "tü": 2140, - "ef": 2141, - "tım": 2142, - "evet": 2143, - "yet": 2144, - "burada": 2145, - "tim": 2146, - "biraz": 2147, - "kor": 2148, - "doğru": 2149, - "inin": 2150, - "kız": 2151, - "diye": 2152, - "dör": 2153, - "etti": 2154, - "onun": 2155, - "isti": 2156, - "ği": 2157, - "sana": 2158, - "üş": 2159, - "arka": 2160, - "hayır": 2161, - "karşı": 2162, - "ile": 2163, - "hak": 2164, - "ıyor": 2165, - "neden": 2166, - "sev": 2167, - "sız": 2168, - "çocu": 2169, - "çalı": 2170, - "olur": 2171, - "bır": 2172, - "gir": 2173, - "ise": 2174, - "ih": 2175, - "kır": 2176, - "dön": 2177, - "böyle": 2178, - "seni": 2179, - "!\"": 2180, - "dört": 2181, - "söy": 2182, - "oş": 2183, - "musun": 2184, - "laş": 2185, - "ip": 2186, - "kay": 2187, - "hem": 2188, - "büyük": 2189, - "aç": 2190, - "bırak": 2191, - "misin": 2192, - "söz": 2193, - "değiş": 2194, - "ünü": 2195, - "gül": 2196, - "kö": 2197, - "karı": 2198, - "tamam": 2199, - "olu": 2200, - "yeni": 2201, - "lam": 2202, - "mıştı": 2203, - "yaş": 2204, - "iniz": 2205, - "kadın": 2206, - "bunun": 2207, - "mey": 2208, - "altı": 2209, - "yi": 2210, - "inden": 2211, - "senin": 2212, - "yat": 2213, - "top": 2214, - "isi": 2215, - "dün": 2216, - "hiçbir": 2217, - "yon": 2218, - "dın": 2219, - "tün": 2220, - "başka": 2221, - "hep": 2222, - "irmi": 2223, - "devam": 2224, - "olacak": 2225, - "artık": 2226, - "durum": 2227, - "imiz": 2228, - "üzel": 2229, - "lerini": 2230, - "sağ": 2231, - "gerek": 2232, - "yirmi": 2233, - "şek": 2234, - "bağ": 2235, - "lara": 2236, - "yür": 2237, - "ması": 2238, - "katı": 2239, - "dedi": 2240, - "gü": 2241, - "sorun": 2242, - "üne": 2243, - "mız": 2244, - "yapı": 2245, - "mil": 2246, - "ğını": 2247, - "tara": 2248, - "vardı": 2249, - "konuş": 2250, - "arak": 2251, - "larak": 2252, - "çocuk": 2253, - "bütün": 2254, - "ley": 2255, - "dür": 2256, - "güzel": 2257, - "ayı": 2258, - "yapa": 2259, - "nı": 2260, - "ayr": 2261, - "öne": 2262, - "yordum": 2263, - "ban": 2264, - "i̇ş": 2265, - "dum": 2266, - "yorlar": 2267, - "larını": 2268, - "çıkar": 2269, - "zan": 2270, - "seç": 2271, - "liyor": 2272, - "tak": 2273, - "şık": 2274, - "tekrar": 2275, - "aş": 2276, - "eş": 2277, - "mişti": 2278, - "kin": 2279, - "imi": 2280, - "eğ": 2281, - "gidi": 2282, - "leş": 2283, - "başladı": 2284, - "gide": 2285, - "otur": 2286, - "dde": 2287, - "ından": 2288, - "üzer": 2289, - "ının": 2290, - "nız": 2291, - "uy": 2292, - "yedi": 2293, - "kat": 2294, - "olarak": 2295, - "ladı": 2296, - "yalnız": 2297, - "bah": 2298, - "iyet": 2299, - "sak": 2300, - "açık": 2301, - "sında": 2302, - "...": 2303, - "insan": 2304, - "aynı": 2305, - "eder": 2306, - "istan": 2307, - "uzun": 2308, - "geri": 2309, - "erek": 2310, - "olan": 2311, - "gerçek": 2312, - "alan": 2313, - "dış": 2314, - "alık": 2315, - "fark": 2316, - "üst": 2317, - "sade": 2318, - "kiş": 2319, - "ldı": 2320, - "zor": 2321, - "etir": 2322, - "herkes": 2323, - "ömer": 2324, - "unda": 2325, - "haf": 2326, - "buna": 2327, - "ydı": 2328, - "peki": 2329, - "adam": 2330, - "haz": 2331, - "sına": 2332, - "kapı": 2333, - "görüş": 2334, - "sadece": 2335, - "aldı": 2336, - "geldi": 2337, - "rz": 2338, - "sz": 2339, - "cz": 2340, - "ię": 2341, - "dz": 2342, - "ał": 2343, - "się": 2344, - "rze": 2345, - "że": 2346, - "wy": 2347, - "rzy": 2348, - "ła": 2349, - "ło": 2350, - "ny": 2351, - "dzie": 2352, - "dzi": 2353, - "czy": 2354, - "cie": 2355, - "prze": 2356, - "dy": 2357, - "kie": 2358, - "ry": 2359, - "ją": 2360, - "ów": 2361, - "przy": 2362, - "mie": 2363, - "szy": 2364, - "cze": 2365, - "bie": 2366, - "cy": 2367, - "nia": 2368, - "ści": 2369, - "sze": 2370, - "jest": 2371, - "ży": 2372, - "ną": 2373, - "któ": 2374, - "ała": 2375, - "mnie": 2376, - "ły": 2377, - "cza": 2378, - "jak": 2379, - "roz": 2380, - "ró": 2381, - "zna": 2382, - "łu": 2383, - "ść": 2384, - "wia": 2385, - "wszy": 2386, - "spo": 2387, - "gdy": 2388, - "wał": 2389, - "wię": 2390, - "łem": 2391, - "ję": 2392, - "sk": 2393, - "rę": 2394, - "dob": 2395, - "już": 2396, - "bę": 2397, - "ałem": 2398, - "sza": 2399, - "pod": 2400, - "dla": 2401, - "pan": 2402, - "nę": 2403, - "może": 2404, - "śli": 2405, - "ało": 2406, - "lko": 2407, - "nych": 2408, - "powie": 2409, - "cię": 2410, - "tylko": 2411, - "naj": 2412, - "tego": 2413, - "ski": 2414, - "nego": 2415, - "wszyst": 2416, - "szcze": 2417, - "jed": 2418, - "jej": 2419, - "two": 2420, - "ąd": 2421, - "śmy": 2422, - "czę": 2423, - "wać": 2424, - "jego": 2425, - "ża": 2426, - "sy": 2427, - "praw": 2428, - "tym": 2429, - "który": 2430, - "ały": 2431, - "trze": 2432, - "niej": 2433, - "nym": 2434, - "gło": 2435, - "jąc": 2436, - "mówi": 2437, - "ska": 2438, - "nej": 2439, - "słu": 2440, - "wła": 2441, - "będzie": 2442, - "dę": 2443, - "pó": 2444, - "bez": 2445, - "nic": 2446, - "pła": 2447, - "ście": 2448, - "są": 2449, - "trzy": 2450, - "kiem": 2451, - "był": 2452, - "mog": 2453, - "robi": 2454, - "tam": 2455, - "mię": 2456, - "zy": 2457, - "pew": 2458, - "myś": 2459, - "przed": 2460, - "sko": 2461, - "które": 2462, - "lę": 2463, - "wsze": 2464, - "ąc": 2465, - "było": 2466, - "sobie": 2467, - "py": 2468, - "cią": 2469, - "jeszcze": 2470, - "tę": 2471, - "czas": 2472, - "szę": 2473, - "gł": 2474, - "kę": 2475, - "czu": 2476, - "przez": 2477, - "sło": 2478, - "wz": 2479, - "kto": 2480, - "ków": 2481, - "czo": 2482, - "liśmy": 2483, - "więc": 2484, - "rą": 2485, - "wó": 2486, - "rza": 2487, - "ności": 2488, - "wet": 2489, - "nął": 2490, - "śmie": 2491, - "nawet": 2492, - "musi": 2493, - "swo": 2494, - "tej": 2495, - "wą": 2496, - "wu": 2497, - "wią": 2498, - "niu": 2499, - "czą": 2500, - "dzo": 2501, - "skie": 2502, - "jeśli": 2503, - "czego": 2504, - "chy": 2505, - "dł": 2506, - "tych": 2507, - "bym": 2508, - "żo": 2509, - "eś": 2510, - "sią": 2511, - "kiedy": 2512, - "wró": 2513, - "dze": 2514, - "dro": 2515, - "rów": 2516, - "pani": 2517, - "kul": 2518, - "nad": 2519, - "chwi": 2520, - "nim": 2521, - "być": 2522, - "chodzi": 2523, - "nio": 2524, - "dobrze": 2525, - "teraz": 2526, - "wokul": 2527, - "coś": 2528, - "kł": 2529, - "pier": 2530, - "gdzie": 2531, - "dzy": 2532, - "pię": 2533, - "dź": 2534, - "ką": 2535, - "gó": 2536, - "zda": 2537, - "chce": 2538, - "stę": 2539, - "świa": 2540, - "wszystko": 2541, - "peł": 2542, - "wiem": 2543, - "wiel": 2544, - "każ": 2545, - "rzu": 2546, - "sły": 2547, - "jedna": 2548, - "myśl": 2549, - "mój": 2550, - "jestem": 2551, - "óż": 2552, - "miej": 2553, - "moż": 2554, - "kła": 2555, - "resz": 2556, - "dłu": 2557, - "stwo": 2558, - "nię": 2559, - "masz": 2560, - "żeby": 2561, - "niem": 2562, - "jakie": 2563, - "sty": 2564, - "nią": 2565, - "wej": 2566, - "oj": 2567, - "sła": 2568, - "ność": 2569, - "zło": 2570, - "szczę": 2571, - "lej": 2572, - "wego": 2573, - "cał": 2574, - "dział": 2575, - "kich": 2576, - "dza": 2577, - "dzię": 2578, - "oczy": 2579, - "zosta": 2580, - "czło": 2581, - "nam": 2582, - "kil": 2583, - "szu": 2584, - "wę": 2585, - "miał": 2586, - "strze": 2587, - "cej": 2588, - "ej": 2589, - "znaj": 2590, - "dać": 2591, - "miejs": 2592, - "kró": 2593, - "kry": 2594, - "bardzo": 2595, - "śnie": 2596, - "lą": 2597, - "gie": 2598, - "ciebie": 2599, - "dni": 2600, - "potrze": 2601, - "wokulski": 2602, - "uwa": 2603, - "umie": 2604, - "jednak": 2605, - "kra": 2606, - "wróci": 2607, - "człowie": 2608, - "czyć": 2609, - "była": 2610, - "żeli": 2611, - "mę": 2612, - "cę": 2613, - "zrobi": 2614, - "mogę": 2615, - "prowa": 2616, - "rem": 2617, - "niech": 2618, - "cznie": 2619, - "kro": 2620, - "tą": 2621, - "chci": 2622, - "bro": 2623, - "dzieć": 2624, - "szą": 2625, - "pad": 2626, - "trz": 2627, - "jem": 2628, - "tów": 2629, - "dru": 2630, - "taj": 2631, - "rzekł": 2632, - "niego": 2633, - "takie": 2634, - "wała": 2635, - "towa": 2636, - "kapła": 2637, - "widzi": 2638, - "podob": 2639, - "dzę": 2640, - "tał": 2641, - "stęp": 2642, - "bą": 2643, - "poko": 2644, - "wem": 2645, - "gę": 2646, - "aby": 2647, - "albo": 2648, - "spra": 2649, - "zno": 2650, - "smo": 2651, - "jesz": 2652, - "księ": 2653, - "jesteś": 2654, - "poz": 2655, - "nigdy": 2656, - "ksią": 2657, - "cóż": 2658, - "ws": 2659, - "pow": 2660, - "tka": 2661, - "świe": 2662, - "szka": 2663, - "samo": 2664, - "sł": 2665, - "rzę": 2666, - "nale": 2667, - "chcesz": 2668, - "nik": 2669, - "pę": 2670, - "chyba": 2671, - "ciąg": 2672, - "jący": 2673, - "woj": 2674, - "nasze": 2675, - "mniej": 2676, - "więcej": 2677, - "zwy": 2678, - "osta": 2679, - "waż": 2680, - "śmier": 2681, - "wier": 2682, - "dzą": 2683, - "zaś": 2684, - "gdyby": 2685, - "jaki": 2686, - "wol": 2687, - "win": 2688, - "dą": 2689, - "ścia": 2690, - "rozma": 2691, - "wal": 2692, - "panie": 2693, - "star": 2694, - "kaz": 2695, - "jeżeli": 2696, - "wra": 2697, - "koń": 2698, - "siebie": 2699, - "znowu": 2700, - "czem": 2701, - "stwa": 2702, - "isto": 2703, - "pół": 2704, - "dał": 2705, - "kobie": 2706, - "ałam": 2707, - "wych": 2708, - "cesa": 2709, - "nich": 2710, - "zawsze": 2711, - "dzić": 2712, - "też": 2713, - "lepie": 2714, - "proszę": 2715, - "kre": 2716, - "twa": 2717, - "łą": 2718, - "chu": 2719, - "cą": 2720, - "prz": 2721, - "łe": 2722, - "szedł": 2723, - "odpowie": 2724, - "myśli": 2725, - "świą": 2726, - "ź": 2727, - "ł": 2728, - "&": 2729, - "=": 2730, - "ă": 2731, - "đ": 2732, - "ţ": 2733, - "–": 2734, - "‘": 2735, - "ij": 2736, - "aa": 2737, - "een": 2738, - "het": 2739, - "aar": 2740, - "oor": 2741, - "ijn": 2742, - "dat": 2743, - "oe": 2744, - "ijk": 2745, - "aan": 2746, - "voor": 2747, - "iet": 2748, - "zijn": 2749, - "niet": 2750, - "oo": 2751, - "moet": 2752, - "heb": 2753, - "uit": 2754, - "wij": 2755, - "aat": 2756, - "lijk": 2757, - "sl": 2758, - "daar": 2759, - "deze": 2760, - "worden": 2761, - "moeten": 2762, - "onder": 2763, - "hebben": 2764, - "ook": 2765, - "ct": 2766, - "nog": 2767, - "aal": 2768, - "eer": 2769, - "bij": 2770, - "mijn": 2771, - "kom": 2772, - "atie": 2773, - "eft": 2774, - "kel": 2775, - "rij": 2776, - "heid": 2777, - "af": 2778, - "stel": 2779, - "maar": 2780, - "wee": 2781, - "heeft": 2782, - "waar": 2783, - "eren": 2784, - "wat": 2785, - "wil": 2786, - "aag": 2787, - "bet": 2788, - "hij": 2789, - "kun": 2790, - "uw": 2791, - "dt": 2792, - "door": 2793, - "tij": 2794, - "ond": 2795, - "geen": 2796, - "gev": 2797, - "veel": 2798, - "naar": 2799, - "aten": 2800, - "kunnen": 2801, - "echt": 2802, - "goe": 2803, - "twee": 2804, - "delijk": 2805, - "uur": 2806, - "toe": 2807, - "meer": 2808, - "onze": 2809, - "tijd": 2810, - "hoe": 2811, - "tot": 2812, - "zou": 2813, - "aak": 2814, - "amen": 2815, - "woor": 2816, - "wordt": 2817, - "gelijk": 2818, - "gaan": 2819, - "ker": 2820, - "eld": 2821, - "hou": 2822, - "zel": 2823, - "tegen": 2824, - "komen": 2825, - "werk": 2826, - "goed": 2827, - "zal": 2828, - "zij": 2829, - "slag": 2830, - "zien": 2831, - "echter": 2832, - "itie": 2833, - "tie": 2834, - "elijk": 2835, - "ische": 2836, - "belan": 2837, - "haar": 2838, - "vr": 2839, - "grijk": 2840, - "doen": 2841, - "land": 2842, - "belangrijk": 2843, - "open": 2844, - "ctie": 2845, - "zelf": 2846, - "mij": 2847, - "iteit": 2848, - "stem": 2849, - "mee": 2850, - "aren": 2851, - "dien": 2852, - "gaat": 2853, - "prob": 2854, - "moe": 2855, - "ullen": 2856, - "zich": 2857, - "daarom": 2858, - "orm": 2859, - "staat": 2860, - "zit": 2861, - "dui": 2862, - "dus": 2863, - "ds": 2864, - "verslag": 2865, - "kelijk": 2866, - "proble": 2867, - "schap": 2868, - "gd": 2869, - "hun": 2870, - "erd": 2871, - "zet": 2872, - "staan": 2873, - "maal": 2874, - "inder": 2875, - "eid": 2876, - "kken": 2877, - "ged": 2878, - "zullen": 2879, - "mensen": 2880, - "jaar": 2881, - "regel": 2882, - "ieder": 2883, - "volgen": 2884, - "geven": 2885, - "even": 2886, - "blij": 2887, - "ië": 2888, - "uwe": 2889, - "maken": 2890, - "oek": 2891, - "nieuwe": 2892, - "baar": 2893, - "andere": 2894, - "ruik": 2895, - "agen": 2896, - "ouw": 2897, - "willen": 2898, - "aakt": 2899, - "hoo": 2900, - "anden": 2901, - "lig": 2902, - "samen": 2903, - "zeer": 2904, - "duidelijk": 2905, - "antwoor": 2906, - "heel": 2907, - "punt": 2908, - "houden": 2909, - "vraag": 2910, - "gele": 2911, - "eens": 2912, - "besch": 2913, - "omen": 2914, - "erg": 2915, - "doel": 2916, - "dag": 2917, - "uren": 2918, - "ings": 2919, - "oren": 2920, - "delen": 2921, - "steun": 2922, - "innen": 2923, - "pol": 2924, - "oon": 2925, - "sn": 2926, - "zonder": 2927, - "nodig": 2928, - "alleen": 2929, - "mid": 2930, - "ragen": 2931, - "iets": 2932, - "versch": 2933, - "gebruik": 2934, - "rouw": 2935, - "stellen": 2936, - "menten": 2937, - "eerste": 2938, - "laat": 2939, - "groot": 2940, - "ood": 2941, - "toch": 2942, - "laten": 2943, - "aard": 2944, - "sle": 2945, - "deel": 2946, - "plaat": 2947, - "ree": 2948, - "betre": 2949, - "lid": 2950, - "uiten": 2951, - "racht": 2952, - "beleid": 2953, - "stie": 2954, - "staten": 2955, - "ggen": 2956, - "reken": 2957, - "alen": 2958, - "ming": 2959, - "mogelijk": 2960, - "grote": 2961, - "altijd": 2962, - "enkel": 2963, - "wik": 2964, - "politie": 2965, - "elk": 2966, - "handel": 2967, - "kwe": 2968, - "maat": 2969, - "elen": 2970, - "vrij": 2971, - "jes": 2972, - "aam": 2973, - "huis": 2974, - "weer": 2975, - "lidstaten": 2976, - "king": 2977, - "kle": 2978, - "bed": 2979, - "geval": 2980, - "wikkel": 2981, - "kwestie": 2982, - "stee": 2983, - "hel": 2984, - "komst": 2985, - "iden": 2986, - "eerd": 2987, - "tweede": 2988, - "probleem": 2989, - "ussen": 2990, - "snel": 2991, - "tig": 2992, - "ult": 2993, - "nemen": 2994, - "commis": 2995, - "verschil": 2996, - "zoek": 2997, - "krij": 2998, - "graag": 2999, - "denk": 3000, - "landen": 3001, - "reden": 3002, - "besl": 3003, - "oeg": 3004, - "beter": 3005, - "heden": 3006, - "mag": 3007, - "boven": 3008, - "cont": 3009, - "fd": 3010, - "hele": 3011, - "vier": 3012, - "gez": 3013, - "kw": 3014, - "aas": 3015, - "ontwikkel": 3016, - "drie": 3017, - "vaak": 3018, - "plaats": 3019, - "gang": 3020, - "ijf": 3021, - "natuur": 3022, - "tussen": 3023, - "bat": 3024, - "komt": 3025, - "wacht": 3026, - "aad": 3027, - "achter": 3028, - "gebie": 3029, - "verk": 3030, - "ligt": 3031, - "nieuw": 3032, - "vand": 3033, - "ý": 3034, - "ď": 3035, - "ě": 3036, - "ř": 3037, - "ť": 3038, - "ů": 3039, - "„": 3040, - "ní": 3041, - "ně": 3042, - "ře": 3043, - "ná": 3044, - "vě": 3045, - "vá": 3046, - "rá": 3047, - "vy": 3048, - "mě": 3049, - "ři": 3050, - "ří": 3051, - "že": 3052, - "jí": 3053, - "vý": 3054, - "ji": 3055, - "dě": 3056, - "če": 3057, - "tě": 3058, - "ky": 3059, - "še": 3060, - "ké": 3061, - "ší": 3062, - "pře": 3063, - "ví": 3064, - "ný": 3065, - "ži": 3066, - "má": 3067, - "cí": 3068, - "zá": 3069, - "ské": 3070, - "dá": 3071, - "byl": 3072, - "tí": 3073, - "pří": 3074, - "při": 3075, - "či": 3076, - "vní": 3077, - "ča": 3078, - "dí": 3079, - "dní": 3080, - "ká": 3081, - "nou": 3082, - "vět": 3083, - "pě": 3084, - "kou": 3085, - "ých": 3086, - "bě": 3087, - "prá": 3088, - "jako": 3089, - "ží": 3090, - "zí": 3091, - "jsou": 3092, - "jsem": 3093, - "lní": 3094, - "cké": 3095, - "vat": 3096, - "před": 3097, - "hla": 3098, - "stá": 3099, - "čí": 3100, - "ši": 3101, - "kla": 3102, - "ště": 3103, - "lou": 3104, - "mů": 3105, - "chá": 3106, - "pů": 3107, - "také": 3108, - "dů": 3109, - "nost": 3110, - "tře": 3111, - "sku": 3112, - "vše": 3113, - "tní": 3114, - "byla": 3115, - "ční": 3116, - "jeho": 3117, - "bý": 3118, - "vání": 3119, - "ných": 3120, - "tři": 3121, - "vz": 3122, - "stře": 3123, - "dva": 3124, - "hle": 3125, - "čá": 3126, - "nosti": 3127, - "vš": 3128, - "hra": 3129, - "jen": 3130, - "slo": 3131, - "však": 3132, - "kdy": 3133, - "bylo": 3134, - "bude": 3135, - "jší": 3136, - "vých": 3137, - "ním": 3138, - "sm": 3139, - "koli": 3140, - "rů": 3141, - "může": 3142, - "není": 3143, - "hod": 3144, - "bí": 3145, - "tý": 3146, - "stě": 3147, - "uje": 3148, - "sá": 3149, - "pět": 3150, - "krá": 3151, - "tom": 3152, - "ství": 3153, - "vně": 3154, - "sed": 3155, - "své": 3156, - "pí": 3157, - "musí": 3158, - "už": 3159, - "tím": 3160, - "jící": 3161, - "jedno": 3162, - "čas": 3163, - "čty": 3164, - "ský": 3165, - "evro": 3166, - "toho": 3167, - "hy": 3168, - "kter": 3169, - "rní": 3170, - "stí": 3171, - "svě": 3172, - "pak": 3173, - "všech": 3174, - "ků": 3175, - "ng": 3176, - "ád": 3177, - "chází": 3178, - "být": 3179, - "první": 3180, - "mno": 3181, - "ského": 3182, - "pá": 3183, - "nebo": 3184, - "kem": 3185, - "sla": 3186, - "ného": 3187, - "zde": 3188, - "další": 3189, - "řa": 3190, - "čtyři": 3191, - "hrá": 3192, - "druh": 3193, - "lně": 3194, - "vla": 3195, - "ských": 3196, - "ško": 3197, - "půso": 3198, - "proto": 3199, - "vů": 3200, - "ská": 3201, - "šest": 3202, - "dně": 3203, - "ještě": 3204, - "mezi": 3205, - "několi": 3206, - "již": 3207, - "čně": 3208, - "slu": 3209, - "zná": 3210, - "sedm": 3211, - "vlá": 3212, - "osm": 3213, - "byly": 3214, - "vám": 3215, - "cký": 3216, - "tech": 3217, - "ději": 3218, - "velmi": 3219, - "leži": 3220, - "vala": 3221, - "lý": 3222, - "tvo": 3223, - "spole": 3224, - "stup": 3225, - "mož": 3226, - "evrop": 3227, - "stal": 3228, - "jde": 3229, - "rodi": 3230, - "její": 3231, - "poli": 3232, - "devět": 3233, - "sme": 3234, - "až": 3235, - "této": 3236, - "tento": 3237, - "kaž": 3238, - "nula": 3239, - "bych": 3240, - "moc": 3241, - "stou": 3242, - "kdo": 3243, - "zd": 3244, - "praco": 3245, - "tomu": 3246, - "ným": 3247, - "živo": 3248, - "zem": 3249, - "násle": 3250, - "sky": 3251, - "jich": 3252, - "měl": 3253, - "děla": 3254, - "jsme": 3255, - "nice": 3256, - "stej": 3257, - "stní": 3258, - "náro": 3259, - "nit": 3260, - "později": 3261, - "tako": 3262, - "nce": 3263, - "čer": 3264, - "ším": 3265, - "něco": 3266, - "vál": 3267, - "řej": 3268, - "krát": 3269, - "ální": 3270, - "asi": 3271, - "které": 3272, - "stav": 3273, - "mají": 3274, - "mys": 3275, - "době": 3276, - "sně": 3277, - "zku": 3278, - "tů": 3279, - "chod": 3280, - "spě": 3281, - "jejich": 3282, - "součas": 3283, - "vali": 3284, - "kte": 3285, - "prů": 3286, - "zení": 3287, - "pat": 3288, - "potře": 3289, - "dnes": 3290, - "zemí": 3291, - "znam": 3292, - "mám": 3293, - "tedy": 3294, - "hlavní": 3295, - "použí": 3296, - "bní": 3297, - "vede": 3298, - "lep": 3299, - "jek": 3300, - "prav": 3301, - "politi": 3302, - "dne": 3303, - "čení": 3304, - "než": 3305, - "děl": 3306, - "čo": 3307, - "cích": 3308, - "sté": 3309, - "dlou": 3310, - "několik": 3311, - "vyu": 3312, - "ckých": 3313, - "nové": 3314, - "čin": 3315, - "dělá": 3316, - "ký": 3317, - "obla": 3318, - "podle": 3319, - "důleži": 3320, - "poku": 3321, - "kone": 3322, - "dý": 3323, - "dvě": 3324, - "žád": 3325, - "nout": 3326, - "tku": 3327, - "tvr": 3328, - "ckého": 3329, - "rov": 3330, - "tele": 3331, - "psa": 3332, - "svět": 3333, - "tivní": 3334, - "dosta": 3335, - "šel": 3336, - "druhé": 3337, - "skou": 3338, - "žo": 3339, - "jedná": 3340, - "význam": 3341, - "problé": 3342, - "publi": 3343, - "ván": 3344, - "odpo": 3345, - "podpo": 3346, - "dle": 3347, - "jaké": 3348, - "šení": 3349, - "vím": 3350, - "během": 3351, - "nachází": 3352, - "slou": 3353, - "pouze": 3354, - "otá": 3355, - "plo": 3356, - "tové": 3357, - "větši": 3358, - "komi": 3359, - "vají": 3360, - "tyto": 3361, - "zápa": 3362, - "změ": 3363, - "moh": 3364, - "více": 3365, - "společ": 3366, - "auto": 3367, - "proti": 3368, - "dět": 3369, - "cháze": 3370, - "žel": 3371, - "«": 3372, - "»": 3373, - "а": 3374, - "б": 3375, - "в": 3376, - "г": 3377, - "д": 3378, - "е": 3379, - "ж": 3380, - "з": 3381, - "и": 3382, - "й": 3383, - "к": 3384, - "л": 3385, - "м": 3386, - "н": 3387, - "о": 3388, - "п": 3389, - "р": 3390, - "с": 3391, - "т": 3392, - "у": 3393, - "ф": 3394, - "х": 3395, - "ц": 3396, - "ч": 3397, - "ш": 3398, - "щ": 3399, - "ъ": 3400, - "ы": 3401, - "ь": 3402, - "э": 3403, - "ю": 3404, - "я": 3405, - "ё": 3406, - "‑": 3407, - "−": 3408, - "ст": 3409, - "ен": 3410, - "но": 3411, - "на": 3412, - "пр": 3413, - "то": 3414, - "по": 3415, - "ра": 3416, - "го": 3417, - "ко": 3418, - "не": 3419, - "во": 3420, - "ва": 3421, - "ет": 3422, - "ер": 3423, - "ни": 3424, - "ел": 3425, - "ит": 3426, - "ны": 3427, - "за": 3428, - "ро": 3429, - "ени": 3430, - "ка": 3431, - "ли": 3432, - "ем": 3433, - "да": 3434, - "об": 3435, - "ла": 3436, - "до": 3437, - "ся": 3438, - "ть": 3439, - "от": 3440, - "ло": 3441, - "ль": 3442, - "ед": 3443, - "со": 3444, - "ми": 3445, - "ре": 3446, - "мо": 3447, - "ци": 3448, - "про": 3449, - "та": 3450, - "это": 3451, - "ки": 3452, - "ру": 3453, - "при": 3454, - "ти": 3455, - "се": 3456, - "ста": 3457, - "вы": 3458, - "мы": 3459, - "ви": 3460, - "бы": 3461, - "ма": 3462, - "ес": 3463, - "ля": 3464, - "сти": 3465, - "ле": 3466, - "что": 3467, - "ме": 3468, - "ри": 3469, - "ча": 3470, - "од": 3471, - "ей": 3472, - "ель": 3473, - "ения": 3474, - "га": 3475, - "ну": 3476, - "си": 3477, - "па": 3478, - "раз": 3479, - "бо": 3480, - "сто": 3481, - "су": 3482, - "са": 3483, - "ду": 3484, - "его": 3485, - "ест": 3486, - "ин": 3487, - "ить": 3488, - "из": 3489, - "же": 3490, - "му": 3491, - "пер": 3492, - "под": 3493, - "ение": 3494, - "сь": 3495, - "ку": 3496, - "пред": 3497, - "ного": 3498, - "ных": 3499, - "вер": 3500, - "те": 3501, - "ной": 3502, - "ции": 3503, - "де": 3504, - "ры": 3505, - "дел": 3506, - "лю": 3507, - "ве": 3508, - "он": 3509, - "мен": 3510, - "ги": 3511, - "ня": 3512, - "бу": 3513, - "пра": 3514, - "все": 3515, - "ется": 3516, - "сть": 3517, - "жа": 3518, - "дол": 3519, - "жи": 3520, - "бе": 3521, - "кон": 3522, - "сл": 3523, - "ши": 3524, - "ди": 3525, - "ств": 3526, - "ско": 3527, - "ные": 3528, - "чи": 3529, - "ют": 3530, - "дер": 3531, - "стра": 3532, - "ты": 3533, - "ход": 3534, - "щи": 3535, - "зо": 3536, - "зна": 3537, - "ности": 3538, - "чес": 3539, - "вля": 3540, - "вать": 3541, - "ор": 3542, - "пол": 3543, - "вет": 3544, - "так": 3545, - "ша": 3546, - "ту": 3547, - "сво": 3548, - "пре": 3549, - "она": 3550, - "итель": 3551, - "ный": 3552, - "сло": 3553, - "как": 3554, - "вл": 3555, - "ность": 3556, - "хо": 3557, - "мож": 3558, - "пе": 3559, - "для": 3560, - "ния": 3561, - "ное": 3562, - "рас": 3563, - "долж": 3564, - "дар": 3565, - "тель": 3566, - "ска": 3567, - "пу": 3568, - "ство": 3569, - "кото": 3570, - "раб": 3571, - "ее": 3572, - "род": 3573, - "эти": 3574, - "соб": 3575, - "ору": 3576, - "жен": 3577, - "ным": 3578, - "ити": 3579, - "ние": 3580, - "ком": 3581, - "дет": 3582, - "сту": 3583, - "гу": 3584, - "пи": 3585, - "меж": 3586, - "ению": 3587, - "тер": 3588, - "работ": 3589, - "воз": 3590, - "ция": 3591, - "кой": 3592, - "щест": 3593, - "гра": 3594, - "зи": 3595, - "ря": 3596, - "между": 3597, - "ства": 3598, - "вс": 3599, - "ело": 3600, - "ше": 3601, - "мер": 3602, - "ба": 3603, - "зы": 3604, - "лу": 3605, - "аль": 3606, - "дей": 3607, - "гла": 3608, - "народ": 3609, - "кти": 3610, - "предста": 3611, - "лся": 3612, - "явля": 3613, - "ски": 3614, - "нов": 3615, - "един": 3616, - "ров": 3617, - "ис": 3618, - "нима": 3619, - "рем": 3620, - "ходи": 3621, - "также": 3622, - "дру": 3623, - "ать": 3624, - "след": 3625, - "гово": 3626, - "ная": 3627, - "ющи": 3628, - "ень": 3629, - "которы": 3630, - "хот": 3631, - "ву": 3632, - "их": 3633, - "ему": 3634, - "чит": 3635, - "важ": 3636, - "орга": 3637, - "чески": 3638, - "ще": 3639, - "ке": 3640, - "ха": 3641, - "пос": 3642, - "том": 3643, - "боль": 3644, - "мне": 3645, - "пас": 3646, - "объ": 3647, - "прав": 3648, - "конф": 3649, - "слу": 3650, - "поддер": 3651, - "стви": 3652, - "наш": 3653, - "лько": 3654, - "стоя": 3655, - "ную": 3656, - "лем": 3657, - "енных": 3658, - "кра": 3659, - "ды": 3660, - "международ": 3661, - "гда": 3662, - "необ": 3663, - "госу": 3664, - "ству": 3665, - "ении": 3666, - "государ": 3667, - "кто": 3668, - "им": 3669, - "чест": 3670, - "рет": 3671, - "вопро": 3672, - "лен": 3673, - "ели": 3674, - "рова": 3675, - "ций": 3676, - "нам": 3677, - "этой": 3678, - "жения": 3679, - "необходи": 3680, - "меня": 3681, - "было": 3682, - "сили": 3683, - "фи": 3684, - "вя": 3685, - "шь": 3686, - "этого": 3687, - "они": 3688, - "органи": 3689, - "безо": 3690, - "проб": 3691, - "име": 3692, - "реш": 3693, - "би": 3694, - "безопас": 3695, - "ются": 3696, - "оста": 3697, - "енно": 3698, - "год": 3699, - "ела": 3700, - "представ": 3701, - "ться": 3702, - "слово": 3703, - "организа": 3704, - "должны": 3705, - "этом": 3706, - "бла": 3707, - "че": 3708, - "чу": 3709, - "благо": 3710, - "этому": 3711, - "врем": 3712, - "спе": 3713, - "ном": 3714, - "ений": 3715, - "спо": 3716, - "нас": 3717, - "нет": 3718, - "зу": 3719, - "вед": 3720, - "еще": 3721, - "сказа": 3722, - "сей": 3723, - "ерен": 3724, - "дан": 3725, - "сам": 3726, - "еля": 3727, - "ран": 3728, - "зыва": 3729, - "является": 3730, - "будет": 3731, - "ктив": 3732, - "тре": 3733, - "деле": 3734, - "мот": 3735, - "конферен": 3736, - "лась": 3737, - "час": 3738, - "сторо": 3739, - "кого": 3740, - "ез": 3741, - "ней": 3742, - "ос": 3743, - "лись": 3744, - "разору": 3745, - "пере": 3746, - "сси": 3747, - "ными": 3748, - "проц": 3749, - "голо": 3750, - "чело": 3751, - "боле": 3752, - "челове": 3753, - "сер": 3754, - "пл": 3755, - "чет": 3756, - "стран": 3757, - "пя": 3758, - "был": 3759, - "кла": 3760, - "тов": 3761, - "жд": 3762, - "дела": 3763, - "ера": 3764, - "уже": 3765, - "совет": 3766, - "ген": 3767, - "безопасности": 3768, - "ца": 3769, - "седа": 3770, - "поз": 3771, - "ответ": 3772, - "проблем": 3773, - "нако": 3774, - "тем": 3775, - "доста": 3776, - "пы": 3777, - "ща": 3778, - "вой": 3779, - "сущест": 3780, - "необходимо": 3781, - "быть": 3782, - "может": 3783, - "дем": 3784, - "чтобы": 3785, - "ек": 3786, - "чер": 3787, - "усили": 3788, - "рес": 3789, - "руд": 3790, - "единенных": 3791, - "доб": 3792, - "дости": 3793, - "ствен": 3794, - "ядер": 3795, - "годня": 3796, - "каза": 3797, - "сегодня": 3798, - "сейчас": 3799, - "только": 3800, - "вод": 3801, - "есь": 3802, - "много": 3803, - "буду": 3804, - "ев": 3805, - "есть": 3806, - "три": 3807, - "общест": 3808, - "явл": 3809, - "высту": 3810, - "ред": 3811, - "счит": 3812, - "сит": 3813, - "делега": 3814, - "лож": 3815, - "этот": 3816, - "фор": 3817, - "клю": 3818, - "возмож": 3819, - "вания": 3820, - "бли": 3821, - "или": 3822, - "вз": 3823, - "наций": 3824, - "ского": 3825, - "приня": 3826, - "пла": 3827, - "оч": 3828, - "иться": 3829, - "сте": 3830, - "наши": 3831, - "которые": 3832, - "ар": 3833, - "имеет": 3834, - "сот": 3835, - "знач": 3836, - "перь": 3837, - "следу": 3838, - "ены": 3839, - "таки": 3840, - "объединенных": 3841, - "стро": 3842, - "теперь": 3843, - "бле": 3844, - "благодар": 3845, - "разв": 3846, - "ан": 3847, - "жива": 3848, - "очень": 3849, - "ят": 3850, - "без": 3851, - "обес": 3852, - "гро": 3853, - "лось": 3854, - "сы": 3855, - "организации": 3856, - "член": 3857, - "того": 3858, - "ональ": 3859, - "жда": 3860, - "всех": 3861, - "свя": 3862, - "более": 3863, - "сов": 3864, - "когда": 3865, - "вот": 3866, - "кре": 3867, - "кры": 3868, - "поэтому": 3869, - "воль": 3870, - "ой": 3871, - "генера": 3872, - "чем": 3873, - "лы": 3874, - "полити": 3875, - "вен": 3876, - "конференции": 3877, - "процес": 3878, - "бя": 3879, - "ите": 3880, - "отно": 3881, - "развити": 3882, - "аф": 3883, - "ющ": 3884, - "вно": 3885, - "мир": 3886, - "нии": 3887, - "кая": 3888, - "ас": 3889, - "ительно": 3890, - "вто": 3891, - "ением": 3892, - "генераль": 3893, - "прот": 3894, - "всем": 3895, - "самбле": 3896, - "ассамбле": 3897, - "ом": 3898, - "зд": 3899, - "смот": 3900, - "реги": 3901, - "чего": 3902, - "однако": 3903, - "усилия": 3904, - "действи": 3905, - "чно": 3906, - "уча": 3907, - "образ": 3908, - "вос": 3909, - "эта": 3910, - "перего": 3911, - "говор": 3912, - "вам": 3913, - "моло": 3914, - "время": 3915, - "дь": 3916, - "хотел": 3917, - "гру": 3918, - "заявл": 3919, - "предоста": 3920, - "поль": 3921, - "нее": 3922, - "резо": 3923, - "перегово": 3924, - "резолю": 3925, - "крет": 3926, - "поддерж": 3927, - "обеспе": 3928, - "него": 3929, - "представит": 3930, - "наде": 3931, - "кри": 3932, - "чь": 3933, - "проек": 3934, - "лет": 3935, - "други": 3936, - "_": 3937, - "،": 3938, - "؛": 3939, - "؟": 3940, - "ء": 3941, - "آ": 3942, - "أ": 3943, - "ؤ": 3944, - "إ": 3945, - "ئ": 3946, - "ا": 3947, - "ب": 3948, - "ة": 3949, - "ت": 3950, - "ث": 3951, - "ج": 3952, - "ح": 3953, - "خ": 3954, - "د": 3955, - "ذ": 3956, - "ر": 3957, - "ز": 3958, - "س": 3959, - "ش": 3960, - "ص": 3961, - "ض": 3962, - "ط": 3963, - "ظ": 3964, - "ع": 3965, - "غ": 3966, - "ـ": 3967, - "ف": 3968, - "ق": 3969, - "ك": 3970, - "ل": 3971, - "م": 3972, - "ن": 3973, - "ه": 3974, - "و": 3975, - "ى": 3976, - "ي": 3977, - "ً": 3978, - "ٌ": 3979, - "ٍ": 3980, - "َ": 3981, - "ُ": 3982, - "ِ": 3983, - "ّ": 3984, - "ْ": 3985, - "ٰ": 3986, - "چ": 3987, - "ڨ": 3988, - "ک": 3989, - "ھ": 3990, - "ی": 3991, - "ۖ": 3992, - "ۗ": 3993, - "ۘ": 3994, - "ۚ": 3995, - "ۛ": 3996, - "—": 3997, - "☭": 3998, - "ﺃ": 3999, - "ﻻ": 4000, - "ال": 4001, - "َا": 4002, - "وَ": 4003, - "َّ": 4004, - "ِي": 4005, - "أَ": 4006, - "لَ": 4007, - "نَ": 4008, - "الْ": 4009, - "هُ": 4010, - "ُو": 4011, - "ما": 4012, - "نْ": 4013, - "من": 4014, - "عَ": 4015, - "نا": 4016, - "لا": 4017, - "مَ": 4018, - "تَ": 4019, - "فَ": 4020, - "أن": 4021, - "لي": 4022, - "مِ": 4023, - "ان": 4024, - "في": 4025, - "رَ": 4026, - "يَ": 4027, - "هِ": 4028, - "مْ": 4029, - "قَ": 4030, - "بِ": 4031, - "لى": 4032, - "ين": 4033, - "إِ": 4034, - "لِ": 4035, - "وا": 4036, - "كَ": 4037, - "ها": 4038, - "ًا": 4039, - "مُ": 4040, - "ون": 4041, - "الم": 4042, - "بَ": 4043, - "يا": 4044, - "ذا": 4045, - "سا": 4046, - "الل": 4047, - "مي": 4048, - "يْ": 4049, - "را": 4050, - "ري": 4051, - "لك": 4052, - "مَا": 4053, - "نَّ": 4054, - "لم": 4055, - "إن": 4056, - "ست": 4057, - "وم": 4058, - "َّا": 4059, - "لَا": 4060, - "هم": 4061, - "ِّ": 4062, - "كُ": 4063, - "كان": 4064, - "سَ": 4065, - "با": 4066, - "دي": 4067, - "حَ": 4068, - "عْ": 4069, - "بي": 4070, - "الأ": 4071, - "ول": 4072, - "فِي": 4073, - "رِ": 4074, - "دا": 4075, - "مِنْ": 4076, - "ُونَ": 4077, - "وْ": 4078, - "هَا": 4079, - "ُّ": 4080, - "الس": 4081, - "الَ": 4082, - "ني": 4083, - "لْ": 4084, - "تُ": 4085, - "هل": 4086, - "رة": 4087, - "دَ": 4088, - "سْ": 4089, - "تِ": 4090, - "نَا": 4091, - "رْ": 4092, - "اللَّ": 4093, - "سامي": 4094, - "كن": 4095, - "كل": 4096, - "هَ": 4097, - "عَلَ": 4098, - "على": 4099, - "مع": 4100, - "إلى": 4101, - "قد": 4102, - "الر": 4103, - "ُوا": 4104, - "ير": 4105, - "عن": 4106, - "يُ": 4107, - "نِ": 4108, - "بْ": 4109, - "الح": 4110, - "هُمْ": 4111, - "قا": 4112, - "ذه": 4113, - "الت": 4114, - "ِينَ": 4115, - "جَ": 4116, - "هذا": 4117, - "عد": 4118, - "الع": 4119, - "دْ": 4120, - "قَالَ": 4121, - "رُ": 4122, - "يم": 4123, - "ية": 4124, - "نُ": 4125, - "خَ": 4126, - "رب": 4127, - "الك": 4128, - "وَا": 4129, - "أنا": 4130, - "ةِ": 4131, - "الن": 4132, - "حد": 4133, - "عِ": 4134, - "تا": 4135, - "هو": 4136, - "فا": 4137, - "عا": 4138, - "الش": 4139, - "لُ": 4140, - "يت": 4141, - "ذَا": 4142, - "يع": 4143, - "الذ": 4144, - "حْ": 4145, - "الص": 4146, - "إِنَّ": 4147, - "جا": 4148, - "علي": 4149, - "كَا": 4150, - "بُ": 4151, - "تع": 4152, - "وق": 4153, - "مل": 4154, - "لَّ": 4155, - "يد": 4156, - "أخ": 4157, - "رف": 4158, - "تي": 4159, - "الِ": 4160, - "ّا": 4161, - "ذلك": 4162, - "أَنْ": 4163, - "سِ": 4164, - "توم": 4165, - "مر": 4166, - "مَنْ": 4167, - "بل": 4168, - "الق": 4169, - "الله": 4170, - "ِيَ": 4171, - "كم": 4172, - "ذَ": 4173, - "عل": 4174, - "حب": 4175, - "سي": 4176, - "عُ": 4177, - "الج": 4178, - "الد": 4179, - "شَ": 4180, - "تك": 4181, - "فْ": 4182, - "صَ": 4183, - "لل": 4184, - "دِ": 4185, - "بر": 4186, - "فِ": 4187, - "ته": 4188, - "أع": 4189, - "تْ": 4190, - "قْ": 4191, - "الْأَ": 4192, - "ئِ": 4193, - "عَنْ": 4194, - "ور": 4195, - "حا": 4196, - "الَّ": 4197, - "مت": 4198, - "فر": 4199, - "دُ": 4200, - "هنا": 4201, - "وَأَ": 4202, - "تب": 4203, - "ةُ": 4204, - "أي": 4205, - "سب": 4206, - "ريد": 4207, - "وج": 4208, - "كُمْ": 4209, - "حِ": 4210, - "كْ": 4211, - "در": 4212, - "َاء": 4213, - "هذه": 4214, - "الط": 4215, - "الْمُ": 4216, - "دة": 4217, - "قل": 4218, - "غَ": 4219, - "يوم": 4220, - "الَّذ": 4221, - "كر": 4222, - "تر": 4223, - "كِ": 4224, - "كي": 4225, - "عَلَى": 4226, - "رَب": 4227, - "عة": 4228, - "قُ": 4229, - "جْ": 4230, - "فض": 4231, - "لة": 4232, - "هْ": 4233, - "رَا": 4234, - "وَلَ": 4235, - "الْمَ": 4236, - "أَنَّ": 4237, - "يَا": 4238, - "أُ": 4239, - "شي": 4240, - "اللَّهُ": 4241, - "لَى": 4242, - "قِ": 4243, - "أت": 4244, - "عَلَيْ": 4245, - "اللَّهِ": 4246, - "الب": 4247, - "ضَ": 4248, - "ةً": 4249, - "قي": 4250, - "ار": 4251, - "بد": 4252, - "خْ": 4253, - "سْتَ": 4254, - "طَ": 4255, - "قَدْ": 4256, - "ذهب": 4257, - "أم": 4258, - "ماذا": 4259, - "وَإِ": 4260, - "ةٌ": 4261, - "ونَ": 4262, - "ليلى": 4263, - "ولا": 4264, - "حُ": 4265, - "هي": 4266, - "صل": 4267, - "الخ": 4268, - "ود": 4269, - "ليس": 4270, - "لدي": 4271, - "قال": 4272, - "كَانَ": 4273, - "مَّ": 4274, - "حي": 4275, - "تم": 4276, - "لن": 4277, - "وَلَا": 4278, - "بع": 4279, - "يمكن": 4280, - "سُ": 4281, - "ةَ": 4282, - "حت": 4283, - "رًا": 4284, - "كا": 4285, - "شا": 4286, - "هِمْ": 4287, - "لَهُ": 4288, - "زَ": 4289, - "داً": 4290, - "مس": 4291, - "كث": 4292, - "الْعَ": 4293, - "جِ": 4294, - "صْ": 4295, - "فَا": 4296, - "له": 4297, - "وي": 4298, - "عَا": 4299, - "هُوَ": 4300, - "بِي": 4301, - "بَا": 4302, - "أس": 4303, - "ثَ": 4304, - "لِي": 4305, - "رض": 4306, - "الرَّ": 4307, - "لِكَ": 4308, - "تَّ": 4309, - "فُ": 4310, - "قة": 4311, - "فعل": 4312, - "مِن": 4313, - "الآ": 4314, - "ثُ": 4315, - "سم": 4316, - "مَّا": 4317, - "بِهِ": 4318, - "تق": 4319, - "خر": 4320, - "لقد": 4321, - "خل": 4322, - "شر": 4323, - "أنت": 4324, - "لَّا": 4325, - "سن": 4326, - "السَّ": 4327, - "الذي": 4328, - "سَا": 4329, - "وما": 4330, - "زل": 4331, - "وب": 4332, - "أْ": 4333, - "إذا": 4334, - "رِي": 4335, - "حة": 4336, - "نِي": 4337, - "الْحَ": 4338, - "وَقَالَ": 4339, - "به": 4340, - "ةٍ": 4341, - "سأ": 4342, - "رٌ": 4343, - "بال": 4344, - "مة": 4345, - "شْ": 4346, - "وت": 4347, - "عند": 4348, - "فس": 4349, - "بَعْ": 4350, - "هر": 4351, - "قط": 4352, - "أح": 4353, - "إنه": 4354, - "وع": 4355, - "فت": 4356, - "غا": 4357, - "هناك": 4358, - "بت": 4359, - "مِنَ": 4360, - "سر": 4361, - "ذَلِكَ": 4362, - "رس": 4363, - "حدث": 4364, - "غْ": 4365, - "ِّي": 4366, - "الإ": 4367, - "وَيَ": 4368, - "جل": 4369, - "است": 4370, - "قِي": 4371, - "عب": 4372, - "وس": 4373, - "يش": 4374, - "الَّذِينَ": 4375, - "تاب": 4376, - "دِي": 4377, - "جب": 4378, - "كون": 4379, - "بن": 4380, - "الث": 4381, - "لَيْ": 4382, - "بعد": 4383, - "وَالْ": 4384, - "فَأَ": 4385, - "عم": 4386, - "هُم": 4387, - "تن": 4388, - "ذْ": 4389, - "أص": 4390, - "أين": 4391, - "رَبِّ": 4392, - "الذين": 4393, - "إِن": 4394, - "بين": 4395, - "جُ": 4396, - "عَلَيْهِ": 4397, - "حَا": 4398, - "لو": 4399, - "ستط": 4400, - "ظر": 4401, - "لَمْ": 4402, - "ءِ": 4403, - "كُل": 4404, - "طل": 4405, - "تَا": 4406, - "ضُ": 4407, - "كنت": 4408, - "لًا": 4409, - "مٌ": 4410, - "قبل": 4411, - "ــ": 4412, - "ذِ": 4413, - "قَوْ": 4414, - "صِ": 4415, - "مًا": 4416, - "كانت": 4417, - "صا": 4418, - "يق": 4419, - "الف": 4420, - "النا": 4421, - "مٍ": 4422, - "إِنْ": 4423, - "النَّ": 4424, - "جد": 4425, - "وَمَا": 4426, - "تت": 4427, - "بح": 4428, - "مكان": 4429, - "كيف": 4430, - "ّة": 4431, - "الا": 4432, - "جَا": 4433, - "أو": 4434, - "ساعد": 4435, - "ضِ": 4436, - "إلا": 4437, - "راً": 4438, - "قَا": 4439, - "رأ": 4440, - "عت": 4441, - "أحد": 4442, - "هد": 4443, - "ضا": 4444, - "طر": 4445, - "أق": 4446, - "ماء": 4447, - "دَّ": 4448, - "البا": 4449, - "مُو": 4450, - "أَوْ": 4451, - "طا": 4452, - "قُو": 4453, - "خِ": 4454, - "تل": 4455, - "ستطيع": 4456, - "دَا": 4457, - "النَّا": 4458, - "إلَى": 4459, - "وَتَ": 4460, - "هَذَا": 4461, - "بة": 4462, - "عليك": 4463, - "جر": 4464, - "المن": 4465, - "زا": 4466, - "رٍ": 4467, - "دع": 4468, - "ًّا": 4469, - "سة": 4470, - "ثُمَّ": 4471, - "شيء": 4472, - "الغ": 4473, - "تح": 4474, - "رُونَ": 4475, - "اليوم": 4476, - "مِي": 4477, - "نُوا": 4478, - "أر": 4479, - "تُمْ": 4480, - "عر": 4481, - "يف": 4482, - "أب": 4483, - "دًا": 4484, - "صَا": 4485, - "التَّ": 4486, - "أريد": 4487, - "الز": 4488, - "يَوْ": 4489, - "إلي": 4490, - "جي": 4491, - "يَعْ": 4492, - "فضل": 4493, - "الإن": 4494, - "أنه": 4495, - "1": 4496, - "2": 4497, - "3": 4498, - "4": 4499, - "5": 4500, - "·": 4501, - "×": 4502, - "̃": 4503, - "̌": 4504, - "ε": 4505, - "λ": 4506, - "μ": 4507, - "•": 4508, - "‧": 4509, - "─": 4510, - "□": 4511, - "、": 4512, - "。": 4513, - "〈": 4514, - "〉": 4515, - "《": 4516, - "》": 4517, - "「": 4518, - "」": 4519, - "『": 4520, - "』": 4521, - "ア": 4522, - "オ": 4523, - "カ": 4524, - "チ": 4525, - "ド": 4526, - "ベ": 4527, - "ャ": 4528, - "ヤ": 4529, - "ン": 4530, - "・": 4531, - "ー": 4532, - "ㄟ": 4533, - "!": 4534, - "(": 4535, - ")": 4536, - ",": 4537, - "-": 4538, - "/": 4539, - ":": 4540, - ";": 4541, - "?": 4542, - "p": 4543, - "i4": 4544, - "zh": 4545, - "i2": 4546, - "ng1": 4547, - "u4": 4548, - "i1": 4549, - "ng2": 4550, - "u3": 4551, - "de5": 4552, - "e4": 4553, - "i3": 4554, - "ng4": 4555, - "an4": 4556, - "shi4": 4557, - "an2": 4558, - "u2": 4559, - "u1": 4560, - "ng3": 4561, - "a1": 4562, - "an1": 4563, - "e2": 4564, - "a4": 4565, - "ei4": 4566, - "ong1": 4567, - "ai4": 4568, - "ao4": 4569, - "ang1": 4570, - "an3": 4571, - "wei4": 4572, - "uo2": 4573, - "n1": 4574, - "en2": 4575, - "ao3": 4576, - "e1": 4577, - "qi": 4578, - "eng2": 4579, - "zho": 4580, - "ang3": 4581, - "ang4": 4582, - "ang2": 4583, - "uo4": 4584, - "ge4": 4585, - "yi1": 4586, - "guo2": 4587, - "a3": 4588, - "he2": 4589, - "e3": 4590, - "yi2": 4591, - "di4": 4592, - "zhong1": 4593, - "bu4": 4594, - "ai2": 4595, - "n2": 4596, - "zai4": 4597, - "shi2": 4598, - "eng1": 4599, - "ren2": 4600, - "ong2": 4601, - "xian4": 4602, - "xu": 4603, - "n4": 4604, - "li4": 4605, - "en4": 4606, - "yu2": 4607, - "ei2": 4608, - "yi2ge4": 4609, - "ou4": 4610, - "ei3": 4611, - "ui4": 4612, - "a2": 4613, - "you3": 4614, - "ao1": 4615, - "da4": 4616, - "cheng2": 4617, - "en1": 4618, - "eng4": 4619, - "yi4": 4620, - "si1": 4621, - "zhi4": 4622, - "jia1": 4623, - "yuan2": 4624, - "ta1": 4625, - "de5yi2ge4": 4626, - "ke1": 4627, - "shu3": 4628, - "xi1": 4629, - "ji2": 4630, - "ao2": 4631, - "ou3": 4632, - "ong4": 4633, - "xia4": 4634, - "ai1": 4635, - "gong1": 4636, - "zhi1": 4637, - "en3": 4638, - "wei2": 4639, - "xue2": 4640, - "qu1": 4641, - "zhou1": 4642, - "er3": 4643, - "ming2": 4644, - "zhong3": 4645, - "li3": 4646, - "wu4": 4647, - "yi3": 4648, - "uo1": 4649, - "e5": 4650, - "ji4": 4651, - "xing2": 4652, - "jian4": 4653, - "hua4": 4654, - "yu3": 4655, - "uo3": 4656, - "ji1": 4657, - "ai3": 4658, - "zuo4": 4659, - "hou4": 4660, - "hui4": 4661, - "ei1": 4662, - "nian2": 4663, - "qi2": 4664, - "dao4": 4665, - "sheng1": 4666, - "de2": 4667, - "dai4": 4668, - "uan2": 4669, - "zhe4": 4670, - "zheng4": 4671, - "ben3": 4672, - "shang4": 4673, - "zhu3": 4674, - "bei4": 4675, - "ye4": 4676, - "chu1": 4677, - "zhan4": 4678, - "le5": 4679, - "lai2": 4680, - "shi3": 4681, - "nan2": 4682, - "ren4": 4683, - "you2": 4684, - "ke4": 4685, - "ba1": 4686, - "fu4": 4687, - "dui4": 4688, - "ya4": 4689, - "mei3": 4690, - "zi4": 4691, - "xin1": 4692, - "jing1": 4693, - "zhu": 4694, - "n3": 4695, - "yong4": 4696, - "mu4": 4697, - "jiao4": 4698, - "ye3": 4699, - "jin4": 4700, - "bian4": 4701, - "lu4": 4702, - "qi1": 4703, - "she4": 4704, - "xiang1": 4705, - "ong3": 4706, - "shu4": 4707, - "dong4": 4708, - "suo3": 4709, - "guan1": 4710, - "san1": 4711, - "te4": 4712, - "duo1": 4713, - "fu2": 4714, - "min2": 4715, - "la1": 4716, - "zhi2": 4717, - "zhen4": 4718, - "ou1": 4719, - "wu3": 4720, - "ma3": 4721, - "i5": 4722, - "zi5": 4723, - "ju4": 4724, - "er4": 4725, - "yao4": 4726, - "xia4de5yi2ge4": 4727, - "si4": 4728, - "tu2": 4729, - "shan1": 4730, - "zui4": 4731, - "yin1": 4732, - "er2": 4733, - "tong2": 4734, - "dong1": 4735, - "yu4": 4736, - "yan2": 4737, - "qian2": 4738, - "shu3xia4de5yi2ge4": 4739, - "jun1": 4740, - "ke3": 4741, - "wen2": 4742, - "fa3": 4743, - "luo2": 4744, - "zhu4": 4745, - "xi4": 4746, - "kou3": 4747, - "bei3": 4748, - "jian1": 4749, - "fa1": 4750, - "dian4": 4751, - "jiang1": 4752, - "wei4yu2": 4753, - "xiang4": 4754, - "zhi3": 4755, - "eng3": 4756, - "fang1": 4757, - "lan2": 4758, - "shu": 4759, - "ri4": 4760, - "lian2": 4761, - "shou3": 4762, - "qiu2": 4763, - "jin1": 4764, - "huo4": 4765, - "shu3xia4de5yi2ge4zhong3": 4766, - "fen1": 4767, - "nei4": 4768, - "gai1": 4769, - "mei3guo2": 4770, - "un2": 4771, - "ge2": 4772, - "bao3": 4773, - "qing1": 4774, - "gao1": 4775, - "tai2": 4776, - "xiao3": 4777, - "jie2": 4778, - "tian1": 4779, - "chang2": 4780, - "quan2": 4781, - "lie4": 4782, - "hai3": 4783, - "fei1": 4784, - "ti3": 4785, - "jue2": 4786, - "ou2": 4787, - "ci3": 4788, - "zu2": 4789, - "ni2": 4790, - "biao3": 4791, - "zhong1guo2": 4792, - "du4": 4793, - "yue4": 4794, - "xing4": 4795, - "sheng4": 4796, - "che1": 4797, - "dan1": 4798, - "jie1": 4799, - "lin2": 4800, - "ping2": 4801, - "fu3": 4802, - "gu3": 4803, - "jie4": 4804, - "v3": 4805, - "sheng3": 4806, - "na4": 4807, - "yuan4": 4808, - "zhang3": 4809, - "guan3": 4810, - "dao3": 4811, - "zu3": 4812, - "ding4": 4813, - "dian3": 4814, - "ceng2": 4815, - "ren2kou3": 4816, - "tai4": 4817, - "tong1": 4818, - "guo4": 4819, - "neng2": 4820, - "chang3": 4821, - "hua2": 4822, - "liu2": 4823, - "ying1": 4824, - "xiao4": 4825, - "ci4": 4826, - "bian4hua4": 4827, - "liang3": 4828, - "gong4": 4829, - "zhong4": 4830, - "de5yi1": 4831, - "se4": 4832, - "kai1": 4833, - "wang2": 4834, - "jiu4": 4835, - "shi1": 4836, - "shou4": 4837, - "mei2": 4838, - "feng1": 4839, - "ze2": 4840, - "tu2shi4": 4841, - "ti2": 4842, - "qi4": 4843, - "jiu3": 4844, - "shen1": 4845, - "zhe3": 4846, - "ren2kou3bian4hua4": 4847, - "ren2kou3bian4hua4tu2shi4": 4848, - "di4qu1": 4849, - "yang2": 4850, - "men5": 4851, - "long2": 4852, - "bing4": 4853, - "chan3": 4854, - "zhu1": 4855, - "wei3": 4856, - "wai4": 4857, - "xing1": 4858, - "bo1": 4859, - "bi3": 4860, - "tang2": 4861, - "hua1": 4862, - "bo2": 4863, - "shui3": 4864, - "shu1": 4865, - "dou1": 4866, - "sai4": 4867, - "chao2": 4868, - "bi4": 4869, - "ling2": 4870, - "lei4": 4871, - "da4xue2": 4872, - "fen4": 4873, - "shu3de5": 4874, - "mu3": 4875, - "jiao1": 4876, - "dang1": 4877, - "cheng1": 4878, - "tong3": 4879, - "nv3": 4880, - "qi3": 4881, - "yan3": 4882, - "mian4": 4883, - "luo4": 4884, - "jing4": 4885, - "ge1": 4886, - "ru4": 4887, - "dan4": 4888, - "ri4ben3": 4889, - "pu3": 4890, - "yun4": 4891, - "huang2": 4892, - "wo3": 4893, - "lv": 4894, - "hai2": 4895, - "shi4yi1": 4896, - "xie1": 4897, - "ying3": 4898, - "wu2": 4899, - "shen2": 4900, - "wang3": 4901, - "guang3": 4902, - "liu4": 4903, - "su4": 4904, - "shi4zhen4": 4905, - "can1": 4906, - "cao3": 4907, - "xia2": 4908, - "ka3": 4909, - "da2": 4910, - "hu4": 4911, - "ban4": 4912, - "dang3": 4913, - "hu2": 4914, - "zong3": 4915, - "deng3": 4916, - "de5yi2ge4shi4zhen4": 4917, - "chuan2": 4918, - "mo4": 4919, - "zhang1": 4920, - "ban1": 4921, - "mo2": 4922, - "cha2": 4923, - "ce4": 4924, - "zhu3yao4": 4925, - "tou2": 4926, - "ju2": 4927, - "shi4wei4yu2": 4928, - "sa4": 4929, - "un1": 4930, - "ke3yi3": 4931, - "du1": 4932, - "han4": 4933, - "liang4": 4934, - "sha1": 4935, - "jia3": 4936, - "zi1": 4937, - "lv4": 4938, - "fu1": 4939, - "xian1": 4940, - "xu4": 4941, - "guang1": 4942, - "meng2": 4943, - "bao4": 4944, - "you4": 4945, - "rong2": 4946, - "zhi1yi1": 4947, - "wei1": 4948, - "mao2": 4949, - "guo2jia1": 4950, - "cong2": 4951, - "gou4": 4952, - "tie3": 4953, - "zhen1": 4954, - "du2": 4955, - "bian1": 4956, - "ci2": 4957, - "qu3": 4958, - "fan4": 4959, - "xiang3": 4960, - "men2": 4961, - "ju1": 4962, - "hong2": 4963, - "zi3": 4964, - "ta1men5": 4965, - "ji3": 4966, - "zong1": 4967, - "zhou1de5yi2ge4shi4zhen4": 4968, - "tuan2": 4969, - "jing3": 4970, - "gong1si1": 4971, - "xie4": 4972, - "li2": 4973, - "li4shi3": 4974, - "bao1": 4975, - "gang3": 4976, - "gui1": 4977, - "zheng1": 4978, - "zhi2wu4": 4979, - "ta1de5": 4980, - "pin3": 4981, - "zhuan1": 4982, - "chong2": 4983, - "shi3yong4": 4984, - "wa3": 4985, - "shuo1": 4986, - "chuan1": 4987, - "lei2": 4988, - "wan1": 4989, - "huo2": 4990, - "su1": 4991, - "zao3": 4992, - "gai3": 4993, - "qu4": 4994, - "gu4": 4995, - "xi2": 4996, - "hang2": 4997, - "ying4": 4998, - "cun1": 4999, - "gen1": 5000, - "ying2": 5001, - "ting2": 5002, - "cheng2shi4": 5003, - "jiang3": 5004, - "ling3": 5005, - "lun2": 5006, - "bu4fen4": 5007, - "deng1": 5008, - "xuan3": 5009, - "dong4wu4": 5010, - "de2guo2": 5011, - "xian3": 5012, - "fan3": 5013, - "zhe5": 5014, - "han2": 5015, - "hao4": 5016, - "mi4": 5017, - "ran2": 5018, - "qin1": 5019, - "tiao2": 5020, - "zhan3": 5021, - "[ar]": 5022, - "[zh-cn]": 5023, - "¡": 5024, - "é": 5025, - "shi": 5026, - "tsu": 5027, - "teki": 5028, - "nai": 5029, - "aru": 5030, - "uu": 5031, - "kai": 5032, - "shite": 5033, - "mono": 5034, - "koto": 5035, - "kara": 5036, - "shita": 5037, - "suru": 5038, - "masu": 5039, - "tai": 5040, - "ware": 5041, - "shin": 5042, - "oku": 5043, - "yuu": 5044, - "iru": 5045, - "jiko": 5046, - "desu": 5047, - "rare": 5048, - "shou": 5049, - "sha": 5050, - "sekai": 5051, - "kyou": 5052, - "mashita": 5053, - "nara": 5054, - "kei": 5055, - "ita": 5056, - "ari": 5057, - "itsu": 5058, - "kono": 5059, - "naka": 5060, - "chou": 5061, - "sore": 5062, - "naru": 5063, - "gaku": 5064, - "reba": 5065, - "hito": 5066, - "sai": 5067, - "nan": 5068, - "dai": 5069, - "tsuku": 5070, - "shiki": 5071, - "sare": 5072, - "naku": 5073, - "jun": 5074, - "kaku": 5075, - "zai": 5076, - "wata": 5077, - "shuu": 5078, - "ii": 5079, - "kare": 5080, - "shii": 5081, - "made": 5082, - "sho": 5083, - "kereba": 5084, - "shika": 5085, - "ichi": 5086, - "deki": 5087, - "nin": 5088, - "wareware": 5089, - "nakereba": 5090, - "oite": 5091, - "yaku": 5092, - "mujun": 5093, - "yoku": 5094, - "butsu": 5095, - "omo": 5096, - "gae": 5097, - "naranai": 5098, - "tachi": 5099, - "chuu": 5100, - "kangae": 5101, - "toki": 5102, - "koro": 5103, - "mujunteki": 5104, - "naga": 5105, - "jin": 5106, - "shima": 5107, - "iku": 5108, - "imasu": 5109, - "hon": 5110, - "kae": 5111, - "kore": 5112, - "kita": 5113, - "datta": 5114, - "jitsu": 5115, - "mae": 5116, - "toku": 5117, - "douitsu": 5118, - "ritsu": 5119, - "kyuu": 5120, - "hyou": 5121, - "rareta": 5122, - "keisei": 5123, - "kkan": 5124, - "rareru": 5125, - "mou": 5126, - "doko": 5127, - "ryou": 5128, - "dake": 5129, - "nakatta": 5130, - "soko": 5131, - "tabe": 5132, - "hana": 5133, - "fuku": 5134, - "yasu": 5135, - "wataku": 5136, - "yama": 5137, - "kyo": 5138, - "genzai": 5139, - "boku": 5140, - "ata": 5141, - "kawa": 5142, - "masen": 5143, - "juu": 5144, - "natte": 5145, - "watakushi": 5146, - "yotte": 5147, - "hai": 5148, - "jishin": 5149, - "rete": 5150, - "oka": 5151, - "kagaku": 5152, - "natta": 5153, - "karu": 5154, - "nari": 5155, - "mata": 5156, - "kuru": 5157, - "gai": 5158, - "kari": 5159, - "shakai": 5160, - "koui": 5161, - "yori": 5162, - "setsu": 5163, - "reru": 5164, - "tokoro": 5165, - "jutsu": 5166, - "saku": 5167, - "ttai": 5168, - "ningen": 5169, - "tame": 5170, - "kankyou": 5171, - "ooku": 5172, - "watashi": 5173, - "tsukuru": 5174, - "sugi": 5175, - "jibun": 5176, - "shitsu": 5177, - "keru": 5178, - "kishi": 5179, - "shikashi": 5180, - "moto": 5181, - "mari": 5182, - "itte": 5183, - "deshita": 5184, - "nde": 5185, - "arimasu": 5186, - "koe": 5187, - "zettai": 5188, - "kkanteki": 5189, - "rekishi": 5190, - "dekiru": 5191, - "tsuka": 5192, - "itta": 5193, - "kobutsu": 5194, - "miru": 5195, - "shoku": 5196, - "shimasu": 5197, - "gijutsu": 5198, - "gyou": 5199, - "joushiki": 5200, - "atta": 5201, - "hodo": 5202, - "koko": 5203, - "tsukurareta": 5204, - "zoku": 5205, - "hitei": 5206, - "koku": 5207, - "rekishiteki": 5208, - "kete": 5209, - "kako": 5210, - "nagara": 5211, - "kakaru": 5212, - "shutai": 5213, - "haji": 5214, - "taku": 5215, - "douitsuteki": 5216, - "mete": 5217, - "tsuu": 5218, - "sarete": 5219, - "genjitsu": 5220, - "bai": 5221, - "nawa": 5222, - "jikan": 5223, - "waru": 5224, - "rt": 5225, - "atsu": 5226, - "soku": 5227, - "kouiteki": 5228, - "kata": 5229, - "tetsu": 5230, - "gawa": 5231, - "kedo": 5232, - "reta": 5233, - "sayou": 5234, - "tteru": 5235, - "tori": 5236, - "kimi": 5237, - "mura": 5238, - "sareru": 5239, - "machi": 5240, - "kya": 5241, - "osa": 5242, - "konna": 5243, - "aku": 5244, - "sareta": 5245, - "ipp": 5246, - "shiku": 5247, - "uchi": 5248, - "hitotsu": 5249, - "hatara": 5250, - "tachiba": 5251, - "shiro": 5252, - "katachi": 5253, - "tomo": 5254, - "ete": 5255, - "meru": 5256, - "nichi": 5257, - "dare": 5258, - "katta": 5259, - "eru": 5260, - "suki": 5261, - "ooki": 5262, - "maru": 5263, - "moku": 5264, - "oko": 5265, - "kangaerareru": 5266, - "oto": 5267, - "tanni": 5268, - "tada": 5269, - "taiteki": 5270, - "motte": 5271, - "kinou": 5272, - "shinai": 5273, - "kki": 5274, - "tari": 5275, - "ranai": 5276, - "kkou": 5277, - "mirai": 5278, - "ppon": 5279, - "goto": 5280, - "hitsu": 5281, - "teru": 5282, - "mochi": 5283, - "katsu": 5284, - "nyuu": 5285, - "zuka": 5286, - "tsuite": 5287, - "nomi": 5288, - "sugu": 5289, - "kuda": 5290, - "tetsugaku": 5291, - "ika": 5292, - "ronri": 5293, - "oki": 5294, - "nippon": 5295, - "shimashita": 5296, - "chishiki": 5297, - "chokkanteki": 5298, - "suko": 5299, - "kuu": 5300, - "arou": 5301, - "katte": 5302, - "kuri": 5303, - "inai": 5304, - "hyougen": 5305, - "ishiki": 5306, - "doku": 5307, - "atte": 5308, - "atara": 5309, - "wari": 5310, - "kao": 5311, - "seisan": 5312, - "hanashi": 5313, - "kake": 5314, - "naji": 5315, - "sunawa": 5316, - "sunawachi": 5317, - "ugo": 5318, - "suu": 5319, - "bara": 5320, - "hiro": 5321, - "iwa": 5322, - "betsu": 5323, - "yoi": 5324, - "seru": 5325, - "shiteru": 5326, - "rarete": 5327, - "toshi": 5328, - "seki": 5329, - "tairitsu": 5330, - "wakara": 5331, - "tokyo": 5332, - "kka": 5333, - "kyoku": 5334, - "iro": 5335, - "mite": 5336, - "saki": 5337, - "kanji": 5338, - "mita": 5339, - "sube": 5340, - "ryoku": 5341, - "matta": 5342, - "kudasai": 5343, - "omoi": 5344, - "wareru": 5345, - "hitsuyou": 5346, - "kashi": 5347, - "renai": 5348, - "kankei": 5349, - "gatte": 5350, - "ochi": 5351, - "motsu": 5352, - "sonzai": 5353, - "taishite": 5354, - "ame": 5355, - "seimei": 5356, - "kano": 5357, - "giri": 5358, - "kangaeru": 5359, - "yue": 5360, - "asa": 5361, - "onaji": 5362, - "yoru": 5363, - "niku": 5364, - "osaka": 5365, - "sukoshi": 5366, - "tama": 5367, - "kanojo": 5368, - "kite": 5369, - "mondai": 5370, - "amari": 5371, - "eki": 5372, - "kojin": 5373, - "haya": 5374, - "dete": 5375, - "atarashii": 5376, - "awa": 5377, - "gakkou": 5378, - "tsuzu": 5379, - "shukan": 5380, - "imashita": 5381, - "atae": 5382, - "darou": 5383, - "hataraku": 5384, - "gata": 5385, - "dachi": 5386, - "matsu": 5387, - "arimasen": 5388, - "seibutsu": 5389, - "mitsu": 5390, - "heya": 5391, - "yasui": 5392, - "deni": 5393, - "noko": 5394, - "haha": 5395, - "domo": 5396, - "kami": 5397, - "sudeni": 5398, - "nao": 5399, - "raku": 5400, - "ike": 5401, - "meta": 5402, - "kodomo": 5403, - "soshite": 5404, - "game": 5405, - "bakari": 5406, - "tote": 5407, - "hatsu": 5408, - "mise": 5409, - "mokuteki": 5410, - "dakara": 5411, - "[ja]": 5412, - "ő": 5413, - "ű": 5414, - "そ": 5415, - "な": 5416, - "ん": 5417, - "포": 5418, - "�": 5419, - "gy": 5420, - "eg": 5421, - "cs": 5422, - "ál": 5423, - "egy": 5424, - "át": 5425, - "ott": 5426, - "ett": 5427, - "meg": 5428, - "hogy": 5429, - "ég": 5430, - "ól": 5431, - "nek": 5432, - "volt": 5433, - "ág": 5434, - "nk": 5435, - "ék": 5436, - "ít": 5437, - "ák": 5438, - "ud": 5439, - "szer": 5440, - "mind": 5441, - "oz": 5442, - "ép": 5443, - "ért": 5444, - "mond": 5445, - "szt": 5446, - "nak": 5447, - "ől": 5448, - "csak": 5449, - "oly": 5450, - "áll": 5451, - "ány": 5452, - "mint": 5453, - "már": 5454, - "ött": 5455, - "nagy": 5456, - "ész": 5457, - "azt": 5458, - "elő": 5459, - "tud": 5460, - "ény": 5461, - "áz": 5462, - "még": 5463, - "köz": 5464, - "ely": 5465, - "ség": 5466, - "hoz": 5467, - "uk": 5468, - "kez": 5469, - "ám": 5470, - "aj": 5471, - "unk": 5472, - "vagy": 5473, - "szem": 5474, - "ember": 5475, - "fog": 5476, - "mert": 5477, - "ös": 5478, - "ság": 5479, - "leg": 5480, - "ünk": 5481, - "hát": 5482, - "ony": 5483, - "ezt": 5484, - "minden": 5485, - "ült": 5486, - "jó": 5487, - "kis": 5488, - "áj": 5489, - "úgy": 5490, - "most": 5491, - "ír": 5492, - "itt": 5493, - "elt": 5494, - "mondta": 5495, - "kell": 5496, - "ált": 5497, - "érd": 5498, - "tö": 5499, - "vár": 5500, - "lát": 5501, - "ők": 5502, - "vet": 5503, - "után": 5504, - "két": 5505, - "nap": 5506, - "ív": 5507, - "ály": 5508, - "vég": 5509, - "ök": 5510, - "dul": 5511, - "néz": 5512, - "ában": 5513, - "kül": 5514, - "akkor": 5515, - "szél": 5516, - "új": 5517, - "olyan": 5518, - "ked": 5519, - "hely": 5520, - "tör": 5521, - "ból": 5522, - "elm": 5523, - "ára": 5524, - "ló": 5525, - "volna": 5526, - "lehet": 5527, - "ebb": 5528, - "sok": 5529, - "olt": 5530, - "eket": 5531, - "bor": 5532, - "fej": 5533, - "gond": 5534, - "akar": 5535, - "fél": 5536, - "úl": 5537, - "otta": 5538, - "valami": 5539, - "jel": 5540, - "éd": 5541, - "arc": 5542, - "hall": 5543, - "föl": 5544, - "ába": 5545, - "olg": 5546, - "kir": 5547, - "old": 5548, - "kérd": 5549, - "jár": 5550, - "úr": 5551, - "zs": 5552, - "élet": 5553, - "ját": 5554, - "ov": 5555, - "éz": 5556, - "vil": 5557, - "őr": 5558, - "ög": 5559, - "lesz": 5560, - "koz": 5561, - "ább": 5562, - "király": 5563, - "eng": 5564, - "igaz": 5565, - "haj": 5566, - "kod": 5567, - "ról": 5568, - "több": 5569, - "szó": 5570, - "ében": 5571, - "öt": 5572, - "nyi": 5573, - "szól": 5574, - "gondol": 5575, - "egész": 5576, - "így": 5577, - "ős": 5578, - "obb": 5579, - "osan": 5580, - "ből": 5581, - "abb": 5582, - "őt": 5583, - "nál": 5584, - "kép": 5585, - "aztán": 5586, - "tart": 5587, - "beszél": 5588, - "előtt": 5589, - "aszt": 5590, - "maj": 5591, - "kör": 5592, - "hang": 5593, - "íz": 5594, - "incs": 5595, - "év": 5596, - "ód": 5597, - "ók": 5598, - "hozz": 5599, - "okat": 5600, - "nagyon": 5601, - "ház": 5602, - "ped": 5603, - "ezte": 5604, - "etlen": 5605, - "neki": 5606, - "majd": 5607, - "szony": 5608, - "ának": 5609, - "felé": 5610, - "egyszer": 5611, - "adt": 5612, - "gyer": 5613, - "amikor": 5614, - "foly": 5615, - "szak": 5616, - "őd": 5617, - "hú": 5618, - "ász": 5619, - "amely": 5620, - "ére": 5621, - "ilyen": 5622, - "oda": 5623, - "ják": 5624, - "tár": 5625, - "ával": 5626, - "lak": 5627, - "gyan": 5628, - "ély": 5629, - "út": 5630, - "kezd": 5631, - "mell": 5632, - "mikor": 5633, - "hez": 5634, - "való": 5635, - "szeret": 5636, - "rend": 5637, - "vissza": 5638, - "fő": 5639, - "asszony": 5640, - "ről": 5641, - "pedig": 5642, - "szép": 5643, - "ták": 5644, - "öv": 5645, - "világ": 5646, - "maga": 5647, - "szik": 5648, - "éj": 5649, - "ént": 5650, - "jött": 5651, - "szí": 5652, - "gat": 5653, - "ettem": 5654, - "hány": 5655, - "ást": 5656, - "ahol": 5657, - "őket": 5658, - "hár": 5659, - "nő": 5660, - "csi": 5661, - "talál": 5662, - "elte": 5663, - "látt": 5664, - "tört": 5665, - "hagy": 5666, - "esz": 5667, - "nél": 5668, - "kut": 5669, - "lány": 5670, - "amit": 5671, - "ső": 5672, - "ellen": 5673, - "magát": 5674, - "ugyan": 5675, - "külön": 5676, - "asz": 5677, - "mindig": 5678, - "lép": 5679, - "talán": 5680, - "szor": 5681, - "illan": 5682, - "nincs": 5683, - "vagyok": 5684, - "telen": 5685, - "ismer": 5686, - "isten": 5687, - "ított": 5688, - "jobb": 5689, - "ves": 5690, - "dult": 5691, - "juk": 5692, - "szen": 5693, - "öm": 5694, - "lett": 5695, - "egyik": 5696, - "bár": 5697, - "szi": 5698, - "szív": 5699, - "azon": 5700, - "eszt": 5701, - "föld": 5702, - "kuty": 5703, - "pillan": 5704, - "fér": 5705, - "től": 5706, - "tű": 5707, - "ébe": 5708, - "tött": 5709, - "barát": 5710, - "íg": 5711, - "ahogy": 5712, - "eh": 5713, - "ep": 5714, - "jelent": 5715, - "tat": 5716, - "szeg": 5717, - "mintha": 5718, - "egyen": 5719, - "szab": 5720, - "bizony": 5721, - "jon": 5722, - "öreg": 5723, - "dolg": 5724, - "csap": 5725, - "tiszt": 5726, - "állt": 5727, - "ancs": 5728, - "idő": 5729, - "ügy": 5730, - "miért": 5731, - "ót": 5732, - "csin": 5733, - "ének": 5734, - "vér": 5735, - "jól": 5736, - "alatt": 5737, - "mely": 5738, - "semmi": 5739, - "nyug": 5740, - "vág": 5741, - "követ": 5742, - "össze": 5743, - "mad": 5744, - "acs": 5745, - "fiú": 5746, - "másik": 5747, - "jön": 5748, - "szám": 5749, - "rész": 5750, - "kér": 5751, - "ével": 5752, - "[hu]": 5753, - "%": 5754, - "0": 5755, - "6": 5756, - "7": 5757, - "8": 5758, - "9": 5759, - "A": 5760, - "B": 5761, - "C": 5762, - "D": 5763, - "E": 5764, - "F": 5765, - "G": 5766, - "H": 5767, - "I": 5768, - "J": 5769, - "K": 5770, - "L": 5771, - "M": 5772, - "N": 5773, - "O": 5774, - "P": 5775, - "Q": 5776, - "R": 5777, - "S": 5778, - "T": 5779, - "U": 5780, - "V": 5781, - "W": 5782, - "X": 5783, - "Y": 5784, - "Z": 5785, - "Ł": 5786, - "α": 5787, - "ς": 5788, - "♥": 5789, - "か": 5790, - "ズ": 5791, - "因": 5792, - "国": 5793, - "怎": 5794, - "抱": 5795, - "推": 5796, - "有": 5797, - "樣": 5798, - "為": 5799, - "群": 5800, - "麼": 5801, - "eo": 5802, - "eul": 5803, - "eun": 5804, - "eon": 5805, - "ae": 5806, - "yeon": 5807, - "yeo": 5808, - "ui": 5809, - "hae": 5810, - "geo": 5811, - "neun": 5812, - "ssda": 5813, - "seo": 5814, - "eong": 5815, - "kk": 5816, - "jeo": 5817, - "deul": 5818, - "eum": 5819, - "yeong": 5820, - "geos": 5821, - "hag": 5822, - "aneun": 5823, - "iss": 5824, - "dae": 5825, - "eob": 5826, - "eol": 5827, - "geu": 5828, - "jeong": 5829, - "sae": 5830, - "doe": 5831, - "geul": 5832, - "eulo": 5833, - "bn": 5834, - "sang": 5835, - "bnida": 5836, - "haneun": 5837, - "jeog": 5838, - "saeng": 5839, - "ineun": 5840, - "anh": 5841, - "salam": 5842, - "eom": 5843, - "nae": 5844, - "gwa": 5845, - "yeol": 5846, - "eseo": 5847, - "myeon": 5848, - "ttae": 5849, - "hw": 5850, - "eobs": 5851, - "jang": 5852, - "gw": 5853, - "ileul": 5854, - "yeog": 5855, - "jeon": 5856, - "sig": 5857, - "jag": 5858, - "hago": 5859, - "deun": 5860, - "seong": 5861, - "gag": 5862, - "ham": 5863, - "dang": 5864, - "leul": 5865, - "sil": 5866, - "dong": 5867, - "handa": 5868, - "eossda": 5869, - "aeg": 5870, - "seon": 5871, - "haessda": 5872, - "issda": 5873, - "ege": 5874, - "mul": 5875, - "jung": 5876, - "jig": 5877, - "issneun": 5878, - "geun": 5879, - "seubnida": 5880, - "won": 5881, - "daneun": 5882, - "eoh": 5883, - "deo": 5884, - "gam": 5885, - "jal": 5886, - "haeng": 5887, - "yang": 5888, - "bang": 5889, - "jae": 5890, - "saenggag": 5891, - "hage": 5892, - "sog": 5893, - "eoss": 5894, - "jasin": 5895, - "jil": 5896, - "eog": 5897, - "gyeong": 5898, - "gong": 5899, - "deon": 5900, - "haess": 5901, - "eung": 5902, - "joh": 5903, - "nal": 5904, - "myeong": 5905, - "eona": 5906, - "igo": 5907, - "gyeol": 5908, - "yag": 5909, - "gwan": 5910, - "uli": 5911, - "yong": 5912, - "lyeo": 5913, - "jog": 5914, - "eohge": 5915, - "bog": 5916, - "tong": 5917, - "manh": 5918, - "jeol": 5919, - "geol": 5920, - "aga": 5921, - "naneun": 5922, - "uneun": 5923, - "cheol": 5924, - "dol": 5925, - "bad": 5926, - "hamyeon": 5927, - "yeossda": 5928, - "ibnida": 5929, - "gye": 5930, - "eos": 5931, - "hwal": 5932, - "salamdeul": 5933, - "jiman": 5934, - "dangsin": 5935, - "jib": 5936, - "ttaemun": 5937, - "ib": 5938, - "eneun": 5939, - "eug": 5940, - "jeom": 5941, - "geuleon": 5942, - "hwa": 5943, - "assda": 5944, - "beob": 5945, - "bae": 5946, - "yeoss": 5947, - "chin": 5948, - "chaeg": 5949, - "geon": 5950, - "naega": 5951, - "iga": 5952, - "sigan": 5953, - "gil": 5954, - "hyeon": 5955, - "lyeog": 5956, - "gug": 5957, - "pyeon": 5958, - "wae": 5959, - "jul": 5960, - "seul": 5961, - "deung": 5962, - "hajiman": 5963, - "eumyeon": 5964, - "pil": 5965, - "nyeon": 5966, - "tae": 5967, - "pyo": 5968, - "jineun": 5969, - "beon": 5970, - "hada": 5971, - "seol": 5972, - "sip": 5973, - "daleun": 5974, - "salm": 5975, - "gyo": 5976, - "cheon": 5977, - "hagi": 5978, - "cheoleom": 5979, - "gal": 5980, - "ila": 5981, - "kkaji": 5982, - "anhneun": 5983, - "habnida": 5984, - "tteon": 5985, - "haeseo": 5986, - "doenda": 5987, - "ttal": 5988, - "ilo": 5989, - "seub": 5990, - "byeon": 5991, - "myeo": 5992, - "beol": 5993, - "jeung": 5994, - "chim": 5995, - "hwang": 5996, - "euneun": 5997, - "jong": 5998, - "boda": 5999, - "nol": 6000, - "neom": 6001, - "buteo": 6002, - "jigeum": 6003, - "eobsda": 6004, - "daelo": 6005, - "yul": 6006, - "pyeong": 6007, - "seoneun": 6008, - "salang": 6009, - "seut": 6010, - "heom": 6011, - "hyang": 6012, - "gwang": 6013, - "eobsneun": 6014, - "hwag": 6015, - "gess": 6016, - "jagi": 6017, - "ileon": 6018, - "wihae": 6019, - "daehan": 6020, - "gaji": 6021, - "meog": 6022, - "jyeo": 6023, - "chaj": 6024, - "byeong": 6025, - "eod": 6026, - "gyeo": 6027, - "eoji": 6028, - "gul": 6029, - "modeun": 6030, - "insaeng": 6031, - "geulae": 6032, - "sasil": 6033, - "sib": 6034, - "chal": 6035, - "ilago": 6036, - "geum": 6037, - "doeneun": 6038, - "bol": 6039, - "gajang": 6040, - "geuligo": 6041, - "hyeong": 6042, - "haengbog": 6043, - "chul": 6044, - "chae": 6045, - "mang": 6046, - "dam": 6047, - "choe": 6048, - "sijag": 6049, - "cheong": 6050, - "ilaneun": 6051, - "ulineun": 6052, - "aen": 6053, - "kke": 6054, - "munje": 6055, - "teu": 6056, - "geuneun": 6057, - "bge": 6058, - "cheo": 6059, - "baeg": 6060, - "jug": 6061, - "sangdae": 6062, - "geugeos": 6063, - "dog": 6064, - "eus": 6065, - "jab": 6066, - "hyeo": 6067, - "tteohge": 6068, - "chil": 6069, - "swi": 6070, - "jileul": 6071, - "chang": 6072, - "ganeun": 6073, - "iji": 6074, - "dago": 6075, - "yohan": 6076, - "teug": 6077, - "ppun": 6078, - "aleul": 6079, - "haengdong": 6080, - "sesang": 6081, - "edo": 6082, - "mandeul": 6083, - "amyeon": 6084, - "kkae": 6085, - "bag": 6086, - "ideul": 6087, - "pum": 6088, - "meol": 6089, - "neul": 6090, - "hamkke": 6091, - "chung": 6092, - "dab": 6093, - "yug": 6094, - "sag": 6095, - "gwangye": 6096, - "ileohge": 6097, - "balo": 6098, - "neunde": 6099, - "hamyeo": 6100, - "geuleoh": 6101, - "anila": 6102, - "bangbeob": 6103, - "dasi": 6104, - "byeol": 6105, - "gyeon": 6106, - "gamjeong": 6107, - "oneul": 6108, - "janeun": 6109, - "yeom": 6110, - "lago": 6111, - "igi": 6112, - "hwan": 6113, - "teul": 6114, - "eoseo": 6115, - "sik": 6116, - "jaga": 6117, - "geuleom": 6118, - "geuleona": 6119, - "jeongdo": 6120, - "gyeog": 6121, - "geuleohge": 6122, - "geudeul": 6123, - "eut": 6124, - "imyeon": 6125, - "jjae": 6126, - "keun": 6127, - "isang": 6128, - "malhaessda": 6129, - "euge": 6130, - "nop": 6131, - "ingan": 6132, - "bomyeon": 6133, - "taeg": 6134, - "dwi": 6135, - "saneun": 6136, - "wan": 6137, - "anhgo": 6138, - "nugu": 6139, - "sung": 6140, - "damyeon": 6141, - "adeul": 6142, - "peul": 6143, - "ttala": 6144, - "geosdo": 6145, - "aji": 6146, - "meon": 6147, - "eumyeo": 6148, - "dolog": 6149, - "neung": 6150, - "modu": 6151, - "[ko]": 6152, - "\u0014": 6153, - "\u0016": 6154, - "$": 6155, - "*": 6156, - "|": 6157, - "°": 6158, - "º": 6159, - "ँ": 6160, - "ं": 6161, - "ः": 6162, - "अ": 6163, - "आ": 6164, - "इ": 6165, - "ई": 6166, - "उ": 6167, - "ऊ": 6168, - "ऋ": 6169, - "ऎ": 6170, - "ए": 6171, - "ऐ": 6172, - "ऑ": 6173, - "ऒ": 6174, - "ओ": 6175, - "औ": 6176, - "क": 6177, - "ख": 6178, - "ग": 6179, - "घ": 6180, - "ङ": 6181, - "च": 6182, - "छ": 6183, - "ज": 6184, - "झ": 6185, - "ञ": 6186, - "ट": 6187, - "ठ": 6188, - "ड": 6189, - "ढ": 6190, - "ण": 6191, - "त": 6192, - "थ": 6193, - "द": 6194, - "ध": 6195, - "न": 6196, - "ऩ": 6197, - "प": 6198, - "फ": 6199, - "ब": 6200, - "भ": 6201, - "म": 6202, - "य": 6203, - "र": 6204, - "ऱ": 6205, - "ल": 6206, - "ळ": 6207, - "व": 6208, - "श": 6209, - "ष": 6210, - "स": 6211, - "ह": 6212, - "़": 6213, - "ा": 6214, - "ि": 6215, - "ी": 6216, - "ु": 6217, - "ू": 6218, - "ृ": 6219, - "ॄ": 6220, - "ॅ": 6221, - "ॆ": 6222, - "े": 6223, - "ै": 6224, - "ॉ": 6225, - "ॊ": 6226, - "ो": 6227, - "ौ": 6228, - "्": 6229, - "ॐ": 6230, - "ॖ": 6231, - "क़": 6232, - "ख़": 6233, - "ग़": 6234, - "ज़": 6235, - "ड़": 6236, - "ढ़": 6237, - "फ़": 6238, - "य़": 6239, - "ॠ": 6240, - "।": 6241, - "॥": 6242, - "०": 6243, - "१": 6244, - "२": 6245, - "३": 6246, - "४": 6247, - "५": 6248, - "६": 6249, - "७": 6250, - "८": 6251, - "९": 6252, - "॰": 6253, - "ॲ": 6254, - "​": 6255, - "‌": 6256, - "‍": 6257, - "‎": 6258, - "₹": 6259, - "के": 6260, - "है": 6261, - "ें": 6262, - "्र": 6263, - "ार": 6264, - "ने": 6265, - "या": 6266, - "में": 6267, - "से": 6268, - "की": 6269, - "का": 6270, - "ों": 6271, - "ता": 6272, - "कर": 6273, - "स्": 6274, - "कि": 6275, - "को": 6276, - "र्": 6277, - "ना": 6278, - "क्": 6279, - "ही": 6280, - "और": 6281, - "पर": 6282, - "ते": 6283, - "हो": 6284, - "प्र": 6285, - "ान": 6286, - "्य": 6287, - "ला": 6288, - "वा": 6289, - "ले": 6290, - "सा": 6291, - "हैं": 6292, - "लि": 6293, - "जा": 6294, - "हा": 6295, - "भी": 6296, - "वि": 6297, - "इस": 6298, - "ती": 6299, - "न्": 6300, - "रा": 6301, - "मा": 6302, - "दे": 6303, - "दि": 6304, - "बा": 6305, - "ति": 6306, - "था": 6307, - "नि": 6308, - "कार": 6309, - "एक": 6310, - "हीं": 6311, - "हु": 6312, - "ंग": 6313, - "ैं": 6314, - "नी": 6315, - "सी": 6316, - "अप": 6317, - "त्": 6318, - "नहीं": 6319, - "री": 6320, - "मे": 6321, - "मु": 6322, - "ित": 6323, - "तो": 6324, - "पा": 6325, - "ली": 6326, - "लिए": 6327, - "गा": 6328, - "ल्": 6329, - "रह": 6330, - "रे": 6331, - "क्ष": 6332, - "मैं": 6333, - "सम": 6334, - "उस": 6335, - "जि": 6336, - "त्र": 6337, - "मि": 6338, - "चा": 6339, - "ोग": 6340, - "सं": 6341, - "द्": 6342, - "सि": 6343, - "आप": 6344, - "तु": 6345, - "दा": 6346, - "कु": 6347, - "यों": 6348, - "वे": 6349, - "जी": 6350, - "्या": 6351, - "उन": 6352, - "िक": 6353, - "ये": 6354, - "भा": 6355, - "्ट": 6356, - "हम": 6357, - "स्ट": 6358, - "शा": 6359, - "ड़": 6360, - "ंद": 6361, - "खा": 6362, - "म्": 6363, - "श्": 6364, - "यह": 6365, - "सक": 6366, - "पू": 6367, - "किया": 6368, - "अपने": 6369, - "रू": 6370, - "सु": 6371, - "मी": 6372, - "हि": 6373, - "जो": 6374, - "थे": 6375, - "रि": 6376, - "दी": 6377, - "थी": 6378, - "गी": 6379, - "लोग": 6380, - "गया": 6381, - "तर": 6382, - "न्ह": 6383, - "च्": 6384, - "वार": 6385, - "बी": 6386, - "प्": 6387, - "दो": 6388, - "टी": 6389, - "शि": 6390, - "करने": 6391, - "गे": 6392, - "ैसे": 6393, - "इन": 6394, - "ंड": 6395, - "साथ": 6396, - "पु": 6397, - "बे": 6398, - "बार": 6399, - "वी": 6400, - "अन": 6401, - "हर": 6402, - "उन्ह": 6403, - "होता": 6404, - "जब": 6405, - "कुछ": 6406, - "मान": 6407, - "क्र": 6408, - "बि": 6409, - "पह": 6410, - "फि": 6411, - "सर": 6412, - "ारी": 6413, - "रो": 6414, - "दू": 6415, - "कहा": 6416, - "तक": 6417, - "शन": 6418, - "ब्": 6419, - "स्थ": 6420, - "वह": 6421, - "बाद": 6422, - "ओं": 6423, - "गु": 6424, - "ज्": 6425, - "्रे": 6426, - "गर": 6427, - "रहे": 6428, - "वर्": 6429, - "हू": 6430, - "ार्": 6431, - "पी": 6432, - "बहु": 6433, - "मुझ": 6434, - "्रा": 6435, - "दिया": 6436, - "सब": 6437, - "करते": 6438, - "अपनी": 6439, - "बहुत": 6440, - "कह": 6441, - "टे": 6442, - "हुए": 6443, - "किसी": 6444, - "रहा": 6445, - "ष्ट": 6446, - "ज़": 6447, - "बना": 6448, - "सो": 6449, - "डि": 6450, - "कोई": 6451, - "व्य": 6452, - "बात": 6453, - "रु": 6454, - "वो": 6455, - "मुझे": 6456, - "द्ध": 6457, - "चार": 6458, - "मेरे": 6459, - "वर": 6460, - "्री": 6461, - "जाता": 6462, - "नों": 6463, - "प्रा": 6464, - "देख": 6465, - "टा": 6466, - "क्या": 6467, - "अध": 6468, - "लग": 6469, - "लो": 6470, - "पि": 6471, - "यु": 6472, - "चे": 6473, - "जिस": 6474, - "ंत": 6475, - "ानी": 6476, - "पै": 6477, - "जन": 6478, - "ारे": 6479, - "ची": 6480, - "मिल": 6481, - "दु": 6482, - "देश": 6483, - "च्छ": 6484, - "ष्": 6485, - "सू": 6486, - "खे": 6487, - "चु": 6488, - "िया": 6489, - "लगा": 6490, - "बु": 6491, - "उनके": 6492, - "ज्ञ": 6493, - "क्षा": 6494, - "तरह": 6495, - "्यादा": 6496, - "वाले": 6497, - "पूर्": 6498, - "मैंने": 6499, - "काम": 6500, - "रूप": 6501, - "होती": 6502, - "उप": 6503, - "जान": 6504, - "प्रकार": 6505, - "भार": 6506, - "मन": 6507, - "हुआ": 6508, - "टर": 6509, - "हूँ": 6510, - "परि": 6511, - "पास": 6512, - "अनु": 6513, - "राज": 6514, - "लोगों": 6515, - "अब": 6516, - "समझ": 6517, - "डी": 6518, - "मौ": 6519, - "शु": 6520, - "चि": 6521, - "पे": 6522, - "कृ": 6523, - "सकते": 6524, - "मह": 6525, - "योग": 6526, - "दर्": 6527, - "उसे": 6528, - "ंध": 6529, - "डा": 6530, - "जाए": 6531, - "बो": 6532, - "ूल": 6533, - "मो": 6534, - "ोंने": 6535, - "ंस": 6536, - "तुम": 6537, - "पहले": 6538, - "बता": 6539, - "तथा": 6540, - "यो": 6541, - "गई": 6542, - "उत्": 6543, - "सकता": 6544, - "कम": 6545, - "ज्यादा": 6546, - "रख": 6547, - "समय": 6548, - "ारा": 6549, - "अगर": 6550, - "स्त": 6551, - "चल": 6552, - "फिर": 6553, - "वारा": 6554, - "करना": 6555, - "शी": 6556, - "गए": 6557, - "बन": 6558, - "ौर": 6559, - "होने": 6560, - "चाह": 6561, - "खु": 6562, - "हाँ": 6563, - "उन्हें": 6564, - "उन्होंने": 6565, - "छो": 6566, - "म्ह": 6567, - "प्रति": 6568, - "निक": 6569, - "वन": 6570, - "्यू": 6571, - "रही": 6572, - "तुम्ह": 6573, - "जैसे": 6574, - "ियों": 6575, - "क्यों": 6576, - "लों": 6577, - "फ़": 6578, - "ंत्र": 6579, - "होते": 6580, - "क्ति": 6581, - "त्य": 6582, - "कर्": 6583, - "कई": 6584, - "वं": 6585, - "किन": 6586, - "पो": 6587, - "कारण": 6588, - "ड़ी": 6589, - "भि": 6590, - "इसके": 6591, - "बर": 6592, - "उसके": 6593, - "द्वारा": 6594, - "शे": 6595, - "कॉ": 6596, - "दिन": 6597, - "न्न": 6598, - "ड़ा": 6599, - "स्व": 6600, - "निर्": 6601, - "मुख": 6602, - "लिया": 6603, - "टि": 6604, - "ज्ञान": 6605, - "क्त": 6606, - "द्र": 6607, - "ग्": 6608, - "क्स": 6609, - "मै": 6610, - "गो": 6611, - "जे": 6612, - "ट्र": 6613, - "मार": 6614, - "त्व": 6615, - "धार": 6616, - "भाव": 6617, - "करता": 6618, - "खि": 6619, - "कं": 6620, - "चाहि": 6621, - "यर": 6622, - "प्त": 6623, - "कों": 6624, - "ंच": 6625, - "जु": 6626, - "मत": 6627, - "अच्छ": 6628, - "हुई": 6629, - "कभी": 6630, - "लेकिन": 6631, - "भू": 6632, - "अपना": 6633, - "दूस": 6634, - "चाहिए": 6635, - "यू": 6636, - "घर": 6637, - "सबसे": 6638, - "मेरी": 6639, - "नाम": 6640, - "ढ़": 6641, - "ंट": 6642, - "ेंगे": 6643, - "बै": 6644, - "फा": 6645, - "एवं": 6646, - "यी": 6647, - "ग्र": 6648, - "क्षे": 6649, - "आज": 6650, - "आपको": 6651, - "भाग": 6652, - "ठा": 6653, - "कै": 6654, - "भारत": 6655, - "उनकी": 6656, - "पहु": 6657, - "सभी": 6658, - "धा": 6659, - "णा": 6660, - "सान": 6661, - "होगा": 6662, - "तब": 6663, - "संग": 6664, - "पर्": 6665, - "अव": 6666, - "तना": 6667, - "गि": 6668, - "यन": 6669, - "स्था": 6670, - "चित": 6671, - "ट्": 6672, - "छा": 6673, - "जाने": 6674, - "क्षेत्र": 6675, - "वाली": 6676, - "पूर्ण": 6677, - "समा": 6678, - "कारी": 6679, - "[hi]": 6680 - }, - "merges": [ - "t h", - "i n", - "th e", - "a n", - "e r", - "o u", - "r e", - "o n", - "a t", - "e d", - "e n", - "t o", - "in g", - "an d", - "i s", - "a s", - "a l", - "o r", - "o f", - "a r", - "i t", - "e s", - "h e", - "s t", - "l e", - "o m", - "s e", - "b e", - "a d", - "o w", - "l y", - "c h", - "w h", - "th at", - "y ou", - "l i", - "v e", - "a c", - "t i", - "l d", - "m e", - "w as", - "g h", - "i d", - "l l", - "w i", - "en t", - "f or", - "a y", - "r o", - "v er", - "i c", - "h er", - "k e", - "h is", - "n o", - "u t", - "u n", - "i r", - "l o", - "w e", - "r i", - "h a", - "wi th", - "gh t", - "ou t", - "i m", - "i on", - "al l", - "a b", - "on e", - "n e", - "g e", - "ou ld", - "t er", - "m o", - "h ad", - "c e", - "s he", - "g o", - "s h", - "u r", - "a m", - "s o", - "p e", - "m y", - "d e", - "a re", - "b ut", - "om e", - "f r", - "the r", - "f e", - "s u", - "d o", - "c on", - "t e", - "a in", - "er e", - "p o", - "i f", - "the y", - "u s", - "a g", - "t r", - "n ow", - "ou n", - "th is", - "ha ve", - "no t", - "s a", - "i l", - "u p", - "th ing", - "fr om", - "a p", - "h im", - "ac k", - "at ion", - "an t", - "ou r", - "o p", - "li ke", - "u st", - "es s", - "b o", - "o k", - "u l", - "in d", - "e x", - "c om", - "s ome", - "the re", - "er s", - "c o", - "re s", - "m an", - "ar d", - "p l", - "w or", - "w ay", - "ti on", - "f o", - "c a", - "w ere", - "b y", - "at e", - "p ro", - "t ed", - "oun d", - "ow n", - "w ould", - "t s", - "wh at", - "q u", - "al ly", - "i ght", - "c k", - "g r", - "wh en", - "v en", - "c an", - "ou gh", - "in e", - "en d", - "p er", - "ou s", - "o d", - "id e", - "k now", - "t y", - "ver y", - "s i", - "a k", - "wh o", - "ab out", - "i ll", - "the m", - "es t", - "re d", - "y e", - "c ould", - "on g", - "you r", - "the ir", - "e m", - "j ust", - "o ther", - "in to", - "an y", - "wh i", - "u m", - "t w", - "as t", - "d er", - "d id", - "i e", - "be en", - "ac e", - "in k", - "it y", - "b ack", - "t ing", - "b r", - "mo re", - "a ke", - "p p", - "the n", - "s p", - "e l", - "u se", - "b l", - "sa id", - "o ver", - "ge t", - "e n", - "e r", - "c h", - "e i", - "i e", - "u n", - "i ch", - "ei n", - "s t", - "a n", - "t e", - "g e", - "a u", - "i n", - "s ch", - "d er", - "un d", - "d ie", - "d a", - "e s", - "a l", - "d en", - "a r", - "g en", - "z u", - "d e", - "h r", - "o n", - "t en", - "e l", - "o r", - "m i", - "s ie", - "da s", - "a t", - "b e", - "ein e", - "ich t", - "b er", - "l e", - "a ch", - "v er", - "s e", - "au f", - "w i", - "s o", - "t er", - "l ich", - "c k", - "u r", - "n icht", - "m m", - "b en", - "a s", - "w ar", - "r e", - "mi t", - "s ich", - "i g", - "l l", - "au s", - "i st", - "w ie", - "o ch", - "un g", - "an n", - "ü r", - "h n", - "i hr", - "s a", - "s en", - "t z", - "de m", - "ei t", - "u m", - "h at", - "wi r", - "v on", - "h a", - "s p", - "w ei", - "i er", - "r o", - "h er", - "r a", - "ein en", - "n e", - "v or", - "al s", - "an d", - "al l", - "w as", - "w o", - "r ei", - "st e", - "l ie", - "au ch", - "d u", - "d es", - "k o", - "ü ber", - "a m", - "b ei", - "h en", - "h m", - "l ei", - "a ber", - "w en", - "h l", - "g er", - "i m", - "u t", - "n ach", - "h e", - "i s", - "b r", - "f t", - "en t", - "i mm", - "j e", - "sch en", - "w er", - "s er", - "a b", - "ä n", - "m e", - "s ein", - "i t", - "o l", - "ch t", - "f ür", - "k l", - "f f", - "eine m", - "n en", - "w e", - "j a", - "u s", - "n och", - "hat te", - "t r", - "p f", - "h in", - "d i", - "ch en", - "b l", - "m an", - "r ü", - "ie l", - "s el", - "das s", - "i hn", - "mi r", - "sch l", - "ö n", - "g an", - "g t", - "ein er", - "st en", - "m ich", - "wen n", - "el l", - "g te", - "in d", - "m al", - "ge l", - "k en", - "n ur", - "mm en", - "f ü", - "er n", - "ö r", - "un ter", - "f r", - "an der", - "g r", - "i l", - "d ur", - "u ch", - "f e", - "t a", - "m en", - "m ach", - "d och", - "t i", - "dur ch", - "o s", - "g l", - "h al", - "ihr e", - "w ä", - "imm er", - "i hm", - "k ann", - "or t", - "d ann", - "l an", - "tz t", - "o der", - "hr en", - "e t", - "k ön", - "i ck", - "f a", - "in g", - "i r", - "wie der", - "da ß", - "m ein", - "f en", - "gan z", - "die se", - "st er", - "da r", - "w a", - "ge s", - "n a", - "f l", - "i gen", - "sch e", - "un gen", - "me hr", - "ß en", - "o t", - "k on", - "ge w", - "ha ben", - "ge h", - "ä t", - "s ind", - "d r", - "w el", - "un s", - "v o", - "m a", - "u te", - "sch on", - "b es", - "ge sch", - "b t", - "ch e", - "s on", - "o b", - "l a", - "p p", - "rü ck", - "s eine", - "k r", - "f re", - "ei l", - "zu m", - "u l", - "h ier", - "k t", - "i ge", - "sp r", - "k e", - "le ben", - "b st", - "z eit", - "i on", - "g ro", - "den n", - "h o", - "sch a", - "b ar", - "al le", - "ge gen", - "w ür", - "m ü", - "z e", - "wer den", - "je tzt", - "ko mmen", - "n ie", - "s ei", - "h eit", - "so ll", - "g lei", - "m eine", - "wo ll", - "n er", - "ha be", - "w ur", - "lich en", - "p er", - "as sen", - "n te", - "se hen", - "wir d", - "b is", - "g ar", - "i en", - "m us", - "u ß", - "ä r", - "st ell", - "k eit", - "z wei", - "sel bst", - "st a", - "p a", - "sa gte", - "te t", - "k am", - "s sen", - "v iel", - "u g", - "z en", - "h ei", - "m ann", - "wi ll", - "ge b", - "war en", - "ü ck", - "ä ch", - "m er", - "r u", - "w or", - "h au", - "ei gen", - "an g", - "we g", - "bl ick", - "f ra", - "all es", - "k a", - "au gen", - "f in", - "lich e", - "t o", - "un ser", - "der n", - "her r", - "n un", - "v ie", - "ch te", - "wo hl", - "f all", - "h t", - "ü n", - "et was", - "st and", - "en d", - "ä u", - "e m", - "m ö", - "te l", - "r ie", - "d ich", - "die s", - "h and", - "b in", - "ff en", - "nicht s", - "d an", - "p l", - "hn e", - "ihn en", - "es en", - "die ser", - "fr au", - "an t", - "ar t", - "di r", - "i sch", - "er st", - "glei ch", - "ko mm", - "h ör", - "ß e", - "d ig", - "se hr", - "z ei", - "sa m", - "au m", - "h ät", - "in gen", - "g ut", - "b o", - "m ut", - "ck en", - "kon nte", - "st imm", - "p ro", - "zu r", - "i tz", - "wei l", - "wür de", - "f ä", - "kön nen", - "k eine", - "f er", - "i schen", - "vo ll", - "ein es", - "se tz", - "z ie", - "de l", - "te te", - "sein er", - "ier en", - "ge st", - "zu rück", - "wur de", - "sch n", - "p r", - "lie ß", - "t ra", - "m ä", - "gen d", - "f ol", - "i k", - "schl a", - "scha ft", - "at er", - "wei ß", - "s einen", - "l assen", - "l u", - "und en", - "t eil", - "ne u", - "ier t", - "men schen", - "hm en", - "st r", - "g i", - "sa h", - "ihr en", - "el n", - "wei ter", - "ge hen", - "ig er", - "mach t", - "ta g", - "al so", - "hal ten", - "n is", - "ach t", - "ge ben", - "f or", - "o g", - "n at", - "m ar", - "de t", - "o hne", - "h aus", - "t ro", - "an ge", - "l au", - "sp iel", - "t re", - "sch r", - "in n", - "s u", - "l os", - "mach en", - "hät te", - "be g", - "wir k", - "al t", - "g lich", - "te s", - "r icht", - "fre und", - "m o", - "ihr er", - "f el", - "b el", - "so l", - "ein mal", - "e ben", - "h ol", - "h än", - "q u", - "ter n", - "h ö", - "sch w", - "re cht", - "wa hr", - "s einem", - "ste hen", - "hl en", - "in s", - "g ing", - "woll te", - "wi ssen", - "ung s", - "al d", - "as s", - "ja hr", - "m or", - "wel t", - "un der", - "zu sa", - "at ion", - "ko pf", - "lan g", - "hin ter", - "at z", - "st ra", - "an gen", - "an k", - "a de", - "gl au", - "f ach", - "hat ten", - "l o", - "f ort", - "ei cht", - "i ff", - "l er", - "m ei", - "diese m", - "k ein", - "f rei", - "fü hr", - "vo m", - "e s", - "e n", - "a i", - "o u", - "o n", - "l e", - "d e", - "r e", - "q u", - "a n", - "e r", - "en t", - "e t", - "l a", - "n e", - "i l", - "a r", - "i s", - "ai t", - "t e", - "a u", - "i n", - "qu e", - "i t", - "u r", - "s e", - "l es", - "c h", - "c e", - "m e", - "o r", - "ou r", - "a s", - "p r", - "a v", - "o m", - "ai s", - "u n", - "an t", - "ou s", - "t r", - "t i", - "l u", - "o i", - "e u", - "l le", - "s i", - "p ar", - "d es", - "an s", - "m ent", - "é t", - "es t", - "j e", - "u ne", - "a l", - "p as", - "t re", - "qu i", - "d u", - "r i", - "c on", - "s on", - "c om", - "e lle", - "d é", - "p our", - "d ans", - "l i", - "s a", - "r é", - "t ou", - "v ous", - "d i", - "v i", - "a g", - "a m", - "a t", - "ou v", - "a p", - "ti on", - "m on", - "s ur", - "c i", - "o s", - "p lu", - "s u", - "en d", - "a b", - "è re", - "ai n", - "m ais", - "o is", - "r es", - "plu s", - "é e", - "ai ent", - "m p", - "ch e", - "lu i", - "av e", - "ét ait", - "m a", - "s es", - "tou t", - "i r", - "v o", - "a c", - "s er", - "an d", - "f f", - "oi r", - "g r", - "av ait", - "é s", - "m es", - "n ous", - "eu x", - "b i", - "t er", - "c o", - "on s", - "p u", - "c es", - "g e", - "t u", - "le ur", - "pr o", - "d on", - "e ur", - "et te", - "ai re", - "ave c", - "d it", - "t é", - "i e", - "u s", - "il le", - "p er", - "com me", - "c r", - "or t", - "m i", - "e x", - "u x", - "v er", - "m o", - "è s", - "v e", - "au x", - "r a", - "j our", - "il s", - "bi en", - "c ou", - "p e", - "que l", - "p eu", - "c ette", - "t es", - "p o", - "in s", - "c u", - "m ê", - "s o", - "f ait", - "g u", - "m ar", - "ê tre", - "l o", - "it é", - "f r", - "a tion", - "en s", - "b r", - "n i", - "l é", - "d is", - "b le", - "m an", - "n é", - "pu is", - "mê me", - "qu es", - "f i", - "e l", - "ag e", - "g ar", - "m oi", - "en ce", - "on t", - "m ain", - "or s", - "au t", - "an ce", - "v en", - "m é", - "s ans", - "e m", - "s é", - "l on", - "h om", - "r o", - "u t", - "c ar", - "ab le", - "i m", - "de r", - "ch er", - "n o", - "vi e", - "au s", - "b e", - "de ux", - "en f", - "o ù", - "t en", - "p h", - "u re", - "te mp", - "p os", - "r ent", - "p é", - "f aire", - "p i", - "tr es", - "ç a", - "an g", - "end re", - "f or", - "p a", - "b on", - "s ou", - "in t", - "pr é", - "s ent", - "t ant", - "n er", - "c er", - "l à", - "l ais", - "pr ès", - "b re", - "c our", - "p et", - "i on", - "i ne", - "com p", - "l ait", - "tr ouv", - "t a", - "ent re", - "son t", - "de v", - "n u", - "temp s", - "d ou", - "r ait", - "b ou", - "qu and", - "jour s", - "l an", - "er s", - "av oir", - "ét é", - "a le", - "p re", - "f ois", - "or te", - "v é", - "m er", - "n on", - "t ous", - "j us", - "cou p", - "t s", - "hom me", - "ê te", - "a d", - "aus si", - "ur s", - "se u", - "or d", - "o b", - "m in", - "g é", - "co re", - "v a", - "v re", - "en core", - "se m", - "i te", - "au tre", - "pr is", - "peu t", - "u e", - "an te", - "m al", - "g n", - "ré p", - "h u", - "si on", - "vo tre", - "di re", - "e z", - "f em", - "leur s", - "m et", - "f in", - "c ri", - "m is", - "t our", - "r ai", - "j am", - "re gar", - "ri en", - "ver s", - "su is", - "p ouv", - "o p", - "v is", - "gr and", - "ant s", - "c or", - "re r", - "ar d", - "c é", - "t ent", - "pr es", - "v ou", - "f a", - "al ors", - "si eur", - "ai ne", - "le r", - "qu oi", - "f on", - "end ant", - "ar ri", - "eu re", - "a près", - "don c", - "it u", - "l è", - "s ait", - "t oi", - "ch a", - "ai l", - "as se", - "i mp", - "vo y", - "con n", - "p la", - "pet it", - "av ant", - "n om", - "t in", - "don t", - "d a", - "s ous", - "e mp", - "per son", - "el les", - "be au", - "par ti", - "ch o", - "pr it", - "tou jours", - "m en", - "r ais", - "jam ais", - "tr av", - "tion s", - "tr ès", - "v oi", - "r en", - "y eux", - "f er", - "v oir", - "pre mi", - "c a", - "g ne", - "h eure", - "r ou", - "e ff", - "no tre", - "ment s", - "t on", - "f ais", - "ce la", - "i er", - "rép on", - "con s", - "ai r", - "ô t", - "p endant", - "i ci", - "tou te", - "j et", - "p ort", - "ét aient", - "p en", - "h é", - "au tres", - "p ère", - "o c", - "quel ques", - "i que", - "l is", - "fem me", - "j ou", - "te ur", - "mon de", - "u se", - "n es", - "d re", - "a ff", - "r ap", - "par t", - "le ment", - "c la", - "f ut", - "quel que", - "pr endre", - "r ê", - "ai lle", - "s ais", - "ch es", - "le t", - "ch ar", - "è res", - "ent s", - "b er", - "g er", - "mo ins", - "e au", - "a î", - "j eu", - "h eur", - "é es", - "tr i", - "po int", - "m om", - "v ent", - "n ouv", - "gr an", - "tr ois", - "s ant", - "tout es", - "con tre", - "è rent", - "che z", - "ave z", - "û t", - "a lle", - "at t", - "p au", - "p orte", - "ouv er", - "b ar", - "l it", - "f ort", - "o t", - "as s", - "pr és", - "cho se", - "v it", - "mon sieur", - "h ab", - "t ête", - "j u", - "te ment", - "c tion", - "v rai", - "la r", - "c et", - "regar d", - "l ant", - "de m", - "s om", - "mom ent", - "il les", - "p le", - "p s", - "b es", - "m ère", - "c l", - "s our", - "y s", - "tr op", - "en ne", - "jus qu", - "av aient", - "av ais", - "jeu ne", - "de puis", - "person ne", - "f it", - "cer t", - "j o", - "g es", - "ou i", - "r est", - "sem b", - "c ap", - "m at", - "m u", - "lon g", - "fr an", - "f aut", - "it i", - "b li", - "che v", - "pr i", - "ent e", - "ain si", - "ch am", - "l ors", - "c as", - "d o", - "il i", - "b é", - "n os", - "an ge", - "su i", - "r it", - "cr o", - "gu e", - "d e", - "e n", - "e s", - "o s", - "l a", - "e r", - "q u", - "a r", - "a n", - "o n", - "qu e", - "a s", - "o r", - "e l", - "d o", - "a l", - "c i", - "u n", - "r e", - "a b", - "i n", - "t e", - "t o", - "s e", - "d i", - "t r", - "d a", - "c on", - "t a", - "s u", - "m i", - "c o", - "t i", - "l e", - "l os", - "n o", - "l o", - "í a", - "c u", - "c a", - "s i", - "v i", - "m e", - "p or", - "m o", - "p ar", - "r a", - "r i", - "la s", - "c h", - "r o", - "m a", - "p er", - "ó n", - "m en", - "de s", - "un a", - "m p", - "s o", - "ab a", - "p u", - "d os", - "t u", - "g u", - "er a", - "de l", - "h a", - "m u", - "l i", - "en t", - "m b", - "h ab", - "es t", - "g o", - "p a", - "r es", - "par a", - "p o", - "á s", - "m os", - "tr a", - "t en", - "an do", - "p i", - "qu i", - "b i", - "m an", - "co mo", - "v e", - "m ás", - "j o", - "ci ón", - "i s", - "t an", - "v o", - "da d", - "c e", - "a do", - "v er", - "f u", - "ci a", - "c er", - "p e", - "c as", - "c ar", - "men te", - "n i", - "su s", - "t ar", - "n a", - "f i", - "t er", - "z a", - "p ro", - "tr o", - "s a", - "l u", - "b a", - "per o", - "s er", - "c es", - "d as", - "d u", - "s in", - "e mp", - "m ar", - "l la", - "e x", - "á n", - "c or", - "i a", - "v a", - "r an", - "ch o", - "g a", - "y o", - "t os", - "c os", - "mi s", - "l es", - "t es", - "v en", - "h o", - "y a", - "en te", - "on es", - "hab ía", - "n u", - "u s", - "p as", - "h i", - "n os", - "es ta", - "la n", - "m as", - "t or", - "l le", - "h e", - "s on", - "b re", - "p re", - "ab an", - "d or", - "í an", - "i r", - "t as", - "é n", - "r u", - "en do", - "a que", - "er o", - "i o", - "qu é", - "m in", - "c ab", - "j a", - "de r", - "t al", - "é s", - "se ñ", - "or a", - "to do", - "la r", - "d on", - "g ar", - "s al", - "p r", - "cu ando", - "j e", - "h u", - "g un", - "b u", - "g i", - "d ar", - "n e", - "r as", - "de n", - "es to", - "par e", - "p en", - "é l", - "tr as", - "c an", - "b o", - "j os", - "mi en", - "pu e", - "c re", - "co mp", - "p on", - "d ía", - "tr os", - "s ab", - "so bre", - "es e", - "mb re", - "er on", - "a ñ", - "m or", - "f or", - "i do", - "por que", - "el la", - "p ri", - "g ran", - "f a", - "c en", - "di s", - "c ri", - "mu y", - "ch a", - "c al", - "es te", - "h as", - "c ó", - "g ra", - "r os", - "p os", - "o b", - "al l", - "aque l", - "j u", - "p res", - "m er", - "di jo", - "c ía", - "ent re", - "z o", - "ci ones", - "bi en", - "mb i", - "el o", - "t ó", - "in a", - "to dos", - "g en", - "ti en", - "est aba", - "de ci", - "ci o", - "h er", - "ñ o", - "l or", - "nu es", - "me di", - "l en", - "vi da", - "f e", - "al i", - "m on", - "c la", - "d re", - "pu es", - "al es", - "vo l", - "m í", - "r ar", - "b le", - "ci on", - "has ta", - "señ or", - "con o", - "a h", - "di os", - "s en", - "es a", - "ú n", - "v ar", - "s an", - "gu i", - "a c", - "o tros", - "ta do", - "bu en", - "ñ a", - "ti emp", - "ha cer", - "j er", - "f er", - "v u", - "f in", - "an a", - "as í", - "an tes", - "t in", - "ve z", - "mien to", - "j ar", - "la b", - "ch e", - "cas a", - "d r", - "es o", - "e go", - "di ó", - "an te", - "est á", - "m al", - "en cia", - "el i", - "í as", - "tiemp o", - "z ar", - "v an", - "m un", - "er ta", - "ta mbi", - "s í", - "b ar", - "a un", - "al e", - "mis mo", - "ent es", - "vi s", - "man o", - "el e", - "na da", - "se gu", - "me j", - "er ra", - "ab le", - "b e", - "ti r", - "un o", - "don de", - "to da", - "des de", - "r en", - "tambi én", - "cu er", - "per son", - "ho mbre", - "o tro", - "li b", - "tr ar", - "cu al", - "ha y", - "a u", - "ca da", - "t aba", - "i mp", - "men to", - "ten ía", - "qu er", - "er an", - "si emp", - "siemp re", - "er to", - "qu í", - "g os", - "pu és", - "el los", - "des pués", - "nu e", - "g an", - "l lo", - "in ter", - "có mo", - "tr i", - "ah ora", - "us te", - "tr aba", - "la do", - "in o", - "po co", - "er te", - "mu jer", - "i m", - "qui er", - "al gun", - "fu e", - "o jos", - "ent on", - "v os", - "es per", - "mu ch", - "o tra", - "a z", - "a d", - "in g", - "e za", - "a quí", - "ci as", - "gu a", - "mu cho", - "deci r", - "es ti", - "i dad", - "al go", - "e z", - "o cu", - "enton ces", - "di do", - "ent os", - "g ri", - "da do", - "i os", - "so l", - "dos e", - "uste d", - "qui en", - "a mi", - "un to", - "f r", - "mi r", - "mej or", - "b as", - "so lo", - "pre gun", - "tu r", - "al g", - "p la", - "to das", - "par te", - "e mb", - "c to", - "mun do", - "tien e", - "tan te", - "pa lab", - "tr an", - "aque lla", - "ci os", - "aun que", - "a y", - "cu en", - "ten er", - "f un", - "res pon", - "all í", - "x i", - "h an", - "pen s", - "con tra", - "tu ra", - "v al", - "di o", - "tr es", - "t re", - "tan to", - "ca min", - "m ó", - "es p", - "a da", - "í o", - "in s", - "ha cia", - "de j", - "est ar", - "i ón", - "g as", - "b er", - "v as", - "no che", - "é r", - "añ os", - "pa dre", - "gu s", - "á r", - "sin o", - "man os", - "ci do", - "es tu", - "a de", - "hu bi", - "vi r", - "b ri", - "ra z", - "ch i", - "pue de", - "men os", - "hab i", - "ho mb", - "ne ces", - "ma y", - "er os", - "r ía", - "he cho", - "es cu", - "l ti", - "án do", - "b us", - "cos as", - "t ú", - "es pa", - "re ci", - "c tor", - "pri m", - "di a", - "de se", - "mien tras", - "h or", - "fu er", - "i da", - "pos i", - "lan te", - "t on", - "an o", - "est as", - "p li", - "ch ar", - "lu ego", - "si ón", - "ci n", - "ti erra", - "m es", - "gu ar", - "ca do", - "en con", - "pr en", - "may or", - "f al", - "e r", - "o n", - "a n", - "t o", - "d i", - "r e", - "l a", - "i n", - "e n", - "a l", - "t a", - "c h", - "e l", - "r i", - "c o", - "t i", - "t e", - "s i", - "r a", - "u n", - "l e", - "l i", - "ch e", - "r o", - "c i", - "c a", - "s e", - "q u", - "m a", - "p o", - "s o", - "i l", - "d o", - "e s", - "v a", - "p er", - "l o", - "c on", - "d el", - "p a", - "m o", - "s a", - "p i", - "d a", - "m i", - "g i", - "s u", - "d e", - "v i", - "z i", - "m e", - "g li", - "n o", - "m en", - "v o", - "t u", - "n on", - "v e", - "t to", - "s t", - "on e", - "an o", - "ch i", - "er a", - "er e", - "f a", - "c e", - "z a", - "un a", - "b i", - "p re", - "s ta", - "o r", - "a r", - "f i", - "on o", - "t ra", - "n a", - "n el", - "n e", - "p ro", - "t ro", - "al e", - "v er", - "n i", - "c u", - "t ti", - "men te", - "del la", - "t er", - "zi one", - "g u", - "p e", - "t ta", - "an do", - "t à", - "al i", - "u o", - "qu el", - "co m", - "s en", - "co me", - "b a", - "al la", - "p ri", - "d u", - "qu es", - "l u", - "on i", - "g gi", - "pa r", - "s si", - "v en", - "in a", - "g a", - "pi ù", - "ci a", - "i m", - "co r", - "m an", - "in o", - "in i", - "t en", - "r an", - "b b", - "g o", - "s to", - "t re", - "a ve", - "a v", - "s ono", - "er i", - "a c", - "s se", - "er o", - "h a", - "s c", - "su l", - "f or", - "v ano", - "po r", - "s ti", - "su o", - "c chi", - "t an", - "z za", - "an che", - "p u", - "i o", - "t te", - "vo l", - "es s", - "s ci", - "co l", - "r u", - "p en", - "f u", - "al l", - "s so", - "s te", - "se m", - "s sa", - "d en", - "a d", - "t ri", - "de i", - "in e", - "ave va", - "men to", - "z z", - "a mo", - "g no", - "f o", - "un o", - "su a", - "g en", - "ri a", - "g e", - "st ra", - "s ì", - "c er", - "ch é", - "b u", - "a p", - "c en", - "d al", - "on a", - "s pe", - "g ni", - "b o", - "t t", - "del le", - "ques to", - "nel la", - "f f", - "d ere", - "an no", - "del l", - "un i", - "bb e", - "an ti", - "g ra", - "s p", - "en e", - "gi o", - "u to", - "qu al", - "gli a", - "qu ando", - "tu tto", - "c an", - "gli o", - "zi oni", - "ca m", - "h o", - "es so", - "s s", - "mo l", - "a t", - "lo ro", - "per ché", - "co sa", - "du e", - "po i", - "ca r", - "s co", - "ci o", - "to r", - "c co", - "c re", - "a m", - "g na", - "te m", - "pri ma", - "lu i", - "co sì", - "qu e", - "gu ar", - "ess ere", - "an i", - "con o", - "b ra", - "al le", - "m on", - "ri o", - "an co", - "cu i", - "s pi", - "vi a", - "g ran", - "gi or", - "a i", - "bi le", - "u l", - "ggi o", - "f e", - "an te", - "ma i", - "ta re", - "in ter", - "in di", - "re bbe", - "sen za", - "so lo", - "zi o", - "e d", - "en te", - "tu tti", - "sta to", - "zi a", - "d alla", - "tu ra", - "mi a", - "vi ta", - "quel la", - "qu a", - "ma r", - "do ve", - "g h", - "al lo", - "sem pre", - "zz o", - "si a", - "mo r", - "do po", - "por ta", - "d re", - "c cia", - "er ano", - "an ni", - "di o", - "chi a", - "en za", - "pro pri", - "qu i", - "m u", - "m b", - "an da", - "c ca", - "o cchi", - "ques ta", - "f fi", - "le i", - "par te", - "d on", - "r on", - "mi o", - "tan to", - "ri s", - "o gni", - "di s", - "r in", - "fa r", - "men ti", - "t el", - "anco ra", - "f ra", - "fa tto", - "man i", - "sen ti", - "p ra", - "tem po", - "es si", - "b bi", - "f in", - "a re", - "la re", - "per s", - "f on", - "b el", - "so r", - "d er", - "pre n", - "an za", - "di re", - "pi e", - "o ra", - "ver so", - "se gu", - "al tro", - "ta to", - "ca to", - "a to", - "vol ta", - "c c", - "fa re", - "pa re", - "ci ò", - "li b", - "bi li", - "n uo", - "s er", - "quel lo", - "co lo", - "p po", - "ca sa", - "tro va", - "o re", - "f er", - "r ono", - "d es", - "mol to", - "al mente", - "s ca", - "vo le", - "t ali", - "sul la", - "s ce", - "men o", - "an to", - "p un", - "s tu", - "ca pi", - "so l", - "gi u", - "m ini", - "m ano", - "z e", - "pi a", - "par ti", - "s al", - "la vo", - "ver o", - "r si", - "al tri", - "es ti", - "s cia", - "suo i", - "gli e", - "so tto", - "b ene", - "sc ri", - "t ale", - "de gli", - "n u", - "al c", - "uo mo", - "p el", - "f re", - "po te", - "es sa", - "s cu", - "si gno", - "el e", - "st ro", - "u ti", - "di a", - "si one", - "g re", - "f ini", - "ar ri", - "l un", - "c ri", - "e si", - "pa ssa", - "r à", - "men tre", - "an d", - "h anno", - "el o", - "u sci", - "gi a", - "gi à", - "di e", - "m ina", - "b e", - "ti ca", - "gior no", - "t in", - "es se", - "mo do", - "c al", - "s pa", - "propri o", - "l en", - "o ri", - "con tro", - "st ru", - "di ven", - "di sse", - "ra to", - "no i", - "v ere", - "pu ò", - "di ce", - "s an", - "es a", - "c ci", - "se con", - "re n", - "c cio", - "qual che", - "tu tta", - "g g", - "mon do", - "for ma", - "p li", - "m ma", - "pen sa", - "de va", - "tu r", - "fo sse", - "so pra", - "ta mente", - "n ess", - "qu anto", - "ra ga", - "un que", - "ca re", - "st re", - "gran de", - "pi cco", - "guar da", - "b en", - "nel l", - "a ff", - "po ssi", - "pre sen", - "r ò", - "pa ro", - "tu a", - "v in", - "an e", - "a s", - "ste sso", - "da v", - "ne i", - "nel le", - "gh i", - "pi o", - "ta r", - "an a", - "la to", - "si d", - "f ine", - "f uo", - "m er", - "z o", - "qua si", - "ul ti", - "i to", - "su e", - "si e", - "f il", - "allo ra", - "m in", - "ven i", - "t ano", - "el lo", - "d e", - "r a", - "e s", - "d o", - "e n", - "q u", - "c o", - "a s", - "o s", - "e r", - "a r", - "s e", - "qu e", - "a n", - "i n", - "i s", - "t o", - "ã o", - "t e", - "d a", - "m a", - "e l", - "t a", - "o r", - "i a", - "r e", - "e m", - "a l", - "co m", - "p a", - "o u", - "c a", - "u m", - "r o", - "v a", - "t i", - "s o", - "m en", - "n ão", - "h a", - "co n", - "m e", - "r i", - "pa ra", - "p o", - "d i", - "s a", - "v o", - "u ma", - "c i", - "n a", - "p or", - "n o", - "g u", - "s u", - "h o", - "an do", - "t ra", - "e i", - "v i", - "e u", - "i m", - "do s", - "el e", - "r es", - "m o", - "en t", - "f i", - "l a", - "e ra", - "l e", - "de s", - "el a", - "men te", - "l h", - "p er", - "l i", - "ç ão", - "m as", - "t er", - "m u", - "es t", - "v e", - "g o", - "l o", - "u s", - "ma is", - "v er", - "c ê", - "in ha", - "vo cê", - "f a", - "t u", - "c u", - "p ar", - "com o", - "p ro", - "s i", - "m os", - "e c", - "p re", - "d as", - "ç a", - "es ta", - "s er", - "u n", - "da de", - "d is", - "f o", - "e x", - "c h", - "i r", - "ra n", - "t ar", - "en te", - "g a", - "t r", - "p e", - "t os", - "b o", - "c ia", - "p en", - "c ar", - "s en", - "su a", - "se m", - "c as", - "f or", - "to u", - "n os", - "te m", - "r ia", - "m es", - "se u", - "co r", - "o n", - "a o", - "p os", - "ra m", - "v el", - "é m", - "t en", - "po de", - "t es", - "esta va", - "c e", - "b a", - "qu ando", - "m i", - "qu er", - "men to", - "se gu", - "t as", - "is so", - "mu i", - "g ar", - "t ro", - "d u", - "fa z", - "õ es", - "p es", - "an to", - "l u", - "p i", - "i x", - "ve z", - "s im", - "j a", - "p r", - "m in", - "b e", - "ra s", - "m an", - "p res", - "est á", - "c er", - "b re", - "p as", - "d ia", - "m b", - "dis se", - "n i", - "r os", - "es se", - "v ia", - "o lh", - "is a", - "an te", - "ê n", - "z a", - "qu i", - "b i", - "t inha", - "me u", - "s ão", - "m inha", - "a c", - "ri o", - "m ar", - "a t", - "p el", - "mui to", - "ta l", - "to r", - "fo i", - "h or", - "j o", - "b em", - "g i", - "f al", - "vo l", - "po n", - "di z", - "l ar", - "gu n", - "m or", - "r u", - "par ec", - "ç o", - "do r", - "pes so", - "n e", - "f er", - "b er", - "p u", - "po is", - "in a", - "es p", - "d ar", - "en do", - "de n", - "so bre", - "co s", - "p ri", - "al i", - "mes mo", - "ç ões", - "g ra", - "se us", - "me i", - "b ra", - "vi da", - "an tes", - "b ri", - "at é", - "ên cia", - "lh e", - "ti v", - "m ã", - "al g", - "qu anto", - "s ó", - "g os", - "de r", - "t ão", - "tu do", - "ent ão", - "r ou", - "es s", - "in da", - "b al", - "in do", - "ci o", - "n do", - "j á", - "va m", - "re i", - "l es", - "ei to", - "v is", - "tem po", - "de pois", - "c ha", - "m el", - "ch e", - "l ha", - "a inda", - "faz er", - "con tra", - "p ou", - "per gun", - "de ix", - "ta mb", - "ra r", - "al a", - "v en", - "t in", - "pel o", - "tamb ém", - "fi ca", - "pre c", - "el es", - "tra n", - "ha via", - "l á", - "to dos", - "j u", - "qu al", - "c an", - "ta do", - "cas a", - "es sa", - "n as", - "g em", - "m em", - "se i", - "na da", - "sen ti", - "c ri", - "ó s", - "de u", - "ei ro", - ". .", - "f un", - "as sim", - "s ou", - "ent re", - "com e", - "i or", - "h ar", - "f e", - "por que", - "s or", - "f in", - "ta mente", - "a qui", - "cu l", - "t ó", - "for ma", - "s ar", - "ou tra", - "olh os", - "i ma", - "m im", - "a go", - "in s", - "co u", - "g ran", - "v al", - "pesso as", - "era m", - "ei ra", - "a que", - "com p", - "de i", - "p ela", - "co isa", - "m ão", - "con h", - "ca da", - "ago ra", - "ia m", - "h á", - "con s", - "su as", - "gu ém", - "o b", - "l an", - "es ti", - "á s", - "la do", - "in ter", - "ca be", - "por ta", - "n em", - "í vel", - "r is", - "j e", - "n un", - "sem pre", - "con segu", - "h as", - "tra bal", - "f u", - "le v", - "l em", - "l as", - "va i", - "tr os", - "t ante", - "te i", - "pr ó", - "que m", - "tu ra", - "on de", - "cabe ça", - "nun ca", - "men tos", - "h um", - "de le", - "ver dade", - "t á", - "h os", - "el i", - "ent es", - "m er", - "alg um", - "diz er", - "s in", - "pen as", - "n ós", - "en quanto", - "ou tro", - "l ho", - "es te", - "mel hor", - "est ar", - "g an", - "b ar", - "pri mei", - "a u", - "i u", - "pen sa", - "a penas", - "p ra", - "es tou", - "con te", - "res pon", - "ho mem", - "do is", - "a do", - "c al", - "a b", - "l os", - "ç as", - "pou co", - "sen hor", - "t ando", - "esp era", - "pa i", - "ri os", - "no i", - "i da", - "ba ix", - "as e", - "is as", - "f r", - "ho ra", - "mu ndo", - "pas sa", - "fi car", - "to do", - "se ja", - "al mente", - "â n", - "c lar", - "a d", - "in c", - "f os", - "lo n", - "g ri", - "ou vi", - "v em", - "g e", - "ta va", - "á rio", - "mo n", - "s os", - "in ho", - "ma l", - "t an", - "t re", - "gran de", - "ran do", - "b u", - "v ou", - "ê s", - "co isas", - "a conte", - "lh er", - "g en", - "ci on", - "an os", - "i do", - "tal vez", - "est ão", - "li v", - "sa b", - "su r", - "ou tros", - "c re", - "qual quer", - "g ou", - "t ri", - "l í", - "tiv esse", - "ra do", - "prec isa", - "mã e", - "su s", - "t anto", - "de la", - "men os", - "s al", - "en tra", - "p é", - "ma ior", - "noi te", - "ti va", - "p ala", - "so n", - "ra ção", - "de us", - "s as", - "un i", - "l or", - "u l", - "in te", - "f ei", - "an o", - "par ti", - "pala v", - "tr ás", - "par te", - "b el", - "ci dade", - "lu gar", - "v os", - "vez es", - "do u", - "en contra", - "tr u", - "e ci", - "a r", - "e r", - "a n", - "e n", - "i n", - "i r", - "o r", - "d e", - "a k", - "ı n", - "a l", - "d i", - "d a", - "b u", - "b ir", - "y or", - "i l", - "e k", - "y a", - "m a", - "l a", - "e l", - "u n", - "k a", - "l ar", - "i m", - "d ı", - "e t", - "o n", - "d u", - "o l", - "e y", - "t ı", - "m i", - "h a", - "b a", - "l er", - "ü n", - "m ı", - "i z", - "l e", - "ı r", - "m e", - "i s", - "n e", - "o k", - "t a", - "s a", - "u m", - "r a", - "g ö", - "i k", - "s ı", - "d en", - "e s", - "b il", - "t i", - "l ı", - "ü z", - "i ç", - "ü r", - "g i", - "u r", - "t e", - "b en", - "d an", - "i y", - "ı m", - "u z", - "v e", - "c ak", - "a y", - "c e", - "i ş", - "ın ı", - "i yor", - "ba ş", - "d ü", - "a t", - "a m", - "g el", - "de ğ", - "k ar", - "i ̇", - "m u", - "e v", - "ö y", - "bu n", - "v ar", - "ya p", - "s en", - "an a", - "s un", - "in i", - "gö r", - "y ı", - "k i", - "l i", - "ar a", - "al ı", - "on u", - "ç ı", - "ş ey", - "s ın", - "k ı", - "ka d", - "s e", - "t an", - "a ğ", - "değ il", - "s in", - "ü k", - "a z", - "ç ok", - "s on", - "ş ı", - "b i", - "ü l", - "t u", - "v er", - "iç in", - "g e", - "k en", - "ey e", - "ol du", - "mı ş", - "y e", - "k al", - "m ek", - "l an", - "öy le", - "yor du", - "er i", - "y üz", - "mi ş", - "b e", - "m ak", - "o la", - "in e", - "y an", - "h er", - "c ek", - "yor um", - "b ak", - "ü m", - "ö n", - "lar ı", - "o ğ", - "d er", - "kad ar", - "h al", - "ar ı", - "s t", - "s an", - "ın da", - "du r", - "g ün", - "v a", - "y ok", - "y er", - "dı m", - "k o", - "da ha", - "l u", - "ın a", - "di m", - "e m", - "bil ir", - "ik i", - "s iz", - "s i", - "n a", - "di ğ", - "s u", - "b ü", - "ha y", - "s or", - "dü ş", - "ü ç", - "un u", - "ö r", - "d ir", - "m ü", - "c a", - "am an", - "f ak", - "a da", - "e de", - "son ra", - "h iç", - "ak i", - "ğ ı", - "bu l", - "r u", - "ma z", - "an la", - "bu ra", - "ge ç", - "ma ya", - "l en", - "k onu", - "c i", - "c u", - "d in", - "t ek", - "z aman", - "el er", - "ö z", - "dı r", - "gi bi", - "o t", - "ş a", - "g er", - "ler i", - "k im", - "k u", - "fak at", - "y ar", - "gö z", - "c ı", - "yor sun", - "b ek", - "in de", - "r o", - "p ek", - "bun u", - "l ik", - "m an", - "il er", - "e di", - "ö l", - "s ür", - "b in", - "s ır", - "çı k", - "sı l", - "al ar", - "k es", - "y ak", - "ç ek", - "yı l", - "e cek", - "ı z", - "gi t", - "ka p", - "a ma", - "ı l", - "lar ın", - "b iz", - "tı r", - "o y", - "an cak", - "d oğ", - "ç a", - "b ana", - "ş im", - "baş la", - "l ü", - "ma dı", - "ben i", - "t ir", - "y ük", - "lı k", - "be ş", - "b el", - "b er", - "m er", - "na sıl", - "tı k", - "k e", - "t ür", - "a v", - ". .", - "d aki", - "p ar", - "t er", - "ce ğ", - "t en", - "z ı", - "iy i", - "d ok", - "ben im", - "c ağ", - "n er", - "y en", - "ş u", - "me z", - "düş ün", - "ken di", - "şim di", - "y ol", - "y u", - "de v", - "is te", - "s ek", - "ma m", - "s öyle", - "di k", - "t o", - "k ur", - "oldu ğ", - "s ını", - "t ar", - "bil iyor", - "k an", - "y al", - "m eye", - "mu ş", - "f a", - "ka ç", - "bil e", - "iy e", - "t ü", - "e f", - "tı m", - "ev et", - "ç o", - "y et", - "g en", - "bura da", - "t im", - "bir az", - "es i", - "k or", - "doğ ru", - "in in", - "kı z", - "di ye", - "d ör", - "et ti", - "on un", - "is ti", - "ğ i", - "h e", - "s ana", - "ü ş", - "ar ka", - "hay ır", - "kar şı", - "h ar", - "il e", - "h ak", - "ı yor", - "ne den", - "s ev", - "sı z", - "ço cu", - "me m", - "ç alı", - "ol ur", - "b ır", - "g ir", - "is e", - "i h", - "c an", - "k ır", - "d ön", - "b öyle", - "sen i", - "! \"", - "al t", - "dör t", - "s öy", - "o ş", - "mu sun", - "la ş", - "h an", - "i p", - "ka y", - "h em", - "bü yük", - "a ç", - "bır ak", - "mi sin", - "s öz", - "u l", - "değ iş", - "ün ü", - "g ül", - "k ö", - "kar ı", - "ta mam", - "ol u", - "r ar", - "yen i", - "la m", - "mış tı", - "ya ş", - "al a", - "in iz", - "kad ın", - "bun un", - "m ey", - "al tı", - "y i", - "s o", - "in den", - "sen in", - "ya t", - "to p", - "s er", - "is i", - "d ün", - "s es", - "hiç bir", - "y on", - "d ın", - "t ün", - "baş ka", - "a s", - "he p", - "i t", - "ir mi", - "dev am", - "ola cak", - "ar tık", - "r e", - "dur um", - "im iz", - "üz el", - "ler ini", - "sa ğ", - "p ro", - "ger ek", - "y irmi", - "ş ek", - "ba ğ", - "me di", - "lar a", - "a h", - "t ur", - "y ür", - "ma sı", - "ka tı", - "de di", - "g ü", - "sor un", - "el i", - "ün e", - "mı z", - "yap ı", - "m il", - "ğ ını", - "t ara", - "m en", - "ha t", - "var dı", - "m et", - "konu ş", - "ar ak", - "lar ak", - "çocu k", - "bü tün", - "l ey", - "d ür", - "g üzel", - "ay ı", - "yap a", - "n ı", - "ay r", - "ö ne", - "yordu m", - "b an", - "i̇ ş", - "du m", - "un a", - "on a", - "yor lar", - "lar ını", - "çı kar", - "z an", - "se ç", - "l iyor", - "t ak", - "şı k", - "tek rar", - "a ş", - "e ş", - "miş ti", - "f ar", - "k in", - "im i", - "i f", - "e ğ", - "gi di", - "le ş", - "başla dı", - "gi de", - "ot ur", - "d de", - "ın dan", - "üz er", - "ın ın", - "n ız", - "u y", - "ye di", - "ka t", - "o larak", - "la dı", - "yal nız", - "ba h", - "iy et", - "m al", - "s ak", - "a çık", - "sın da", - ".. .", - "in san", - "ay nı", - "e der", - "is tan", - "uz un", - "sa h", - "d o", - "g eri", - "er ek", - "ol an", - "ger çek", - "f en", - "al an", - "dı ş", - "alı k", - "far k", - "ü st", - "sa de", - "r i", - "k iş", - "l dı", - "z or", - "et ir", - "her kes", - "s al", - "ö mer", - "s el", - "un da", - "ha f", - "bun a", - "y dı", - "pek i", - "ada m", - "ha z", - "sın a", - "kap ı", - "gör üş", - "sade ce", - "al dı", - "gel di", - "i e", - "n ie", - "n a", - "r z", - "s z", - "c z", - "p o", - "s t", - "c h", - "i ę", - "d z", - "n i", - "a ł", - "r a", - "j e", - "r o", - "d o", - "s ię", - "z a", - "g o", - "e m", - "w i", - "c i", - "rz e", - "k o", - "l e", - "l i", - "w a", - "t o", - "k a", - "m i", - "ż e", - "t a", - "w ie", - "b y", - "m o", - "w y", - "rz y", - "ł a", - "j a", - "n o", - "ł o", - "w o", - "p a", - "m a", - "t e", - "t y", - "n y", - "k i", - "d a", - "n e", - "dz ie", - "dz i", - "cz y", - "c ie", - "m y", - "p rze", - "d y", - "o d", - "l a", - "k ie", - "r y", - "st a", - "j ą", - "ó w", - "c e", - "p rzy", - "c o", - "k u", - "m ie", - "sz y", - "cz e", - "r e", - "b a", - "s i", - "b ie", - "m u", - "w e", - "c y", - "ni a", - "ś ci", - "sz e", - "je st", - "k t", - "s a", - "b o", - "t u", - "ż y", - "n ą", - "b i", - "r u", - "a le", - "kt ó", - "p ra", - "ał a", - "m nie", - "p ie", - "ł y", - "cz a", - "ja k", - "ro z", - "r ó", - "l u", - "z na", - "g a", - "ra z", - "ł u", - "ta k", - "j u", - "p i", - "ś ć", - "s o", - "wi a", - "m ó", - "ch o", - "w szy", - "p e", - "s po", - "c a", - "g dy", - "w ał", - "w ię", - "d e", - "b e", - "p ro", - "ł em", - "j ę", - "s k", - "z e", - "l o", - "g i", - "r ę", - "do b", - "d u", - "ju ż", - "st o", - "b ę", - "ał em", - "sz a", - "m e", - "po d", - "d la", - "pa n", - "n ę", - "z o", - "mo że", - "ś li", - "s ie", - "ał o", - "t em", - "l ko", - "ny ch", - "po wie", - "c ię", - "s u", - "ty lko", - "i n", - "b u", - "na j", - "ch a", - "te go", - "p u", - "s ki", - "ne go", - "wszy st", - "sz cze", - "je d", - "je j", - "t wo", - "ą d", - "ś my", - "cz ę", - "wa ć", - "je go", - "ż a", - "i m", - "s y", - "pra w", - "ty m", - "któ ry", - "ał y", - "t rze", - "nie j", - "s e", - "ny m", - "i ch", - "o b", - ". .", - "g ło", - "ją c", - "mó wi", - "s ka", - "o n", - "ne j", - "s łu", - "w ła", - "bę dzie", - "d ę", - "p ó", - "be z", - "ni c", - "p ła", - "ś cie", - "mi a", - "s ą", - "t rzy", - "kie m", - "by ł", - "mo g", - "ro bi", - "ta m", - "c u", - "te n", - "m ię", - "z y", - "pe w", - "ci a", - "my ś", - "prze d", - "s ko", - "n u", - "któ re", - "a l", - "l ę", - "w sze", - "ą c", - "by ło", - "so bie", - "p y", - "ci ą", - "ba r", - "je szcze", - "h a", - "t ę", - "b ra", - "cza s", - "sz ę", - "g ł", - "k ę", - "ma r", - "cz u", - "prze z", - "f i", - "s ło", - "w z", - "k to", - "k ów", - "cz o", - "li śmy", - "st ra", - "wię c", - "r ą", - "ma m", - "w ó", - "rz a", - "g ro", - "no ści", - "f a", - "we t", - "ną ł", - "ś mie", - "na wet", - "mu si", - "s wo", - "te j", - "w ą", - "w u", - "wi ą", - "ni u", - "cz ą", - "b li", - "dz o", - "s kie", - "n em", - "je śli", - "cze go", - "ch y", - "d ł", - "ty ch", - "by m", - "ż o", - "e ś", - "si ą", - "kie dy", - "na s", - "w ró", - "dz e", - "d ro", - "t ra", - "r ów", - "pa ni", - "z ie", - "ku l", - "na d", - "ch wi", - "ni m", - "t ro", - "by ć", - "cho dzi", - "ni o", - "dob rze", - "te raz", - "wo kul", - "co ś", - "k ł", - "pie r", - "h e", - "g dzie", - "dz y", - "p ię", - "d ź", - "k ą", - "g ó", - "z da", - "ch ce", - "st ę", - "o r", - "ś wia", - "wszyst ko", - "st ro", - "pe ł", - "wie m", - "wie l", - "ka ż", - "ki m", - "rz u", - "s ły", - "jed na", - "z u", - "myś l", - "mó j", - "g u", - "wa r", - "jest em", - "ó ż", - "mie j", - "mo ż", - "k ła", - "re sz", - "d łu", - "st wo", - "n ię", - "ma sz", - "że by", - "nie m", - "ja kie", - "st y", - "ni ą", - "we j", - "o j", - "g ra", - "s ła", - "no ść", - "z ło", - "sz czę", - ".. .", - "r i", - "le j", - "we go", - "c ał", - "dzi ał", - "ki ch", - "dz a", - "dz ię", - "o czy", - "zo sta", - "cz ło", - "na m", - "ki l", - "o na", - "sz u", - "w ę", - "pa r", - "mi ał", - "st rze", - "ce j", - "e j", - "zna j", - "da ć", - "miej s", - "k ró", - "k ry", - "bar dzo", - "si a", - "z i", - "ś nie", - "l ą", - "g ie", - "cie bie", - "d ni", - "st u", - "po trze", - "wokul ski", - "u wa", - "u mie", - "jedna k", - "k ra", - "wró ci", - "czło wie", - "czy ć", - "by ła", - "że li", - "m ę", - "c ę", - "z robi", - "mog ę", - "pro wa", - "r em", - "nie ch", - "cz nie", - "k ro", - "t ą", - "ch ci", - "b ro", - "dzie ć", - "sz ą", - "pa d", - "t rz", - "t ru", - "je m", - "a ni", - "t ów", - "a r", - "d ru", - "ta j", - "rze kł", - "sa m", - "st e", - "nie go", - "ta kie", - "w ała", - "to wa", - "ka pła", - "wi dzi", - "po dob", - "dz ę", - "t ał", - "stę p", - "b ą", - "po ko", - "w em", - "g ę", - "a by", - "g e", - "al bo", - "s pra", - "z no", - "de n", - "s mo", - "je sz", - "k się", - "jest eś", - "po z", - "ni gdy", - "k sią", - "c óż", - "w s", - "po w", - "t ka", - "ś wie", - "sz ka", - "sa mo", - "s ł", - "rz ę", - "na le", - "chce sz", - "ni k", - "p ę", - "chy ba", - "cią g", - "ją cy", - "wo j", - "na sze", - "mnie j", - "wię cej", - "z wy", - "o sta", - "f e", - "wa ż", - "h o", - "se r", - "śmie r", - "wie r", - "dz ą", - "za ś", - "gdy by", - "ja ki", - "wo l", - "wi n", - "d ą", - "ści a", - "roz ma", - "wa l", - "pa nie", - "sta r", - "ka z", - "je żeli", - "d em", - "w ra", - "ko ń", - "sie bie", - "zno wu", - "p ró", - "cz em", - "st wa", - "i sto", - "pó ł", - "d ał", - "ko bie", - "ała m", - "wy ch", - "ce sa", - "ni ch", - "za wsze", - "dzi ć", - "te ż", - "le pie", - "pro szę", - "k re", - "t wa", - "o t", - "ł ą", - "ch u", - "c ą", - "p rz", - "ł e", - "sze dł", - "od powie", - "my śli", - "ś wią", - "e n", - "e r", - "d e", - "a n", - "e t", - "i j", - "i n", - "e l", - "a a", - "s t", - "o r", - "g e", - "i s", - "a t", - "i e", - "c h", - "o n", - "e en", - "h et", - "i t", - "v er", - "aa r", - "a l", - "o or", - "g en", - "v an", - "o p", - "d en", - "h e", - "o m", - "t e", - "w e", - "i k", - "r e", - "z e", - "ij n", - "d at", - "b e", - "d er", - "in g", - "o e", - "ij k", - "a an", - "ch t", - "v oor", - "l e", - "i et", - "r o", - "m o", - "k en", - "z ijn", - "m en", - "i g", - "j e", - "n iet", - "a r", - "o o", - "i d", - "u n", - "i l", - "s ch", - "mo et", - "st e", - "u r", - "o l", - "he b", - "u it", - "g el", - "w ij", - "a s", - "m e", - "t en", - "w or", - "o u", - "v en", - "l en", - "aa t", - "d it", - "m et", - "r a", - "b en", - "s p", - "o ver", - "d ie", - "n o", - "w er", - "l ijk", - "f t", - "s l", - "an d", - "v e", - "t er", - "i er", - "i en", - "t o", - "d aar", - "g r", - "b el", - "de ze", - "d u", - "a g", - "k an", - "wor den", - "in gen", - "moet en", - "n en", - "on der", - "heb ben", - "r u", - "oo k", - "s en", - "c t", - "k t", - "no g", - "aa l", - "w as", - "u l", - "e er", - "b ij", - "m ijn", - "p ro", - "v ol", - "d o", - "k om", - "at ie", - "e ft", - "k el", - "al s", - "r ij", - "he id", - "a f", - "st el", - "m aar", - "a p", - "we e", - "a d", - "he eft", - "w aar", - "i cht", - "d an", - "er en", - "n e", - "w el", - "w at", - "w il", - "a cht", - "aa g", - "ge b", - "c on", - "z o", - "k e", - "b et", - "h ij", - "d ig", - "k un", - "u w", - "d t", - "d oor", - "t ij", - "a m", - "an g", - "on d", - "er s", - "is ch", - "ge en", - "i ge", - "ge v", - "ve el", - "n u", - "m a", - "on s", - "o f", - "b l", - "n aar", - "g ro", - "p l", - "an der", - "at en", - "kun nen", - "e cht", - "h ier", - "g oe", - "an t", - "u s", - "t wee", - "on t", - "de lijk", - "el e", - "u ur", - "al le", - "t oe", - "me er", - "i st", - "n a", - "n ie", - "on ze", - "l o", - "i m", - "p en", - "h ad", - "tij d", - "h oe", - "to t", - "z ou", - "a k", - "aa k", - "a men", - "d r", - "w oor", - "s e", - "wor dt", - "o t", - "gel ijk", - "g aan", - "i c", - "g er", - "k er", - "el d", - "e m", - "h ou", - "de l", - "z en", - "z el", - "te gen", - "b o", - "kom en", - "c om", - "i gen", - "e it", - "wer k", - "goe d", - "z al", - "z ij", - "sl ag", - "e s", - "z ien", - "a st", - "echt er", - "it ie", - "t ie", - "el ijk", - "m is", - "isch e", - "bel an", - "h aar", - "i ch", - "b er", - "h an", - "v r", - "al e", - "c i", - "gr ijk", - "in d", - "do en", - "l and", - "belan grijk", - "p un", - "op en", - "ct ie", - "zel f", - "m ij", - "it eit", - "ste m", - "me e", - "ar en", - "al l", - "b r", - "re cht", - "d ien", - "h u", - "g aat", - "pro b", - "m oe", - "p er", - "a u", - "ul len", - "z ich", - "daar om", - "or m", - "k l", - "v o", - "en t", - "st aat", - "z it", - "du i", - "n at", - "du s", - "d s", - "ver slag", - "kel ijk", - "prob le", - "w et", - "ge m", - "c r", - "i on", - "p r", - "sch ap", - "g d", - "h un", - "z a", - "er d", - "z et", - "st aan", - "st r", - "m aal", - "in der", - "e id", - "st en", - "p ar", - "k ken", - "ge d", - "z ullen", - "re s", - "men sen", - "j aar", - "re gel", - "ie der", - "vol gen", - "ge ven", - "e ven", - "l u", - "bl ij", - "i ë", - "k o", - "u we", - "m an", - "ma ken", - "l ie", - "g a", - "oe k", - "nie uwe", - "b aar", - "h o", - "h er", - "in ter", - "ander e", - "ru ik", - "s u", - "a gen", - "or t", - "m er", - "ou w", - "st er", - "wil len", - "aa kt", - "h oo", - "an den", - "f f", - "l ig", - "t re", - "s amen", - "ze er", - "dui delijk", - "ant woor", - "he el", - "men t", - "pun t", - "hou den", - "we g", - "vr aag", - "gel e", - "een s", - "be sch", - "om en", - "er g", - "do el", - "d ag", - "sp e", - "ur en", - "ing s", - "or en", - "l ang", - "de len", - "m ar", - "ste un", - "in nen", - "p ol", - "o on", - "i de", - "s n", - "s ie", - "r icht", - "z onder", - "no dig", - "all een", - "m id", - "ra gen", - "iet s", - "ver sch", - "geb ruik", - "st u", - "ro uw", - "stel len", - "be g", - "men ten", - "v in", - "eer ste", - "l aat", - "gro ot", - "oo d", - "to ch", - "l aten", - "aar d", - "s le", - "de el", - "st and", - "pl aat", - "re e", - "bet re", - "d i", - "l id", - "uit en", - "ra cht", - "bel eid", - "g et", - "ar t", - "st ie", - "st aten", - "g gen", - "re ken", - "e in", - "al en", - "m ing", - "mo gelijk", - "gro te", - "al tijd", - "z or", - "en kel", - "w ik", - "pol itie", - "e igen", - "el k", - "han del", - "g t", - "k we", - "m aat", - "el en", - "i p", - "v rij", - "s om", - "je s", - "aa m", - "hu is", - "v al", - "we er", - "lid staten", - "k ing", - "k le", - "be d", - "gev al", - "stel l", - "a i", - "wik kel", - "kwe stie", - "t al", - "ste e", - "a b", - "h el", - "kom st", - "p as", - "s s", - "it u", - "i den", - "eer d", - "m in", - "c e", - "p o", - "twee de", - "proble em", - "w aren", - "us sen", - "sn el", - "t ig", - "ge w", - "j u", - "ul t", - "ne men", - "com mis", - "versch il", - "k on", - "z oek", - "k rij", - "gr aag", - "den k", - "l anden", - "re den", - "be sl", - "oe g", - "bet er", - "he den", - "m ag", - "p e", - "bo ven", - "a c", - "con t", - "f d", - "h ele", - "k r", - "v ier", - "w in", - "ge z", - "k w", - "m il", - "v or", - "he m", - "ra m", - "aa s", - "ont wikkel", - "dr ie", - "v aak", - "plaat s", - "l a", - "g ang", - "ij f", - "f in", - "nat uur", - "t ussen", - "u g", - "in e", - "d a", - "b at", - "kom t", - "w acht", - "aa d", - "u t", - "é n", - "acht er", - "geb ie", - "ver k", - "lig t", - "c es", - "nie uw", - "van d", - "s t", - "n í", - "j e", - "p o", - "c h", - "r o", - "n a", - "s e", - "t o", - "n e", - "l e", - "k o", - "l a", - "d o", - "r a", - "n o", - "t e", - "h o", - "n ě", - "v a", - "l i", - "l o", - "ř e", - "c e", - "d e", - "v e", - "b y", - "n i", - "s k", - "t a", - "n á", - "z a", - "p ro", - "v o", - "v ě", - "m e", - "v á", - "s o", - "k a", - "r á", - "v y", - "z e", - "m i", - "p a", - "t i", - "st a", - "m ě", - "n é", - "ř i", - "ř í", - "m o", - "ž e", - "m a", - "j í", - "v ý", - "j i", - "d ě", - "r e", - "d a", - "k u", - "j a", - "c i", - "r u", - "č e", - "o b", - "t ě", - "m u", - "k y", - "d i", - "š e", - "k é", - "š í", - "t u", - "v i", - "p ře", - "v í", - "s i", - "n ý", - "o d", - "so u", - "v é", - "n y", - "r i", - "d y", - "b u", - "b o", - "t y", - "l á", - "l u", - "n u", - "ž i", - "m á", - "st i", - "c í", - "z á", - "p ra", - "sk é", - "m í", - "c o", - "d u", - "d á", - "by l", - "st o", - "s a", - "t í", - "je d", - "p ří", - "p ři", - "t é", - "s í", - "č i", - "v ní", - "č a", - "d í", - "z i", - "st u", - "p e", - "b a", - "d ní", - "ro z", - "va l", - "l í", - "s po", - "k á", - "b e", - "p i", - "no u", - "ta k", - "st e", - "r y", - "l é", - "vě t", - "se m", - "p ě", - "ko n", - "ne j", - "l y", - "ko u", - "ý ch", - "b ě", - "p r", - "f i", - "p rá", - "a le", - "ja ko", - "po d", - "ž í", - "z í", - "j sou", - "j sem", - "ch o", - "l ní", - "c ké", - "t á", - "m y", - "a k", - "h u", - "va t", - "pře d", - "h la", - "k e", - "st á", - "č í", - "š i", - "s le", - "k la", - "š tě", - "lo u", - "m ů", - "z na", - "ch á", - "o r", - "p ů", - "h a", - "b i", - "ta ké", - "d ů", - "no st", - "t ře", - "te r", - "p u", - "i n", - "v r", - "ve l", - "sk u", - "v še", - "t ní", - "do b", - "by la", - "č ní", - "ja k", - "v u", - "je ho", - "b ý", - "vá ní", - "ný ch", - "po u", - "te n", - "t ři", - "v z", - "st ře", - "d va", - "h le", - "č á", - "no sti", - "c k", - "v š", - "vo u", - "s u", - "h e", - "h ra", - "je n", - "s y", - "da l", - "po z", - "s lo", - "te l", - "d ru", - "de n", - "vš ak", - "g i", - "k dy", - "by lo", - "bu de", - "st ra", - "j ší", - "m é", - "me n", - "vý ch", - "ní m", - "s m", - "ko li", - "r ů", - "t ra", - "mů že", - "ne ní", - "ho d", - "b í", - "do u", - "sk a", - "t ý", - "st ě", - "u je", - "s á", - "pě t", - "ne s", - "k rá", - "to m", - "st ví", - "v ně", - "se d", - "s vé", - "p í", - "z o", - "mu sí", - "u ž", - "tí m", - "jí cí", - "jed no", - "t r", - "ča s", - "e v", - "č ty", - "sk ý", - "ni c", - "ev ro", - "to ho", - "h y", - "k ter", - "r ní", - "st í", - "s vě", - "pa k", - "vše ch", - "k ů", - "n g", - "á d", - "chá zí", - "a ni", - "a r", - "jed na", - "bý t", - "t ro", - "k ra", - "pr vní", - "m no", - "ské ho", - "p á", - "p la", - "le m", - "ne bo", - "ke m", - "st ro", - "s la", - "né ho", - "z de", - "dal ší", - "ř a", - "čty ři", - "h rá", - "dru h", - "l ně", - "v la", - "sk ých", - "š ko", - "pů so", - "pro to", - "v ů", - "sk á", - "ve n", - "še st", - "d ně", - "je ště", - "me zi", - "te k", - "s ko", - "ch a", - "ně koli", - "be z", - "g ra", - "ji ž", - "č ně", - "j á", - "s lu", - "z ná", - "ve r", - "sed m", - "k ro", - "ta m", - "a no", - "v lá", - "o sm", - "byl y", - "vá m", - "ck ý", - "te ch", - "dě ji", - "vel mi", - "le ži", - "va la", - "l ý", - "t vo", - "spo le", - "ch u", - "stu p", - "mo ž", - "evro p", - "g e", - "sta l", - "j de", - "ch y", - "ro di", - "je jí", - "po li", - "de vět", - "s me", - "a ž", - "té to", - "re m", - "d é", - "f or", - "u ni", - "f o", - "ten to", - "a u", - "ka ž", - "nu la", - "na d", - "by ch", - "mo c", - "sto u", - "e x", - "le n", - "k do", - "z d", - "pra co", - "to mu", - "ný m", - "ži vo", - "ze m", - "f e", - "f u", - "ná sle", - "j o", - "sk y", - "ji ch", - "h á", - "mě l", - "dě la", - "j sme", - "p re", - "ni ce", - "ste j", - "ne m", - "st ní", - "he m", - "ná ro", - "z u", - "b li", - "ni t", - "pa r", - "a l", - "poz ději", - "ta ko", - "n ce", - "če r", - "ší m", - "ně co", - "vá l", - "ře j", - "krá t", - "á lní", - "u r", - ". .", - "a si", - "kter é", - "sta v", - "ma jí", - "my s", - "do bě", - "s ně", - "ce n", - "z y", - "z ku", - "t ů", - "ch od", - "s pě", - "je jich", - "sou čas", - "d r", - "va li", - "ri e", - "k te", - "pr ů", - "ze ní", - "pa t", - "a n", - "po tře", - "de m", - "d nes", - "ze mí", - "sa mo", - "zna m", - "b ra", - "má m", - "te dy", - "g o", - "hla vní", - "pou ží", - "b ní", - "ve de", - "le p", - "je k", - "pra v", - "poli ti", - "d ne", - "je m", - "le t", - "če ní", - "pro b", - "ne ž", - "dě l", - "fi l", - "č o", - "cí ch", - "st é", - "d lou", - "h i", - "a by", - "to u", - "několi k", - "d la", - "vy u", - "vi t", - "ho u", - "ck ých", - "no vé", - "či n", - "st y", - "dě lá", - "k ý", - "ob la", - "pod le", - "ra n", - "dů leži", - "ta to", - "po ku", - "ko ne", - "d ý", - "d vě", - "ž ád", - "nou t", - "t ku", - "t vr", - "cké ho", - "ro v", - "r é", - "te le", - "p sa", - "s vět", - "ti vní", - "do sta", - "te m", - "še l", - "druh é", - "s kou", - "ž o", - "jed ná", - "vý znam", - "prob lé", - "pu bli", - "vá n", - "od po", - "pod po", - "d le", - "ja ké", - "še ní", - "ví m", - "bě hem", - "na chází", - "s lou", - "pou ze", - "o tá", - "p lo", - "to vé", - "vět ši", - "ko mi", - "va jí", - "ty to", - "zá pa", - "z mě", - "mo h", - "ví ce", - "spole č", - "au to", - "pro ti", - "st ru", - "dě t", - "chá ze", - "že l", - "с т", - "е н", - "н о", - "н а", - "п р", - "т о", - "п о", - "р а", - "г о", - "к о", - "н е", - "в о", - "в а", - "е т", - "е р", - "н и", - "е л", - "и т", - "н ы", - "з а", - "р о", - "ен и", - "к а", - "л и", - "е м", - "д а", - "о б", - "л а", - "д о", - "с я", - "т ь", - "о т", - "л о", - "л ь", - "е д", - "с о", - "м и", - "р е", - "м о", - "ц и", - "пр о", - "т а", - "э то", - "к и", - "р у", - "пр и", - "т и", - "с е", - "ст а", - "в ы", - "м ы", - "в и", - "б ы", - "м а", - "е с", - "л я", - "ст и", - "л е", - "ч то", - "м е", - "р и", - "ч а", - "о д", - "е й", - "ел ь", - "ени я", - "г а", - "н у", - "с и", - "п а", - "ра з", - "б о", - "ст о", - "с у", - "с а", - "д у", - "е го", - "е ст", - "и н", - "ит ь", - "и з", - "ж е", - "м у", - "п ер", - "по д", - "ени е", - "с ь", - "к у", - "пр ед", - "но го", - "ны х", - "в ер", - "т е", - "но й", - "ци и", - "д е", - "р ы", - "д ел", - "л ю", - "в е", - "о н", - "м ен", - "г и", - "н я", - "б у", - "пр а", - "в се", - "ет ся", - "ст ь", - "ж а", - "до л", - "ж и", - "б е", - "ко н", - "с л", - "ш и", - "д и", - "ст в", - "с ко", - "ны е", - "ч и", - "ю т", - "д ер", - "ст ра", - "т ы", - "х од", - "щ и", - "з о", - "з на", - "но сти", - "ч ес", - "в ля", - "ва ть", - "о р", - "по л", - "в ет", - "та к", - "ш а", - "т у", - "с во", - "пр е", - "о на", - "ит ель", - "ны й", - "с ло", - "ка к", - "в л", - "но сть", - "х о", - "мо ж", - "п е", - "д ля", - "ни я", - "но е", - "ра с", - "дол ж", - "да р", - "т ель", - "с ка", - "п у", - "ст во", - "ко то", - "ра б", - "е е", - "ро д", - "э ти", - "с об", - "о ру", - "ж ен", - "ны м", - "ит и", - "ни е", - "ко м", - "д ет", - "ст у", - "г у", - "п и", - "ме ж", - "ени ю", - "т ер", - "раб от", - "во з", - "ци я", - "ко й", - "щ ест", - "г ра", - "з и", - "р я", - "меж ду", - "ст ва", - "в с", - "ел о", - "ш е", - "м ер", - "б а", - "з ы", - "л у", - "а ль", - "д ей", - "г ла", - "на род", - "к ти", - "пред ста", - "л ся", - "я вля", - "с ки", - "но в", - "ед ин", - "ро в", - "и с", - "ни ма", - "р ем", - "ход и", - "так же", - "д ру", - "а ть", - "сл ед", - "го во", - "на я", - "ю щи", - "ен ь", - "кото ры", - "х от", - "в у", - "и х", - "ем у", - "ч ит", - "ва ж", - "ор га", - "чес ки", - "щ е", - "к е", - "х а", - "по с", - "то м", - "бо ль", - "м не", - "па с", - "об ъ", - "пра в", - "кон ф", - "сл у", - "под дер", - "ст ви", - "на ш", - "ль ко", - "сто я", - "ну ю", - "л ем", - "ен ных", - "к ра", - "д ы", - "между народ", - "г да", - "не об", - "го су", - "ств у", - "ени и", - "госу дар", - "к то", - "и м", - "ч ест", - "р ет", - "во про", - "л ен", - "ел и", - "ро ва", - "ци й", - "на м", - "это й", - "ж ения", - "необ ходи", - "мен я", - "бы ло", - "си ли", - "ф и", - "в я", - "ш ь", - "это го", - "о ни", - "орга ни", - "бе зо", - "пр об", - "и ме", - "ре ш", - "б и", - "безо пас", - "ют ся", - "о ста", - "ен но", - "го д", - "ел а", - "предста в", - "ть ся", - "сло во", - "органи за", - "долж ны", - "это м", - "б ла", - "ч е", - "ч у", - "бла го", - "это му", - "в рем", - "с пе", - "но м", - "ени й", - "с по", - "на с", - "не т", - "з у", - "в ед", - "е ще", - "ска за", - "се й", - "ер ен", - "да н", - "са м", - "ел я", - "ра н", - "зы ва", - "явля ется", - "бу дет", - "кти в", - "т ре", - "дел е", - "м от", - "конф ерен", - "ла сь", - "ча с", - "сто ро", - "ко го", - "е з", - "не й", - "о с", - "ли сь", - "раз ору", - "пер е", - "с си", - "ны ми", - "про ц", - "го ло", - "ч ело", - "бо ле", - "чело ве", - "с ер", - "п л", - "ч ет", - "стра н", - "п я", - "бы л", - "к ла", - "то в", - "ж д", - "дел а", - "е ра", - "у же", - "со вет", - "г ен", - "безопас ности", - "ц а", - "се да", - "по з", - "от вет", - "проб лем", - "на ко", - "т ем", - "до ста", - "п ы", - "щ а", - "во й", - "су щест", - "необходи мо", - "бы ть", - "мож ет", - "д ем", - "что бы", - "е к", - "ч ер", - "у сили", - "ре с", - "ру д", - "един енных", - "д об", - "до сти", - "ств ен", - "я дер", - "год ня", - "ка за", - "се годня", - "сей час", - "то лько", - "во д", - "ес ь", - "м ного", - "бу ду", - "е в", - "ест ь", - "т ри", - "об щест", - ". .", - "я вл", - "вы сту", - "р ед", - "с чит", - "с ит", - "деле га", - "ло ж", - "это т", - "ф ор", - "к лю", - "воз мож", - "ва ния", - "б ли", - "и ли", - "в з", - "на ций", - "ско го", - "при ня", - "п ла", - "о ч", - "ить ся", - "ст е", - "на ши", - "которы е", - "а р", - "име ет", - "с от", - "зна ч", - "пер ь", - "след у", - "ен ы", - "та ки", - "объ единенных", - "ст ро", - "те перь", - "б ле", - "благо дар", - "раз в", - "а н", - "жи ва", - "оч ень", - "я т", - "бе з", - "об ес", - "г ро", - "ло сь", - "с ы", - "организа ции", - "ч лен", - "то го", - "она ль", - "ж да", - "все х", - "с вя", - "боле е", - "со в", - "ко гда", - "во т", - "к ре", - "к ры", - "по этому", - "во ль", - "о й", - "ген ера", - "ч ем", - "л ы", - "пол ити", - "в ен", - "конферен ции", - "проц ес", - "б я", - "ит е", - "от но", - "разв ити", - "а ф", - "ю щ", - "в но", - "ми р", - "ни и", - "ка я", - "а с", - "итель но", - "в то", - "ени ем", - "генера ль", - "пр от", - "вс ем", - "сам бле", - "ас самбле", - "о м", - "з д", - "с мот", - "ре ги", - "ч его", - "од нако", - "усили я", - "дей стви", - "ч но", - "у ча", - "об раз", - "во с", - "э та", - "пер его", - "гово р", - "ва м", - "мо ло", - "врем я", - "д ь", - "хот ел", - "г ру", - "за явл", - "пре доста", - "по ль", - "не е", - "ре зо", - "перего во", - "резо лю", - "к рет", - "поддер ж", - "обес пе", - "не го", - "представ ит", - "на де", - "к ри", - "ч ь", - "про ек", - "л ет", - "дру ги", - "ا ل", - "َ ا", - "و َ", - "ّ َ", - "ِ ي", - "أ َ", - "ل َ", - "ن َ", - "ال ْ", - "ه ُ", - "ُ و", - "م ا", - "ن ْ", - "م ن", - "ع َ", - "ن ا", - "ل ا", - "م َ", - "ت َ", - "ف َ", - "أ ن", - "ل ي", - "م ِ", - "ا ن", - "ف ي", - "ر َ", - "ي َ", - "ه ِ", - "م ْ", - "ق َ", - "ب ِ", - "ل ى", - "ي ن", - "إ ِ", - "ل ِ", - "و ا", - "ك َ", - "ه ا", - "ً ا", - "م ُ", - "و ن", - "ال م", - "ب َ", - "ي ا", - "ذ ا", - "س ا", - "ال ل", - "م ي", - "ي ْ", - "ر ا", - "ر ي", - "ل ك", - "م َا", - "ن َّ", - "ل م", - "إ ن", - "س ت", - "و م", - "ّ َا", - "ل َا", - "ه م", - "ّ ِ", - "ك ُ", - "ك ان", - "س َ", - "ب ا", - "د ي", - "ح َ", - "ع ْ", - "ب ي", - "ال أ", - "و ل", - "ف ِي", - "ر ِ", - "د ا", - "مِ نْ", - "ُو نَ", - "و ْ", - "ه َا", - "ّ ُ", - "ال س", - "ال َ", - "ن ي", - "ل ْ", - "ت ُ", - "ه ل", - "ر ة", - "د َ", - "س ْ", - "ت ِ", - "ن َا", - "ر ْ", - "الل َّ", - "سا مي", - "ك ن", - "ك ل", - "ه َ", - "عَ لَ", - "ع لى", - "م ع", - "إ لى", - "ق د", - "ال ر", - "ُو ا", - "ي ر", - "ع ن", - "ي ُ", - "ن ِ", - "ب ْ", - "ال ح", - "هُ مْ", - "ق ا", - "ذ ه", - "ال ت", - "ِي نَ", - "ج َ", - "ه ذا", - "ع د", - "ال ع", - "د ْ", - "قَ الَ", - "ر ُ", - "ي م", - "ي ة", - "ن ُ", - "خ َ", - "ر ب", - "ال ك", - "و َا", - "أ نا", - "ة ِ", - "ال ن", - "ح د", - "ع ِ", - "ت ا", - "ه و", - "ف ا", - "ع ا", - "ال ش", - "ل ُ", - "ي ت", - "ذ َا", - "ي ع", - "ال ذ", - "ح ْ", - "ال ص", - "إِ نَّ", - "ج ا", - "ع لي", - "ك َا", - "ب ُ", - "ت ع", - "و ق", - "م ل", - "ل َّ", - "ي د", - "أ خ", - "ر ف", - "ت ي", - "ال ِ", - "ّ ا", - "ذ لك", - "أَ نْ", - "س ِ", - "ت وم", - "م ر", - "مَ نْ", - "ب ل", - "ال ق", - "الل ه", - "ِي َ", - "ك م", - "ذ َ", - "ع ل", - "ح ب", - "س ي", - "ع ُ", - "ال ج", - "ال د", - "ش َ", - "ت ك", - "ف ْ", - "ص َ", - "ل ل", - "د ِ", - "ب ر", - "ف ِ", - "ت ه", - "أ ع", - "ت ْ", - "ق ْ", - "الْ أَ", - "ئ ِ", - "عَ نْ", - "و ر", - "ح ا", - "ال َّ", - "م ت", - "ف ر", - "د ُ", - "ه نا", - "وَ أَ", - "ت ب", - "ة ُ", - "أ ي", - "س ب", - "ري د", - "و ج", - "كُ مْ", - "ح ِ", - "ك ْ", - "د ر", - "َا ء", - "ه ذه", - "ال ط", - "الْ مُ", - "د ة", - "ق ل", - "غ َ", - "ي وم", - "الَّ ذ", - "ك ر", - "ت ر", - "ك ِ", - "ك ي", - "عَلَ ى", - "رَ ب", - "ع ة", - "ق ُ", - "ج ْ", - "ف ض", - "ل ة", - "ه ْ", - "ر َا", - "وَ لَ", - "الْ مَ", - "أَ نَّ", - "ي َا", - "أ ُ", - "ش ي", - "اللَّ هُ", - "لَ ى", - "ق ِ", - "أ ت", - "عَلَ يْ", - "اللَّ هِ", - "ال ب", - "ض َ", - "ة ً", - "ق ي", - "ا ر", - "ب د", - "خ ْ", - "سْ تَ", - "ط َ", - "قَ دْ", - "ذه ب", - "أ م", - "ما ذا", - "وَ إِ", - "ة ٌ", - "و نَ", - "لي لى", - "و لا", - "ح ُ", - "ه ي", - "ص ل", - "ال خ", - "و د", - "لي س", - "ل دي", - "ق ال", - "كَا نَ", - "م َّ", - "ح ي", - "ت م", - "ل ن", - "وَ لَا", - "ب ع", - "يم كن", - "س ُ", - "ة َ", - "ح ت", - "ر ًا", - "ك ا", - "ش ا", - "هِ مْ", - "لَ هُ", - "ز َ", - "دا ً", - "م س", - "ك ث", - "الْ عَ", - "ج ِ", - "ص ْ", - "ف َا", - "ل ه", - "و ي", - "ع َا", - "هُ وَ", - "ب ِي", - "ب َا", - "أ س", - "ث َ", - "ل ِي", - "ر ض", - "الر َّ", - "لِ كَ", - "ت َّ", - "ف ُ", - "ق ة", - "ف عل", - "مِ ن", - "ال آ", - "ث ُ", - "س م", - "م َّا", - "بِ هِ", - "ت ق", - "خ ر", - "ل قد", - "خ ل", - "ش ر", - "أن ت", - "ل َّا", - "س ن", - "الس َّ", - "الذ ي", - "س َا", - "و ما", - "ز ل", - "و ب", - "أ ْ", - "إ ذا", - "ر ِي", - "ح ة", - "ن ِي", - "الْ حَ", - "وَ قَالَ", - "ب ه", - "ة ٍ", - "س أ", - "ر ٌ", - "ب ال", - "م ة", - "ش ْ", - "و ت", - "عن د", - "ف س", - "بَ عْ", - "ه ر", - "ق ط", - "أ ح", - "إن ه", - "و ع", - "ف ت", - "غ ا", - "هنا ك", - "ب ت", - "مِ نَ", - "س ر", - "ذَ لِكَ", - "ر س", - "حد ث", - "غ ْ", - "ّ ِي", - "ال إ", - "وَ يَ", - "ج ل", - "ا ست", - "ق ِي", - "ع ب", - "و س", - "ي ش", - "الَّذ ِينَ", - "تا ب", - "د ِي", - "ج ب", - "ك ون", - "ب ن", - "ال ث", - "لَ يْ", - "ب عد", - "وَ الْ", - "فَ أَ", - "ع م", - "هُ م", - "ت ن", - "ذ ْ", - "أ ص", - "أ ين", - "رَب ِّ", - "الذ ين", - "إِ ن", - "ب ين", - "ج ُ", - "عَلَيْ هِ", - "ح َا", - "ل و", - "ست ط", - "ظ ر", - "لَ مْ", - "ء ِ", - "كُ ل", - "ط ل", - "ت َا", - "ض ُ", - "كن ت", - "ل ًا", - "م ٌ", - "ق بل", - "ـ ـ", - "ذ ِ", - "قَ وْ", - "ص ِ", - "م ًا", - "كان ت", - "ص ا", - "ي ق", - "ال ف", - "ال نا", - "م ٍ", - "إِ نْ", - "ال نَّ", - "ج د", - "وَ مَا", - "ت ت", - "ب ح", - "م كان", - "كي ف", - "ّ ة", - "ال ا", - "ج َا", - "أ و", - "سا عد", - "ض ِ", - "إ لا", - "را ً", - "ق َا", - "ر أ", - "ع ت", - "أ حد", - "ه د", - "ض ا", - "ط ر", - "أ ق", - "ما ء", - "د َّ", - "ال با", - "م ُو", - "أَ وْ", - "ط ا", - "ق ُو", - "خ ِ", - "ت ل", - "ستط يع", - "د َا", - "الن َّا", - "إ لَى", - "وَ تَ", - "هَ ذَا", - "ب ة", - "علي ك", - "ج ر", - "ال من", - "ز ا", - "ر ٍ", - "د ع", - "ّ ًا", - "س ة", - "ثُ مَّ", - "شي ء", - "ال غ", - "ت ح", - "ر ُونَ", - "ال يوم", - "م ِي", - "ن ُوا", - "أ ر", - "تُ مْ", - "ع ر", - "ي ف", - "أ ب", - "د ًا", - "ص َا", - "الت َّ", - "أ ريد", - "ال ز", - "يَ وْ", - "إ لي", - "ج ي", - "يَ عْ", - "فض ل", - "ال إن", - "أن ه", - "n g", - "i 4", - "a n", - "s h", - "z h", - "i 2", - "ng 1", - "u 4", - "i 1", - "ng 2", - "d e", - "j i", - "a o", - "x i", - "u 3", - "de 5", - "e 4", - "i 3", - "ng 4", - "an 4", - "e n", - "u o", - "sh i4", - "an 2", - "u 2", - "c h", - "u 1", - "ng 3", - "a 1", - "an 1", - "e 2", - "a 4", - "e i4", - "o ng1", - "a i4", - "ao 4", - "h u", - "a ng1", - "l i", - "y o", - "an 3", - "w ei4", - "uo 2", - "n 1", - "en 2", - "ao 3", - "e 1", - "y u", - "q i", - "e ng2", - "zh o", - "a ng3", - "a ng4", - "a ng2", - "uo 4", - "m i", - "g e4", - "y i1", - "g uo2", - "e r", - "b i", - "a 3", - "h e2", - "e 3", - "y i2", - "d i4", - "zh ong1", - "b u4", - "g u", - "a i2", - "n 2", - "z ai4", - "sh i2", - "e ng1", - "r en2", - "o ng2", - "xi an4", - "y i", - "x u", - "n 4", - "l i4", - "en 4", - "y u2", - "e i2", - "yi2 ge4", - "o u4", - "e i3", - "d i", - "u i4", - "a 2", - "yo u3", - "ao 1", - "d a4", - "ch eng2", - "en 1", - "e ng4", - "y i4", - "s i1", - "zh i4", - "ji a1", - "yu an2", - "n i", - "t a1", - "de5 yi2ge4", - "k e1", - "sh u3", - "x i1", - "j i2", - "ao 2", - "t i", - "o u3", - "o ng4", - "xi a4", - "a i1", - "g ong1", - "zh i1", - "en 3", - "w ei2", - "j u", - "xu e2", - "q u1", - "zho u1", - "er 3", - "mi ng2", - "zho ng3", - "l i3", - "w u4", - "y i3", - "uo 1", - "e 5", - "j i4", - "xi ng2", - "ji an4", - "hu a4", - "y u3", - "uo 3", - "j i1", - "a i3", - "z uo4", - "h ou4", - "hu i4", - "e i1", - "ni an2", - "q i2", - "p i", - "d ao4", - "sh eng1", - "de 2", - "d ai4", - "u an2", - "zh e4", - "zh eng4", - "b en3", - "sh ang4", - "zh u3", - "b ei4", - "y e4", - "ch u1", - "zh an4", - "l e5", - "l ai2", - "sh i3", - "n an2", - "r en4", - "yo u2", - "k e4", - "b a1", - "f u4", - "d ui4", - "y a4", - "m ei3", - "z i4", - "xi n1", - "ji ng1", - "zh u", - "n 3", - "yo ng4", - "m u4", - "ji ao4", - "y e3", - "ji n4", - "bi an4", - "l u4", - "q i1", - "sh e4", - "xi ang1", - "o ng3", - "sh u4", - "d ong4", - "s uo3", - "gu an1", - "s an1", - "b o", - "t e4", - "d uo1", - "f u2", - "mi n2", - "l a1", - "zh i2", - "zh en4", - "o u1", - "w u3", - "m a3", - "i 5", - "z i5", - "j u4", - "er 4", - "y ao4", - "xia4 de5yi2ge4", - "s i4", - "t u2", - "sh an1", - "z ui4", - "ch u", - "yi n1", - "er 2", - "t ong2", - "d ong1", - "y u4", - "y an2", - "qi an2", - "shu3 xia4de5yi2ge4", - "ju n1", - "k e3", - "w en2", - "f a3", - "l uo2", - "zh u4", - "x i4", - "k ou3", - "b ei3", - "ji an1", - "f a1", - "di an4", - "ji ang1", - "wei4 yu2", - "xi ang4", - "zh i3", - "e ng3", - "f ang1", - "l an2", - "sh u", - "r i4", - "li an2", - "sh ou3", - "m o", - "qi u2", - "ji n1", - "h uo4", - "shu3xia4de5yi2ge4 zhong3", - "f en1", - "n ei4", - "g ai1", - "mei3 guo2", - "u n2", - "g e2", - "b ao3", - "qi ng1", - "g ao1", - "t ai2", - "d u", - "xi ao3", - "ji e2", - "ti an1", - "ch ang2", - "q uan2", - "li e4", - "h ai3", - "f ei1", - "t i3", - "ju e2", - "o u2", - "c i3", - "z u2", - "n i2", - "bi ao3", - "zhong1 guo2", - "d u4", - "yu e4", - "xi ng4", - "sh eng4", - "ch e1", - "d an1", - "ji e1", - "li n2", - "pi ng2", - "f u3", - "g u3", - "ji e4", - "w o", - "v 3", - "sh eng3", - "n a4", - "yu an4", - "zh ang3", - "gu an3", - "d ao3", - "z u3", - "di ng4", - "di an3", - "c eng2", - "ren2 kou3", - "t ai4", - "t ong1", - "g uo4", - "n eng2", - "ch ang3", - "hu a2", - "li u2", - "yi ng1", - "xi ao4", - "c i4", - "bian4 hua4", - "li ang3", - "g ong4", - "zho ng4", - "de5 yi1", - "s e4", - "k ai1", - "w ang2", - "ji u4", - "sh i1", - "sh ou4", - "m ei2", - "k u", - "s u", - "f eng1", - "z e2", - "tu2 shi4", - "t i2", - "q i4", - "ji u3", - "sh en1", - "zh e3", - "ren2kou3 bian4hua4", - "ren2kou3bian4hua4 tu2shi4", - "di4 qu1", - "y ang2", - "m en", - "men 5", - "l ong2", - "bi ng4", - "ch an3", - "zh u1", - "w ei3", - "w ai4", - "xi ng1", - "bo 1", - "b i3", - "t ang2", - "hu a1", - "bo 2", - "shu i3", - "sh u1", - "d ou1", - "s ai4", - "ch ao2", - "b i4", - "li ng2", - "l ei4", - "da4 xue2", - "f en4", - "shu3 de5", - "m u3", - "ji ao1", - "d ang1", - "ch eng1", - "t ong3", - "n v3", - "q i3", - "y an3", - "mi an4", - "l uo4", - "ji ng4", - "g e1", - "r u4", - "d an4", - "ri4 ben3", - "p u3", - "yu n4", - "hu ang2", - "wo 3", - "l v", - "h ai2", - "shi4 yi1", - "xi e1", - "yi ng3", - "w u2", - "sh en2", - "w ang3", - "gu ang3", - "li u4", - "s u4", - "shi4 zhen4", - "c an1", - "c ao3", - "xi a2", - "k a3", - "d a2", - "h u4", - "b an4", - "d ang3", - "h u2", - "z ong3", - "de ng3", - "de5yi2ge4 shi4zhen4", - "ch uan2", - "mo 4", - "zh ang1", - "b an1", - "mo 2", - "ch a2", - "c e4", - "zhu3 yao4", - "t ou2", - "j u2", - "shi4 wei4yu2", - "s a4", - "u n1", - "ke3 yi3", - "d u1", - "h an4", - "li ang4", - "sh a1", - "ji a3", - "z i1", - "lv 4", - "f u1", - "xi an1", - "x u4", - "gu ang1", - "m eng2", - "b ao4", - "yo u4", - "r ong2", - "zhi1 yi1", - "w ei1", - "m ao2", - "guo2 jia1", - "c ong2", - "g ou4", - "ti e3", - "zh en1", - "d u2", - "bi an1", - "c i2", - "q u3", - "f an4", - "xi ang3", - "m en2", - "j u1", - "h ong2", - "z i3", - "ta1 men5", - "ji 3", - "z ong1", - "zhou1 de5yi2ge4shi4zhen4", - "t uan2", - "ji ng3", - "gong1 si1", - "xi e4", - "l i2", - "li4 shi3", - "b ao1", - "g ang3", - "gu i1", - "zh eng1", - "zhi2 wu4", - "ta1 de5", - "pi n3", - "zhu an1", - "ch ong2", - "shi3 yong4", - "w a3", - "sh uo1", - "chu an1", - "l ei2", - "w an1", - "h uo2", - "q u", - "s u1", - "z ao3", - "g ai3", - "q u4", - "g u4", - "l u", - "x i2", - "h ang2", - "yi ng4", - "c un1", - "g en1", - "yi ng2", - "ti ng2", - "cheng2 shi4", - "ji ang3", - "li ng3", - "l un2", - "bu4 fen4", - "de ng1", - "xu an3", - "dong4 wu4", - "de2 guo2", - "xi an3", - "f an3", - "zh e5", - "h an2", - "h ao4", - "m i4", - "r an2", - "qi n1", - "ti ao2", - "zh an3", - "h i", - "k a", - "n o", - "t e", - "s u", - "s hi", - "t a", - "t o", - "n a", - "w a", - "o u", - "r u", - "n i", - "k u", - "k i", - "g a", - "d e", - "k o", - "m a", - "r e", - "r a", - "m o", - "t su", - "w o", - "e n", - "r i", - "s a", - "d a", - "s e", - "j i", - "h a", - "c hi", - "k e", - "te ki", - "m i", - "y ou", - "s h", - "s o", - "y o", - "y a", - "na i", - "t te", - "a ru", - "b a", - "u u", - "t ta", - "ka i", - "ka n", - "shi te", - "m e", - "d o", - "mo no", - "se i", - "r o", - "ko to", - "ka ra", - "shi ta", - "b u", - "m u", - "c h", - "su ru", - "k ou", - "g o", - "ma su", - "ta i", - "f u", - "k en", - "i u", - "g en", - "wa re", - "shi n", - "z u", - "a i", - "o n", - "o ku", - "g i", - "d ou", - "n e", - "y uu", - "i ru", - "i te", - "ji ko", - "de su", - "j u", - "ra re", - "sh u", - "b e", - "sh ou", - "s ha", - "se kai", - "s ou", - "k you", - "ma shita", - "s en", - "na ra", - "sa n", - "ke i", - "i ta", - "a ri", - "i tsu", - "ko no", - "j ou", - "na ka", - "ch ou", - "so re", - "g u", - "na ru", - "ga ku", - "re ba", - "g e", - "h o", - "i n", - "hi to", - "sa i", - "na n", - "da i", - "tsu ku", - "shi ki", - "sa re", - "na ku", - "p p", - "bu n", - "ju n", - "so no", - "ka ku", - "z ai", - "b i", - "to u", - "wa ta", - "sh uu", - "i i", - "te i", - "ka re", - "y u", - "shi i", - "ma de", - "sh o", - "a n", - "ke reba", - "shi ka", - "i chi", - "ha n", - "de ki", - "ni n", - "ware ware", - "na kereba", - "o ite", - "h ou", - "ya ku", - "ra i", - "mu jun", - "l e", - "yo ku", - "bu tsu", - "o o", - "ko n", - "o mo", - "ga e", - "nara nai", - "ta chi", - "z en", - "ch uu", - "kan gae", - "ta ra", - "to ki", - "ko ro", - "mujun teki", - "z e", - "na ga", - "ji n", - "shi ma", - "te n", - "i ki", - "i ku", - "no u", - "i masu", - "r ou", - "h on", - "ka e", - "t to", - "ko re", - "ta n", - "ki ta", - "i s", - "da tta", - "ji tsu", - "ma e", - "i e", - "me i", - "da n", - "h e", - "to ku", - "dou itsu", - "ri tsu", - "k yuu", - "h you", - "rare ta", - "kei sei", - "k kan", - "rare ru", - "m ou", - "do ko", - "r you", - "da ke", - "naka tta", - "so ko", - "ta be", - "e r", - "ha na", - "c o", - "fu ku", - "p a", - "so n", - "ya su", - "ch o", - "wata ku", - "ya ma", - "z a", - "k yo", - "gen zai", - "b oku", - "a ta", - "j a", - "ka wa", - "ma sen", - "j uu", - "ro n", - "b o", - "na tte", - "wataku shi", - "yo tte", - "ma i", - "g ou", - "ha i", - "mo n", - "ba n", - "ji shin", - "c a", - "re te", - "n en", - "o ka", - "ka gaku", - "na tta", - "p o", - "ka ru", - "na ri", - "m en", - "ma ta", - "e i", - "ku ru", - "ga i", - "ka ri", - "sha kai", - "kou i", - "yo ri", - "se tsu", - "j o", - "re ru", - "to koro", - "ju tsu", - "i on", - "sa ku", - "tta i", - "c ha", - "nin gen", - "n u", - "c e", - "ta me", - "kan kyou", - "de n", - "o oku", - "i ma", - "wata shi", - "tsuku ru", - "su gi", - "b en", - "ji bun", - "shi tsu", - "ke ru", - "ki n", - "ki shi", - "shika shi", - "mo to", - "ma ri", - "i tte", - "de shita", - "n de", - "ari masu", - "te r", - "z ou", - "ko e", - "ze ttai", - "kkan teki", - "h en", - "re kishi", - "deki ru", - "tsu ka", - "l a", - "i tta", - "o i", - "ko butsu", - "mi ru", - "sh oku", - "shi masu", - "gi jutsu", - "g you", - "jou shiki", - "a tta", - "ho do", - "ko ko", - "tsuku rareta", - "z oku", - "hi tei", - "ko ku", - "rekishi teki", - "ke te", - "o ri", - "i mi", - "ka ko", - "naga ra", - "ka karu", - "shu tai", - "ha ji", - "ma n", - "ta ku", - "ra n", - "douitsu teki", - "z o", - "me te", - "re i", - "tsu u", - "sare te", - "gen jitsu", - "p e", - "s t", - "ba i", - "na wa", - "ji kan", - "wa ru", - "r t", - "a tsu", - "so ku", - "koui teki", - "a ra", - "u ma", - "a no", - "i de", - "ka ta", - "te tsu", - "ga wa", - "ke do", - "re ta", - "mi n", - "sa you", - "tte ru", - "to ri", - "p u", - "ki mi", - "b ou", - "mu ra", - "sare ru", - "ma chi", - "k ya", - "o sa", - "kon na", - "a ku", - "a l", - "sare ta", - "i pp", - "shi ku", - "u chi", - "hito tsu", - "ha tara", - "tachi ba", - "shi ro", - "ka tachi", - "to mo", - "e te", - "me ru", - "ni chi", - "da re", - "ka tta", - "e ru", - "su ki", - "a ge", - "oo ki", - "ma ru", - "mo ku", - "o ko", - "kangae rareru", - "o to", - "tan ni", - "ta da", - "tai teki", - "mo tte", - "ki nou", - "shi nai", - "k ki", - "u e", - "ta ri", - "l i", - "ra nai", - "k kou", - "mi rai", - "pp on", - "go to", - "hi n", - "hi tsu", - "te ru", - "mo chi", - "ka tsu", - "re n", - "n yuu", - "su i", - "zu ka", - "tsu ite", - "no mi", - "su gu", - "ku da", - "tetsu gaku", - "i ka", - "ron ri", - "o ki", - "ni ppon", - "p er", - "shi mashita", - "chi shiki", - "cho kkanteki", - "su ko", - "t ion", - "ku u", - "a na", - "a rou", - "ka tte", - "ku ri", - "i nai", - "hyou gen", - "i shiki", - "do ku", - "a tte", - "a tara", - "to n", - "wa ri", - "ka o", - "sei san", - "hana shi", - "s i", - "ka ke", - "na ji", - "su nawa", - "sunawa chi", - "u go", - "su u", - "ba ra", - "le v", - "hi ro", - "i wa", - "be tsu", - "yo i", - "se ru", - "shite ru", - "rare te", - "to shi", - "se ki", - "tai ritsu", - "wa kara", - "to kyo", - "k ka", - "k yoku", - "u n", - "i ro", - "mi te", - "sa ki", - "kan ji", - "mi ta", - "su be", - "r yoku", - "ma tta", - "kuda sai", - "omo i", - "ta no", - "ware ru", - "co m", - "hitsu you", - "ka shi", - "re nai", - "kan kei", - "a to", - "ga tte", - "o chi", - "mo tsu", - "in g", - "son zai", - "l l", - "o re", - "tai shite", - "a me", - "sei mei", - "ka no", - "gi ri", - "kangae ru", - "yu e", - "a sa", - "o naji", - "yo ru", - "ni ku", - "osa ka", - "suko shi", - "c k", - "ta ma", - "kano jo", - "ki te", - "mon dai", - "a mari", - "e ki", - "ko jin", - "ha ya", - "i t", - "de te", - "atara shii", - "a wa", - "ga kkou", - "tsu zu", - "shu kan", - "i mashita", - "mi na", - "ata e", - "da rou", - "hatara ku", - "ga ta", - "da chi", - "ma tsu", - "ari masen", - "sei butsu", - "mi tsu", - "he ya", - "yasu i", - "d i", - "de ni", - "no ko", - "ha ha", - "do mo", - "ka mi", - "su deni", - "na o", - "ra ku", - "i ke", - "a ki", - "me ta", - "l o", - "ko domo", - "so shite", - "ga me", - "ba kari", - "to te", - "ha tsu", - "mi se", - "moku teki", - "da kara", - "s z", - "e l", - "g y", - "e n", - "t t", - "e m", - "a n", - "a k", - "e r", - "a z", - "a l", - "e t", - "o l", - "e g", - "e k", - "m i", - "o n", - "é s", - "c s", - "a t", - "á r", - "h o", - "e z", - "á l", - "i s", - "á n", - "o r", - "a r", - "e gy", - "e s", - "é r", - "á t", - "o tt", - "e tt", - "m eg", - "t a", - "o k", - "o s", - "ho gy", - "n em", - "é g", - "n y", - "k i", - "é l", - "h a", - "á s", - "ü l", - "i n", - "mi n", - "n a", - "e d", - "o m", - "i k", - "k ö", - "m a", - "n i", - "v a", - "v ol", - "é t", - "b b", - "f el", - "i g", - "l e", - "r a", - "é n", - "t e", - "d e", - "a d", - "ó l", - "b e", - "on d", - "j a", - "r e", - "u l", - "b en", - "n ek", - "u t", - "vol t", - "b an", - "ö r", - "o g", - "a p", - "o d", - "á g", - "n k", - "é k", - "v al", - "k or", - "a m", - "i l", - "í t", - "á k", - "b a", - "u d", - "sz er", - "min d", - "o z", - "é p", - "el l", - "ér t", - "m ond", - "i t", - "sz t", - "n ak", - "a mi", - "n e", - "ő l", - "cs ak", - "n é", - "ma g", - "ol y", - "m er", - "ál l", - "án y", - "ö n", - "ö l", - "min t", - "m ár", - "ö tt", - "na gy", - "é sz", - "az t", - "el ő", - "t ud", - "o t", - "é ny", - "á z", - "m ég", - "kö z", - "el y", - "s ég", - "en t", - "s em", - "ta m", - "h et", - "h al", - "f i", - "a s", - "v an", - "ho z", - "v e", - "u k", - "k ez", - "á m", - "v el", - "b er", - "a j", - "u nk", - "i z", - "va gy", - "m os", - "sz em", - "em ber", - "f og", - "mer t", - "ü k", - "l en", - "ö s", - "e j", - "t al", - "h at", - "t ak", - "h i", - "m ás", - "s ág", - "ett e", - "l eg", - "ü nk", - "h át", - "sz a", - "on y", - "ez t", - "mind en", - "en d", - "ül t", - "h an", - "j ó", - "k is", - "á j", - "in t", - "ú gy", - "i d", - "mos t", - "ar t", - "í r", - "k er", - "i tt", - "a tt", - "el t", - "mond ta", - "k ell", - "l á", - "ak i", - "ál t", - "ér d", - "t ö", - "l an", - "v ár", - "h ol", - "t el", - "l át", - "ő k", - "v et", - "s e", - "ut án", - "k ét", - "na p", - "í v", - "ál y", - "v ég", - "ö k", - "i r", - "d ul", - "v is", - "né z", - "t er", - "á ban", - "k ül", - "ak kor", - "k ap", - "sz él", - "y en", - "ú j", - "i m", - "oly an", - "es en", - "k ed", - "h ely", - "t ör", - "b ól", - "el m", - "r á", - "ár a", - "r ó", - "l ó", - "vol na", - "t an", - "le het", - "e bb", - "t en", - "t ek", - "s ok", - "k al", - "f or", - "u g", - "ol t", - "k a", - "ek et", - "b or", - "f ej", - "g ond", - "a g", - "ak ar", - "f él", - "ú l", - "b el", - "ott a", - "mi t", - "val ami", - "j el", - "é d", - "ar c", - "u r", - "hal l", - "t i", - "f öl", - "á ba", - "ol g", - "ki r", - "ol d", - "m ar", - "k érd", - "j ár", - "ú r", - "sz e", - "z s", - "él et", - "j át", - "o v", - "u s", - "é z", - "v il", - "v er", - "ő r", - "á d", - "ö g", - "le sz", - "on t", - "b iz", - "k oz", - "á bb", - "kir ály", - "es t", - "a b", - "en g", - "ig az", - "b ar", - "ha j", - "d i", - "o b", - "k od", - "r ól", - "v ez", - "tö bb", - "sz ó", - "é ben", - "ö t", - "ny i", - "t á", - "sz ól", - "gond ol", - "eg ész", - "í gy", - "ő s", - "o bb", - "os an", - "b ől", - "a bb", - "c i", - "ő t", - "n ál", - "k ép", - "azt án", - "v i", - "t art", - "be szél", - "m en", - "elő tt", - "a szt", - "ma j", - "kö r", - "han g", - "í z", - "in cs", - "a i", - "é v", - "ó d", - "ó k", - "hoz z", - "t em", - "ok at", - "an y", - "nagy on", - "h áz", - "p er", - "p ed", - "ez te", - "et len", - "nek i", - "maj d", - "sz ony", - "án ak", - "fel é", - "egy szer", - "j e", - "ad t", - "gy er", - "ami kor", - "f oly", - "sz ak", - "ő d", - "h ú", - "á sz", - "am ely", - "h ar", - "ér e", - "il yen", - "od a", - "j ák", - "t ár", - "á val", - "l ak", - "t ó", - "m ent", - "gy an", - "él y", - "ú t", - "v ar", - "kez d", - "m ell", - "mi kor", - "h ez", - "val ó", - "k o", - "m es", - "szer et", - "r end", - "l et", - "vis sza", - "ig en", - "f ő", - "va s", - "as szony", - "r ől", - "ped ig", - "p i", - "sz ép", - "t ák", - "ö v", - "an i", - "vil ág", - "p en", - "mag a", - "t et", - "sz ik", - "é j", - "én t", - "j ött", - "s an", - "sz í", - "i de", - "g at", - "ett em", - "ul t", - "h ány", - "ás t", - "a hol", - "ők et", - "h ár", - "k el", - "n ő", - "cs i", - "tal ál", - "el te", - "lá tt", - "tör t", - "ha gy", - "e sz", - "s en", - "n él", - "p ar", - "v ál", - "k ut", - "l ány", - "ami t", - "s ő", - "ell en", - "mag át", - "in k", - "u gyan", - "kül ön", - "a sz", - "mind ig", - "l ép", - "tal án", - "u n", - "sz or", - "k e", - "il lan", - "n incs", - "z et", - "vagy ok", - "tel en", - "is mer", - "s or", - "is ten", - "ít ott", - "j obb", - "v es", - "dul t", - "j uk", - "sz en", - "r o", - "ö m", - "l ett", - "k ar", - "egy ik", - "b ár", - "sz i", - "sz ív", - "az on", - "e szt", - "föl d", - "kut y", - "p illan", - "f ér", - "k om", - "t ől", - "t ű", - "é be", - "t ött", - "bar át", - "í g", - "a hogy", - "e h", - "e p", - "s o", - "v en", - "jel ent", - "t at", - "sz eg", - "mint ha", - "f al", - "egy en", - "mi l", - "sza b", - "r i", - "é m", - "biz ony", - "j on", - "ör eg", - "d olg", - "cs ap", - "ti szt", - "áll t", - "an cs", - "id ő", - "k at", - "ü gy", - "mi ért", - "ó t", - "ü r", - "cs in", - "h az", - "b et", - "én ek", - "v ér", - "j ól", - "al att", - "m ely", - "l o", - "sem mi", - "ny ug", - "v ág", - "kö vet", - "ös sze", - "ma d", - "l i", - "a cs", - "fi ú", - "kö n", - "más ik", - "j ön", - "sz ám", - "g er", - "s ó", - "r ész", - "k ér", - "z el", - "é vel", - "e o", - "e u", - "a n", - "eu l", - "eu n", - "eo n", - "a e", - "d a", - "a l", - "s s", - "i n", - "i l", - "a g", - "an g", - "y eon", - "y eo", - "d o", - "c h", - "n g", - "j i", - "h an", - "g a", - "g o", - "u i", - "h ae", - "a m", - "u l", - "u n", - "g eo", - "s i", - "n eun", - "ss da", - "s eo", - "eon g", - "y o", - "i da", - "t t", - "k k", - "j eo", - "d eul", - "w a", - "eu m", - "g e", - "o n", - "o g", - "s al", - "m an", - "yeon g", - "geo s", - "h ag", - "an eun", - "j a", - "g i", - "s u", - "i ss", - "o l", - "d ae", - "eo b", - "h a", - "j u", - "eo l", - "g eu", - "j eong", - "s ae", - "do e", - "g eul", - "s eu", - "s in", - "eul o", - "b n", - "s ang", - "bn ida", - "h al", - "b o", - "han eun", - "m al", - "i m", - "m o", - "b u", - "jeo g", - "sae ng", - "in eun", - "an h", - "m a", - "sal am", - "j o", - "s a", - "eo m", - "n ae", - "w i", - "l o", - "g wa", - "yeo l", - "n a", - "e seo", - "y e", - "m yeon", - "tt ae", - "h w", - "j e", - "eob s", - "j ang", - "g u", - "g w", - "il eul", - "yeo g", - "j eon", - "si g", - "j ag", - "j in", - "y u", - "o e", - "s e", - "hag o", - "d eun", - "y a", - "m un", - "s eong", - "g ag", - "h am", - "d ang", - "b a", - "l eul", - "s il", - "do ng", - "kk a", - "b al", - "da l", - "han da", - "eo ssda", - "ae g", - "l i", - "ha ji", - "s eon", - "o ng", - "hae ssda", - "d e", - "i ssda", - "e ge", - "b un", - "m ul", - "ju ng", - "ji g", - "m u", - "iss neun", - "b i", - "g eun", - "seu bnida", - "w on", - "p p", - "d aneun", - "eo h", - "d eo", - "ga m", - "j al", - "hae ng", - "ag o", - "y ang", - "b ul", - "b ang", - "u m", - "s o", - "h i", - "j ae", - "si m", - "saeng gag", - "hag e", - "s og", - "eo ss", - "d an", - "ja sin", - "j il", - "eo g", - "g yeong", - "doe n", - "go ng", - "m i", - "ch i", - "d eu", - "d eon", - "hae ss", - "d u", - "n am", - "eun g", - "jo h", - "n al", - "m yeong", - "w o", - "eon a", - "i go", - "g yeol", - "y ag", - "gw an", - "ul i", - "yo ng", - "n o", - "l yeo", - "j og", - "eoh ge", - "ga t", - "b og", - "mo s", - "t ong", - "ch a", - "man h", - "jeo l", - "geo l", - "h oe", - "ag a", - "n aneun", - "g an", - "un eun", - "ch eol", - "ch e", - "do l", - "b on", - "b an", - "ba d", - "ch u", - "ham yeon", - "yeo ssda", - "i bnida", - "g ye", - "eo s", - "hw al", - "salam deul", - "ji man", - "dang sin", - "ji b", - "ttae mun", - "m ae", - "i b", - "e neun", - "eu g", - "jeo m", - "geul eon", - "h wa", - "a ssda", - "b eob", - "bu t", - "b ae", - "yeo ss", - "ch in", - "ch aeg", - "g eon", - "g ae", - "nae ga", - "i ga", - "m og", - "sig an", - "g il", - "h yeon", - "l yeog", - "gu g", - "p yeon", - "s an", - "w ae", - "j ul", - "s eul", - "deun g", - "haji man", - "eum yeon", - "p il", - "m ol", - "n eu", - "a ss", - "n yeon", - "t ae", - "h u", - "p yo", - "s ul", - "g ang", - "j ineun", - "b eon", - "ha da", - "seo l", - "si p", - "dal eun", - "a p", - "sal m", - "g yo", - "ch eon", - "hag i", - "in a", - "cheol eom", - "g al", - "il a", - "kka ji", - "anh neun", - "ha bnida", - "tt eon", - "n u", - "hae seo", - "doen da", - "s ol", - "tt al", - "l a", - "il o", - "seu b", - "b yeon", - "m yeo", - "b eol", - "s on", - "n un", - "j un", - "j am", - "j eung", - "tt o", - "e n", - "mo m", - "h o", - "ch im", - "hw ang", - "eun eun", - "jo ng", - "bo da", - "n ol", - "n eom", - "but eo", - "jig eum", - "eobs da", - "dae lo", - "i g", - "y ul", - "p yeong", - "seon eun", - "sal ang", - "seu t", - "h im", - "n an", - "h eom", - "h yang", - "p i", - "gw ang", - "eobs neun", - "hw ag", - "ge ss", - "jag i", - "il eon", - "wi hae", - "dae han", - "ga ji", - "m eog", - "j yeo", - "cha j", - "b yeong", - "eo d", - "g yeo", - "do n", - "eo ji", - "g ul", - "mo deun", - "j on", - "in saeng", - "geul ae", - "h ang", - "sa sil", - "si b", - "ch al", - "il ago", - "doe l", - "g eum", - "doe neun", - "b ol", - "ga jang", - "geul igo", - "e l", - "h yeong", - "haeng bog", - "ch ul", - "h on", - "ch ae", - "s am", - "m ang", - "in da", - "da m", - "w ol", - "ch oe", - "d ul", - "si jag", - "ch eong", - "il aneun", - "ul ineun", - "ae n", - "kk e", - "mun je", - "a do", - "t eu", - "g un", - "geun eun", - "b ge", - "ch eo", - "b aeg", - "ju g", - "t a", - "sang dae", - "geu geos", - "do g", - "eu s", - "deu s", - "ja b", - "h yeo", - "tt eohge", - "u g", - "ma j", - "ch il", - "s wi", - "j ileul", - "ch ang", - "g aneun", - "m ag", - "i ji", - "da go", - "m in", - "yo han", - "t eug", - "pp un", - "al eul", - "haeng dong", - "p o", - "m il", - "ch am", - "se sang", - "e do", - "p an", - "man deul", - "am yeon", - "a b", - "kk ae", - "b ag", - "i deul", - "p um", - "m eol", - "s un", - "n eul", - "ham kke", - "chu ng", - "da b", - "yu g", - "s ag", - "gwang ye", - "il eohge", - "bal o", - "neun de", - "ham yeo", - "go s", - "geul eoh", - "an ila", - "bang beob", - "da si", - "b yeol", - "g yeon", - "gam jeong", - "on eul", - "j aneun", - "yeo m", - "l ago", - "i gi", - "hw an", - "t eul", - "eo seo", - "si k", - "ch o", - "jag a", - "geul eom", - "geul eona", - "jeong do", - "g yeog", - "geul eohge", - "geu deul", - "eu t", - "im yeon", - "j jae", - "k eun", - "i sang", - "mal haessda", - "eu ge", - "no p", - "in gan", - "bo myeon", - "t aeg", - "seu s", - "d wi", - "s aneun", - "w an", - "anh go", - "t an", - "nu gu", - "su ng", - "da myeon", - "a deul", - "p eul", - "ttal a", - "d i", - "geos do", - "a ji", - "m eon", - "eum yeo", - "dol og", - "neun g", - "mo du", - "क े", - "ह ै", - "े ं", - "् र", - "ा र", - "न े", - "य ा", - "म ें", - "स े", - "क ी", - "क ा", - "ो ं", - "त ा", - "क र", - "स ्", - "क ि", - "क ो", - "र ्", - "न ा", - "क ्", - "ह ी", - "औ र", - "प र", - "त े", - "ह ो", - "प ्र", - "ा न", - "् य", - "ल ा", - "व ा", - "ल े", - "स ा", - "है ं", - "ल ि", - "ज ा", - "ह ा", - "भ ी", - "व ि", - "इ स", - "त ी", - "न ्", - "र ा", - "म ा", - "द े", - "द ि", - "ब ा", - "त ि", - "थ ा", - "न ि", - "क ार", - "ए क", - "ही ं", - "ह ु", - "ं ग", - "ै ं", - "न ी", - "स ी", - "अ प", - "त ्", - "न हीं", - "र ी", - "म े", - "म ु", - "ि त", - "त ो", - "प ा", - "ल ी", - "लि ए", - "ग ा", - "ल ्", - "र ह", - "र े", - "क् ष", - "म ैं", - "स म", - "उ स", - "ज ि", - "त ्र", - "म ि", - "च ा", - "ो ग", - "स ं", - "द ्", - "स ि", - "आ प", - "त ु", - "द ा", - "क ु", - "य ों", - "व े", - "ज ी", - "् या", - "उ न", - "ि क", - "य े", - "भ ा", - "् ट", - "ह म", - "स् ट", - "श ा", - "ड ़", - "ं द", - "ख ा", - "म ्", - "श ्", - "य ह", - "स क", - "प ू", - "कि या", - "अप ने", - "र ू", - "स ु", - "म ी", - "ह ि", - "ज ो", - "थ े", - "र ि", - "द ी", - "थ ी", - "ग ी", - "ल ोग", - "ग या", - "त र", - "न् ह", - "च ्", - "व ार", - "ब ी", - "प ्", - "द ो", - "ट ी", - "श ि", - "कर ने", - "ग े", - "ै से", - "इ न", - "ं ड", - "सा थ", - "प ु", - "ब े", - "ब ार", - "व ी", - "अ न", - "ह र", - "उ न्ह", - "हो ता", - "ज ब", - "कु छ", - "म ान", - "क ्र", - "ब ि", - "प ह", - "फ ि", - "स र", - "ार ी", - "र ो", - "द ू", - "क हा", - "त क", - "श न", - "ब ्", - "स् थ", - "व ह", - "बा द", - "ओ ं", - "ग ु", - "ज ्", - "्र े", - "ग र", - "रह े", - "व र्", - "ह ू", - "ार ्", - "प ी", - "ब हु", - "मु झ", - "्र ा", - "दि या", - "स ब", - "कर ते", - "अप नी", - "बहु त", - "क ह", - "ट े", - "हु ए", - "कि सी", - "र हा", - "ष ्ट", - "ज ़", - "ब ना", - "स ो", - "ड ि", - "को ई", - "व ्य", - "बा त", - "र ु", - "व ो", - "मुझ े", - "द् ध", - "च ार", - "मे रे", - "व र", - "्र ी", - "जा ता", - "न ों", - "प्र ा", - "दे ख", - "ट ा", - "क् या", - "अ ध", - "ल ग", - "ल ो", - "प ि", - "य ु", - "च े", - "जि स", - "ं त", - "ान ी", - "प ै", - "ज न", - "ार े", - "च ी", - "मि ल", - "द ु", - "दे श", - "च् छ", - "ष ्", - "स ू", - "ख े", - "च ु", - "ि या", - "ल गा", - "ब ु", - "उन के", - "ज् ञ", - "क्ष ा", - "त रह", - "्या दा", - "वा ले", - "पू र्", - "मैं ने", - "का म", - "रू प", - "हो ती", - "उ प", - "ज ान", - "प्र कार", - "भ ार", - "म न", - "हु आ", - "ट र", - "हू ँ", - "पर ि", - "पा स", - "अन ु", - "रा ज", - "लोग ों", - "अ ब", - "सम झ", - "ड ी", - "म ौ", - "श ु", - "च ि", - "प े", - "क ृ", - "सक ते", - "म ह", - "य ोग", - "द र्", - "उ से", - "ं ध", - "ड ा", - "जा ए", - "ब ो", - "ू ल", - "म ो", - "ों ने", - "ं स", - "तु म", - "पह ले", - "ब ता", - "त था", - "य ो", - "ग ई", - "उ त्", - "सक ता", - "क म", - "ज ्यादा", - "र ख", - "सम य", - "ार ा", - "अ गर", - "स् त", - "च ल", - "फि र", - "वार ा", - "कर ना", - "श ी", - "ग ए", - "ब न", - "ौ र", - "हो ने", - "चा ह", - "ख ु", - "हा ँ", - "उन्ह ें", - "उन्ह ोंने", - "छ ो", - "म् ह", - "प्र ति", - "नि क", - "व न", - "्य ू", - "र ही", - "तु म्ह", - "ज ैसे", - "ि यों", - "क् यों", - "ल ों", - "फ ़", - "ं त्र", - "हो ते", - "क् ति", - "त ्य", - "कर ्", - "क ई", - "व ं", - "कि न", - "प ो", - "कार ण", - "ड़ ी", - "भ ि", - "इस के", - "ब र", - "उस के", - "द् वारा", - "श े", - "क ॉ", - "दि न", - "न् न", - "ड़ ा", - "स् व", - "नि र्", - "मु ख", - "लि या", - "ट ि", - "ज्ञ ान", - "क् त", - "द ्र", - "ग ्", - "क् स", - "म ै", - "ग ो", - "ज े", - "ट ्र", - "म ार", - "त् व", - "ध ार", - "भा व", - "कर ता", - "ख ि", - "क ं", - "चा हि", - "य र", - "प् त", - "क ों", - "ं च", - "ज ु", - "म त", - "अ च्छ", - "हु ई", - "क भी", - "ले किन", - "भ ू", - "अप ना", - "दू स", - "चाहि ए", - "य ू", - "घ र", - "सब से", - "मे री", - "ना म", - "ढ ़", - "ं ट", - "ें गे", - "ब ै", - "फ ा", - "ए वं", - "य ी", - "ग ्र", - "क्ष े", - "आ ज", - "आप को", - "भा ग", - "ठ ा", - "क ै", - "भार त", - "उन की", - "प हु", - "स भी", - "ध ा", - "ण ा", - "स ान", - "हो गा", - "त ब", - "स ंग", - "प र्", - "अ व", - "त ना", - "ग ि", - "य न", - "स् था", - "च ित", - "ट ्", - "छ ा", - "जा ने", - "क्षे त्र", - "वा ली", - "पूर् ण", - "स मा", - "कार ी" - ] - } -} \ No newline at end of file diff --git a/models/lyrics_utils/zh_num2words.py b/models/lyrics_utils/zh_num2words.py deleted file mode 100644 index 8029b153499e8ebf7e7278ec20803435207cecc2..0000000000000000000000000000000000000000 --- a/models/lyrics_utils/zh_num2words.py +++ /dev/null @@ -1,1209 +0,0 @@ -# Authors: -# 2019.5 Zhiyang Zhou (https://github.com/Joee1995/chn_text_norm.git) -# 2019.9 - 2022 Jiayu DU -#copy from https://github.com/coqui-ai/TTS/blob/dbf1a08a0d4e47fdad6172e433eeb34bc6b13b4e/TTS/tts/layers/xtts/zh_num2words.py -import argparse -import csv -import os -import re -import string -import sys - -# fmt: off - -# ================================================================================ # -# basic constant -# ================================================================================ # -CHINESE_DIGIS = "零一二三四五六七八九" -BIG_CHINESE_DIGIS_SIMPLIFIED = "零壹贰叁肆伍陆柒捌玖" -BIG_CHINESE_DIGIS_TRADITIONAL = "零壹貳參肆伍陸柒捌玖" -SMALLER_BIG_CHINESE_UNITS_SIMPLIFIED = "十百千万" -SMALLER_BIG_CHINESE_UNITS_TRADITIONAL = "拾佰仟萬" -LARGER_CHINESE_NUMERING_UNITS_SIMPLIFIED = "亿兆京垓秭穰沟涧正载" -LARGER_CHINESE_NUMERING_UNITS_TRADITIONAL = "億兆京垓秭穰溝澗正載" -SMALLER_CHINESE_NUMERING_UNITS_SIMPLIFIED = "十百千万" -SMALLER_CHINESE_NUMERING_UNITS_TRADITIONAL = "拾佰仟萬" - -ZERO_ALT = "〇" -ONE_ALT = "幺" -TWO_ALTS = ["两", "兩"] - -POSITIVE = ["正", "正"] -NEGATIVE = ["负", "負"] -POINT = ["点", "點"] -# PLUS = [u'加', u'加'] -# SIL = [u'杠', u'槓'] - -FILLER_CHARS = ["呃", "啊"] - -ER_WHITELIST = ( - "(儿女|儿子|儿孙|女儿|儿媳|妻儿|" - "胎儿|婴儿|新生儿|婴幼儿|幼儿|少儿|小儿|儿歌|儿童|儿科|托儿所|孤儿|" - "儿戏|儿化|台儿庄|鹿儿岛|正儿八经|吊儿郎当|生儿育女|托儿带女|养儿防老|痴儿呆女|" - "佳儿佳妇|儿怜兽扰|儿无常父|儿不嫌母丑|儿行千里母担忧|儿大不由爷|苏乞儿)" -) -ER_WHITELIST_PATTERN = re.compile(ER_WHITELIST) - -# 中文数字系统类型 -NUMBERING_TYPES = ["low", "mid", "high"] - -CURRENCY_NAMES = "(人民币|美元|日元|英镑|欧元|马克|法郎|加拿大元|澳元|港币|先令|芬兰马克|爱尔兰镑|" "里拉|荷兰盾|埃斯库多|比塞塔|印尼盾|林吉特|新西兰元|比索|卢布|新加坡元|韩元|泰铢)" -CURRENCY_UNITS = "((亿|千万|百万|万|千|百)|(亿|千万|百万|万|千|百|)元|(亿|千万|百万|万|千|百|)块|角|毛|分)" -COM_QUANTIFIERS = ( - "(匹|张|座|回|场|尾|条|个|首|阙|阵|网|炮|顶|丘|棵|只|支|袭|辆|挑|担|颗|壳|窠|曲|墙|群|腔|" - "砣|座|客|贯|扎|捆|刀|令|打|手|罗|坡|山|岭|江|溪|钟|队|单|双|对|出|口|头|脚|板|跳|枝|件|贴|" - "针|线|管|名|位|身|堂|课|本|页|家|户|层|丝|毫|厘|分|钱|两|斤|担|铢|石|钧|锱|忽|(千|毫|微)克|" - "毫|厘|分|寸|尺|丈|里|寻|常|铺|程|(千|分|厘|毫|微)米|撮|勺|合|升|斗|石|盘|碗|碟|叠|桶|笼|盆|" - "盒|杯|钟|斛|锅|簋|篮|盘|桶|罐|瓶|壶|卮|盏|箩|箱|煲|啖|袋|钵|年|月|日|季|刻|时|周|天|秒|分|旬|" - "纪|岁|世|更|夜|春|夏|秋|冬|代|伏|辈|丸|泡|粒|颗|幢|堆|条|根|支|道|面|片|张|颗|块)" -) - - -# Punctuation information are based on Zhon project (https://github.com/tsroten/zhon.git) -CN_PUNCS_STOP = "!?。。" -CN_PUNCS_NONSTOP = ""#$%&'()*+,-/:;<=>@[\]^_`{|}~⦅⦆「」、、〃《》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏·〈〉-" -CN_PUNCS = CN_PUNCS_STOP + CN_PUNCS_NONSTOP - -PUNCS = CN_PUNCS + string.punctuation -PUNCS_TRANSFORM = str.maketrans(PUNCS, "," * len(PUNCS), "") # replace puncs with English comma - - -# https://zh.wikipedia.org/wiki/全行和半行 -QJ2BJ = { - " ": " ", - "!": "!", - """: '"', - "#": "#", - "$": "$", - "%": "%", - "&": "&", - "'": "'", - "(": "(", - ")": ")", - "*": "*", - "+": "+", - ",": ",", - "-": "-", - ".": ".", - "/": "/", - "0": "0", - "1": "1", - "2": "2", - "3": "3", - "4": "4", - "5": "5", - "6": "6", - "7": "7", - "8": "8", - "9": "9", - ":": ":", - ";": ";", - "<": "<", - "=": "=", - ">": ">", - "?": "?", - "@": "@", - "A": "A", - "B": "B", - "C": "C", - "D": "D", - "E": "E", - "F": "F", - "G": "G", - "H": "H", - "I": "I", - "J": "J", - "K": "K", - "L": "L", - "M": "M", - "N": "N", - "O": "O", - "P": "P", - "Q": "Q", - "R": "R", - "S": "S", - "T": "T", - "U": "U", - "V": "V", - "W": "W", - "X": "X", - "Y": "Y", - "Z": "Z", - "[": "[", - "\": "\\", - "]": "]", - "^": "^", - "_": "_", - "`": "`", - "a": "a", - "b": "b", - "c": "c", - "d": "d", - "e": "e", - "f": "f", - "g": "g", - "h": "h", - "i": "i", - "j": "j", - "k": "k", - "l": "l", - "m": "m", - "n": "n", - "o": "o", - "p": "p", - "q": "q", - "r": "r", - "s": "s", - "t": "t", - "u": "u", - "v": "v", - "w": "w", - "x": "x", - "y": "y", - "z": "z", - "{": "{", - "|": "|", - "}": "}", - "~": "~", -} -QJ2BJ_TRANSFORM = str.maketrans("".join(QJ2BJ.keys()), "".join(QJ2BJ.values()), "") - - -# 2013 China National Standard: https://zh.wikipedia.org/wiki/通用规范汉字表, raw resources: -# https://github.com/mozillazg/pinyin-data/blob/master/kMandarin_8105.txt with 8105 chinese chars in total -CN_CHARS_COMMON = ( - "一丁七万丈三上下不与丏丐丑专且丕世丘丙业丛东丝丞丢两严丧个丫中丰串临丸丹为主丽举" - "乂乃久么义之乌乍乎乏乐乒乓乔乖乘乙乜九乞也习乡书乩买乱乳乸乾了予争事二亍于亏云互" - "亓五井亘亚些亟亡亢交亥亦产亨亩享京亭亮亲亳亵亶亸亹人亿什仁仂仃仄仅仆仇仉今介仍从" - "仑仓仔仕他仗付仙仝仞仟仡代令以仨仪仫们仰仲仳仵件价任份仿企伈伉伊伋伍伎伏伐休众优" - "伙会伛伞伟传伢伣伤伥伦伧伪伫伭伯估伲伴伶伸伺似伽伾佁佃但位低住佐佑体何佖佗佘余佚" - "佛作佝佞佟你佣佤佥佩佬佯佰佳佴佶佸佺佻佼佽佾使侁侂侃侄侈侉例侍侏侑侔侗侘供依侠侣" - "侥侦侧侨侩侪侬侮侯侴侵侹便促俄俅俊俍俎俏俐俑俗俘俙俚俜保俞俟信俣俦俨俩俪俫俭修俯" - "俱俳俵俶俸俺俾倌倍倏倒倓倔倕倘候倚倜倞借倡倥倦倧倨倩倪倬倭倮倴债倻值倾偁偃假偈偌" - "偎偏偓偕做停偡健偬偭偰偲偶偷偻偾偿傀傃傅傈傉傍傒傕傣傥傧储傩催傲傺傻僇僎像僔僖僚" - "僦僧僬僭僮僰僳僵僻儆儇儋儒儡儦儳儴儿兀允元兄充兆先光克免兑兔兕兖党兜兢入全八公六" - "兮兰共关兴兵其具典兹养兼兽冀冁内冈冉册再冏冒冔冕冗写军农冠冢冤冥冬冮冯冰冱冲决况" - "冶冷冻冼冽净凄准凇凉凋凌减凑凓凘凛凝几凡凤凫凭凯凰凳凶凸凹出击凼函凿刀刁刃分切刈" - "刊刍刎刑划刖列刘则刚创初删判刨利别刬刭刮到刳制刷券刹刺刻刽刿剀剁剂剃剅削剋剌前剐" - "剑剔剕剖剜剞剟剡剥剧剩剪副割剽剿劁劂劄劈劐劓力劝办功加务劢劣动助努劫劬劭励劲劳劼" - "劾势勃勇勉勋勍勐勒勔勖勘勚募勠勤勰勺勾勿匀包匆匈匍匏匐匕化北匙匜匝匠匡匣匦匪匮匹" - "区医匼匾匿十千卅升午卉半华协卑卒卓单卖南博卜卞卟占卡卢卣卤卦卧卫卬卮卯印危即却卵" - "卷卸卺卿厂厄厅历厉压厌厍厕厖厘厚厝原厢厣厥厦厨厩厮去厾县叁参叆叇又叉及友双反发叔" - "叕取受变叙叚叛叟叠口古句另叨叩只叫召叭叮可台叱史右叵叶号司叹叻叼叽吁吃各吆合吉吊" - "同名后吏吐向吒吓吕吖吗君吝吞吟吠吡吣否吧吨吩含听吭吮启吱吲吴吵吸吹吻吼吽吾呀呃呆" - "呇呈告呋呐呒呓呔呕呖呗员呙呛呜呢呣呤呦周呱呲味呵呶呷呸呻呼命咀咂咄咆咇咉咋和咍咎" - "咏咐咒咔咕咖咙咚咛咝咡咣咤咥咦咧咨咩咪咫咬咯咱咳咴咸咺咻咽咿哀品哂哃哄哆哇哈哉哌" - "响哎哏哐哑哒哓哔哕哗哙哚哝哞哟哢哥哦哧哨哩哪哭哮哱哲哳哺哼哽哿唁唆唇唉唏唐唑唔唛" - "唝唠唢唣唤唧唪唬售唯唰唱唳唵唷唼唾唿啁啃啄商啉啊啐啕啖啜啡啤啥啦啧啪啫啬啭啮啰啴" - "啵啶啷啸啻啼啾喀喁喂喃善喆喇喈喉喊喋喏喑喔喘喙喜喝喟喤喧喱喳喵喷喹喻喽喾嗄嗅嗉嗌" - "嗍嗐嗑嗒嗓嗔嗖嗜嗝嗞嗟嗡嗣嗤嗥嗦嗨嗪嗫嗬嗯嗲嗳嗵嗷嗽嗾嘀嘁嘈嘉嘌嘎嘏嘘嘚嘛嘞嘟嘡" - "嘣嘤嘧嘬嘭嘱嘲嘴嘶嘹嘻嘿噀噂噇噌噍噎噔噗噘噙噜噢噤器噩噪噫噬噱噶噻噼嚄嚅嚆嚎嚏嚓" - "嚚嚣嚭嚯嚷嚼囊囔囚四回囟因囡团囤囫园困囱围囵囷囹固国图囿圃圄圆圈圉圊圌圐圙圜土圢" - "圣在圩圪圫圬圭圮圯地圲圳圹场圻圾址坂均坉坊坋坌坍坎坏坐坑坒块坚坛坜坝坞坟坠坡坤坥" - "坦坨坩坪坫坬坭坯坰坳坷坻坼坽垂垃垄垆垈型垌垍垎垏垒垓垕垙垚垛垞垟垠垡垢垣垤垦垧垩" - "垫垭垮垯垱垲垴垵垸垺垾垿埂埃埆埇埋埌城埏埒埔埕埗埘埙埚埝域埠埤埪埫埭埯埴埵埸培基" - "埼埽堂堃堆堇堉堋堌堍堎堐堑堕堙堞堠堡堤堧堨堪堰堲堵堼堽堾塄塅塆塌塍塑塔塘塝塞塥填" - "塬塱塾墀墁境墅墈墉墐墒墓墕墘墙墚增墟墡墣墦墨墩墼壁壅壑壕壤士壬壮声壳壶壸壹处备复" - "夏夐夔夕外夙多夜够夤夥大天太夫夬夭央夯失头夷夸夹夺夼奁奂奄奇奈奉奋奎奏契奓奔奕奖" - "套奘奚奠奡奢奥奭女奴奶奸她好妁如妃妄妆妇妈妊妍妒妓妖妗妘妙妞妣妤妥妧妨妩妪妫妭妮" - "妯妲妹妻妾姆姈姊始姐姑姒姓委姗姘姚姜姝姞姣姤姥姨姬姮姱姶姹姻姽姿娀威娃娄娅娆娇娈" - "娉娌娑娓娘娜娟娠娣娥娩娱娲娴娵娶娼婀婆婉婊婌婍婕婘婚婞婠婢婤婧婪婫婳婴婵婶婷婺婻" - "婼婿媂媄媆媒媓媖媚媛媞媪媭媱媲媳媵媸媾嫁嫂嫄嫉嫌嫒嫔嫕嫖嫘嫚嫜嫠嫡嫣嫦嫩嫪嫫嫭嫱" - "嫽嬉嬖嬗嬛嬥嬬嬴嬷嬿孀孅子孑孓孔孕孖字存孙孚孛孜孝孟孢季孤孥学孩孪孬孰孱孳孵孺孽" - "宁它宄宅宇守安宋完宏宓宕宗官宙定宛宜宝实宠审客宣室宥宦宧宪宫宬宰害宴宵家宸容宽宾" - "宿寁寂寄寅密寇富寐寒寓寝寞察寡寤寥寨寮寰寸对寺寻导寿封射将尉尊小少尔尕尖尘尚尜尝" - "尢尤尥尧尨尪尬就尴尸尹尺尻尼尽尾尿局屁层屃居屈屉届屋屎屏屐屑展屙属屠屡屣履屦屯山" - "屹屺屼屾屿岁岂岈岊岌岍岐岑岔岖岗岘岙岚岛岜岞岠岢岣岨岩岫岬岭岱岳岵岷岸岽岿峁峂峃" - "峄峋峒峗峘峙峛峡峣峤峥峦峧峨峪峭峰峱峻峿崀崁崂崃崄崆崇崌崎崒崔崖崚崛崞崟崡崤崦崧" - "崩崭崮崴崶崽崾崿嵁嵅嵇嵊嵋嵌嵎嵖嵘嵚嵛嵝嵩嵫嵬嵯嵲嵴嶂嶅嶍嶒嶓嶙嶝嶟嶦嶲嶷巅巇巉" - "巍川州巡巢工左巧巨巩巫差巯己已巳巴巷巽巾币市布帅帆师希帏帐帑帔帕帖帘帙帚帛帜帝帡" - "带帧帨席帮帱帷常帻帼帽幂幄幅幌幔幕幖幛幞幡幢幪干平年并幸幺幻幼幽广庄庆庇床庋序庐" - "庑库应底庖店庙庚府庞废庠庤庥度座庭庱庳庵庶康庸庹庼庾廆廉廊廋廑廒廓廖廙廛廨廪延廷" - "建廿开弁异弃弄弆弇弈弊弋式弑弓引弗弘弛弟张弢弥弦弧弨弩弭弯弱弶弸弹强弼彀归当录彖" - "彗彘彝彟形彤彦彧彩彪彬彭彰影彳彷役彻彼往征徂径待徇很徉徊律徐徒徕得徘徙徛徜御徨循" - "徭微徵德徼徽心必忆忉忌忍忏忐忑忒忖志忘忙忝忞忠忡忤忧忪快忭忮忱忳念忸忺忻忽忾忿怀" - "态怂怃怄怅怆怊怍怎怏怒怔怕怖怙怛怜思怠怡急怦性怨怩怪怫怯怵总怼怿恁恂恃恋恍恐恒恓" - "恔恕恙恚恝恢恣恤恧恨恩恪恫恬恭息恰恳恶恸恹恺恻恼恽恿悃悄悆悈悉悌悍悒悔悖悚悛悝悟" - "悠悢患悦您悫悬悭悯悰悱悲悴悸悻悼情惆惇惊惋惎惑惔惕惘惙惚惛惜惝惟惠惦惧惨惩惫惬惭" - "惮惯惰想惴惶惹惺愀愁愃愆愈愉愍愎意愐愔愕愚感愠愣愤愦愧愫愭愿慆慈慊慌慎慑慕慝慢慥" - "慧慨慬慭慰慵慷憋憎憔憕憙憧憨憩憬憭憷憺憾懂懈懊懋懑懒懔懦懵懿戆戈戊戋戌戍戎戏成我" - "戒戕或戗战戚戛戟戡戢戣戤戥截戬戭戮戳戴户戽戾房所扁扂扃扅扆扇扈扉扊手才扎扑扒打扔" - "托扛扞扣扦执扩扪扫扬扭扮扯扰扳扶批扺扼扽找承技抃抄抉把抑抒抓抔投抖抗折抚抛抟抠抡" - "抢护报抨披抬抱抵抹抻押抽抿拂拃拄担拆拇拈拉拊拌拍拎拐拒拓拔拖拗拘拙招拜拟拢拣拤拥" - "拦拧拨择括拭拮拯拱拳拴拶拷拼拽拾拿持挂指挈按挎挑挓挖挚挛挝挞挟挠挡挣挤挥挦挨挪挫" - "振挲挹挺挽捂捃捅捆捉捋捌捍捎捏捐捕捞损捡换捣捧捩捭据捯捶捷捺捻捽掀掂掇授掉掊掌掎" - "掏掐排掖掘掞掠探掣接控推掩措掬掭掮掰掳掴掷掸掺掼掾揄揆揉揍描提插揕揖揠握揣揩揪揭" - "揳援揶揸揽揿搀搁搂搅搋搌搏搐搒搓搔搛搜搞搠搡搦搪搬搭搴携搽摁摄摅摆摇摈摊摏摒摔摘" - "摛摞摧摩摭摴摸摹摽撂撄撅撇撑撒撕撖撙撞撤撩撬播撮撰撵撷撸撺撼擀擂擅操擎擐擒擘擞擢" - "擤擦擿攀攉攒攘攥攫攮支收攸改攻攽放政故效敉敌敏救敔敕敖教敛敝敞敢散敦敩敫敬数敲整" - "敷文斋斌斐斑斓斗料斛斜斝斟斠斡斤斥斧斩斫断斯新斶方於施旁旃旄旅旆旋旌旎族旐旒旖旗" - "旞无既日旦旧旨早旬旭旮旯旰旱旴旵时旷旸旺旻旿昀昂昃昄昆昇昈昉昊昌明昏昒易昔昕昙昝" - "星映昡昣昤春昧昨昪昫昭是昱昳昴昵昶昺昼昽显晁晃晅晊晋晌晏晐晒晓晔晕晖晗晙晚晞晟晡" - "晢晤晦晨晪晫普景晰晱晴晶晷智晾暂暄暅暇暌暑暕暖暗暝暧暨暮暲暴暵暶暹暾暿曈曌曙曛曜" - "曝曦曩曰曲曳更曷曹曼曾替最月有朋服朏朐朓朔朕朗望朝期朦木未末本札术朱朳朴朵朸机朽" - "杀杂权杄杆杈杉杌李杏材村杓杕杖杙杜杞束杠条来杧杨杩杪杭杯杰杲杳杵杷杻杼松板极构枅" - "枇枉枋枍析枕林枘枚果枝枞枢枣枥枧枨枪枫枭枯枰枲枳枵架枷枸枹柁柃柄柈柊柏某柑柒染柔" - "柖柘柙柚柜柝柞柠柢查柩柬柯柰柱柳柴柷柽柿栀栅标栈栉栊栋栌栎栏栐树栒栓栖栗栝栟校栩" - "株栲栳栴样核根栻格栽栾桀桁桂桃桄桅框案桉桊桌桎桐桑桓桔桕桠桡桢档桤桥桦桧桨桩桫桯" - "桲桴桶桷桹梁梃梅梆梌梏梓梗梠梢梣梦梧梨梭梯械梳梴梵梼梽梾梿检棁棂棉棋棍棐棒棓棕棘" - "棚棠棣棤棨棪棫棬森棰棱棵棹棺棻棼棽椀椁椅椆椋植椎椐椑椒椓椟椠椤椪椭椰椴椸椹椽椿楂" - "楒楔楗楙楚楝楞楠楣楦楩楪楫楮楯楷楸楹楼概榃榄榅榆榇榈榉榍榑榔榕榖榛榜榧榨榫榭榰榱" - "榴榷榻槁槃槊槌槎槐槔槚槛槜槟槠槭槱槲槽槿樊樗樘樟模樨横樯樱樵樽樾橄橇橐橑橘橙橛橞" - "橡橥橦橱橹橼檀檄檎檐檑檗檞檠檩檫檬櫆欂欠次欢欣欤欧欲欸欹欺欻款歃歅歆歇歉歌歙止正" - "此步武歧歪歹死歼殁殂殃殄殆殇殉殊残殍殒殓殖殚殛殡殣殪殳殴段殷殿毁毂毅毋毌母每毐毒" - "毓比毕毖毗毙毛毡毪毫毯毳毵毹毽氅氆氇氍氏氐民氓气氕氖氘氙氚氛氟氡氢氤氦氧氨氩氪氮" - "氯氰氲水永氾氿汀汁求汆汇汈汉汊汋汐汔汕汗汛汜汝汞江池污汤汧汨汩汪汫汭汰汲汴汶汹汽" - "汾沁沂沃沄沅沆沇沈沉沌沏沐沓沔沘沙沚沛沟没沣沤沥沦沧沨沩沪沫沭沮沱河沸油沺治沼沽" - "沾沿泂泃泄泅泇泉泊泌泐泓泔法泖泗泙泚泛泜泞泠泡波泣泥注泪泫泮泯泰泱泳泵泷泸泺泻泼" - "泽泾洁洄洇洈洋洌洎洑洒洓洗洘洙洚洛洞洢洣津洧洨洪洫洭洮洱洲洳洴洵洸洹洺活洼洽派洿" - "流浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕浙浚浛浜浞浟浠浡浣浥浦浩浪浬浭浮浯浰浲浴海浸" - "浼涂涄涅消涉涌涍涎涐涑涓涔涕涘涛涝涞涟涠涡涢涣涤润涧涨涩涪涫涮涯液涴涵涸涿淀淄淅" - "淆淇淋淌淏淑淖淘淙淜淝淞淟淠淡淤淦淫淬淮淯深淳淴混淹添淼清渊渌渍渎渐渑渔渗渚渝渟" - "渠渡渣渤渥温渫渭港渰渲渴游渺渼湃湄湉湍湎湑湓湔湖湘湛湜湝湟湣湫湮湲湴湾湿溁溃溅溆" - "溇溉溍溏源溘溚溜溞溟溠溢溥溦溧溪溯溱溲溴溵溶溷溹溺溻溽滁滂滃滆滇滉滋滍滏滑滓滔滕" - "滗滘滚滞滟滠满滢滤滥滦滧滨滩滪滫滴滹漂漆漈漉漋漏漓演漕漖漠漤漦漩漪漫漭漯漱漳漴漶" - "漷漹漻漼漾潆潇潋潍潏潖潘潜潞潟潢潦潩潭潮潲潴潵潸潺潼潽潾澂澄澈澉澌澍澎澛澜澡澥澧" - "澪澭澳澴澶澹澼澽激濂濉濋濑濒濞濠濡濩濮濯瀌瀍瀑瀔瀚瀛瀣瀱瀵瀹瀼灈灌灏灞火灭灯灰灵" - "灶灸灼灾灿炀炅炆炉炊炌炎炒炔炕炖炘炙炜炝炟炣炫炬炭炮炯炱炳炷炸点炻炼炽烀烁烂烃烈" - "烊烔烘烙烛烜烝烟烠烤烦烧烨烩烫烬热烯烶烷烹烺烻烽焆焉焊焌焐焓焕焖焗焘焙焚焜焞焦焯" - "焰焱然煁煃煅煊煋煌煎煓煜煞煟煤煦照煨煮煲煳煴煸煺煽熄熇熊熏熔熘熙熛熜熟熠熥熨熬熵" - "熹熻燃燊燋燎燏燔燕燚燠燥燧燮燹爆爇爔爚爝爟爨爪爬爰爱爵父爷爸爹爻爽爿牁牂片版牌牍" - "牒牖牙牚牛牝牟牡牢牤牥牦牧物牮牯牲牵特牺牻牾牿犀犁犄犇犊犋犍犏犒犟犨犬犯犰犴状犷" - "犸犹狁狂狃狄狈狉狍狎狐狒狗狙狝狞狠狡狨狩独狭狮狯狰狱狲狳狴狷狸狺狻狼猁猃猄猇猊猎" - "猕猖猗猛猜猝猞猡猢猥猩猪猫猬献猯猰猱猴猷猹猺猾猿獍獐獒獗獠獬獭獯獴獾玃玄率玉王玎" - "玑玒玓玕玖玘玙玚玛玞玟玠玡玢玤玥玦玩玫玭玮环现玱玲玳玶玷玹玺玻玼玿珀珂珅珇珈珉珊" - "珋珌珍珏珐珑珒珕珖珙珛珝珞珠珢珣珥珦珧珩珪珫班珰珲珵珷珸珹珺珽琀球琄琅理琇琈琉琊" - "琎琏琐琔琚琛琟琡琢琤琥琦琨琪琫琬琭琮琯琰琲琳琴琵琶琼瑀瑁瑂瑃瑄瑅瑆瑑瑓瑔瑕瑖瑗瑙" - "瑚瑛瑜瑝瑞瑟瑢瑧瑨瑬瑭瑰瑱瑳瑶瑷瑾璀璁璃璆璇璈璋璎璐璒璘璜璞璟璠璥璧璨璩璪璬璮璱" - "璲璺瓀瓒瓖瓘瓜瓞瓠瓢瓣瓤瓦瓮瓯瓴瓶瓷瓻瓿甄甍甏甑甓甗甘甚甜生甡甥甦用甩甪甫甬甭甯" - "田由甲申电男甸町画甾畀畅畈畋界畎畏畔畖留畚畛畜畤略畦番畬畯畲畴畸畹畿疁疃疆疍疏疐" - "疑疔疖疗疙疚疝疟疠疡疢疣疤疥疫疬疭疮疯疰疱疲疳疴疵疸疹疼疽疾痂痃痄病症痈痉痊痍痒" - "痓痔痕痘痛痞痢痣痤痦痧痨痪痫痰痱痴痹痼痿瘀瘁瘃瘅瘆瘊瘌瘐瘕瘗瘘瘙瘛瘟瘠瘢瘤瘥瘦瘩" - "瘪瘫瘭瘰瘳瘴瘵瘸瘼瘾瘿癀癃癌癍癔癖癗癜癞癣癫癯癸登白百癿皂的皆皇皈皋皎皑皓皕皖皙" - "皛皞皤皦皭皮皱皲皴皿盂盅盆盈盉益盍盎盏盐监盒盔盖盗盘盛盟盥盦目盯盱盲直盷相盹盼盾" - "省眄眇眈眉眊看眍眙眚真眠眢眦眨眩眬眭眯眵眶眷眸眺眼着睁睃睄睇睎睐睑睚睛睡睢督睥睦" - "睨睫睬睹睽睾睿瞀瞄瞅瞋瞌瞍瞎瞑瞒瞟瞠瞢瞥瞧瞩瞪瞫瞬瞭瞰瞳瞵瞻瞽瞿矍矗矛矜矞矢矣知" - "矧矩矫矬短矮矰石矶矸矻矼矾矿砀码砂砄砆砉砌砍砑砒研砖砗砘砚砜砝砟砠砣砥砧砫砬砭砮" - "砰破砵砷砸砹砺砻砼砾础硁硅硇硊硌硍硎硐硒硔硕硖硗硙硚硝硪硫硬硭确硼硿碃碇碈碉碌碍" - "碎碏碑碓碗碘碚碛碜碟碡碣碥碧碨碰碱碲碳碴碶碹碾磁磅磉磊磋磏磐磔磕磙磜磡磨磬磲磴磷" - "磹磻礁礅礌礓礞礴礵示礼社祀祁祃祆祇祈祉祊祋祎祏祐祓祕祖祗祚祛祜祝神祟祠祢祥祧票祭" - "祯祲祷祸祺祼祾禀禁禄禅禊禋福禒禔禘禚禛禤禧禳禹禺离禽禾秀私秃秆秉秋种科秒秕秘租秣" - "秤秦秧秩秫秬秭积称秸移秽秾稀稂稃稆程稌稍税稑稔稗稙稚稞稠稣稳稷稹稻稼稽稿穄穆穑穗" - "穙穜穟穰穴究穷穸穹空穿窀突窃窄窅窈窊窍窎窑窒窕窖窗窘窜窝窟窠窣窥窦窨窬窭窳窸窿立" - "竑竖竘站竞竟章竣童竦竫竭端竹竺竽竿笃笄笆笈笊笋笏笑笔笕笙笛笞笠笤笥符笨笪笫第笮笯" - "笱笳笸笺笼笾筀筅筇等筋筌筏筐筑筒答策筘筚筛筜筝筠筢筤筥筦筮筱筲筵筶筷筹筻筼签简箅" - "箍箐箓箔箕箖算箜管箢箦箧箨箩箪箫箬箭箱箴箸篁篆篇篌篑篓篙篚篝篡篥篦篪篮篯篱篷篼篾" - "簃簇簉簋簌簏簕簖簝簟簠簧簪簰簸簿籀籁籍籥米籴类籼籽粉粑粒粕粗粘粜粝粞粟粢粤粥粪粮" - "粱粲粳粹粼粽精粿糁糅糇糈糊糌糍糒糕糖糗糙糜糟糠糨糯糵系紊素索紧紫累絜絮絷綦綮縠縢" - "縻繁繄繇纂纛纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁" - "绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩" - "绪绫续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缌缎缐缑缒缓缔缕" - "编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缸缺罂罄罅罍罐" - "网罔罕罗罘罚罟罡罢罨罩罪置罱署罴罶罹罽罾羁羊羌美羑羓羔羕羖羚羝羞羟羡群羧羯羰羱羲" - "羸羹羼羽羿翀翁翂翃翅翈翊翌翎翔翕翘翙翚翛翟翠翡翥翦翩翮翯翰翱翳翷翻翼翾耀老考耄者" - "耆耇耋而耍耏耐耑耒耔耕耖耗耘耙耜耠耢耤耥耦耧耨耩耪耰耱耳耵耶耷耸耻耽耿聂聃聆聊聋" - "职聍聒联聘聚聩聪聱聿肃肄肆肇肉肋肌肓肖肘肚肛肝肟肠股肢肤肥肩肪肫肭肮肯肱育肴肷肸" - "肺肼肽肾肿胀胁胂胃胄胆胈背胍胎胖胗胙胚胛胜胝胞胠胡胣胤胥胧胨胩胪胫胬胭胯胰胱胲胳" - "胴胶胸胺胼能脂脆脉脊脍脎脏脐脑脒脓脔脖脘脚脞脟脩脬脯脱脲脶脸脾脿腆腈腊腋腌腐腑腒" - "腓腔腕腘腙腚腠腥腧腨腩腭腮腯腰腱腴腹腺腻腼腽腾腿膀膂膈膊膏膑膘膙膛膜膝膦膨膳膺膻" - "臀臂臃臆臊臌臑臜臣臧自臬臭至致臻臼臾舀舁舂舄舅舆舌舍舐舒舔舛舜舞舟舠舢舣舥航舫般" - "舭舯舰舱舲舳舴舵舶舷舸船舻舾艄艅艇艉艋艎艏艘艚艟艨艮良艰色艳艴艺艽艾艿节芃芄芈芊" - "芋芍芎芏芑芒芗芘芙芜芝芟芠芡芣芤芥芦芨芩芪芫芬芭芮芯芰花芳芴芷芸芹芼芽芾苁苄苇苈" - "苉苊苋苌苍苎苏苑苒苓苔苕苗苘苛苜苞苟苠苡苣苤若苦苧苫苯英苴苷苹苻苾茀茁茂范茄茅茆" - "茈茉茋茌茎茏茑茓茔茕茗茚茛茜茝茧茨茫茬茭茯茱茳茴茵茶茸茹茺茼茽荀荁荃荄荆荇草荏荐" - "荑荒荓荔荖荙荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药荷荸荻荼荽莅莆莉莎莒莓莘莙莛" - "莜莝莞莠莨莩莪莫莰莱莲莳莴莶获莸莹莺莼莽莿菀菁菂菅菇菉菊菌菍菏菔菖菘菜菝菟菠菡菥" - "菩菪菰菱菲菹菼菽萁萃萄萆萋萌萍萎萏萑萘萚萜萝萣萤营萦萧萨萩萱萳萸萹萼落葆葎葑葖著" - "葙葚葛葜葡董葩葫葬葭葰葱葳葴葵葶葸葺蒂蒄蒇蒈蒉蒋蒌蒎蒐蒗蒙蒜蒟蒡蒨蒯蒱蒲蒴蒸蒹蒺" - "蒻蒽蒿蓁蓂蓄蓇蓉蓊蓍蓏蓐蓑蓓蓖蓝蓟蓠蓢蓣蓥蓦蓬蓰蓼蓿蔀蔃蔈蔊蔌蔑蔓蔗蔚蔟蔡蔫蔬蔷" - "蔸蔹蔺蔻蔼蔽蕃蕈蕉蕊蕖蕗蕙蕞蕤蕨蕰蕲蕴蕹蕺蕻蕾薁薄薅薇薏薛薜薢薤薨薪薮薯薰薳薷薸" - "薹薿藁藉藏藐藓藕藜藟藠藤藦藨藩藻藿蘅蘑蘖蘘蘧蘩蘸蘼虎虏虐虑虒虓虔虚虞虢虤虫虬虮虱" - "虷虸虹虺虻虼虽虾虿蚀蚁蚂蚄蚆蚊蚋蚌蚍蚓蚕蚜蚝蚣蚤蚧蚨蚩蚪蚬蚯蚰蚱蚲蚴蚶蚺蛀蛃蛄蛆" - "蛇蛉蛊蛋蛎蛏蛐蛑蛔蛘蛙蛛蛞蛟蛤蛩蛭蛮蛰蛱蛲蛳蛴蛸蛹蛾蜀蜂蜃蜇蜈蜉蜊蜍蜎蜐蜒蜓蜕蜗" - "蜘蜚蜜蜞蜡蜢蜣蜥蜩蜮蜱蜴蜷蜻蜾蜿蝇蝈蝉蝌蝎蝓蝗蝘蝙蝠蝣蝤蝥蝮蝰蝲蝴蝶蝻蝼蝽蝾螂螃" - "螅螈螋融螗螟螠螣螨螫螬螭螯螱螳螵螺螽蟀蟆蟊蟋蟏蟑蟒蟛蟠蟥蟪蟫蟮蟹蟾蠃蠊蠋蠓蠕蠖蠡" - "蠢蠲蠹蠼血衃衄衅行衍衎衒衔街衙衠衡衢衣补表衩衫衬衮衰衲衷衽衾衿袁袂袄袅袆袈袋袍袒" - "袖袗袜袢袤袪被袭袯袱袷袼裁裂装裆裈裉裎裒裔裕裘裙裛裟裢裣裤裥裨裰裱裳裴裸裹裼裾褂" - "褊褐褒褓褕褙褚褛褟褡褥褪褫褯褰褴褶襁襄襕襚襜襞襟襦襫襻西要覃覆见观觃规觅视觇览觉" - "觊觋觌觎觏觐觑角觖觚觜觞觟解觥触觫觭觯觱觳觿言訄訇訚訾詈詟詹誉誊誓謇警譬计订讣认" - "讥讦讧讨让讪讫训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词" - "诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诫诬语诮误诰诱诲诳说诵请" - "诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谙谚谛谜谝谞谟谠谡" - "谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷谼谿豁豆豇豉豌豕豚象豢豨豪豫豮豳豸豹" - "豺貂貅貆貉貊貌貔貘贝贞负贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼" - "贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赤" - "赦赧赪赫赭走赳赴赵赶起趁趄超越趋趑趔趟趣趯趱足趴趵趸趺趼趾趿跂跃跄跆跋跌跎跏跐跑" - "跖跗跚跛距跞跟跣跤跨跪跬路跱跳践跶跷跸跹跺跻跽踅踉踊踌踏踒踔踝踞踟踢踣踦踩踪踬踮" - "踯踱踵踶踹踺踽蹀蹁蹂蹄蹅蹇蹈蹉蹊蹋蹐蹑蹒蹙蹚蹜蹢蹦蹩蹬蹭蹯蹰蹲蹴蹶蹼蹽蹾蹿躁躅躇" - "躏躐躔躜躞身躬躯躲躺车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较" - "辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辛辜辞辟辣辨辩辫辰辱边辽达辿迁迂迄" - "迅过迈迎运近迓返迕还这进远违连迟迢迤迥迦迨迩迪迫迭迮述迳迷迸迹迺追退送适逃逄逅逆" - "选逊逋逍透逐逑递途逖逗通逛逝逞速造逡逢逦逭逮逯逴逵逶逸逻逼逾遁遂遄遆遇遍遏遐遑遒" - "道遗遘遛遢遣遥遨遭遮遴遵遹遽避邀邂邃邈邋邑邓邕邗邘邙邛邝邠邡邢那邦邨邪邬邮邯邰邱" - "邲邳邴邵邶邸邹邺邻邽邾邿郁郃郄郅郇郈郊郎郏郐郑郓郗郚郛郜郝郡郢郤郦郧部郪郫郭郯郴" - "郸都郾郿鄀鄂鄃鄄鄅鄌鄑鄗鄘鄙鄚鄜鄞鄠鄢鄣鄫鄯鄱鄹酂酃酅酆酉酊酋酌配酎酏酐酒酗酚酝" - "酞酡酢酣酤酥酦酩酪酬酮酯酰酱酲酴酵酶酷酸酹酺酽酾酿醅醇醉醋醌醍醐醑醒醚醛醢醨醪醭" - "醮醯醴醵醺醾采釉释里重野量釐金釜鉴銎銮鋆鋈錾鍪鎏鏊鏖鐾鑫钆钇针钉钊钋钌钍钎钏钐钒" - "钓钔钕钖钗钘钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钷钹钺钻钼" - "钽钾钿铀铁铂铃铄铅铆铈铉铊铋铌铍铎铏铐铑铒铕铖铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铧铨" - "铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐" - "锑锒锓锔锕锖锗锘错锚锛锜锝锞锟锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹" - "锺锻锼锽锾锿镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镚镛镜镝镞镠镡镢镣" - "镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶长门闩闪闫闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼" - "闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阔阕阖阗阘阙阚阜队阡阪阮阱防阳阴阵阶" - "阻阼阽阿陀陂附际陆陇陈陉陋陌降陎限陑陔陕陛陞陟陡院除陧陨险陪陬陲陴陵陶陷隃隅隆隈" - "隋隍随隐隔隗隘隙障隧隩隰隳隶隹隺隼隽难雀雁雄雅集雇雉雊雌雍雎雏雒雕雠雨雩雪雯雱雳" - "零雷雹雾需霁霄霅霆震霈霉霍霎霏霓霖霜霞霨霪霭霰露霸霹霾青靓靖静靛非靠靡面靥革靬靰" - "靳靴靶靸靺靼靽靿鞁鞅鞋鞍鞑鞒鞔鞘鞠鞡鞣鞧鞨鞫鞬鞭鞮鞯鞲鞳鞴韂韦韧韨韩韪韫韬韭音韵" - "韶页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颓颔颖颗题颙颚颛颜额" - "颞颟颠颡颢颤颥颦颧风飏飐飑飒飓飔飕飗飘飙飞食飧飨餍餐餮饔饕饥饧饨饩饪饫饬饭饮饯饰" - "饱饲饳饴饵饶饷饸饹饺饻饼饽饿馁馃馄馅馆馇馈馉馊馋馌馍馏馐馑馒馓馔馕首馗馘香馝馞馥" - "馧馨马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑" - "骒骓骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧骨骰骱骶骷骸骺骼髀髁髂髃髅髋髌髎髑髓高" - "髡髢髦髫髭髯髹髻髽鬃鬈鬏鬒鬓鬘鬟鬣鬯鬲鬶鬷鬻鬼魁魂魃魄魅魆魇魈魉魋魍魏魑魔鱼鱽鱾" - "鱿鲀鲁鲂鲃鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨" - "鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳇鳈鳉鳊鳌鳍鳎鳏鳐鳑鳒鳓" - "鳔鳕鳖鳗鳘鳙鳚鳛鳜鳝鳞鳟鳠鳡鳢鳣鳤鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸵鸶" - "鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟" - "鹠鹡鹢鹣鹤鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹴鹾鹿麀麂麇麈麋麑麒麓麖麝麟麦麸麹麻麽麾黄" - "黇黉黍黎黏黑黔默黛黜黝黟黠黡黢黥黧黩黪黯黹黻黼黾鼋鼍鼎鼐鼒鼓鼗鼙鼠鼢鼩鼫鼬鼯鼱鼷" - "鼹鼻鼽鼾齁齇齉齐齑齿龀龁龂龃龄龅龆龇龈龉龊龋龌龙龚龛龟龠龢鿍鿎鿏㑇㑊㕮㘎㙍㙘㙦㛃" - "㛚㛹㟃㠇㠓㤘㥄㧐㧑㧟㫰㬊㬎㬚㭎㭕㮾㰀㳇㳘㳚㴔㵐㶲㸆㸌㺄㻬㽏㿠䁖䂮䃅䃎䅟䌹䎃䎖䏝䏡" - "䏲䐃䓖䓛䓨䓫䓬䗖䗛䗪䗴䜣䝙䢺䢼䣘䥽䦃䲟䲠䲢䴓䴔䴕䴖䴗䴘䴙䶮𠅤𠙶𠳐𡎚𡐓𣗋𣲗𣲘𣸣𤧛𤩽" - "𤫉𥔲𥕢𥖨𥻗𦈡𦒍𦙶𦝼𦭜𦰡𧿹𨐈𨙸𨚕𨟠𨭉𨱇𨱏𨱑𨱔𨺙𩽾𩾃𩾌𪟝𪣻𪤗𪨰𪨶𪩘𪾢𫄧𫄨𫄷𫄸𫇭𫌀𫍣𫍯" - "𫍲𫍽𫐄𫐐𫐓𫑡𫓧𫓯𫓶𫓹𫔍𫔎𫔶𫖮𫖯𫖳𫗧𫗴𫘜𫘝𫘦𫘧𫘨𫘪𫘬𫚕𫚖𫚭𫛭𫞩𫟅𫟦𫟹𫟼𫠆𫠊𫠜𫢸𫫇𫭟" - "𫭢𫭼𫮃𫰛𫵷𫶇𫷷𫸩𬀩𬀪𬂩𬃊𬇕𬇙𬇹𬉼𬊈𬊤𬌗𬍛𬍡𬍤𬒈𬒔𬒗𬕂𬘓𬘘𬘡𬘩𬘫𬘬𬘭𬘯𬙂𬙊𬙋𬜬𬜯𬞟" - "𬟁𬟽𬣙𬣞𬣡𬣳𬤇𬤊𬤝𬨂𬨎𬩽𬪩𬬩𬬭𬬮𬬱𬬸𬬹𬬻𬬿𬭁𬭊𬭎𬭚𬭛𬭤𬭩𬭬𬭯𬭳𬭶𬭸𬭼𬮱𬮿𬯀𬯎𬱖𬱟" - "𬳵𬳶𬳽𬳿𬴂𬴃𬴊𬶋𬶍𬶏𬶐𬶟𬶠𬶨𬶭𬶮𬷕𬸘𬸚𬸣𬸦𬸪𬹼𬺈𬺓" -) -CN_CHARS_EXT = "吶诶屌囧飚屄" - -CN_CHARS = CN_CHARS_COMMON + CN_CHARS_EXT -IN_CH_CHARS = {c: True for c in CN_CHARS} - -EN_CHARS = string.ascii_letters + string.digits -IN_EN_CHARS = {c: True for c in EN_CHARS} - -VALID_CHARS = CN_CHARS + EN_CHARS + " " -IN_VALID_CHARS = {c: True for c in VALID_CHARS} - - -# ================================================================================ # -# basic class -# ================================================================================ # -class ChineseChar(object): - """ - 中文字符 - 每个字符对应简体和繁体, - e.g. 简体 = '负', 繁体 = '負' - 转换时可转换为简体或繁体 - """ - - def __init__(self, simplified, traditional): - self.simplified = simplified - self.traditional = traditional - # self.__repr__ = self.__str__ - - def __str__(self): - return self.simplified or self.traditional or None - - def __repr__(self): - return self.__str__() - - -class ChineseNumberUnit(ChineseChar): - """ - 中文数字/数位字符 - 每个字符除繁简体外还有一个额外的大写字符 - e.g. '陆' 和 '陸' - """ - - def __init__(self, power, simplified, traditional, big_s, big_t): - super(ChineseNumberUnit, self).__init__(simplified, traditional) - self.power = power - self.big_s = big_s - self.big_t = big_t - - def __str__(self): - return "10^{}".format(self.power) - - @classmethod - def create(cls, index, value, numbering_type=NUMBERING_TYPES[1], small_unit=False): - if small_unit: - return ChineseNumberUnit( - power=index + 1, simplified=value[0], traditional=value[1], big_s=value[1], big_t=value[1] - ) - elif numbering_type == NUMBERING_TYPES[0]: - return ChineseNumberUnit( - power=index + 8, simplified=value[0], traditional=value[1], big_s=value[0], big_t=value[1] - ) - elif numbering_type == NUMBERING_TYPES[1]: - return ChineseNumberUnit( - power=(index + 2) * 4, simplified=value[0], traditional=value[1], big_s=value[0], big_t=value[1] - ) - elif numbering_type == NUMBERING_TYPES[2]: - return ChineseNumberUnit( - power=pow(2, index + 3), simplified=value[0], traditional=value[1], big_s=value[0], big_t=value[1] - ) - else: - raise ValueError("Counting type should be in {0} ({1} provided).".format(NUMBERING_TYPES, numbering_type)) - - -class ChineseNumberDigit(ChineseChar): - """ - 中文数字字符 - """ - - def __init__(self, value, simplified, traditional, big_s, big_t, alt_s=None, alt_t=None): - super(ChineseNumberDigit, self).__init__(simplified, traditional) - self.value = value - self.big_s = big_s - self.big_t = big_t - self.alt_s = alt_s - self.alt_t = alt_t - - def __str__(self): - return str(self.value) - - @classmethod - def create(cls, i, v): - return ChineseNumberDigit(i, v[0], v[1], v[2], v[3]) - - -class ChineseMath(ChineseChar): - """ - 中文数位字符 - """ - - def __init__(self, simplified, traditional, symbol, expression=None): - super(ChineseMath, self).__init__(simplified, traditional) - self.symbol = symbol - self.expression = expression - self.big_s = simplified - self.big_t = traditional - - -CC, CNU, CND, CM = ChineseChar, ChineseNumberUnit, ChineseNumberDigit, ChineseMath - - -class NumberSystem(object): - """ - 中文数字系统 - """ - - pass - - -class MathSymbol(object): - """ - 用于中文数字系统的数学符号 (繁/简体), e.g. - positive = ['正', '正'] - negative = ['负', '負'] - point = ['点', '點'] - """ - - def __init__(self, positive, negative, point): - self.positive = positive - self.negative = negative - self.point = point - - def __iter__(self): - for v in self.__dict__.values(): - yield v - - -# class OtherSymbol(object): -# """ -# 其他符号 -# """ -# -# def __init__(self, sil): -# self.sil = sil -# -# def __iter__(self): -# for v in self.__dict__.values(): -# yield v - - -# ================================================================================ # -# basic utils -# ================================================================================ # -def create_system(numbering_type=NUMBERING_TYPES[1]): - """ - 根据数字系统类型返回创建相应的数字系统,默认为 mid - NUMBERING_TYPES = ['low', 'mid', 'high']: 中文数字系统类型 - low: '兆' = '亿' * '十' = $10^{9}$, '京' = '兆' * '十', etc. - mid: '兆' = '亿' * '万' = $10^{12}$, '京' = '兆' * '万', etc. - high: '兆' = '亿' * '亿' = $10^{16}$, '京' = '兆' * '兆', etc. - 返回对应的数字系统 - """ - - # chinese number units of '亿' and larger - all_larger_units = zip(LARGER_CHINESE_NUMERING_UNITS_SIMPLIFIED, LARGER_CHINESE_NUMERING_UNITS_TRADITIONAL) - larger_units = [CNU.create(i, v, numbering_type, False) for i, v in enumerate(all_larger_units)] - # chinese number units of '十, 百, 千, 万' - all_smaller_units = zip(SMALLER_CHINESE_NUMERING_UNITS_SIMPLIFIED, SMALLER_CHINESE_NUMERING_UNITS_TRADITIONAL) - smaller_units = [CNU.create(i, v, small_unit=True) for i, v in enumerate(all_smaller_units)] - # digis - chinese_digis = zip(CHINESE_DIGIS, CHINESE_DIGIS, BIG_CHINESE_DIGIS_SIMPLIFIED, BIG_CHINESE_DIGIS_TRADITIONAL) - digits = [CND.create(i, v) for i, v in enumerate(chinese_digis)] - digits[0].alt_s, digits[0].alt_t = ZERO_ALT, ZERO_ALT - digits[1].alt_s, digits[1].alt_t = ONE_ALT, ONE_ALT - digits[2].alt_s, digits[2].alt_t = TWO_ALTS[0], TWO_ALTS[1] - - # symbols - positive_cn = CM(POSITIVE[0], POSITIVE[1], "+", lambda x: x) - negative_cn = CM(NEGATIVE[0], NEGATIVE[1], "-", lambda x: -x) - point_cn = CM(POINT[0], POINT[1], ".", lambda x, y: float(str(x) + "." + str(y))) - # sil_cn = CM(SIL[0], SIL[1], '-', lambda x, y: float(str(x) + '-' + str(y))) - system = NumberSystem() - system.units = smaller_units + larger_units - system.digits = digits - system.math = MathSymbol(positive_cn, negative_cn, point_cn) - # system.symbols = OtherSymbol(sil_cn) - return system - - -def chn2num(chinese_string, numbering_type=NUMBERING_TYPES[1]): - def get_symbol(char, system): - for u in system.units: - if char in [u.traditional, u.simplified, u.big_s, u.big_t]: - return u - for d in system.digits: - if char in [d.traditional, d.simplified, d.big_s, d.big_t, d.alt_s, d.alt_t]: - return d - for m in system.math: - if char in [m.traditional, m.simplified]: - return m - - def string2symbols(chinese_string, system): - int_string, dec_string = chinese_string, "" - for p in [system.math.point.simplified, system.math.point.traditional]: - if p in chinese_string: - int_string, dec_string = chinese_string.split(p) - break - return [get_symbol(c, system) for c in int_string], [get_symbol(c, system) for c in dec_string] - - def correct_symbols(integer_symbols, system): - """ - 一百八 to 一百八十 - 一亿一千三百万 to 一亿 一千万 三百万 - """ - - if integer_symbols and isinstance(integer_symbols[0], CNU): - if integer_symbols[0].power == 1: - integer_symbols = [system.digits[1]] + integer_symbols - - if len(integer_symbols) > 1: - if isinstance(integer_symbols[-1], CND) and isinstance(integer_symbols[-2], CNU): - integer_symbols.append(CNU(integer_symbols[-2].power - 1, None, None, None, None)) - - result = [] - unit_count = 0 - for s in integer_symbols: - if isinstance(s, CND): - result.append(s) - unit_count = 0 - elif isinstance(s, CNU): - current_unit = CNU(s.power, None, None, None, None) - unit_count += 1 - - if unit_count == 1: - result.append(current_unit) - elif unit_count > 1: - for i in range(len(result)): - if isinstance(result[-i - 1], CNU) and result[-i - 1].power < current_unit.power: - result[-i - 1] = CNU(result[-i - 1].power + current_unit.power, None, None, None, None) - return result - - def compute_value(integer_symbols): - """ - Compute the value. - When current unit is larger than previous unit, current unit * all previous units will be used as all previous units. - e.g. '两千万' = 2000 * 10000 not 2000 + 10000 - """ - value = [0] - last_power = 0 - for s in integer_symbols: - if isinstance(s, CND): - value[-1] = s.value - elif isinstance(s, CNU): - value[-1] *= pow(10, s.power) - if s.power > last_power: - value[:-1] = list(map(lambda v: v * pow(10, s.power), value[:-1])) - last_power = s.power - value.append(0) - return sum(value) - - system = create_system(numbering_type) - int_part, dec_part = string2symbols(chinese_string, system) - int_part = correct_symbols(int_part, system) - int_str = str(compute_value(int_part)) - dec_str = "".join([str(d.value) for d in dec_part]) - if dec_part: - return "{0}.{1}".format(int_str, dec_str) - else: - return int_str - - -def num2chn( - number_string, - numbering_type=NUMBERING_TYPES[1], - big=False, - traditional=False, - alt_zero=False, - alt_one=False, - alt_two=True, - use_zeros=True, - use_units=True, -): - def get_value(value_string, use_zeros=True): - striped_string = value_string.lstrip("0") - - # record nothing if all zeros - if not striped_string: - return [] - - # record one digits - elif len(striped_string) == 1: - if use_zeros and len(value_string) != len(striped_string): - return [system.digits[0], system.digits[int(striped_string)]] - else: - return [system.digits[int(striped_string)]] - - # recursively record multiple digits - else: - result_unit = next(u for u in reversed(system.units) if u.power < len(striped_string)) - result_string = value_string[: -result_unit.power] - return get_value(result_string) + [result_unit] + get_value(striped_string[-result_unit.power :]) - - system = create_system(numbering_type) - - int_dec = number_string.split(".") - if len(int_dec) == 1: - int_string = int_dec[0] - dec_string = "" - elif len(int_dec) == 2: - int_string = int_dec[0] - dec_string = int_dec[1] - else: - raise ValueError("invalid input num string with more than one dot: {}".format(number_string)) - - if use_units and len(int_string) > 1: - result_symbols = get_value(int_string) - else: - result_symbols = [system.digits[int(c)] for c in int_string] - dec_symbols = [system.digits[int(c)] for c in dec_string] - if dec_string: - result_symbols += [system.math.point] + dec_symbols - - if alt_two: - liang = CND(2, system.digits[2].alt_s, system.digits[2].alt_t, system.digits[2].big_s, system.digits[2].big_t) - for i, v in enumerate(result_symbols): - if isinstance(v, CND) and v.value == 2: - next_symbol = result_symbols[i + 1] if i < len(result_symbols) - 1 else None - previous_symbol = result_symbols[i - 1] if i > 0 else None - if isinstance(next_symbol, CNU) and isinstance(previous_symbol, (CNU, type(None))): - if next_symbol.power != 1 and ((previous_symbol is None) or (previous_symbol.power != 1)): - result_symbols[i] = liang - - # if big is True, '两' will not be used and `alt_two` has no impact on output - if big: - attr_name = "big_" - if traditional: - attr_name += "t" - else: - attr_name += "s" - else: - if traditional: - attr_name = "traditional" - else: - attr_name = "simplified" - - result = "".join([getattr(s, attr_name) for s in result_symbols]) - - # if not use_zeros: - # result = result.strip(getattr(system.digits[0], attr_name)) - - if alt_zero: - result = result.replace(getattr(system.digits[0], attr_name), system.digits[0].alt_s) - - if alt_one: - result = result.replace(getattr(system.digits[1], attr_name), system.digits[1].alt_s) - - for i, p in enumerate(POINT): - if result.startswith(p): - return CHINESE_DIGIS[0] + result - - # ^10, 11, .., 19 - if ( - len(result) >= 2 - and result[1] in [SMALLER_CHINESE_NUMERING_UNITS_SIMPLIFIED[0], SMALLER_CHINESE_NUMERING_UNITS_TRADITIONAL[0]] - and result[0] in [CHINESE_DIGIS[1], BIG_CHINESE_DIGIS_SIMPLIFIED[1], BIG_CHINESE_DIGIS_TRADITIONAL[1]] - ): - result = result[1:] - - return result - - -# ================================================================================ # -# different types of rewriters -# ================================================================================ # -class Cardinal: - """ - CARDINAL类 - """ - - def __init__(self, cardinal=None, chntext=None): - self.cardinal = cardinal - self.chntext = chntext - - def chntext2cardinal(self): - return chn2num(self.chntext) - - def cardinal2chntext(self): - return num2chn(self.cardinal) - - -class Digit: - """ - DIGIT类 - """ - - def __init__(self, digit=None, chntext=None): - self.digit = digit - self.chntext = chntext - - # def chntext2digit(self): - # return chn2num(self.chntext) - - def digit2chntext(self): - return num2chn(self.digit, alt_two=False, use_units=False) - - -class TelePhone: - """ - TELEPHONE类 - """ - - def __init__(self, telephone=None, raw_chntext=None, chntext=None): - self.telephone = telephone - self.raw_chntext = raw_chntext - self.chntext = chntext - - # def chntext2telephone(self): - # sil_parts = self.raw_chntext.split('') - # self.telephone = '-'.join([ - # str(chn2num(p)) for p in sil_parts - # ]) - # return self.telephone - - def telephone2chntext(self, fixed=False): - if fixed: - sil_parts = self.telephone.split("-") - self.raw_chntext = "".join([num2chn(part, alt_two=False, use_units=False) for part in sil_parts]) - self.chntext = self.raw_chntext.replace("", "") - else: - sp_parts = self.telephone.strip("+").split() - self.raw_chntext = "".join([num2chn(part, alt_two=False, use_units=False) for part in sp_parts]) - self.chntext = self.raw_chntext.replace("", "") - return self.chntext - - -class Fraction: - """ - FRACTION类 - """ - - def __init__(self, fraction=None, chntext=None): - self.fraction = fraction - self.chntext = chntext - - def chntext2fraction(self): - denominator, numerator = self.chntext.split("分之") - return chn2num(numerator) + "/" + chn2num(denominator) - - def fraction2chntext(self): - numerator, denominator = self.fraction.split("/") - return num2chn(denominator) + "分之" + num2chn(numerator) - - -class Date: - """ - DATE类 - """ - - def __init__(self, date=None, chntext=None): - self.date = date - self.chntext = chntext - - # def chntext2date(self): - # chntext = self.chntext - # try: - # year, other = chntext.strip().split('年', maxsplit=1) - # year = Digit(chntext=year).digit2chntext() + '年' - # except ValueError: - # other = chntext - # year = '' - # if other: - # try: - # month, day = other.strip().split('月', maxsplit=1) - # month = Cardinal(chntext=month).chntext2cardinal() + '月' - # except ValueError: - # day = chntext - # month = '' - # if day: - # day = Cardinal(chntext=day[:-1]).chntext2cardinal() + day[-1] - # else: - # month = '' - # day = '' - # date = year + month + day - # self.date = date - # return self.date - - def date2chntext(self): - date = self.date - try: - year, other = date.strip().split("年", 1) - year = Digit(digit=year).digit2chntext() + "年" - except ValueError: - other = date - year = "" - if other: - try: - month, day = other.strip().split("月", 1) - month = Cardinal(cardinal=month).cardinal2chntext() + "月" - except ValueError: - day = date - month = "" - if day: - day = Cardinal(cardinal=day[:-1]).cardinal2chntext() + day[-1] - else: - month = "" - day = "" - chntext = year + month + day - self.chntext = chntext - return self.chntext - - -class Money: - """ - MONEY类 - """ - - def __init__(self, money=None, chntext=None): - self.money = money - self.chntext = chntext - - # def chntext2money(self): - # return self.money - - def money2chntext(self): - money = self.money - pattern = re.compile(r"(\d+(\.\d+)?)") - matchers = pattern.findall(money) - if matchers: - for matcher in matchers: - money = money.replace(matcher[0], Cardinal(cardinal=matcher[0]).cardinal2chntext()) - self.chntext = money - return self.chntext - - -class Percentage: - """ - PERCENTAGE类 - """ - - def __init__(self, percentage=None, chntext=None): - self.percentage = percentage - self.chntext = chntext - - def chntext2percentage(self): - return chn2num(self.chntext.strip().strip("百分之")) + "%" - - def percentage2chntext(self): - return "百分之" + num2chn(self.percentage.strip().strip("%")) - - -def normalize_nsw(raw_text): - text = "^" + raw_text + "$" - - # 规范化日期 - pattern = re.compile(r"\D+((([089]\d|(19|20)\d{2})年)?(\d{1,2}月(\d{1,2}[日号])?)?)") - matchers = pattern.findall(text) - if matchers: - # print('date') - for matcher in matchers: - text = text.replace(matcher[0], Date(date=matcher[0]).date2chntext(), 1) - - # 规范化金钱 - pattern = re.compile(r"\D+((\d+(\.\d+)?)[多余几]?" + CURRENCY_UNITS + r"(\d" + CURRENCY_UNITS + r"?)?)") - matchers = pattern.findall(text) - if matchers: - # print('money') - for matcher in matchers: - text = text.replace(matcher[0], Money(money=matcher[0]).money2chntext(), 1) - - # 规范化固话/手机号码 - # 手机 - # http://www.jihaoba.com/news/show/13680 - # 移动:139、138、137、136、135、134、159、158、157、150、151、152、188、187、182、183、184、178、198 - # 联通:130、131、132、156、155、186、185、176 - # 电信:133、153、189、180、181、177 - pattern = re.compile(r"\D((\+?86 ?)?1([38]\d|5[0-35-9]|7[678]|9[89])\d{8})\D") - matchers = pattern.findall(text) - if matchers: - # print('telephone') - for matcher in matchers: - text = text.replace(matcher[0], TelePhone(telephone=matcher[0]).telephone2chntext(), 1) - # 固话 - pattern = re.compile(r"\D((0(10|2[1-3]|[3-9]\d{2})-?)?[1-9]\d{6,7})\D") - matchers = pattern.findall(text) - if matchers: - # print('fixed telephone') - for matcher in matchers: - text = text.replace(matcher[0], TelePhone(telephone=matcher[0]).telephone2chntext(fixed=True), 1) - - # 规范化分数 - pattern = re.compile(r"(\d+/\d+)") - matchers = pattern.findall(text) - if matchers: - # print('fraction') - for matcher in matchers: - text = text.replace(matcher, Fraction(fraction=matcher).fraction2chntext(), 1) - - # 规范化百分数 - text = text.replace("%", "%") - pattern = re.compile(r"(\d+(\.\d+)?%)") - matchers = pattern.findall(text) - if matchers: - # print('percentage') - for matcher in matchers: - text = text.replace(matcher[0], Percentage(percentage=matcher[0]).percentage2chntext(), 1) - - # 规范化纯数+量词 - pattern = re.compile(r"(\d+(\.\d+)?)[多余几]?" + COM_QUANTIFIERS) - matchers = pattern.findall(text) - if matchers: - # print('cardinal+quantifier') - for matcher in matchers: - text = text.replace(matcher[0], Cardinal(cardinal=matcher[0]).cardinal2chntext(), 1) - - # 规范化数字编号 - pattern = re.compile(r"(\d{4,32})") - matchers = pattern.findall(text) - if matchers: - # print('digit') - for matcher in matchers: - text = text.replace(matcher, Digit(digit=matcher).digit2chntext(), 1) - - # 规范化纯数 - pattern = re.compile(r"(\d+(\.\d+)?)") - matchers = pattern.findall(text) - if matchers: - # print('cardinal') - for matcher in matchers: - text = text.replace(matcher[0], Cardinal(cardinal=matcher[0]).cardinal2chntext(), 1) - - # restore P2P, O2O, B2C, B2B etc - pattern = re.compile(r"(([a-zA-Z]+)二([a-zA-Z]+))") - matchers = pattern.findall(text) - if matchers: - # print('particular') - for matcher in matchers: - text = text.replace(matcher[0], matcher[1] + "2" + matcher[2], 1) - - return text.lstrip("^").rstrip("$") - - -def remove_erhua(text): - """ - 去除儿化音词中的儿: - 他女儿在那边儿 -> 他女儿在那边 - """ - - new_str = "" - while re.search("儿", text): - a = re.search("儿", text).span() - remove_er_flag = 0 - - if ER_WHITELIST_PATTERN.search(text): - b = ER_WHITELIST_PATTERN.search(text).span() - if b[0] <= a[0]: - remove_er_flag = 1 - - if remove_er_flag == 0: - new_str = new_str + text[0 : a[0]] - text = text[a[1] :] - else: - new_str = new_str + text[0 : b[1]] - text = text[b[1] :] - - text = new_str + text - return text - - -def remove_space(text): - tokens = text.split() - new = [] - for k, t in enumerate(tokens): - if k != 0: - if IN_EN_CHARS.get(tokens[k - 1][-1]) and IN_EN_CHARS.get(t[0]): - new.append(" ") - new.append(t) - return "".join(new) - - -class TextNorm: - def __init__( - self, - to_banjiao: bool = False, - to_upper: bool = False, - to_lower: bool = False, - remove_fillers: bool = False, - remove_erhua: bool = False, - check_chars: bool = False, - remove_space: bool = False, - cc_mode: str = "", - ): - self.to_banjiao = to_banjiao - self.to_upper = to_upper - self.to_lower = to_lower - self.remove_fillers = remove_fillers - self.remove_erhua = remove_erhua - self.check_chars = check_chars - self.remove_space = remove_space - - self.cc = None - if cc_mode: - from opencc import OpenCC # Open Chinese Convert: pip install opencc - - self.cc = OpenCC(cc_mode) - - def __call__(self, text): - if self.cc: - text = self.cc.convert(text) - - if self.to_banjiao: - text = text.translate(QJ2BJ_TRANSFORM) - - if self.to_upper: - text = text.upper() - - if self.to_lower: - text = text.lower() - - if self.remove_fillers: - for c in FILLER_CHARS: - text = text.replace(c, "") - - if self.remove_erhua: - text = remove_erhua(text) - - text = normalize_nsw(text) - - text = text.translate(PUNCS_TRANSFORM) - - if self.check_chars: - for c in text: - if not IN_VALID_CHARS.get(c): - print(f"WARNING: illegal char {c} in: {text}", file=sys.stderr) - return "" - - if self.remove_space: - text = remove_space(text) - - return text - - -if __name__ == "__main__": - p = argparse.ArgumentParser() - - # normalizer options - p.add_argument("--to_banjiao", action="store_true", help="convert quanjiao chars to banjiao") - p.add_argument("--to_upper", action="store_true", help="convert to upper case") - p.add_argument("--to_lower", action="store_true", help="convert to lower case") - p.add_argument("--remove_fillers", action="store_true", help='remove filler chars such as "呃, 啊"') - p.add_argument("--remove_erhua", action="store_true", help='remove erhua chars such as "他女儿在那边儿 -> 他女儿在那边"') - p.add_argument("--check_chars", action="store_true", help="skip sentences containing illegal chars") - p.add_argument("--remove_space", action="store_true", help="remove whitespace") - p.add_argument( - "--cc_mode", choices=["", "t2s", "s2t"], default="", help="convert between traditional to simplified" - ) - - # I/O options - p.add_argument("--log_interval", type=int, default=10000, help="log interval in number of processed lines") - p.add_argument("--has_key", action="store_true", help="will be deprecated, set --format ark instead") - p.add_argument("--format", type=str, choices=["txt", "ark", "tsv"], default="txt", help="input format") - p.add_argument("ifile", help="input filename, assume utf-8 encoding") - p.add_argument("ofile", help="output filename") - - args = p.parse_args() - - if args.has_key: - args.format = "ark" - - normalizer = TextNorm( - to_banjiao=args.to_banjiao, - to_upper=args.to_upper, - to_lower=args.to_lower, - remove_fillers=args.remove_fillers, - remove_erhua=args.remove_erhua, - check_chars=args.check_chars, - remove_space=args.remove_space, - cc_mode=args.cc_mode, - ) - - normalizer = TextNorm( - to_banjiao=args.to_banjiao, - to_upper=args.to_upper, - to_lower=args.to_lower, - remove_fillers=args.remove_fillers, - remove_erhua=args.remove_erhua, - check_chars=args.check_chars, - remove_space=args.remove_space, - cc_mode=args.cc_mode, - ) - - ndone = 0 - with open(args.ifile, "r", encoding="utf-8") as istream, open(args.ofile, "w+", encoding="utf-8") as ostream: - if args.format == "tsv": - reader = csv.DictReader(istream, delimiter="\t") - assert "TEXT" in reader.fieldnames - print("\t".join(reader.fieldnames), file=ostream) - - for item in reader: - text = item["TEXT"] - - if text: - text = normalizer(text) - - if text: - item["TEXT"] = text - print("\t".join([item[f] for f in reader.fieldnames]), file=ostream) - - ndone += 1 - if ndone % args.log_interval == 0: - print(f"text norm: {ndone} lines done.", file=sys.stderr, flush=True) - else: - for l in istream: - key, text = "", "" - if args.format == "ark": # KALDI archive, line format: "key text" - cols = l.strip().split(maxsplit=1) - key, text = cols[0], cols[1] if len(cols) == 2 else "" - else: - text = l.strip() - - if text: - text = normalizer(text) - - if text: - if args.format == "ark": - print(key + "\t" + text, file=ostream) - else: - print(text, file=ostream) - - ndone += 1 - if ndone % args.log_interval == 0: - print(f"text norm: {ndone} lines done.", file=sys.stderr, flush=True) - print(f"text norm: {ndone} lines done in total.", file=sys.stderr, flush=True) \ No newline at end of file diff --git a/music_dcae/__init__.py b/music_dcae/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/music_dcae/music_dcae_pipeline.py b/music_dcae/music_dcae_pipeline.py deleted file mode 100644 index 0ca2f6dc76d5a452b777ddec428e96b8647e1e54..0000000000000000000000000000000000000000 --- a/music_dcae/music_dcae_pipeline.py +++ /dev/null @@ -1,141 +0,0 @@ -import os -import torch -from diffusers import AutoencoderDC -import torchaudio -import torchvision.transforms as transforms -from diffusers.models.modeling_utils import ModelMixin -from diffusers.loaders import FromOriginalModelMixin -from diffusers.configuration_utils import ConfigMixin, register_to_config - - -try: - from .music_vocoder import ADaMoSHiFiGANV1 -except ImportError: - from music_vocoder import ADaMoSHiFiGANV1 - - -root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -DEFAULT_PRETRAINED_PATH = os.path.join(root_dir, "checkpoints", "music_dcae_f8c8") -VOCODER_PRETRAINED_PATH = os.path.join(root_dir, "checkpoints", "music_vocoder") - - -class MusicDCAE(ModelMixin, ConfigMixin, FromOriginalModelMixin): - @register_to_config - def __init__(self, source_sample_rate=None, dcae_checkpoint_path=DEFAULT_PRETRAINED_PATH, vocoder_checkpoint_path=VOCODER_PRETRAINED_PATH): - super(MusicDCAE, self).__init__() - - self.dcae = AutoencoderDC.from_pretrained(dcae_checkpoint_path) - self.vocoder = ADaMoSHiFiGANV1.from_pretrained(vocoder_checkpoint_path) - - if source_sample_rate is None: - source_sample_rate = 48000 - - self.resampler = torchaudio.transforms.Resample(source_sample_rate, 44100) - - self.transform = transforms.Compose([ - transforms.Normalize(0.5, 0.5), - ]) - self.min_mel_value = -11.0 - self.max_mel_value = 3.0 - self.audio_chunk_size = int(round((1024 * 512 / 44100 * 48000))) - self.mel_chunk_size = 1024 - self.time_dimention_multiple = 8 - self.latent_chunk_size = self.mel_chunk_size // self.time_dimention_multiple - self.scale_factor = 0.1786 - self.shift_factor = -1.9091 - - def load_audio(self, audio_path): - audio, sr = torchaudio.load(audio_path) - return audio, sr - - def forward_mel(self, audios): - mels = [] - for i in range(len(audios)): - image = self.vocoder.mel_transform(audios[i]) - mels.append(image) - mels = torch.stack(mels) - return mels - - @torch.no_grad() - def encode(self, audios, audio_lengths=None, sr=None): - if audio_lengths is None: - audio_lengths = torch.tensor([audios.shape[2]] * audios.shape[0]) - audio_lengths = audio_lengths.to(audios.device) - - # audios: N x 2 x T, 48kHz - device = audios.device - dtype = audios.dtype - - if sr is None: - sr = 48000 - resampler = self.resampler - else: - resampler = torchaudio.transforms.Resample(sr, 44100).to(device).to(dtype) - - audio = resampler(audios) - - max_audio_len = audio.shape[-1] - if max_audio_len % (8 * 512) != 0: - audio = torch.nn.functional.pad(audio, (0, 8 * 512 - max_audio_len % (8 * 512))) - - mels = self.forward_mel(audio) - mels = (mels - self.min_mel_value) / (self.max_mel_value - self.min_mel_value) - mels = self.transform(mels) - latents = [] - for mel in mels: - latent = self.dcae.encoder(mel.unsqueeze(0)) - latents.append(latent) - latents = torch.cat(latents, dim=0) - latent_lengths = (audio_lengths / sr * 44100 / 512 / self.time_dimention_multiple).long() - latents = (latents - self.shift_factor) * self.scale_factor - return latents, latent_lengths - - @torch.no_grad() - def decode(self, latents, audio_lengths=None, sr=None): - latents = latents / self.scale_factor + self.shift_factor - - pred_wavs = [] - - for latent in latents: - mels = self.dcae.decoder(latent.unsqueeze(0)) - mels = mels * 0.5 + 0.5 - mels = mels * (self.max_mel_value - self.min_mel_value) + self.min_mel_value - wav = self.vocoder.decode(mels[0]).squeeze(1) - - if sr is not None: - resampler = torchaudio.transforms.Resample(44100, sr).to(latents.device).to(latents.dtype) - wav = resampler(wav) - else: - sr = 44100 - pred_wavs.append(wav) - - if audio_lengths is not None: - pred_wavs = [wav[:, :length].cpu() for wav, length in zip(pred_wavs, audio_lengths)] - return sr, pred_wavs - - def forward(self, audios, audio_lengths=None, sr=None): - latents, latent_lengths = self.encode(audios=audios, audio_lengths=audio_lengths, sr=sr) - sr, pred_wavs = self.decode(latents=latents, audio_lengths=audio_lengths, sr=sr) - return sr, pred_wavs, latents, latent_lengths - - -if __name__ == "__main__": - - audio, sr = torchaudio.load("test.wav") - audio_lengths = torch.tensor([audio.shape[1]]) - audios = audio.unsqueeze(0) - - # test encode only - model = MusicDCAE() - # latents, latent_lengths = model.encode(audios, audio_lengths) - # print("latents shape: ", latents.shape) - # print("latent_lengths: ", latent_lengths) - - # test encode and decode - sr, pred_wavs, latents, latent_lengths = model(audios, audio_lengths, sr) - print("reconstructed wavs: ", pred_wavs[0].shape) - print("latents shape: ", latents.shape) - print("latent_lengths: ", latent_lengths) - print("sr: ", sr) - torchaudio.save("test_reconstructed.flac", pred_wavs[0], sr) - print("test_reconstructed.flac") diff --git a/music_dcae/music_log_mel.py b/music_dcae/music_log_mel.py deleted file mode 100644 index 70a9bc5854375171a227844bb7fe73f24fae80a5..0000000000000000000000000000000000000000 --- a/music_dcae/music_log_mel.py +++ /dev/null @@ -1,107 +0,0 @@ -import torch -import torch.nn as nn -from torch import Tensor -from torchaudio.transforms import MelScale - - -class LinearSpectrogram(nn.Module): - def __init__( - self, - n_fft=2048, - win_length=2048, - hop_length=512, - center=False, - mode="pow2_sqrt", - ): - super().__init__() - - self.n_fft = n_fft - self.win_length = win_length - self.hop_length = hop_length - self.center = center - self.mode = mode - - self.register_buffer("window", torch.hann_window(win_length)) - - def forward(self, y: Tensor) -> Tensor: - if y.ndim == 3: - y = y.squeeze(1) - - y = torch.nn.functional.pad( - y.unsqueeze(1), - ( - (self.win_length - self.hop_length) // 2, - (self.win_length - self.hop_length + 1) // 2, - ), - mode="reflect", - ).squeeze(1) - dtype = y.dtype - spec = torch.stft( - y.float(), - self.n_fft, - hop_length=self.hop_length, - win_length=self.win_length, - window=self.window, - center=self.center, - pad_mode="reflect", - normalized=False, - onesided=True, - return_complex=True, - ) - spec = torch.view_as_real(spec) - - if self.mode == "pow2_sqrt": - spec = torch.sqrt(spec.pow(2).sum(-1) + 1e-6) - spec = spec.to(dtype) - return spec - - -class LogMelSpectrogram(nn.Module): - def __init__( - self, - sample_rate=44100, - n_fft=2048, - win_length=2048, - hop_length=512, - n_mels=128, - center=False, - f_min=0.0, - f_max=None, - ): - super().__init__() - - self.sample_rate = sample_rate - self.n_fft = n_fft - self.win_length = win_length - self.hop_length = hop_length - self.center = center - self.n_mels = n_mels - self.f_min = f_min - self.f_max = f_max or sample_rate // 2 - - self.spectrogram = LinearSpectrogram(n_fft, win_length, hop_length, center) - self.mel_scale = MelScale( - self.n_mels, - self.sample_rate, - self.f_min, - self.f_max, - self.n_fft // 2 + 1, - "slaney", - "slaney", - ) - - def compress(self, x: Tensor) -> Tensor: - return torch.log(torch.clamp(x, min=1e-5)) - - def decompress(self, x: Tensor) -> Tensor: - return torch.exp(x) - - def forward(self, x: Tensor, return_linear: bool = False) -> Tensor: - linear = self.spectrogram(x) - x = self.mel_scale(linear) - x = self.compress(x) - # print(x.shape) - if return_linear: - return x, self.compress(linear) - - return x diff --git a/music_dcae/music_vocoder.py b/music_dcae/music_vocoder.py deleted file mode 100644 index f0b7fcf8618f1cfa63847e50f15f51fd2a06b2f9..0000000000000000000000000000000000000000 --- a/music_dcae/music_vocoder.py +++ /dev/null @@ -1,576 +0,0 @@ -import librosa -import torch -from torch import nn - -from functools import partial -from math import prod -from typing import Callable, Tuple, List - -import numpy as np -import torch.nn.functional as F -from torch.nn import Conv1d -from torch.nn.utils import weight_norm -from torch.nn.utils.parametrize import remove_parametrizations as remove_weight_norm -from diffusers.models.modeling_utils import ModelMixin -from diffusers.loaders import FromOriginalModelMixin -from diffusers.configuration_utils import ConfigMixin, register_to_config - - -try: - from music_log_mel import LogMelSpectrogram -except ImportError: - from .music_log_mel import LogMelSpectrogram - - -def drop_path( - x, drop_prob: float = 0.0, training: bool = False, scale_by_keep: bool = True -): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - - This is the same as the DropConnect impl I created for EfficientNet, etc networks, however, - the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper... - See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for - changing the layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use - 'survival rate' as the argument. - - """ # noqa: E501 - - if drop_prob == 0.0 or not training: - return x - keep_prob = 1 - drop_prob - shape = (x.shape[0],) + (1,) * ( - x.ndim - 1 - ) # work with diff dim tensors, not just 2D ConvNets - random_tensor = x.new_empty(shape).bernoulli_(keep_prob) - if keep_prob > 0.0 and scale_by_keep: - random_tensor.div_(keep_prob) - return x * random_tensor - - -class DropPath(nn.Module): - """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).""" # noqa: E501 - - def __init__(self, drop_prob: float = 0.0, scale_by_keep: bool = True): - super(DropPath, self).__init__() - self.drop_prob = drop_prob - self.scale_by_keep = scale_by_keep - - def forward(self, x): - return drop_path(x, self.drop_prob, self.training, self.scale_by_keep) - - def extra_repr(self): - return f"drop_prob={round(self.drop_prob,3):0.3f}" - - -class LayerNorm(nn.Module): - r"""LayerNorm that supports two data formats: channels_last (default) or channels_first. - The ordering of the dimensions in the inputs. channels_last corresponds to inputs with - shape (batch_size, height, width, channels) while channels_first corresponds to inputs - with shape (batch_size, channels, height, width). - """ # noqa: E501 - - def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"): - super().__init__() - self.weight = nn.Parameter(torch.ones(normalized_shape)) - self.bias = nn.Parameter(torch.zeros(normalized_shape)) - self.eps = eps - self.data_format = data_format - if self.data_format not in ["channels_last", "channels_first"]: - raise NotImplementedError - self.normalized_shape = (normalized_shape,) - - def forward(self, x): - if self.data_format == "channels_last": - return F.layer_norm( - x, self.normalized_shape, self.weight, self.bias, self.eps - ) - elif self.data_format == "channels_first": - u = x.mean(1, keepdim=True) - s = (x - u).pow(2).mean(1, keepdim=True) - x = (x - u) / torch.sqrt(s + self.eps) - x = self.weight[:, None] * x + self.bias[:, None] - return x - - -class ConvNeXtBlock(nn.Module): - r"""ConvNeXt Block. There are two equivalent implementations: - (1) DwConv -> LayerNorm (channels_first) -> 1x1 Conv -> GELU -> 1x1 Conv; all in (N, C, H, W) - (2) DwConv -> Permute to (N, H, W, C); LayerNorm (channels_last) -> Linear -> GELU -> Linear; Permute back - We use (2) as we find it slightly faster in PyTorch - - Args: - dim (int): Number of input channels. - drop_path (float): Stochastic depth rate. Default: 0.0 - layer_scale_init_value (float): Init value for Layer Scale. Default: 1e-6. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4.0. - kernel_size (int): Kernel size for depthwise conv. Default: 7. - dilation (int): Dilation for depthwise conv. Default: 1. - """ # noqa: E501 - - def __init__( - self, - dim: int, - drop_path: float = 0.0, - layer_scale_init_value: float = 1e-6, - mlp_ratio: float = 4.0, - kernel_size: int = 7, - dilation: int = 1, - ): - super().__init__() - - self.dwconv = nn.Conv1d( - dim, - dim, - kernel_size=kernel_size, - padding=int(dilation * (kernel_size - 1) / 2), - groups=dim, - ) # depthwise conv - self.norm = LayerNorm(dim, eps=1e-6) - self.pwconv1 = nn.Linear( - dim, int(mlp_ratio * dim) - ) # pointwise/1x1 convs, implemented with linear layers - self.act = nn.GELU() - self.pwconv2 = nn.Linear(int(mlp_ratio * dim), dim) - self.gamma = ( - nn.Parameter(layer_scale_init_value * - torch.ones((dim)), requires_grad=True) - if layer_scale_init_value > 0 - else None - ) - self.drop_path = DropPath( - drop_path) if drop_path > 0.0 else nn.Identity() - - def forward(self, x, apply_residual: bool = True): - input = x - - x = self.dwconv(x) - x = x.permute(0, 2, 1) # (N, C, L) -> (N, L, C) - x = self.norm(x) - x = self.pwconv1(x) - x = self.act(x) - x = self.pwconv2(x) - - if self.gamma is not None: - x = self.gamma * x - - x = x.permute(0, 2, 1) # (N, L, C) -> (N, C, L) - x = self.drop_path(x) - - if apply_residual: - x = input + x - - return x - - -class ParallelConvNeXtBlock(nn.Module): - def __init__(self, kernel_sizes: List[int], *args, **kwargs): - super().__init__() - self.blocks = nn.ModuleList( - [ - ConvNeXtBlock(kernel_size=kernel_size, *args, **kwargs) - for kernel_size in kernel_sizes - ] - ) - - def forward(self, x: torch.Tensor) -> torch.Tensor: - return torch.stack( - [block(x, apply_residual=False) for block in self.blocks] + [x], - dim=1, - ).sum(dim=1) - - -class ConvNeXtEncoder(nn.Module): - def __init__( - self, - input_channels=3, - depths=[3, 3, 9, 3], - dims=[96, 192, 384, 768], - drop_path_rate=0.0, - layer_scale_init_value=1e-6, - kernel_sizes: Tuple[int] = (7,), - ): - super().__init__() - assert len(depths) == len(dims) - - self.channel_layers = nn.ModuleList() - stem = nn.Sequential( - nn.Conv1d( - input_channels, - dims[0], - kernel_size=7, - padding=3, - padding_mode="replicate", - ), - LayerNorm(dims[0], eps=1e-6, data_format="channels_first"), - ) - self.channel_layers.append(stem) - - for i in range(len(depths) - 1): - mid_layer = nn.Sequential( - LayerNorm(dims[i], eps=1e-6, data_format="channels_first"), - nn.Conv1d(dims[i], dims[i + 1], kernel_size=1), - ) - self.channel_layers.append(mid_layer) - - block_fn = ( - partial(ConvNeXtBlock, kernel_size=kernel_sizes[0]) - if len(kernel_sizes) == 1 - else partial(ParallelConvNeXtBlock, kernel_sizes=kernel_sizes) - ) - - self.stages = nn.ModuleList() - drop_path_rates = [ - x.item() for x in torch.linspace(0, drop_path_rate, sum(depths)) - ] - - cur = 0 - for i in range(len(depths)): - stage = nn.Sequential( - *[ - block_fn( - dim=dims[i], - drop_path=drop_path_rates[cur + j], - layer_scale_init_value=layer_scale_init_value, - ) - for j in range(depths[i]) - ] - ) - self.stages.append(stage) - cur += depths[i] - - self.norm = LayerNorm(dims[-1], eps=1e-6, data_format="channels_first") - self.apply(self._init_weights) - - def _init_weights(self, m): - if isinstance(m, (nn.Conv1d, nn.Linear)): - nn.init.trunc_normal_(m.weight, std=0.02) - nn.init.constant_(m.bias, 0) - - def forward( - self, - x: torch.Tensor, - ) -> torch.Tensor: - for channel_layer, stage in zip(self.channel_layers, self.stages): - x = channel_layer(x) - x = stage(x) - - return self.norm(x) - - -def init_weights(m, mean=0.0, std=0.01): - classname = m.__class__.__name__ - if classname.find("Conv") != -1: - m.weight.data.normal_(mean, std) - - -def get_padding(kernel_size, dilation=1): - return (kernel_size * dilation - dilation) // 2 - - -class ResBlock1(torch.nn.Module): - def __init__(self, channels, kernel_size=3, dilation=(1, 3, 5)): - super().__init__() - - self.convs1 = nn.ModuleList( - [ - weight_norm( - Conv1d( - channels, - channels, - kernel_size, - 1, - dilation=dilation[0], - padding=get_padding(kernel_size, dilation[0]), - ) - ), - weight_norm( - Conv1d( - channels, - channels, - kernel_size, - 1, - dilation=dilation[1], - padding=get_padding(kernel_size, dilation[1]), - ) - ), - weight_norm( - Conv1d( - channels, - channels, - kernel_size, - 1, - dilation=dilation[2], - padding=get_padding(kernel_size, dilation[2]), - ) - ), - ] - ) - self.convs1.apply(init_weights) - - self.convs2 = nn.ModuleList( - [ - weight_norm( - Conv1d( - channels, - channels, - kernel_size, - 1, - dilation=1, - padding=get_padding(kernel_size, 1), - ) - ), - weight_norm( - Conv1d( - channels, - channels, - kernel_size, - 1, - dilation=1, - padding=get_padding(kernel_size, 1), - ) - ), - weight_norm( - Conv1d( - channels, - channels, - kernel_size, - 1, - dilation=1, - padding=get_padding(kernel_size, 1), - ) - ), - ] - ) - self.convs2.apply(init_weights) - - def forward(self, x): - for c1, c2 in zip(self.convs1, self.convs2): - xt = F.silu(x) - xt = c1(xt) - xt = F.silu(xt) - xt = c2(xt) - x = xt + x - return x - - def remove_weight_norm(self): - for conv in self.convs1: - remove_weight_norm(conv) - for conv in self.convs2: - remove_weight_norm(conv) - - -class HiFiGANGenerator(nn.Module): - def __init__( - self, - *, - hop_length: int = 512, - upsample_rates: Tuple[int] = (8, 8, 2, 2, 2), - upsample_kernel_sizes: Tuple[int] = (16, 16, 8, 2, 2), - resblock_kernel_sizes: Tuple[int] = (3, 7, 11), - resblock_dilation_sizes: Tuple[Tuple[int]] = ( - (1, 3, 5), (1, 3, 5), (1, 3, 5)), - num_mels: int = 128, - upsample_initial_channel: int = 512, - use_template: bool = True, - pre_conv_kernel_size: int = 7, - post_conv_kernel_size: int = 7, - post_activation: Callable = partial(nn.SiLU, inplace=True), - ): - super().__init__() - - assert ( - prod(upsample_rates) == hop_length - ), f"hop_length must be {prod(upsample_rates)}" - - self.conv_pre = weight_norm( - nn.Conv1d( - num_mels, - upsample_initial_channel, - pre_conv_kernel_size, - 1, - padding=get_padding(pre_conv_kernel_size), - ) - ) - - self.num_upsamples = len(upsample_rates) - self.num_kernels = len(resblock_kernel_sizes) - - self.noise_convs = nn.ModuleList() - self.use_template = use_template - self.ups = nn.ModuleList() - - for i, (u, k) in enumerate(zip(upsample_rates, upsample_kernel_sizes)): - c_cur = upsample_initial_channel // (2 ** (i + 1)) - self.ups.append( - weight_norm( - nn.ConvTranspose1d( - upsample_initial_channel // (2**i), - upsample_initial_channel // (2 ** (i + 1)), - k, - u, - padding=(k - u) // 2, - ) - ) - ) - - if not use_template: - continue - - if i + 1 < len(upsample_rates): - stride_f0 = np.prod(upsample_rates[i + 1:]) - self.noise_convs.append( - Conv1d( - 1, - c_cur, - kernel_size=stride_f0 * 2, - stride=stride_f0, - padding=stride_f0 // 2, - ) - ) - else: - self.noise_convs.append(Conv1d(1, c_cur, kernel_size=1)) - - self.resblocks = nn.ModuleList() - for i in range(len(self.ups)): - ch = upsample_initial_channel // (2 ** (i + 1)) - for k, d in zip(resblock_kernel_sizes, resblock_dilation_sizes): - self.resblocks.append(ResBlock1(ch, k, d)) - - self.activation_post = post_activation() - self.conv_post = weight_norm( - nn.Conv1d( - ch, - 1, - post_conv_kernel_size, - 1, - padding=get_padding(post_conv_kernel_size), - ) - ) - self.ups.apply(init_weights) - self.conv_post.apply(init_weights) - - def forward(self, x, template=None): - x = self.conv_pre(x) - - for i in range(self.num_upsamples): - x = F.silu(x, inplace=True) - x = self.ups[i](x) - - if self.use_template: - x = x + self.noise_convs[i](template) - - xs = None - - for j in range(self.num_kernels): - if xs is None: - xs = self.resblocks[i * self.num_kernels + j](x) - else: - xs += self.resblocks[i * self.num_kernels + j](x) - - x = xs / self.num_kernels - - x = self.activation_post(x) - x = self.conv_post(x) - x = torch.tanh(x) - - return x - - def remove_weight_norm(self): - for up in self.ups: - remove_weight_norm(up) - for block in self.resblocks: - block.remove_weight_norm() - remove_weight_norm(self.conv_pre) - remove_weight_norm(self.conv_post) - - -class ADaMoSHiFiGANV1(ModelMixin, ConfigMixin, FromOriginalModelMixin): - - @register_to_config - def __init__( - self, - input_channels: int = 128, - depths: List[int] = [3, 3, 9, 3], - dims: List[int] = [128, 256, 384, 512], - drop_path_rate: float = 0.0, - kernel_sizes: Tuple[int] = (7,), - upsample_rates: Tuple[int] = (4, 4, 2, 2, 2, 2, 2), - upsample_kernel_sizes: Tuple[int] = (8, 8, 4, 4, 4, 4, 4), - resblock_kernel_sizes: Tuple[int] = (3, 7, 11, 13), - resblock_dilation_sizes: Tuple[Tuple[int]] = ( - (1, 3, 5), (1, 3, 5), (1, 3, 5), (1, 3, 5)), - num_mels: int = 512, - upsample_initial_channel: int = 1024, - use_template: bool = False, - pre_conv_kernel_size: int = 13, - post_conv_kernel_size: int = 13, - sampling_rate: int = 44100, - n_fft: int = 2048, - win_length: int = 2048, - hop_length: int = 512, - f_min: int = 40, - f_max: int = 16000, - n_mels: int = 128, - ): - super().__init__() - - self.backbone = ConvNeXtEncoder( - input_channels=input_channels, - depths=depths, - dims=dims, - drop_path_rate=drop_path_rate, - kernel_sizes=kernel_sizes, - ) - - self.head = HiFiGANGenerator( - hop_length=hop_length, - upsample_rates=upsample_rates, - upsample_kernel_sizes=upsample_kernel_sizes, - resblock_kernel_sizes=resblock_kernel_sizes, - resblock_dilation_sizes=resblock_dilation_sizes, - num_mels=num_mels, - upsample_initial_channel=upsample_initial_channel, - use_template=use_template, - pre_conv_kernel_size=pre_conv_kernel_size, - post_conv_kernel_size=post_conv_kernel_size, - ) - self.sampling_rate = sampling_rate - self.mel_transform = LogMelSpectrogram( - sample_rate=sampling_rate, - n_fft=n_fft, - win_length=win_length, - hop_length=hop_length, - f_min=f_min, - f_max=f_max, - n_mels=n_mels, - ) - self.eval() - - @torch.no_grad() - def decode(self, mel): - y = self.backbone(mel) - y = self.head(y) - return y - - @torch.no_grad() - def encode(self, x): - return self.mel_transform(x) - - def forward(self, mel): - y = self.backbone(mel) - y = self.head(y) - return y - - -if __name__ == "__main__": - import soundfile as sf - - x = "test_audio.flac" - model = ADaMoSHiFiGANV1.from_pretrained("./checkpoints/music_vocoder", local_files_only=True) - - wav, sr = librosa.load(x, sr=44100, mono=True) - wav = torch.from_numpy(wav).float()[None] - mel = model.encode(wav) - - wav = model.decode(mel)[0].mT - sf.write("test_audio_vocoder_rec.flac", wav.cpu().numpy(), 44100) diff --git a/packages.txt b/packages.txt deleted file mode 100644 index a9f1eea092d5e971b5475b82ee835cec7f196bad..0000000000000000000000000000000000000000 --- a/packages.txt +++ /dev/null @@ -1 +0,0 @@ -ffmpeg \ No newline at end of file diff --git a/pipeline_ace_step.py b/pipeline_ace_step.py deleted file mode 100644 index 953de2ce75a7e0cd528e0c6806e13134a12b3ab7..0000000000000000000000000000000000000000 --- a/pipeline_ace_step.py +++ /dev/null @@ -1,1744 +0,0 @@ -import random -import time -import os -import re -import spaces -import torch -import torch.nn as nn -from loguru import logger -from tqdm import tqdm -import json -import math -from huggingface_hub import hf_hub_download, snapshot_download - -# from diffusers.pipelines.pipeline_utils import DiffusionPipeline -from schedulers.scheduling_flow_match_euler_discrete import ( - FlowMatchEulerDiscreteScheduler, -) -from schedulers.scheduling_flow_match_heun_discrete import ( - FlowMatchHeunDiscreteScheduler, -) -from diffusers.pipelines.stable_diffusion_3.pipeline_stable_diffusion_3 import ( - retrieve_timesteps, -) -from diffusers.utils.torch_utils import randn_tensor -from transformers import UMT5EncoderModel, AutoTokenizer - -from language_segmentation import LangSegment -from music_dcae.music_dcae_pipeline import MusicDCAE -from models.ace_step_transformer import ACEStepTransformer2DModel -from models.lyrics_utils.lyric_tokenizer import VoiceBpeTokenizer -from apg_guidance import ( - apg_forward, - MomentumBuffer, - cfg_forward, - cfg_zero_star, - cfg_double_condition_forward, -) -import torchaudio -import torio - - -torch.backends.cudnn.benchmark = False -torch.set_float32_matmul_precision("high") -torch.backends.cudnn.deterministic = True -torch.backends.cuda.matmul.allow_tf32 = True -os.environ["TOKENIZERS_PARALLELISM"] = "false" - - -SUPPORT_LANGUAGES = { - "en": 259, - "de": 260, - "fr": 262, - "es": 284, - "it": 285, - "pt": 286, - "pl": 294, - "tr": 295, - "ru": 267, - "cs": 293, - "nl": 297, - "ar": 5022, - "zh": 5023, - "ja": 5412, - "hu": 5753, - "ko": 6152, - "hi": 6680, -} - -structure_pattern = re.compile(r"\[.*?\]") - - -def ensure_directory_exists(directory): - directory = str(directory) - if not os.path.exists(directory): - os.makedirs(directory) - - -REPO_ID = "ACE-Step/ACE-Step-v1-3.5B" - - -# class ACEStepPipeline(DiffusionPipeline): -class ACEStepPipeline: - - def __init__( - self, - checkpoint_dir=None, - device_id=0, - dtype="bfloat16", - text_encoder_checkpoint_path=None, - persistent_storage_path=None, - torch_compile=False, - **kwargs, - ): - if not checkpoint_dir: - if persistent_storage_path is None: - checkpoint_dir = os.path.join(os.path.dirname(__file__), "checkpoints") - else: - checkpoint_dir = os.path.join(persistent_storage_path, "checkpoints") - ensure_directory_exists(checkpoint_dir) - self.checkpoint_dir = checkpoint_dir - device = ( - torch.device(f"cuda:{device_id}") - if torch.cuda.is_available() - else torch.device("cpu") - ) - if device.type == "cpu" and torch.backends.mps.is_available(): - device = torch.device("mps") - self.dtype = torch.bfloat16 if dtype == "bfloat16" else torch.float32 - if device.type == "mps": - self.dtype = torch.float32 - self.device = device - self.loaded = False - self.torch_compile = torch_compile - self.lora_path = "none" - - def load_lora(self, lora_name_or_path): - if lora_name_or_path != self.lora_path and lora_name_or_path != "none": - if not os.path.exists(lora_name_or_path): - lora_download_path = snapshot_download( - lora_name_or_path, cache_dir=self.checkpoint_dir - ) - else: - lora_download_path = lora_name_or_path - if self.lora_path != "none": - self.ace_step_transformer.unload_lora() - self.ace_step_transformer.load_lora_adapter( - os.path.join(lora_download_path, "pytorch_lora_weights.safetensors"), - adapter_name="zh_rap_lora", - with_alpha=True, - ) - logger.info( - f"Loading lora weights from: {lora_name_or_path} download path is: {lora_download_path}" - ) - self.lora_path = lora_name_or_path - elif self.lora_path != "none" and lora_name_or_path == "none": - logger.info("No lora weights to load.") - self.ace_step_transformer.unload_lora() - - def load_checkpoint(self, checkpoint_dir=None): - device = self.device - - dcae_model_path = os.path.join(checkpoint_dir, "music_dcae_f8c8") - vocoder_model_path = os.path.join(checkpoint_dir, "music_vocoder") - ace_step_model_path = os.path.join(checkpoint_dir, "ace_step_transformer") - text_encoder_model_path = os.path.join(checkpoint_dir, "umt5-base") - - files_exist = ( - os.path.exists(os.path.join(dcae_model_path, "config.json")) - and os.path.exists( - os.path.join(dcae_model_path, "diffusion_pytorch_model.safetensors") - ) - and os.path.exists(os.path.join(vocoder_model_path, "config.json")) - and os.path.exists( - os.path.join(vocoder_model_path, "diffusion_pytorch_model.safetensors") - ) - and os.path.exists(os.path.join(ace_step_model_path, "config.json")) - and os.path.exists( - os.path.join(ace_step_model_path, "diffusion_pytorch_model.safetensors") - ) - and os.path.exists(os.path.join(text_encoder_model_path, "config.json")) - and os.path.exists( - os.path.join(text_encoder_model_path, "model.safetensors") - ) - and os.path.exists( - os.path.join(text_encoder_model_path, "special_tokens_map.json") - ) - and os.path.exists( - os.path.join(text_encoder_model_path, "tokenizer_config.json") - ) - and os.path.exists(os.path.join(text_encoder_model_path, "tokenizer.json")) - ) - - if not files_exist: - logger.info( - f"Checkpoint directory {checkpoint_dir} is not complete, downloading from Hugging Face Hub" - ) - - # download music dcae model - os.makedirs(dcae_model_path, exist_ok=True) - hf_hub_download( - repo_id=REPO_ID, - subfolder="music_dcae_f8c8", - filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - hf_hub_download( - repo_id=REPO_ID, - subfolder="music_dcae_f8c8", - filename="diffusion_pytorch_model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - - # download vocoder model - os.makedirs(vocoder_model_path, exist_ok=True) - hf_hub_download( - repo_id=REPO_ID, - subfolder="music_vocoder", - filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - hf_hub_download( - repo_id=REPO_ID, - subfolder="music_vocoder", - filename="diffusion_pytorch_model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - - # download ace_step transformer model - os.makedirs(ace_step_model_path, exist_ok=True) - hf_hub_download( - repo_id=REPO_ID, - subfolder="ace_step_transformer", - filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - hf_hub_download( - repo_id=REPO_ID, - subfolder="ace_step_transformer", - filename="diffusion_pytorch_model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - - # download text encoder model - os.makedirs(text_encoder_model_path, exist_ok=True) - hf_hub_download( - repo_id=REPO_ID, - subfolder="umt5-base", - filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - hf_hub_download( - repo_id=REPO_ID, - subfolder="umt5-base", - filename="model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - hf_hub_download( - repo_id=REPO_ID, - subfolder="umt5-base", - filename="special_tokens_map.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - hf_hub_download( - repo_id=REPO_ID, - subfolder="umt5-base", - filename="tokenizer_config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - hf_hub_download( - repo_id=REPO_ID, - subfolder="umt5-base", - filename="tokenizer.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, - ) - - logger.info("Models downloaded") - - dcae_checkpoint_path = dcae_model_path - vocoder_checkpoint_path = vocoder_model_path - ace_step_checkpoint_path = ace_step_model_path - text_encoder_checkpoint_path = text_encoder_model_path - - self.music_dcae = MusicDCAE( - dcae_checkpoint_path=dcae_checkpoint_path, - vocoder_checkpoint_path=vocoder_checkpoint_path, - ) - self.music_dcae.to(device).eval().to(self.dtype) - - self.ace_step_transformer = ACEStepTransformer2DModel.from_pretrained( - ace_step_checkpoint_path, torch_dtype=self.dtype - ) - self.ace_step_transformer.to(device).eval().to(self.dtype) - - lang_segment = LangSegment() - - lang_segment.setfilters( - [ - "af", - "am", - "an", - "ar", - "as", - "az", - "be", - "bg", - "bn", - "br", - "bs", - "ca", - "cs", - "cy", - "da", - "de", - "dz", - "el", - "en", - "eo", - "es", - "et", - "eu", - "fa", - "fi", - "fo", - "fr", - "ga", - "gl", - "gu", - "he", - "hi", - "hr", - "ht", - "hu", - "hy", - "id", - "is", - "it", - "ja", - "jv", - "ka", - "kk", - "km", - "kn", - "ko", - "ku", - "ky", - "la", - "lb", - "lo", - "lt", - "lv", - "mg", - "mk", - "ml", - "mn", - "mr", - "ms", - "mt", - "nb", - "ne", - "nl", - "nn", - "no", - "oc", - "or", - "pa", - "pl", - "ps", - "pt", - "qu", - "ro", - "ru", - "rw", - "se", - "si", - "sk", - "sl", - "sq", - "sr", - "sv", - "sw", - "ta", - "te", - "th", - "tl", - "tr", - "ug", - "uk", - "ur", - "vi", - "vo", - "wa", - "xh", - "zh", - "zu", - ] - ) - self.lang_segment = lang_segment - self.lyric_tokenizer = VoiceBpeTokenizer() - text_encoder_model = UMT5EncoderModel.from_pretrained( - text_encoder_checkpoint_path, torch_dtype=self.dtype - ).eval() - text_encoder_model = text_encoder_model.to(device).to(self.dtype) - text_encoder_model.requires_grad_(False) - self.text_encoder_model = text_encoder_model - self.text_tokenizer = AutoTokenizer.from_pretrained( - text_encoder_checkpoint_path - ) - self.loaded = True - - # compile - if self.torch_compile: - self.music_dcae = torch.compile(self.music_dcae) - self.ace_step_transformer = torch.compile(self.ace_step_transformer) - self.text_encoder_model = torch.compile(self.text_encoder_model) - - def get_text_embeddings(self, texts, device, text_max_length=256): - inputs = self.text_tokenizer( - texts, - return_tensors="pt", - padding=True, - truncation=True, - max_length=text_max_length, - ) - inputs = {key: value.to(device) for key, value in inputs.items()} - if self.text_encoder_model.device != device: - self.text_encoder_model.to(device) - with torch.no_grad(): - outputs = self.text_encoder_model(**inputs) - last_hidden_states = outputs.last_hidden_state - attention_mask = inputs["attention_mask"] - return last_hidden_states, attention_mask - - def get_text_embeddings_null( - self, texts, device, text_max_length=256, tau=0.01, l_min=8, l_max=10 - ): - inputs = self.text_tokenizer( - texts, - return_tensors="pt", - padding=True, - truncation=True, - max_length=text_max_length, - ) - inputs = {key: value.to(device) for key, value in inputs.items()} - if self.text_encoder_model.device != device: - self.text_encoder_model.to(device) - - def forward_with_temperature(inputs, tau=0.01, l_min=8, l_max=10): - handlers = [] - - def hook(module, input, output): - output[:] *= tau - return output - - for i in range(l_min, l_max): - handler = ( - self.text_encoder_model.encoder.block[i] - .layer[0] - .SelfAttention.q.register_forward_hook(hook) - ) - handlers.append(handler) - - with torch.no_grad(): - outputs = self.text_encoder_model(**inputs) - last_hidden_states = outputs.last_hidden_state - - for hook in handlers: - hook.remove() - - return last_hidden_states - - last_hidden_states = forward_with_temperature(inputs, tau, l_min, l_max) - return last_hidden_states - - def set_seeds(self, batch_size, manual_seeds=None): - processed_input_seeds = None - if manual_seeds is not None: - if isinstance(manual_seeds, str): - if "," in manual_seeds: - processed_input_seeds = list(map(int, manual_seeds.split(","))) - elif manual_seeds.isdigit(): - processed_input_seeds = int(manual_seeds) - elif isinstance(manual_seeds, list) and all( - isinstance(s, int) for s in manual_seeds - ): - if len(manual_seeds) > 0: - processed_input_seeds = list(manual_seeds) - elif isinstance(manual_seeds, int): - processed_input_seeds = manual_seeds - random_generators = [ - torch.Generator(device=self.device) for _ in range(batch_size) - ] - actual_seeds = [] - for i in range(batch_size): - current_seed_for_generator = None - if processed_input_seeds is None: - current_seed_for_generator = torch.randint(0, 2**32, (1,)).item() - elif isinstance(processed_input_seeds, int): - current_seed_for_generator = processed_input_seeds - elif isinstance(processed_input_seeds, list): - if i < len(processed_input_seeds): - current_seed_for_generator = processed_input_seeds[i] - else: - current_seed_for_generator = processed_input_seeds[-1] - if current_seed_for_generator is None: - current_seed_for_generator = torch.randint(0, 2**32, (1,)).item() - random_generators[i].manual_seed(current_seed_for_generator) - actual_seeds.append(current_seed_for_generator) - return random_generators, actual_seeds - - def get_lang(self, text): - language = "en" - try: - _ = self.lang_segment.getTexts(text) - langCounts = self.lang_segment.getCounts() - language = langCounts[0][0] - if len(langCounts) > 1 and language == "en": - language = langCounts[1][0] - except Exception as err: - language = "en" - return language - - def tokenize_lyrics(self, lyrics, debug=False): - lines = lyrics.split("\n") - lyric_token_idx = [261] - for line in lines: - line = line.strip() - if not line: - lyric_token_idx += [2] - continue - - lang = self.get_lang(line) - - if lang not in SUPPORT_LANGUAGES: - lang = "en" - if "zh" in lang: - lang = "zh" - if "spa" in lang: - lang = "es" - - try: - if structure_pattern.match(line): - token_idx = self.lyric_tokenizer.encode(line, "en") - else: - token_idx = self.lyric_tokenizer.encode(line, lang) - if debug: - toks = self.lyric_tokenizer.batch_decode( - [[tok_id] for tok_id in token_idx] - ) - logger.info(f"debbug {line} --> {lang} --> {toks}") - lyric_token_idx = lyric_token_idx + token_idx + [2] - except Exception as e: - print("tokenize error", e, "for line", line, "major_language", lang) - return lyric_token_idx - - def calc_v( - self, - zt_src, - zt_tar, - t, - encoder_text_hidden_states, - text_attention_mask, - target_encoder_text_hidden_states, - target_text_attention_mask, - speaker_embds, - target_speaker_embeds, - lyric_token_ids, - lyric_mask, - target_lyric_token_ids, - target_lyric_mask, - do_classifier_free_guidance=False, - guidance_scale=1.0, - target_guidance_scale=1.0, - cfg_type="apg", - attention_mask=None, - momentum_buffer=None, - momentum_buffer_tar=None, - return_src_pred=True, - ): - noise_pred_src = None - if return_src_pred: - src_latent_model_input = ( - torch.cat([zt_src, zt_src]) if do_classifier_free_guidance else zt_src - ) - timestep = t.expand(src_latent_model_input.shape[0]) - # source - noise_pred_src = self.ace_step_transformer( - hidden_states=src_latent_model_input, - attention_mask=attention_mask, - encoder_text_hidden_states=encoder_text_hidden_states, - text_attention_mask=text_attention_mask, - speaker_embeds=speaker_embds, - lyric_token_idx=lyric_token_ids, - lyric_mask=lyric_mask, - timestep=timestep, - ).sample - - if do_classifier_free_guidance: - noise_pred_with_cond_src, noise_pred_uncond_src = noise_pred_src.chunk( - 2 - ) - if cfg_type == "apg": - noise_pred_src = apg_forward( - pred_cond=noise_pred_with_cond_src, - pred_uncond=noise_pred_uncond_src, - guidance_scale=guidance_scale, - momentum_buffer=momentum_buffer, - ) - elif cfg_type == "cfg": - noise_pred_src = cfg_forward( - cond_output=noise_pred_with_cond_src, - uncond_output=noise_pred_uncond_src, - cfg_strength=guidance_scale, - ) - - tar_latent_model_input = ( - torch.cat([zt_tar, zt_tar]) if do_classifier_free_guidance else zt_tar - ) - timestep = t.expand(tar_latent_model_input.shape[0]) - # target - noise_pred_tar = self.ace_step_transformer( - hidden_states=tar_latent_model_input, - attention_mask=attention_mask, - encoder_text_hidden_states=target_encoder_text_hidden_states, - text_attention_mask=target_text_attention_mask, - speaker_embeds=target_speaker_embeds, - lyric_token_idx=target_lyric_token_ids, - lyric_mask=target_lyric_mask, - timestep=timestep, - ).sample - - if do_classifier_free_guidance: - noise_pred_with_cond_tar, noise_pred_uncond_tar = noise_pred_tar.chunk(2) - if cfg_type == "apg": - noise_pred_tar = apg_forward( - pred_cond=noise_pred_with_cond_tar, - pred_uncond=noise_pred_uncond_tar, - guidance_scale=target_guidance_scale, - momentum_buffer=momentum_buffer_tar, - ) - elif cfg_type == "cfg": - noise_pred_tar = cfg_forward( - cond_output=noise_pred_with_cond_tar, - uncond_output=noise_pred_uncond_tar, - cfg_strength=target_guidance_scale, - ) - return noise_pred_src, noise_pred_tar - - @torch.no_grad() - def flowedit_diffusion_process( - self, - encoder_text_hidden_states, - text_attention_mask, - speaker_embds, - lyric_token_ids, - lyric_mask, - target_encoder_text_hidden_states, - target_text_attention_mask, - target_speaker_embeds, - target_lyric_token_ids, - target_lyric_mask, - src_latents, - random_generators=None, - infer_steps=60, - guidance_scale=15.0, - n_min=0, - n_max=1.0, - n_avg=1, - ): - - do_classifier_free_guidance = True - if guidance_scale == 0.0 or guidance_scale == 1.0: - do_classifier_free_guidance = False - - target_guidance_scale = guidance_scale - device = encoder_text_hidden_states.device - dtype = encoder_text_hidden_states.dtype - bsz = encoder_text_hidden_states.shape[0] - - scheduler = FlowMatchEulerDiscreteScheduler( - num_train_timesteps=1000, - shift=3.0, - ) - - T_steps = infer_steps - frame_length = src_latents.shape[-1] - attention_mask = torch.ones(bsz, frame_length, device=device, dtype=dtype) - - timesteps, T_steps = retrieve_timesteps( - scheduler, T_steps, device, timesteps=None - ) - - if do_classifier_free_guidance: - attention_mask = torch.cat([attention_mask] * 2, dim=0) - - encoder_text_hidden_states = torch.cat( - [ - encoder_text_hidden_states, - torch.zeros_like(encoder_text_hidden_states), - ], - 0, - ) - text_attention_mask = torch.cat([text_attention_mask] * 2, dim=0) - - target_encoder_text_hidden_states = torch.cat( - [ - target_encoder_text_hidden_states, - torch.zeros_like(target_encoder_text_hidden_states), - ], - 0, - ) - target_text_attention_mask = torch.cat( - [target_text_attention_mask] * 2, dim=0 - ) - - speaker_embds = torch.cat( - [speaker_embds, torch.zeros_like(speaker_embds)], 0 - ) - target_speaker_embeds = torch.cat( - [target_speaker_embeds, torch.zeros_like(target_speaker_embeds)], 0 - ) - - lyric_token_ids = torch.cat( - [lyric_token_ids, torch.zeros_like(lyric_token_ids)], 0 - ) - lyric_mask = torch.cat([lyric_mask, torch.zeros_like(lyric_mask)], 0) - - target_lyric_token_ids = torch.cat( - [target_lyric_token_ids, torch.zeros_like(target_lyric_token_ids)], 0 - ) - target_lyric_mask = torch.cat( - [target_lyric_mask, torch.zeros_like(target_lyric_mask)], 0 - ) - - momentum_buffer = MomentumBuffer() - momentum_buffer_tar = MomentumBuffer() - x_src = src_latents - zt_edit = x_src.clone() - xt_tar = None - n_min = int(infer_steps * n_min) - n_max = int(infer_steps * n_max) - - logger.info("flowedit start from {} to {}".format(n_min, n_max)) - - for i, t in tqdm(enumerate(timesteps), total=T_steps): - - if i < n_min: - continue - - t_i = t / 1000 - - if i + 1 < len(timesteps): - t_im1 = (timesteps[i + 1]) / 1000 - else: - t_im1 = torch.zeros_like(t_i).to(t_i.device) - - if i < n_max: - # Calculate the average of the V predictions - V_delta_avg = torch.zeros_like(x_src) - for k in range(n_avg): - fwd_noise = randn_tensor( - shape=x_src.shape, - generator=random_generators, - device=device, - dtype=dtype, - ) - - zt_src = (1 - t_i) * x_src + (t_i) * fwd_noise - - zt_tar = zt_edit + zt_src - x_src - - Vt_src, Vt_tar = self.calc_v( - zt_src=zt_src, - zt_tar=zt_tar, - t=t, - encoder_text_hidden_states=encoder_text_hidden_states, - text_attention_mask=text_attention_mask, - target_encoder_text_hidden_states=target_encoder_text_hidden_states, - target_text_attention_mask=target_text_attention_mask, - speaker_embds=speaker_embds, - target_speaker_embeds=target_speaker_embeds, - lyric_token_ids=lyric_token_ids, - lyric_mask=lyric_mask, - target_lyric_token_ids=target_lyric_token_ids, - target_lyric_mask=target_lyric_mask, - do_classifier_free_guidance=do_classifier_free_guidance, - guidance_scale=guidance_scale, - target_guidance_scale=target_guidance_scale, - attention_mask=attention_mask, - momentum_buffer=momentum_buffer, - ) - V_delta_avg += (1 / n_avg) * ( - Vt_tar - Vt_src - ) # - (hfg-1)*( x_src)) - - # propagate direct ODE - zt_edit = zt_edit.to(torch.float32) - zt_edit = zt_edit + (t_im1 - t_i) * V_delta_avg - zt_edit = zt_edit.to(V_delta_avg.dtype) - else: # i >= T_steps-n_min # regular sampling for last n_min steps - if i == n_max: - fwd_noise = randn_tensor( - shape=x_src.shape, - generator=random_generators, - device=device, - dtype=dtype, - ) - scheduler._init_step_index(t) - sigma = scheduler.sigmas[scheduler.step_index] - xt_src = sigma * fwd_noise + (1.0 - sigma) * x_src - xt_tar = zt_edit + xt_src - x_src - - _, Vt_tar = self.calc_v( - zt_src=None, - zt_tar=xt_tar, - t=t, - encoder_text_hidden_states=encoder_text_hidden_states, - text_attention_mask=text_attention_mask, - target_encoder_text_hidden_states=target_encoder_text_hidden_states, - target_text_attention_mask=target_text_attention_mask, - speaker_embds=speaker_embds, - target_speaker_embeds=target_speaker_embeds, - lyric_token_ids=lyric_token_ids, - lyric_mask=lyric_mask, - target_lyric_token_ids=target_lyric_token_ids, - target_lyric_mask=target_lyric_mask, - do_classifier_free_guidance=do_classifier_free_guidance, - guidance_scale=guidance_scale, - target_guidance_scale=target_guidance_scale, - attention_mask=attention_mask, - momentum_buffer_tar=momentum_buffer_tar, - return_src_pred=False, - ) - - dtype = Vt_tar.dtype - xt_tar = xt_tar.to(torch.float32) - prev_sample = xt_tar + (t_im1 - t_i) * Vt_tar - prev_sample = prev_sample.to(dtype) - xt_tar = prev_sample - - target_latents = zt_edit if xt_tar is None else xt_tar - return target_latents - - def add_latents_noise( - self, - gt_latents, - variance, - noise, - scheduler, - ): - - bsz = gt_latents.shape[0] - u = torch.tensor([variance] * bsz, dtype=gt_latents.dtype) - indices = (u * scheduler.config.num_train_timesteps).long() - timesteps = scheduler.timesteps.unsqueeze(1).to(gt_latents.dtype) - indices = indices.to(timesteps.device).to(gt_latents.dtype).unsqueeze(1) - nearest_idx = torch.argmin(torch.cdist(indices, timesteps), dim=1) - sigma = ( - scheduler.sigmas[nearest_idx] - .flatten() - .to(gt_latents.device) - .to(gt_latents.dtype) - ) - while len(sigma.shape) < gt_latents.ndim: - sigma = sigma.unsqueeze(-1) - noisy_image = sigma * noise + (1.0 - sigma) * gt_latents - init_timestep = indices[0] - return noisy_image, init_timestep - - @torch.no_grad() - def text2music_diffusion_process( - self, - duration, - encoder_text_hidden_states, - text_attention_mask, - speaker_embds, - lyric_token_ids, - lyric_mask, - random_generators=None, - infer_steps=60, - guidance_scale=15.0, - omega_scale=10.0, - scheduler_type="euler", - cfg_type="apg", - zero_steps=1, - use_zero_init=True, - guidance_interval=0.5, - guidance_interval_decay=1.0, - min_guidance_scale=3.0, - oss_steps=[], - encoder_text_hidden_states_null=None, - use_erg_lyric=False, - use_erg_diffusion=False, - retake_random_generators=None, - retake_variance=0.5, - add_retake_noise=False, - guidance_scale_text=0.0, - guidance_scale_lyric=0.0, - repaint_start=0, - repaint_end=0, - src_latents=None, - audio2audio_enable=False, - ref_audio_strength=0.5, - ref_latents=None, - ): - - logger.info( - "cfg_type: {}, guidance_scale: {}, omega_scale: {}".format( - cfg_type, guidance_scale, omega_scale - ) - ) - do_classifier_free_guidance = True - if guidance_scale == 0.0 or guidance_scale == 1.0: - do_classifier_free_guidance = False - - do_double_condition_guidance = False - if ( - guidance_scale_text is not None - and guidance_scale_text > 1.0 - and guidance_scale_lyric is not None - and guidance_scale_lyric > 1.0 - ): - do_double_condition_guidance = True - logger.info( - "do_double_condition_guidance: {}, guidance_scale_text: {}, guidance_scale_lyric: {}".format( - do_double_condition_guidance, - guidance_scale_text, - guidance_scale_lyric, - ) - ) - - device = encoder_text_hidden_states.device - dtype = encoder_text_hidden_states.dtype - bsz = encoder_text_hidden_states.shape[0] - - if scheduler_type == "euler": - scheduler = FlowMatchEulerDiscreteScheduler( - num_train_timesteps=1000, - shift=3.0, - ) - elif scheduler_type == "heun": - scheduler = FlowMatchHeunDiscreteScheduler( - num_train_timesteps=1000, - shift=3.0, - ) - - frame_length = int(duration * 44100 / 512 / 8) - if src_latents is not None: - frame_length = src_latents.shape[-1] - - if ref_latents is not None: - frame_length = ref_latents.shape[-1] - - if len(oss_steps) > 0: - infer_steps = max(oss_steps) - scheduler.set_timesteps - timesteps, num_inference_steps = retrieve_timesteps( - scheduler, - num_inference_steps=infer_steps, - device=device, - timesteps=None, - ) - new_timesteps = torch.zeros(len(oss_steps), dtype=dtype, device=device) - for idx in range(len(oss_steps)): - new_timesteps[idx] = timesteps[oss_steps[idx] - 1] - num_inference_steps = len(oss_steps) - sigmas = (new_timesteps / 1000).float().cpu().numpy() - timesteps, num_inference_steps = retrieve_timesteps( - scheduler, - num_inference_steps=num_inference_steps, - device=device, - sigmas=sigmas, - ) - logger.info( - f"oss_steps: {oss_steps}, num_inference_steps: {num_inference_steps} after remapping to timesteps {timesteps}" - ) - else: - timesteps, num_inference_steps = retrieve_timesteps( - scheduler, - num_inference_steps=infer_steps, - device=device, - timesteps=None, - ) - - target_latents = randn_tensor( - shape=(bsz, 8, 16, frame_length), - generator=random_generators, - device=device, - dtype=dtype, - ) - - is_repaint = False - is_extend = False - if add_retake_noise: - n_min = int(infer_steps * (1 - retake_variance)) - retake_variance = ( - torch.tensor(retake_variance * math.pi / 2).to(device).to(dtype) - ) - retake_latents = randn_tensor( - shape=(bsz, 8, 16, frame_length), - generator=retake_random_generators, - device=device, - dtype=dtype, - ) - repaint_start_frame = int(repaint_start * 44100 / 512 / 8) - repaint_end_frame = int(repaint_end * 44100 / 512 / 8) - x0 = src_latents - # retake - is_repaint = repaint_end_frame - repaint_start_frame != frame_length - - is_extend = (repaint_start_frame < 0) or (repaint_end_frame > frame_length) - if is_extend: - is_repaint = True - - # TODO: train a mask aware repainting controlnet - # to make sure mean = 0, std = 1 - if not is_repaint: - target_latents = ( - torch.cos(retake_variance) * target_latents - + torch.sin(retake_variance) * retake_latents - ) - elif not is_extend: - # if repaint_end_frame - repaint_mask = torch.zeros( - (bsz, 8, 16, frame_length), device=device, dtype=dtype - ) - repaint_mask[:, :, :, repaint_start_frame:repaint_end_frame] = 1.0 - repaint_noise = ( - torch.cos(retake_variance) * target_latents - + torch.sin(retake_variance) * retake_latents - ) - repaint_noise = torch.where( - repaint_mask == 1.0, repaint_noise, target_latents - ) - zt_edit = x0.clone() - z0 = repaint_noise - elif is_extend: - to_right_pad_gt_latents = None - to_left_pad_gt_latents = None - gt_latents = src_latents - src_latents_length = gt_latents.shape[-1] - max_infer_fame_length = int(240 * 44100 / 512 / 8) - left_pad_frame_length = 0 - right_pad_frame_length = 0 - right_trim_length = 0 - left_trim_length = 0 - if repaint_start_frame < 0: - left_pad_frame_length = abs(repaint_start_frame) - frame_length = left_pad_frame_length + gt_latents.shape[-1] - extend_gt_latents = torch.nn.functional.pad( - gt_latents, (left_pad_frame_length, 0), "constant", 0 - ) - if frame_length > max_infer_fame_length: - right_trim_length = frame_length - max_infer_fame_length - extend_gt_latents = extend_gt_latents[ - :, :, :, :max_infer_fame_length - ] - to_right_pad_gt_latents = extend_gt_latents[ - :, :, :, -right_trim_length: - ] - frame_length = max_infer_fame_length - repaint_start_frame = 0 - gt_latents = extend_gt_latents - - if repaint_end_frame > src_latents_length: - right_pad_frame_length = repaint_end_frame - gt_latents.shape[-1] - frame_length = gt_latents.shape[-1] + right_pad_frame_length - extend_gt_latents = torch.nn.functional.pad( - gt_latents, (0, right_pad_frame_length), "constant", 0 - ) - if frame_length > max_infer_fame_length: - left_trim_length = frame_length - max_infer_fame_length - extend_gt_latents = extend_gt_latents[ - :, :, :, -max_infer_fame_length: - ] - to_left_pad_gt_latents = extend_gt_latents[ - :, :, :, :left_trim_length - ] - frame_length = max_infer_fame_length - repaint_end_frame = frame_length - gt_latents = extend_gt_latents - - repaint_mask = torch.zeros( - (bsz, 8, 16, frame_length), device=device, dtype=dtype - ) - if left_pad_frame_length > 0: - repaint_mask[:, :, :, :left_pad_frame_length] = 1.0 - if right_pad_frame_length > 0: - repaint_mask[:, :, :, -right_pad_frame_length:] = 1.0 - x0 = gt_latents - padd_list = [] - if left_pad_frame_length > 0: - padd_list.append(retake_latents[:, :, :, :left_pad_frame_length]) - padd_list.append( - target_latents[ - :, - :, - :, - left_trim_length : target_latents.shape[-1] - right_trim_length, - ] - ) - if right_pad_frame_length > 0: - padd_list.append(retake_latents[:, :, :, -right_pad_frame_length:]) - target_latents = torch.cat(padd_list, dim=-1) - assert ( - target_latents.shape[-1] == x0.shape[-1] - ), f"{target_latents.shape=} {x0.shape=}" - zt_edit = x0.clone() - z0 = target_latents - - init_timestep = 1000 - if audio2audio_enable and ref_latents is not None: - target_latents, init_timestep = self.add_latents_noise( - gt_latents=ref_latents, - variance=(1 - ref_audio_strength), - noise=target_latents, - scheduler=scheduler, - ) - - attention_mask = torch.ones(bsz, frame_length, device=device, dtype=dtype) - - # guidance interval - start_idx = int(num_inference_steps * ((1 - guidance_interval) / 2)) - end_idx = int(num_inference_steps * (guidance_interval / 2 + 0.5)) - logger.info( - f"start_idx: {start_idx}, end_idx: {end_idx}, num_inference_steps: {num_inference_steps}" - ) - - momentum_buffer = MomentumBuffer() - - def forward_encoder_with_temperature(self, inputs, tau=0.01, l_min=4, l_max=6): - handlers = [] - - def hook(module, input, output): - output[:] *= tau - return output - - for i in range(l_min, l_max): - handler = self.ace_step_transformer.lyric_encoder.encoders[ - i - ].self_attn.linear_q.register_forward_hook(hook) - handlers.append(handler) - - encoder_hidden_states, encoder_hidden_mask = ( - self.ace_step_transformer.encode(**inputs) - ) - - for hook in handlers: - hook.remove() - - return encoder_hidden_states - - # P(speaker, text, lyric) - encoder_hidden_states, encoder_hidden_mask = self.ace_step_transformer.encode( - encoder_text_hidden_states, - text_attention_mask, - speaker_embds, - lyric_token_ids, - lyric_mask, - ) - - if use_erg_lyric: - # P(null_speaker, text_weaker, lyric_weaker) - encoder_hidden_states_null = forward_encoder_with_temperature( - self, - inputs={ - "encoder_text_hidden_states": ( - encoder_text_hidden_states_null - if encoder_text_hidden_states_null is not None - else torch.zeros_like(encoder_text_hidden_states) - ), - "text_attention_mask": text_attention_mask, - "speaker_embeds": torch.zeros_like(speaker_embds), - "lyric_token_idx": lyric_token_ids, - "lyric_mask": lyric_mask, - }, - ) - else: - # P(null_speaker, null_text, null_lyric) - encoder_hidden_states_null, _ = self.ace_step_transformer.encode( - torch.zeros_like(encoder_text_hidden_states), - text_attention_mask, - torch.zeros_like(speaker_embds), - torch.zeros_like(lyric_token_ids), - lyric_mask, - ) - - encoder_hidden_states_no_lyric = None - if do_double_condition_guidance: - # P(null_speaker, text, lyric_weaker) - if use_erg_lyric: - encoder_hidden_states_no_lyric = forward_encoder_with_temperature( - self, - inputs={ - "encoder_text_hidden_states": encoder_text_hidden_states, - "text_attention_mask": text_attention_mask, - "speaker_embeds": torch.zeros_like(speaker_embds), - "lyric_token_idx": lyric_token_ids, - "lyric_mask": lyric_mask, - }, - ) - # P(null_speaker, text, no_lyric) - else: - encoder_hidden_states_no_lyric, _ = self.ace_step_transformer.encode( - encoder_text_hidden_states, - text_attention_mask, - torch.zeros_like(speaker_embds), - torch.zeros_like(lyric_token_ids), - lyric_mask, - ) - - def forward_diffusion_with_temperature( - self, hidden_states, timestep, inputs, tau=0.01, l_min=15, l_max=20 - ): - handlers = [] - - def hook(module, input, output): - output[:] *= tau - return output - - for i in range(l_min, l_max): - handler = self.ace_step_transformer.transformer_blocks[ - i - ].attn.to_q.register_forward_hook(hook) - handlers.append(handler) - handler = self.ace_step_transformer.transformer_blocks[ - i - ].cross_attn.to_q.register_forward_hook(hook) - handlers.append(handler) - - sample = self.ace_step_transformer.decode( - hidden_states=hidden_states, timestep=timestep, **inputs - ).sample - - for hook in handlers: - hook.remove() - - return sample - - for i, t in tqdm(enumerate(timesteps), total=num_inference_steps): - - if t > init_timestep: - continue - - if is_repaint: - if i < n_min: - continue - elif i == n_min: - t_i = t / 1000 - zt_src = (1 - t_i) * x0 + (t_i) * z0 - target_latents = zt_edit + zt_src - x0 - logger.info(f"repaint start from {n_min} add {t_i} level of noise") - - # expand the latents if we are doing classifier free guidance - latents = target_latents - - is_in_guidance_interval = start_idx <= i < end_idx - if is_in_guidance_interval and do_classifier_free_guidance: - # compute current guidance scale - if guidance_interval_decay > 0: - # Linearly interpolate to calculate the current guidance scale - progress = (i - start_idx) / ( - end_idx - start_idx - 1 - ) # 归一化到[0,1] - current_guidance_scale = ( - guidance_scale - - (guidance_scale - min_guidance_scale) - * progress - * guidance_interval_decay - ) - else: - current_guidance_scale = guidance_scale - - latent_model_input = latents - timestep = t.expand(latent_model_input.shape[0]) - output_length = latent_model_input.shape[-1] - # P(x|speaker, text, lyric) - noise_pred_with_cond = self.ace_step_transformer.decode( - hidden_states=latent_model_input, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_hidden_mask=encoder_hidden_mask, - output_length=output_length, - timestep=timestep, - ).sample - - noise_pred_with_only_text_cond = None - if ( - do_double_condition_guidance - and encoder_hidden_states_no_lyric is not None - ): - noise_pred_with_only_text_cond = self.ace_step_transformer.decode( - hidden_states=latent_model_input, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states_no_lyric, - encoder_hidden_mask=encoder_hidden_mask, - output_length=output_length, - timestep=timestep, - ).sample - - if use_erg_diffusion: - noise_pred_uncond = forward_diffusion_with_temperature( - self, - hidden_states=latent_model_input, - timestep=timestep, - inputs={ - "encoder_hidden_states": encoder_hidden_states_null, - "encoder_hidden_mask": encoder_hidden_mask, - "output_length": output_length, - "attention_mask": attention_mask, - }, - ) - else: - noise_pred_uncond = self.ace_step_transformer.decode( - hidden_states=latent_model_input, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states_null, - encoder_hidden_mask=encoder_hidden_mask, - output_length=output_length, - timestep=timestep, - ).sample - - if ( - do_double_condition_guidance - and noise_pred_with_only_text_cond is not None - ): - noise_pred = cfg_double_condition_forward( - cond_output=noise_pred_with_cond, - uncond_output=noise_pred_uncond, - only_text_cond_output=noise_pred_with_only_text_cond, - guidance_scale_text=guidance_scale_text, - guidance_scale_lyric=guidance_scale_lyric, - ) - - elif cfg_type == "apg": - noise_pred = apg_forward( - pred_cond=noise_pred_with_cond, - pred_uncond=noise_pred_uncond, - guidance_scale=current_guidance_scale, - momentum_buffer=momentum_buffer, - ) - elif cfg_type == "cfg": - noise_pred = cfg_forward( - cond_output=noise_pred_with_cond, - uncond_output=noise_pred_uncond, - cfg_strength=current_guidance_scale, - ) - elif cfg_type == "cfg_star": - noise_pred = cfg_zero_star( - noise_pred_with_cond=noise_pred_with_cond, - noise_pred_uncond=noise_pred_uncond, - guidance_scale=current_guidance_scale, - i=i, - zero_steps=zero_steps, - use_zero_init=use_zero_init, - ) - else: - latent_model_input = latents - timestep = t.expand(latent_model_input.shape[0]) - noise_pred = self.ace_step_transformer.decode( - hidden_states=latent_model_input, - attention_mask=attention_mask, - encoder_hidden_states=encoder_hidden_states, - encoder_hidden_mask=encoder_hidden_mask, - output_length=latent_model_input.shape[-1], - timestep=timestep, - ).sample - - if is_repaint and i >= n_min: - t_i = t / 1000 - if i + 1 < len(timesteps): - t_im1 = (timesteps[i + 1]) / 1000 - else: - t_im1 = torch.zeros_like(t_i).to(t_i.device) - dtype = noise_pred.dtype - target_latents = target_latents.to(torch.float32) - prev_sample = target_latents + (t_im1 - t_i) * noise_pred - prev_sample = prev_sample.to(dtype) - target_latents = prev_sample - zt_src = (1 - t_im1) * x0 + (t_im1) * z0 - target_latents = torch.where( - repaint_mask == 1.0, target_latents, zt_src - ) - else: - target_latents = scheduler.step( - model_output=noise_pred, - timestep=t, - sample=target_latents, - return_dict=False, - omega=omega_scale, - )[0] - - if is_extend: - if to_right_pad_gt_latents is not None: - target_latents = torch.cat( - [target_latents, to_right_pad_gt_latents], dim=-1 - ) - if to_left_pad_gt_latents is not None: - target_latents = torch.cat( - [to_right_pad_gt_latents, target_latents], dim=0 - ) - return target_latents - - def latents2audio( - self, - latents, - target_wav_duration_second=30, - sample_rate=48000, - save_path=None, - format="mp3", - ): - output_audio_paths = [] - bs = latents.shape[0] - audio_lengths = [target_wav_duration_second * sample_rate] * bs - pred_latents = latents - with torch.no_grad(): - _, pred_wavs = self.music_dcae.decode(pred_latents, sr=sample_rate) - pred_wavs = [pred_wav.cpu().float() for pred_wav in pred_wavs] - for i in tqdm(range(bs)): - output_audio_path = self.save_wav_file( - pred_wavs[i], i, sample_rate=sample_rate - ) - output_audio_paths.append(output_audio_path) - return output_audio_paths - - def save_wav_file( - self, target_wav, idx, save_path=None, sample_rate=48000, format="mp3" - ): - if save_path is None: - logger.warning("save_path is None, using default path ./outputs/") - base_path = f"./outputs" - ensure_directory_exists(base_path) - else: - base_path = save_path - ensure_directory_exists(base_path) - - output_path_flac = ( - f"{base_path}/output_{time.strftime('%Y%m%d%H%M%S')}_{idx}.{format}" - ) - target_wav = target_wav.float() - torchaudio.save( - output_path_flac, - target_wav, - sample_rate=sample_rate, - format=format, - compression=torio.io.CodecConfig(bit_rate=320000), - ) - return output_path_flac - - def infer_latents(self, input_audio_path): - if input_audio_path is None: - return None - input_audio, sr = self.music_dcae.load_audio(input_audio_path) - input_audio = input_audio.unsqueeze(0) - device, dtype = self.device, self.dtype - input_audio = input_audio.to(device=device, dtype=dtype) - latents, _ = self.music_dcae.encode(input_audio, sr=sr) - return latents - - @spaces.GPU - def __call__( - self, - audio_duration: float = 60.0, - prompt: str = None, - lyrics: str = None, - infer_step: int = 60, - guidance_scale: float = 15.0, - scheduler_type: str = "euler", - cfg_type: str = "apg", - omega_scale: int = 10.0, - manual_seeds: list = None, - guidance_interval: float = 0.5, - guidance_interval_decay: float = 0.0, - min_guidance_scale: float = 3.0, - use_erg_tag: bool = True, - use_erg_lyric: bool = True, - use_erg_diffusion: bool = True, - oss_steps: str = None, - guidance_scale_text: float = 0.0, - guidance_scale_lyric: float = 0.0, - audio2audio_enable: bool = False, - ref_audio_strength: float = 0.5, - ref_audio_input: str = None, - lora_name_or_path: str = "none", - retake_seeds: list = None, - retake_variance: float = 0.5, - task: str = "text2music", - repaint_start: int = 0, - repaint_end: int = 0, - src_audio_path: str = None, - edit_target_prompt: str = None, - edit_target_lyrics: str = None, - edit_n_min: float = 0.0, - edit_n_max: float = 1.0, - edit_n_avg: int = 1, - save_path: str = None, - format: str = "mp3", - batch_size: int = 1, - debug: bool = False, - ): - - start_time = time.time() - - if audio2audio_enable and ref_audio_input is not None: - task = "audio2audio" - - if not self.loaded: - logger.warning("Checkpoint not loaded, loading checkpoint...") - self.load_checkpoint(self.checkpoint_dir) - load_model_cost = time.time() - start_time - logger.info(f"Model loaded in {load_model_cost:.2f} seconds.") - self.load_lora(lora_name_or_path) - start_time = time.time() - - random_generators, actual_seeds = self.set_seeds(batch_size, manual_seeds) - retake_random_generators, actual_retake_seeds = self.set_seeds( - batch_size, retake_seeds - ) - - if isinstance(oss_steps, str) and len(oss_steps) > 0: - oss_steps = list(map(int, oss_steps.split(","))) - else: - oss_steps = [] - - texts = [prompt] - encoder_text_hidden_states, text_attention_mask = self.get_text_embeddings( - texts, self.device - ) - encoder_text_hidden_states = encoder_text_hidden_states.repeat(batch_size, 1, 1) - text_attention_mask = text_attention_mask.repeat(batch_size, 1) - - encoder_text_hidden_states_null = None - if use_erg_tag: - encoder_text_hidden_states_null = self.get_text_embeddings_null( - texts, self.device - ) - encoder_text_hidden_states_null = encoder_text_hidden_states_null.repeat( - batch_size, 1, 1 - ) - - # not support for released checkpoint - speaker_embeds = torch.zeros(batch_size, 512).to(self.device).to(self.dtype) - - # 6 lyric - lyric_token_idx = torch.tensor([0]).repeat(batch_size, 1).to(self.device).long() - lyric_mask = torch.tensor([0]).repeat(batch_size, 1).to(self.device).long() - if len(lyrics) > 0: - lyric_token_idx = self.tokenize_lyrics(lyrics, debug=debug) - lyric_mask = [1] * len(lyric_token_idx) - lyric_token_idx = ( - torch.tensor(lyric_token_idx) - .unsqueeze(0) - .to(self.device) - .repeat(batch_size, 1) - ) - lyric_mask = ( - torch.tensor(lyric_mask) - .unsqueeze(0) - .to(self.device) - .repeat(batch_size, 1) - ) - - if audio_duration <= 0: - audio_duration = random.uniform(30.0, 240.0) - logger.info(f"random audio duration: {audio_duration}") - - end_time = time.time() - preprocess_time_cost = end_time - start_time - start_time = end_time - - add_retake_noise = task in ("retake", "repaint", "extend") - # retake equal to repaint - if task == "retake": - repaint_start = 0 - repaint_end = audio_duration - - src_latents = None - if src_audio_path is not None: - assert src_audio_path is not None and task in ( - "repaint", - "edit", - "extend", - ), "src_audio_path is required for retake/repaint/extend task" - assert os.path.exists( - src_audio_path - ), f"src_audio_path {src_audio_path} does not exist" - src_latents = self.infer_latents(src_audio_path) - - ref_latents = None - if ref_audio_input is not None and audio2audio_enable: - assert ( - ref_audio_input is not None - ), "ref_audio_input is required for audio2audio task" - assert os.path.exists( - ref_audio_input - ), f"ref_audio_input {ref_audio_input} does not exist" - ref_latents = self.infer_latents(ref_audio_input) - - if task == "edit": - texts = [edit_target_prompt] - target_encoder_text_hidden_states, target_text_attention_mask = ( - self.get_text_embeddings(texts, self.device) - ) - target_encoder_text_hidden_states = ( - target_encoder_text_hidden_states.repeat(batch_size, 1, 1) - ) - target_text_attention_mask = target_text_attention_mask.repeat( - batch_size, 1 - ) - - target_lyric_token_idx = ( - torch.tensor([0]).repeat(batch_size, 1).to(self.device).long() - ) - target_lyric_mask = ( - torch.tensor([0]).repeat(batch_size, 1).to(self.device).long() - ) - if len(edit_target_lyrics) > 0: - target_lyric_token_idx = self.tokenize_lyrics( - edit_target_lyrics, debug=True - ) - target_lyric_mask = [1] * len(target_lyric_token_idx) - target_lyric_token_idx = ( - torch.tensor(target_lyric_token_idx) - .unsqueeze(0) - .to(self.device) - .repeat(batch_size, 1) - ) - target_lyric_mask = ( - torch.tensor(target_lyric_mask) - .unsqueeze(0) - .to(self.device) - .repeat(batch_size, 1) - ) - - target_speaker_embeds = speaker_embeds.clone() - - target_latents = self.flowedit_diffusion_process( - encoder_text_hidden_states=encoder_text_hidden_states, - text_attention_mask=text_attention_mask, - speaker_embds=speaker_embeds, - lyric_token_ids=lyric_token_idx, - lyric_mask=lyric_mask, - target_encoder_text_hidden_states=target_encoder_text_hidden_states, - target_text_attention_mask=target_text_attention_mask, - target_speaker_embeds=target_speaker_embeds, - target_lyric_token_ids=target_lyric_token_idx, - target_lyric_mask=target_lyric_mask, - src_latents=src_latents, - random_generators=retake_random_generators, # more diversity - infer_steps=infer_step, - guidance_scale=guidance_scale, - n_min=edit_n_min, - n_max=edit_n_max, - n_avg=edit_n_avg, - ) - else: - target_latents = self.text2music_diffusion_process( - duration=audio_duration, - encoder_text_hidden_states=encoder_text_hidden_states, - text_attention_mask=text_attention_mask, - speaker_embds=speaker_embeds, - lyric_token_ids=lyric_token_idx, - lyric_mask=lyric_mask, - guidance_scale=guidance_scale, - omega_scale=omega_scale, - infer_steps=infer_step, - random_generators=random_generators, - scheduler_type=scheduler_type, - cfg_type=cfg_type, - guidance_interval=guidance_interval, - guidance_interval_decay=guidance_interval_decay, - min_guidance_scale=min_guidance_scale, - oss_steps=oss_steps, - encoder_text_hidden_states_null=encoder_text_hidden_states_null, - use_erg_lyric=use_erg_lyric, - use_erg_diffusion=use_erg_diffusion, - retake_random_generators=retake_random_generators, - retake_variance=retake_variance, - add_retake_noise=add_retake_noise, - guidance_scale_text=guidance_scale_text, - guidance_scale_lyric=guidance_scale_lyric, - repaint_start=repaint_start, - repaint_end=repaint_end, - src_latents=src_latents, - audio2audio_enable=audio2audio_enable, - ref_audio_strength=ref_audio_strength, - ref_latents=ref_latents, - ) - - end_time = time.time() - diffusion_time_cost = end_time - start_time - start_time = end_time - - output_paths = self.latents2audio( - latents=target_latents, - target_wav_duration_second=audio_duration, - save_path=save_path, - format=format, - ) - - end_time = time.time() - latent2audio_time_cost = end_time - start_time - timecosts = { - "preprocess": preprocess_time_cost, - "diffusion": diffusion_time_cost, - "latent2audio": latent2audio_time_cost, - } - - input_params_json = { - "lora_name_or_path": lora_name_or_path, - "task": task, - "prompt": prompt if task != "edit" else edit_target_prompt, - "lyrics": lyrics if task != "edit" else edit_target_lyrics, - "audio_duration": audio_duration, - "infer_step": infer_step, - "guidance_scale": guidance_scale, - "scheduler_type": scheduler_type, - "cfg_type": cfg_type, - "omega_scale": omega_scale, - "guidance_interval": guidance_interval, - "guidance_interval_decay": guidance_interval_decay, - "min_guidance_scale": min_guidance_scale, - "use_erg_tag": use_erg_tag, - "use_erg_lyric": use_erg_lyric, - "use_erg_diffusion": use_erg_diffusion, - "oss_steps": oss_steps, - "timecosts": timecosts, - "actual_seeds": actual_seeds, - "retake_seeds": actual_retake_seeds, - "retake_variance": retake_variance, - "guidance_scale_text": guidance_scale_text, - "guidance_scale_lyric": guidance_scale_lyric, - "repaint_start": repaint_start, - "repaint_end": repaint_end, - "edit_n_min": edit_n_min, - "edit_n_max": edit_n_max, - "edit_n_avg": edit_n_avg, - "src_audio_path": src_audio_path, - "edit_target_prompt": edit_target_prompt, - "edit_target_lyrics": edit_target_lyrics, - "audio2audio_enable": audio2audio_enable, - "ref_audio_strength": ref_audio_strength, - "ref_audio_input": ref_audio_input, - } - # save input_params_json - for output_audio_path in output_paths: - input_params_json_save_path = output_audio_path.replace( - f".{format}", "_input_params.json" - ) - input_params_json["audio_path"] = output_audio_path - with open(input_params_json_save_path, "w", encoding="utf-8") as f: - json.dump(input_params_json, f, indent=4, ensure_ascii=False) - - return output_paths + [input_params_json] diff --git a/requirements.txt b/requirements.txt index ae9fa03982f15ad049f3292f40597d5adcc1139b..5188a79ac0c9c5df8e5862371a8bef8b99053d54 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,7 @@ +--extra-index-url https://download.pytorch.org/whl/cu126 + +git+https://github.com/ace-step/ACE-Step + datasets==3.4.1 diffusers==0.32.2 gradio @@ -20,6 +24,7 @@ spacy==3.8.4 accelerate==1.6.0 cutlet fugashi[unidic-lite] +click peft tensorboard -tensorboardX \ No newline at end of file +tensorboardX diff --git a/schedulers/scheduling_flow_match_euler_discrete.py b/schedulers/scheduling_flow_match_euler_discrete.py deleted file mode 100644 index 997d8eefc2a0c586e532a79116f1996af4c95ee7..0000000000000000000000000000000000000000 --- a/schedulers/scheduling_flow_match_euler_discrete.py +++ /dev/null @@ -1,394 +0,0 @@ -# Copyright 2024 Stability AI, Katherine Crowson and The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import math -from dataclasses import dataclass -from typing import List, Optional, Tuple, Union - -import numpy as np -import torch - -from diffusers.configuration_utils import ConfigMixin, register_to_config -from diffusers.utils import BaseOutput, logging -from diffusers.schedulers.scheduling_utils import SchedulerMixin - - -logger = logging.get_logger(__name__) # pylint: disable=invalid-name - - -@dataclass -class FlowMatchEulerDiscreteSchedulerOutput(BaseOutput): - """ - Output class for the scheduler's `step` function output. - - Args: - prev_sample (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)` for images): - Computed sample `(x_{t-1})` of previous timestep. `prev_sample` should be used as next model input in the - denoising loop. - """ - - prev_sample: torch.FloatTensor - - -class FlowMatchEulerDiscreteScheduler(SchedulerMixin, ConfigMixin): - """ - Euler scheduler. - - This model inherits from [`SchedulerMixin`] and [`ConfigMixin`]. Check the superclass documentation for the generic - methods the library implements for all schedulers such as loading and saving. - - Args: - num_train_timesteps (`int`, defaults to 1000): - The number of diffusion steps to train the model. - timestep_spacing (`str`, defaults to `"linspace"`): - The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and - Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information. - shift (`float`, defaults to 1.0): - The shift value for the timestep schedule. - """ - - _compatibles = [] - order = 1 - - @register_to_config - def __init__( - self, - num_train_timesteps: int = 1000, - shift: float = 1.0, - use_dynamic_shifting=False, - base_shift: Optional[float] = 0.5, - max_shift: Optional[float] = 1.15, - base_image_seq_len: Optional[int] = 256, - max_image_seq_len: Optional[int] = 4096, - ): - timesteps = np.linspace(1, num_train_timesteps, num_train_timesteps, dtype=np.float32)[::-1].copy() - timesteps = torch.from_numpy(timesteps).to(dtype=torch.float32) - - sigmas = timesteps / num_train_timesteps - if not use_dynamic_shifting: - # when use_dynamic_shifting is True, we apply the timestep shifting on the fly based on the image resolution - sigmas = shift * sigmas / (1 + (shift - 1) * sigmas) - - self.timesteps = sigmas * num_train_timesteps - - self._step_index = None - self._begin_index = None - - self.sigmas = sigmas.to("cpu") # to avoid too much CPU/GPU communication - self.sigma_min = self.sigmas[-1].item() - self.sigma_max = self.sigmas[0].item() - - @property - def step_index(self): - """ - The index counter for current timestep. It will increase 1 after each scheduler step. - """ - return self._step_index - - @property - def begin_index(self): - """ - The index for the first timestep. It should be set from pipeline with `set_begin_index` method. - """ - return self._begin_index - - # Copied from diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler.set_begin_index - def set_begin_index(self, begin_index: int = 0): - """ - Sets the begin index for the scheduler. This function should be run from pipeline before the inference. - - Args: - begin_index (`int`): - The begin index for the scheduler. - """ - self._begin_index = begin_index - - def scale_noise( - self, - sample: torch.FloatTensor, - timestep: Union[float, torch.FloatTensor], - noise: Optional[torch.FloatTensor] = None, - ) -> torch.FloatTensor: - """ - Forward process in flow-matching - - Args: - sample (`torch.FloatTensor`): - The input sample. - timestep (`int`, *optional*): - The current timestep in the diffusion chain. - - Returns: - `torch.FloatTensor`: - A scaled input sample. - """ - # Make sure sigmas and timesteps have the same device and dtype as original_samples - sigmas = self.sigmas.to(device=sample.device, dtype=sample.dtype) - - if sample.device.type == "mps" and torch.is_floating_point(timestep): - # mps does not support float64 - schedule_timesteps = self.timesteps.to(sample.device, dtype=torch.float32) - timestep = timestep.to(sample.device, dtype=torch.float32) - else: - schedule_timesteps = self.timesteps.to(sample.device) - timestep = timestep.to(sample.device) - - # self.begin_index is None when scheduler is used for training, or pipeline does not implement set_begin_index - if self.begin_index is None: - step_indices = [self.index_for_timestep(t, schedule_timesteps) for t in timestep] - elif self.step_index is not None: - # add_noise is called after first denoising step (for inpainting) - step_indices = [self.step_index] * timestep.shape[0] - else: - # add noise is called before first denoising step to create initial latent(img2img) - step_indices = [self.begin_index] * timestep.shape[0] - - sigma = sigmas[step_indices].flatten() - while len(sigma.shape) < len(sample.shape): - sigma = sigma.unsqueeze(-1) - - sample = sigma * noise + (1.0 - sigma) * sample - - return sample - - def _sigma_to_t(self, sigma): - return sigma * self.config.num_train_timesteps - - def time_shift(self, mu: float, sigma: float, t: torch.Tensor): - return math.exp(mu) / (math.exp(mu) + (1 / t - 1) ** sigma) - - def set_timesteps( - self, - num_inference_steps: int = None, - device: Union[str, torch.device] = None, - sigmas: Optional[List[float]] = None, - mu: Optional[float] = None, - ): - """ - Sets the discrete timesteps used for the diffusion chain (to be run before inference). - - Args: - num_inference_steps (`int`): - The number of diffusion steps used when generating samples with a pre-trained model. - device (`str` or `torch.device`, *optional*): - The device to which the timesteps should be moved to. If `None`, the timesteps are not moved. - """ - - if self.config.use_dynamic_shifting and mu is None: - raise ValueError(" you have a pass a value for `mu` when `use_dynamic_shifting` is set to be `True`") - - if sigmas is None: - self.num_inference_steps = num_inference_steps - timesteps = np.linspace( - self._sigma_to_t(self.sigma_max), self._sigma_to_t(self.sigma_min), num_inference_steps - ) - - sigmas = timesteps / self.config.num_train_timesteps - - if self.config.use_dynamic_shifting: - sigmas = self.time_shift(mu, 1.0, sigmas) - else: - sigmas = self.config.shift * sigmas / (1 + (self.config.shift - 1) * sigmas) - - sigmas = torch.from_numpy(sigmas).to(dtype=torch.float32, device=device) - timesteps = sigmas * self.config.num_train_timesteps - - self.timesteps = timesteps.to(device=device) - self.sigmas = torch.cat([sigmas, torch.zeros(1, device=sigmas.device)]) - - self._step_index = None - self._begin_index = None - - def index_for_timestep(self, timestep, schedule_timesteps=None): - if schedule_timesteps is None: - schedule_timesteps = self.timesteps - - indices = (schedule_timesteps == timestep).nonzero() - - # The sigma index that is taken for the **very** first `step` - # is always the second index (or the last index if there is only 1) - # This way we can ensure we don't accidentally skip a sigma in - # case we start in the middle of the denoising schedule (e.g. for image-to-image) - pos = 1 if len(indices) > 1 else 0 - - return indices[pos].item() - - def _init_step_index(self, timestep): - if self.begin_index is None: - if isinstance(timestep, torch.Tensor): - timestep = timestep.to(self.timesteps.device) - self._step_index = self.index_for_timestep(timestep) - else: - self._step_index = self._begin_index - - def step( - self, - model_output: torch.FloatTensor, - timestep: Union[float, torch.FloatTensor], - sample: torch.FloatTensor, - s_churn: float = 0.0, - s_tmin: float = 0.0, - s_tmax: float = float("inf"), - s_noise: float = 1.0, - generator: Optional[torch.Generator] = None, - return_dict: bool = True, - omega: Union[float, np.array] = 0.0 - ) -> Union[FlowMatchEulerDiscreteSchedulerOutput, Tuple]: - """ - Predict the sample from the previous timestep by reversing the SDE. This function propagates the diffusion - process from the learned model outputs (most often the predicted noise). - - Args: - model_output (`torch.FloatTensor`): - The direct output from learned diffusion model. - timestep (`float`): - The current discrete timestep in the diffusion chain. - sample (`torch.FloatTensor`): - A current instance of a sample created by the diffusion process. - s_churn (`float`): - s_tmin (`float`): - s_tmax (`float`): - s_noise (`float`, defaults to 1.0): - Scaling factor for noise added to the sample. - generator (`torch.Generator`, *optional*): - A random number generator. - return_dict (`bool`): - Whether or not to return a [`~schedulers.scheduling_euler_discrete.EulerDiscreteSchedulerOutput`] or - tuple. - - Returns: - [`~schedulers.scheduling_euler_discrete.EulerDiscreteSchedulerOutput`] or `tuple`: - If return_dict is `True`, [`~schedulers.scheduling_euler_discrete.EulerDiscreteSchedulerOutput`] is - returned, otherwise a tuple is returned where the first element is the sample tensor. - """ - - def logistic_function(x, L=0.9, U=1.1, x_0=0.0, k=1): - # L = Lower bound - # U = Upper bound - # x_0 = Midpoint (x corresponding to y = 1.0) - # k = Steepness, can adjust based on preference - - if isinstance(x, torch.Tensor): - device_ = x.device - x = x.to(torch.float).cpu().numpy() - - new_x = L + (U - L) / (1 + np.exp(-k * (x - x_0))) - - if isinstance(new_x, np.ndarray): - new_x = torch.from_numpy(new_x).to(device_) - return new_x - - self.omega_bef_rescale = omega - omega = logistic_function(omega, k=0.1) - self.omega_aft_rescale = omega - - if ( - isinstance(timestep, int) - or isinstance(timestep, torch.IntTensor) - or isinstance(timestep, torch.LongTensor) - ): - raise ValueError( - ( - "Passing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to" - " `EulerDiscreteScheduler.step()` is not supported. Make sure to pass" - " one of the `scheduler.timesteps` as a timestep." - ), - ) - - if self.step_index is None: - self._init_step_index(timestep) - - # Upcast to avoid precision issues when computing prev_sample - sample = sample.to(torch.float32) - - sigma = self.sigmas[self.step_index] - sigma_next = self.sigmas[self.step_index + 1] - - ## -- - ## mean shift 1 - dx = (sigma_next - sigma) * model_output - m = dx.mean() - # print(dx.shape) # torch.Size([1, 16, 128, 128]) - # print(f'm: {m}') # m: -0.0014209747314453125 - # raise NotImplementedError - dx_ = (dx - m) * omega + m - prev_sample = sample + dx_ - - # ## -- - # ## mean shift 2 - # m = model_output.mean() - # model_output_ = (model_output - m) * omega + m - # prev_sample = sample + (sigma_next - sigma) * model_output_ - - # ## -- - # ## original - # prev_sample = sample + (sigma_next - sigma) * model_output * omega - - # ## -- - # ## spatial mean 1 - # dx = (sigma_next - sigma) * model_output - # m = dx.mean(dim=(0, 1), keepdim=True) - # # print(dx.shape) # torch.Size([1, 16, 128, 128]) - # # print(m.shape) # torch.Size([1, 1, 128, 128]) - # # raise NotImplementedError - # dx_ = (dx - m) * omega + m - # prev_sample = sample + dx_ - - # ## -- - # ## spatial mean 2 - # m = model_output.mean(dim=(0, 1), keepdim=True) - # model_output_ = (model_output - m) * omega + m - # prev_sample = sample + (sigma_next - sigma) * model_output_ - - # ## -- - # ## channel mean 1 - # m = model_output.mean(dim=(2, 3), keepdim=True) - # # print(m.shape) # torch.Size([1, 16, 1, 1]) - # model_output_ = (model_output - m) * omega + m - # prev_sample = sample + (sigma_next - sigma) * model_output_ - - # ## -- - # ## channel mean 2 - # dx = (sigma_next - sigma) * model_output - # m = dx.mean(dim=(2, 3), keepdim=True) - # # print(m.shape) # torch.Size([1, 16, 1, 1]) - # dx_ = (dx - m) * omega + m - # prev_sample = sample + dx_ - - # ## -- - # ## keep sample mean - # m_tgt = sample.mean() - # prev_sample_ = sample + (sigma_next - sigma) * model_output * omega - # m_src = prev_sample_.mean() - # prev_sample = prev_sample_ - m_src + m_tgt - - # ## -- - # ## test - # # print(sample.mean()) - # prev_sample = sample + (sigma_next - sigma) * model_output * omega - # # raise NotImplementedError - - # Cast sample back to model compatible dtype - prev_sample = prev_sample.to(model_output.dtype) - - # upon completion increase step index by one - self._step_index += 1 - - if not return_dict: - return (prev_sample,) - - return FlowMatchEulerDiscreteSchedulerOutput(prev_sample=prev_sample) - - def __len__(self): - return self.config.num_train_timesteps diff --git a/schedulers/scheduling_flow_match_heun_discrete.py b/schedulers/scheduling_flow_match_heun_discrete.py deleted file mode 100644 index b459a004a0fbda4cbacee5783aeb4c116db49214..0000000000000000000000000000000000000000 --- a/schedulers/scheduling_flow_match_heun_discrete.py +++ /dev/null @@ -1,348 +0,0 @@ -# Copyright 2024 Stability AI, Katherine Crowson and The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from dataclasses import dataclass -from typing import Optional, Tuple, Union - -import numpy as np -import torch - -from diffusers.configuration_utils import ConfigMixin, register_to_config -from diffusers.utils import BaseOutput, logging -from diffusers.utils.torch_utils import randn_tensor -from diffusers.schedulers.scheduling_utils import SchedulerMixin - - -logger = logging.get_logger(__name__) # pylint: disable=invalid-name - - -@dataclass -class FlowMatchHeunDiscreteSchedulerOutput(BaseOutput): - """ - Output class for the scheduler's `step` function output. - - Args: - prev_sample (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)` for images): - Computed sample `(x_{t-1})` of previous timestep. `prev_sample` should be used as next model input in the - denoising loop. - """ - - prev_sample: torch.FloatTensor - - -class FlowMatchHeunDiscreteScheduler(SchedulerMixin, ConfigMixin): - """ - Heun scheduler. - - This model inherits from [`SchedulerMixin`] and [`ConfigMixin`]. Check the superclass documentation for the generic - methods the library implements for all schedulers such as loading and saving. - - Args: - num_train_timesteps (`int`, defaults to 1000): - The number of diffusion steps to train the model. - timestep_spacing (`str`, defaults to `"linspace"`): - The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and - Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information. - shift (`float`, defaults to 1.0): - The shift value for the timestep schedule. - """ - - _compatibles = [] - order = 2 - - @register_to_config - def __init__( - self, - num_train_timesteps: int = 1000, - shift: float = 1.0, - ): - timesteps = np.linspace(1, num_train_timesteps, num_train_timesteps, dtype=np.float32)[::-1].copy() - timesteps = torch.from_numpy(timesteps).to(dtype=torch.float32) - - sigmas = timesteps / num_train_timesteps - sigmas = shift * sigmas / (1 + (shift - 1) * sigmas) - - self.timesteps = sigmas * num_train_timesteps - - self._step_index = None - self._begin_index = None - - self.sigmas = sigmas.to("cpu") # to avoid too much CPU/GPU communication - self.sigma_min = self.sigmas[-1].item() - self.sigma_max = self.sigmas[0].item() - - @property - def step_index(self): - """ - The index counter for current timestep. It will increase 1 after each scheduler step. - """ - return self._step_index - - @property - def begin_index(self): - """ - The index for the first timestep. It should be set from pipeline with `set_begin_index` method. - """ - return self._begin_index - - # Copied from diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler.set_begin_index - def set_begin_index(self, begin_index: int = 0): - """ - Sets the begin index for the scheduler. This function should be run from pipeline before the inference. - - Args: - begin_index (`int`): - The begin index for the scheduler. - """ - self._begin_index = begin_index - - def scale_noise( - self, - sample: torch.FloatTensor, - timestep: Union[float, torch.FloatTensor], - noise: Optional[torch.FloatTensor] = None, - ) -> torch.FloatTensor: - """ - Forward process in flow-matching - - Args: - sample (`torch.FloatTensor`): - The input sample. - timestep (`int`, *optional*): - The current timestep in the diffusion chain. - - Returns: - `torch.FloatTensor`: - A scaled input sample. - """ - if self.step_index is None: - self._init_step_index(timestep) - - sigma = self.sigmas[self.step_index] - sample = sigma * noise + (1.0 - sigma) * sample - - return sample - - def _sigma_to_t(self, sigma): - return sigma * self.config.num_train_timesteps - - def set_timesteps(self, num_inference_steps: int, device: Union[str, torch.device] = None): - """ - Sets the discrete timesteps used for the diffusion chain (to be run before inference). - - Args: - num_inference_steps (`int`): - The number of diffusion steps used when generating samples with a pre-trained model. - device (`str` or `torch.device`, *optional*): - The device to which the timesteps should be moved to. If `None`, the timesteps are not moved. - """ - self.num_inference_steps = num_inference_steps - - timesteps = np.linspace( - self._sigma_to_t(self.sigma_max), self._sigma_to_t(self.sigma_min), num_inference_steps - ) - - sigmas = timesteps / self.config.num_train_timesteps - sigmas = self.config.shift * sigmas / (1 + (self.config.shift - 1) * sigmas) - sigmas = torch.from_numpy(sigmas).to(dtype=torch.float32, device=device) - - timesteps = sigmas * self.config.num_train_timesteps - timesteps = torch.cat([timesteps[:1], timesteps[1:].repeat_interleave(2)]) - self.timesteps = timesteps.to(device=device) - - sigmas = torch.cat([sigmas, torch.zeros(1, device=sigmas.device)]) - self.sigmas = torch.cat([sigmas[:1], sigmas[1:-1].repeat_interleave(2), sigmas[-1:]]) - - # empty dt and derivative - self.prev_derivative = None - self.dt = None - - self._step_index = None - self._begin_index = None - - def index_for_timestep(self, timestep, schedule_timesteps=None): - if schedule_timesteps is None: - schedule_timesteps = self.timesteps - - indices = (schedule_timesteps == timestep).nonzero() - - # The sigma index that is taken for the **very** first `step` - # is always the second index (or the last index if there is only 1) - # This way we can ensure we don't accidentally skip a sigma in - # case we start in the middle of the denoising schedule (e.g. for image-to-image) - pos = 1 if len(indices) > 1 else 0 - - return indices[pos].item() - - def _init_step_index(self, timestep): - if self.begin_index is None: - if isinstance(timestep, torch.Tensor): - timestep = timestep.to(self.timesteps.device) - self._step_index = self.index_for_timestep(timestep) - else: - self._step_index = self._begin_index - - @property - def state_in_first_order(self): - return self.dt is None - - def step( - self, - model_output: torch.FloatTensor, - timestep: Union[float, torch.FloatTensor], - sample: torch.FloatTensor, - s_churn: float = 0.0, - s_tmin: float = 0.0, - s_tmax: float = float("inf"), - s_noise: float = 1.0, - generator: Optional[torch.Generator] = None, - return_dict: bool = True, - omega: Union[float, np.array] = 0.0 - ) -> Union[FlowMatchHeunDiscreteSchedulerOutput, Tuple]: - """ - Predict the sample from the previous timestep by reversing the SDE. This function propagates the diffusion - process from the learned model outputs (most often the predicted noise). - - Args: - model_output (`torch.FloatTensor`): - The direct output from learned diffusion model. - timestep (`float`): - The current discrete timestep in the diffusion chain. - sample (`torch.FloatTensor`): - A current instance of a sample created by the diffusion process. - s_churn (`float`): - s_tmin (`float`): - s_tmax (`float`): - s_noise (`float`, defaults to 1.0): - Scaling factor for noise added to the sample. - generator (`torch.Generator`, *optional*): - A random number generator. - return_dict (`bool`): - Whether or not to return a [`~schedulers.scheduling_Heun_discrete.HeunDiscreteSchedulerOutput`] or - tuple. - - Returns: - [`~schedulers.scheduling_Heun_discrete.HeunDiscreteSchedulerOutput`] or `tuple`: - If return_dict is `True`, [`~schedulers.scheduling_Heun_discrete.HeunDiscreteSchedulerOutput`] is - returned, otherwise a tuple is returned where the first element is the sample tensor. - """ - - def logistic_function(x, L=0.9, U=1.1, x_0=0.0, k=1): - # L = Lower bound - # U = Upper bound - # x_0 = Midpoint (x corresponding to y = 1.0) - # k = Steepness, can adjust based on preference - - if isinstance(x, torch.Tensor): - device_ = x.device - x = x.to(torch.float).cpu().numpy() - - new_x = L + (U - L) / (1 + np.exp(-k * (x - x_0))) - - if isinstance(new_x, np.ndarray): - new_x = torch.from_numpy(new_x).to(device_) - return new_x - - self.omega_bef_rescale = omega - omega = logistic_function(omega, k=0.1) - self.omega_aft_rescale = omega - - if ( - isinstance(timestep, int) - or isinstance(timestep, torch.IntTensor) - or isinstance(timestep, torch.LongTensor) - ): - raise ValueError( - ( - "Passing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to" - " `HeunDiscreteScheduler.step()` is not supported. Make sure to pass" - " one of the `scheduler.timesteps` as a timestep." - ), - ) - - if self.step_index is None: - self._init_step_index(timestep) - - # Upcast to avoid precision issues when computing prev_sample - sample = sample.to(torch.float32) - - if self.state_in_first_order: - sigma = self.sigmas[self.step_index] - sigma_next = self.sigmas[self.step_index + 1] - else: - # 2nd order / Heun's method - sigma = self.sigmas[self.step_index - 1] - sigma_next = self.sigmas[self.step_index] - - gamma = min(s_churn / (len(self.sigmas) - 1), 2**0.5 - 1) if s_tmin <= sigma <= s_tmax else 0.0 - - sigma_hat = sigma * (gamma + 1) - - if gamma > 0: - noise = randn_tensor( - model_output.shape, dtype=model_output.dtype, device=model_output.device, generator=generator - ) - eps = noise * s_noise - sample = sample + eps * (sigma_hat**2 - sigma**2) ** 0.5 - - if self.state_in_first_order: - # 1. compute predicted original sample (x_0) from sigma-scaled predicted noise - denoised = sample - model_output * sigma - # 2. convert to an ODE derivative for 1st order - derivative = (sample - denoised) / sigma_hat - # 3. Delta timestep - dt = sigma_next - sigma_hat - - # store for 2nd order step - self.prev_derivative = derivative - self.dt = dt - self.sample = sample - else: - # 1. compute predicted original sample (x_0) from sigma-scaled predicted noise - denoised = sample - model_output * sigma_next - # 2. 2nd order / Heun's method - derivative = (sample - denoised) / sigma_next - derivative = 0.5 * (self.prev_derivative + derivative) - - # 3. take prev timestep & sample - dt = self.dt - sample = self.sample - - # free dt and derivative - # Note, this puts the scheduler in "first order mode" - self.prev_derivative = None - self.dt = None - self.sample = None - - # original sample way - # prev_sample = sample + derivative * dt - - dx = derivative * dt - m = dx.mean() - dx_ = (dx - m) * omega + m - prev_sample = sample + dx_ - - # Cast sample back to model compatible dtype - prev_sample = prev_sample.to(model_output.dtype) - - # upon completion increase step index by one - self._step_index += 1 - - if not return_dict: - return (prev_sample,) - - return FlowMatchHeunDiscreteSchedulerOutput(prev_sample=prev_sample) - - def __len__(self): - return self.config.num_train_timesteps diff --git a/test.json b/test.json deleted file mode 100644 index 871ce7f0760263857a927e910d334dd5d6a9ff8b..0000000000000000000000000000000000000000 --- a/test.json +++ /dev/null @@ -1 +0,0 @@ -{'id': 'gen-1746104947-KKBqwgZ992wxV5m4PZga', 'provider': 'Google', 'model': 'google/gemini-2.5-flash-preview', 'object': 'chat.completion', 'created': 1746104947, 'choices': [{'logprobs': None, 'finish_reason': 'stop', 'native_finish_reason': 'STOP', 'index': 0, 'message': {'role': 'assistant', 'content': '```json\n[\n {\n "id": "1",\n "lyrics": "[Intro]\\nYo\\nCheck the mic, one two\\n你们欠我的总要还\\n[Chorus]\\n欠我的总要还\\n别想着逃跑\\n我来了带着我的flow\\n就像一场风暴\\n别再假装不知道\\n你们的演技太糟\\n今天我就让你知道\\n什么叫做报应到\\n[Verse 1]\\n还记得那天吗\\n我的付出你们全抛下\\n踩着我的头\\n往上爬\\n现在轮到我\\n来收账啦\\n那些虚伪的嘴脸\\n还在对我笑\\n却不知道报应\\n已经在敲门了\\n每一个背叛\\n都刻在我的心上\\n今天就是你们\\n付出代价的时候\\n[Pre-Chorus]\\n别求饶\\n别哭叫\\n这一切都是你们\\n自找的\\n[Chorus]\\n欠我的总要还\\n别想着逃跑\\n我来了带着我的flow\\n就像一场风暴\\n别再假装不知道\\n你们的演技太糟\\n今天我就让你知道\\n什么叫做报应到\\n[Outro]\\nHahaha\\nPayback time\\n你们跑不掉的\\n永远",\n "tags": "Rap, Hip Hop, Boombap, Ambient Synth Pads, Humorous, Revenge"\n },\n {\n "id": "120",\n "lyrics": "[Intro]\\nYeah\\nLet\'s take it back\\n回望过去的光景\\n[Verse 1]\\n曾经的街道\\n熟悉的味道\\n那些画面\\n在脑海里环绕\\n年轻的我们\\n充满着梦想\\n以为世界\\n就在我们的手掌\\n那段时光\\n单纯又美好\\n虽然 sometimes 很苦\\n但是我们都在笑\\n那些面孔\\n有些已不再联系\\n但他们的故事\\n依然在我记忆里\\n[Chorus]\\n回望过去\\n就像一部电影\\n有好有坏\\n有哭也有笑声\\n那些经历\\n塑造了今天的我\\n感谢一切\\n让我变得成熟\\n[Verse 2]\\n记得第一次心碎\\n在雨中流泪\\n记得第一次成功\\n那种喜悦滋味\\n记得那些争吵\\n也记得和解的拥抱\\n每一次跌倒\\n都教会我如何 STAND TALL\\n那些友情\\n那些爱情\\n都是我生命中\\n最珍贵的风景\\n[Bridge]\\n时间流逝\\n我们都在改变\\n但有些东西\\n永远不会变\\n初心还在\\n梦想还在\\n带着过去的经验\\n走向未来\\n[Chorus]\\n回望过去\\n就像一部电影\\n有好有坏\\n有哭也有笑声\\n那些经历\\n塑造了今天的我\\n感谢一切\\n让我变得成熟\\n[Outro]\\nLooking back\\nNever forget\\n那些日子\\n永远在我心里\\nYeah",\n "tags": "Rap, Hip Hop, Jazz Hop, Fast Tempo, Synth Lead, Traditional Instrument Samples, Storytelling, Looking Back"\n },\n {\n "id": "210",\n "lyrics": "[Intro]\\nYo\\nLet\'s go\\nParty started!\\n[Verse 1]\\n节奏快到爆炸\\n我的 Flow 像火箭一样发射\\n麦克风在我手里\\n就是我的武器\\n每一个字都像子弹\\n精准地击中你\\n从不放慢速度\\n只有一路狂飙\\n派对动物在欢呼\\n气氛越来越高潮\\n汗水湿透了衣裳\\n精力无限释放\\n今晚不回家\\n玩到天亮\\n[Chorus]\\n派对时间到了\\n跟着我的节奏摇摆\\n忘记所有烦恼\\n今晚我们主宰舞台\\n音乐声震耳欲聋\\n点燃激情和冲动\\n我们 unstoppable\\n像 electric guitar riff 的作用\\n[Verse 2]\\n别傻站着\\n加入我们的人潮\\n尽情扭动\\n释放你的 SIGNAL\\n不用在意别人眼光\\n做最真实的自己\\n这个夜晚\\n属于你的胜利\\n我的歌声在你耳边\\n就像电流穿梭\\n让你感受到力量\\n让你全身都着火\\n[Chorus]\\n派对时间到了\\n跟着我的节奏摇摆\\n忘记所有烦恼\\n今晚我们主宰舞台\\n音乐声震耳欲聋\\n点燃激情和冲动\\n我们 unstoppable\\n像 electric guitar riff 的作用\\n[Bridge]\\n从黑夜到黎明\\n我们的能量不会停\\n一直在前进\\n unstoppable 势不可挡\\n[Outro]\\nYeah\\nThat\'s right\\nParty never ends\\nLet\'s get it!",\n "tags": "Rap, Hip Hop, Fast Tempo, Chopper Flow, Sampled Vocal Hook, Electric Guitar Riff, Motivational, Chill, Relaxed, Party Scene"\n }\n]\n```', 'refusal': None, 'reasoning': None}}], 'usage': {'prompt_tokens': 1212, 'completion_tokens': 1121, 'total_tokens': 2333}} diff --git a/ui/components.py b/ui/components.py deleted file mode 100644 index 5c6e0f5b1e56f93d60e0dbcb13aaee898b809d40..0000000000000000000000000000000000000000 --- a/ui/components.py +++ /dev/null @@ -1,958 +0,0 @@ -""" -ACE-Step: A Step Towards Music Generation Foundation Model - -https://github.com/ace-step/ACE-Step - -Apache 2.0 License -""" - -import gradio as gr -import librosa -import os - - -TAG_DEFAULT = "funk, pop, soul, rock, melodic, guitar, drums, bass, keyboard, percussion, 105 BPM, energetic, upbeat, groovy, vibrant, dynamic" -LYRIC_DEFAULT = """[verse] -Neon lights they flicker bright -City hums in dead of night -Rhythms pulse through concrete veins -Lost in echoes of refrains - -[verse] -Bassline groovin' in my chest -Heartbeats match the city's zest -Electric whispers fill the air -Synthesized dreams everywhere - -[chorus] -Turn it up and let it flow -Feel the fire let it grow -In this rhythm we belong -Hear the night sing out our song - -[verse] -Guitar strings they start to weep -Wake the soul from silent sleep -Every note a story told -In this night we’re bold and gold - -[bridge] -Voices blend in harmony -Lost in pure cacophony -Timeless echoes timeless cries -Soulful shouts beneath the skies - -[verse] -Keyboard dances on the keys -Melodies on evening breeze -Catch the tune and hold it tight -In this moment we take flight -""" - -# First, let's define the presets at the top of the file, after the imports -GENRE_PRESETS = { - "Modern Pop": "pop, synth, drums, guitar, 120 bpm, upbeat, catchy, vibrant, female vocals, polished vocals", - "Rock": "rock, electric guitar, drums, bass, 130 bpm, energetic, rebellious, gritty, male vocals, raw vocals", - "Hip Hop": "hip hop, 808 bass, hi-hats, synth, 90 bpm, bold, urban, intense, male vocals, rhythmic vocals", - "Country": "country, acoustic guitar, steel guitar, fiddle, 100 bpm, heartfelt, rustic, warm, male vocals, twangy vocals", - "EDM": "edm, synth, bass, kick drum, 128 bpm, euphoric, pulsating, energetic, instrumental", - "Reggae": "reggae, guitar, bass, drums, 80 bpm, chill, soulful, positive, male vocals, smooth vocals", - "Classical": "classical, orchestral, strings, piano, 60 bpm, elegant, emotive, timeless, instrumental", - "Jazz": "jazz, saxophone, piano, double bass, 110 bpm, smooth, improvisational, soulful, male vocals, crooning vocals", - "Metal": "metal, electric guitar, double kick drum, bass, 160 bpm, aggressive, intense, heavy, male vocals, screamed vocals", - "R&B": "r&b, synth, bass, drums, 85 bpm, sultry, groovy, romantic, female vocals, silky vocals" -} - -# Add this function to handle preset selection -def update_tags_from_preset(preset_name): - if preset_name == "Custom": - return "" - return GENRE_PRESETS.get(preset_name, "") - - -def create_output_ui(task_name="Text2Music"): - # For many consumer-grade GPU devices, only one batch can be run - output_audio1 = gr.Audio(type="filepath", label=f"{task_name} Generated Audio 1") - # output_audio2 = gr.Audio(type="filepath", label="Generated Audio 2") - with gr.Accordion(f"{task_name} Parameters", open=False): - input_params_json = gr.JSON(label=f"{task_name} Parameters") - # outputs = [output_audio1, output_audio2] - outputs = [output_audio1] - return outputs, input_params_json - - -def dump_func(*args): - print(args) - return [] - - -def create_text2music_ui( - gr, - text2music_process_func, - sample_data_func=None, - load_data_func=None, -): - - with gr.Row(): - with gr.Column(): - with gr.Row(equal_height=True): - # add markdown, tags and lyrics examples are from ai music generation community - audio_duration = gr.Slider( - -1, - 240.0, - step=0.00001, - value=-1, - label="Audio Duration", - interactive=True, - info="-1 means random duration (30 ~ 240).", - scale=9, - ) - sample_bnt = gr.Button("Sample", variant="secondary", scale=1) - - # audio2audio - with gr.Row(equal_height=True): - audio2audio_enable = gr.Checkbox(label="Enable Audio2Audio", value=False, info="Check to enable Audio-to-Audio generation using a reference audio.", elem_id="audio2audio_checkbox") - lora_name_or_path = gr.Dropdown( - label="Lora Name or Path", - choices=["ACE-Step/ACE-Step-v1-chinese-rap-LoRA", "none"], - value="none", - allow_custom_value=True, - ) - - ref_audio_input = gr.Audio(type="filepath", label="Reference Audio (for Audio2Audio)", visible=False, elem_id="ref_audio_input", show_download_button=True) - ref_audio_strength = gr.Slider( - label="Refer audio strength", - minimum=0.0, - maximum=1.0, - step=0.01, - value=0.5, - elem_id="ref_audio_strength", - visible=False, - interactive=True, - ) - - def toggle_ref_audio_visibility(is_checked): - return ( - gr.update(visible=is_checked, elem_id="ref_audio_input"), - gr.update(visible=is_checked, elem_id="ref_audio_strength"), - ) - - audio2audio_enable.change( - fn=toggle_ref_audio_visibility, - inputs=[audio2audio_enable], - outputs=[ref_audio_input, ref_audio_strength], - ) - - with gr.Column(scale=2): - with gr.Group(): - gr.Markdown("""
Support tags, descriptions, and scene. Use commas to separate different tags.
Tags and lyrics examples are from AI music generation community.
""") - with gr.Row(): - genre_preset = gr.Dropdown( - choices=["Custom"] + list(GENRE_PRESETS.keys()), - value="Custom", - label="Preset", - scale=1, - ) - prompt = gr.Textbox( - lines=1, - label="Tags", - max_lines=4, - value=TAG_DEFAULT, - scale=9, - ) - - # Add the change event for the preset dropdown - genre_preset.change( - fn=update_tags_from_preset, - inputs=[genre_preset], - outputs=[prompt] - ) - with gr.Group(): - gr.Markdown("""
Support lyric structure tags like [verse], [chorus], and [bridge] to separate different parts of the lyrics.
Use [instrumental] or [inst] to generate instrumental music. Not support genre structure tag in lyrics
""") - lyrics = gr.Textbox( - lines=9, - label="Lyrics", - max_lines=13, - value=LYRIC_DEFAULT, - ) - - with gr.Accordion("Basic Settings", open=False): - infer_step = gr.Slider( - minimum=1, - maximum=200, - step=1, - value=60, - label="Infer Steps", - interactive=True, - ) - guidance_scale = gr.Slider( - minimum=0.0, - maximum=30.0, - step=0.1, - value=15.0, - label="Guidance Scale", - interactive=True, - info="When guidance_scale_lyric > 1 and guidance_scale_text > 1, the guidance scale will not be applied.", - ) - guidance_scale_text = gr.Slider( - minimum=0.0, - maximum=10.0, - step=0.1, - value=0.0, - label="Guidance Scale Text", - interactive=True, - info="Guidance scale for text condition. It can only apply to cfg. set guidance_scale_text=5.0, guidance_scale_lyric=1.5 for start", - ) - guidance_scale_lyric = gr.Slider( - minimum=0.0, - maximum=10.0, - step=0.1, - value=0.0, - label="Guidance Scale Lyric", - interactive=True, - ) - - manual_seeds = gr.Textbox( - label="manual seeds (default None)", - placeholder="1,2,3,4", - value=None, - info="Seed for the generation", - ) - - with gr.Accordion("Advanced Settings", open=False): - scheduler_type = gr.Radio( - ["euler", "heun"], - value="euler", - label="Scheduler Type", - elem_id="scheduler_type", - info="Scheduler type for the generation. euler is recommended. heun will take more time.", - ) - cfg_type = gr.Radio( - ["cfg", "apg", "cfg_star"], - value="apg", - label="CFG Type", - elem_id="cfg_type", - info="CFG type for the generation. apg is recommended. cfg and cfg_star are almost the same.", - ) - use_erg_tag = gr.Checkbox( - label="use ERG for tag", - value=True, - info="Use Entropy Rectifying Guidance for tag. It will multiple a temperature to the attention to make a weaker tag condition and make better diversity.", - ) - use_erg_lyric = gr.Checkbox( - label="use ERG for lyric", - value=False, - info="The same but apply to lyric encoder's attention.", - ) - use_erg_diffusion = gr.Checkbox( - label="use ERG for diffusion", - value=True, - info="The same but apply to diffusion model's attention.", - ) - - omega_scale = gr.Slider( - minimum=-100.0, - maximum=100.0, - step=0.1, - value=10.0, - label="Granularity Scale", - interactive=True, - info="Granularity scale for the generation. Higher values can reduce artifacts", - ) - - guidance_interval = gr.Slider( - minimum=0.0, - maximum=1.0, - step=0.01, - value=0.5, - label="Guidance Interval", - interactive=True, - info="Guidance interval for the generation. 0.5 means only apply guidance in the middle steps (0.25 * infer_steps to 0.75 * infer_steps)", - ) - guidance_interval_decay = gr.Slider( - minimum=0.0, - maximum=1.0, - step=0.01, - value=0.0, - label="Guidance Interval Decay", - interactive=True, - info="Guidance interval decay for the generation. Guidance scale will decay from guidance_scale to min_guidance_scale in the interval. 0.0 means no decay.", - ) - min_guidance_scale = gr.Slider( - minimum=0.0, - maximum=200.0, - step=0.1, - value=3.0, - label="Min Guidance Scale", - interactive=True, - info="Min guidance scale for guidance interval decay's end scale", - ) - oss_steps = gr.Textbox( - label="OSS Steps", - placeholder="16, 29, 52, 96, 129, 158, 172, 183, 189, 200", - value=None, - info="Optimal Steps for the generation. But not test well", - ) - - text2music_bnt = gr.Button("Generate", variant="primary") - - with gr.Column(): - outputs, input_params_json = create_output_ui() - with gr.Tab("retake"): - retake_variance = gr.Slider( - minimum=0.0, maximum=1.0, step=0.01, value=0.2, label="variance" - ) - retake_seeds = gr.Textbox( - label="retake seeds (default None)", placeholder="", value=None - ) - retake_bnt = gr.Button("Retake", variant="primary") - retake_outputs, retake_input_params_json = create_output_ui("Retake") - - def retake_process_func(json_data, retake_variance, retake_seeds): - return text2music_process_func( - json_data["audio_duration"], - json_data["prompt"], - json_data["lyrics"], - json_data["infer_step"], - json_data["guidance_scale"], - json_data["scheduler_type"], - json_data["cfg_type"], - json_data["omega_scale"], - ", ".join(map(str, json_data["actual_seeds"])), - json_data["guidance_interval"], - json_data["guidance_interval_decay"], - json_data["min_guidance_scale"], - json_data["use_erg_tag"], - json_data["use_erg_lyric"], - json_data["use_erg_diffusion"], - ", ".join(map(str, json_data["oss_steps"])), - ( - json_data["guidance_scale_text"] - if "guidance_scale_text" in json_data - else 0.0 - ), - ( - json_data["guidance_scale_lyric"] - if "guidance_scale_lyric" in json_data - else 0.0 - ), - retake_seeds=retake_seeds, - retake_variance=retake_variance, - task="retake", - lora_name_or_path="none" if "lora_name_or_path" not in json_data else json_data["lora_name_or_path"] - ) - - retake_bnt.click( - fn=retake_process_func, - inputs=[ - input_params_json, - retake_variance, - retake_seeds, - ], - outputs=retake_outputs + [retake_input_params_json], - ) - with gr.Tab("repainting"): - retake_variance = gr.Slider( - minimum=0.0, maximum=1.0, step=0.01, value=0.2, label="variance" - ) - retake_seeds = gr.Textbox( - label="repaint seeds (default None)", placeholder="", value=None - ) - repaint_start = gr.Slider( - minimum=0.0, - maximum=240.0, - step=0.01, - value=0.0, - label="Repaint Start Time", - interactive=True, - ) - repaint_end = gr.Slider( - minimum=0.0, - maximum=240.0, - step=0.01, - value=30.0, - label="Repaint End Time", - interactive=True, - ) - repaint_source = gr.Radio( - ["text2music", "last_repaint", "upload"], - value="text2music", - label="Repaint Source", - elem_id="repaint_source", - ) - - repaint_source_audio_upload = gr.Audio( - label="Upload Audio", - type="filepath", - visible=False, - elem_id="repaint_source_audio_upload", - show_download_button=True, - ) - repaint_source.change( - fn=lambda x: gr.update( - visible=x == "upload", elem_id="repaint_source_audio_upload" - ), - inputs=[repaint_source], - outputs=[repaint_source_audio_upload], - ) - - repaint_bnt = gr.Button("Repaint", variant="primary") - repaint_outputs, repaint_input_params_json = create_output_ui("Repaint") - - def repaint_process_func( - text2music_json_data, - repaint_json_data, - retake_variance, - retake_seeds, - repaint_start, - repaint_end, - repaint_source, - repaint_source_audio_upload, - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - ): - if repaint_source == "upload": - src_audio_path = repaint_source_audio_upload - audio_duration = librosa.get_duration(filename=src_audio_path) - json_data = {"audio_duration": audio_duration} - elif repaint_source == "text2music": - json_data = text2music_json_data - src_audio_path = json_data["audio_path"] - elif repaint_source == "last_repaint": - json_data = repaint_json_data - src_audio_path = json_data["audio_path"] - - return text2music_process_func( - json_data["audio_duration"], - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - retake_seeds=retake_seeds, - retake_variance=retake_variance, - task="repaint", - repaint_start=repaint_start, - repaint_end=repaint_end, - src_audio_path=src_audio_path, - lora_name_or_path="none" if "lora_name_or_path" not in json_data else json_data["lora_name_or_path"] - ) - - repaint_bnt.click( - fn=repaint_process_func, - inputs=[ - input_params_json, - repaint_input_params_json, - retake_variance, - retake_seeds, - repaint_start, - repaint_end, - repaint_source, - repaint_source_audio_upload, - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - ], - outputs=repaint_outputs + [repaint_input_params_json], - ) - with gr.Tab("edit"): - edit_prompt = gr.Textbox(lines=2, label="Edit Tags", max_lines=4) - edit_lyrics = gr.Textbox(lines=9, label="Edit Lyrics", max_lines=13) - retake_seeds = gr.Textbox( - label="edit seeds (default None)", placeholder="", value=None - ) - - edit_type = gr.Radio( - ["only_lyrics", "remix"], - value="only_lyrics", - label="Edit Type", - elem_id="edit_type", - info="`only_lyrics` will keep the whole song the same except lyrics difference. Make your diffrence smaller, e.g. one lyrc line change.\nremix can change the song melody and genre", - ) - edit_n_min = gr.Slider( - minimum=0.0, - maximum=1.0, - step=0.01, - value=0.6, - label="edit_n_min", - interactive=True, - ) - edit_n_max = gr.Slider( - minimum=0.0, - maximum=1.0, - step=0.01, - value=1.0, - label="edit_n_max", - interactive=True, - ) - - def edit_type_change_func(edit_type): - if edit_type == "only_lyrics": - n_min = 0.6 - n_max = 1.0 - elif edit_type == "remix": - n_min = 0.2 - n_max = 0.4 - return n_min, n_max - - edit_type.change( - edit_type_change_func, - inputs=[edit_type], - outputs=[edit_n_min, edit_n_max], - ) - - edit_source = gr.Radio( - ["text2music", "last_edit", "upload"], - value="text2music", - label="Edit Source", - elem_id="edit_source", - ) - edit_source_audio_upload = gr.Audio( - label="Upload Audio", - type="filepath", - visible=False, - elem_id="edit_source_audio_upload", - show_download_button=True, - ) - edit_source.change( - fn=lambda x: gr.update( - visible=x == "upload", elem_id="edit_source_audio_upload" - ), - inputs=[edit_source], - outputs=[edit_source_audio_upload], - ) - - edit_bnt = gr.Button("Edit", variant="primary") - edit_outputs, edit_input_params_json = create_output_ui("Edit") - - def edit_process_func( - text2music_json_data, - edit_input_params_json, - edit_source, - edit_source_audio_upload, - prompt, - lyrics, - edit_prompt, - edit_lyrics, - edit_n_min, - edit_n_max, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - retake_seeds, - ): - if edit_source == "upload": - src_audio_path = edit_source_audio_upload - audio_duration = librosa.get_duration(filename=src_audio_path) - json_data = {"audio_duration": audio_duration} - elif edit_source == "text2music": - json_data = text2music_json_data - src_audio_path = json_data["audio_path"] - elif edit_source == "last_edit": - json_data = edit_input_params_json - src_audio_path = json_data["audio_path"] - - if not edit_prompt: - edit_prompt = prompt - if not edit_lyrics: - edit_lyrics = lyrics - - return text2music_process_func( - json_data["audio_duration"], - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - task="edit", - src_audio_path=src_audio_path, - edit_target_prompt=edit_prompt, - edit_target_lyrics=edit_lyrics, - edit_n_min=edit_n_min, - edit_n_max=edit_n_max, - retake_seeds=retake_seeds, - lora_name_or_path="none" if "lora_name_or_path" not in json_data else json_data["lora_name_or_path"] - ) - - edit_bnt.click( - fn=edit_process_func, - inputs=[ - input_params_json, - edit_input_params_json, - edit_source, - edit_source_audio_upload, - prompt, - lyrics, - edit_prompt, - edit_lyrics, - edit_n_min, - edit_n_max, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - retake_seeds, - ], - outputs=edit_outputs + [edit_input_params_json], - ) - with gr.Tab("extend"): - extend_seeds = gr.Textbox( - label="extend seeds (default None)", placeholder="", value=None - ) - left_extend_length = gr.Slider( - minimum=0.0, - maximum=240.0, - step=0.01, - value=0.0, - label="Left Extend Length", - interactive=True, - ) - right_extend_length = gr.Slider( - minimum=0.0, - maximum=240.0, - step=0.01, - value=30.0, - label="Right Extend Length", - interactive=True, - ) - extend_source = gr.Radio( - ["text2music", "last_extend", "upload"], - value="text2music", - label="Extend Source", - elem_id="extend_source", - ) - - extend_source_audio_upload = gr.Audio( - label="Upload Audio", - type="filepath", - visible=False, - elem_id="extend_source_audio_upload", - show_download_button=True, - ) - extend_source.change( - fn=lambda x: gr.update( - visible=x == "upload", elem_id="extend_source_audio_upload" - ), - inputs=[extend_source], - outputs=[extend_source_audio_upload], - ) - - extend_bnt = gr.Button("Extend", variant="primary") - extend_outputs, extend_input_params_json = create_output_ui("Extend") - - def extend_process_func( - text2music_json_data, - extend_input_params_json, - extend_seeds, - left_extend_length, - right_extend_length, - extend_source, - extend_source_audio_upload, - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - ): - if extend_source == "upload": - src_audio_path = extend_source_audio_upload - # get audio duration - audio_duration = librosa.get_duration(filename=src_audio_path) - json_data = {"audio_duration": audio_duration} - elif extend_source == "text2music": - json_data = text2music_json_data - src_audio_path = json_data["audio_path"] - elif extend_source == "last_extend": - json_data = extend_input_params_json - src_audio_path = json_data["audio_path"] - - repaint_start = -left_extend_length - repaint_end = json_data["audio_duration"] + right_extend_length - return text2music_process_func( - json_data["audio_duration"], - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - retake_seeds=extend_seeds, - retake_variance=1.0, - task="extend", - repaint_start=repaint_start, - repaint_end=repaint_end, - src_audio_path=src_audio_path, - lora_name_or_path="none" if "lora_name_or_path" not in json_data else json_data["lora_name_or_path"] - ) - - extend_bnt.click( - fn=extend_process_func, - inputs=[ - input_params_json, - extend_input_params_json, - extend_seeds, - left_extend_length, - right_extend_length, - extend_source, - extend_source_audio_upload, - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - ], - outputs=extend_outputs + [extend_input_params_json], - ) - - def json2output(json_data): - return ( - json_data["audio_duration"], - json_data["prompt"], - json_data["lyrics"], - json_data["infer_step"], - json_data["guidance_scale"], - json_data["scheduler_type"], - json_data["cfg_type"], - json_data["omega_scale"], - ", ".join(map(str, json_data["actual_seeds"])), - json_data["guidance_interval"], - json_data["guidance_interval_decay"], - json_data["min_guidance_scale"], - json_data["use_erg_tag"], - json_data["use_erg_lyric"], - json_data["use_erg_diffusion"], - ", ".join(map(str, json_data["oss_steps"])), - ( - json_data["guidance_scale_text"] - if "guidance_scale_text" in json_data - else 0.0 - ), - ( - json_data["guidance_scale_lyric"] - if "guidance_scale_lyric" in json_data - else 0.0 - ), - ( - json_data["audio2audio_enable"] - if "audio2audio_enable" in json_data - else False - ), - ( - json_data["ref_audio_strength"] - if "ref_audio_strength" in json_data - else 0.5 - ), - ( - json_data["ref_audio_input"] - if "ref_audio_input" in json_data - else None - ), - ) - - def sample_data(lora_name_or_path_): - json_data = sample_data_func(lora_name_or_path_) - return json2output(json_data) - - sample_bnt.click( - sample_data, - inputs=[lora_name_or_path], - outputs=[ - audio_duration, - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - audio2audio_enable, - ref_audio_strength, - ref_audio_input, - ], - ) - - text2music_bnt.click( - fn=text2music_process_func, - inputs=[ - audio_duration, - prompt, - lyrics, - infer_step, - guidance_scale, - scheduler_type, - cfg_type, - omega_scale, - manual_seeds, - guidance_interval, - guidance_interval_decay, - min_guidance_scale, - use_erg_tag, - use_erg_lyric, - use_erg_diffusion, - oss_steps, - guidance_scale_text, - guidance_scale_lyric, - audio2audio_enable, - ref_audio_strength, - ref_audio_input, - lora_name_or_path, - ], - outputs=outputs + [input_params_json], - ) - - -def create_main_demo_ui( - text2music_process_func=dump_func, - sample_data_func=dump_func, - load_data_func=dump_func, -): - with gr.Blocks( - title="ACE-Step Model 1.0 DEMO", - ) as demo: - gr.Markdown( - """ -

ACE-Step: A Step Towards Music Generation Foundation Model

-

- Project | - Checkpoints | - Discord -

- """ - ) - with gr.Tab("text2music"): - create_text2music_ui( - gr=gr, - text2music_process_func=text2music_process_func, - sample_data_func=sample_data_func, - load_data_func=load_data_func, - ) - return demo - - -if __name__ == "__main__": - demo = create_main_demo_ui() - demo.launch( - server_name="0.0.0.0", - server_port=7860, - ) diff --git a/webui.bat b/webui.bat new file mode 100644 index 0000000000000000000000000000000000000000..b6dee1ec66e6d329aa94da229f422bea2bfa0370 --- /dev/null +++ b/webui.bat @@ -0,0 +1,162 @@ +@echo off + +:: The original source of the webui.bat file is stable-diffusion-webui +:: Modified and enhanced by Gemini with features for venv management and requirements handling. + +:: --------- Configuration --------- +set COMMANDLINE_ARGS= +:: Define the name of the Launch application +set APPLICATION_NAME=app.py +:: Define the name of the virtual environment directory +set VENV_NAME=venv +:: Set to 1 to always attempt to update packages from requirements.txt on every launch +set ALWAYS_UPDATE_REQS=0 +:: --------------------------------- + + +:: Set PYTHON executable if not already defined +if not defined PYTHON (set PYTHON=python) +:: Set VENV_DIR using VENV_NAME if not already defined +if not defined VENV_DIR (set "VENV_DIR=%~dp0%VENV_NAME%") + +mkdir tmp 2>NUL + +:: Check if Python is callable +%PYTHON% -c "" >tmp/stdout.txt 2>tmp/stderr.txt +if %ERRORLEVEL% == 0 goto :check_pip +echo Couldn't launch python +goto :show_stdout_stderr + +:check_pip +:: Check if pip is available +%PYTHON% -mpip --help >tmp/stdout.txt 2>tmp/stderr.txt +if %ERRORLEVEL% == 0 goto :start_venv +:: If pip is not available and PIP_INSTALLER_LOCATION is set, try to install pip +if "%PIP_INSTALLER_LOCATION%" == "" goto :show_stdout_stderr +%PYTHON% "%PIP_INSTALLER_LOCATION%" >tmp/stdout.txt 2>tmp/stderr.txt +if %ERRORLEVEL% == 0 goto :start_venv +echo Couldn't install pip +goto :show_stdout_stderr + +:start_venv +:: Skip venv creation/activation if VENV_DIR is explicitly set to "-" +if ["%VENV_DIR%"] == ["-"] goto :skip_venv_entirely +:: Skip venv creation/activation if SKIP_VENV is set to "1" +if ["%SKIP_VENV%"] == ["1"] goto :skip_venv_entirely + +:: Check if the venv already exists by looking for Python.exe in its Scripts directory +dir "%VENV_DIR%\Scripts\Python.exe" >tmp/stdout.txt 2>tmp/stderr.txt +if %ERRORLEVEL% == 0 goto :activate_venv_and_maybe_update + +:: Venv does not exist, create it +echo Virtual environment not found in "%VENV_DIR%". Creating a new one. +for /f "delims=" %%i in ('CALL %PYTHON% -c "import sys; print(sys.executable)"') do set PYTHON_FULLNAME="%%i" +echo Creating venv in directory %VENV_DIR% using python %PYTHON_FULLNAME% +%PYTHON_FULLNAME% -m venv "%VENV_DIR%" >tmp/stdout.txt 2>tmp/stderr.txt +if %ERRORLEVEL% NEQ 0 ( + echo Unable to create venv in directory "%VENV_DIR%" + goto :show_stdout_stderr +) +echo Venv created. + +:: Install requirements for the first time if venv was just created +:: This section handles the initial installation of packages from requirements.txt +:: immediately after a new virtual environment is created. +echo Checking for requirements.txt for initial setup in %~dp0 +if exist "%~dp0requirements.txt" ( + echo Found requirements.txt, attempting to install for initial setup... + call "%VENV_DIR%\Scripts\activate.bat" + echo Installing packages from requirements.txt ^(initial setup^)... + "%VENV_DIR%\Scripts\python.exe" -m pip install -r "%~dp0requirements.txt" + if %ERRORLEVEL% NEQ 0 ( + echo Failed to install requirements during initial setup. Please check the output above. + pause + goto :show_stdout_stderr_custom_pip_initial + ) + echo Initial requirements installed successfully. + call "%VENV_DIR%\Scripts\deactivate.bat" +) else ( + echo No requirements.txt found for initial setup, skipping package installation. +) +goto :activate_venv_and_maybe_update + + +:activate_venv_and_maybe_update +:: This label is reached if the venv exists or was just created. +:: Set PYTHON to point to the venv's Python interpreter. +set PYTHON="%VENV_DIR%\Scripts\Python.exe" +echo Activating venv: %PYTHON% + +:: Always update requirements if ALWAYS_UPDATE_REQS is 1 +:: This section allows for updating packages from requirements.txt on every launch +:: if the ALWAYS_UPDATE_REQS variable is set to 1. +if defined ALWAYS_UPDATE_REQS ( + if "%ALWAYS_UPDATE_REQS%"=="1" ( + echo ALWAYS_UPDATE_REQS is enabled. + if exist "%~dp0requirements.txt" ( + echo Attempting to update packages from requirements.txt... + REM No need to call activate.bat here again, PYTHON is already set to the venv's python + %PYTHON% -m pip install -r "%~dp0requirements.txt" + if %ERRORLEVEL% NEQ 0 ( + echo Failed to update requirements. Please check the output above. + pause + goto :endofscript + ) + echo Requirements updated successfully. + ) else ( + echo ALWAYS_UPDATE_REQS is enabled, but no requirements.txt found. Skipping update. + ) + ) else ( + echo ALWAYS_UPDATE_REQS is not enabled or not set to 1. Skipping routine update. + ) +) + +goto :launch + +:skip_venv_entirely +:: This label is reached if venv usage is explicitly skipped. +echo Skipping venv. +goto :launch + +:launch +:: Launch the main application +echo Launching Web UI with arguments: %COMMANDLINE_ARGS% %* +%PYTHON% %APPLICATION_NAME% %COMMANDLINE_ARGS% %* +echo Launch finished. +pause +exit /b + +:show_stdout_stderr_custom_pip_initial +:: Custom error handler for failures during the initial pip install process. +echo. +echo exit code ^(pip initial install^): %errorlevel% +echo Errors during initial pip install. See output above. +echo. +echo Launch unsuccessful. Exiting. +pause +exit /b + + +:show_stdout_stderr +:: General error handler: displays stdout and stderr from the tmp directory. +echo. +echo exit code: %errorlevel% + +for /f %%i in ("tmp\stdout.txt") do set size=%%~zi +if %size% equ 0 goto :show_stderr +echo. +echo stdout: +type tmp\stdout.txt + +:show_stderr +for /f %%i in ("tmp\stderr.txt") do set size=%%~zi +if %size% equ 0 goto :endofscript +echo. +echo stderr: +type tmp\stderr.txt + +:endofscript +echo. +echo Launch unsuccessful. Exiting. +pause +exit /b \ No newline at end of file