AnhP commited on
Commit
6cfcfea
·
verified ·
1 Parent(s): 6b2d304

Upload 92 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. assets/f0/.gitattributes +0 -0
  3. assets/ico.png +3 -0
  4. assets/languages/en-US.json +809 -0
  5. assets/languages/vi-VN.json +809 -0
  6. assets/logs/mute/f0/mute.wav.npy +3 -0
  7. assets/logs/mute/f0_voiced/mute.wav.npy +3 -0
  8. assets/logs/mute/sliced_audios/mute32000.wav +3 -0
  9. assets/logs/mute/sliced_audios/mute40000.wav +3 -0
  10. assets/logs/mute/sliced_audios/mute48000.wav +3 -0
  11. assets/logs/mute/sliced_audios_16k/mute.wav +0 -0
  12. assets/logs/mute/v1_extracted/mute.npy +3 -0
  13. assets/logs/mute/v2_extracted/mute.npy +3 -0
  14. assets/models/audioldm2/.gitattributes +0 -0
  15. assets/models/embedders/.gitattributes +0 -0
  16. assets/models/predictors/.gitattributes +0 -0
  17. assets/models/pretrained_custom/.gitattributes +0 -0
  18. assets/models/pretrained_v1/.gitattributes +0 -0
  19. assets/models/pretrained_v2/.gitattributes +0 -0
  20. assets/models/speaker_diarization/assets/gpt2.tiktoken +0 -0
  21. assets/models/speaker_diarization/assets/mel_filters.npz +3 -0
  22. assets/models/speaker_diarization/assets/multilingual.tiktoken +0 -0
  23. assets/models/speaker_diarization/models/.gitattributes +0 -0
  24. assets/models/uvr5/.gitattributes +0 -0
  25. assets/presets/.gitattributes +0 -0
  26. assets/weights/.gitattributes +0 -0
  27. audios/.gitattributes +0 -0
  28. dataset/.gitattributes +0 -0
  29. main/app/app.py +0 -0
  30. main/app/parser.py +340 -0
  31. main/app/tensorboard.py +30 -0
  32. main/configs/config.json +547 -0
  33. main/configs/config.py +90 -0
  34. main/configs/decrypt.bin +3 -0
  35. main/configs/v1/32000.json +46 -0
  36. main/configs/v1/40000.json +46 -0
  37. main/configs/v1/48000.json +46 -0
  38. main/configs/v2/32000.json +42 -0
  39. main/configs/v2/40000.json +42 -0
  40. main/configs/v2/48000.json +42 -0
  41. main/inference/audio_effects.py +180 -0
  42. main/inference/audioldm2.py +210 -0
  43. main/inference/convert.py +590 -0
  44. main/inference/create_dataset.py +230 -0
  45. main/inference/create_index.py +90 -0
  46. main/inference/extract.py +360 -0
  47. main/inference/preprocess.py +270 -0
  48. main/inference/separator_music.py +310 -0
  49. main/inference/train.py +990 -0
  50. main/library/algorithm/commons.py +60 -0
.gitattributes CHANGED
@@ -38,3 +38,4 @@ assets/logs/mute/sliced_audios/mute32000.wav filter=lfs diff=lfs merge=lfs -text
38
  assets/logs/mute/sliced_audios/mute40000.wav filter=lfs diff=lfs merge=lfs -text
39
  assets/logs/mute/sliced_audios/mute44100.wav filter=lfs diff=lfs merge=lfs -text
40
  assets/logs/mute/sliced_audios/mute48000.wav filter=lfs diff=lfs merge=lfs -text
 
 
38
  assets/logs/mute/sliced_audios/mute40000.wav filter=lfs diff=lfs merge=lfs -text
39
  assets/logs/mute/sliced_audios/mute44100.wav filter=lfs diff=lfs merge=lfs -text
40
  assets/logs/mute/sliced_audios/mute48000.wav filter=lfs diff=lfs merge=lfs -text
41
+ assets/ico.png filter=lfs diff=lfs merge=lfs -text
assets/f0/.gitattributes ADDED
File without changes
assets/ico.png ADDED

Git LFS Details

  • SHA256: 3580dfee1d9b4c8ed32870bb798a36d50e6586a0872a1da9bdbe4c3ca425b7f6
  • Pointer size: 132 Bytes
  • Size of remote file: 3.95 MB
assets/languages/en-US.json ADDED
@@ -0,0 +1,809 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "set_lang": "Display language set to {lang}.",
3
+ "no_support_gpu": "Unfortunately, no compatible GPU is available to support your training.",
4
+ "text": "text",
5
+ "upload_success": "File {name} uploaded successfully.",
6
+ "download_url": "Download from the link",
7
+ "download_from_csv": "Download from the CSV model repository",
8
+ "search_models": "Search models",
9
+ "upload": "Upload",
10
+ "option_not_valid": "Invalid option!",
11
+ "list_model": "Model list",
12
+ "success": "Completed!",
13
+ "index": "index",
14
+ "model": "model",
15
+ "zip": "compress",
16
+ "search": "search",
17
+ "provide_file": "Please provide a valid {filename} file!",
18
+ "start": "Starting {start}...",
19
+ "not_found": "Not found {name}.",
20
+ "found": "Found {results} results!",
21
+ "download_music": "download music",
22
+ "download": "download",
23
+ "provide_url": "Please provide a url.",
24
+ "provide_name_is_save": "Please provide a model name to save.",
25
+ "not_support_url": "Your model url is not supported.",
26
+ "error_occurred": "An error occurred: {e}.",
27
+ "not_model": "The file you uploaded is not a model file!",
28
+ "unable_analyze_model": "Unable to analyze the model!",
29
+ "download_pretrain": "Downloading pre-trained model...",
30
+ "provide_pretrain": "Please provide a pre-trained model url {dg}.",
31
+ "sr_not_same": "The sample rates of the two models are not the same.",
32
+ "architectures_not_same": "Cannot merge models. The architectures are not the same.",
33
+ "fushion_model": "model fusion",
34
+ "model_fushion_info": "The model {name} is fused from {pth_1} and {pth_2} with a ratio of {ratio}.",
35
+ "not_found_create_time": "Creation time not found.",
36
+ "format_not_valid": "Invalid format.",
37
+ "read_info": "Models trained on different applications may produce different information or may not be readable!",
38
+ "epoch": "epoch.",
39
+ "step": "step",
40
+ "sr": "Sample rate",
41
+ "f0": "pitch training",
42
+ "version": "version.",
43
+ "not_f0": "Pitch training not performed",
44
+ "trained_f0": "Pitch training performed",
45
+ "model_info": "Model Name: {model_name}\n\n Model Creator: {model_author}\n\nEpoch: {epochs}\n\nSteps: {steps}\n\nVersion: {version}\n\nSample Rate: {sr}\n\nPitch Training: {pitch_guidance}\n\nHash (ID): {model_hash}\n\nCreation Time: {creation_date_str}\n\nVocoder: {vocoder}\n",
46
+ "input_not_valid": "Please provide valid input!",
47
+ "output_not_valid": "Please provide valid output!",
48
+ "apply_effect": "apply effect",
49
+ "enter_the_text": "Please enter the text to speech!",
50
+ "choose_voice": "Please choose a voice!",
51
+ "convert": "Converting {name}...",
52
+ "separator_music": "music separation",
53
+ "notfound": "Not found",
54
+ "turn_on_use_audio": "Please enable using separated audio to proceed",
55
+ "turn_off_convert_backup": "Disable backup voice conversion to use the original voice",
56
+ "turn_off_merge_backup": "Disable merging backup voice to use the original voice",
57
+ "not_found_original_vocal": "Original vocal not found!",
58
+ "convert_vocal": "Converting voice...",
59
+ "convert_success": "Voice conversion completed!",
60
+ "convert_backup": "Converting backup voice...",
61
+ "convert_backup_success": "Backup voice conversion completed!",
62
+ "merge_backup": "Merging main voice with backup voice...",
63
+ "merge_success": "Merge completed.",
64
+ "is_folder": "Input is a folder: Converting all audio files in the folder...",
65
+ "not_found_in_folder": "No audio files found in the folder!",
66
+ "batch_convert": "Batch conversion in progress...",
67
+ "batch_convert_success": "Batch conversion successful!",
68
+ "create": "create",
69
+ "provide_name": "Please provide a model name.",
70
+ "not_found_data": "Data not found",
71
+ "not_found_data_preprocess": "Processed audio data not found, please reprocess.",
72
+ "not_found_data_extract": "Extracted audio data not found, please re-extract.",
73
+ "provide_pretrained": "Please provide pre-trained {dg}.",
74
+ "download_pretrained": "Download pre-trained {dg}{rvc_version} original",
75
+ "not_found_pretrain": "Pre-trained {dg} not found",
76
+ "not_use_pretrain": "No pre-trained model will be used",
77
+ "training": "training",
78
+ "rick_roll": "Click here if you want to be Rick Roll :) ---> [RickRoll]({rickroll})",
79
+ "terms_of_use": "**Please do not use the project for any unethical, illegal, or harmful purposes to individuals or organizations...**",
80
+ "exemption": "**In cases where users do not comply with the terms or violate them, I will not be responsible for any claims, damages, or liabilities, whether in contract, negligence, or other causes arising from, outside of, or related to the software, its use, or other transactions associated with it.**",
81
+ "separator_tab": "Music Separation",
82
+ "4_part": "A simple music separation system can separate into 4 parts: Instruments, Vocals, Main vocals, Backup vocals",
83
+ "clear_audio": "Clean audio",
84
+ "separator_backing": "Separate backup vocals",
85
+ "denoise_mdx": "Denoise MDX separation",
86
+ "use_mdx": "Use MDX",
87
+ "dereveb_audio": "Remove vocal reverb",
88
+ "dereveb_backing": "Remove backup reverb",
89
+ "separator_model": "Music separation model",
90
+ "separator_backing_model": "Backup separation model",
91
+ "shift": "Shift",
92
+ "shift_info": "Higher is better quality but slower and uses more resources",
93
+ "segments_size": "Segments Size",
94
+ "segments_size_info": "Higher is better quality but uses more resources",
95
+ "batch_size": "Batch size",
96
+ "batch_size_info": "Number of samples processed simultaneously in one training cycle. Higher can cause memory overflow",
97
+ "mdx_batch_size_info": "Number of samples processed at a time. Batch processing optimizes calculations. Large batches can cause memory overflow; small batches reduce resource efficiency",
98
+ "overlap": "Overlap",
99
+ "overlap_info": "Overlap amount between prediction windows",
100
+ "export_format": "Export format",
101
+ "export_info": "The export format to export the audio file in",
102
+ "output_separator": "Separated output",
103
+ "hop_length_info": "Analyzing the time transfer window when performing transformations is allowed. The detailed value is compact but requires more calculation",
104
+ "drop_audio": "Drop audio here",
105
+ "drop_text": "Drop text file here",
106
+ "use_url": "YouTube link",
107
+ "url_audio": "Link audio",
108
+ "downloads": "Downloads",
109
+ "clean_strength": "Audio cleaning strength",
110
+ "clean_strength_info": "Strength of the audio cleaner for filtering vocals during export",
111
+ "input_output": "Audio input, output",
112
+ "audio_path": "Input audio path",
113
+ "refesh": "Refresh",
114
+ "output_folder": "Output audio folder path",
115
+ "output_folder_info": "Enter the folder path where the audio will be exported",
116
+ "input_audio": "Audio input",
117
+ "instruments": "Instruments",
118
+ "original_vocal": "Original vocal",
119
+ "main_vocal": "Main vocal",
120
+ "backing_vocal": "Backup vocal",
121
+ "convert_audio": "Convert Audio",
122
+ "convert_info": "Convert audio using a trained voice model",
123
+ "autotune": "Auto-tune",
124
+ "use_audio": "Use separated audio",
125
+ "convert_original": "Convert original voice",
126
+ "convert_backing": "Convert backup voice",
127
+ "not_merge_backing": "Do not merge backup voice",
128
+ "merge_instruments": "Merge instruments",
129
+ "pitch": "Pitch",
130
+ "pitch_info": "Recommendation: set to 12 to change male voice to female and vice versa",
131
+ "model_accordion": "Model and index",
132
+ "model_name": "Model file",
133
+ "index_path": "Index file",
134
+ "index_strength": "Index strength",
135
+ "index_strength_info": "Higher values increase strength. However, lower values may reduce artificial effects in the audio",
136
+ "output_path": "Audio output path",
137
+ "output_path_info": "Enter the output path (leave it as .wav format; it will auto-correct during conversion)",
138
+ "setting": "General settings",
139
+ "f0_method": "Extraction method",
140
+ "f0_method_info": "Method used for data extraction",
141
+ "f0_method_hybrid": "HYBRID extraction method",
142
+ "f0_method_hybrid_info": "Combination of two or more different types of extracts",
143
+ "hubert_model": "Embedding model",
144
+ "hubert_info": "Pre-trained model to assist embedding",
145
+ "modelname": "Model name",
146
+ "modelname_info": "If you have your own model, just upload it and input the name here",
147
+ "split_audio": "Split audio",
148
+ "autotune_rate": "Auto-tune rate",
149
+ "autotune_rate_info": "Level of auto-tuning adjustment",
150
+ "resample": "Resample",
151
+ "resample_info": "Resample post-processing to the final sample rate; 0 means no resampling, NOTE: SOME FORMATS DO NOT SUPPORT SPEEDS OVER 48000",
152
+ "filter_radius": "Filter radius",
153
+ "filter_radius_info": "If greater than three, median filtering is applied. The value represents the filter radius and can reduce breathiness or noise.",
154
+ "volume_envelope": "Volume envelope",
155
+ "volume_envelope_info": "Use the input volume envelope to replace or mix with the output volume envelope. The closer to 1, the more the output envelope is used",
156
+ "protect": "Consonant protection",
157
+ "protect_info": "Protect distinct consonants and breathing sounds to prevent audio tearing and other artifacts. Increasing this value provides comprehensive protection. Reducing it may reduce protection but also minimize indexing effects",
158
+ "output_convert": "Converted audio",
159
+ "main_convert": "Convert main voice",
160
+ "main_or_backing": "Main voice + Backup voice",
161
+ "voice_or_instruments": "Voice + Instruments",
162
+ "convert_text": "Convert Text",
163
+ "convert_text_markdown": "## Convert Text to Speech",
164
+ "convert_text_markdown_2": "Convert text to speech and read aloud using the trained voice model",
165
+ "input_txt": "Input data from a text file (.txt)",
166
+ "text_to_speech": "Text to read",
167
+ "voice_speed": "Reading speed",
168
+ "voice_speed_info": "Speed of the voice",
169
+ "tts_1": "1. Convert Text to Speech",
170
+ "tts_2": "2. Convert Speech",
171
+ "voice": "Voices by country",
172
+ "output_tts": "Output speech path",
173
+ "output_tts_convert": "Converted speech output path",
174
+ "tts_output": "Enter the output path",
175
+ "output_tts_markdown": "Unconverted and converted audio",
176
+ "output_text_to_speech": "Generated speech from text-to-speech conversion",
177
+ "output_file_tts_convert": "Speech converted using the model",
178
+ "output_audio": "Audio output",
179
+ "provide_output": "Enter the output path",
180
+ "audio_effects": "Audio Effects",
181
+ "apply_audio_effects": "## Add Additional Audio Effects",
182
+ "audio_effects_edit": "Add effects to audio",
183
+ "reverb": "Reverb effect",
184
+ "chorus": "Chorus effect",
185
+ "delay": "Delay effect",
186
+ "more_option": "Additional options",
187
+ "phaser": "Phaser effect",
188
+ "compressor": "Compressor effect",
189
+ "apply": "Apply",
190
+ "reverb_freeze": "Freeze mode",
191
+ "reverb_freeze_info": "Create a continuous echo effect when this mode is enabled",
192
+ "room_size": "Room size",
193
+ "room_size_info": "Adjust the room space to create reverberation",
194
+ "damping": "Damping",
195
+ "damping_info": "Adjust the level of absorption to control the amount of reverberation",
196
+ "wet_level": "Reverb signal level",
197
+ "wet_level_info": "Adjust the level of the reverb signal effect",
198
+ "dry_level": "Original signal level",
199
+ "dry_level_info": "Adjust the level of the signal without effects",
200
+ "width": "Audio width",
201
+ "width_info": "Adjust the width of the audio space",
202
+ "chorus_depth": "Chorus depth",
203
+ "chorus_depth_info": "Adjust the intensity of the chorus to create a wider sound",
204
+ "chorus_rate_hz": "Frequency",
205
+ "chorus_rate_hz_info": "Adjust the oscillation speed of the chorus effect",
206
+ "chorus_mix": "Mix signals",
207
+ "chorus_mix_info": "Adjust the mix level between the original and the processed signal",
208
+ "chorus_centre_delay_ms": "Center delay (ms)",
209
+ "chorus_centre_delay_ms_info": "The delay time between stereo channels to create the chorus effect",
210
+ "chorus_feedback": "Feedback",
211
+ "chorus_feedback_info": "Adjust the amount of the effect signal fed back into the original signal",
212
+ "delay_seconds": "Delay time",
213
+ "delay_seconds_info": "Adjust the delay time between the original and the processed signal",
214
+ "delay_feedback": "Delay feedback",
215
+ "delay_feedback_info": "Adjust the amount of feedback signal, creating a repeating effect",
216
+ "delay_mix": "Delay signal mix",
217
+ "delay_mix_info": "Adjust the mix level between the original and delayed signal",
218
+ "fade": "Fade effect",
219
+ "bass_or_treble": "Bass and treble",
220
+ "limiter": "Threshold limiter",
221
+ "distortion": "Distortion effect",
222
+ "gain": "Audio gain",
223
+ "bitcrush": "Bit reduction effect",
224
+ "clipping": "Clipping effect",
225
+ "fade_in": "Fade-in effect (ms)",
226
+ "fade_in_info": "Time for the audio to gradually increase from 0 to normal level",
227
+ "fade_out": "Fade-out effect (ms)",
228
+ "fade_out_info": "the time it takes for the sound to fade from normal to zero",
229
+ "bass_boost": "Bass boost level (dB)",
230
+ "bass_boost_info": "amount of bass boost in audio track",
231
+ "bass_frequency": "Low-pass filter cutoff frequency (Hz)",
232
+ "bass_frequency_info": "frequencies are reduced. Low frequencies make the bass clearer",
233
+ "treble_boost": "Treble boost level (dB)",
234
+ "treble_boost_info": "high level of sound reinforcement in the audio track",
235
+ "treble_frequency": "High-pass filter cutoff frequency (Hz)",
236
+ "treble_frequency_info": "The frequency will be filtered out. The higher the frequency, the higher the sound will be retained.",
237
+ "limiter_threashold_db": "Limiter threshold",
238
+ "limiter_threashold_db_info": "Limit the maximum audio level to prevent it from exceeding the threshold",
239
+ "limiter_release_ms": "Release time",
240
+ "limiter_release_ms_info": "Time for the audio to return after being limited (Mili Seconds)",
241
+ "distortion_info": "Adjust the level of distortion to create a noisy effect",
242
+ "gain_info": "Adjust the volume level of the signal",
243
+ "clipping_threashold_db": "Clipping threshold",
244
+ "clipping_threashold_db_info": "Trim signals exceeding the threshold, creating a distorted sound",
245
+ "bitcrush_bit_depth": "Bit depth",
246
+ "bitcrush_bit_depth_info": "Reduce audio quality by decreasing bit depth, creating a distorted effect",
247
+ "phaser_depth": "Phaser depth",
248
+ "phaser_depth_info": "Adjust the depth of the effect, impacting its intensity",
249
+ "phaser_rate_hz": "Frequency",
250
+ "phaser_rate_hz_info": "Adjust the frequency of the phaser effect",
251
+ "phaser_mix": "Mix signal",
252
+ "phaser_mix_info": "Adjust the mix level between the original and processed signals",
253
+ "phaser_centre_frequency_hz": "Center frequency",
254
+ "phaser_centre_frequency_hz_info": "The center frequency of the phaser effect, affecting the adjusted frequencies",
255
+ "phaser_feedback": "Feedback",
256
+ "phaser_feedback_info": "Adjust the feedback level of the effect, creating a stronger or lighter phaser feel",
257
+ "compressor_threashold_db": "Compressor threshold",
258
+ "compressor_threashold_db_info": "The threshold level above which the audio will be compressed",
259
+ "compressor_ratio": "Compression ratio",
260
+ "compressor_ratio_info": "Adjust the level of audio compression when exceeding the threshold",
261
+ "compressor_attack_ms": "Attack time (ms)",
262
+ "compressor_attack_ms_info": "Time for compression to start taking effect after the audio exceeds the threshold",
263
+ "compressor_release_ms": "Release time",
264
+ "compressor_release_ms_info": "Time for the audio to return to normal after being compressed",
265
+ "create_dataset_url": "Link to audio (use commas for multiple links)",
266
+ "createdataset": "Create dataset",
267
+ "create_dataset_markdown": "## Create Dataset training from YouTube",
268
+ "create_dataset_markdown_2": "Process and create training datasets using YouTube links",
269
+ "denoise": "Denoise",
270
+ "skip": "Skip",
271
+ "model_ver": "Voice separation version",
272
+ "model_ver_info": "The model version for separating vocals",
273
+ "create_dataset_info": "Dataset creation information",
274
+ "output_data": "Dataset output",
275
+ "output_data_info": "Output data after creation",
276
+ "skip_start": "Skip beginning",
277
+ "skip_start_info": "Skip the initial seconds of the audio; use commas for multiple audios",
278
+ "skip_end": "Skip end",
279
+ "skip_end_info": "Skip the final seconds of the audio; use commas for multiple audios",
280
+ "training_model": "Train Model",
281
+ "training_markdown": "Train and build a voice model with a set of voice data",
282
+ "training_model_name": "Name of the model during training (avoid special characters or spaces)",
283
+ "sample_rate": "Sample rate",
284
+ "sample_rate_info": "Sample rate of the model",
285
+ "training_version": "Model version",
286
+ "training_version_info": "Version of the model during training",
287
+ "training_pitch": "Pitch Guidance",
288
+ "upload_dataset": "Upload dataset",
289
+ "preprocess_effect": "Post processing",
290
+ "clear_dataset": "Clean dataset",
291
+ "preprocess_info": "Preprocessing information",
292
+ "preprocess_button": "1. Processing",
293
+ "extract_button": "2. Extract",
294
+ "extract_info": "Data extraction information",
295
+ "total_epoch": "Total epochs",
296
+ "total_epoch_info": "Total training epochs",
297
+ "save_epoch": "Save frequency",
298
+ "save_epoch_info": "Frequency of saving the model during training to allow retraining",
299
+ "create_index": "Create index",
300
+ "index_algorithm": "Index algorithm",
301
+ "index_algorithm_info": "Algorithm for creating the index",
302
+ "custom_dataset": "Custom dataset folder",
303
+ "custom_dataset_info": "Custom dataset folder for training data",
304
+ "overtraining_detector": "Overtraining detector",
305
+ "overtraining_detector_info": "Check for overtraining during model training",
306
+ "cleanup_training": "Clean Up",
307
+ "cleanup_training_info": "Only enable if you need to retrain the model from scratch.",
308
+ "cache_in_gpu": "Cache in GPU",
309
+ "cache_in_gpu_info": "Store the model in GPU cache memory",
310
+ "dataset_folder": "Folder containing dataset",
311
+ "threshold": "Overtraining threshold",
312
+ "setting_cpu_gpu": "CPU/GPU settings",
313
+ "gpu_number": "Number of GPUs used",
314
+ "gpu_number_info": "Number of GPUs used during training",
315
+ "save_only_latest": "Save only the latest",
316
+ "save_only_latest_info": "Save only the latest D and G models",
317
+ "save_every_weights": "Save all models",
318
+ "save_every_weights_info": "Save all models after each epoch",
319
+ "gpu_info": "GPU information",
320
+ "gpu_info_2": "Information about the GPU used during training",
321
+ "cpu_core": "Number of CPU cores available",
322
+ "cpu_core_info": "Number of CPU cores used during training",
323
+ "not_use_pretrain_2": "Do not use pretraining",
324
+ "not_use_pretrain_info": "Do not use pre-trained models",
325
+ "custom_pretrain": "Custom pretraining",
326
+ "custom_pretrain_info": "Customize pre-training settings",
327
+ "pretrain_file": "Pre-trained model file {dg}",
328
+ "train_info": "Training information",
329
+ "export_model": "5. Export Model",
330
+ "zip_model": "2. Compress model",
331
+ "output_zip": "Output file after compression",
332
+ "model_path": "Model path",
333
+ "model_ratio": "Model ratio",
334
+ "model_ratio_info": "Adjusting towards one side will make the model more like that side",
335
+ "output_model_path": "Model output path",
336
+ "fushion": "Model Fusion",
337
+ "fushion_markdown": "## Fushion Two Models",
338
+ "fushion_markdown_2": "Combine two voice models into a single model",
339
+ "read_model": "Read Information",
340
+ "read_model_markdown": "## Read Model Information",
341
+ "read_model_markdown_2": "Retrieve recorded information within the model",
342
+ "drop_model": "Drop model here",
343
+ "readmodel": "Read model",
344
+ "model_path_info": "Enter the path to the model file",
345
+ "modelinfo": "Model Information",
346
+ "download_markdown": "## Download Model",
347
+ "download_markdown_2": "Download voice models, pre-trained models, and embedding models",
348
+ "model_download": "Download voice model",
349
+ "model_url": "Link to the model",
350
+ "15s": "Please wait about 15 seconds. The system will restart automatically!",
351
+ "model_download_select": "Choose a model download method",
352
+ "model_warehouse": "Model repository",
353
+ "get_model": "Retrieve model",
354
+ "name_to_search": "Name to search",
355
+ "search_2": "Search",
356
+ "select_download_model": "Choose a searched model (Click to select)",
357
+ "download_pretrained_2": "Download pre-trained model",
358
+ "only_huggingface": "Supports only huggingface.co",
359
+ "pretrained_url": "Pre-trained model link {dg}",
360
+ "select_pretrain": "Choose pre-trained model",
361
+ "select_pretrain_info": "Choose a pre-trained model to download",
362
+ "pretrain_sr": "Model sample rate",
363
+ "drop_pretrain": "Drop pre-trained model {dg} here",
364
+ "settings": "Settings",
365
+ "settings_markdown": "## Additional Settings",
366
+ "settings_markdown_2": "Customize additional features of the project",
367
+ "lang": "Language",
368
+ "lang_restart": "The display language in the project (When changing the language, the system will automatically restart after 15 seconds to update)",
369
+ "change_lang": "Change Language",
370
+ "theme": "Theme",
371
+ "theme_restart": "Theme type displayed in the interface (When changing the theme, the system will automatically restart after 15 seconds to update)",
372
+ "theme_button": "Change Theme",
373
+ "change_light_dark": "Switch Light/Dark Mode",
374
+ "tensorboard_url": "Tensorboard URL",
375
+ "errors_loading_audio": "Error loading audio: {e}",
376
+ "apply_error": "An error occurred while applying effects: {e}",
377
+ "indexpath": "Index path",
378
+ "split_total": "Total parts split",
379
+ "process_audio_error": "An error occurred while processing the audio",
380
+ "merge_error": "An error occurred while merging audio",
381
+ "not_found_convert_file": "Processed file not found",
382
+ "convert_batch": "Batch conversion...",
383
+ "found_audio": "Found {audio_files} audio files for conversion.",
384
+ "not_found_audio": "No audio files found!",
385
+ "error_convert": "An error occurred during audio conversion: {e}",
386
+ "convert_batch_success": "Batch conversion completed successfully in {elapsed_time} seconds. {output_path}",
387
+ "convert_audio_success": "File {input_path} converted successfully in {elapsed_time} seconds. {output_path}",
388
+ "hybrid_methods": "Estimating f0 pitch using methods {methods}",
389
+ "method_not_valid": "Invalid method",
390
+ "read_faiss_index_error": "An error occurred while reading the FAISS index: {e}",
391
+ "read_model_error": "Failed to load model: {e}",
392
+ "starting_download": "Starting download",
393
+ "version_not_valid": "Invalid vocal separation version",
394
+ "skip<audio": "Cannot skip as skip time is less than audio file length",
395
+ "skip>audio": "Cannot skip as skip time is greater than audio file length",
396
+ "=<0": "Skip time is less than or equal to 0 and has been skipped",
397
+ "skip_warning": "Skip duration ({seconds} seconds) exceeds audio length ({total_duration} seconds). Skipping.",
398
+ "download_success": "Download completed successfully",
399
+ "create_dataset_error": "An error occurred while creating the training dataset",
400
+ "create_dataset_success": "Training dataset creation completed in {elapsed_time} seconds",
401
+ "skip_start_audio": "Successfully skipped start of audio: {input_file}",
402
+ "skip_end_audio": "Successfully skipped end of audio: {input_file}",
403
+ "merge_audio": "Merged all parts containing audio",
404
+ "separator_process": "Separating vocals: {input}...",
405
+ "not_found_main_vocal": "Main vocal not found!",
406
+ "not_found_backing_vocal": "Backup vocal not found!",
407
+ "not_found_instruments": "Instruments not found",
408
+ "merge_instruments_process": "Merging vocals with instruments...",
409
+ "dereverb": "Removing vocal reverb",
410
+ "dereverb_success": "Successfully removed vocal reverb",
411
+ "save_index": "Index file saved",
412
+ "create_index_error": "An error occurred while creating the index",
413
+ "sr_not_16000": "Sample rate must be 16000",
414
+ "gpu_not_valid": "Invalid GPU index. Switching to CPU.",
415
+ "extract_file_error": "An error occurred while extracting the file",
416
+ "extract_f0_method": "Starting pitch extraction using {num_processes} cores with method {f0_method}...",
417
+ "extract_f0": "Pitch Extraction",
418
+ "extract_f0_success": "Pitch extraction completed in {elapsed_time} seconds.",
419
+ "NaN": "contains NaN values and will be ignored.",
420
+ "start_extract_hubert": "Starting Embedding extraction...",
421
+ "not_found_audio_file": "Audio file not found. Please ensure you provided the correct audio.",
422
+ "process_error": "An error occurred during processing",
423
+ "extract_hubert_success": "Embedding extraction completed in {elapsed_time} seconds.",
424
+ "export_process": "Model path",
425
+ "extract_error": "An error occurred during data extraction",
426
+ "extract_success": "Data extraction successful",
427
+ "min_length>=min_interval>=hop_size": "min_length must be greater than or equal to min_interval and hop_size",
428
+ "max_sil_kept>=hop_size": "max_sil_kept must be greater than or equal to hop_size",
429
+ "start_preprocess": "Starting data preprocessing with {num_processes} cores...",
430
+ "not_integer": "Voice ID folder must be an integer; instead got",
431
+ "preprocess_success": "Preprocessing completed in {elapsed_time} seconds.",
432
+ "preprocess_model_success": "Preprocessing data for the model completed successfully",
433
+ "turn_on_dereverb": "Reverb removal for backup vocals requires enabling reverb removal",
434
+ "turn_on_separator_backing": "Backup vocal separation requires enabling vocal separation",
435
+ "backing_model_ver": "Backup vocal separation model version",
436
+ "clean_audio_success": "Audio cleaned successfully!",
437
+ "separator_error": "An error occurred during music separation",
438
+ "separator_success": "Music separation completed in {elapsed_time} seconds",
439
+ "separator_process_2": "Processing music separation",
440
+ "separator_success_2": "Music separation successful!",
441
+ "separator_process_backing": "Processing backup vocal separation",
442
+ "separator_process_backing_success": "Backup vocal separation successful!",
443
+ "process_original": "Processing original vocal reverb removal...",
444
+ "process_original_success": "Original vocal reverb removal successful!",
445
+ "process_main": "Processing main vocal reverb removal...",
446
+ "process_main_success": "Main vocal reverb removal successful!",
447
+ "process_backing": "Processing backup vocal reverb removal...",
448
+ "process_backing_success": "Backup vocal reverb removal successful!",
449
+ "save_every_epoch": "Save model after: ",
450
+ "total_e": "Total epochs: ",
451
+ "dorg": "Pre-trained G: {pretrainG} | Pre-trained D: {pretrainD}",
452
+ "training_f0": "Pitch Guidance",
453
+ "not_gpu": "No GPU detected, reverting to CPU (not recommended)",
454
+ "not_found_checkpoint": "Checkpoint file not found: {checkpoint_path}",
455
+ "save_checkpoint": "Reloaded checkpoint '{checkpoint_path}' (epoch {checkpoint_dict})",
456
+ "save_model": "Saved model '{checkpoint_path}' (epoch {iteration})",
457
+ "sr_does_not_match": "{sample_rate} Sample rate does not match target {sample_rate2} Sample rate",
458
+ "spec_error": "An error occurred while retrieving specifications from {spec_filename}: {e}",
459
+ "time_or_speed_training": "time={current_time} | training speed={elapsed_time_str}",
460
+ "savemodel": "Saved model '{model_dir}' (epoch {epoch} and step {step})",
461
+ "model_author": "Credit model to {model_author}",
462
+ "unregistered": "Model unregistered",
463
+ "not_author": "Model not credited",
464
+ "training_author": "Model creator name",
465
+ "training_author_info": "To credit the model, enter your name here",
466
+ "extract_model_error": "An error occurred while extracting the model",
467
+ "start_training": "Starting training",
468
+ "import_pretrain": "Loaded pre-trained model ({dg}) '{pretrain}'",
469
+ "not_using_pretrain": "No pre-trained model ({dg}) will be used",
470
+ "training_warning": "WARNING: Generated loss is lower than the lower threshold loss for the next epoch.",
471
+ "overtraining_find": "Overtraining detected at epoch {epoch} with smoothed generator loss {smoothed_value_gen} and smoothed discriminator loss {smoothed_value_disc}",
472
+ "best_epoch": "New best epoch {epoch} with smoothed generator loss {smoothed_value_gen} and smoothed discriminator loss {smoothed_value_disc}",
473
+ "success_training": "Training completed with {epoch} epochs, {global_step} steps, and {loss_gen_all} total generator loss.",
474
+ "training_info": "Lowest generator loss: {lowest_value_rounded} at epoch {lowest_value_epoch}, step {lowest_value_step}",
475
+ "model_training_info": "{model_name} | epoch={epoch} | step={global_step} | {epoch_recorder} | lowest value={lowest_value_rounded} (epoch {lowest_value_epoch} and step {lowest_value_step}) | remaining epochs for overtraining: g/total: {remaining_epochs_gen} d/total: {remaining_epochs_disc} | smoothed generator loss={smoothed_value_gen} | smoothed discriminator loss={smoothed_value_disc}",
476
+ "model_training_info_2": "{model_name} | epoch={epoch} | step={global_step} | {epoch_recorder} | lowest value={lowest_value_rounded} (epoch {lowest_value_epoch} and step {lowest_value_step})",
477
+ "model_training_info_3": "{model_name} | epoch={epoch} | step={global_step} | {epoch_recorder}",
478
+ "training_error": "An error occurred while training the model:",
479
+ "separator_info": "Initializing with output path: {output_dir}, output format: {output_format}",
480
+ "output_dir_is_none": "Output folder not specified. Using current working directory.",
481
+ ">0or=1": "Normalization threshold must be greater than 0 and less than or equal to 1.",
482
+ "output_single": "Single root output requested; only one file ({output_single_stem}) will be written",
483
+ "step2": "The second step will be reversed using spectrogram instead of waveform. This may improve quality but is slightly slower.",
484
+ "name_ver": "Version {name}",
485
+ "os": "Operating System",
486
+ "platform_info": "System: {system_info} Name: {node} Release: {release} Machine: {machine} Processor: {processor}",
487
+ "none_ffmpeg": "FFmpeg is not installed. Please install FFmpeg to use this package.",
488
+ "install_onnx": "ONNX Runtime package {pu} installed with version",
489
+ "running_in_cpu": "Unable to configure hardware acceleration, running in CPU mode",
490
+ "running_in_cuda": "CUDA available in Torch, setting Torch device to CUDA",
491
+ "onnx_have": "ONNXruntime available {have}, enabling acceleration",
492
+ "onnx_not_have": "{have} not available in ONNXruntime; acceleration will NOT be enabled",
493
+ "python_not_install": "Python package: {package_name} is not installed",
494
+ "hash": "Calculating hash for model file {model_path}",
495
+ "ioerror": "IOError while seeking -10 MB or reading model file to compute hash: {e}",
496
+ "cancel_download": "File already exists at {output_path}, skipping download",
497
+ "download_model": "Downloading file from {url} to {output_path} with a timeout of 300 seconds",
498
+ "download_error": "Failed to download file from {url}, response code: {status_code}",
499
+ "vip_model": "Model: '{model_friendly_name}' is a premium model intended by Anjok07 only for paid subscriber access.",
500
+ "vip_print": "Hey there, if you haven't subscribed, please consider supporting UVR's developer, Anjok07, by subscribing here: https://patreon.com/uvr",
501
+ "search_model": "Searching for model {model_filename} in the list of supported models in the group",
502
+ "load_download_json": "Downloaded model list loaded",
503
+ "single_model": "Identified single model file: {model_friendly_name}",
504
+ "not_found_model": "Model not found in the UVR repository, attempting to download from the audio model separation repository...",
505
+ "single_model_path": "Returning path for single model file: {model_path}",
506
+ "find_model": "Input file name {model_filename} found in multi-file model: {model_friendly_name}",
507
+ "find_models": "Identified multi-file model: {model_friendly_name}, iterating through files to download",
508
+ "find_path": "Attempting to determine download PATH for config pair",
509
+ "not_found_model_warehouse": "Model not found in the UVR repository, attempting to download from the audio model separation repository...",
510
+ "yaml_warning": "The model name you specified, {model_filename}, is actually a model config file rather than a model file.",
511
+ "yaml_warning_2": "We found a model matching this config file: {config_key}, so we'll use that model file for this run.",
512
+ "yaml_warning_3": "To avoid confusing/inconsistent behavior in the future, specify the actual model file name instead.",
513
+ "yaml_debug": "Config YAML model file not found in UVR repository, attempting to download from the audio model separation repository...",
514
+ "download_model_friendly": "All files downloaded for model {model_friendly_name}, returning original path {model_path}",
515
+ "not_found_model_2": "Model file {model_filename} not found in the supported files",
516
+ "load_yaml": "Loading model data from YAML at path {model_data_yaml_filepath}",
517
+ "load_yaml_2": "Model data loaded from YAML file: {model_data}",
518
+ "hash_md5": "Computing MD5 hash for model file to identify model parameters from UVR data...",
519
+ "model_hash": "Model {model_path} has hash {model_hash}",
520
+ "mdx_data": "MDX model data path set to {mdx_model_data_path}",
521
+ "load_mdx": "Loading MDX model parameters from UVR model data file...",
522
+ "model_not_support": "Unsupported model file: no parameters found for MD5 hash {model_hash} in UVR model data for MDX vault.",
523
+ "uvr_json": "Model data loaded from UVR JSON with hash {model_hash}: {model_data}",
524
+ "loading_model": "Loading model {model_filename}...",
525
+ "download_model_friendly_2": "Downloaded model, friendly name: {model_friendly_name}, Model path: {model_path}",
526
+ "model_type_not_support": "Unsupported model type: {model_type}",
527
+ "demucs_not_support_python<3.10": "Demucs models require Python version 3.10 or higher.",
528
+ "import_module": "Importing module for model type",
529
+ "initialization": "Initializing separator class for model type",
530
+ "loading_model_success": "Model loading completed.",
531
+ "loading_model_duration": "Model loading duration",
532
+ "starting_separator": "Starting separation process for audio file path",
533
+ "normalization": "Normalization threshold set to {normalization_threshold}, waveform will be scaled down to this maximum amplitude to prevent clipping.",
534
+ "loading_separator_model": "Downloading model {model_filename}...",
535
+ "separator_success_3": "Separation process completed.",
536
+ "separator_duration": "Separation duration",
537
+ "downloading_model": "Downloaded model, type: {model_type}, friendly name: {model_friendly_name}, Model path: {model_path}, Model data: {model_data_dict_size} items",
538
+ "demucs_info": "Demucs parameters: Segment size = {segment_size}, Segment size active = {segments_enabled}",
539
+ "demucs_info_2": "Demucs parameters: Number of predictions = {shifts}, Overlap = {overlap}",
540
+ "start_demucs": "Demucs Separator initialization completed",
541
+ "start_separator": "Starting separation process...",
542
+ "prepare_mix": "Preparing mixture...",
543
+ "demix": "Mixture prepared for demixing. Shape: {shape}",
544
+ "cancel_mix": "Loading model for demixing...",
545
+ "model_review": "Model loaded and set to evaluation mode.",
546
+ "del_gpu_cache_after_demix": "Cleared model and GPU cache after demixing.",
547
+ "process_output_file": "Processing output file...",
548
+ "source_length": "Processing source array, source length is {source_length}",
549
+ "process_ver": "Processing source version...",
550
+ "set_map": "Set source map to {part} parts...",
551
+ "process_all_part": "Processing for all root parts...",
552
+ "skip_part": "Skipping root part {stem_name} as out_single_stem is set to {output_single_stem}...",
553
+ "starting_demix_demucs": "Starting the demix process in demix_demucs...",
554
+ "model_infer": "Running model inference...",
555
+ "name_not_pretrained": "{name} is not a pre-trained model or a model bundle.",
556
+ "invalid_checksum": "Invalid checksum for file {path}, expected {checksum} but got {actual_checksum}",
557
+ "mdx_info": "MDX parameters: Batch size = {batch_size}, Segment size = {segment_size}",
558
+ "mdx_info_2": "MDX parameters: Overlap = {overlap}, Hop_length = {hop_length}, Denoising enabled = {enable_denoise}",
559
+ "mdx_info_3": "MDX parameters",
560
+ "load_model_onnx": "Loading ONNX model for inference...",
561
+ "load_model_onnx_success": "Successfully loaded model using ONNXruntime inference session.",
562
+ "onnx_to_pytorch": "Model converted from ONNX to PyTorch due to mismatched segment size with dim_t, processing may be slower.",
563
+ "stft": "Inverse STFT applied. Returning result with shape",
564
+ "no_denoise": "Model running on spectrum without denoising.",
565
+ "mix": "Preparing mix for input audio file {audio_file_path}...",
566
+ "normalization_demix": "Normalizing mix prior to demixing...",
567
+ "mix_success": "Mix preparation completed.",
568
+ "primary_source": "Normalizing primary source...",
569
+ "secondary_source": "Producing secondary source: Mixing in compatible mode",
570
+ "invert_using_spec": "Inverting secondary stem using spectrum when invert_USE_spec is set to True",
571
+ "invert_using_spec_2": "Inverting secondary stem by subtracting transformed stem from the initial transformed mix",
572
+ "enable_denoise": "Model running on both positive and negative spectrums for denoising.",
573
+ "is_match_mix": "is_match_mix: Predicted spectrum obtained directly from STFT output.",
574
+ "save_secondary_stem_output_path": "Saving secondary stem {stem_name} to {stem_output_path}...",
575
+ "starting_model": "Initializing model settings...",
576
+ "input_info": "Model input parameters",
577
+ "model_settings": "Model settings",
578
+ "initialize_mix": "Initializing mix with is_ckpt = {is_ckpt}. Initial mix shape: {shape}",
579
+ "!=2": "Expected 2-channel audio signal but got {shape} channels",
580
+ "process_check": "Processing in checkpoint mode...",
581
+ "stft_2": "STFT applied to mix. Spectrum shape: {shape}",
582
+ "cache": "Computed padding",
583
+ "shape": "Mix shape after padding: {shape}, Number of parts: {num_chunks}",
584
+ "process_no_check": "Processing in no-checkpoint mode...",
585
+ "n_sample_or_pad": "Number of samples: {n_sample}, Computed padding: {pad}",
586
+ "shape_2": "Mix shape after padding",
587
+ "process_part": "Processed part {mix_waves}: Start {i}, End {ii}",
588
+ "mix_waves_to_tensor": "Converted mix_waves to tensor. Tensor shape: {shape}",
589
+ "mix_match": "Mix mode Match; applying compensation factor.",
590
+ "tar_waves": "tar_waves. Shape",
591
+ "normalization_2": "Normalizing result by dividing it by divisor.",
592
+ "mix_wave": "Processing mix_wave batch",
593
+ "mix_or_batch": "Mix parts into batches. Number of batches",
594
+ "demix_is_match_mix": "Starting demix process with is_match_mix,",
595
+ "mix_shape": "Root mix parts stored. Shape",
596
+ "chunk_size_or_overlap": "Chunk size for compatible mixing: {chunk_size}, Overlap: {overlap}",
597
+ "chunk_size_or_overlap_standard": "Standard chunk size: {chunk_size}, Overlap: {overlap}",
598
+ "calc_size": "Generated size calculated",
599
+ "window": "Window applied to this segment.",
600
+ "process_part_2": "Processing segment {total}/{total_chunks}: Start {start}, End {end}",
601
+ "all_process_part": "Total segments to process",
602
+ "step_or_overlap": "Step size to process parts: {step} with overlap set to {overlap}.",
603
+ "mix_cache": "Mix prepared with padding. Mix shape",
604
+ "dims": "Cannot use sin/cos position encoding with odd dimensions (dim={dims})",
605
+ "activation": "activation must be relu/gelu, not {activation}",
606
+ "length_or_training_length": "Provided length {length} exceeds training duration {training_length}",
607
+ "type_not_valid": "Invalid type for",
608
+ "del_parameter": "Removing non-existent parameter ",
609
+ "info": "Common parameters: Model name = {model_name}, Model path = {model_path}",
610
+ "info_2": "Common parameters: Output path = {output_dir}, Output format = {output_format}",
611
+ "info_3": "Common parameters: Normalization threshold = {normalization_threshold}",
612
+ "info_4": "Common parameters: Denoising enabled = {enable_denoise}, Single stem output = {output_single_stem}",
613
+ "info_5": "Common parameters: Inversion using specs = {invert_using_spec}, Sample rate = {sample_rate}",
614
+ "info_6": "Common parameters: Primary root name = {primary_stem_name}, Secondary root name = {secondary_stem_name}",
615
+ "info_7": "Common parameters: Karaoke mode = {is_karaoke}, BV model = {is_bv_model}, BV model rebalancing = {bv_model_rebalance}",
616
+ "success_process": "Completed processing root {stem_name} and writing audio...",
617
+ "load_audio": "Loading audio from file",
618
+ "load_audio_success": "Audio loaded. Sample rate: {sr}, Audio shape: {shape}",
619
+ "convert_mix": "Converting provided mix array.",
620
+ "convert_shape": "Converted mix shape: {shape}",
621
+ "audio_not_valid": "Audio file {audio_path} is empty or invalid",
622
+ "audio_valid": "Audio file is valid and contains data.",
623
+ "mix_single": "Mix is mono. Converting to stereo.",
624
+ "convert_mix_audio": "Converted to stereo mix.",
625
+ "mix_success_2": "Mix preparation completed.",
626
+ "duration": "Audio duration is {duration_hours} hours ({duration_seconds} seconds).",
627
+ "write": "Using {name} to write.",
628
+ "write_audio": "Writing {name} with root path:",
629
+ "original_not_valid": "Warning: Original source array is nearly silent or empty.",
630
+ "shape_audio": "Audio data shape before processing",
631
+ "convert_data": "Data type before conversion",
632
+ "original_source_to_int16": "Converted original_source to int16.",
633
+ "shape_audio_2": "Interleaved audio data shape",
634
+ "create_audiosegment": "Successfully created AudioSegment.",
635
+ "create_audiosegment_error": "Specific error while creating AudioSegment",
636
+ "export_error": "Error exporting audio file",
637
+ "export_success": "Successfully exported audio file to",
638
+ "clean": "Running garbage collection...",
639
+ "clean_cache": "Clearing {name} cache...",
640
+ "del_path": "Deleting path, source, and root of input audio file...",
641
+ "not_success": "Process was not successful: ",
642
+ "resample_error": "Error during resampling",
643
+ "shapes": "Shapes",
644
+ "wav_resolution": "Resolution type",
645
+ "warnings": "Warning: Extremely aggressive values detected",
646
+ "warnings_2": "Warning: NaN or infinite values detected in wave input. Shape",
647
+ "process_file": "Processing file... \n",
648
+ "save_instruments": "Saving reverse track...",
649
+ "assert": "Audio files must have the same shape - Mix: {mixshape}, Inst: {instrumentalshape}",
650
+ "rubberband": "Rubberband CLI cannot be executed. Please ensure Rubberband-CLI is installed.",
651
+ "rate": "Rate must be strictly positive",
652
+ "gdown_error": "Could not retrieve the public link for the file. You may need to change its permissions to 'Anyone with the link' or there may already be excessive access permissions.",
653
+ "to": "To:",
654
+ "gdown_value_error": "A path or ID must be specified",
655
+ "missing_url": "URL is missing",
656
+ "mac_not_match": "MAC does not match",
657
+ "file_not_access": "File is not accessible",
658
+ "int_resp==-3": "Request failed, retrying",
659
+ "search_separate": "Search for separate files...",
660
+ "found_choice": "Found {choice}",
661
+ "separator==0": "No separate files found!",
662
+ "select_separate": "Select separate files",
663
+ "start_app": "Starting interface...",
664
+ "provide_audio": "Enter the path to the audio file",
665
+ "set_torch_mps": "Set Torch device to MPS",
666
+ "googletts": "Convert text using Google",
667
+ "pitch_info_2": "Pitch adjustment for text-to-speech converter",
668
+ "waveform": "Waveform must have the shape (# frames, # channels)",
669
+ "freq_mask_smooth_hz": "freq_mask_smooth_hz must be at least {hz}Hz",
670
+ "time_mask_smooth_ms": "time_mask_smooth_ms must be at least {ms}ms",
671
+ "x": "x must be greater",
672
+ "xn": "xn must be greater",
673
+ "not_found_pid": "No processes found!",
674
+ "end_pid": "Process terminated!",
675
+ "not_found_separate_model": "No separation model files found!",
676
+ "not_found_pretrained": "No pretrained model files found!",
677
+ "not_found_log": "No log files found!",
678
+ "not_found_predictors": "No predictor model files found!",
679
+ "not_found_embedders": "No embedder model files found!",
680
+ "provide_folder": "Please provide a valid folder!",
681
+ "empty_folder": "The data folder is empty!",
682
+ "vocoder": "Vocoder",
683
+ "vocoder_info": "A vocoder analyzes and synthesizes human speech signals for voice transformation.\n\nDefault: This option is HiFi-GAN-NSF, compatible with all RVCs (except 44.1k option)\n\nMRF-HiFi-GAN: Higher fidelity.\n\nRefineGAN: Superior sound quality.",
684
+ "code_error": "Error: Received status code",
685
+ "json_error": "Error: Unable to parse response.",
686
+ "requests_error": "Request failed: {e}",
687
+ "memory_efficient_training": "Using memory-efficient training",
688
+ "not_use_pretrain_error_download": "Will not use pretrained models due to missing files",
689
+ "provide_file_settings": "Please provide a preset settings file!",
690
+ "load_presets": "Loaded preset file {presets}",
691
+ "provide_filename_settings": "Please provide a preset file name!",
692
+ "choose1": "Please select one to export!",
693
+ "export_settings": "Exported preset file {name}",
694
+ "use_presets": "Using preset file",
695
+ "file_preset": "Preset file",
696
+ "load_file": "Load file",
697
+ "export_file": "Export preset file",
698
+ "save_clean": "Save cleanup",
699
+ "save_autotune": "Save autotune",
700
+ "save_pitch": "Save pitch",
701
+ "save_index_2": "Save index impact",
702
+ "save_resample": "Save resampling",
703
+ "save_filter": "Save median filter",
704
+ "save_envelope": "Save sound envelope",
705
+ "save_protect": "Save sound protection",
706
+ "save_split": "Save sound split",
707
+ "filename_to_save": "File name to save",
708
+ "upload_presets": "Upload preset file",
709
+ "stop": "Stop process",
710
+ "stop_separate": "Stop Music Separation",
711
+ "stop_convert": "Stop Conversion",
712
+ "stop_create_dataset": "Stop Dataset Creation",
713
+ "stop_training": "Stop Training",
714
+ "stop_extract": "Stop Data Processing",
715
+ "stop_preprocess": "Stop Data Extraction",
716
+ "not_found_presets": "No preset files found in the folder!",
717
+ "port": "Port {port} is unavailable! Lowering port by one...",
718
+ "empty_json": "{file}: Corrupted or empty",
719
+ "thank": "Thank you for reporting the issue, and apologies for any inconvenience caused!",
720
+ "error_read_log": "An error occurred while reading log files!",
721
+ "error_send": "An error occurred while sending the report! Please contact me on Discord: pham_huynh_anh!",
722
+ "report_bugs": "Report Bugs",
723
+ "agree_log": "Agree to provide all log files",
724
+ "error_info": "Error description",
725
+ "error_info_2": "Provide more information about the error",
726
+ "report_bug_info": "Report bugs encountered during program usage",
727
+ "sr_info": "NOTE: SOME FORMATS DO NOT SUPPORT RATES ABOVE 48000",
728
+ "report_info": "If possible, agree to provide log files to help with debugging.\n\nIf log files are not provided, please describe the error in detail, including when and where it occurred.\n\nIf this reporting system also fails, you can reach out via [ISSUE]({github}) or Discord: `pham_huynh_anh`",
729
+ "default_setting": "An error occurred during separation, resetting all settings to default...",
730
+ "dataset_folder1": "Please enter the data folder name",
731
+ "checkpointing_err": "Pretrained model parameters such as sample rate or architecture do not match the selected model.",
732
+ "start_onnx_export": "Start converting model to onnx...",
733
+ "convert_model": "Convert Model",
734
+ "pytorch2onnx": "Converting PYTORCH Model to ONNX Model",
735
+ "pytorch2onnx_markdown": "Convert RVC model from pytorch to onnx to optimize audio conversion",
736
+ "error_readfile": "An error occurred while reading the file!",
737
+ "read_sf": "Read audio file using soundfile...",
738
+ "read_librosa": "Read audio files using librosa as soundfile is not supported...",
739
+ "f0_onnx_mode": "F0 ONNX Mode",
740
+ "f0_onnx_mode_info": "Extracting pitch using the ONNX model can help improve speed",
741
+ "formantshift": "Pitch and Formant Shift",
742
+ "formant_qfrency": "Frequency for Formant Shift",
743
+ "formant_timbre": "Timbre for Formant Transformation",
744
+ "time_frames": "Time (Frames)",
745
+ "Frequency": "Frequency (Hz)",
746
+ "f0_extractor_tab": "F0 Extraction",
747
+ "f0_extractor_markdown": "## Pitch Extraction",
748
+ "f0_extractor_markdown_2": "F0 pitch extraction is intended for use in audio conversion inference",
749
+ "start_extract": "Starting extraction process...",
750
+ "extract_done": "Extraction process completed!",
751
+ "f0_file": "Use pre-extracted F0 file",
752
+ "upload_f0": "Upload F0 file",
753
+ "f0_file_2": "F0 File",
754
+ "clean_f0_file": "Clean up F0 file",
755
+ "embed_mode": "Embedders Mode",
756
+ "embed_mode_info": "Extracting embeddings using different models",
757
+ "close": "The application is shutting down...",
758
+ "start_whisper": "Starting voice recognition with Whisper...",
759
+ "whisper_done": "Voice recognition complete!",
760
+ "process_audio": "Preprocessing audio...",
761
+ "process_done_start_convert": "Audio processing complete! proceeding with audio conversion...",
762
+ "convert_with_whisper": "Convert Audio With Whisper",
763
+ "convert_with_whisper_info": "Convert audio using a trained speech model with a Whisper model for speech recognition\n\nWhisper will recognize different voices then cut the individual voices and use the RVC model to convert those segments\n\nThe Whisper model may not work properly which may cause strange output",
764
+ "num_spk": "Number of voices",
765
+ "num_spk_info": "Number of voices in the audio",
766
+ "model_size": "Whisper model size",
767
+ "model_size_info": "Whisper model size\n\nLarge models can produce strange outputs",
768
+ "editing": "Editing",
769
+ "inverting": "Inverting",
770
+ "steps": "Steps",
771
+ "source_prompt": "Source Prompt",
772
+ "target_prompt": "Prompt",
773
+ "cfg_scale_src": "Source Prompt",
774
+ "cfg_scale_tar": "Target Prompt",
775
+ "t_start": "Edit Level",
776
+ "save_compute": "Effective Edit",
777
+ "error_edit": "An error occurred while editing background music {e}",
778
+ "start_edit": "Starting editing background music {input_path}...",
779
+ "edit_success": "Finished editing the soundtrack after {time} with output {output_path}",
780
+ "audio_editing": "Editing the Soundtrack",
781
+ "audio_editing_info": "## Editing Soundtrack Using Audioldm2 Model",
782
+ "audio_editing_markdown": "Editing the soundtrack using Audioldm2 model can help change the type of instrument inside the soundtrack",
783
+ "target_prompt_info": "Describe your desired edited output",
784
+ "cfg_scale_src_info": "The extent to which the source influences the output. Higher values retain more characteristics from the source. Lower values give the system more freedom to transform.",
785
+ "cfg_scale_tar_info": "The extent to which the target influences the final result. Higher values force the result to follow the characteristics of the target. Lower values balance the source and target.",
786
+ "audioldm2_model": "Audioldm2 model",
787
+ "audioldm2_model_info": "Choose the Audioldm2 model of your choice\n\nLoading the weights and inference will also take a long time depending on your GPU",
788
+ "source_prompt_info": "Optional: Describe the original audio input",
789
+ "t_start_info": "Lower correction levels will be closer to the original sound, higher will be stronger correction.",
790
+ "steps_label": "Number diffusion steps",
791
+ "steps_info": "Higher values (e.g. 200) produce higher quality output.",
792
+ "title": "Simple high-quality and high-performance voice and instrument conversion and training tool for Vietnamese people",
793
+ "fp16_not_support": "CPU does not support fp16 well, convert fp16 -> fp32",
794
+ "precision": "Precision",
795
+ "precision_info": "Precision of inference and model training\n\nNote: CPU Does not support fp16\n\nFor RefineGAN and MRF HIFIGAN when converting use fp32 as fp16 can cause them to give weird output",
796
+ "update_precision": "Update Precision",
797
+ "start_update_precision": "Start updating precision",
798
+ "deterministic": "Deterministic algorithm",
799
+ "deterministic_info": "When enabled, highly deterministic algorithms are used, ensuring that each run of the same input data will yield the same results.\n\nWhen disabled, more optimal algorithms may be selected but may not be fully deterministic, resulting in different training results between runs.",
800
+ "benchmark": "Benchmark algorithm",
801
+ "benchmark_info": "When enabled, it will test and select the most optimized algorithm for the specific hardware and size. This can help speed up training.\n\nWhen disabled, it will not perform this algorithm optimization, which can reduce speed but ensures that each run uses the same algorithm, which is useful if you want to reproduce exactly.",
802
+ "font": "Font",
803
+ "font_info": "Interface font\n\nVisit [Google Font](https://fonts.google.com) to choose your favorite font.",
804
+ "change_font": "Change Font",
805
+ "f0_unlock": "Unlock all",
806
+ "f0_unlock_info": "Unlock all pitch extraction methods",
807
+ "stop_audioldm2": "Stop Audioldm2",
808
+ "srt": "SRT file is empty or corrupt!"
809
+ }
assets/languages/vi-VN.json ADDED
@@ -0,0 +1,809 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "set_lang": "Đã đặt ngôn ngữ hiển thị là {lang}",
3
+ "no_support_gpu": "Thật không may, không có GPU tương thích để hỗ trợ việc đào tạo của bạn.",
4
+ "text": "văn bản",
5
+ "upload_success": "Đã tải lên tệp {name} hoàn tất.",
6
+ "download_url": "Tải từ đường dẫn liên kết",
7
+ "download_from_csv": "Tải từ kho mô hình csv",
8
+ "search_models": "Tìm kiếm mô hình",
9
+ "upload": "Tải lên",
10
+ "option_not_valid": "Tùy chọn không hợp lệ!",
11
+ "list_model": "Danh sách mô hình",
12
+ "success": "Hoàn tất!",
13
+ "index": "chỉ mục",
14
+ "model": "mô hình",
15
+ "zip": "nén",
16
+ "search": "tìm kiếm",
17
+ "provide_file": "Vui lòng cung cấp tệp {filename} hợp lệ!",
18
+ "start": "Bắt đầu {start}...",
19
+ "not_found": "Không tìm thấy {name}",
20
+ "found": "Đã tìm thấy {results} kết quả!",
21
+ "download_music": "tải nhạc",
22
+ "download": "tải xuống",
23
+ "provide_url": "Vui lòng cung cấp đường dẫn liên kết.",
24
+ "provide_name_is_save": "Vui lòng cung cấp tên mô hình để lưu.",
25
+ "not_support_url": "Liên kết mô hình của bạn không được hỗ trợ.",
26
+ "error_occurred": "Đã xảy ra lỗi: {e}",
27
+ "not_model": "Tệp bạn vừa tải lên không phải là tệp mô hình!",
28
+ "unable_analyze_model": "Không phân tích được mô hình!",
29
+ "download_pretrain": "Tải xuống huấn luyện trước...",
30
+ "provide_pretrain": "Vui lòng cung cấp đường dẫn mô hình huấn luyện trước {dg}.",
31
+ "sr_not_same": "Tốc độ lấy mẫu của hai mô hình không giống nhau",
32
+ "architectures_not_same": "Không thể hợp nhất các mô hình. Các kiến trúc mô hình không giống nhau.",
33
+ "fushion_model": "dung hợp mô hình",
34
+ "model_fushion_info": "Mô hình được {name} được dung hợp từ {pth_1} và {pth_2} với ratio {ratio}.",
35
+ "not_found_create_time": "Không tìm thấy thời gian tạo.",
36
+ "format_not_valid": "Định dạng không hợp lệ.",
37
+ "read_info": "Các mô hình được huấn luyện trên các ứng dụng khác nhau có thể đem lại các thông tin khác nhau hoặc không thể đọc!",
38
+ "epoch": "kỷ nguyên.",
39
+ "step": "bước",
40
+ "sr": "Tốc độ lấy mẫu",
41
+ "f0": "huấn luyện cao độ",
42
+ "version": "phiên bản.",
43
+ "not_f0": "Không được huấn luyện cao độ",
44
+ "trained_f0": "Được huấn luyện cao độ",
45
+ "model_info": "Tên mô hình: {model_name}\n\n Người tạo mô hình: {model_author}\n\nKỷ nguyên: {epochs}\n\nSố bước: {steps}\n\nPhiên bản của mô hình: {version}\n\nTốc độ lấy mẫu: {sr}\n\nHuấn luyện cao độ: {pitch_guidance}\n\nHash (ID): {model_hash}\n\nThời gian tạo: {creation_date_str}\n\nBộ mã hóa: {vocoder}\n",
46
+ "input_not_valid": "Vui lòng nhập đầu vào hợp lệ!",
47
+ "output_not_valid": "Vui lòng nhập đầu ra hợp lệ!",
48
+ "apply_effect": "áp dụng hiệu ứng",
49
+ "enter_the_text": "Vui lòng nhập văn bản để chuyển!",
50
+ "choose_voice": "Vui lòng chọn giọng!",
51
+ "convert": "Chuyển đổi {name}...",
52
+ "separator_music": "tách nhạc",
53
+ "notfound": "Không tìm thấy",
54
+ "turn_on_use_audio": "Vui lòng bật sử dụng âm thanh vừa tách để sử dụng",
55
+ "turn_off_convert_backup": "Tắt chuyển đổi giọng bè để có thể sử dụng giọng gốc",
56
+ "turn_off_merge_backup": "Tắt không kết hợp giọng bè để có thể sử dụng giọng gốc",
57
+ "not_found_original_vocal": "Không tìm thấy giọng gốc!",
58
+ "convert_vocal": "Đang chuyển đổi giọng nói...",
59
+ "convert_success": "Đã hoàn tất chuyển đổi giọng nói!",
60
+ "convert_backup": "Đang chuyển đổi giọng bè...",
61
+ "convert_backup_success": "Đã Hoàn tất chuyển đổi giọng bè!",
62
+ "merge_backup": "Kết hợp giọng với giọng bè...",
63
+ "merge_success": "Kết hợp Hoàn tất.",
64
+ "is_folder": "Đầu vào là một thư mục: Chuyển đổi tất cả tệp âm thanh trong thư mục...",
65
+ "not_found_in_folder": "Không tìm thấy tệp âm thanh trong thư mục!",
66
+ "batch_convert": "Đang chuyển đổi hàng loạt...",
67
+ "batch_convert_success": "Chuyển đổi hàng loạt hoàn tất!",
68
+ "create": "tạo",
69
+ "provide_name": "Vui lòng cung cấp tên mô hình.",
70
+ "not_found_data": "Không tìm thấy dữ liệu",
71
+ "not_found_data_preprocess": "Không tìm thấy dữ liệu được xử lý, vui lòng xử lý lại âm thanh",
72
+ "not_found_data_extract": "Không tìm thấy dữ liệu được trích xuất, vui lòng trích xuất lại âm thanh",
73
+ "provide_pretrained": "Vui lòng nhập huấn luyện {dg}",
74
+ "download_pretrained": "Tải xuống huấn luyện trước {dg}{rvc_version} gốc",
75
+ "not_found_pretrain": "Không tìm thấy huấn luyện trước {dg}",
76
+ "not_use_pretrain": "Sẽ không có huấn luyện trước được sử dụng",
77
+ "training": "huấn luyện",
78
+ "rick_roll": "Bấm vào đây nếu bạn muốn bị Rick Roll:) ---> [RickRoll]({rickroll})",
79
+ "terms_of_use": "**Vui lòng không sử dụng Dự án với bất kỳ mục đích nào vi phạm đạo đức, pháp luật, hoặc gây tổn hại đến cá nhân, tổ chức...**",
80
+ "exemption": "**Trong trường hợp người sử dụng không tuân thủ các điều khoản hoặc vi phạm, tôi sẽ không chịu trách nhiệm về bất kỳ khiếu nại, thiệt hại, hay trách nhiệm pháp lý nào, dù là trong hợp đồng, do sơ suất, hay các lý do khác, phát sinh từ, ngoài, hoặc liên quan đến phần mềm, việc sử dụng phần mềm hoặc các giao dịch khác liên quan đến phần mềm.**",
81
+ "separator_tab": "Tách Nhạc",
82
+ "4_part": "Một hệ thống tách nhạc đơn giản có thể tách được 4 phần: Nhạc, giọng, giọng chính, giọng bè",
83
+ "clear_audio": "Làm sạch âm thanh",
84
+ "separator_backing": "Tách giọng bè",
85
+ "denoise_mdx": "Khữ tách MDX",
86
+ "use_mdx": "Sử dụng MDX",
87
+ "dereveb_audio": "Tách vang",
88
+ "dereveb_backing": "Tách vang bè",
89
+ "separator_model": "Mô hình tách nhạc",
90
+ "separator_backing_model": "Mô hình tách bè",
91
+ "shift": "Số lượng dự đoán",
92
+ "shift_info": "Càng cao chất lượng càng tốt nhưng lâu nhưng tốn tài nguyên",
93
+ "segments_size": "Kích Thước Phân Đoạn",
94
+ "segments_size_info": "Càng cao chất lượng càng tốt nhưng tốn tài nguyên",
95
+ "batch_size": "Kích thước lô",
96
+ "batch_size_info": "Số lượng mẫu xử lý đồng thời trong một lần huấn luyện. Cao có thể gây tràn bộ nhớ",
97
+ "mdx_batch_size_info": "Số lượng mẫu được xử lý cùng một lúc. Việc chia thành các lô giúp tối ưu hóa quá trình tính toán. Lô quá lớn có thể làm tràn bộ nhớ, khi lô quá nhỏ sẽ làm giảm hiệu quả dùng tài nguyên",
98
+ "overlap": "Chồng chéo",
99
+ "overlap_info": "Số lượng chồng chéo giữa các cửa sổ dự đoán",
100
+ "export_format": "Định dạng âm thanh",
101
+ "export_info": "Định dạng âm thanh khi xuất tệp âm thanh ra",
102
+ "output_separator": "Âm thanh đã được tách",
103
+ "hop_length_info": "Khoảng thời gian chuyển cửa sổ phân tích khi thực hiện phép biến đổi. Giá trị nhỏ độ chi tiết cao nhưng cần tính toán nhiều hơn",
104
+ "drop_audio": "Thả âm thanh vào đây",
105
+ "drop_text": "Thả tệp văn bản vào đây",
106
+ "use_url": "Sử dụng đường dẫn youtube",
107
+ "url_audio": "Đường dẫn liên kết đến âm thanh",
108
+ "downloads": "Tải Xuống",
109
+ "clean_strength": "Mức độ làm sạch âm thanh",
110
+ "clean_strength_info": "Mức độ của bộ làm sạch âm thanh để lọc giọng hát khi xuất",
111
+ "input_output": "Đầu vào, đầu ra âm thanh",
112
+ "audio_path": "Đường dẫn đầu vào âm thanh",
113
+ "refesh": "Tải lại",
114
+ "output_folder": "Đường dẫn thư mục đầu ra âm thanh",
115
+ "output_folder_info": "Nhập đường dẫn thư mục âm thanh sẽ xuất ra ở đó",
116
+ "input_audio": "Đầu vào âm thanh",
117
+ "instruments": "Nhạc nền",
118
+ "original_vocal": "Giọng gốc",
119
+ "main_vocal": "Giọng chính",
120
+ "backing_vocal": "Giọng bè",
121
+ "convert_audio": "Chuyển Đổi Âm Thanh",
122
+ "convert_info": "Chuyển đổi âm thanh bằng mô hình giọng nói đã được huấn luyện",
123
+ "autotune": "Tự động điều chỉnh",
124
+ "use_audio": "Sử dụng âm thanh vừa tách",
125
+ "convert_original": "Chuyển đổi giọng gốc",
126
+ "convert_backing": "Chuyển đổi giọng bè",
127
+ "not_merge_backing": "Không kết hợp giọng bè",
128
+ "merge_instruments": "Kết hợp nhạc nền",
129
+ "pitch": "Cao độ",
130
+ "pitch_info": "Khuyến cáo: chỉnh lên 12 để chuyển giọng nam thành nữ và ngược lại",
131
+ "model_accordion": "Mô hình và chỉ mục",
132
+ "model_name": "Tệp mô hình",
133
+ "index_path": "Tệp chỉ mục",
134
+ "index_strength": "Ảnh hưởng của chỉ mục",
135
+ "index_strength_info": "Càng cao ảnh hưởng càng lớn. Tuy nhiên, việc chọn giá trị thấp hơn có thể giảm hiện tượng giả trong âm thanh",
136
+ "output_path": "Đường dẫn đầu ra âm thanh",
137
+ "output_path_info": "Nhập đường dẫn đầu ra(cứ để định dạng .wav khi chuyển đổi nó tự sửa)",
138
+ "setting": "Cài đặt chung",
139
+ "f0_method": "Phương pháp trích xuất",
140
+ "f0_method_info": "Phương pháp đ��� trích xuất dữ liệu",
141
+ "f0_method_hybrid": "Phương pháp trích xuất HYBRID",
142
+ "f0_method_hybrid_info": "Sự kết hợp của hai hoặc nhiều loại trích xuất khác nhau",
143
+ "hubert_model": "Mô hình nhúng",
144
+ "hubert_info": "Mô hình được huấn luyện trước để giúp nhúng",
145
+ "modelname": "Tên của mô hình",
146
+ "modelname_info": "Nếu bạn có mô hình riêng chỉ cần tải và nhập tên của mô hình vào đây",
147
+ "split_audio": "Cắt âm thanh",
148
+ "autotune_rate": "Mức độ điều chỉnh",
149
+ "autotune_rate_info": "Mức độ điều chỉnh tự động",
150
+ "resample": "Lấy mẫu lại",
151
+ "resample_info": "Lấy mẫu lại sau xử lý đến tốc độ lấy mẫu cuối cùng, 0 có nghĩa là không lấy mẫu lại, LƯU Ý: MỘT SỐ ĐỊNH DẠNG KHÔNG HỖ TRỢ TỐC ĐỘ TRÊN 48000",
152
+ "filter_radius": "Lọc trung vị",
153
+ "filter_radius_info": "Nếu giá trị lớn hơn ba sẽ áp dụng tính năng lọc trung vị. Giá trị đại diện cho bán kính bộ lọc và có thể làm giảm hơi thở hoặc tắt thở.",
154
+ "volume_envelope": "Đường bao âm thanh",
155
+ "volume_envelope_info": "Sử dụng đường bao âm lượng của đầu vào để thay thế hoặc trộn với đường bao âm lượng của đầu ra. Càng gần 1 thì đường bao đầu ra càng được sử dụng nhiều",
156
+ "protect": "Bảo vệ phụ âm",
157
+ "protect_info": "Bảo vệ các phụ âm riêng biệt và âm thanh thở ngăn chặn việc rách điện âm và các hiện tượng giả khác. Việc chỉnh tối đa sẽ bảo vệ toàn diện. Việc giảm giá trị này có thể giảm độ bảo vệ, đồng thời có khả năng giảm thiểu hiệu ứng lập chỉ mục",
158
+ "output_convert": "Âm thanh đã được chuyển đổi",
159
+ "main_convert": "Chuyển đổi giọng chính",
160
+ "main_or_backing": "Giọng chính + Giọng bè",
161
+ "voice_or_instruments": "Giọng + Nhạc nền",
162
+ "convert_text": "Chuyển Đổi Văn Bản",
163
+ "convert_text_markdown": "## Chuyển Đổi Văn Bản Thành Giọng Nói",
164
+ "convert_text_markdown_2": "Chuyển văn bản thành giọng nói và đọc lại bằng mô hình giọng nói được huấn luyện",
165
+ "input_txt": "Nhập dữ liệu từ tệp văn bản txt",
166
+ "text_to_speech": "Văn bản cần đọc",
167
+ "voice_speed": "Tốc độ đọc",
168
+ "voice_speed_info": "Tốc độ đọc của giọng nói",
169
+ "tts_1": "1. Chuyển Đổi Văn Bản",
170
+ "tts_2": "2. Chuyển Đổi Giọng Nói",
171
+ "voice": "Giọng nói của các nước",
172
+ "output_tts": "Đường dẫn đầu ra giọng nói",
173
+ "output_tts_convert": "Đường dẫn đầu ra giọng chuyển đổi",
174
+ "tts_output": "Nhập đường dẫn đầu ra",
175
+ "output_tts_markdown": "Âm thanh chưa được chuyển đổi và âm thanh đã được chuyển đổi",
176
+ "output_text_to_speech": "Giọng được tạo bởi chuyển đổi văn bản thành giọng nói",
177
+ "output_file_tts_convert": "Giọng được chuyển đổi bởi mô hình",
178
+ "output_audio": "Đầu ra âm thanh",
179
+ "provide_output": "Nhập đường dẫn đầu ra",
180
+ "audio_effects": "Hiệu Ứng Âm Thanh",
181
+ "apply_audio_effects": "## Áp Dụng Thêm Hiệu Ứng Cho Âm Thanh",
182
+ "audio_effects_edit": "Chỉnh sửa thêm hiệu ứng cho âm thanh",
183
+ "reverb": "Hiệu ứng vọng âm",
184
+ "chorus": "Hiệu ứng hòa âm",
185
+ "delay": "Hiệu ứng độ trễ",
186
+ "more_option": "Tùy chọn thêm",
187
+ "phaser": "Hiệu ứng xoay pha",
188
+ "compressor": "Hiệu ứng nén",
189
+ "apply": "Áp dụng",
190
+ "reverb_freeze": "Chế độ đóng băng",
191
+ "reverb_freeze_info": "Tạo hiệu ứng vang liên tục khi bật chế độ này",
192
+ "room_size": "Kích thước phòng",
193
+ "room_size_info": "Điều chỉnh không gian của phòng để tạo độ vang",
194
+ "damping": "Giảm âm",
195
+ "damping_info": "Điều chỉnh độ hút âm, kiểm soát mức độ vang",
196
+ "wet_level": "Mức độ tín hiệu vang",
197
+ "wet_level_info": "Điều chỉnh mức độ của tín hiệu có hiệu ứng vọng âm",
198
+ "dry_level": "Mức độ tín hiệu gốc",
199
+ "dry_level_info": "Điều chỉnh mức độ của tín hiệu không có hiệu ứng",
200
+ "width": "Chiều rộng âm thanh",
201
+ "width_info": "Điều chỉnh độ rộng của không gian âm thanh",
202
+ "chorus_depth": "Giảm âm",
203
+ "chorus_depth_info": "Điều chỉnh cường độ hòa âm, tạo ra cảm giác rộng cho âm thanh",
204
+ "chorus_rate_hz": "Tần số",
205
+ "chorus_rate_hz_info": "Điều chỉnh tốc độ dao động của hòa âm",
206
+ "chorus_mix": "Trộn tín hiệu",
207
+ "chorus_mix_info": "Điều chỉnh mức độ trộn giữa âm gốc và âm có hiệu ứng",
208
+ "chorus_centre_delay_ms": "Đỗ trễ trung tâm (mili giây)",
209
+ "chorus_centre_delay_ms_info": "Khoảng thời gian trễ giữa các kênh stereo để tạo hiệu ứng hòa âm",
210
+ "chorus_feedback": "Phản hồi",
211
+ "chorus_feedback_info": "Điều chỉnh lượng tín hiệu hiệu ứng được quay lại vào tín hiệu gốc",
212
+ "delay_seconds": "Thời gian trễ",
213
+ "delay_seconds_info": "Điều chỉnh khoảng thời gian trễ giữa âm gốc và âm có hiệu ứng",
214
+ "delay_feedback": "Phản hồi độ trễ",
215
+ "delay_feedback_info": "Điều chỉnh lượng tín hiệu được quay lại, tạo hiệu ứng lặp lại",
216
+ "delay_mix": "Trộn tín hiệu độ trễ",
217
+ "delay_mix_info": "Điều chỉnh mức độ trộn giữa âm gốc và âm trễ",
218
+ "fade": "Hiệu ứng mờ dần",
219
+ "bass_or_treble": "Âm trầm và âm cao",
220
+ "limiter": "Giới hạn ngưỡng",
221
+ "distortion": "Hiệu ứng nhiễu âm",
222
+ "gain": "Cường độ âm",
223
+ "bitcrush": "Hiệu ứng giảm bits",
224
+ "clipping": "Hiệu ứng méo âm",
225
+ "fade_in": "Hiệu ứng mờ dần vào (mili giây)",
226
+ "fade_in_info": "Thời gian mà âm thanh sẽ tăng dần từ mức 0 đến mức bình thường",
227
+ "fade_out": "Hiệu ứng mờ dần ra (mili giây)",
228
+ "fade_out_info": "thời gian mà âm thanh sẽ giảm dần từ bình thường xuống mức 0",
229
+ "bass_boost": "Độ khuếch đại âm trầm (db)",
230
+ "bass_boost_info": "mức độ tăng cường âm trầm trong đoạn âm thanh",
231
+ "bass_frequency": "Tần số cắt của bộ lọc thông thấp (Hz)",
232
+ "bass_frequency_info": "tần số bị giảm. Tần số thấp sẽ làm âm trầm rõ hơn",
233
+ "treble_boost": "Độ khuếch đại âm cao (db)",
234
+ "treble_boost_info": "mức độ tăng cường âm cao trong đoạn âm thanh",
235
+ "treble_frequency": "Tần số cắt của bộ lọc thông cao (Hz)",
236
+ "treble_frequency_info": "tần số sẽ lọc bỏ. Tần số càng cao thì giữ lại âm càng cao",
237
+ "limiter_threashold_db": "Ngưỡng giới hạn",
238
+ "limiter_threashold_db_info": "Giới hạn mức độ âm thanh tối đa, ngăn không cho vượt quá ngưỡng",
239
+ "limiter_release_ms": "Thời gian thả",
240
+ "limiter_release_ms_info": "Khoảng thời gian để âm thanh trở lại sau khi bị giới hạn (Mili Giây)",
241
+ "distortion_info": "Điều chỉnh mức độ nhiễu âm, tạo hiệu ứng méo tiếng",
242
+ "gain_info": "Tăng giảm âm lượng của tín hiệu",
243
+ "clipping_threashold_db": "Ngưỡng cắt",
244
+ "clipping_threashold_db_info": "Cắt bớt tín hiệu vượt quá ngưỡng, tạo âm thanh méo",
245
+ "bitcrush_bit_depth": "Độ sâu bit",
246
+ "bitcrush_bit_depth_info": "Giảm chất lượng âm thanh bằng cách giảm số bit, tạo hiệu ứng âm thanh bị méo",
247
+ "phaser_depth": "Độ sâu",
248
+ "phaser_depth_info": "Điều chỉnh độ sâu của hiệu ứng, ảnh hưởng đến cường độ của hiệu ứng xoay pha",
249
+ "phaser_rate_hz": "Tần số",
250
+ "phaser_rate_hz_info": "Điều chỉnh tốc độ của hiệu ứng hiệu ứng xoay pha",
251
+ "phaser_mix": "Trộn tín hiệu",
252
+ "phaser_mix_info": "Điều chỉnh mức độ trộn giữa tín hiệu gốc và tín hiệu đã qua xử lý",
253
+ "phaser_centre_frequency_hz": "Tần số trung tâm",
254
+ "phaser_centre_frequency_hz_info": "Tần số trung tâm của hiệu ứng xoay pha, ảnh hưởng đến tần số bị điều chỉnh",
255
+ "phaser_feedback": "Phản hồi",
256
+ "phaser_feedback_info": "Điều chỉnh lượng phản hồi tín hiệu, tạo cảm giác xoay pha mạnh hoặc nhẹ",
257
+ "compressor_threashold_db": "Ngưỡng nén",
258
+ "compressor_threashold_db_info": "Ngưỡng mức âm thanh sẽ bị nén khi vượt qua ngưỡng này",
259
+ "compressor_ratio": "Tỉ lệ nén",
260
+ "compressor_ratio_info": "Điều chỉnh mức độ nén âm thanh khi vượt qua ngưỡng",
261
+ "compressor_attack_ms": "Thời gian tấn công (mili giây)",
262
+ "compressor_attack_ms_info": "Khoảng thời gian nén bắt đầu tác dụng sau khi âm thanh vượt ngưỡng",
263
+ "compressor_release_ms": "Thời gian thả",
264
+ "compressor_release_ms_info": "Thời gian để âm thanh trở lại trạng thái bình thường sau khi bị nén",
265
+ "create_dataset_url": "Đường dẫn liên kết đến âm thanh(sử dụng dấu , để sử dụng nhiều liên kết)",
266
+ "createdataset": "Tạo dữ liệu",
267
+ "create_dataset_markdown": "## Tạo Dữ Liệu Huấn Luyện Từ Youtube",
268
+ "create_dataset_markdown_2": "Xử lý và tạo tập tin dữ liệu huấn luyện bằng đường dẫn youtube",
269
+ "denoise": "Khử tách mô hình",
270
+ "skip": "Bỏ qua giây",
271
+ "model_ver": "Phiên bản tách giọng",
272
+ "model_ver_info": "Phiên bản của mô hình tách nhạc để tách giọng",
273
+ "create_dataset_info": "Thông tin tạo dữ liệu",
274
+ "output_data": "Đầu ra dữ liệu",
275
+ "output_data_info": "Đầu ra dữ liệu sau khi tạo xong dữ liệu",
276
+ "skip_start": "Bỏ qua phần đầu",
277
+ "skip_start_info": "Bỏ qua số giây đầu của âm thanh, dùng dấu , để sử dụng cho nhiều âm thanh",
278
+ "skip_end": "Bỏ qua phần cuối",
279
+ "skip_end_info": "Bỏ qua số giây cuối của âm thanh, dùng dấu , để sử dụng cho nhiều âm thanh",
280
+ "training_model": "Huấn Luyện Mô Hình",
281
+ "training_markdown": "Huấn luyện và đào tạo mô hình giọng nói bằng một lượng dữ liệu giọng nói",
282
+ "training_model_name": "Tên của mô hình khi huấn luyện(không sử dụng ký tự đặc biệt hay dấu cách)",
283
+ "sample_rate": "Tỉ lệ lấy mẫu",
284
+ "sample_rate_info": "Tỉ lệ lấy mẫu của mô hình",
285
+ "training_version": "Phiên bản mô hình",
286
+ "training_version_info": "Phiên bản mô hình khi huấn luyện",
287
+ "training_pitch": "Huấn luyện cao độ",
288
+ "upload_dataset": "Tải lên dữ liệu huấn luyện",
289
+ "preprocess_effect": "Xử lý hậu kỳ",
290
+ "clear_dataset": "Làm sạch dữ liệu",
291
+ "preprocess_info": "Thông tin phần xử lý trước",
292
+ "preprocess_button": "1. Xử lý dữ liệu",
293
+ "extract_button": "2. Trích xuất dữ liệu",
294
+ "extract_info": "Thông tin phần trích xuất dữ liệu",
295
+ "total_epoch": "Tổng số kỷ nguyên",
296
+ "total_epoch_info": "Tổng số kỷ nguyên huấn luyện đào tạo",
297
+ "save_epoch": "Tần suất lưu",
298
+ "save_epoch_info": "Tần suất lưu mô hình khi huấn luyện, giúp việc huấn luyện lại mô hình",
299
+ "create_index": "Tạo chỉ mục",
300
+ "index_algorithm": "Thuật toán chỉ mục",
301
+ "index_algorithm_info": "Thuật toán tạo chỉ mục",
302
+ "custom_dataset": "Tùy chọn thư mục",
303
+ "custom_dataset_info": "Tùy chọn thư mục dữ liệu huấn luyện",
304
+ "overtraining_detector": "Kiểm tra quá sức",
305
+ "overtraining_detector_info": "Kiểm tra huấn luyện mô hình quá sức",
306
+ "cleanup_training": "Làm sạch huấn luyện",
307
+ "cleanup_training_info": "Bật khi cần huấn luyện lại từ đầu.",
308
+ "cache_in_gpu": "Lưu mô hình vào đệm",
309
+ "cache_in_gpu_info": "Lưu mô hình vào bộ nhớ đệm gpu",
310
+ "dataset_folder": "Thư mục chứa dữ liệu",
311
+ "threshold": "Ngưỡng huấn luyện quá sức",
312
+ "setting_cpu_gpu": "Tùy chọn CPU/GPU",
313
+ "gpu_number": "Số gpu được sử dụng",
314
+ "gpu_number_info": "Số của GPU được sử dụng trong huấn luyện",
315
+ "save_only_latest": "Chỉ lưu mới nhất",
316
+ "save_only_latest_info": "Chỉ lưu mô hình D và G mới nhất",
317
+ "save_every_weights": "Lưu mọi mô hình",
318
+ "save_every_weights_info": "Lưu mọi mô hình sau mỗi lượt kỷ nguyên",
319
+ "gpu_info": "Thông tin của GPU",
320
+ "gpu_info_2": "Thông tin của GPU được sử dụng trong huấn luyện",
321
+ "cpu_core": "Số lõi xử lý có thể sử dụng",
322
+ "cpu_core_info": "Số lõi được sử dụng trong việc huấn luyện",
323
+ "not_use_pretrain_2": "Không dùng huấn luyện",
324
+ "not_use_pretrain_info": "Không dùng huấn luyện trước",
325
+ "custom_pretrain": "Tùy chỉnh huấn luyện",
326
+ "custom_pretrain_info": "Tùy chỉnh huấn luyện trước",
327
+ "pretrain_file": "Tệp mô hình huấn luyện trước {dg}",
328
+ "train_info": "Thông tin phần huấn luyện",
329
+ "export_model": "5. Xuất Mô hình",
330
+ "zip_model": "2. Nén mô hình",
331
+ "output_zip": "Đầu ra tệp khi nén",
332
+ "model_path": "Đường dẫn mô hình",
333
+ "model_ratio": "Tỉ lệ mô hình",
334
+ "model_ratio_info": "Chỉnh hướng về bên nào sẽ làm cho mô hình giống với bên đó",
335
+ "output_model_path": "Đầu ra mô hình",
336
+ "fushion": "Dung Hợp Mô Hình",
337
+ "fushion_markdown": "## Dung Hợp Hai Mô Hình Với Nhau",
338
+ "fushion_markdown_2": "Dung hợp hai mô hình giọng nói lại với nhau để tạo thành một mô hình duy nhất",
339
+ "read_model": "Đọc Thông Tin",
340
+ "read_model_markdown": "## Đọc Thông Tin Của Mô Hình",
341
+ "read_model_markdown_2": "Đọc các thông tin được ghi trong mô hình",
342
+ "drop_model": "Thả mô hình vào đây",
343
+ "readmodel": "Đọc mô hình",
344
+ "model_path_info": "Nhập đường dẫn đến tệp mô hình",
345
+ "modelinfo": "Thông Tin Mô Hình",
346
+ "download_markdown": "## Tải Xuống Mô Hình",
347
+ "download_markdown_2": "Tải xuống mô hình giọng nói, mô hình huấn luyện trước, mô hình nhúng",
348
+ "model_download": "Tải xuống mô hình giọng nói",
349
+ "model_url": "Đường dẫn liên kết đến mô hình",
350
+ "15s": "Vui lòng đợi khoảng 15 giây. Hệ thống sẽ tự khởi động lại!",
351
+ "model_download_select": "Chọn cách tải mô hình",
352
+ "model_warehouse": "Kho mô hình",
353
+ "get_model": "Nhận mô hình",
354
+ "name_to_search": "Tên để tìm kiếm",
355
+ "search_2": "Tìm kiếm",
356
+ "select_download_model": "Chọn mô hình đã được tìm kiếm(Bấm vào để chọn)",
357
+ "download_pretrained_2": "Tải xuống mô hình huấn luyện trước",
358
+ "only_huggingface": "Chỉ hỗ trợ huggingface.co",
359
+ "pretrained_url": "Đường dẫn liên kết đến mô hình huấn luyện trước {dg}",
360
+ "select_pretrain": "Chọn mô hình huấn luyện trước",
361
+ "select_pretrain_info": "Chọn mô hình huấn luyện trước để cài đặt về",
362
+ "pretrain_sr": "Tốc độ lấy mẫu của mô hình",
363
+ "drop_pretrain": "Thả mô hình huấn luyện trước {dg} vào đây",
364
+ "settings": "Tùy Chỉnh",
365
+ "settings_markdown": "## Tùy Chỉnh Thêm",
366
+ "settings_markdown_2": "Tùy chỉnh thêm một số tính năng của dự án",
367
+ "lang": "Ngôn ngữ",
368
+ "lang_restart": "Ngôn ngữ được hiển thị trong dự án(Khi đổi ngôn ngữ hệ thống sẽ tự khởi động lại sau 15 giây để cập nhật)",
369
+ "change_lang": "Đổi Ngôn Ngữ",
370
+ "theme": "Chủ đề",
371
+ "theme_restart": "Loại Chủ đề của giao diện được hiển thị(Khi đổi chủ đề hệ thống sẽ tự khởi động lại sau 15 giây để cập nhật)",
372
+ "theme_button": "Đổi Chủ Đề",
373
+ "change_light_dark": "Đổi Chế Độ Sáng/Tối",
374
+ "tensorboard_url": "Đường dẫn biểu đồ",
375
+ "errors_loading_audio": "Lỗi khi tải âm thanh: {e}",
376
+ "apply_error": "Đã xảy ra lỗi khi áp dụng hiệu ứng: {e}",
377
+ "indexpath": "Đường dẫn chỉ mục",
378
+ "split_total": "Tổng số phần đã cắt",
379
+ "process_audio_error": "Đã xảy ra lỗi khi xử lý âm thanh",
380
+ "merge_error": "Đã xảy ra lỗi khi ghép âm thanh",
381
+ "not_found_convert_file": "Không tìm thấy tệp đã xử lý",
382
+ "convert_batch": "Chuyển đổi hàng loạt...",
383
+ "found_audio": "Tìm thấy {audio_files} tệp âm thanh cho việc chuyển đổi.",
384
+ "not_found_audio": "Không tìm thấy tệp âm thanh!",
385
+ "error_convert": "Đã xảy ra lỗi khi chuyển đổi âm thanh: {e}",
386
+ "convert_batch_success": "Đã chuyển đổi hàng loạt hoàn tất sau {elapsed_time} giây. {output_path}",
387
+ "convert_audio_success": "Tệp {input_path} được chuyển đổi hoàn tất sau {elapsed_time} giây. {output_path}",
388
+ "hybrid_methods": "Tính toán ước lượng cao độ f0 cho các phương pháp {methods}",
389
+ "method_not_valid": "Phương pháp không hợp lệ",
390
+ "read_faiss_index_error": "Đã xảy ra lỗi khi đọc chỉ mục FAISS: {e}",
391
+ "read_model_error": "Thất bại khi tải mô hình: {e}",
392
+ "starting_download": "Bắt đầu tải xuống",
393
+ "version_not_valid": "Phiên bản tách giọng không hợp lệ",
394
+ "skip<audio": "Không thể bỏ qua vì số lượng thời gian bỏ qua thấp hơn số lượng tệp âm thanh",
395
+ "skip>audio": "Không thể bỏ qua vì số lượng thời gian bỏ qua cao hơn số lượng tệp âm thanh",
396
+ "=<0": "Thời gian bỏ qua bé hơn hoặc bằng 0 nên bỏ qua",
397
+ "skip_warning": "Thời lượng bỏ qua ({seconds} giây) vượt quá thời lượng âm thanh ({total_duration} giây). Bỏ qua.",
398
+ "download_success": "Đã tải xuống hoàn tất",
399
+ "create_dataset_error": "Đã xảy ra lỗi khi tạo dữ liệu huấn luyện",
400
+ "create_dataset_success": "Quá trình tạo dữ liệu huấn huyện đã hoàn tất sau: {elapsed_time} giây",
401
+ "skip_start_audio": "Bỏ qua âm thanh đầu hoàn tất: {input_file}",
402
+ "skip_end_audio": "Bỏ qua âm thanh cuối hoàn tất: {input_file}",
403
+ "merge_audio": "Đã ghép các phần chứa âm thanh lại",
404
+ "separator_process": "Đang tách giọng: {input}...",
405
+ "not_found_main_vocal": "Không tìm thấy giọng chính!",
406
+ "not_found_backing_vocal": "Không tìm thấy giọng bè!",
407
+ "not_found_instruments": "Không tìm thấy nhạc nền",
408
+ "merge_instruments_process": "Kết hợp giọng với nhạc nền...",
409
+ "dereverb": "Đang tách âm vang",
410
+ "dereverb_success": "Đã tách âm vang hoàn tất",
411
+ "save_index": "Đã lưu tệp chỉ mục",
412
+ "create_index_error": "Đã xảy ra lỗi khi tạo chỉ mục",
413
+ "sr_not_16000": "Tỉ lệ mẫu phải là 16000",
414
+ "gpu_not_valid": "Chỉ số GPU không hợp lệ. Chuyển sang CPU.",
415
+ "extract_file_error": "Đã xảy ra lỗi khi giải nén tập tin",
416
+ "extract_f0_method": "Bắt đầu trích xuất cao độ với {num_processes} lõi với phương pháp trích xuất {f0_method}...",
417
+ "extract_f0": "Trích Xuất Cao Độ",
418
+ "extract_f0_success": "Quá trình trích xuất cao độ đã hoàn tất vào {elapsed_time} giây.",
419
+ "NaN": "chứa giá trị NaN và sẽ bị bỏ qua.",
420
+ "start_extract_hubert": "Đang bắt đầu nhúng trích xuất...",
421
+ "not_found_audio_file": "Không tìm thấy tập tin âm thanh. Hãy chắc chắn rằng bạn đã cung cấp âm thanh chính xác.",
422
+ "process_error": "Đã xảy ra lỗi khi xử lý",
423
+ "extract_hubert_success": "Quá trình trích xuất nhúng đã hoàn tất trong {elapsed_time} giây.",
424
+ "export_process": "Đường dẫn của mô hình",
425
+ "extract_error": "Đã xảy ra lỗi khi trích xuất dữ liệu",
426
+ "extract_success": "Đã trích xuất hoàn tất mô hình",
427
+ "min_length>=min_interval>=hop_size": "min_length lớn hơn hoặc bằng min_interval lớn hơn hoặc bằng hop_size là bắt buộc",
428
+ "max_sil_kept>=hop_size": "max_sil_kept lớn hơn hoặc bằng hop_size là bắt buộc",
429
+ "start_preprocess": "Đang bắt đầu xử lý dữ liệu với {num_processes} lõi xử lý...",
430
+ "not_integer": "Thư mục ID giọng nói phải là số nguyên, thay vào đó có",
431
+ "preprocess_success": "Quá trình xử lý hoàn tất sau {elapsed_time} giây.",
432
+ "preprocess_model_success": "Đã hoàn tất xử lý trước dữ liệu cho mô hình",
433
+ "turn_on_dereverb": "Điều kiện cần để sử dụng tách vang giọng bè là phải bật tách vang",
434
+ "turn_on_separator_backing": "Điều kiện cần để sử dụng tách vang giọng bè là phải bật tách bè",
435
+ "backing_model_ver": "Phiên bản mô hình của tách bè",
436
+ "clean_audio_success": "Đã làm sạch âm hoàn tất!",
437
+ "separator_error": "Đã xảy ra lỗi khi tách nhạc",
438
+ "separator_success": "Quá trình tách nhạc đã hoàn tất sau: {elapsed_time} giây",
439
+ "separator_process_2": "Đang xử lý tách nhạc",
440
+ "separator_success_2": "Đã tách nhạc hoàn tất!",
441
+ "separator_process_backing": "Đang xử lý tách giọng bè",
442
+ "separator_process_backing_success": "Đã tách giọng bè hoàn tất!",
443
+ "process_original": "Đang xử lý tách âm vang giọng gốc...",
444
+ "process_original_success": "Đã tách âm vang giọng gốc hoàn tất!",
445
+ "process_main": "Đang xử lý tách âm vang giọng chính...",
446
+ "process_main_success": "Đã tách âm vang giọng chính hoàn tất!",
447
+ "process_backing": "Đang xử lý tách âm vang giọng bè...",
448
+ "process_backing_success": "Đã tách âm vang giọng bè hoàn tất!",
449
+ "save_every_epoch": "Lưu mô hình sau: ",
450
+ "total_e": "Tổng số kỷ nguyên huấn luyện: ",
451
+ "dorg": "Huấn luyện trước G: {pretrainG} | Huấn luyện trước D: {pretrainD}",
452
+ "training_f0": "Huấn luyện cao độ",
453
+ "not_gpu": "Không phát hiện thấy GPU, hoàn nguyên về CPU (không khuyến nghị)",
454
+ "not_found_checkpoint": "Không tìm thấy tệp điểm đã lưu: {checkpoint_path}",
455
+ "save_checkpoint": "Đã tải lại điểm đã lưu '{checkpoint_path}' (kỷ nguyên {checkpoint_dict})",
456
+ "save_model": "Đã lưu mô hình '{checkpoint_path}' (kỷ nguyên {iteration})",
457
+ "sr_does_not_match": "{sample_rate} Tỉ lệ mẫu không khớp với mục tiêu {sample_rate2} Tỉ lệ mẫu",
458
+ "spec_error": "Đã xảy ra lỗi khi nhận thông số kỹ thuật từ {spec_filename}: {e}",
459
+ "time_or_speed_training": "thời gian={current_time} | tốc độ huấn luyện={elapsed_time_str}",
460
+ "savemodel": "Đã lưu mô hình '{model_dir}' (kỷ nguyên {epoch} và bước {step})",
461
+ "model_author": "Ghi công mô hình cho {model_author}",
462
+ "unregistered": "Mô hình không được ghi chép",
463
+ "not_author": "Mô hình không được ghi chép",
464
+ "training_author": "Tên chủ mô hình",
465
+ "training_author_info": "Nếu bạn muốn ghi công mô hình hãy nhập tên của bạn vào đây",
466
+ "extract_model_error": "Đã xảy ra lỗi khi trích xuất mô hình",
467
+ "start_training": "Bắt đầu huấn luyện",
468
+ "import_pretrain": "Đã nạp huấn luyện trước ({dg}) '{pretrain}'",
469
+ "not_using_pretrain": "Sẽ không có huấn luyện trước ({dg}) được sử dụng",
470
+ "training_warning": "CẢNH BÁO: Tổn thất tạo ra thấp hơn đã bị vượt quá tổn thất thấp hơn trong kỷ nguyên tiếp theo.",
471
+ "overtraining_find": "Tập luyện quá sức được phát hiện ở kỷ nguyên {epoch} với mất mát g được làm mịn {smoothed_value_gen} và mất mát d được làm mịn {smoothed_value_disc}",
472
+ "best_epoch": "Kỷ nguyên mới tốt nhất {epoch} với mất mát g được làm mịn {smoothed_value_gen} và mất mát d được làm mịn {smoothed_value_disc}",
473
+ "success_training": "Đã đào tạo hoàn tất với {epoch} kỷ nguyên, {global_step} các bước và {loss_gen_all} mất mát gen.",
474
+ "training_info": "Tổn thất gen thấp nhất: {lowest_value_rounded} ở ký nguyên {lowest_value_epoch}, bước {lowest_value_step}",
475
+ "model_training_info": "{model_name} | kỷ nguyên={epoch} | bước={global_step} | {epoch_recorder} | giá trị thấp nhất={lowest_value_rounded} (kỷ nguyên {lowest_value_epoch} và bước {lowest_value_step}) | Số kỷ nguyên còn lại để tập luyện quá sức: g/total: {remaining_epochs_gen} d/total: {remaining_epochs_disc} | làm mịn mất mát gen={smoothed_value_gen} | làm mịn mất mát disc={smoothed_value_disc}",
476
+ "model_training_info_2": "{model_name} | kỷ nguyên={epoch} | bước={global_step} | {epoch_recorder} | giá trị thấp nhất={lowest_value_rounded} (kỷ nguyên {lowest_value_epoch} và bước {lowest_value_step})",
477
+ "model_training_info_3": "{model_name} | kỷ nguyên={epoch} | bước={global_step} | {epoch_recorder}",
478
+ "training_error": "Đã xảy ra lỗi khi huấn luyện mô hình:",
479
+ "separator_info": "Đang khởi tạo với đường dẫn đầu ra: {output_dir}, định dạng đầu ra: {output_format}",
480
+ "output_dir_is_none": "Thư mục đầu ra không được chỉ định. Sử dụng thư mục làm việc hiện tại.",
481
+ ">0or=1": "Ngưỡng chuẩn hóa phải lớn hơn 0 và nhỏ hơn hoặc bằng 1.",
482
+ "output_single": "Đã yêu cầu đầu ra một gốc nên chỉ có một tệp đầu ra ({output_single_stem}) sẽ được ghi",
483
+ "step2": "Bước thứ hai sẽ được đảo ngược bằng cách sử dụng quang phổ thay vì dạng sóng. Điều này có thể cải thiện chất lượng nhưng chậm hơn một chút.",
484
+ "name_ver": "Phiên bản {name}",
485
+ "os": "Hệ điều hành",
486
+ "platform_info": "Hệ thống: {system_info} Tên: {node} Phát hành: {release} Máy: {machine} Vi xử lý: {processor}",
487
+ "none_ffmpeg": "FFmpeg chưa được cài đặt. Vui lòng cài đặt FFmpeg để sử dụng gói này.",
488
+ "install_onnx": "Gói {pu} ONNX Runtime được cài đặt cùng với phiên bản",
489
+ "running_in_cpu": "Không thể cấu hình khả năng tăng tốc phần cứng, chạy ở chế độ CPU",
490
+ "running_in_cuda": "CUDA có sẵn trong Torch, cài đặt thiết bị Torch thành CUDA",
491
+ "onnx_have": "ONNXruntime có sẵn {have}, cho phép tăng tốc",
492
+ "onnx_not_have": "{have} không có sẵn trong ONNXruntime, do đó khả năng tăng tốc sẽ KHÔNG được bật",
493
+ "python_not_install": "Gói Python: {package_name} chưa được cài đặt",
494
+ "hash": "Tính hash của tệp mô hình {model_path}",
495
+ "ioerror": "IOError đang tìm kiếm -10 MB hoặc đọc tệp mô hình để tính toán hàm băm: {e}",
496
+ "cancel_download": "Tệp đã tồn tại tại {output_path}, bỏ qua quá trình tải xuống",
497
+ "download_model": "Đang tải tệp từ {url} xuống {output_path} với thời gian chờ 300 giây",
498
+ "download_error": "Không tải được tệp xuống từ {url}, mã phản hồi: {status_code}",
499
+ "vip_model": "Mô hình: '{model_friendly_name}' là mô hình cao cấp, được Anjok07 dự định chỉ dành cho những người đăng ký trả phí truy cập.",
500
+ "vip_print": "Này bạn, nếu bạn chưa đăng ký, vui lòng cân nhắc việc hỗ trợ cho nhà phát triển của UVR, Anjok07 bằng cách đăng ký tại đây: https://patreon.com/uvr",
501
+ "search_model": "Đang tìm kiếm mô hình {model_filename} trong tập tin các mô hình được hỗ trợ trong nhóm",
502
+ "load_download_json": "Đã tải danh sách tải xuống mô hình",
503
+ "single_model": "Đã xác định được tệp mô hình đơn: {model_friendly_name}",
504
+ "not_found_model": "Không tìm thấy mô hình trong kho lưu trữ UVR, đang cố tải xuống từ kho lưu trữ mô hình phân tách âm thanh...",
505
+ "single_model_path": "Đường dẫn trả về cho tệp mô hình đơn: {model_path}",
506
+ "find_model": "Đã tìm thấy tên tệp đầu vào {model_filename} trong mô hình nhiều tệp: {model_friendly_name}",
507
+ "find_models": "Đã xác định mô hình nhiều tệp: {model_friendly_name}, lặp qua các tệp để tải xuống",
508
+ "find_path": "Đang cố gắng xác định ĐƯỜNG DẪN tải xuống cho cặp cấu hình",
509
+ "not_found_model_warehouse": "Không tìm thấy mô hình trong kho lưu trữ UVR, đang cố tải xuống từ kho lưu trữ mô hình phân tách âm thanh...",
510
+ "yaml_warning": "Tên mô hình bạn đã chỉ định, {model_filename} thực sự là tệp cấu hình mô hình chứ không phải tệp mô hình.",
511
+ "yaml_warning_2": "Chúng tôi đã tìm thấy một mô hình khớp với tệp cấu hình này: {config_key} nên chúng tôi sẽ sử dụng tệp mô hình đó cho lần chạy này.",
512
+ "yaml_warning_3": "Để tránh hành vi gây nhầm lẫn/không nhất quán trong tương lai, thay vào đó hãy chỉ định tên tệp mô hình thực tế.",
513
+ "yaml_debug": "Không tìm thấy tệp cấu hình mô hình YAML trong kho lưu trữ UVR, đang cố tải xuống từ kho lưu trữ mô hình phân tách âm thanh...",
514
+ "download_model_friendly": "Tất cả các tệp đã tải xuống cho mô hình {model_friendly_name}, trả về đường dẫn ban đầu {model_path}",
515
+ "not_found_model_2": "Không tìm thấy tệp mô hình {model_filename} trong các tệp mô hình được hỗ trợ",
516
+ "load_yaml": "Đang tải dữ liệu mô hình từ YAML tại đường dẫn {model_data_yaml_filepath}",
517
+ "load_yaml_2": "Dữ liệu mô hình được tải từ tệp YAML: {model_data}",
518
+ "hash_md5": "Tính hash MD5 cho tệp mô hình để xác định các tham số mô hình từ dữ liệu UVR...",
519
+ "model_hash": "Mô hình {model_path} có hash {model_hash}",
520
+ "mdx_data": "Đường dẫn dữ liệu mô hình MDX được đặt thành {mdx_model_data_path}",
521
+ "load_mdx": "Đang tải các tham số mô hình MDX từ tệp dữ liệu mô hình UVR...",
522
+ "model_not_support": "Tệp mô hình không được hỗ trợ: không thể tìm thấy tham số cho hash MD5 {model_hash} trong tệp dữ liệu mô hình UVR cho vòm MDX.",
523
+ "uvr_json": "Dữ liệu mô hình được tải từ UVR JSON bằng hàm băm {model_hash}: {model_data}",
524
+ "loading_model": "Đang tải mô hình {model_filename}...",
525
+ "download_model_friendly_2": "Đã tải xuống mô hình, tên thân thiện: {model_friendly_name}, Đường dẫn mô hình: {model_path}",
526
+ "model_type_not_support": "Loại mô hình không được hỗ trợ: {model_type}",
527
+ "demucs_not_support_python<3.10": "Các mô hình Demucs yêu cầu phiên bản Python 3.10 trở lên.",
528
+ "import_module": "Nhập mô-đun cho loại mô hình",
529
+ "initialization": "Khởi tạo lớp phân cách cho loại mô hình",
530
+ "loading_model_success": "Đang tải mô hình hoàn tất.",
531
+ "loading_model_duration": "Tải thời lượng mô hình",
532
+ "starting_separator": "Bắt đầu quá trình tách cho đường dẫn tập tin âm thanh",
533
+ "normalization": "Ngưỡng chuẩn hóa được đặt thành {normalization_threshold}, dạng sóng sẽ hạ xuống biên độ tối đa này để tránh bị cắt.",
534
+ "loading_separator_model": "Đang tải xuống mô hình {model_filename}...",
535
+ "separator_success_3": "Quá trình tách hoàn tất.",
536
+ "separator_duration": "Thời gian tách",
537
+ "downloading_model": "Đã tải xuống mô hình, loại: {model_type}, tên thân thiện: {model_friendly_name}, đường dẫn mô hình: {model_path}, dữ liệu mô hình: {model_data_dict_size} mục",
538
+ "demucs_info": "Thông số Demucs: Kích thước phân đoạn = {segment_size}, Kích hoạt kích thước phân đoạn = {segments_enabled}",
539
+ "demucs_info_2": "Thông số Demucs: Số lượng dự đoán = {shifts}, Chồng chéo = {overlap}",
540
+ "start_demucs": "Khởi tạo hoàn tất Demucs Separator",
541
+ "start_separator": "Bắt đầu quá trình tách...",
542
+ "prepare_mix": "Chuẩn bị hỗn hợp...",
543
+ "demix": "Hỗn hợp đã chuẩn bị để khử trộn. Hình dạng: {shape}",
544
+ "cancel_mix": "Đang tải mô hình để hủy trộn...",
545
+ "model_review": "Mô hình được tải và đặt ở chế độ đánh giá.",
546
+ "del_gpu_cache_after_demix": "Đã xóa bộ nhớ đệm mô hình và GPU sau khi hủy trộn.",
547
+ "process_output_file": "Đang xử lý tập tin đầu ra...",
548
+ "source_length": "Đang xử lý mảng nguồn, độ dài nguồn là {source_length}",
549
+ "process_ver": "Đang xử lý nguồn phiên bản...",
550
+ "set_map": "Đặt bản đồ nguồn thành {part} phần gốc...",
551
+ "process_all_part": "Xử lý cho tất cả các phần gốc...",
552
+ "skip_part": "Bỏ qua phần viết gốc {stem_name} vì out_single_stem được đặt thành {output_single_stem}...",
553
+ "starting_demix_demucs": "Đang bắt đầu quá trình trộn trong demix_demucs...",
554
+ "model_infer": "Chạy mô hình suy luận...",
555
+ "name_not_pretrained": "{name} không phải là một mô hình được đào tạo trước hay một túi mô hình.",
556
+ "invalid_checksum": "Tổng kiểm tra không hợp lệ cho tệp {path}, dự kiến {checksum} nhưng lại nhận được {actual_checksum}",
557
+ "mdx_info": "Thông số MDX: Kích thước lô = {batch_size}, Kích thước phân đoạn = {segment_size}",
558
+ "mdx_info_2": "Thông số MDX: Chồng chéo = {overlap}, Hop_length = {hop_length}, Kích hoạt khữ nhiễu = {enable_denoise}",
559
+ "mdx_info_3": "Thông số MDX",
560
+ "load_model_onnx": "Đang tải mô hình ONNX để suy lu���n...",
561
+ "load_model_onnx_success": "Đã tải mô hình hoàn tất bằng phiên suy luận ONNXruntime.",
562
+ "onnx_to_pytorch": "Mô hình được chuyển đổi từ onnx sang pytorch do kích thước phân đoạn không khớp với dim_t, quá trình xử lý có thể chậm hơn.",
563
+ "stft": "STFT nghịch đảo được áp dụng. Trả về kết quả có hình dạng",
564
+ "no_denoise": "Mô hình chạy trên quang phổ mà không khử nhiễu.",
565
+ "mix": "Đang chuẩn bị trộn cho tệp âm thanh đầu vào {audio_file_path}...",
566
+ "normalization_demix": "Chuẩn hóa hỗn hợp trước khi khử trộn...",
567
+ "mix_success": "Quá trình trộn hoàn tất.",
568
+ "primary_source": "Bình thường hóa nguồn chính...",
569
+ "secondary_source": "Sản xuất nguồn thứ cấp: Trộn ở chế độ trộn phù hợp",
570
+ "invert_using_spec": "Đảo ngược thân thứ cấp bằng cách sử dụng quang phổ khi invert_USE_spec được đặt thành True",
571
+ "invert_using_spec_2": "Đảo ngược thân thứ cấp bằng cách trừ đi thân cây được chuyển đổi từ hỗn hợp ban đầu được chuyển đổi",
572
+ "enable_denoise": "Mô hình chạy trên cả phổ âm và dương để khử nhiễu.",
573
+ "is_match_mix": "is_match_mix: dự đoán phổ thu được trực tiếp từ đầu ra STFT.",
574
+ "save_secondary_stem_output_path": "Đang lưu phần gốc {stem_name} vào {stem_output_path}...",
575
+ "starting_model": "Đang khởi tạo cài đặt mô hình...",
576
+ "input_info": "Thông số đầu vào của mô hình",
577
+ "model_settings": "Cài đặt mô hình",
578
+ "initialize_mix": "Đang khởi tạo kết hợp với is_ckpt = {is_ckpt}. Hình dạng trộn ban đầu: {shape}",
579
+ "!=2": "Dự kiến có tín hiệu âm thanh 2 kênh nhưng lại có {shape} kênh",
580
+ "process_check": "Xử lý ở chế độ điểm kiểm tra...",
581
+ "stft_2": "STFT được áp dụng trên hỗn hợp. Hình dạng quang phổ: {shape}",
582
+ "cache": "Khoảng đệm được tính toán",
583
+ "shape": "Hình dạng hỗn hợp sau khi đệm: {shape}, Số phần: {num_chunks}",
584
+ "process_no_check": "Xử lý ở chế độ không có điểm kiểm tra...",
585
+ "n_sample_or_pad": "Số lượng mẫu: {n_sample}, Đã tính đệm: {pad}",
586
+ "shape_2": "Hình dạng hỗn hợp sau khi đệm",
587
+ "process_part": "Đoạn đã xử lý {mix_waves}: Bắt đầu {i}, Kết thúc {ii}",
588
+ "mix_waves_to_tensor": "Đã chuyển đổi mix_waves thành tensor. Hình dạng tensor: {shape}",
589
+ "mix_match": "Chế độ trộn Match; áp dụng hệ số bù.",
590
+ "tar_waves": "Sóng tar_waves. Hình dạng",
591
+ "normalization_2": "Chuẩn hóa kết quả bằng cách chia kết quả cho số chia.",
592
+ "mix_wave": "Đang xử lý lô mix_wave",
593
+ "mix_or_batch": "Trộn phần chia thành từng đợt. Số lượng lô",
594
+ "demix_is_match_mix": "Bắt đầu quá trình hủy trộn với is_match_mix,",
595
+ "mix_shape": "Hỗn hợp phần gốc được lưu trữ. Hình dạng",
596
+ "chunk_size_or_overlap": "Kích thước đoạn để trộn phù hợp: {chunk_size}, Chồng chéo: {overlap}",
597
+ "chunk_size_or_overlap_standard": "Kích thước phần tiêu chuẩn: {chunk_size}, Chồng chéo: {overlap}",
598
+ "calc_size": "Kích thước được tạo được tính toán",
599
+ "window": "Cửa sổ được áp dụng cho đoạn này.",
600
+ "process_part_2": "Đang xử lý đoạn {total}/{total_chunks}: Bắt đầu {start}, Kết thúc {end}",
601
+ "all_process_part": "Tổng số phần cần xử lý",
602
+ "step_or_overlap": "Kích thước bước để xử lý các phần: {step} khi chồng chéo được đặt thành {overlap}.",
603
+ "mix_cache": "Hỗn hợp được chuẩn bị với lớp đệm. Hình dạng hỗn hợp",
604
+ "dims": "Không thể sử dụng mã hóa vị trí sin/cos với thứ nguyên lẻ (có dim={dims})",
605
+ "activation": "kích hoạt phải là relu/gelu, không phải {activation}",
606
+ "length_or_training_length": "Độ dài cho trước {length} dài hơn thời lượng huấn luyện {training_length}",
607
+ "type_not_valid": "Loại không hợp lệ cho",
608
+ "del_parameter": "Bỏ tham số không tồn tại ",
609
+ "info": "Các thông số phổ biến: Tên mô hình = {model_name}, Đường dẫn mô hình = {model_path}",
610
+ "info_2": "Các thông số phổ biến: Đường dẫn đầu ra = {output_dir}, Định dạng đầu ra = {output_format}",
611
+ "info_3": "Các thông số phổ biến: ngưỡng chuẩn hóa = {normalization_threshold}",
612
+ "info_4": "Các thông số phổ biến: Kích hoạt khữ nhiễu = {enable_denoise}, Đầu ra một phần = {output_single_stem}",
613
+ "info_5": "Các thông số phổ biến: Đảo ngược bằng cách sử dụng thông số kỹ thuật = {invert_using_spec}, tỷ lệ mẫu = {sample_rate}",
614
+ "info_6": "Các thông số phổ biến: Tên phần gốc chính = {primary_stem_name}, Tên phần gốc phụ = {secondary_stem_name}",
615
+ "info_7": "Các thông số phổ biến: Là Karaoke = {is_karaoke}, là mô hình bv = {is_bv_model}, tái cân bằng mô hình bv = {bv_model_rebalance}",
616
+ "success_process": "Đang hoàn tất quá trình xử lý phần gốc {stem_name} và ghi âm thanh...",
617
+ "load_audio": "Đang tải âm thanh từ tập tin",
618
+ "load_audio_success": "Đã tải âm thanh. Tốc độ mẫu: {sr}, Hình dạng âm thanh: {shape}",
619
+ "convert_mix": "Chuyển đổi mảng hỗn hợp được cung cấp.",
620
+ "convert_shape": "Hình dạng hỗn hợp chuyển đổi: {shape}",
621
+ "audio_not_valid": "Tệp âm thanh {audio_path} trống hoặc không hợp lệ",
622
+ "audio_valid": "Tệp âm thanh hợp lệ và chứa dữ liệu.",
623
+ "mix_single": "Hỗn hợp là đơn sắc. Chuyển đổi sang âm thanh nổi.",
624
+ "convert_mix_audio": "Đã chuyển đổi thành bản trộn âm thanh nổi.",
625
+ "mix_success_2": "Công tác chuẩn bị hỗn hợp đã hoàn tất.",
626
+ "duration": "Thời lượng âm thanh là {duration_hours} giờ ({duration_seconds} giây).",
627
+ "write": "Sử dụng {name} để viết.",
628
+ "write_audio": "Đang nhập {name} bằng đường dẫn gốc:",
629
+ "original_not_valid": "Cảnh báo: mảng nguồn gốc gần như im lặng hoặc trống.",
630
+ "shape_audio": "Hình dạng dữ liệu âm thanh trước khi xử lý",
631
+ "convert_data": "Kiểu dữ liệu trước khi chuyển đổi",
632
+ "original_source_to_int16": "Đã chuyển đổi original_source thành int16.",
633
+ "shape_audio_2": "Hình dạng dữ liệu âm thanh xen kẽ",
634
+ "create_audiosegment": "Đã tạo AudioSegment hoàn tất.",
635
+ "create_audiosegment_error": "Lỗi cụ thể khi tạo AudioSegment",
636
+ "export_error": "Lỗi xuất file âm thanh",
637
+ "export_success": "Đã xuất hoàn tất tệp âm thanh sang",
638
+ "clean": "Chạy thu gom rác...",
639
+ "clean_cache": "Xóa bộ nhớ đệm {name}...",
640
+ "del_path": "Xóa đường dẫn, nguồn và gốc của tệp âm thanh đầu vào...",
641
+ "not_success": "Quá trình đăng không hoàn tất: ",
642
+ "resample_error": "Lỗi trong quá trình lấy mẫu lại",
643
+ "shapes": "Hình dạng",
644
+ "wav_resolution": "Loại độ phân giải",
645
+ "warnings": "Cảnh báo: Đã phát hiện các giá trị cực kỳ hung hãn",
646
+ "warnings_2": "Cảnh báo: Đã phát hiện NaN hoặc giá trị vô hạn trong đầu vào sóng. Hình dạng",
647
+ "process_file": "Đang xử lý tập tin... \n",
648
+ "save_instruments": "Lưu bản nhạc ngược...",
649
+ "assert": "Các tệp âm thanh phải có hình dạng giống nhau - Mix: {mixshape}, Inst: {instrumentalshape}",
650
+ "rubberband": "Không thể thực Rubberband. Vui lòng xác minh rằng Rubberband-cli đã được cài đặt.",
651
+ "rate": "Tỉ lệ phải hoàn toàn tích cực",
652
+ "gdown_error": "Không thể truy xuất liên kết công khai của tệp. Bạn có thể cần phải thay đổi quyền thành bất kỳ ai có liên kết hoặc đã có nhiều quyền truy cập.",
653
+ "to": "Đến:",
654
+ "gdown_value_error": "Phải chỉ định đường dẫn hoặc id",
655
+ "missing_url": "Thiếu đường dẫn",
656
+ "mac_not_match": "MAC không khớp",
657
+ "file_not_access": "Tệp tin không thể truy cập",
658
+ "int_resp==-3": "Yêu cầu không hoàn tất, đang thử lại",
659
+ "search_separate": "Tìm bản tách...",
660
+ "found_choice": "Tìm thấy {choice}",
661
+ "separator==0": "Không tìm thấy bản tách nào!",
662
+ "select_separate": "Chọn bản tách",
663
+ "start_app": "Khởi động giao diện...",
664
+ "provide_audio": "Nhập đường dẫn đến tệp âm thanh",
665
+ "set_torch_mps": "Cài đặt thiết bị Torch thành MPS",
666
+ "googletts": "Chuyển đổi văn bản bằng google",
667
+ "pitch_info_2": "Cao độ giọng nói của bộ chuyển đổi văn bản",
668
+ "waveform": "Dạng sóng phải có hình dạng (# khung, # kênh)",
669
+ "freq_mask_smooth_hz": "freq_mask_smooth_hz cần ít nhất là {hz}Hz",
670
+ "time_mask_smooth_ms": "time_mask_smooth_ms cần ít nhất là {ms}ms",
671
+ "x": "x phải lớn hơn",
672
+ "xn": "xn phải lớn hơn",
673
+ "not_found_pid": "Không thấy tiến trình nào!",
674
+ "end_pid": "Đã kết thúc tiến trình!",
675
+ "not_found_separate_model": "Không tìm thấy tệp mô hình tách nhạc nào!",
676
+ "not_found_pretrained": "Không tìm thấy tệp mô hình huấn luyện trước nào!",
677
+ "not_found_log": "Không tìm thấy tệp nhật ký nào!",
678
+ "not_found_predictors": "Không tìm thấy tệp mô hình dự đoán nào!",
679
+ "not_found_embedders": "Không tìm thấy tệp mô hình nhúng nào!",
680
+ "provide_folder": "Vui lòng cung cấp thư mục hợp lệ!",
681
+ "empty_folder": "Thư mục dữ liệu trống!",
682
+ "vocoder": "Bộ mã hóa",
683
+ "vocoder_info": "Bộ mã hóa giọng nói dùng để phân tích và tổng hợp tín hiệu giọng nói của con người để chuyển đổi giọng nói.\n\nDefault: Tùy chọn này là HiFi-GAN-NSF, tương thích với tất cả các RVC (trừ tùy chọn 44,1k)\n\nMRF-HiFi-GAN: Độ trung thực cao hơn.\n\nRefineGAN: Chất lượng âm thanh vượt trội.",
684
+ "code_error": "Lỗi: Nhận mã trạng thái",
685
+ "json_error": "Lỗi: Không thể phân tích từ phản hồi.",
686
+ "requests_error": "Yêu cầu thất bại: {e}",
687
+ "memory_efficient_training": "Sử dụng hiệu quả bộ nhớ",
688
+ "not_use_pretrain_error_download": "Sẽ không dùng huấn luyện trước vì không có mô hình",
689
+ "provide_file_settings": "Vui lòng cung cấp tệp cài đặt trước!",
690
+ "load_presets": "Đã tải tệp cài đặt trước {presets}",
691
+ "provide_filename_settings": "Vui lòng cung cấp tên tệp cài đặt trước!",
692
+ "choose1": "Vui lòng chọn 1 để xuất!",
693
+ "export_settings": "Đã xuất tệp cài đặt trước {name}",
694
+ "use_presets": "Sử dụng tệp cài đặt trước",
695
+ "file_preset": "Tệp cài đặt trước",
696
+ "load_file": "Tải tệp",
697
+ "export_file": "Xuất tệp cài đặt trước",
698
+ "save_clean": "Lưu làm sạch",
699
+ "save_autotune": "Lưu tự điều chỉnh",
700
+ "save_pitch": "Lưu cao độ",
701
+ "save_index_2": "Lưu ảnh hưởng chỉ mục",
702
+ "save_resample": "Lưu lấy mẫu lại",
703
+ "save_filter": "Lưu trung vị",
704
+ "save_envelope": "Lưu đường bao âm",
705
+ "save_protect": "Lưu bảo vệ âm",
706
+ "save_split": "Lưu cắt âm",
707
+ "filename_to_save": "Tên khi lưu tệp",
708
+ "upload_presets": "Tải lên tệp cài đặt",
709
+ "stop": "Dừng tiến trình",
710
+ "stop_separate": "Dừng Tách Nhạc",
711
+ "stop_convert": "Dừng Chuyển Đổi",
712
+ "stop_create_dataset": "Dừng Tạo Dữ Liệu",
713
+ "stop_training": "Dừng Huấn Luyện",
714
+ "stop_extract": "Dừng Xử Lí Dữ Liệu",
715
+ "stop_preprocess": "Dừng Trích Xuất Dữ Liệu",
716
+ "not_found_presets": "Không tìm thấy tệp cài đặt sẳn nào trong thư mục!",
717
+ "port": "Cổng {port} không thể dùng! Giảm cổng xuống một...",
718
+ "empty_json": "{file}: Bị lỗi hoặc trống",
719
+ "thank": "Cảm ơn bạn đã báo cáo lỗi và cũng xin lỗi bạn vì sự bất tiện do lỗi gây ra này!",
720
+ "error_read_log": "Đã xảy ra lỗi khi đọc các tệp nhật ký!",
721
+ "error_send": "Đã xảy ra lỗi khi gửi báo cáo! Hãy liên hệ tôi qua Discord: pham_huynh_anh!",
722
+ "report_bugs": "Báo Cáo Lỗi",
723
+ "agree_log": "Đồng ý cung cấp tất cả tệp nhật ký",
724
+ "error_info": "Mô tả lỗi",
725
+ "error_info_2": "Cung cấp thêm thông tin về lỗi",
726
+ "report_bug_info": "Báo cáo các lỗi xảy ra khi sử dụng chương trình",
727
+ "sr_info": "LƯU Ý: MỘT SỐ ĐỊNH DẠNG KHÔNG HỖ TRỢ TRÊN 48000",
728
+ "report_info": "Nếu được bạn hãy đồng ý cung cấp các tệp nhật ký để hỗ trợ quá trình sửa lỗi\n\nNếu không cung cấp các tệp nhật ký bạn hãy mô tả chi tiết lỗi, lỗi xảy ra khi nào ở đâu\n\nNếu hệ thống báo cáo này bị lỗi nốt thì bạn có thể liên hệ qua [ISSUE]({github}) hoặc discord: `pham_huynh_anh`",
729
+ "default_setting": "Đã xảy ra lỗi khi sử dụng tách, đặt tất cả cài đặt về mặc định...",
730
+ "dataset_folder1": "Vui lòng nhập tên thư mục dữ liệu",
731
+ "checkpointing_err": "Các tham số của mô hình đào tạo trước như tốc độ mẫu hoặc kiến trúc không khớp với mô hình đã chọn.",
732
+ "start_onnx_export": "Bắt đầu chuyển đổi mô hình sang dạng onnx...",
733
+ "convert_model": "Chuyển Đổi Mô Hình",
734
+ "pytorch2onnx": "Chuyển Đổi Mô Hình PYTORCH Sang ONNX",
735
+ "pytorch2onnx_markdown": "Chuyển đổi mô hình RVC từ dạng pytorch sang onnx để tối ưu cho việc chuyển đổi âm thanh",
736
+ "error_readfile": "Đã xảy ra lỗi khi đọc tệp!",
737
+ "read_sf": "Đọc tệp âm thanh bằng soundfile...",
738
+ "read_librosa": "Đọc tệp âm thanh bằng librosa do soundfile không hỗ trợ...",
739
+ "f0_onnx_mode": "Chế độ F0 ONNX",
740
+ "f0_onnx_mode_info": "Trích xuất cao độ bằng mô hình ONNX có thể giúp tăng tốc độ",
741
+ "formantshift": "Dịch chuyển cao độ và âm sắc",
742
+ "formant_qfrency": "Tần số cho dịch chuyển định dạng",
743
+ "formant_timbre": "Âm sắc để chuyển đổi định dạng",
744
+ "time_frames": "Thời Gian (Khung)",
745
+ "Frequency": "Tần Số (Hz)",
746
+ "f0_extractor_tab": "Trích xuất F0",
747
+ "f0_extractor_markdown": "## Trích Xuất Cao Độ",
748
+ "f0_extractor_markdown_2": "Trích xuất cao độ F0 nhằm mục đích sử dụng cho suy luận chuyển đổi âm thanh",
749
+ "start_extract": "Bắt đầu quá trình trích xuất...",
750
+ "extract_done": "Hoàn tất quá trình trích xuất!",
751
+ "f0_file": "Sử dụng tệp F0 trích xuất trước",
752
+ "upload_f0": "Tải lên tệp F0",
753
+ "f0_file_2": "Tệp F0",
754
+ "clean_f0_file": "Dọp dẹp tệp F0",
755
+ "embed_mode": "Chế độ nhúng",
756
+ "embed_mode_info": "Trích xuất nhúng bằng các mô hình khác nhau",
757
+ "close": "Ứng dụng đang tắt...",
758
+ "start_whisper": "Bắt đầu nhận dạng giọng nói bằng Whisper...",
759
+ "whisper_done": "Đã nhận dạng giọng nói hoàn tất!",
760
+ "process_audio": "Xử lí trước âm thanh...",
761
+ "process_done_start_convert": "Hoàn tất xử lí âm thanh! tiến hành chuyển đổi âm thanh...",
762
+ "convert_with_whisper": "Chuyển Đổi Âm Thanh Với Whisper",
763
+ "convert_with_whisper_info": "Chuyển đổi âm thanh bằng mô hình giọng nói đã được huấn luyện kèm với mô hình Whisper để nhận diện giọng nói\n\nWhisper sẽ nhận dạng các giọng nói khác nhau sau đó cắt các giọng riêng ra rồi dùng mô hình RVC để chuyển đổi lại các phân đoạn đó\n\nMô hình Whisper có thể hoạt động không chính xác làm cho đầu ra có thể kì lạ",
764
+ "num_spk": "Số lượng giọng",
765
+ "num_spk_info": "Số lượng giọng nói có trong âm thanh",
766
+ "model_size": "Kích thước mô hình Whisper",
767
+ "model_size_info": "Kích thước mô hình Whisper\n\nCác mô hình large có thể đưa ra các đầu ra kì lạ",
768
+ "editing": "Chỉnh Sửa",
769
+ "inverting": "Đảo Ngược",
770
+ "steps": "Bước",
771
+ "source_prompt": "Lời Nhắc Nguồn",
772
+ "target_prompt": "Lời Nhắc",
773
+ "cfg_scale_src": "Hướng Dẫn Nguồn",
774
+ "cfg_scale_tar": "Hướng Dẫn Mục Tiêu",
775
+ "t_start": "Mức Độ Chỉnh Sửa",
776
+ "save_compute": "Chỉnh Sửa Hiệu Quả",
777
+ "error_edit": "Đã xảy ra lỗi khi chỉnh sửa nhạc nền {e}",
778
+ "start_edit": "Bắt đầu chỉnh sửa nhạc nền {input_path}...",
779
+ "edit_success": "Đã hoàn thành chỉnh sửa nhạc nền sau {time} với đầu ra {output_path}",
780
+ "audio_editing": "Chỉnh Sửa Nhạc Nền",
781
+ "audio_editing_info": "## Chỉnh Sửa Nhạc Nền Bằng Mô Hình Audioldm2",
782
+ "audio_editing_markdown": "Chỉnh sửa nhạc nền bằng mô hình của Audioldm2 có thể giúp thay đổi loại nhạc cụ bên trong nhạc nền",
783
+ "target_prompt_info": "Mô tả đầu ra đã chỉnh sửa mong muốn của bạn",
784
+ "cfg_scale_src_info": "Mức độ ảnh hưởng của gốc lên kết quả đầu ra. Giá trị cao hơn giữ lại nhiều đặc điểm hơn từ nguồn. Giá trị thấp hơn làm cho hệ thống tự do hơn trong việc biến đổi.",
785
+ "cfg_scale_tar_info": "Mức độ mục tiêu ảnh hưởng đến kết quả cuối cùng. Giá trị cao hơn sẽ ép kết quả theo đặc điểm của mục tiêu. Giá trị thấp hơn sẽ cân bằng giữa nguồn và mục tiêu.",
786
+ "audioldm2_model": "Mô hình Audioldm2",
787
+ "audioldm2_model_info": "Chọn mô hình Audioldm2 theo mong muốn của bạn\n\nViệc tải trọng số và suy luận cũng sẽ tốn nhiều thời gian tùy thuộc vào GPU của bạn",
788
+ "source_prompt_info": "Tùy chọn: Mô tả đầu vào âm thanh gốc",
789
+ "t_start_info": "Mức chỉnh sửa thấp hơn sẽ gần với âm thanh gốc hơn, cao hơn sẽ chỉnh sửa mạnh hơn.",
790
+ "steps_label": "Bước khuếch tán số",
791
+ "steps_info": "Giá trị cao hơn (ví dụ: 200) tạo ra sản phẩm có chất lượng cao hơn.",
792
+ "title": "Công cụ huấn luyện, chuyển đổi nhạc cụ và giọng nói chất lượng và hiệu suất cao đơn giản dành cho người Việt",
793
+ "fp16_not_support": "CPU Không hỗ trợ tốt fp16, chuyển đổi fp16 -> fp32",
794
+ "precision": "Độ chính xác",
795
+ "precision_info": "Độ chính xác của suy luận và huấn luyện mô hình\n\nLưu ý: CPU Không hỗ trợ fp16\n\nĐối với RefineGAN và MRF HIFIGAN khi chuyển đổi nên sử dụng fp32 vì fp16 có thể khiến chúng cho ra đầu ra kì lạ",
796
+ "update_precision": "Cập Nhật Độ Chính Xác",
797
+ "start_update_precision": "Bắt đầu cập nhật độ chính xác",
798
+ "deterministic": "Thuật toán xác định",
799
+ "deterministic_info": "Khi bật sẽ sử dụng các thuật toán có tính xác định cao, đảm bảo rằng mỗi lần chạy cùng một dữ liệu đầu vào sẽ cho kết quả giống nhau.\n\nKhi tắt có thể chọn các thuật toán tối ưu hơn nhưng có thể không hoàn toàn xác định, dẫn đến k���t quả huấn luyện có sự khác biệt giữa các lần chạy.",
800
+ "benchmark": "Thuật toán điểm chuẩn",
801
+ "benchmark_info": "Khi bật sẽ thử nghiệm và chọn thuật toán tối ưu nhất cho phần cứng và kích thước cụ thể. Điều này có thể giúp tăng tốc độ huấn luyện.\n\nKhi tắt sẽ không thực hiện tối ưu thuật toán này, có thể làm giảm tốc độ nhưng đảm bảo rằng mỗi lần chạy sử dụng cùng một thuật toán, điều này hữu ích nếu bạn muốn tái tạo chính xác.",
802
+ "font": "Phông chữ",
803
+ "font_info": "Phông chữ của giao diện\n\nTruy cập vào [Google Font](https://fonts.google.com) để lựa phông yêu thích của bạn.",
804
+ "change_font": "Đổi Phông Chữ",
805
+ "f0_unlock": "Mở khóa tất cả",
806
+ "f0_unlock_info": "Mở khóa toàn bộ phương pháp trích xuất cao độ",
807
+ "stop_audioldm2": "Dừng chỉnh sửa nhạc",
808
+ "srt": "Tệp SRT trống hoặc bị lỗi!"
809
+ }
assets/logs/mute/f0/mute.wav.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9b9acf9ab7facdb032e1d687fe35182670b0b94566c4b209ae48c239d19956a6
3
+ size 1332
assets/logs/mute/f0_voiced/mute.wav.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:30792849c8e72d67e6691754077f2888b101cb741e9c7f193c91dd9692870c87
3
+ size 2536
assets/logs/mute/sliced_audios/mute32000.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9edcf85ec77e88bd01edf3d887bdc418d3596d573f7ad2694da546f41dae6baf
3
+ size 192078
assets/logs/mute/sliced_audios/mute40000.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:67a816e77b50cb9f016e49e5c01f07e080c4e3b82b7a8ac3e64bcb143f90f31b
3
+ size 240078
assets/logs/mute/sliced_audios/mute48000.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2f2bb4daaa106e351aebb001e5a25de985c0b472f22e8d60676bc924a79056ee
3
+ size 288078
assets/logs/mute/sliced_audios_16k/mute.wav ADDED
Binary file (96.1 kB). View file
 
assets/logs/mute/v1_extracted/mute.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64d5abbac078e19a3f649c0d78a02cb33a71407ded3ddf2db78e6b803d0c0126
3
+ size 152704
assets/logs/mute/v2_extracted/mute.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:16ef62b957887ac9f0913aa5158f18983afff1ef5a3e4c5fd067ac20fc380d54
3
+ size 457856
assets/models/audioldm2/.gitattributes ADDED
File without changes
assets/models/embedders/.gitattributes ADDED
File without changes
assets/models/predictors/.gitattributes ADDED
File without changes
assets/models/pretrained_custom/.gitattributes ADDED
File without changes
assets/models/pretrained_v1/.gitattributes ADDED
File without changes
assets/models/pretrained_v2/.gitattributes ADDED
File without changes
assets/models/speaker_diarization/assets/gpt2.tiktoken ADDED
The diff for this file is too large to render. See raw diff
 
assets/models/speaker_diarization/assets/mel_filters.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7450ae70723a5ef9d341e3cee628c7cb0177f36ce42c44b7ed2bf3325f0f6d4c
3
+ size 4271
assets/models/speaker_diarization/assets/multilingual.tiktoken ADDED
The diff for this file is too large to render. See raw diff
 
assets/models/speaker_diarization/models/.gitattributes ADDED
File without changes
assets/models/uvr5/.gitattributes ADDED
File without changes
assets/presets/.gitattributes ADDED
File without changes
assets/weights/.gitattributes ADDED
File without changes
audios/.gitattributes ADDED
File without changes
dataset/.gitattributes ADDED
File without changes
main/app/app.py ADDED
The diff for this file is too large to render. See raw diff
 
main/app/parser.py ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ sys.path.append(os.getcwd())
5
+
6
+ try:
7
+ argv = sys.argv[1]
8
+ except IndexError:
9
+ argv = None
10
+
11
+ argv_is_allows = ["--audio_effects", "--audioldm2", "--convert", "--create_dataset", "--create_index", "--extract", "--preprocess", "--separator_music", "--train", "--help_audio_effects", "--help_audioldm2", "--help_convert", "--help_create_dataset", "--help_create_index", "--help_extract", "--help_preprocess", "--help_separator_music", "--help_train", "--help"]
12
+
13
+ if argv not in argv_is_allows:
14
+ print("Cú pháp không hợp lệ! Sử dụng --help để biết thêm")
15
+ quit()
16
+
17
+ if argv_is_allows[0] in argv: from main.inference.audio_effects import main
18
+ elif argv_is_allows[1] in argv: from main.inference.audioldm2 import main
19
+ elif argv_is_allows[2] in argv: from main.inference.convert import main
20
+ elif argv_is_allows[3] in argv: from main.inference.create_dataset import main
21
+ elif argv_is_allows[4] in argv: from main.inference.create_index import main
22
+ elif argv_is_allows[5] in argv: from main.inference.extract import main
23
+ elif argv_is_allows[6] in argv: from main.inference.preprocess import main
24
+ elif argv_is_allows[7] in argv: from main.inference.separator_music import main
25
+ elif argv_is_allows[8] in argv: from main.inference.train import main
26
+ elif argv_is_allows[9] in argv:
27
+ print("""Các tham số của `--audio_effects`:
28
+ 1. Đường dẫn tệp:
29
+ - `--input_path` (bắt buộc): Đường dẫn đến tệp âm thanh đầu vào.
30
+ - `--output_path` (mặc định: `./audios/apply_effects.wav`): Đường dẫn lưu tệp đầu ra.
31
+ - `--export_format` (mặc định: `wav`): Định dạng xuất tệp (`wav`, `mp3`, ...).
32
+
33
+ 2. Lấy mẫu lại:
34
+ - `--resample` (mặc định: `False`): Có lấy mẫu lại hay không.
35
+ - `--resample_sr` (mặc định: `0`): Tần số lấy mẫu mới (Hz).
36
+
37
+ 3. Hiệu ứng chorus:
38
+ - `--chorus`: Bật/tắt chorus.
39
+ - `--chorus_depth`, `--chorus_rate`, `--chorus_mix`, `--chorus_delay`, `--chorus_feedback`: Các thông số điều chỉnh chorus.
40
+
41
+ 4. Hiệu ứng distortion:
42
+ - `--distortion`: Bật/tắt distortion.
43
+ - `--drive_db`: Mức độ méo âm thanh.
44
+
45
+ 5. Hiệu ứng reverb:
46
+ - `--reverb`: Bật/tắt hồi âm.
47
+ - `--reverb_room_size`, `--reverb_damping`, `--reverb_wet_level`, `--reverb_dry_level`, `--reverb_width`, `--reverb_freeze_mode`: Điều chỉnh hồi âm.
48
+
49
+ 6. Hiệu ứng pitch shift:
50
+ - `--pitchshift`: Bật/tắt thay đổi cao độ.
51
+ - `--pitch_shift`: Giá trị dịch cao độ.
52
+
53
+ 7. Hiệu ứng delay:
54
+ - `--delay`: Bật/tắt delay.
55
+ - `--delay_seconds`, `--delay_feedback`, `--delay_mix`: Điều chỉnh thời gian trễ, phản hồi và hòa trộn.
56
+
57
+ 8. Compressor:
58
+ - `--compressor`: Bật/tắt compressor.
59
+ - `--compressor_threshold`, `--compressor_ratio`, `--compressor_attack_ms`, `--compressor_release_ms`: Các thông số nén.
60
+
61
+ 9. Limiter:
62
+ - `--limiter`: Bật/tắt giới hạn mức âm thanh.
63
+ - `--limiter_threshold`, `--limiter_release`: Ngưỡng giới hạn và thời gian nhả.
64
+
65
+ 10. Gain (Khuếch đại):
66
+ - `--gain`: Bật/tắt gain.
67
+ - `--gain_db`: Mức gain (dB).
68
+
69
+ 11. Bitcrush:
70
+ - `--bitcrush`: Bật/tắt hiệu ứng giảm độ phân giải.
71
+ - `--bitcrush_bit_depth`: Số bit của bitcrush.
72
+
73
+ 12. Clipping:
74
+ - `--clipping`: Bật/tắt cắt âm thanh.
75
+ - `--clipping_threshold`: Ngưỡng clipping.
76
+
77
+ 13. Phaser:
78
+ - `--phaser`: Bật/tắt hiệu ứng phaser.
79
+ - `--phaser_rate_hz`, `--phaser_depth`, `--phaser_centre_frequency_hz`, `--phaser_feedback`, `--phaser_mix`: Điều chỉnh hiệu ứng phaser.
80
+
81
+ 14. Boost bass & treble:
82
+ - `--treble_bass_boost`: Bật/tắt tăng cường âm bass và treble.
83
+ - `--bass_boost_db`, `--bass_boost_frequency`, `--treble_boost_db`, `--treble_boost_frequency`: Các thông số tăng bass và treble.
84
+
85
+ 15. Fade in & fade out:
86
+ - `--fade_in_out`: Bật/tắt hiệu ứng fade.
87
+ - `--fade_in_duration`, `--fade_out_duration`: Thời gian fade vào/ra.
88
+
89
+ 16. Kết hợp âm thanh:
90
+ - `--audio_combination`: Bật/tắt ghép nhiều tệp âm thanh.
91
+ - `--audio_combination_input`: Đường dẫn tệp âm thanh bổ sung.
92
+ """)
93
+ quit()
94
+ elif argv_is_allows[10] in argv:
95
+ print("""Các tham số của --audioldm2:
96
+ 1. Đường dẫn tệp:
97
+ - `--input_path` (bắt buộc): Đường dẫn đến tệp âm thanh đầu vào.
98
+ - `--output_path` (mặc định: `./output.wav`): Đường dẫn lưu tệp đầu ra.
99
+ - `--export_format` (mặc định: `wav`): Định dạng xuất tệp.
100
+
101
+ 2. Cấu hình âm thanh:
102
+ - `--sample_rate` (mặc định: `44100`): Tần số lấy mẫu (Hz).
103
+
104
+ 3. Cấu hình mô hình AudioLDM:
105
+ - `--audioldm_model` (mặc định: `audioldm2-music`): Chọn mô hình AudioLDM để xử lý.
106
+
107
+ 4. Prompt hướng dẫn mô hình:
108
+ - `--source_prompt` (mặc định: ``): Mô tả âm thanh nguồn.
109
+ - `--target_prompt` (mặc định: ``): Mô tả âm thanh đích.
110
+
111
+ 5. Cấu hình thuật toán xử lý:
112
+ - `--steps` (mặc định: `200`): Số bước xử lý trong quá trình tổng hợp âm thanh.
113
+ - `--cfg_scale_src` (mặc định: `3.5`): Hệ số điều chỉnh hướng dẫn cho âm thanh nguồn.
114
+ - `--cfg_scale_tar` (mặc định: `12`): Hệ số điều chỉnh hướng dẫn cho âm thanh đích.
115
+ - `--t_start` (mặc định: `45`): Mức độ chỉnh sửa.
116
+
117
+ 6. Tối ưu hóa tính toán:
118
+ - `--save_compute` (mặc định: `False`): Có bật chế độ tối ưu tính toán hay không.
119
+ """)
120
+ quit()
121
+ elif argv_is_allows[11] in argv:
122
+ print("""Các tham số của --convert:
123
+ 1. Cấu hình xử lý giọng nói:
124
+ - `--pitch` (mặc định: `0`): Điều chỉnh cao độ.
125
+ - `--filter_radius` (mặc định: `3`): Độ mượt của đường F0.
126
+ - `--index_rate` (mặc định: `0.5`): Tỷ lệ sử dụng chỉ mục giọng nói.
127
+ - `--volume_envelope` (mặc định: `1`): Hệ số điều chỉnh biên độ âm lượng.
128
+ - `--protect` (mặc định: `0.33`): Bảo vệ phụ âm.
129
+
130
+ 2. Cấu hình mẫu (frame hop):
131
+ - `--hop_length` (mặc định: `64`): Bước nhảy khi xử lý âm thanh.
132
+
133
+ 3. Cấu hình F0:
134
+ - `--f0_method` (mặc định: `rmvpe`): Phương pháp dự đoán F0 (`pm`, `dio`, `mangio-crepe-tiny`, `mangio-crepe-small`, `mangio-crepe-medium`, `mangio-crepe-large`, `mangio-crepe-full`, `crepe-tiny`, `crepe-small`, `crepe-medium`, `crepe-large`, `crepe-full`, `fcpe`, `fcpe-legacy`, `rmvpe`, `rmvpe-legacy`, `harvest`, `yin`, `pyin`, `swipe`).
135
+ - `--f0_autotune` (mặc định: `False`): Có tự động điều chỉnh F0 hay không.
136
+ - `--f0_autotune_strength` (mặc định: `1`): Cường độ hiệu chỉnh tự động F0.
137
+ - `--f0_file` (mặc định: ``): Đường dẫn tệp F0 có sẵn.
138
+ - `--f0_onnx` (mặc định: `False`): Có sử dụng phiên bản ONNX của F0 hay không.
139
+
140
+ 4. Mô hình nhúng:
141
+ - `--embedder_model` (mặc định: `contentvec_base`): Mô hình nhúng sử dụng.
142
+ - `--embedders_mode` (mặc định: `fairseq`): Chế độ nhúng (`fairseq`, `transformers`, `onnx`).
143
+
144
+ 5. Đường dẫn tệp:
145
+ - `--input_path` (bắt buộc): Đường dẫn tệp âm thanh đầu vào.
146
+ - `--output_path` (mặc định: `./audios/output.wav`): Đường dẫn lưu tệp đầu ra.
147
+ - `--export_format` (mặc định: `wav`): Định dạng xuất tệp.
148
+ - `--pth_path` (bắt buộc): Đường dẫn đến tệp mô hình `.pth`.
149
+ - `--index_path` (mặc định: `None`): Đường dẫn tệp chỉ mục (nếu có).
150
+
151
+ 6. Làm sạch âm thanh:
152
+ - `--clean_audio` (mặc định: `False`): Có áp dụng làm sạch âm thanh không.
153
+ - `--clean_strength` (mặc định: `0.7`): Mức độ làm sạch.
154
+
155
+ 7. Resampling & chia nhỏ âm thanh:
156
+ - `--resample_sr` (mặc định: `0`): Tần số lấy mẫu mới (0 nghĩa là giữ nguyên).
157
+ - `--split_audio` (mặc định: `False`): Có chia nhỏ audio trước khi xử lý không.
158
+
159
+ 8. Kiểm tra & tối ưu hóa:
160
+ - `--checkpointing` (mặc định: `False`): Bật/tắt checkpointing để tiết kiệm RAM.
161
+
162
+ 9. Dịch formant:
163
+ - `--formant_shifting` (mặc định: `False`): Có bật hiệu ứng dịch formant không.
164
+ - `--formant_qfrency` (mặc định: `0.8`): Hệ số dịch formant theo tần số.
165
+ - `--formant_timbre` (mặc định: `0.8`): Hệ số thay đổi màu sắc giọng.
166
+ """)
167
+ quit()
168
+ elif argv_is_allows[12] in argv:
169
+ print("""Các tham số của --create_dataset:
170
+ 1. Đường dẫn & cấu hình dataset:
171
+ - `--input_audio` (bắt buộc): Đường dẫn liên kết đến âm thanh (Liên kết Youtube, có thể dùng dấu `,` để dùng nhiều liên kết).
172
+ - `--output_dataset` (mặc định: `./dataset`): Thư mục xuất dữ liệu đầu ra.
173
+ - `--sample_rate` (mặc định: `44100`): Tần số lấy mẫu cho âm thanh.
174
+
175
+ 2. Làm sạch dữ liệu:
176
+ - `--clean_dataset` (mặc định: `False`): Có áp dụng làm sạch dữ liệu hay không.
177
+ - `--clean_strength` (mặc định: `0.7`): Mức độ làm sạch dữ liệu.
178
+
179
+ 3. Tách giọng & hiệu ứng:
180
+ - `--separator_reverb` (mặc định: `False`): Có tách vang giọng không.
181
+ - `--kim_vocal_version` (mặc định: `2`): Phiên bản mô hình Kim Vocal để tách (`1`, `2`).
182
+
183
+ 4. Cấu hình phân đoạn âm thanh:
184
+ - `--overlap` (mặc định: `0.25`): Mức độ chồng lấn giữa các đoạn khi tách.
185
+ - `--segments_size` (mặc định: `256`): Kích thước của từng phân đoạn.
186
+
187
+ 5. Cấu hình MDX (Music Demixing):
188
+ - `--mdx_hop_length` (mặc định: `1024`): Bước nhảy MDX khi xử lý.
189
+ - `--mdx_batch_size` (mặc định: `1`): Kích thước batch khi xử lý MDX.
190
+ - `--denoise_mdx` (mặc định: `False`): Có áp dụng khử nhiễu khi tách bằng MDX không.
191
+
192
+ 6. Bỏ qua phần âm thanh:
193
+ - `--skip` (mặc định: `False`): Có bỏ qua giây âm thanh nào không.
194
+ - `--skip_start_audios` (mặc định: `0`): Thời gian (giây) cần bỏ qua ở đầu audio.
195
+ - `--skip_end_audios` (mặc định: `0`): Thời gian (giây) cần bỏ qua ở cuối audio.
196
+ """)
197
+ quit()
198
+ elif argv_is_allows[13] in argv:
199
+ print("""Các tham số của --create_index:
200
+ 1. Thông tin mô hình:
201
+ - `--model_name` (bắt buộc): Tên mô hình.
202
+ - `--rvc_version` (mặc định: `v2`): Phiên bản (`v1`, `v2`).
203
+ - `--index_algorithm` (mặc định: `Auto`): Thuật toán index sử dụng (`Auto`, `Faiss`, `KMeans`).
204
+ """)
205
+ quit()
206
+ elif argv_is_allows[14] in argv:
207
+ print("""Các tham số của --extract:
208
+ 1. Thông tin mô hình:
209
+ - `--model_name` (bắt buộc): Tên mô hình.
210
+ - `--rvc_version` (mặc định: `v2`): Phiên bản RVC (`v1`, `v2`).
211
+
212
+ 2. Cấu hình F0:
213
+ - `--f0_method` (mặc định: `rmvpe`): Phương pháp dự đoán F0 (`pm`, `dio`, `mangio-crepe-tiny`, `mangio-crepe-small`, `mangio-crepe-medium`, `mangio-crepe-large`, `mangio-crepe-full`, `crepe-tiny`, `crepe-small`, `crepe-medium`, `crepe-large`, `crepe-full`, `fcpe`, `fcpe-legacy`, `rmvpe`, `rmvpe-legacy`, `harvest`, `yin`, `pyin`, `swipe`).
214
+ - `--pitch_guidance` (mặc định: `True`): Có sử dụng hướng dẫn cao độ hay không.
215
+
216
+ 3. Cấu hình xử lý:
217
+ - `--hop_length` (mặc định: `128`): Độ dài bước nhảy trong quá trình xử lý.
218
+ - `--cpu_cores` (mặc định: `2`): Số lượng luồng CPU sử dụng.
219
+ - `--gpu` (mặc định: `-`): Chỉ định GPU sử dụng (ví dụ: `0` cho GPU đầu tiên, `-` để tắt GPU).
220
+ - `--sample_rate` (bắt buộc): Tần số lấy mẫu của âm thanh đầu vào.
221
+
222
+ 4. Cấu hình nhúng:
223
+ - `--embedder_model` (mặc định: `contentvec_base`): Tên mô hình nhúng.
224
+ - `--f0_onnx` (mặc định: `False`): Có sử dụng phiên bản ONNX của F0 hay không.
225
+ - `--embedders_mode` (mặc định: `fairseq`): Chế độ nhúng (`fairseq`, `transformers`, `onnx`).
226
+ """)
227
+ quit()
228
+ elif argv_is_allows[15] in argv:
229
+ print("""Các tham số của --preprocess:
230
+ 1. Thông tin mô hình:
231
+ - `--model_name` (bắt buộc): Tên mô hình.
232
+
233
+ 2. Cấu hình dữ liệu:
234
+ - `--dataset_path` (mặc định: `./dataset`): Đường dẫn thư mục chứa tệp dữ liệu.
235
+ - `--sample_rate` (bắt buộc): Tần số lấy mẫu của dữ liệu âm thanh.
236
+
237
+ 3. Cấu hình xử lý:
238
+ - `--cpu_cores` (mặc định: `2`): Số lượng luồng CPU sử dụng.
239
+ - `--cut_preprocess` (mặc định: `True`): Có cắt tệp dữ liệu hay không.
240
+ - `--process_effects` (mặc định: `False`): Có áp dụng tiền xử lý hay không.
241
+ - `--clean_dataset` (mặc định: `False`): Có làm sạch tệp dữ liệu hay không.
242
+ - `--clean_strength` (mặc định: `0.7`): Độ mạnh của quá trình làm sạch dữ liệu.
243
+ """)
244
+ quit()
245
+ elif argv_is_allows[16] in argv:
246
+ print("""Các tham số của --separator_music:
247
+ 1. Đường dẫn dữ liệu:
248
+ - `--input_path` (bắt buộc): Đường dẫn tệp âm thanh đầu vào.
249
+ - `--output_path` (mặc định: `./audios`): Thư mục lưu tệp đầu ra.
250
+ - `--format` (mặc định: `wav`): Định dạng xuất tệp (`wav`, `mp3`,...).
251
+
252
+ 2. Cấu hình xử lý âm thanh:
253
+ - `--shifts` (m���c định: `2`): Số lượng dự đoán.
254
+ - `--segments_size` (mặc định: `256`): Kích thước phân đoạn âm thanh.
255
+ - `--overlap` (mặc định: `0.25`): Mức độ chồng lấn giữa các đoạn.
256
+ - `--mdx_hop_length` (mặc định: `1024`): Bước nhảy MDX khi xử lý.
257
+ - `--mdx_batch_size` (mặc định: `1`): Kích thước lô.
258
+
259
+ 3. Xử lý làm sạch:
260
+ - `--clean_audio` (mặc định: `False`): Có làm sạch âm thanh hay không.
261
+ - `--clean_strength` (mặc định: `0.7`): Độ mạnh của bộ lọc làm sạch.
262
+
263
+ 4. Cấu hình mô hình:
264
+ - `--model_name` (mặc định: `HT-Normal`): Mô hình tách nhạc (`Main_340`, `Main_390`, `Main_406`, `Main_427`, `Main_438`, `Inst_full_292`, `Inst_HQ_1`, `Inst_HQ_2`, `Inst_HQ_3`, `Inst_HQ_4`, `Inst_HQ_5`, `Kim_Vocal_1`, `Kim_Vocal_2`, `Kim_Inst`, `Inst_187_beta`, `Inst_82_beta`, `Inst_90_beta`, `Voc_FT`, `Crowd_HQ`, `Inst_1`, `Inst_2`, `Inst_3`, `MDXNET_1_9703`, `MDXNET_2_9682`, `MDXNET_3_9662`, `Inst_Main`, `MDXNET_Main`, `MDXNET_9482`, `HT-Normal`, `HT-Tuned`, `HD_MMI`, `HT_6S`).
265
+ - `--kara_model` (mặc định: `Version-1`): Phiên bản mô hình tách bè (`Version-1`, `Version-2`).
266
+
267
+ 5. Hiệu ứng và xử lý hậu kỳ:
268
+ - `--backing` (mặc định: `False`): Có tách bè hay không.
269
+ - `--mdx_denoise` (mặc định: `False`): Có sử dụng khử nhiễu MDX hay không.
270
+ - `--reverb` (mặc định: `False`): Có tách vang hay không.
271
+ - `--backing_reverb` (mặc định: `False`): có tách vang cho giọng bè không.
272
+
273
+ 6. Tần số lấy mẫu:
274
+ - `--sample_rate` (mặc định: `44100`): Tần số lấy mẫu của âm thanh đầu ra.
275
+ """)
276
+ quit()
277
+ elif argv_is_allows[17] in argv:
278
+ print("""Các tham số của --train:
279
+ 1. Cấu hình mô hình:
280
+ - `--model_name` (bắt buộc): Tên mô hình.
281
+ - `--rvc_version` (mặc định: `v2`): Phiên bản RVC (`v1`, `v2`).
282
+ - `--model_author` (tùy chọn): Tác giả của mô hình.
283
+
284
+ 2. Cấu hình lưu:
285
+ - `--save_every_epoch` (bắt buộc): Số kỷ nguyên giữa mỗi lần lưu.
286
+ - `--save_only_latest` (mặc định: `True`): Chỉ lưu điểm mới nhất.
287
+ - `--save_every_weights` (mặc định: `True`): Lưu tất cả trọng số của mô hình.
288
+
289
+ 3. Cấu hình huấn luyện:
290
+ - `--total_epoch` (mặc định: `300`): Tổng số kỷ nguyên huấn luyện.
291
+ - `--batch_size` (mặc định: `8`): Kích thước lô trong quá trình huấn luyện.
292
+ - `--sample_rate` (bắt buộc): Tần số lấy mẫu của âm thanh.
293
+
294
+ 4. Cấu hình thiết bị:
295
+ - `--gpu` (mặc định: `0`): Chỉ định GPU để sử dụng (số hoặc `-` nếu không dùng GPU).
296
+ - `--cache_data_in_gpu` (mặc định: `False`): Lưu dữ liệu vào GPU để tăng tốc.
297
+
298
+ 5. Cấu hình huấn luyện nâng cao:
299
+ - `--pitch_guidance` (mặc định: `True`): Sử dụng hướng dẫn cao độ.
300
+ - `--g_pretrained_path` (mặc định: ``): Đường dẫn đến trọng số G đã huấn luyện trước.
301
+ - `--d_pretrained_path` (mặc định: ``): Đường dẫn đến trọng số D đã huấn luyện trước.
302
+ - `--vocoder` (mặc định: `Default`): Bộ mã hóa được sử dụng (`Default`, `MRF-HiFi-GAN`, `RefineGAN`).
303
+
304
+ 6. Phát hiện huấn luyện quá mức:
305
+ - `--overtraining_detector` (mặc định: `False`): Bật/tắt chế độ phát hiện huấn luyện quá mức.
306
+ - `--overtraining_threshold` (mặc định: `50`): Ngưỡng để xác định huấn luyện quá mức.
307
+
308
+ 7. Xử lý dữ liệu:
309
+ - `--cleanup` (mặc định: `False`): Dọn dẹp tệp huấn luyện cũ để tiến hành huấn luyện lại từ đầu.
310
+
311
+ 8. Tối ưu:
312
+ - `--checkpointing` (mặc định: `False`): Bật/tắt checkpointing để tiết kiệm RAM.
313
+ - `--deterministic` (mặc định: `False`): Khi bật sẽ sử dụng các thuật toán có tính xác định cao, đảm bảo rằng mỗi lần chạy cùng một dữ liệu đầu vào sẽ cho kết quả giống nhau.
314
+ - `--benchmark` (mặc định: `False`): Khi bật sẽ thử nghiệm và chọn thuật toán tối ưu nhất cho phần cứng và kích thước cụ thể.
315
+ """)
316
+ quit()
317
+ elif argv_is_allows[18] in argv:
318
+ print("""Sử dụng:
319
+ 1. `--help_audio_effects`: Trợ giúp về phần thêm hiệu ứng âm thanh.
320
+ 2. `--help_audioldm2`: Trợ giúp về phần chỉnh sửa nhạc.
321
+ 3. `--help_convert`: Trợ giúp về chuyển đổi âm thanh.
322
+ 4. `--help_create_dataset`: Trợ giúp về tạo dữ liệu huấn luyện.
323
+ 5. `--help_create_index`: Trợ giúp về tạo chỉ mục.
324
+ 6. `--help_extract`: Trợ giúp về trích xuất dữ liệu huấn luyện.
325
+ 7. `--help_preprocess`: Trợ giúp về xử lý trước dữ liệu.
326
+ 8. `--help_separator_music`: Trợ giúp về tách nhạc.
327
+ 9. `--help_train`: Trợ giúp về huấn luyện mô hình.
328
+ """)
329
+ quit()
330
+
331
+
332
+ if __name__ == "__main__":
333
+ if "--train" in argv:
334
+ import torch.multiprocessing as mp
335
+ mp.set_start_method("spawn")
336
+
337
+ try:
338
+ main()
339
+ except:
340
+ pass
main/app/tensorboard.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import json
4
+ import logging
5
+ import webbrowser
6
+
7
+ from tensorboard import program
8
+
9
+ sys.path.append(os.getcwd())
10
+
11
+ from main.configs.config import Config
12
+ translations = Config().translations
13
+
14
+ with open(os.path.join("main", "configs", "config.json"), "r") as f:
15
+ configs = json.load(f)
16
+
17
+ def launch_tensorboard():
18
+ for l in ["root", "tensorboard"]:
19
+ logging.getLogger(l).setLevel(logging.ERROR)
20
+
21
+ tb = program.TensorBoard()
22
+ tb.configure(argv=[None, "--logdir", "assets/logs", f"--port={configs['tensorboard_port']}"])
23
+ url = tb.launch()
24
+
25
+ print(f"{translations['tensorboard_url']}: {url}")
26
+ if "--open" in sys.argv: webbrowser.open(url)
27
+
28
+ return f"{translations['tensorboard_url']}: {url}"
29
+
30
+ if __name__ == "__main__": launch_tensorboard()
main/configs/config.json ADDED
@@ -0,0 +1,547 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "language": "vi-VN",
3
+ "support_language": [
4
+ "en-US",
5
+ "vi-VN"
6
+ ],
7
+ "theme": "NoCrypt/miku",
8
+ "themes": [
9
+ "NoCrypt/miku",
10
+ "gstaff/xkcd",
11
+ "JohnSmith9982/small_and_pretty",
12
+ "ParityError/Interstellar",
13
+ "earneleh/paris",
14
+ "shivi/calm_seafoam",
15
+ "Hev832/Applio",
16
+ "YTheme/Minecraft",
17
+ "gstaff/sketch",
18
+ "SebastianBravo/simci_css",
19
+ "allenai/gradio-theme",
20
+ "Nymbo/Nymbo_Theme_5",
21
+ "lone17/kotaemon",
22
+ "Zarkel/IBM_Carbon_Theme",
23
+ "SherlockRamos/Feliz",
24
+ "freddyaboulton/dracula_revamped",
25
+ "freddyaboulton/bad-theme-space",
26
+ "gradio/dracula_revamped",
27
+ "abidlabs/dracula_revamped",
28
+ "gradio/dracula_test",
29
+ "gradio/seafoam",
30
+ "gradio/glass",
31
+ "gradio/monochrome",
32
+ "gradio/soft",
33
+ "gradio/default",
34
+ "gradio/base",
35
+ "abidlabs/pakistan",
36
+ "dawood/microsoft_windows",
37
+ "ysharma/steampunk",
38
+ "ysharma/huggingface",
39
+ "abidlabs/Lime",
40
+ "freddyaboulton/this-theme-does-not-exist-2",
41
+ "aliabid94/new-theme",
42
+ "aliabid94/test2",
43
+ "aliabid94/test3",
44
+ "aliabid94/test4",
45
+ "abidlabs/banana",
46
+ "freddyaboulton/test-blue",
47
+ "gstaff/whiteboard",
48
+ "ysharma/llamas",
49
+ "abidlabs/font-test",
50
+ "YenLai/Superhuman",
51
+ "bethecloud/storj_theme",
52
+ "sudeepshouche/minimalist",
53
+ "knotdgaf/gradiotest",
54
+ "ParityError/Anime",
55
+ "Ajaxon6255/Emerald_Isle",
56
+ "ParityError/LimeFace",
57
+ "finlaymacklon/smooth_slate",
58
+ "finlaymacklon/boxy_violet",
59
+ "derekzen/stardust",
60
+ "EveryPizza/Cartoony-Gradio-Theme",
61
+ "Ifeanyi/Cyanister",
62
+ "Tshackelton/IBMPlex-DenseReadable",
63
+ "snehilsanyal/scikit-learn",
64
+ "Himhimhim/xkcd",
65
+ "nota-ai/theme",
66
+ "rawrsor1/Everforest",
67
+ "rottenlittlecreature/Moon_Goblin",
68
+ "abidlabs/test-yellow",
69
+ "abidlabs/test-yellow3",
70
+ "idspicQstitho/dracula_revamped",
71
+ "kfahn/AnimalPose",
72
+ "HaleyCH/HaleyCH_Theme",
73
+ "simulKitke/dracula_test",
74
+ "braintacles/CrimsonNight",
75
+ "wentaohe/whiteboardv2",
76
+ "reilnuud/polite",
77
+ "remilia/Ghostly",
78
+ "Franklisi/darkmode",
79
+ "coding-alt/soft",
80
+ "xiaobaiyuan/theme_land",
81
+ "step-3-profit/Midnight-Deep",
82
+ "xiaobaiyuan/theme_demo",
83
+ "Taithrah/Minimal",
84
+ "Insuz/SimpleIndigo",
85
+ "zkunn/Alipay_Gradio_theme",
86
+ "Insuz/Mocha",
87
+ "xiaobaiyuan/theme_brief",
88
+ "Ama434/434-base-Barlow",
89
+ "Ama434/def_barlow",
90
+ "Ama434/neutral-barlow",
91
+ "dawood/dracula_test",
92
+ "nuttea/Softblue",
93
+ "BlueDancer/Alien_Diffusion",
94
+ "naughtondale/monochrome",
95
+ "Dagfinn1962/standard",
96
+ "default"
97
+ ],
98
+ "mdx_model": [
99
+ "Main_340",
100
+ "Main_390",
101
+ "Main_406",
102
+ "Main_427",
103
+ "Main_438",
104
+ "Inst_full_292",
105
+ "Inst_HQ_1",
106
+ "Inst_HQ_2",
107
+ "Inst_HQ_3",
108
+ "Inst_HQ_4",
109
+ "Inst_HQ_5",
110
+ "Kim_Vocal_1",
111
+ "Kim_Vocal_2",
112
+ "Kim_Inst",
113
+ "Inst_187_beta",
114
+ "Inst_82_beta",
115
+ "Inst_90_beta",
116
+ "Voc_FT",
117
+ "Crowd_HQ",
118
+ "Inst_1",
119
+ "Inst_2",
120
+ "Inst_3",
121
+ "MDXNET_1_9703",
122
+ "MDXNET_2_9682",
123
+ "MDXNET_3_9662",
124
+ "Inst_Main",
125
+ "MDXNET_Main",
126
+ "MDXNET_9482"
127
+ ],
128
+ "demucs_model": [
129
+ "HT-Normal",
130
+ "HT-Tuned",
131
+ "HD_MMI",
132
+ "HT_6S"
133
+ ],
134
+ "edge_tts": [
135
+ "af-ZA-AdriNeural",
136
+ "af-ZA-WillemNeural",
137
+ "sq-AL-AnilaNeural",
138
+ "sq-AL-IlirNeural",
139
+ "am-ET-AmehaNeural",
140
+ "am-ET-MekdesNeural",
141
+ "ar-DZ-AminaNeural",
142
+ "ar-DZ-IsmaelNeural",
143
+ "ar-BH-AliNeural",
144
+ "ar-BH-LailaNeural",
145
+ "ar-EG-SalmaNeural",
146
+ "ar-EG-ShakirNeural",
147
+ "ar-IQ-BasselNeural",
148
+ "ar-IQ-RanaNeural",
149
+ "ar-JO-SanaNeural",
150
+ "ar-JO-TaimNeural",
151
+ "ar-KW-FahedNeural",
152
+ "ar-KW-NouraNeural",
153
+ "ar-LB-LaylaNeural",
154
+ "ar-LB-RamiNeural",
155
+ "ar-LY-ImanNeural",
156
+ "ar-LY-OmarNeural",
157
+ "ar-MA-JamalNeural",
158
+ "ar-MA-MounaNeural",
159
+ "ar-OM-AbdullahNeural",
160
+ "ar-OM-AyshaNeural",
161
+ "ar-QA-AmalNeural",
162
+ "ar-QA-MoazNeural",
163
+ "ar-SA-HamedNeural",
164
+ "ar-SA-ZariyahNeural",
165
+ "ar-SY-AmanyNeural",
166
+ "ar-SY-LaithNeural",
167
+ "ar-TN-HediNeural",
168
+ "ar-TN-ReemNeural",
169
+ "ar-AE-FatimaNeural",
170
+ "ar-AE-HamdanNeural",
171
+ "ar-YE-MaryamNeural",
172
+ "ar-YE-SalehNeural",
173
+ "az-AZ-BabekNeural",
174
+ "az-AZ-BanuNeural",
175
+ "bn-BD-NabanitaNeural",
176
+ "bn-BD-PradeepNeural",
177
+ "bn-IN-BashkarNeural",
178
+ "bn-IN-TanishaaNeural",
179
+ "bs-BA-GoranNeural",
180
+ "bs-BA-VesnaNeural",
181
+ "bg-BG-BorislavNeural",
182
+ "bg-BG-KalinaNeural",
183
+ "my-MM-NilarNeural",
184
+ "my-MM-ThihaNeural",
185
+ "ca-ES-EnricNeural",
186
+ "ca-ES-JoanaNeural",
187
+ "zh-HK-HiuGaaiNeural",
188
+ "zh-HK-HiuMaanNeural",
189
+ "zh-HK-WanLungNeural",
190
+ "zh-CN-XiaoxiaoNeural",
191
+ "zh-CN-XiaoyiNeural",
192
+ "zh-CN-YunjianNeural",
193
+ "zh-CN-YunxiNeural",
194
+ "zh-CN-YunxiaNeural",
195
+ "zh-CN-YunyangNeural",
196
+ "zh-CN-liaoning-XiaobeiNeural",
197
+ "zh-TW-HsiaoChenNeural",
198
+ "zh-TW-YunJheNeural",
199
+ "zh-TW-HsiaoYuNeural",
200
+ "zh-CN-shaanxi-XiaoniNeural",
201
+ "hr-HR-GabrijelaNeural",
202
+ "hr-HR-SreckoNeural",
203
+ "cs-CZ-AntoninNeural",
204
+ "cs-CZ-VlastaNeural",
205
+ "da-DK-ChristelNeural",
206
+ "da-DK-JeppeNeural",
207
+ "nl-BE-ArnaudNeural",
208
+ "nl-BE-DenaNeural",
209
+ "nl-NL-ColetteNeural",
210
+ "nl-NL-FennaNeural",
211
+ "nl-NL-MaartenNeural",
212
+ "en-AU-NatashaNeural",
213
+ "en-AU-WilliamNeural",
214
+ "en-CA-ClaraNeural",
215
+ "en-CA-LiamNeural",
216
+ "en-HK-SamNeural",
217
+ "en-HK-YanNeural",
218
+ "en-IN-NeerjaExpressiveNeural",
219
+ "en-IN-NeerjaNeural",
220
+ "en-IN-PrabhatNeural",
221
+ "en-IE-ConnorNeural",
222
+ "en-IE-EmilyNeural",
223
+ "en-KE-AsiliaNeural",
224
+ "en-KE-ChilembaNeural",
225
+ "en-NZ-MitchellNeural",
226
+ "en-NZ-MollyNeural",
227
+ "en-NG-AbeoNeural",
228
+ "en-NG-EzinneNeural",
229
+ "en-PH-JamesNeural",
230
+ "en-PH-RosaNeural",
231
+ "en-SG-LunaNeural",
232
+ "en-SG-WayneNeural",
233
+ "en-ZA-LeahNeural",
234
+ "en-ZA-LukeNeural",
235
+ "en-TZ-ElimuNeural",
236
+ "en-TZ-ImaniNeural",
237
+ "en-GB-LibbyNeural",
238
+ "en-GB-MaisieNeural",
239
+ "en-GB-RyanNeural",
240
+ "en-GB-SoniaNeural",
241
+ "en-GB-ThomasNeural",
242
+ "en-US-AvaMultilingualNeural",
243
+ "en-US-AndrewMultilingualNeural",
244
+ "en-US-EmmaMultilingualNeural",
245
+ "en-US-BrianMultilingualNeural",
246
+ "en-US-AvaNeural",
247
+ "en-US-AndrewNeural",
248
+ "en-US-EmmaNeural",
249
+ "en-US-BrianNeural",
250
+ "en-US-AnaNeural",
251
+ "en-US-AriaNeural",
252
+ "en-US-ChristopherNeural",
253
+ "en-US-EricNeural",
254
+ "en-US-GuyNeural",
255
+ "en-US-JennyNeural",
256
+ "en-US-MichelleNeural",
257
+ "en-US-RogerNeural",
258
+ "en-US-SteffanNeural",
259
+ "et-EE-AnuNeural",
260
+ "et-EE-KertNeural",
261
+ "fil-PH-AngeloNeural",
262
+ "fil-PH-BlessicaNeural",
263
+ "fi-FI-HarriNeural",
264
+ "fi-FI-NooraNeural",
265
+ "fr-BE-CharlineNeural",
266
+ "fr-BE-GerardNeural",
267
+ "fr-CA-ThierryNeural",
268
+ "fr-CA-AntoineNeural",
269
+ "fr-CA-JeanNeural",
270
+ "fr-CA-SylvieNeural",
271
+ "fr-FR-VivienneMultilingualNeural",
272
+ "fr-FR-RemyMultilingualNeural",
273
+ "fr-FR-DeniseNeural",
274
+ "fr-FR-EloiseNeural",
275
+ "fr-FR-HenriNeural",
276
+ "fr-CH-ArianeNeural",
277
+ "fr-CH-FabriceNeural",
278
+ "gl-ES-RoiNeural",
279
+ "gl-ES-SabelaNeural",
280
+ "ka-GE-EkaNeural",
281
+ "ka-GE-GiorgiNeural",
282
+ "de-AT-IngridNeural",
283
+ "de-AT-JonasNeural",
284
+ "de-DE-SeraphinaMultilingualNeural",
285
+ "de-DE-FlorianMultilingualNeural",
286
+ "de-DE-AmalaNeural",
287
+ "de-DE-ConradNeural",
288
+ "de-DE-KatjaNeural",
289
+ "de-DE-KillianNeural",
290
+ "de-CH-JanNeural",
291
+ "de-CH-LeniNeural",
292
+ "el-GR-AthinaNeural",
293
+ "el-GR-NestorasNeural",
294
+ "gu-IN-DhwaniNeural",
295
+ "gu-IN-NiranjanNeural",
296
+ "he-IL-AvriNeural",
297
+ "he-IL-HilaNeural",
298
+ "hi-IN-MadhurNeural",
299
+ "hi-IN-SwaraNeural",
300
+ "hu-HU-NoemiNeural",
301
+ "hu-HU-TamasNeural",
302
+ "is-IS-GudrunNeural",
303
+ "is-IS-GunnarNeural",
304
+ "id-ID-ArdiNeural",
305
+ "id-ID-GadisNeural",
306
+ "ga-IE-ColmNeural",
307
+ "ga-IE-OrlaNeural",
308
+ "it-IT-GiuseppeNeural",
309
+ "it-IT-DiegoNeural",
310
+ "it-IT-ElsaNeural",
311
+ "it-IT-IsabellaNeural",
312
+ "ja-JP-KeitaNeural",
313
+ "ja-JP-NanamiNeural",
314
+ "jv-ID-DimasNeural",
315
+ "jv-ID-SitiNeural",
316
+ "kn-IN-GaganNeural",
317
+ "kn-IN-SapnaNeural",
318
+ "kk-KZ-AigulNeural",
319
+ "kk-KZ-DauletNeural",
320
+ "km-KH-PisethNeural",
321
+ "km-KH-SreymomNeural",
322
+ "ko-KR-HyunsuNeural",
323
+ "ko-KR-InJoonNeural",
324
+ "ko-KR-SunHiNeural",
325
+ "lo-LA-ChanthavongNeural",
326
+ "lo-LA-KeomanyNeural",
327
+ "lv-LV-EveritaNeural",
328
+ "lv-LV-NilsNeural",
329
+ "lt-LT-LeonasNeural",
330
+ "lt-LT-OnaNeural",
331
+ "mk-MK-AleksandarNeural",
332
+ "mk-MK-MarijaNeural",
333
+ "ms-MY-OsmanNeural",
334
+ "ms-MY-YasminNeural",
335
+ "ml-IN-MidhunNeural",
336
+ "ml-IN-SobhanaNeural",
337
+ "mt-MT-GraceNeural",
338
+ "mt-MT-JosephNeural",
339
+ "mr-IN-AarohiNeural",
340
+ "mr-IN-ManoharNeural",
341
+ "mn-MN-BataaNeural",
342
+ "mn-MN-YesuiNeural",
343
+ "ne-NP-HemkalaNeural",
344
+ "ne-NP-SagarNeural",
345
+ "nb-NO-FinnNeural",
346
+ "nb-NO-PernilleNeural",
347
+ "ps-AF-GulNawazNeural",
348
+ "ps-AF-LatifaNeural",
349
+ "fa-IR-DilaraNeural",
350
+ "fa-IR-FaridNeural",
351
+ "pl-PL-MarekNeural",
352
+ "pl-PL-ZofiaNeural",
353
+ "pt-BR-ThalitaNeural",
354
+ "pt-BR-AntonioNeural",
355
+ "pt-BR-FranciscaNeural",
356
+ "pt-PT-DuarteNeural",
357
+ "pt-PT-RaquelNeural",
358
+ "ro-RO-AlinaNeural",
359
+ "ro-RO-EmilNeural",
360
+ "ru-RU-DmitryNeural",
361
+ "ru-RU-SvetlanaNeural",
362
+ "sr-RS-NicholasNeural",
363
+ "sr-RS-SophieNeural",
364
+ "si-LK-SameeraNeural",
365
+ "si-LK-ThiliniNeural",
366
+ "sk-SK-LukasNeural",
367
+ "sk-SK-ViktoriaNeural",
368
+ "sl-SI-PetraNeural",
369
+ "sl-SI-RokNeural",
370
+ "so-SO-MuuseNeural",
371
+ "so-SO-UbaxNeural",
372
+ "es-AR-ElenaNeural",
373
+ "es-AR-TomasNeural",
374
+ "es-BO-MarceloNeural",
375
+ "es-BO-SofiaNeural",
376
+ "es-CL-CatalinaNeural",
377
+ "es-CL-LorenzoNeural",
378
+ "es-ES-XimenaNeural",
379
+ "es-CO-GonzaloNeural",
380
+ "es-CO-SalomeNeural",
381
+ "es-CR-JuanNeural",
382
+ "es-CR-MariaNeural",
383
+ "es-CU-BelkysNeural",
384
+ "es-CU-ManuelNeural",
385
+ "es-DO-EmilioNeural",
386
+ "es-DO-RamonaNeural",
387
+ "es-EC-AndreaNeural",
388
+ "es-EC-LuisNeural",
389
+ "es-SV-LorenaNeural",
390
+ "es-SV-RodrigoNeural",
391
+ "es-GQ-JavierNeural",
392
+ "es-GQ-TeresaNeural",
393
+ "es-GT-AndresNeural",
394
+ "es-GT-MartaNeural",
395
+ "es-HN-CarlosNeural",
396
+ "es-HN-KarlaNeural",
397
+ "es-MX-DaliaNeural",
398
+ "es-MX-JorgeNeural",
399
+ "es-NI-FedericoNeural",
400
+ "es-NI-YolandaNeural",
401
+ "es-PA-MargaritaNeural",
402
+ "es-PA-RobertoNeural",
403
+ "es-PY-MarioNeural",
404
+ "es-PY-TaniaNeural",
405
+ "es-PE-AlexNeural",
406
+ "es-PE-CamilaNeural",
407
+ "es-PR-KarinaNeural",
408
+ "es-PR-VictorNeural",
409
+ "es-ES-AlvaroNeural",
410
+ "es-ES-ElviraNeural",
411
+ "es-US-AlonsoNeural",
412
+ "es-US-PalomaNeural",
413
+ "es-UY-MateoNeural",
414
+ "es-UY-ValentinaNeural",
415
+ "es-VE-PaolaNeural",
416
+ "es-VE-SebastianNeural",
417
+ "su-ID-JajangNeural",
418
+ "su-ID-TutiNeural",
419
+ "sw-KE-RafikiNeural",
420
+ "sw-KE-ZuriNeural",
421
+ "sw-TZ-DaudiNeural",
422
+ "sw-TZ-RehemaNeural",
423
+ "sv-SE-MattiasNeural",
424
+ "sv-SE-SofieNeural",
425
+ "ta-IN-PallaviNeural",
426
+ "ta-IN-ValluvarNeural",
427
+ "ta-MY-KaniNeural",
428
+ "ta-MY-SuryaNeural",
429
+ "ta-SG-AnbuNeural",
430
+ "ta-SG-VenbaNeural",
431
+ "ta-LK-KumarNeural",
432
+ "ta-LK-SaranyaNeural",
433
+ "te-IN-MohanNeural",
434
+ "te-IN-ShrutiNeural",
435
+ "th-TH-NiwatNeural",
436
+ "th-TH-PremwadeeNeural",
437
+ "tr-TR-AhmetNeural",
438
+ "tr-TR-EmelNeural",
439
+ "uk-UA-OstapNeural",
440
+ "uk-UA-PolinaNeural",
441
+ "ur-IN-GulNeural",
442
+ "ur-IN-SalmanNeural",
443
+ "ur-PK-AsadNeural",
444
+ "ur-PK-UzmaNeural",
445
+ "uz-UZ-MadinaNeural",
446
+ "uz-UZ-SardorNeural",
447
+ "vi-VN-HoaiMyNeural",
448
+ "vi-VN-NamMinhNeural",
449
+ "cy-GB-AledNeural",
450
+ "cy-GB-NiaNeural",
451
+ "zu-ZA-ThandoNeural",
452
+ "zu-ZA-ThembaNeural"
453
+ ],
454
+ "google_tts_voice": [
455
+ "af",
456
+ "am",
457
+ "ar",
458
+ "bg",
459
+ "bn",
460
+ "bs",
461
+ "ca",
462
+ "cs",
463
+ "cy",
464
+ "da",
465
+ "de",
466
+ "el",
467
+ "en",
468
+ "es",
469
+ "et",
470
+ "eu",
471
+ "fi",
472
+ "fr",
473
+ "fr-CA",
474
+ "gl",
475
+ "gu",
476
+ "ha",
477
+ "hi",
478
+ "hr",
479
+ "hu",
480
+ "id",
481
+ "is",
482
+ "it",
483
+ "iw",
484
+ "ja",
485
+ "jw",
486
+ "km",
487
+ "kn",
488
+ "ko",
489
+ "la",
490
+ "lt",
491
+ "lv",
492
+ "ml",
493
+ "mr",
494
+ "ms",
495
+ "my",
496
+ "ne",
497
+ "nl",
498
+ "no",
499
+ "pa",
500
+ "pl",
501
+ "pt",
502
+ "pt-PT",
503
+ "ro",
504
+ "ru",
505
+ "si",
506
+ "sk",
507
+ "sq",
508
+ "sr",
509
+ "su",
510
+ "sv",
511
+ "sw",
512
+ "ta",
513
+ "te",
514
+ "th",
515
+ "tl",
516
+ "tr",
517
+ "uk",
518
+ "ur",
519
+ "vi",
520
+ "yue",
521
+ "zh-CN",
522
+ "zh-TW",
523
+ "zh"
524
+ ],
525
+ "fp16": true,
526
+ "separator_tab": true,
527
+ "convert_tab": true,
528
+ "convert_with_whisper": true,
529
+ "tts_tab": true,
530
+ "audioldm2": true,
531
+ "effects_tab": true,
532
+ "create_dataset_tab": true,
533
+ "training_tab": true,
534
+ "fushion_tab": true,
535
+ "read_tab": true,
536
+ "onnx_tab": true,
537
+ "downloads_tab": true,
538
+ "f0_extractor_tab": true,
539
+ "settings_tab": true,
540
+ "report_bug_tab": true,
541
+ "font": "https://fonts.googleapis.com/css2?family=Shadows+Into+Light&display=swap",
542
+ "app_port": 7860,
543
+ "tensorboard_port": 6870,
544
+ "num_of_restart": 5,
545
+ "server_name": "0.0.0.0",
546
+ "app_show_error": true
547
+ }
main/configs/config.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import torch
4
+
5
+
6
+ version_config_paths = [os.path.join(version, size) for version in ["v1", "v2"] for size in ["32000.json", "40000.json", "48000.json"]]
7
+
8
+ def singleton(cls):
9
+ instances = {}
10
+
11
+ def get_instance(*args, **kwargs):
12
+ if cls not in instances: instances[cls] = cls(*args, **kwargs)
13
+ return instances[cls]
14
+
15
+ return get_instance
16
+
17
+ @singleton
18
+ class Config:
19
+ def __init__(self):
20
+ self.device = "cuda:0" if torch.cuda.is_available() else "cpu"
21
+ self.configs = json.load(open(os.path.join("main", "configs", "config.json"), "r"))
22
+ self.translations = self.multi_language()
23
+ self.json_config = self.load_config_json()
24
+ self.gpu_mem = None
25
+ self.per_preprocess = 3.7
26
+ self.is_half = self.is_fp16()
27
+ self.x_pad, self.x_query, self.x_center, self.x_max = self.device_config()
28
+
29
+ def multi_language(self):
30
+ try:
31
+ lang = self.configs.get("language", "vi-VN")
32
+ if len([l for l in os.listdir(os.path.join("assets", "languages")) if l.endswith(".json")]) < 1: raise FileNotFoundError("Không tìm thấy bất cứ gói ngôn ngữ nào(No package languages found)")
33
+
34
+ if not lang: lang = "vi-VN"
35
+ if lang not in self.configs["support_language"]: raise ValueError("Ngôn ngữ không được hỗ trợ(Language not supported)")
36
+
37
+ lang_path = os.path.join("assets", "languages", f"{lang}.json")
38
+ if not os.path.exists(lang_path): lang_path = os.path.join("assets", "languages", "vi-VN.json")
39
+
40
+ with open(lang_path, encoding="utf-8") as f:
41
+ translations = json.load(f)
42
+ except json.JSONDecodeError:
43
+ print(self.translations["empty_json"].format(file=lang))
44
+ pass
45
+
46
+ return translations
47
+
48
+ def is_fp16(self):
49
+ fp16 = self.configs.get("fp16", False)
50
+
51
+ if self.device in ["cpu", "mps"] and fp16:
52
+ self.configs["fp16"] = False
53
+ fp16 = False
54
+
55
+ with open(os.path.join("main", "configs", "config.json"), "w") as f:
56
+ json.dump(self.configs, f, indent=4)
57
+
58
+ if not fp16: self.preprocess_per = 3.0
59
+ return fp16
60
+
61
+ def load_config_json(self):
62
+ configs = {}
63
+
64
+ for config_file in version_config_paths:
65
+ try:
66
+ with open(os.path.join("main", "configs", config_file), "r") as f:
67
+ configs[config_file] = json.load(f)
68
+ except json.JSONDecodeError:
69
+ print(self.translations["empty_json"].format(file=config_file))
70
+ pass
71
+
72
+ return configs
73
+
74
+ def device_config(self):
75
+ if self.device.startswith("cuda"): self.set_cuda_config()
76
+ elif self.has_mps(): self.device = "mps"
77
+ else: self.device = "cpu"
78
+
79
+ if self.gpu_mem is not None and self.gpu_mem <= 4:
80
+ self.preprocess_per = 3.0
81
+ return 1, 5, 30, 32
82
+
83
+ return (3, 10, 60, 65) if self.is_half else (1, 6, 38, 41)
84
+
85
+ def set_cuda_config(self):
86
+ i_device = int(self.device.split(":")[-1])
87
+ self.gpu_mem = torch.cuda.get_device_properties(i_device).total_memory // (1024**3)
88
+
89
+ def has_mps(self):
90
+ return torch.backends.mps.is_available()
main/configs/decrypt.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:330268cbf6b9317a76510b533e1640ef48ed074a07c013e5b1abc4d48cfd9dce
3
+ size 32
main/configs/v1/32000.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "train": {
3
+ "log_interval": 200,
4
+ "seed": 1234,
5
+ "epochs": 20000,
6
+ "learning_rate": 0.0001,
7
+ "betas": [0.8, 0.99],
8
+ "eps": 1e-09,
9
+ "batch_size": 4,
10
+ "lr_decay": 0.999875,
11
+ "segment_size": 12800,
12
+ "init_lr_ratio": 1,
13
+ "warmup_epochs": 0,
14
+ "c_mel": 45,
15
+ "c_kl": 1.0
16
+ },
17
+ "data": {
18
+ "max_wav_value": 32768.0,
19
+ "sample_rate": 32000,
20
+ "filter_length": 1024,
21
+ "hop_length": 320,
22
+ "win_length": 1024,
23
+ "n_mel_channels": 80,
24
+ "mel_fmin": 0.0,
25
+ "mel_fmax": null
26
+ },
27
+ "model": {
28
+ "inter_channels": 192,
29
+ "hidden_channels": 192,
30
+ "filter_channels": 768,
31
+ "text_enc_hidden_dim": 256,
32
+ "n_heads": 2,
33
+ "n_layers": 6,
34
+ "kernel_size": 3,
35
+ "p_dropout": 0,
36
+ "resblock": "1",
37
+ "resblock_kernel_sizes": [3, 7, 11],
38
+ "resblock_dilation_sizes": [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
39
+ "upsample_rates": [10, 4, 2, 2, 2],
40
+ "upsample_initial_channel": 512,
41
+ "upsample_kernel_sizes": [16, 16, 4, 4, 4],
42
+ "use_spectral_norm": false,
43
+ "gin_channels": 256,
44
+ "spk_embed_dim": 109
45
+ }
46
+ }
main/configs/v1/40000.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "train": {
3
+ "log_interval": 200,
4
+ "seed": 1234,
5
+ "epochs": 20000,
6
+ "learning_rate": 0.0001,
7
+ "betas": [0.8, 0.99],
8
+ "eps": 1e-09,
9
+ "batch_size": 4,
10
+ "lr_decay": 0.999875,
11
+ "segment_size": 12800,
12
+ "init_lr_ratio": 1,
13
+ "warmup_epochs": 0,
14
+ "c_mel": 45,
15
+ "c_kl": 1.0
16
+ },
17
+ "data": {
18
+ "max_wav_value": 32768.0,
19
+ "sample_rate": 40000,
20
+ "filter_length": 2048,
21
+ "hop_length": 400,
22
+ "win_length": 2048,
23
+ "n_mel_channels": 125,
24
+ "mel_fmin": 0.0,
25
+ "mel_fmax": null
26
+ },
27
+ "model": {
28
+ "inter_channels": 192,
29
+ "hidden_channels": 192,
30
+ "filter_channels": 768,
31
+ "text_enc_hidden_dim": 256,
32
+ "n_heads": 2,
33
+ "n_layers": 6,
34
+ "kernel_size": 3,
35
+ "p_dropout": 0,
36
+ "resblock": "1",
37
+ "resblock_kernel_sizes": [3, 7, 11],
38
+ "resblock_dilation_sizes": [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
39
+ "upsample_rates": [10, 10, 2, 2],
40
+ "upsample_initial_channel": 512,
41
+ "upsample_kernel_sizes": [16, 16, 4, 4],
42
+ "use_spectral_norm": false,
43
+ "gin_channels": 256,
44
+ "spk_embed_dim": 109
45
+ }
46
+ }
main/configs/v1/48000.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "train": {
3
+ "log_interval": 200,
4
+ "seed": 1234,
5
+ "epochs": 20000,
6
+ "learning_rate": 0.0001,
7
+ "betas": [0.8, 0.99],
8
+ "eps": 1e-09,
9
+ "batch_size": 4,
10
+ "lr_decay": 0.999875,
11
+ "segment_size": 11520,
12
+ "init_lr_ratio": 1,
13
+ "warmup_epochs": 0,
14
+ "c_mel": 45,
15
+ "c_kl": 1.0
16
+ },
17
+ "data": {
18
+ "max_wav_value": 32768.0,
19
+ "sample_rate": 48000,
20
+ "filter_length": 2048,
21
+ "hop_length": 480,
22
+ "win_length": 2048,
23
+ "n_mel_channels": 128,
24
+ "mel_fmin": 0.0,
25
+ "mel_fmax": null
26
+ },
27
+ "model": {
28
+ "inter_channels": 192,
29
+ "hidden_channels": 192,
30
+ "filter_channels": 768,
31
+ "text_enc_hidden_dim": 256,
32
+ "n_heads": 2,
33
+ "n_layers": 6,
34
+ "kernel_size": 3,
35
+ "p_dropout": 0,
36
+ "resblock": "1",
37
+ "resblock_kernel_sizes": [3, 7, 11],
38
+ "resblock_dilation_sizes": [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
39
+ "upsample_rates": [10, 6, 2, 2, 2],
40
+ "upsample_initial_channel": 512,
41
+ "upsample_kernel_sizes": [16, 16, 4, 4, 4],
42
+ "use_spectral_norm": false,
43
+ "gin_channels": 256,
44
+ "spk_embed_dim": 109
45
+ }
46
+ }
main/configs/v2/32000.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "train": {
3
+ "log_interval": 200,
4
+ "seed": 1234,
5
+ "learning_rate": 0.0001,
6
+ "betas": [0.8, 0.99],
7
+ "eps": 1e-09,
8
+ "lr_decay": 0.999875,
9
+ "segment_size": 12800,
10
+ "c_mel": 45,
11
+ "c_kl": 1.0
12
+ },
13
+ "data": {
14
+ "max_wav_value": 32768.0,
15
+ "sample_rate": 32000,
16
+ "filter_length": 1024,
17
+ "hop_length": 320,
18
+ "win_length": 1024,
19
+ "n_mel_channels": 80,
20
+ "mel_fmin": 0.0,
21
+ "mel_fmax": null
22
+ },
23
+ "model": {
24
+ "inter_channels": 192,
25
+ "hidden_channels": 192,
26
+ "filter_channels": 768,
27
+ "text_enc_hidden_dim": 768,
28
+ "n_heads": 2,
29
+ "n_layers": 6,
30
+ "kernel_size": 3,
31
+ "p_dropout": 0,
32
+ "resblock": "1",
33
+ "resblock_kernel_sizes": [3, 7, 11],
34
+ "resblock_dilation_sizes": [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
35
+ "upsample_rates": [10, 8, 2, 2],
36
+ "upsample_initial_channel": 512,
37
+ "upsample_kernel_sizes": [20, 16, 4, 4],
38
+ "use_spectral_norm": false,
39
+ "gin_channels": 256,
40
+ "spk_embed_dim": 109
41
+ }
42
+ }
main/configs/v2/40000.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "train": {
3
+ "log_interval": 200,
4
+ "seed": 1234,
5
+ "learning_rate": 0.0001,
6
+ "betas": [0.8, 0.99],
7
+ "eps": 1e-09,
8
+ "lr_decay": 0.999875,
9
+ "segment_size": 12800,
10
+ "c_mel": 45,
11
+ "c_kl": 1.0
12
+ },
13
+ "data": {
14
+ "max_wav_value": 32768.0,
15
+ "sample_rate": 40000,
16
+ "filter_length": 2048,
17
+ "hop_length": 400,
18
+ "win_length": 2048,
19
+ "n_mel_channels": 125,
20
+ "mel_fmin": 0.0,
21
+ "mel_fmax": null
22
+ },
23
+ "model": {
24
+ "inter_channels": 192,
25
+ "hidden_channels": 192,
26
+ "filter_channels": 768,
27
+ "text_enc_hidden_dim": 768,
28
+ "n_heads": 2,
29
+ "n_layers": 6,
30
+ "kernel_size": 3,
31
+ "p_dropout": 0,
32
+ "resblock": "1",
33
+ "resblock_kernel_sizes": [3, 7, 11],
34
+ "resblock_dilation_sizes": [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
35
+ "upsample_rates": [10, 10, 2, 2],
36
+ "upsample_initial_channel": 512,
37
+ "upsample_kernel_sizes": [16, 16, 4, 4],
38
+ "use_spectral_norm": false,
39
+ "gin_channels": 256,
40
+ "spk_embed_dim": 109
41
+ }
42
+ }
main/configs/v2/48000.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "train": {
3
+ "log_interval": 200,
4
+ "seed": 1234,
5
+ "learning_rate": 0.0001,
6
+ "betas": [0.8, 0.99],
7
+ "eps": 1e-09,
8
+ "lr_decay": 0.999875,
9
+ "segment_size": 17280,
10
+ "c_mel": 45,
11
+ "c_kl": 1.0
12
+ },
13
+ "data": {
14
+ "max_wav_value": 32768.0,
15
+ "sample_rate": 48000,
16
+ "filter_length": 2048,
17
+ "hop_length": 480,
18
+ "win_length": 2048,
19
+ "n_mel_channels": 128,
20
+ "mel_fmin": 0.0,
21
+ "mel_fmax": null
22
+ },
23
+ "model": {
24
+ "inter_channels": 192,
25
+ "hidden_channels": 192,
26
+ "filter_channels": 768,
27
+ "text_enc_hidden_dim": 768,
28
+ "n_heads": 2,
29
+ "n_layers": 6,
30
+ "kernel_size": 3,
31
+ "p_dropout": 0,
32
+ "resblock": "1",
33
+ "resblock_kernel_sizes": [3, 7, 11],
34
+ "resblock_dilation_sizes": [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
35
+ "upsample_rates": [12, 10, 2, 2],
36
+ "upsample_initial_channel": 512,
37
+ "upsample_kernel_sizes": [24, 20, 4, 4],
38
+ "use_spectral_norm": false,
39
+ "gin_channels": 256,
40
+ "spk_embed_dim": 109
41
+ }
42
+ }
main/inference/audio_effects.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import librosa
4
+ import argparse
5
+
6
+ import numpy as np
7
+ import soundfile as sf
8
+
9
+ from distutils.util import strtobool
10
+ from scipy.signal import butter, filtfilt
11
+ from pedalboard import Pedalboard, Chorus, Distortion, Reverb, PitchShift, Delay, Limiter, Gain, Bitcrush, Clipping, Compressor, Phaser, HighpassFilter
12
+
13
+ sys.path.append(os.getcwd())
14
+
15
+ from main.configs.config import Config
16
+ from main.library.utils import pydub_convert, pydub_load
17
+
18
+ translations = Config().translations
19
+
20
+ def parse_arguments():
21
+ parser = argparse.ArgumentParser()
22
+ parser.add_argument("--input_path", type=str, required=True)
23
+ parser.add_argument("--output_path", type=str, default="./audios/apply_effects.wav")
24
+ parser.add_argument("--export_format", type=str, default="wav")
25
+ parser.add_argument("--resample", type=lambda x: bool(strtobool(x)), default=False)
26
+ parser.add_argument("--resample_sr", type=int, default=0)
27
+ parser.add_argument("--chorus", type=lambda x: bool(strtobool(x)), default=False)
28
+ parser.add_argument("--chorus_depth", type=float, default=0.5)
29
+ parser.add_argument("--chorus_rate", type=float, default=1.5)
30
+ parser.add_argument("--chorus_mix", type=float, default=0.5)
31
+ parser.add_argument("--chorus_delay", type=int, default=10)
32
+ parser.add_argument("--chorus_feedback", type=float, default=0)
33
+ parser.add_argument("--distortion", type=lambda x: bool(strtobool(x)), default=False)
34
+ parser.add_argument("--drive_db", type=int, default=20)
35
+ parser.add_argument("--reverb", type=lambda x: bool(strtobool(x)), default=False)
36
+ parser.add_argument("--reverb_room_size", type=float, default=0.5)
37
+ parser.add_argument("--reverb_damping", type=float, default=0.5)
38
+ parser.add_argument("--reverb_wet_level", type=float, default=0.33)
39
+ parser.add_argument("--reverb_dry_level", type=float, default=0.67)
40
+ parser.add_argument("--reverb_width", type=float, default=1)
41
+ parser.add_argument("--reverb_freeze_mode", type=lambda x: bool(strtobool(x)), default=False)
42
+ parser.add_argument("--pitchshift", type=lambda x: bool(strtobool(x)), default=False)
43
+ parser.add_argument("--pitch_shift", type=int, default=0)
44
+ parser.add_argument("--delay", type=lambda x: bool(strtobool(x)), default=False)
45
+ parser.add_argument("--delay_seconds", type=float, default=0.5)
46
+ parser.add_argument("--delay_feedback", type=float, default=0.5)
47
+ parser.add_argument("--delay_mix", type=float, default=0.5)
48
+ parser.add_argument("--compressor", type=lambda x: bool(strtobool(x)), default=False)
49
+ parser.add_argument("--compressor_threshold", type=int, default=-20)
50
+ parser.add_argument("--compressor_ratio", type=float, default=4)
51
+ parser.add_argument("--compressor_attack_ms", type=float, default=10)
52
+ parser.add_argument("--compressor_release_ms", type=int, default=200)
53
+ parser.add_argument("--limiter", type=lambda x: bool(strtobool(x)), default=False)
54
+ parser.add_argument("--limiter_threshold", type=int, default=0)
55
+ parser.add_argument("--limiter_release", type=int, default=100)
56
+ parser.add_argument("--gain", type=lambda x: bool(strtobool(x)), default=False)
57
+ parser.add_argument("--gain_db", type=int, default=0)
58
+ parser.add_argument("--bitcrush", type=lambda x: bool(strtobool(x)), default=False)
59
+ parser.add_argument("--bitcrush_bit_depth", type=int, default=16)
60
+ parser.add_argument("--clipping", type=lambda x: bool(strtobool(x)), default=False)
61
+ parser.add_argument("--clipping_threshold", type=int, default=-10)
62
+ parser.add_argument("--phaser", type=lambda x: bool(strtobool(x)), default=False)
63
+ parser.add_argument("--phaser_rate_hz", type=float, default=0.5)
64
+ parser.add_argument("--phaser_depth", type=float, default=0.5)
65
+ parser.add_argument("--phaser_centre_frequency_hz", type=int, default=1000)
66
+ parser.add_argument("--phaser_feedback", type=float, default=0)
67
+ parser.add_argument("--phaser_mix", type=float, default=0.5)
68
+ parser.add_argument("--treble_bass_boost", type=lambda x: bool(strtobool(x)), default=False)
69
+ parser.add_argument("--bass_boost_db", type=int, default=0)
70
+ parser.add_argument("--bass_boost_frequency", type=int, default=100)
71
+ parser.add_argument("--treble_boost_db", type=int, default=0)
72
+ parser.add_argument("--treble_boost_frequency", type=int, default=3000)
73
+ parser.add_argument("--fade_in_out", type=lambda x: bool(strtobool(x)), default=False)
74
+ parser.add_argument("--fade_in_duration", type=float, default=2000)
75
+ parser.add_argument("--fade_out_duration", type=float, default=2000)
76
+ parser.add_argument("--audio_combination", type=lambda x: bool(strtobool(x)), default=False)
77
+ parser.add_argument("--audio_combination_input", type=str)
78
+
79
+ return parser.parse_args()
80
+
81
+ def process_audio(input_path, output_path, resample, resample_sr, chorus_depth, chorus_rate, chorus_mix, chorus_delay, chorus_feedback, distortion_drive, reverb_room_size, reverb_damping, reverb_wet_level, reverb_dry_level, reverb_width, reverb_freeze_mode, pitch_shift, delay_seconds, delay_feedback, delay_mix, compressor_threshold, compressor_ratio, compressor_attack_ms, compressor_release_ms, limiter_threshold, limiter_release, gain_db, bitcrush_bit_depth, clipping_threshold, phaser_rate_hz, phaser_depth, phaser_centre_frequency_hz, phaser_feedback, phaser_mix, bass_boost_db, bass_boost_frequency, treble_boost_db, treble_boost_frequency, fade_in_duration, fade_out_duration, export_format, chorus, distortion, reverb, pitchshift, delay, compressor, limiter, gain, bitcrush, clipping, phaser, treble_bass_boost, fade_in_out, audio_combination, audio_combination_input):
82
+ def bass_boost(audio, gain_db, frequency, sample_rate):
83
+ if gain_db >= 1:
84
+ b, a = butter(4, frequency / (0.5 * sample_rate), btype='low')
85
+
86
+ return filtfilt(b, a, audio) * 10 ** (gain_db / 20)
87
+ else: return audio
88
+
89
+ def treble_boost(audio, gain_db, frequency, sample_rate):
90
+ if gain_db >=1:
91
+ b, a = butter(4, frequency / (0.5 * sample_rate), btype='high')
92
+
93
+ return filtfilt(b, a, audio) * 10 ** (gain_db / 20)
94
+ else: return audio
95
+
96
+ def fade_out_effect(audio, sr, duration=3.0):
97
+ length = int(duration * sr)
98
+ end = audio.shape[0]
99
+
100
+ if length > end: length = end
101
+ start = end - length
102
+
103
+ audio[start:end] = audio[start:end] * np.linspace(1.0, 0.0, length)
104
+ return audio
105
+
106
+ def fade_in_effect(audio, sr, duration=3.0):
107
+ length = int(duration * sr)
108
+ start = 0
109
+
110
+ if length > audio.shape[0]: length = audio.shape[0]
111
+ end = length
112
+
113
+ audio[start:end] = audio[start:end] * np.linspace(0.0, 1.0, length)
114
+ return audio
115
+
116
+ if not input_path or not os.path.exists(input_path):
117
+ print(translations["input_not_valid"])
118
+ sys.exit(1)
119
+
120
+ if not output_path:
121
+ print(translations["output_not_valid"])
122
+ sys.exit(1)
123
+
124
+ if os.path.exists(output_path): os.remove(output_path)
125
+
126
+ try:
127
+ input_path = input_path.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
128
+
129
+ try:
130
+ audio, sample_rate = sf.read(input_path, dtype=np.float32)
131
+ except:
132
+ audio, sample_rate = librosa.load(input_path, sr=None)
133
+ except Exception as e:
134
+ raise RuntimeError(f"{translations['errors_loading_audio']}: {e}")
135
+
136
+ audio = audio.flatten()
137
+
138
+ try:
139
+ board = Pedalboard([HighpassFilter()])
140
+
141
+ if chorus: board.append(Chorus(depth=chorus_depth, rate_hz=chorus_rate, mix=chorus_mix, centre_delay_ms=chorus_delay, feedback=chorus_feedback))
142
+ if distortion: board.append(Distortion(drive_db=distortion_drive))
143
+ if reverb: board.append(Reverb(room_size=reverb_room_size, damping=reverb_damping, wet_level=reverb_wet_level, dry_level=reverb_dry_level, width=reverb_width, freeze_mode=1 if reverb_freeze_mode else 0))
144
+ if pitchshift: board.append(PitchShift(semitones=pitch_shift))
145
+ if delay: board.append(Delay(delay_seconds=delay_seconds, feedback=delay_feedback, mix=delay_mix))
146
+ if compressor: board.append(Compressor(threshold_db=compressor_threshold, ratio=compressor_ratio, attack_ms=compressor_attack_ms, release_ms=compressor_release_ms))
147
+ if limiter: board.append(Limiter(threshold_db=limiter_threshold, release_ms=limiter_release))
148
+ if gain: board.append(Gain(gain_db=gain_db))
149
+ if bitcrush: board.append(Bitcrush(bit_depth=bitcrush_bit_depth))
150
+ if clipping: board.append(Clipping(threshold_db=clipping_threshold))
151
+ if phaser: board.append(Phaser(rate_hz=phaser_rate_hz, depth=phaser_depth, centre_frequency_hz=phaser_centre_frequency_hz, feedback=phaser_feedback, mix=phaser_mix))
152
+
153
+ processed_audio = board(audio, sample_rate)
154
+
155
+ if treble_bass_boost:
156
+ processed_audio = bass_boost(processed_audio, bass_boost_db, bass_boost_frequency, sample_rate)
157
+ processed_audio = treble_boost(processed_audio, treble_boost_db, treble_boost_frequency, sample_rate)
158
+
159
+ if fade_in_out:
160
+ processed_audio = fade_in_effect(processed_audio, sample_rate, fade_in_duration)
161
+ processed_audio = fade_out_effect(processed_audio, sample_rate, fade_out_duration)
162
+
163
+ if resample_sr != sample_rate and resample_sr > 0 and resample:
164
+ target_sr = min([8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 96000], key=lambda x: abs(x - resample_sr))
165
+ processed_audio = librosa.resample(processed_audio, orig_sr=sample_rate, target_sr=target_sr, res_type="soxr_vhq")
166
+ sample_rate = target_sr
167
+
168
+ sf.write(output_path.replace("wav", export_format), processed_audio, sample_rate, format=export_format)
169
+
170
+ if audio_combination: pydub_convert(pydub_load(audio_combination_input)).overlay(pydub_convert(pydub_load(output_path.replace("wav", export_format)))).export(output_path.replace("wav", export_format), format=export_format)
171
+ except Exception as e:
172
+ raise RuntimeError(translations["apply_error"].format(e=e))
173
+
174
+ return output_path
175
+
176
+ def main():
177
+ args = parse_arguments()
178
+ process_audio(input_path=args.input_path, output_path=args.output_path, resample=args.resample, resample_sr=args.resample_sr, chorus_depth=args.chorus_depth, chorus_rate=args.chorus_rate, chorus_mix=args.chorus_mix, chorus_delay=args.chorus_delay, chorus_feedback=args.chorus_feedback, distortion_drive=args.drive_db, reverb_room_size=args.reverb_room_size, reverb_damping=args.reverb_damping, reverb_wet_level=args.reverb_wet_level, reverb_dry_level=args.reverb_dry_level, reverb_width=args.reverb_width, reverb_freeze_mode=args.reverb_freeze_mode, pitch_shift=args.pitch_shift, delay_seconds=args.delay_seconds, delay_feedback=args.delay_feedback, delay_mix=args.delay_mix, compressor_threshold=args.compressor_threshold, compressor_ratio=args.compressor_ratio, compressor_attack_ms=args.compressor_attack_ms, compressor_release_ms=args.compressor_release_ms, limiter_threshold=args.limiter_threshold, limiter_release=args.limiter_release, gain_db=args.gain_db, bitcrush_bit_depth=args.bitcrush_bit_depth, clipping_threshold=args.clipping_threshold, phaser_rate_hz=args.phaser_rate_hz, phaser_depth=args.phaser_depth, phaser_centre_frequency_hz=args.phaser_centre_frequency_hz, phaser_feedback=args.phaser_feedback, phaser_mix=args.phaser_mix, bass_boost_db=args.bass_boost_db, bass_boost_frequency=args.bass_boost_frequency, treble_boost_db=args.treble_boost_db, treble_boost_frequency=args.treble_boost_frequency, fade_in_duration=args.fade_in_duration, fade_out_duration=args.fade_out_duration, export_format=args.export_format, chorus=args.chorus, distortion=args.distortion, reverb=args.reverb, pitchshift=args.pitchshift, delay=args.delay, compressor=args.compressor, limiter=args.limiter, gain=args.gain, bitcrush=args.bitcrush, clipping=args.clipping, phaser=args.phaser, treble_bass_boost=args.treble_bass_boost, fade_in_out=args.fade_in_out, audio_combination=args.audio_combination, audio_combination_input=args.audio_combination_input)
179
+
180
+ if __name__ == "__main__": main()
main/inference/audioldm2.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import time
4
+ import tqdm
5
+ import torch
6
+ import logging
7
+ import librosa
8
+ import argparse
9
+ import scipy.signal
10
+ import logging.handlers
11
+
12
+ import numpy as np
13
+ import soundfile as sf
14
+
15
+ from torch import inference_mode
16
+ from distutils.util import strtobool
17
+
18
+ sys.path.append(os.getcwd())
19
+
20
+ from main.configs.config import Config
21
+ from main.library.audioldm2.utils import load_audio
22
+ from main.library.audioldm2.models import load_model
23
+
24
+ config = Config()
25
+ translations = config.translations
26
+ logger = logging.getLogger(__name__)
27
+ logger.propagate = False
28
+
29
+ for l in ["torch", "httpx", "httpcore", "diffusers", "transformers"]:
30
+ logging.getLogger(l).setLevel(logging.ERROR)
31
+
32
+ if logger.hasHandlers(): logger.handlers.clear()
33
+ else:
34
+ console_handler = logging.StreamHandler()
35
+ console_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
36
+ console_handler.setFormatter(console_formatter)
37
+ console_handler.setLevel(logging.INFO)
38
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join("assets", "logs", "audioldm2.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
39
+ file_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
40
+ file_handler.setFormatter(file_formatter)
41
+ file_handler.setLevel(logging.DEBUG)
42
+ logger.addHandler(console_handler)
43
+ logger.addHandler(file_handler)
44
+ logger.setLevel(logging.DEBUG)
45
+
46
+ def parse_arguments():
47
+ parser = argparse.ArgumentParser()
48
+ parser.add_argument("--input_path", type=str, required=True)
49
+ parser.add_argument("--output_path", type=str, default="./output.wav")
50
+ parser.add_argument("--export_format", type=str, default="wav")
51
+ parser.add_argument("--sample_rate", type=int, default=44100)
52
+ parser.add_argument("--audioldm_model", type=str, default="audioldm2-music")
53
+ parser.add_argument("--source_prompt", type=str, default="")
54
+ parser.add_argument("--target_prompt", type=str, default="")
55
+ parser.add_argument("--steps", type=int, default=200)
56
+ parser.add_argument("--cfg_scale_src", type=float, default=3.5)
57
+ parser.add_argument("--cfg_scale_tar", type=float, default=12)
58
+ parser.add_argument("--t_start", type=int, default=45)
59
+ parser.add_argument("--save_compute", type=lambda x: bool(strtobool(x)), default=False)
60
+
61
+ return parser.parse_args()
62
+
63
+ def main():
64
+ args = parse_arguments()
65
+ input_path, output_path, export_format, sample_rate, audioldm_model, source_prompt, target_prompt, steps, cfg_scale_src, cfg_scale_tar, t_start, save_compute = args.input_path, args.output_path, args.export_format, args.sample_rate, args.audioldm_model, args.source_prompt, args.target_prompt, args.steps, args.cfg_scale_src, args.cfg_scale_tar, args.t_start, args.save_compute
66
+
67
+ log_data = {translations['audio_path']: input_path, translations['output_path']: output_path.replace('wav', export_format), translations['model_name']: audioldm_model, translations['export_format']: export_format, translations['sample_rate']: sample_rate, translations['steps']: steps, translations['source_prompt']: source_prompt, translations['target_prompt']: target_prompt, translations['cfg_scale_src']: cfg_scale_src, translations['cfg_scale_tar']: cfg_scale_tar, translations['t_start']: t_start, translations['save_compute']: save_compute}
68
+
69
+ for key, value in log_data.items():
70
+ logger.debug(f"{key}: {value}")
71
+
72
+ start_time = time.time()
73
+ logger.info(translations["start_edit"].format(input_path=input_path))
74
+ pid_path = os.path.join("assets", "audioldm2_pid.txt")
75
+ with open(pid_path, "w") as pid_file:
76
+ pid_file.write(str(os.getpid()))
77
+
78
+ try:
79
+ edit(input_path, output_path, audioldm_model, source_prompt, target_prompt, steps, cfg_scale_src, cfg_scale_tar, t_start, save_compute, sample_rate, config.device, export_format=export_format)
80
+ except Exception as e:
81
+ logger.error(translations["error_edit"].format(e=e))
82
+ import traceback
83
+ logger.debug(traceback.format_exc())
84
+
85
+ logger.info(translations["edit_success"].format(time=f"{(time.time() - start_time):.2f}", output_path=output_path.replace('wav', export_format)))
86
+
87
+ def invert(ldm_stable, x0, prompt_src, num_diffusion_steps, cfg_scale_src, duration, save_compute):
88
+ with inference_mode():
89
+ w0 = ldm_stable.vae_encode(x0)
90
+
91
+ _, zs, wts, extra_info = inversion_forward_process(ldm_stable, w0, etas=1, prompts=[prompt_src], cfg_scales=[cfg_scale_src], num_inference_steps=num_diffusion_steps, numerical_fix=True, duration=duration, save_compute=save_compute)
92
+ return zs, wts, extra_info
93
+
94
+ def low_pass_filter(audio, cutoff=7500, sr=16000):
95
+ b, a = scipy.signal.butter(4, cutoff / (sr / 2), btype='low')
96
+ return scipy.signal.filtfilt(b, a, audio)
97
+
98
+ def sample(output_audio, sr, ldm_stable, zs, wts, extra_info, prompt_tar, tstart, cfg_scale_tar, duration, save_compute, export_format = "wav"):
99
+ tstart = torch.tensor(tstart, dtype=torch.int32)
100
+ w0, _ = inversion_reverse_process(ldm_stable, xT=wts, tstart=tstart, etas=1., prompts=[prompt_tar], neg_prompts=[""], cfg_scales=[cfg_scale_tar], zs=zs[:int(tstart)], duration=duration, extra_info=extra_info, save_compute=save_compute)
101
+
102
+ with inference_mode():
103
+ x0_dec = ldm_stable.vae_decode(w0.to(torch.float16 if config.is_half else torch.float32))
104
+
105
+ if x0_dec.dim() < 4: x0_dec = x0_dec[None, :, :, :]
106
+
107
+ with torch.no_grad():
108
+ audio = ldm_stable.decode_to_mel(x0_dec.to(torch.float16 if config.is_half else torch.float32))
109
+
110
+ audio = audio.float().squeeze().cpu().numpy()
111
+ orig_sr = 16000
112
+
113
+ if sr != 16000 and sr > 0:
114
+ audio = librosa.resample(audio, orig_sr=orig_sr, target_sr=sr, res_type="soxr_vhq")
115
+ orig_sr = sr
116
+
117
+ audio = low_pass_filter(audio, 7500, orig_sr)
118
+
119
+ sf.write(output_audio, np.tile(audio, (2, 1)).T, orig_sr, format=export_format)
120
+ return output_audio
121
+
122
+ def edit(input_audio, output_audio, model_id, source_prompt = "", target_prompt = "", steps = 200, cfg_scale_src = 3.5, cfg_scale_tar = 12, t_start = 45, save_compute = True, sr = 44100, device = "cpu", export_format = "wav"):
123
+ ldm_stable = load_model(model_id, device=device)
124
+ ldm_stable.model.scheduler.set_timesteps(steps, device=device)
125
+ x0, duration = load_audio(input_audio, ldm_stable.get_melspectrogram(), device=device)
126
+ zs_tensor, wts_tensor, extra_info_list = invert(ldm_stable=ldm_stable, x0=x0, prompt_src=source_prompt, num_diffusion_steps=steps, cfg_scale_src=cfg_scale_src, duration=duration, save_compute=save_compute)
127
+
128
+ return sample(output_audio, sr, ldm_stable, zs_tensor, wts_tensor, extra_info_list, prompt_tar=target_prompt, tstart=int(t_start / 100 * steps), cfg_scale_tar=cfg_scale_tar, duration=duration, save_compute=save_compute, export_format=export_format)
129
+
130
+ def inversion_forward_process(model, x0, etas = None, prompts = [""], cfg_scales = [3.5], num_inference_steps = 50, numerical_fix = False, duration = None, first_order = False, save_compute = True):
131
+ if len(prompts) > 1 or prompts[0] != "":
132
+ text_embeddings_hidden_states, text_embeddings_class_labels, text_embeddings_boolean_prompt_mask = model.encode_text(prompts)
133
+ uncond_embeddings_hidden_states, uncond_embeddings_class_lables, uncond_boolean_prompt_mask = model.encode_text([""], negative=True, save_compute=save_compute, cond_length=text_embeddings_class_labels.shape[1] if text_embeddings_class_labels is not None else None)
134
+ else: uncond_embeddings_hidden_states, uncond_embeddings_class_lables, uncond_boolean_prompt_mask = model.encode_text([""], negative=True, save_compute=False)
135
+
136
+ timesteps = model.model.scheduler.timesteps.to(model.device)
137
+ variance_noise_shape = model.get_noise_shape(x0, num_inference_steps)
138
+
139
+ if type(etas) in [int, float]: etas = [etas]*model.model.scheduler.num_inference_steps
140
+
141
+ xts = model.sample_xts_from_x0(x0, num_inference_steps=num_inference_steps)
142
+ zs = torch.zeros(size=variance_noise_shape, device=model.device)
143
+ extra_info = [None] * len(zs)
144
+
145
+ if timesteps[0].dtype == torch.int64: t_to_idx = {int(v): k for k, v in enumerate(timesteps)}
146
+ elif timesteps[0].dtype == torch.float32: t_to_idx = {float(v): k for k, v in enumerate(timesteps)}
147
+
148
+ xt = x0
149
+ model.setup_extra_inputs(xt, init_timestep=timesteps[0], audio_end_in_s=duration, save_compute=save_compute and prompts[0] != "")
150
+
151
+ for t in tqdm.tqdm(timesteps, desc=translations["inverting"], ncols=100, unit="a"):
152
+ idx = num_inference_steps - t_to_idx[int(t) if timesteps[0].dtype == torch.int64 else float(t)] - 1
153
+ xt = xts[idx + 1][None]
154
+ xt_inp = model.model.scheduler.scale_model_input(xt, t).to(torch.float16 if config.is_half else torch.float32)
155
+
156
+ with torch.no_grad():
157
+ if save_compute and prompts[0] != "":
158
+ comb_out, _, _ = model.unet_forward(xt_inp.expand(2, -1, -1, -1) if hasattr(model.model, 'unet') else xt_inp.expand(2, -1, -1), timestep=t, encoder_hidden_states=torch.cat([uncond_embeddings_hidden_states, text_embeddings_hidden_states], dim=0) if uncond_embeddings_hidden_states is not None else None, class_labels=torch.cat([uncond_embeddings_class_lables, text_embeddings_class_labels], dim=0) if uncond_embeddings_class_lables is not None else None, encoder_attention_mask=torch.cat([uncond_boolean_prompt_mask, text_embeddings_boolean_prompt_mask], dim=0) if uncond_boolean_prompt_mask is not None else None)
159
+ out, cond_out = comb_out.sample.chunk(2, dim=0)
160
+ else:
161
+ out = model.unet_forward(xt_inp, timestep=t, encoder_hidden_states=uncond_embeddings_hidden_states, class_labels=uncond_embeddings_class_lables, encoder_attention_mask=uncond_boolean_prompt_mask)[0].sample
162
+ if len(prompts) > 1 or prompts[0] != "": cond_out = model.unet_forward(xt_inp, timestep=t, encoder_hidden_states=text_embeddings_hidden_states, class_labels=text_embeddings_class_labels, encoder_attention_mask=text_embeddings_boolean_prompt_mask)[0].sample
163
+
164
+ if len(prompts) > 1 or prompts[0] != "": noise_pred = out + (cfg_scales[0] * (cond_out - out)).sum(axis=0).unsqueeze(0)
165
+ else: noise_pred = out
166
+
167
+ xtm1 = xts[idx][None]
168
+ z, xtm1, extra = model.get_zs_from_xts(xt, xtm1, noise_pred, t, eta=etas[idx], numerical_fix=numerical_fix, first_order=first_order)
169
+ zs[idx] = z
170
+ xts[idx] = xtm1
171
+ extra_info[idx] = extra
172
+
173
+ if zs is not None: zs[0] = torch.zeros_like(zs[0])
174
+ return xt, zs, xts, extra_info
175
+
176
+ def inversion_reverse_process(model, xT, tstart, etas = 0, prompts = [""], neg_prompts = [""], cfg_scales = None, zs = None, duration = None, first_order = False, extra_info = None, save_compute = True):
177
+ text_embeddings_hidden_states, text_embeddings_class_labels, text_embeddings_boolean_prompt_mask = model.encode_text(prompts)
178
+ uncond_embeddings_hidden_states, uncond_embeddings_class_lables, uncond_boolean_prompt_mask = model.encode_text(neg_prompts, negative=True, save_compute=save_compute, cond_length=text_embeddings_class_labels.shape[1] if text_embeddings_class_labels is not None else None)
179
+ xt = xT[tstart.max()].unsqueeze(0)
180
+
181
+ if etas is None: etas = 0
182
+ if type(etas) in [int, float]: etas = [etas]*model.model.scheduler.num_inference_steps
183
+
184
+ assert len(etas) == model.model.scheduler.num_inference_steps
185
+ timesteps = model.model.scheduler.timesteps.to(model.device)
186
+
187
+ if timesteps[0].dtype == torch.int64: t_to_idx = {int(v): k for k, v in enumerate(timesteps[-zs.shape[0]:])}
188
+ elif timesteps[0].dtype == torch.float32: t_to_idx = {float(v): k for k, v in enumerate(timesteps[-zs.shape[0]:])}
189
+
190
+ model.setup_extra_inputs(xt, extra_info=extra_info, init_timestep=timesteps[-zs.shape[0]], audio_end_in_s=duration, save_compute=save_compute)
191
+
192
+ for t in tqdm.tqdm(timesteps[-zs.shape[0]:], desc=translations["editing"], ncols=100, unit="a"):
193
+ idx = model.model.scheduler.num_inference_steps - t_to_idx[int(t) if timesteps[0].dtype == torch.int64 else float(t)] - (model.model.scheduler.num_inference_steps - zs.shape[0] + 1)
194
+ xt_inp = model.model.scheduler.scale_model_input(xt, t).to(torch.float16 if config.is_half else torch.float32)
195
+
196
+ with torch.no_grad():
197
+ if save_compute:
198
+ comb_out, _, _ = model.unet_forward(xt_inp.expand(2, -1, -1, -1) if hasattr(model.model, 'unet') else xt_inp.expand(2, -1, -1), timestep=t, encoder_hidden_states=torch.cat([uncond_embeddings_hidden_states, text_embeddings_hidden_states], dim=0) if uncond_embeddings_hidden_states is not None else None, class_labels=torch.cat([uncond_embeddings_class_lables, text_embeddings_class_labels], dim=0) if uncond_embeddings_class_lables is not None else None, encoder_attention_mask=torch.cat([uncond_boolean_prompt_mask, text_embeddings_boolean_prompt_mask], dim=0) if uncond_boolean_prompt_mask is not None else None)
199
+ uncond_out, cond_out = comb_out.sample.chunk(2, dim=0)
200
+ else:
201
+ uncond_out = model.unet_forward(xt_inp, timestep=t, encoder_hidden_states=uncond_embeddings_hidden_states, class_labels=uncond_embeddings_class_lables, encoder_attention_mask=uncond_boolean_prompt_mask)[0].sample
202
+ cond_out = model.unet_forward(xt_inp, timestep=t, encoder_hidden_states=text_embeddings_hidden_states, class_labels=text_embeddings_class_labels, encoder_attention_mask=text_embeddings_boolean_prompt_mask)[0].sample
203
+
204
+ z = zs[idx] if zs is not None else None
205
+ noise_pred = uncond_out + (cfg_scales[0] * (cond_out - uncond_out)).sum(axis=0).unsqueeze(0)
206
+ xt = model.reverse_step_with_custom_noise(noise_pred, t, xt, variance_noise=z.unsqueeze(0), eta=etas[idx], first_order=first_order)
207
+
208
+ return xt, zs
209
+
210
+ if __name__ == "__main__": main()
main/inference/convert.py ADDED
@@ -0,0 +1,590 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import os
3
+ import gc
4
+ import sys
5
+ import time
6
+ import faiss
7
+ import torch
8
+ import librosa
9
+ import logging
10
+ import argparse
11
+ import warnings
12
+ import onnxruntime
13
+ import logging.handlers
14
+
15
+ import numpy as np
16
+ import soundfile as sf
17
+ import torch.nn.functional as F
18
+
19
+ from tqdm import tqdm
20
+ from scipy import signal
21
+ from distutils.util import strtobool
22
+
23
+ warnings.filterwarnings("ignore")
24
+ sys.path.append(os.getcwd())
25
+
26
+ from main.configs.config import Config
27
+ from main.library.algorithm.synthesizers import Synthesizer
28
+ from main.library.utils import check_predictors, check_embedders, load_audio, load_embedders_model, cut, restore
29
+
30
+ bh, ah = signal.butter(N=5, Wn=48, btype="high", fs=16000)
31
+ config = Config()
32
+ translations = config.translations
33
+ logger = logging.getLogger(__name__)
34
+ logger.propagate = False
35
+
36
+ for l in ["torch", "faiss", "httpx", "fairseq", "httpcore", "faiss.loader", "numba.core", "urllib3", "transformers", "matplotlib"]:
37
+ logging.getLogger(l).setLevel(logging.ERROR)
38
+
39
+ if logger.hasHandlers(): logger.handlers.clear()
40
+ else:
41
+ console_handler = logging.StreamHandler()
42
+ console_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
43
+ console_handler.setFormatter(console_formatter)
44
+ console_handler.setLevel(logging.INFO)
45
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join("assets", "logs", "convert.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
46
+ file_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
47
+ file_handler.setFormatter(file_formatter)
48
+ file_handler.setLevel(logging.DEBUG)
49
+ logger.addHandler(console_handler)
50
+ logger.addHandler(file_handler)
51
+ logger.setLevel(logging.DEBUG)
52
+
53
+ def parse_arguments():
54
+ parser = argparse.ArgumentParser()
55
+ parser.add_argument("--pitch", type=int, default=0)
56
+ parser.add_argument("--filter_radius", type=int, default=3)
57
+ parser.add_argument("--index_rate", type=float, default=0.5)
58
+ parser.add_argument("--volume_envelope", type=float, default=1)
59
+ parser.add_argument("--protect", type=float, default=0.33)
60
+ parser.add_argument("--hop_length", type=int, default=64)
61
+ parser.add_argument("--f0_method", type=str, default="rmvpe")
62
+ parser.add_argument("--embedder_model", type=str, default="contentvec_base")
63
+ parser.add_argument("--input_path", type=str, required=True)
64
+ parser.add_argument("--output_path", type=str, default="./audios/output.wav")
65
+ parser.add_argument("--export_format", type=str, default="wav")
66
+ parser.add_argument("--pth_path", type=str, required=True)
67
+ parser.add_argument("--index_path", type=str)
68
+ parser.add_argument("--f0_autotune", type=lambda x: bool(strtobool(x)), default=False)
69
+ parser.add_argument("--f0_autotune_strength", type=float, default=1)
70
+ parser.add_argument("--clean_audio", type=lambda x: bool(strtobool(x)), default=False)
71
+ parser.add_argument("--clean_strength", type=float, default=0.7)
72
+ parser.add_argument("--resample_sr", type=int, default=0)
73
+ parser.add_argument("--split_audio", type=lambda x: bool(strtobool(x)), default=False)
74
+ parser.add_argument("--checkpointing", type=lambda x: bool(strtobool(x)), default=False)
75
+ parser.add_argument("--f0_file", type=str, default="")
76
+ parser.add_argument("--f0_onnx", type=lambda x: bool(strtobool(x)), default=False)
77
+ parser.add_argument("--embedders_mode", type=str, default="fairseq")
78
+ parser.add_argument("--formant_shifting", type=lambda x: bool(strtobool(x)), default=False)
79
+ parser.add_argument("--formant_qfrency", type=float, default=0.8)
80
+ parser.add_argument("--formant_timbre", type=float, default=0.8)
81
+
82
+ return parser.parse_args()
83
+
84
+ def main():
85
+ args = parse_arguments()
86
+ pitch, filter_radius, index_rate, volume_envelope, protect, hop_length, f0_method, input_path, output_path, pth_path, index_path, f0_autotune, f0_autotune_strength, clean_audio, clean_strength, export_format, embedder_model, resample_sr, split_audio, checkpointing, f0_file, f0_onnx, embedders_mode, formant_shifting, formant_qfrency, formant_timbre = args.pitch, args.filter_radius, args.index_rate, args.volume_envelope,args.protect, args.hop_length, args.f0_method, args.input_path, args.output_path, args.pth_path, args.index_path, args.f0_autotune, args.f0_autotune_strength, args.clean_audio, args.clean_strength, args.export_format, args.embedder_model, args.resample_sr, args.split_audio, args.checkpointing, args.f0_file, args.f0_onnx, args.embedders_mode, args.formant_shifting, args.formant_qfrency, args.formant_timbre
87
+
88
+ log_data = {translations['pitch']: pitch, translations['filter_radius']: filter_radius, translations['index_strength']: index_rate, translations['volume_envelope']: volume_envelope, translations['protect']: protect, "Hop length": hop_length, translations['f0_method']: f0_method, translations['audio_path']: input_path, translations['output_path']: output_path.replace('wav', export_format), translations['model_path']: pth_path, translations['indexpath']: index_path, translations['autotune']: f0_autotune, translations['clear_audio']: clean_audio, translations['export_format']: export_format, translations['hubert_model']: embedder_model, translations['split_audio']: split_audio, translations['memory_efficient_training']: checkpointing, translations["f0_onnx_mode"]: f0_onnx, translations["embed_mode"]: embedders_mode}
89
+
90
+ if clean_audio: log_data[translations['clean_strength']] = clean_strength
91
+ if resample_sr != 0: log_data[translations['sample_rate']] = resample_sr
92
+
93
+ if f0_autotune: log_data[translations['autotune_rate_info']] = f0_autotune_strength
94
+ if os.path.isfile(f0_file): log_data[translations['f0_file']] = f0_file
95
+
96
+ if formant_shifting:
97
+ log_data[translations['formant_qfrency']] = formant_qfrency
98
+ log_data[translations['formant_timbre']] = formant_timbre
99
+
100
+ for key, value in log_data.items():
101
+ logger.debug(f"{key}: {value}")
102
+
103
+ run_convert_script(pitch=pitch, filter_radius=filter_radius, index_rate=index_rate, volume_envelope=volume_envelope, protect=protect, hop_length=hop_length, f0_method=f0_method, input_path=input_path, output_path=output_path, pth_path=pth_path, index_path=index_path, f0_autotune=f0_autotune, f0_autotune_strength=f0_autotune_strength, clean_audio=clean_audio, clean_strength=clean_strength, export_format=export_format, embedder_model=embedder_model, resample_sr=resample_sr, split_audio=split_audio, checkpointing=checkpointing, f0_file=f0_file, f0_onnx=f0_onnx, embedders_mode=embedders_mode, formant_shifting=formant_shifting, formant_qfrency=formant_qfrency, formant_timbre=formant_timbre)
104
+
105
+ def run_convert_script(pitch=0, filter_radius=3, index_rate=0.5, volume_envelope=1, protect=0.5, hop_length=64, f0_method="rmvpe", input_path=None, output_path="./output.wav", pth_path=None, index_path=None, f0_autotune=False, f0_autotune_strength=1, clean_audio=False, clean_strength=0.7, export_format="wav", embedder_model="contentvec_base", resample_sr=0, split_audio=False, checkpointing=False, f0_file=None, f0_onnx=False, embedders_mode="fairseq", formant_shifting=False, formant_qfrency=0.8, formant_timbre=0.8):
106
+ check_predictors(f0_method, f0_onnx); check_embedders(embedder_model, embedders_mode)
107
+
108
+ if not pth_path or not os.path.exists(pth_path) or os.path.isdir(pth_path) or not pth_path.endswith((".pth", ".onnx")):
109
+ logger.warning(translations["provide_file"].format(filename=translations["model"]))
110
+ sys.exit(1)
111
+
112
+ cvt = VoiceConverter(pth_path, 0)
113
+ start_time = time.time()
114
+
115
+ pid_path = os.path.join("assets", "convert_pid.txt")
116
+ with open(pid_path, "w") as pid_file:
117
+ pid_file.write(str(os.getpid()))
118
+
119
+ if os.path.isdir(input_path):
120
+ logger.info(translations["convert_batch"])
121
+ audio_files = [f for f in os.listdir(input_path) if f.lower().endswith(("wav", "mp3", "flac", "ogg", "opus", "m4a", "mp4", "aac", "alac", "wma", "aiff", "webm", "ac3"))]
122
+
123
+ if not audio_files:
124
+ logger.warning(translations["not_found_audio"])
125
+ sys.exit(1)
126
+
127
+ logger.info(translations["found_audio"].format(audio_files=len(audio_files)))
128
+
129
+ for audio in audio_files:
130
+ audio_path = os.path.join(input_path, audio)
131
+ output_audio = os.path.join(input_path, os.path.splitext(audio)[0] + f"_output.{export_format}")
132
+
133
+ logger.info(f"{translations['convert_audio']} '{audio_path}'...")
134
+ if os.path.exists(output_audio): os.remove(output_audio)
135
+ cvt.convert_audio(pitch=pitch, filter_radius=filter_radius, index_rate=index_rate, volume_envelope=volume_envelope, protect=protect, hop_length=hop_length, f0_method=f0_method, audio_input_path=audio_path, audio_output_path=output_audio, index_path=index_path, f0_autotune=f0_autotune, f0_autotune_strength=f0_autotune_strength, clean_audio=clean_audio, clean_strength=clean_strength, export_format=export_format, embedder_model=embedder_model, resample_sr=resample_sr, checkpointing=checkpointing, f0_file=f0_file, f0_onnx=f0_onnx, embedders_mode=embedders_mode, formant_shifting=formant_shifting, formant_qfrency=formant_qfrency, formant_timbre=formant_timbre, split_audio=split_audio)
136
+
137
+ logger.info(translations["convert_batch_success"].format(elapsed_time=f"{(time.time() - start_time):.2f}", output_path=output_path.replace('wav', export_format)))
138
+ else:
139
+ if not os.path.exists(input_path):
140
+ logger.warning(translations["not_found_audio"])
141
+ sys.exit(1)
142
+
143
+ logger.info(f"{translations['convert_audio']} '{input_path}'...")
144
+ if os.path.exists(output_path): os.remove(output_path)
145
+ cvt.convert_audio(pitch=pitch, filter_radius=filter_radius, index_rate=index_rate, volume_envelope=volume_envelope, protect=protect, hop_length=hop_length, f0_method=f0_method, audio_input_path=input_path, audio_output_path=output_path, index_path=index_path, f0_autotune=f0_autotune, f0_autotune_strength=f0_autotune_strength, clean_audio=clean_audio, clean_strength=clean_strength, export_format=export_format, embedder_model=embedder_model, resample_sr=resample_sr, checkpointing=checkpointing, f0_file=f0_file, f0_onnx=f0_onnx, embedders_mode=embedders_mode, formant_shifting=formant_shifting, formant_qfrency=formant_qfrency, formant_timbre=formant_timbre, split_audio=split_audio)
146
+
147
+ if os.path.exists(pid_path): os.remove(pid_path)
148
+ logger.info(translations["convert_audio_success"].format(input_path=input_path, elapsed_time=f"{(time.time() - start_time):.2f}", output_path=output_path.replace('wav', export_format)))
149
+
150
+ def change_rms(source_audio, source_rate, target_audio, target_rate, rate):
151
+ rms2 = F.interpolate(torch.from_numpy(librosa.feature.rms(y=target_audio, frame_length=target_rate // 2 * 2, hop_length=target_rate // 2)).float().unsqueeze(0), size=target_audio.shape[0], mode="linear").squeeze()
152
+ return (target_audio * (torch.pow(F.interpolate(torch.from_numpy(librosa.feature.rms(y=source_audio, frame_length=source_rate // 2 * 2, hop_length=source_rate // 2)).float().unsqueeze(0), size=target_audio.shape[0], mode="linear").squeeze(), 1 - rate) * torch.pow(torch.maximum(rms2, torch.zeros_like(rms2) + 1e-6), rate - 1)).numpy())
153
+
154
+ def clear_gpu_cache():
155
+ gc.collect()
156
+ if torch.cuda.is_available(): torch.cuda.empty_cache()
157
+ elif torch.backends.mps.is_available(): torch.mps.empty_cache()
158
+
159
+ def get_providers():
160
+ ort_providers = onnxruntime.get_available_providers()
161
+
162
+ if "CUDAExecutionProvider" in ort_providers: providers = ["CUDAExecutionProvider"]
163
+ elif "CoreMLExecutionProvider" in ort_providers: providers = ["CoreMLExecutionProvider"]
164
+ else: providers = ["CPUExecutionProvider"]
165
+
166
+ return providers
167
+
168
+ class Autotune:
169
+ def __init__(self, ref_freqs):
170
+ self.ref_freqs = ref_freqs
171
+ self.note_dict = self.ref_freqs
172
+
173
+ def autotune_f0(self, f0, f0_autotune_strength):
174
+ autotuned_f0 = np.zeros_like(f0)
175
+
176
+ for i, freq in enumerate(f0):
177
+ autotuned_f0[i] = freq + (min(self.note_dict, key=lambda x: abs(x - freq)) - freq) * f0_autotune_strength
178
+
179
+ return autotuned_f0
180
+
181
+ class VC:
182
+ def __init__(self, tgt_sr, config):
183
+ self.x_pad = config.x_pad
184
+ self.x_query = config.x_query
185
+ self.x_center = config.x_center
186
+ self.x_max = config.x_max
187
+ self.sample_rate = 16000
188
+ self.window = 160
189
+ self.t_pad = self.sample_rate * self.x_pad
190
+ self.t_pad_tgt = tgt_sr * self.x_pad
191
+ self.t_pad2 = self.t_pad * 2
192
+ self.t_query = self.sample_rate * self.x_query
193
+ self.t_center = self.sample_rate * self.x_center
194
+ self.t_max = self.sample_rate * self.x_max
195
+ self.time_step = self.window / self.sample_rate * 1000
196
+ self.f0_min = 50
197
+ self.f0_max = 1100
198
+ self.f0_mel_min = 1127 * np.log(1 + self.f0_min / 700)
199
+ self.f0_mel_max = 1127 * np.log(1 + self.f0_max / 700)
200
+ self.device = config.device
201
+ self.is_half = config.is_half
202
+ self.ref_freqs = [49.00, 51.91, 55.00, 58.27, 61.74, 65.41, 69.30, 73.42, 77.78, 82.41, 87.31, 92.50, 98.00, 103.83, 110.00, 116.54, 123.47, 130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185.00, 196.00, 207.65, 220.00, 233.08, 246.94, 261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88, 523.25, 554.37, 587.33, 622.25, 659.25, 698.46, 739.99, 783.99, 830.61, 880.00, 932.33, 987.77, 1046.50]
203
+ self.autotune = Autotune(self.ref_freqs)
204
+ self.note_dict = self.autotune.note_dict
205
+
206
+ def get_f0_pm(self, x, p_len):
207
+ import parselmouth
208
+
209
+ f0 = (parselmouth.Sound(x, self.sample_rate).to_pitch_ac(time_step=self.window / self.sample_rate * 1000 / 1000, voicing_threshold=0.6, pitch_floor=self.f0_min, pitch_ceiling=self.f0_max).selected_array["frequency"])
210
+ pad_size = (p_len - len(f0) + 1) // 2
211
+
212
+ if pad_size > 0 or p_len - len(f0) - pad_size > 0: f0 = np.pad(f0, [[pad_size, p_len - len(f0) - pad_size]], mode="constant")
213
+ return f0
214
+
215
+ def get_f0_mangio_crepe(self, x, p_len, hop_length, model="full", onnx=False):
216
+ from main.library.predictors.CREPE import predict
217
+
218
+ x = x.astype(np.float32)
219
+ x /= np.quantile(np.abs(x), 0.999)
220
+
221
+ audio = torch.unsqueeze(torch.from_numpy(x).to(self.device, copy=True), dim=0)
222
+ if audio.ndim == 2 and audio.shape[0] > 1: audio = torch.mean(audio, dim=0, keepdim=True).detach()
223
+
224
+ p_len = p_len or x.shape[0] // hop_length
225
+ source = np.array(predict(audio.detach(), self.sample_rate, hop_length, self.f0_min, self.f0_max, model, batch_size=hop_length * 2, device=self.device, pad=True, providers=get_providers(), onnx=onnx).squeeze(0).cpu().float().numpy())
226
+ source[source < 0.001] = np.nan
227
+
228
+ return np.nan_to_num(np.interp(np.arange(0, len(source) * p_len, len(source)) / p_len, np.arange(0, len(source)), source))
229
+
230
+ def get_f0_crepe(self, x, model="full", onnx=False):
231
+ from main.library.predictors.CREPE import predict, mean, median
232
+
233
+ f0, pd = predict(torch.tensor(np.copy(x))[None].float(), self.sample_rate, self.window, self.f0_min, self.f0_max, model, batch_size=512, device=self.device, return_periodicity=True, providers=get_providers(), onnx=onnx)
234
+ f0, pd = mean(f0, 3), median(pd, 3)
235
+ f0[pd < 0.1] = 0
236
+
237
+ return f0[0].cpu().numpy()
238
+
239
+ def get_f0_fcpe(self, x, p_len, hop_length, onnx=False, legacy=False):
240
+ from main.library.predictors.FCPE import FCPE
241
+
242
+ model_fcpe = FCPE(os.path.join("assets", "models", "predictors", ("fcpe_legacy" if legacy else "fcpe") + (".onnx" if onnx else ".pt")), hop_length=int(hop_length), f0_min=int(self.f0_min), f0_max=int(self.f0_max), dtype=torch.float32, device=self.device, sample_rate=self.sample_rate, threshold=0.03 if legacy else 0.006, providers=get_providers(), onnx=onnx, legacy=legacy)
243
+ f0 = model_fcpe.compute_f0(x, p_len=p_len)
244
+
245
+ del model_fcpe
246
+ return f0
247
+
248
+ def get_f0_rmvpe(self, x, legacy=False, onnx=False):
249
+ from main.library.predictors.RMVPE import RMVPE
250
+
251
+ rmvpe_model = RMVPE(os.path.join("assets", "models", "predictors", "rmvpe" + (".onnx" if onnx else ".pt")), is_half=self.is_half, device=self.device, onnx=onnx, providers=get_providers())
252
+ f0 = rmvpe_model.infer_from_audio_with_pitch(x, thred=0.03, f0_min=self.f0_min, f0_max=self.f0_max) if legacy else rmvpe_model.infer_from_audio(x, thred=0.03)
253
+
254
+ del rmvpe_model
255
+ return f0
256
+
257
+ def get_f0_pyworld(self, x, filter_radius, model="harvest"):
258
+ from main.library.predictors.WORLD_WRAPPER import PYWORLD
259
+
260
+ pw = PYWORLD()
261
+ x = x.astype(np.double)
262
+
263
+ if model == "harvest": f0, t = pw.harvest(x, fs=self.sample_rate, f0_ceil=self.f0_max, f0_floor=self.f0_min, frame_period=10)
264
+ elif model == "dio": f0, t = pw.dio(x, fs=self.sample_rate, f0_ceil=self.f0_max, f0_floor=self.f0_min, frame_period=10)
265
+ else: raise ValueError(translations["method_not_valid"])
266
+
267
+ f0 = pw.stonemask(x, self.sample_rate, t, f0)
268
+
269
+ if filter_radius > 2 or model == "dio": f0 = signal.medfilt(f0, filter_radius)
270
+ return f0
271
+
272
+ def get_f0_swipe(self, x):
273
+ from main.library.predictors.SWIPE import swipe
274
+
275
+ f0, _ = swipe(x.astype(np.float32), self.sample_rate, f0_floor=self.f0_min, f0_ceil=self.f0_max, frame_period=10)
276
+ return f0
277
+
278
+ def get_f0_yin(self, x, hop_length, p_len, mode="yin"):
279
+ source = np.array(librosa.yin(x.astype(np.float32), sr=self.sample_rate, fmin=self.f0_min, fmax=self.f0_max, hop_length=hop_length) if mode == "yin" else librosa.pyin(x.astype(np.float32), fmin=self.f0_min, fmax=self.f0_max, sr=self.sample_rate, hop_length=hop_length)[0])
280
+ source[source < 0.001] = np.nan
281
+ return np.nan_to_num(np.interp(np.arange(0, len(source) * p_len, len(source)) / p_len, np.arange(0, len(source)), source))
282
+
283
+ def get_f0_hybrid(self, methods_str, x, p_len, hop_length, filter_radius, onnx_mode):
284
+ methods_str = re.search("hybrid\[(.+)\]", methods_str)
285
+ if methods_str: methods = [method.strip() for method in methods_str.group(1).split("+")]
286
+
287
+ f0_computation_stack, resampled_stack = [], []
288
+ logger.debug(translations["hybrid_methods"].format(methods=methods))
289
+
290
+ x = x.astype(np.float32)
291
+ x /= np.quantile(np.abs(x), 0.999)
292
+
293
+ for method in methods:
294
+ f0 = None
295
+ f0_methods = {"pm": lambda: self.get_f0_pm(x, p_len), "dio": lambda: self.get_f0_pyworld(x, filter_radius, "dio"), "mangio-crepe-tiny": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "tiny", onnx=onnx_mode), "mangio-crepe-small": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "small", onnx=onnx_mode), "mangio-crepe-medium": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "medium", onnx=onnx_mode), "mangio-crepe-large": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "large", onnx=onnx_mode), "mangio-crepe-full": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "full", onnx=onnx_mode), "crepe-tiny": lambda: self.get_f0_crepe(x, "tiny", onnx=onnx_mode), "crepe-small": lambda: self.get_f0_crepe(x, "small", onnx=onnx_mode), "crepe-medium": lambda: self.get_f0_crepe(x, "medium", onnx=onnx_mode), "crepe-large": lambda: self.get_f0_crepe(x, "large", onnx=onnx_mode), "crepe-full": lambda: self.get_f0_crepe(x, "full", onnx=onnx_mode), "fcpe": lambda: self.get_f0_fcpe(x, p_len, int(hop_length), onnx=onnx_mode), "fcpe-legacy": lambda: self.get_f0_fcpe(x, p_len, int(hop_length), legacy=True, onnx=onnx_mode), "rmvpe": lambda: self.get_f0_rmvpe(x, onnx=onnx_mode), "rmvpe-legacy": lambda: self.get_f0_rmvpe(x, legacy=True, onnx=onnx_mode), "harvest": lambda: self.get_f0_pyworld(x, filter_radius, "harvest"), "yin": lambda: self.get_f0_yin(x, int(hop_length), p_len, mode="yin"), "pyin": lambda: self.get_f0_yin(x, int(hop_length), p_len, mode="pyin"), "swipe": lambda: self.get_f0_swipe(x)}
296
+ f0 = f0_methods.get(method, lambda: ValueError(translations["method_not_valid"]))()
297
+ f0_computation_stack.append(f0)
298
+
299
+ for f0 in f0_computation_stack:
300
+ resampled_stack.append(np.interp(np.linspace(0, len(f0), p_len), np.arange(len(f0)), f0))
301
+
302
+ return resampled_stack[0] if len(resampled_stack) == 1 else np.nanmedian(np.vstack(resampled_stack), axis=0)
303
+
304
+ def get_f0(self, x, p_len, pitch, f0_method, filter_radius, hop_length, f0_autotune, f0_autotune_strength, inp_f0=None, onnx_mode=False):
305
+ f0_methods = {"pm": lambda: self.get_f0_pm(x, p_len), "dio": lambda: self.get_f0_pyworld(x, filter_radius, "dio"), "mangio-crepe-tiny": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "tiny", onnx=onnx_mode), "mangio-crepe-small": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "small", onnx=onnx_mode), "mangio-crepe-medium": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "medium", onnx=onnx_mode), "mangio-crepe-large": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "large", onnx=onnx_mode), "mangio-crepe-full": lambda: self.get_f0_mangio_crepe(x, p_len, int(hop_length), "full", onnx=onnx_mode), "crepe-tiny": lambda: self.get_f0_crepe(x, "tiny", onnx=onnx_mode), "crepe-small": lambda: self.get_f0_crepe(x, "small", onnx=onnx_mode), "crepe-medium": lambda: self.get_f0_crepe(x, "medium", onnx=onnx_mode), "crepe-large": lambda: self.get_f0_crepe(x, "large", onnx=onnx_mode), "crepe-full": lambda: self.get_f0_crepe(x, "full", onnx=onnx_mode), "fcpe": lambda: self.get_f0_fcpe(x, p_len, int(hop_length), onnx=onnx_mode), "fcpe-legacy": lambda: self.get_f0_fcpe(x, p_len, int(hop_length), legacy=True, onnx=onnx_mode), "rmvpe": lambda: self.get_f0_rmvpe(x, onnx=onnx_mode), "rmvpe-legacy": lambda: self.get_f0_rmvpe(x, legacy=True, onnx=onnx_mode), "harvest": lambda: self.get_f0_pyworld(x, filter_radius, "harvest"), "yin": lambda: self.get_f0_yin(x, int(hop_length), p_len, mode="yin"), "pyin": lambda: self.get_f0_yin(x, int(hop_length), p_len, mode="pyin"), "swipe": lambda: self.get_f0_swipe(x)}
306
+ f0 = self.get_f0_hybrid(f0_method, x, p_len, hop_length, filter_radius, onnx_mode) if "hybrid" in f0_method else f0_methods.get(f0_method, lambda: ValueError(translations["method_not_valid"]))()
307
+
308
+ if f0_autotune: f0 = Autotune.autotune_f0(self, f0, f0_autotune_strength)
309
+ if isinstance(f0, tuple): f0 = f0[0]
310
+
311
+ f0 *= pow(2, pitch / 12)
312
+ tf0 = self.sample_rate // self.window
313
+
314
+ if inp_f0 is not None:
315
+ replace_f0 = np.interp(list(range(np.round((inp_f0[:, 0].max() - inp_f0[:, 0].min()) * tf0 + 1).astype(np.int16))), inp_f0[:, 0] * 100, inp_f0[:, 1])
316
+ f0[self.x_pad * tf0 : self.x_pad * tf0 + len(replace_f0)] = replace_f0[:f0[self.x_pad * tf0 : self.x_pad * tf0 + len(replace_f0)].shape[0]]
317
+
318
+ f0_mel = 1127 * np.log(1 + f0 / 700)
319
+ f0_mel[f0_mel > 0] = (f0_mel[f0_mel > 0] - self.f0_mel_min) * 254 / (self.f0_mel_max - self.f0_mel_min) + 1
320
+ f0_mel[f0_mel <= 1] = 1
321
+ f0_mel[f0_mel > 255] = 255
322
+
323
+ return np.rint(f0_mel).astype(np.int32), f0.copy()
324
+
325
+ def extract_features(self, model, feats, version):
326
+ return torch.as_tensor(model.run([model.get_outputs()[0].name, model.get_outputs()[1].name], {"feats": feats.detach().cpu().numpy()})[0 if version == "v1" else 1], dtype=torch.float32, device=feats.device)
327
+
328
+ def voice_conversion(self, model, net_g, sid, audio0, pitch, pitchf, index, big_npy, index_rate, version, protect):
329
+ pitch_guidance = pitch != None and pitchf != None
330
+ feats = (torch.from_numpy(audio0).half() if self.is_half else torch.from_numpy(audio0).float())
331
+
332
+ if feats.dim() == 2: feats = feats.mean(-1)
333
+ assert feats.dim() == 1, feats.dim()
334
+ feats = feats.view(1, -1)
335
+
336
+ with torch.no_grad():
337
+ if self.embed_suffix == ".pt":
338
+ padding_mask = torch.BoolTensor(feats.shape).to(self.device).fill_(False)
339
+ logits = model.extract_features(**{"source": feats.to(self.device), "padding_mask": padding_mask, "output_layer": 9 if version == "v1" else 12})
340
+ feats = model.final_proj(logits[0]) if version == "v1" else logits[0]
341
+ elif self.embed_suffix == ".onnx": feats = self.extract_features(model, feats.to(self.device), version).to(self.device)
342
+ elif self.embed_suffix == ".safetensors":
343
+ logits = model(feats.to(self.device))["last_hidden_state"]
344
+ feats = (model.final_proj(logits[0]).unsqueeze(0) if version == "v1" else logits)
345
+ else: raise ValueError(translations["option_not_valid"])
346
+
347
+ if protect < 0.5 and pitch_guidance: feats0 = feats.clone()
348
+
349
+ if (not isinstance(index, type(None)) and not isinstance(big_npy, type(None)) and index_rate != 0):
350
+ npy = feats[0].cpu().numpy()
351
+ if self.is_half: npy = npy.astype(np.float32)
352
+
353
+ score, ix = index.search(npy, k=8)
354
+ weight = np.square(1 / score)
355
+
356
+ npy = np.sum(big_npy[ix] * np.expand_dims(weight / weight.sum(axis=1, keepdims=True), axis=2), axis=1)
357
+ if self.is_half: npy = npy.astype(np.float16)
358
+
359
+ feats = (torch.from_numpy(npy).unsqueeze(0).to(self.device) * index_rate + (1 - index_rate) * feats)
360
+
361
+ feats = F.interpolate(feats.permute(0, 2, 1), scale_factor=2).permute(0, 2, 1)
362
+ if protect < 0.5 and pitch_guidance: feats0 = F.interpolate(feats0.permute(0, 2, 1), scale_factor=2).permute(0, 2, 1)
363
+
364
+ p_len = audio0.shape[0] // self.window
365
+
366
+ if feats.shape[1] < p_len:
367
+ p_len = feats.shape[1]
368
+ if pitch_guidance:
369
+ pitch = pitch[:, :p_len]
370
+ pitchf = pitchf[:, :p_len]
371
+
372
+ if protect < 0.5 and pitch_guidance:
373
+ pitchff = pitchf.clone()
374
+ pitchff[pitchf > 0] = 1
375
+ pitchff[pitchf < 1] = protect
376
+ pitchff = pitchff.unsqueeze(-1)
377
+
378
+ feats = (feats * pitchff + feats0 * (1 - pitchff)).to(feats0.dtype)
379
+
380
+ p_len = torch.tensor([p_len], device=self.device).long()
381
+ audio1 = ((net_g.infer(feats.half() if self.is_half else feats.float(), p_len, pitch if pitch_guidance else None, (pitchf.half() if self.is_half else pitchf.float()) if pitch_guidance else None, sid)[0][0, 0]).data.cpu().float().numpy()) if self.suffix == ".pth" else (net_g.run([net_g.get_outputs()[0].name], ({net_g.get_inputs()[0].name: feats.cpu().numpy().astype(np.float32), net_g.get_inputs()[1].name: p_len.cpu().numpy(), net_g.get_inputs()[2].name: np.array([sid.cpu().item()], dtype=np.int64), net_g.get_inputs()[3].name: np.random.randn(1, 192, p_len).astype(np.float32), net_g.get_inputs()[4].name: pitch.cpu().numpy().astype(np.int64), net_g.get_inputs()[5].name: pitchf.cpu().numpy().astype(np.float32)} if pitch_guidance else {net_g.get_inputs()[0].name: feats.cpu().numpy().astype(np.float32), net_g.get_inputs()[1].name: p_len.cpu().numpy(), net_g.get_inputs()[2].name: np.array([sid.cpu().item()], dtype=np.int64), net_g.get_inputs()[3].name: np.random.randn(1, 192, p_len).astype(np.float32)}))[0][0, 0])
382
+
383
+ if self.embed_suffix == ".pt": del padding_mask
384
+ del feats, p_len, net_g
385
+ clear_gpu_cache()
386
+ return audio1
387
+
388
+ def pipeline(self, model, net_g, sid, audio, pitch, f0_method, file_index, index_rate, pitch_guidance, filter_radius, volume_envelope, version, protect, hop_length, f0_autotune, f0_autotune_strength, suffix, embed_suffix, f0_file=None, f0_onnx=False, pbar=None):
389
+ self.suffix = suffix
390
+ self.embed_suffix = embed_suffix
391
+
392
+ if file_index != "" and os.path.exists(file_index) and index_rate != 0:
393
+ try:
394
+ index = faiss.read_index(file_index)
395
+ big_npy = index.reconstruct_n(0, index.ntotal)
396
+ except Exception as e:
397
+ logger.error(translations["read_faiss_index_error"].format(e=e))
398
+ index = big_npy = None
399
+ else: index = big_npy = None
400
+
401
+ pbar.update(1)
402
+ opt_ts, audio_opt = [], []
403
+ audio = signal.filtfilt(bh, ah, audio)
404
+ audio_pad = np.pad(audio, (self.window // 2, self.window // 2), mode="reflect")
405
+
406
+ if audio_pad.shape[0] > self.t_max:
407
+ audio_sum = np.zeros_like(audio)
408
+ for i in range(self.window):
409
+ audio_sum += audio_pad[i : i - self.window]
410
+
411
+ for t in range(self.t_center, audio.shape[0], self.t_center):
412
+ opt_ts.append(t - self.t_query + np.where(np.abs(audio_sum[t - self.t_query : t + self.t_query]) == np.abs(audio_sum[t - self.t_query : t + self.t_query]).min())[0][0])
413
+
414
+ s = 0
415
+ t, inp_f0 = None, None
416
+ audio_pad = np.pad(audio, (self.t_pad, self.t_pad), mode="reflect")
417
+ sid = torch.tensor(sid, device=self.device).unsqueeze(0).long()
418
+ p_len = audio_pad.shape[0] // self.window
419
+
420
+ if hasattr(f0_file, "name"):
421
+ try:
422
+ with open(f0_file.name, "r") as f:
423
+ raw_lines = f.read()
424
+ if len(raw_lines) > 0:
425
+ inp_f0 = []
426
+ for line in raw_lines.strip("\n").split("\n"):
427
+ inp_f0.append([float(i) for i in line.split(",")])
428
+
429
+ inp_f0 = np.array(inp_f0, dtype=np.float32)
430
+ except:
431
+ logger.error(translations["error_readfile"])
432
+ inp_f0 = None
433
+
434
+ pbar.update(1)
435
+ if pitch_guidance:
436
+ pitch, pitchf = self.get_f0(audio_pad, p_len, pitch, f0_method, filter_radius, hop_length, f0_autotune, f0_autotune_strength, inp_f0, onnx_mode=f0_onnx)
437
+ pitch, pitchf = pitch[:p_len], pitchf[:p_len]
438
+ if self.device == "mps": pitchf = pitchf.astype(np.float32)
439
+ pitch, pitchf = torch.tensor(pitch, device=self.device).unsqueeze(0).long(), torch.tensor(pitchf, device=self.device).unsqueeze(0).float()
440
+
441
+ pbar.update(1)
442
+ for t in opt_ts:
443
+ t = t // self.window * self.window
444
+ audio_opt.append(self.voice_conversion(model, net_g, sid, audio_pad[s : t + self.t_pad2 + self.window], pitch[:, s // self.window : (t + self.t_pad2) // self.window] if pitch_guidance else None, pitchf[:, s // self.window : (t + self.t_pad2) // self.window] if pitch_guidance else None, index, big_npy, index_rate, version, protect)[self.t_pad_tgt : -self.t_pad_tgt])
445
+ s = t
446
+
447
+ audio_opt.append(self.voice_conversion(model, net_g, sid, audio_pad[t:], (pitch[:, t // self.window :] if t is not None else pitch) if pitch_guidance else None, (pitchf[:, t // self.window :] if t is not None else pitchf) if pitch_guidance else None, index, big_npy, index_rate, version, protect)[self.t_pad_tgt : -self.t_pad_tgt])
448
+ audio_opt = np.concatenate(audio_opt)
449
+ if volume_envelope != 1: audio_opt = change_rms(audio, self.sample_rate, audio_opt, self.sample_rate, volume_envelope)
450
+ audio_max = np.abs(audio_opt).max() / 0.99
451
+ if audio_max > 1: audio_opt /= audio_max
452
+
453
+ if pitch_guidance: del pitch, pitchf
454
+ del sid
455
+ clear_gpu_cache()
456
+ pbar.update(1)
457
+
458
+ return audio_opt
459
+
460
+ class VoiceConverter:
461
+ def __init__(self, model_path, sid = 0):
462
+ self.config = config
463
+ self.device = config.device
464
+ self.hubert_model = None
465
+ self.tgt_sr = None
466
+ self.net_g = None
467
+ self.vc = None
468
+ self.cpt = None
469
+ self.version = None
470
+ self.n_spk = None
471
+ self.use_f0 = None
472
+ self.loaded_model = None
473
+ self.vocoder = "Default"
474
+ self.checkpointing = False
475
+ self.sample_rate = 16000
476
+ self.sid = sid
477
+ self.get_vc(model_path, sid)
478
+
479
+ def convert_audio(self, audio_input_path, audio_output_path, index_path, embedder_model, pitch, f0_method, index_rate, volume_envelope, protect, hop_length, f0_autotune, f0_autotune_strength, filter_radius, clean_audio, clean_strength, export_format, resample_sr = 0, checkpointing = False, f0_file = None, f0_onnx = False, embedders_mode = "fairseq", formant_shifting = False, formant_qfrency = 0.8, formant_timbre = 0.8, split_audio = False):
480
+ try:
481
+ with tqdm(total=10, desc=translations["convert_audio"], ncols=100, unit="a") as pbar:
482
+ audio = load_audio(logger, audio_input_path, self.sample_rate, formant_shifting=formant_shifting, formant_qfrency=formant_qfrency, formant_timbre=formant_timbre)
483
+ self.checkpointing = checkpointing
484
+ audio_max = np.abs(audio).max() / 0.95
485
+ if audio_max > 1: audio /= audio_max
486
+
487
+ pbar.update(1)
488
+ if not self.hubert_model:
489
+ models, _, embed_suffix = load_embedders_model(embedder_model, embedders_mode, providers=get_providers())
490
+ self.hubert_model = (models.to(self.device).half() if self.config.is_half else models.to(self.device).float()).eval() if embed_suffix in [".pt", ".safetensors"] else models
491
+ self.embed_suffix = embed_suffix
492
+
493
+ pbar.update(1)
494
+ if self.tgt_sr != resample_sr >= self.sample_rate: self.tgt_sr = resample_sr
495
+ target_sr = min([8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 96000], key=lambda x: abs(x - self.tgt_sr))
496
+
497
+ if split_audio:
498
+ chunks = cut(audio, self.sample_rate, db_thresh=-60, min_interval=500)
499
+ pbar.total = len(chunks) * 4 + 6
500
+ logger.info(f"{translations['split_total']}: {len(chunks)}")
501
+ else: chunks = [(audio, 0, 0)]
502
+
503
+ converted_chunks = []
504
+ pbar.update(1)
505
+
506
+ for waveform, start, end in chunks:
507
+ converted_chunks.append((start, end, self.vc.pipeline(model=self.hubert_model, net_g=self.net_g, sid=self.sid, audio=waveform, pitch=pitch, f0_method=f0_method, file_index=(index_path.strip().strip('"').strip("\n").strip('"').strip().replace("trained", "added")), index_rate=index_rate, pitch_guidance=self.use_f0, filter_radius=filter_radius, volume_envelope=volume_envelope, version=self.version, protect=protect, hop_length=hop_length, f0_autotune=f0_autotune, f0_autotune_strength=f0_autotune_strength, suffix=self.suffix, embed_suffix=self.embed_suffix, f0_file=f0_file, f0_onnx=f0_onnx, pbar=pbar)))
508
+
509
+ pbar.update(1)
510
+ audio_output = restore(converted_chunks, total_len=len(audio), dtype=converted_chunks[0][2].dtype) if split_audio else converted_chunks[0][2]
511
+ if target_sr >= self.sample_rate and self.tgt_sr != target_sr: audio_output = librosa.resample(audio_output, orig_sr=self.tgt_sr, target_sr=target_sr, res_type="soxr_vhq")
512
+
513
+ pbar.update(1)
514
+ if clean_audio:
515
+ from main.tools.noisereduce import reduce_noise
516
+ audio_output = reduce_noise(y=audio_output, sr=target_sr, prop_decrease=clean_strength, device=self.device)
517
+
518
+ sf.write(audio_output_path, audio_output, target_sr, format=export_format)
519
+ pbar.update(1)
520
+ except Exception as e:
521
+ logger.error(translations["error_convert"].format(e=e))
522
+ import traceback
523
+ logger.debug(traceback.format_exc())
524
+
525
+ def get_vc(self, weight_root, sid):
526
+ if sid == "" or sid == []:
527
+ self.cleanup()
528
+ clear_gpu_cache()
529
+
530
+ if not self.loaded_model or self.loaded_model != weight_root:
531
+ self.loaded_model = weight_root
532
+ self.load_model()
533
+ if self.cpt is not None: self.setup()
534
+
535
+ def cleanup(self):
536
+ if self.hubert_model is not None:
537
+ del self.net_g, self.n_spk, self.vc, self.hubert_model, self.tgt_sr
538
+ self.hubert_model = self.net_g = self.n_spk = self.vc = self.tgt_sr = None
539
+ clear_gpu_cache()
540
+
541
+ del self.net_g, self.cpt
542
+ clear_gpu_cache()
543
+ self.cpt = None
544
+
545
+ def load_model(self):
546
+ if os.path.isfile(self.loaded_model):
547
+ if self.loaded_model.endswith(".pth"): self.cpt = torch.load(self.loaded_model, map_location="cpu")
548
+ else:
549
+ sess_options = onnxruntime.SessionOptions()
550
+ sess_options.log_severity_level = 3
551
+ self.cpt = onnxruntime.InferenceSession(self.loaded_model, sess_options=sess_options, providers=get_providers())
552
+ else: self.cpt = None
553
+
554
+ def setup(self):
555
+ if self.cpt is not None:
556
+ if self.loaded_model.endswith(".pth"):
557
+ self.tgt_sr = self.cpt["config"][-1]
558
+ self.cpt["config"][-3] = self.cpt["weight"]["emb_g.weight"].shape[0]
559
+ self.use_f0 = self.cpt.get("f0", 1)
560
+ self.version = self.cpt.get("version", "v1")
561
+ self.vocoder = self.cpt.get("vocoder", "Default")
562
+ if self.vocoder != "Default": self.config.is_half = False
563
+
564
+ self.net_g = Synthesizer(*self.cpt["config"], use_f0=self.use_f0, text_enc_hidden_dim=768 if self.version == "v2" else 256, vocoder=self.vocoder, checkpointing=self.checkpointing)
565
+ del self.net_g.enc_q
566
+
567
+ self.net_g.load_state_dict(self.cpt["weight"], strict=False)
568
+ self.net_g.eval().to(self.device)
569
+ self.net_g = (self.net_g.half() if self.config.is_half else self.net_g.float())
570
+ self.n_spk = self.cpt["config"][-3]
571
+ self.suffix = ".pth"
572
+ else:
573
+ import json
574
+ import onnx
575
+
576
+ metadata_dict = None
577
+ for prop in onnx.load(self.loaded_model).metadata_props:
578
+ if prop.key == "model_info":
579
+ metadata_dict = json.loads(prop.value)
580
+ break
581
+
582
+ self.net_g = self.cpt
583
+ self.tgt_sr = metadata_dict.get("sr", 32000)
584
+ self.use_f0 = metadata_dict.get("f0", 1)
585
+ self.version = metadata_dict.get("version", "v1")
586
+ self.suffix = ".onnx"
587
+
588
+ self.vc = VC(self.tgt_sr, self.config)
589
+
590
+ if __name__ == "__main__": main()
main/inference/create_dataset.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import time
4
+ import yt_dlp
5
+ import shutil
6
+ import librosa
7
+ import logging
8
+ import argparse
9
+ import warnings
10
+ import logging.handlers
11
+
12
+ from soundfile import read, write
13
+ from distutils.util import strtobool
14
+
15
+ sys.path.append(os.getcwd())
16
+
17
+ from main.configs.config import Config
18
+ from main.library.algorithm.separator import Separator
19
+
20
+ config = Config()
21
+ translations = config.translations
22
+ dataset_temp = os.path.join("dataset_temp")
23
+ logger = logging.getLogger(__name__)
24
+
25
+ if logger.hasHandlers(): logger.handlers.clear()
26
+ else:
27
+ console_handler = logging.StreamHandler()
28
+ console_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
29
+ console_handler.setFormatter(console_formatter)
30
+ console_handler.setLevel(logging.INFO)
31
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join("assets", "logs", "create_dataset.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
32
+ file_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
33
+ file_handler.setFormatter(file_formatter)
34
+ file_handler.setLevel(logging.DEBUG)
35
+ logger.addHandler(console_handler)
36
+ logger.addHandler(file_handler)
37
+ logger.setLevel(logging.DEBUG)
38
+
39
+ def parse_arguments():
40
+ parser = argparse.ArgumentParser()
41
+ parser.add_argument("--input_audio", type=str, required=True)
42
+ parser.add_argument("--output_dataset", type=str, default="./dataset")
43
+ parser.add_argument("--sample_rate", type=int, default=44100)
44
+ parser.add_argument("--clean_dataset", type=lambda x: bool(strtobool(x)), default=False)
45
+ parser.add_argument("--clean_strength", type=float, default=0.7)
46
+ parser.add_argument("--separator_reverb", type=lambda x: bool(strtobool(x)), default=False)
47
+ parser.add_argument("--kim_vocal_version", type=int, default=2)
48
+ parser.add_argument("--overlap", type=float, default=0.25)
49
+ parser.add_argument("--segments_size", type=int, default=256)
50
+ parser.add_argument("--mdx_hop_length", type=int, default=1024)
51
+ parser.add_argument("--mdx_batch_size", type=int, default=1)
52
+ parser.add_argument("--denoise_mdx", type=lambda x: bool(strtobool(x)), default=False)
53
+ parser.add_argument("--skip", type=lambda x: bool(strtobool(x)), default=False)
54
+ parser.add_argument("--skip_start_audios", type=str, default="0")
55
+ parser.add_argument("--skip_end_audios", type=str, default="0")
56
+
57
+ return parser.parse_args()
58
+
59
+ def main():
60
+ pid_path = os.path.join("assets", "create_dataset_pid.txt")
61
+ with open(pid_path, "w") as pid_file:
62
+ pid_file.write(str(os.getpid()))
63
+
64
+ args = parse_arguments()
65
+ input_audio, output_dataset, sample_rate, clean_dataset, clean_strength, separator_reverb, kim_vocal_version, overlap, segments_size, hop_length, batch_size, denoise_mdx, skip, skip_start_audios, skip_end_audios = args.input_audio, args.output_dataset, args.sample_rate, args.clean_dataset, args.clean_strength, args.separator_reverb, args.kim_vocal_version, args.overlap, args.segments_size, args.mdx_hop_length, args.mdx_batch_size, args.denoise_mdx, args.skip, args.skip_start_audios, args.skip_end_audios
66
+ log_data = {translations['audio_path']: input_audio, translations['output_path']: output_dataset, translations['sr']: sample_rate, translations['clear_dataset']: clean_dataset, translations['dereveb_audio']: separator_reverb, translations['segments_size']: segments_size, translations['overlap']: overlap, "Hop length": hop_length, translations['batch_size']: batch_size, translations['denoise_mdx']: denoise_mdx, translations['skip']: skip}
67
+
68
+ if clean_dataset: log_data[translations['clean_strength']] = clean_strength
69
+ if skip:
70
+ log_data[translations['skip_start']] = skip_start_audios
71
+ log_data[translations['skip_end']] = skip_end_audios
72
+
73
+ for key, value in log_data.items():
74
+ logger.debug(f"{key}: {value}")
75
+
76
+ if kim_vocal_version not in [1, 2]: raise ValueError(translations["version_not_valid"])
77
+ start_time = time.time()
78
+
79
+ try:
80
+ paths = []
81
+
82
+ if not os.path.exists(dataset_temp): os.makedirs(dataset_temp, exist_ok=True)
83
+ urls = input_audio.replace(", ", ",").split(",")
84
+
85
+ for url in urls:
86
+ path = downloader(url, urls.index(url))
87
+ paths.append(path)
88
+
89
+ if skip:
90
+ skip_start_audios, skip_end_audios = skip_start_audios.replace(", ", ",").split(","), skip_end_audios.replace(", ", ",").split(",")
91
+
92
+ if len(skip_start_audios) < len(paths) or len(skip_end_audios) < len(paths):
93
+ logger.warning(translations["skip<audio"])
94
+ sys.exit(1)
95
+ elif len(skip_start_audios) > len(paths) or len(skip_end_audios) > len(paths):
96
+ logger.warning(translations["skip>audio"])
97
+ sys.exit(1)
98
+ else:
99
+ for audio, skip_start_audio, skip_end_audio in zip(paths, skip_start_audios, skip_end_audios):
100
+ skip_start(audio, skip_start_audio)
101
+ skip_end(audio, skip_end_audio)
102
+
103
+ separator_paths = []
104
+
105
+ for audio in paths:
106
+ vocals = separator_music_main(audio, dataset_temp, segments_size, overlap, denoise_mdx, kim_vocal_version, hop_length, batch_size, sample_rate)
107
+ if separator_reverb: vocals = separator_reverb_audio(vocals, dataset_temp, segments_size, overlap, denoise_mdx, hop_length, batch_size, sample_rate)
108
+ separator_paths.append(vocals)
109
+
110
+ paths = separator_paths
111
+
112
+ for audio_path in paths:
113
+ data, sample_rate = read(audio_path)
114
+ data = librosa.to_mono(data.T)
115
+
116
+ if clean_dataset:
117
+ from main.tools.noisereduce import reduce_noise
118
+ data = reduce_noise(y=data, prop_decrease=clean_strength, device=config.device)
119
+
120
+ write(audio_path, data, sample_rate)
121
+ except Exception as e:
122
+ logger.error(f"{translations['create_dataset_error']}: {e}")
123
+ import traceback
124
+ logger.error(traceback.format_exc())
125
+ finally:
126
+ for audio in paths:
127
+ shutil.move(audio, output_dataset)
128
+
129
+ if os.path.exists(dataset_temp): shutil.rmtree(dataset_temp, ignore_errors=True)
130
+
131
+ elapsed_time = time.time() - start_time
132
+ if os.path.exists(pid_path): os.remove(pid_path)
133
+ logger.info(translations["create_dataset_success"].format(elapsed_time=f"{elapsed_time:.2f}"))
134
+
135
+ def downloader(url, name):
136
+ with warnings.catch_warnings():
137
+ warnings.simplefilter("ignore")
138
+
139
+ ydl_opts = {"format": "bestaudio/best", "outtmpl": os.path.join(dataset_temp, f"{name}"), "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "wav", "preferredquality": "192"}], "no_warnings": True, "noplaylist": True, "noplaylist": True, "verbose": False}
140
+ logger.info(f"{translations['starting_download']}: {url}...")
141
+
142
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
143
+ ydl.extract_info(url)
144
+ logger.info(f"{translations['download_success']}: {url}")
145
+
146
+ return os.path.join(dataset_temp, f"{name}" + ".wav")
147
+
148
+ def skip_start(input_file, seconds):
149
+ data, sr = read(input_file)
150
+ total_duration = len(data) / sr
151
+
152
+ if seconds <= 0: logger.warning(translations["=<0"])
153
+ elif seconds >= total_duration: logger.warning(translations["skip_warning"].format(seconds=seconds, total_duration=f"{total_duration:.2f}"))
154
+ else:
155
+ logger.info(f"{translations['skip_start']}: {input_file}...")
156
+ write(input_file, data[int(seconds * sr):], sr)
157
+
158
+ logger.info(translations["skip_start_audio"].format(input_file=input_file))
159
+
160
+ def skip_end(input_file, seconds):
161
+ data, sr = read(input_file)
162
+ total_duration = len(data) / sr
163
+
164
+ if seconds <= 0: logger.warning(translations["=<0"])
165
+ elif seconds > total_duration: logger.warning(translations["skip_warning"].format(seconds=seconds, total_duration=f"{total_duration:.2f}"))
166
+ else:
167
+ logger.info(f"{translations['skip_end']}: {input_file}...")
168
+ write(input_file, data[:-int(seconds * sr)], sr)
169
+
170
+ logger.info(translations["skip_end_audio"].format(input_file=input_file))
171
+
172
+ def separator_music_main(input, output, segments_size, overlap, denoise, version, hop_length, batch_size, sample_rate):
173
+ if not os.path.exists(input):
174
+ logger.warning(translations["input_not_valid"])
175
+ return None
176
+
177
+ if not os.path.exists(output):
178
+ logger.warning(translations["output_not_valid"])
179
+ return None
180
+
181
+ model = f"Kim_Vocal_{version}.onnx"
182
+ output_separator = separator_main(audio_file=input, model_filename=model, output_format="wav", output_dir=output, mdx_segment_size=segments_size, mdx_overlap=overlap, mdx_batch_size=batch_size, mdx_hop_length=hop_length, mdx_enable_denoise=denoise, sample_rate=sample_rate)
183
+
184
+ for f in output_separator:
185
+ path = os.path.join(output, f)
186
+ if not os.path.exists(path): logger.error(translations["not_found"].format(name=path))
187
+
188
+ if '_(Instrumental)_' in f: os.rename(path, os.path.splitext(path)[0].replace("(", "").replace(")", "") + ".wav")
189
+ elif '_(Vocals)_' in f:
190
+ rename_file = os.path.splitext(path)[0].replace("(", "").replace(")", "") + ".wav"
191
+ os.rename(path, rename_file)
192
+
193
+ return rename_file
194
+
195
+ def separator_reverb_audio(input, output, segments_size, overlap, denoise, hop_length, batch_size, sample_rate):
196
+ if not os.path.exists(input):
197
+ logger.warning(translations["input_not_valid"])
198
+ return None
199
+
200
+ if not os.path.exists(output):
201
+ logger.warning(translations["output_not_valid"])
202
+ return None
203
+
204
+ logger.info(f"{translations['dereverb']}: {input}...")
205
+ output_dereverb = separator_main(audio_file=input, model_filename="Reverb_HQ_By_FoxJoy.onnx", output_format="wav", output_dir=output, mdx_segment_size=segments_size, mdx_overlap=overlap, mdx_batch_size=hop_length, mdx_hop_length=batch_size, mdx_enable_denoise=denoise, sample_rate=sample_rate)
206
+
207
+ for f in output_dereverb:
208
+ path = os.path.join(output, f)
209
+ if not os.path.exists(path): logger.error(translations["not_found"].format(name=path))
210
+
211
+ if '_(Reverb)_' in f: os.rename(path, os.path.splitext(path)[0].replace("(", "").replace(")", "") + ".wav")
212
+ elif '_(No Reverb)_' in f:
213
+ rename_file = os.path.splitext(path)[0].replace("(", "").replace(")", "") + ".wav"
214
+ os.rename(path, rename_file)
215
+
216
+ logger.info(f"{translations['dereverb_success']}: {rename_file}")
217
+ return rename_file
218
+
219
+ def separator_main(audio_file=None, model_filename="Kim_Vocal_1.onnx", output_format="wav", output_dir=".", mdx_segment_size=256, mdx_overlap=0.25, mdx_batch_size=1, mdx_hop_length=1024, mdx_enable_denoise=True, sample_rate=44100):
220
+ try:
221
+ separator = Separator(logger=logger, log_formatter=file_formatter, log_level=logging.INFO, output_dir=output_dir, output_format=output_format, output_bitrate=None, normalization_threshold=0.9, output_single_stem=None, invert_using_spec=False, sample_rate=sample_rate, mdx_params={"hop_length": mdx_hop_length, "segment_size": mdx_segment_size, "overlap": mdx_overlap, "batch_size": mdx_batch_size, "enable_denoise": mdx_enable_denoise})
222
+ separator.load_model(model_filename=model_filename)
223
+ return separator.separate(audio_file)
224
+ except:
225
+ logger.debug(translations["default_setting"])
226
+ separator = Separator(logger=logger, log_formatter=file_formatter, log_level=logging.INFO, output_dir=output_dir, output_format=output_format, output_bitrate=None, normalization_threshold=0.9, output_single_stem=None, invert_using_spec=False, sample_rate=44100, mdx_params={"hop_length": 1024, "segment_size": 256, "overlap": 0.25, "batch_size": 1, "enable_denoise": mdx_enable_denoise})
227
+ separator.load_model(model_filename=model_filename)
228
+ return separator.separate(audio_file)
229
+
230
+ if __name__ == "__main__": main()
main/inference/create_index.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import faiss
4
+ import logging
5
+ import argparse
6
+ import logging.handlers
7
+
8
+ import numpy as np
9
+
10
+ from multiprocessing import cpu_count
11
+ from sklearn.cluster import MiniBatchKMeans
12
+
13
+ sys.path.append(os.getcwd())
14
+
15
+ from main.configs.config import Config
16
+ translations = Config().translations
17
+
18
+ def parse_arguments():
19
+ parser = argparse.ArgumentParser()
20
+ parser.add_argument("--model_name", type=str, required=True)
21
+ parser.add_argument("--rvc_version", type=str, default="v2")
22
+ parser.add_argument("--index_algorithm", type=str, default="Auto")
23
+
24
+ return parser.parse_args()
25
+
26
+ def main():
27
+ args = parse_arguments()
28
+ exp_dir = os.path.join("assets", "logs", args.model_name)
29
+ version, index_algorithm = args.rvc_version, args.index_algorithm
30
+ logger = logging.getLogger(__name__)
31
+
32
+ if logger.hasHandlers(): logger.handlers.clear()
33
+ else:
34
+ console_handler = logging.StreamHandler()
35
+ console_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
36
+ console_handler.setFormatter(console_formatter)
37
+ console_handler.setLevel(logging.INFO)
38
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join(exp_dir, "create_index.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
39
+ file_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
40
+ file_handler.setFormatter(file_formatter)
41
+ file_handler.setLevel(logging.DEBUG)
42
+ logger.addHandler(console_handler)
43
+ logger.addHandler(file_handler)
44
+ logger.setLevel(logging.DEBUG)
45
+
46
+ log_data = {translations['modelname']: args.model_name, translations['model_path']: exp_dir, translations['training_version']: version, translations['index_algorithm_info']: index_algorithm}
47
+ for key, value in log_data.items():
48
+ logger.debug(f"{key}: {value}")
49
+
50
+ try:
51
+ npys = []
52
+ feature_dir = os.path.join(exp_dir, f"{version}_extracted")
53
+ model_name = os.path.basename(exp_dir)
54
+
55
+ for name in sorted(os.listdir(feature_dir)):
56
+ npys.append(np.load(os.path.join(feature_dir, name)))
57
+
58
+ big_npy = np.concatenate(npys, axis=0)
59
+ big_npy_idx = np.arange(big_npy.shape[0])
60
+ np.random.shuffle(big_npy_idx)
61
+ big_npy = big_npy[big_npy_idx]
62
+
63
+ if big_npy.shape[0] > 2e5 and (index_algorithm == "Auto" or index_algorithm == "KMeans"): big_npy = (MiniBatchKMeans(n_clusters=10000, verbose=True, batch_size=256 * cpu_count(), compute_labels=False, init="random").fit(big_npy).cluster_centers_)
64
+ np.save(os.path.join(exp_dir, "total_fea.npy"), big_npy)
65
+
66
+ n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39)
67
+ index_trained = faiss.index_factory(256 if version == "v1" else 768, f"IVF{n_ivf},Flat")
68
+ index_ivf_trained = faiss.extract_index_ivf(index_trained)
69
+ index_ivf_trained.nprobe = 1
70
+ index_trained.train(big_npy)
71
+ faiss.write_index(index_trained, os.path.join(exp_dir, f"trained_IVF{n_ivf}_Flat_nprobe_{index_ivf_trained.nprobe}_{model_name}_{version}.index"))
72
+
73
+ index_added = faiss.index_factory(256 if version == "v1" else 768, f"IVF{n_ivf},Flat")
74
+ index_ivf_added = faiss.extract_index_ivf(index_added)
75
+ index_ivf_added.nprobe = 1
76
+ index_added.train(big_npy)
77
+ batch_size_add = 8192
78
+
79
+ for i in range(0, big_npy.shape[0], batch_size_add):
80
+ index_added.add(big_npy[i : i + batch_size_add])
81
+
82
+ index_filepath_added = os.path.join(exp_dir, f"added_IVF{n_ivf}_Flat_nprobe_{index_ivf_added.nprobe}_{model_name}_{version}.index")
83
+ faiss.write_index(index_added, index_filepath_added)
84
+ logger.info(f"{translations['save_index']} '{index_filepath_added}'")
85
+ except Exception as e:
86
+ logger.error(f"{translations['create_index_error']}: {e}")
87
+ import traceback
88
+ logger.debug(traceback.format_exc())
89
+
90
+ if __name__ == "__main__": main()
main/inference/extract.py ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import sys
4
+ import time
5
+ import tqdm
6
+ import torch
7
+ import shutil
8
+ import logging
9
+ import argparse
10
+ import warnings
11
+ import onnxruntime
12
+ import logging.handlers
13
+
14
+ import numpy as np
15
+ import soundfile as sf
16
+ import torch.nn.functional as F
17
+
18
+ from random import shuffle
19
+ from distutils.util import strtobool
20
+ from concurrent.futures import ThreadPoolExecutor, as_completed
21
+
22
+ sys.path.append(os.getcwd())
23
+
24
+ from main.configs.config import Config
25
+ from main.library.utils import check_predictors, check_embedders, load_audio, load_embedders_model
26
+
27
+ logger = logging.getLogger(__name__)
28
+ config = Config()
29
+ translations = config.translations
30
+ logger.propagate = False
31
+
32
+ warnings.filterwarnings("ignore")
33
+ for l in ["torch", "faiss", "httpx", "fairseq", "httpcore", "faiss.loader", "numba.core", "urllib3", "matplotlib"]:
34
+ logging.getLogger(l).setLevel(logging.ERROR)
35
+
36
+ def parse_arguments():
37
+ parser = argparse.ArgumentParser()
38
+ parser.add_argument("--model_name", type=str, required=True)
39
+ parser.add_argument("--rvc_version", type=str, default="v2")
40
+ parser.add_argument("--f0_method", type=str, default="rmvpe")
41
+ parser.add_argument("--pitch_guidance", type=lambda x: bool(strtobool(x)), default=True)
42
+ parser.add_argument("--hop_length", type=int, default=128)
43
+ parser.add_argument("--cpu_cores", type=int, default=2)
44
+ parser.add_argument("--gpu", type=str, default="-")
45
+ parser.add_argument("--sample_rate", type=int, required=True)
46
+ parser.add_argument("--embedder_model", type=str, default="contentvec_base")
47
+ parser.add_argument("--f0_onnx", type=lambda x: bool(strtobool(x)), default=False)
48
+ parser.add_argument("--embedders_mode", type=str, default="fairseq")
49
+
50
+ return parser.parse_args()
51
+
52
+ def generate_config(rvc_version, sample_rate, model_path):
53
+ config_save_path = os.path.join(model_path, "config.json")
54
+ if not os.path.exists(config_save_path): shutil.copy(os.path.join("main", "configs", rvc_version, f"{sample_rate}.json"), config_save_path)
55
+
56
+ def generate_filelist(pitch_guidance, model_path, rvc_version, sample_rate):
57
+ gt_wavs_dir, feature_dir = os.path.join(model_path, "sliced_audios"), os.path.join(model_path, f"{rvc_version}_extracted")
58
+ f0_dir, f0nsf_dir = None, None
59
+
60
+ if pitch_guidance: f0_dir, f0nsf_dir = os.path.join(model_path, "f0"), os.path.join(model_path, "f0_voiced")
61
+
62
+ gt_wavs_files, feature_files = set(name.split(".")[0] for name in os.listdir(gt_wavs_dir)), set(name.split(".")[0] for name in os.listdir(feature_dir))
63
+ names = gt_wavs_files & feature_files & set(name.split(".")[0] for name in os.listdir(f0_dir)) & set(name.split(".")[0] for name in os.listdir(f0nsf_dir)) if pitch_guidance else gt_wavs_files & feature_files
64
+
65
+ options = []
66
+ mute_base_path = os.path.join("assets", "logs", "mute")
67
+
68
+ for name in names:
69
+ options.append(f"{gt_wavs_dir}/{name}.wav|{feature_dir}/{name}.npy|{f0_dir}/{name}.wav.npy|{f0nsf_dir}/{name}.wav.npy|0" if pitch_guidance else f"{gt_wavs_dir}/{name}.wav|{feature_dir}/{name}.npy|0")
70
+
71
+ mute_audio_path, mute_feature_path = os.path.join(mute_base_path, "sliced_audios", f"mute{sample_rate}.wav"), os.path.join(mute_base_path, f"{rvc_version}_extracted", "mute.npy")
72
+ for _ in range(2):
73
+ options.append(f"{mute_audio_path}|{mute_feature_path}|{os.path.join(mute_base_path, 'f0', 'mute.wav.npy')}|{os.path.join(mute_base_path, 'f0_voiced', 'mute.wav.npy')}|0" if pitch_guidance else f"{mute_audio_path}|{mute_feature_path}|0")
74
+
75
+ shuffle(options)
76
+ with open(os.path.join(model_path, "filelist.txt"), "w") as f:
77
+ f.write("\n".join(options))
78
+
79
+ def setup_paths(exp_dir, version = None):
80
+ wav_path = os.path.join(exp_dir, "sliced_audios_16k")
81
+
82
+ if version:
83
+ out_path = os.path.join(exp_dir, f"{version}_extracted")
84
+ os.makedirs(out_path, exist_ok=True)
85
+ return wav_path, out_path
86
+ else:
87
+ output_root1, output_root2 = os.path.join(exp_dir, "f0"), os.path.join(exp_dir, "f0_voiced")
88
+ os.makedirs(output_root1, exist_ok=True); os.makedirs(output_root2, exist_ok=True)
89
+ return wav_path, output_root1, output_root2
90
+
91
+ def read_wave(wav_path, normalize = False, is_half = False):
92
+ wav, sr = sf.read(wav_path, dtype=np.float32)
93
+ assert sr == 16000, translations["sr_not_16000"]
94
+
95
+ feats = torch.from_numpy(wav).float()
96
+ if feats.dim() == 2: feats = feats.mean(-1)
97
+ feats = feats.view(1, -1)
98
+
99
+ if normalize: feats = F.layer_norm(feats, feats.shape)
100
+ return feats.half() if is_half else feats.float()
101
+
102
+ def get_device(gpu_index):
103
+ try:
104
+ index = int(gpu_index)
105
+ if index < torch.cuda.device_count(): return f"cuda:{index}"
106
+ else: logger.warning(translations["gpu_not_valid"])
107
+ except ValueError:
108
+ logger.warning(translations["gpu_not_valid"])
109
+ return "cpu"
110
+
111
+ def get_providers():
112
+ ort_providers = onnxruntime.get_available_providers()
113
+
114
+ if "CUDAExecutionProvider" in ort_providers: providers = ["CUDAExecutionProvider"]
115
+ elif "CoreMLExecutionProvider" in ort_providers: providers = ["CoreMLExecutionProvider"]
116
+ else: providers = ["CPUExecutionProvider"]
117
+
118
+ return providers
119
+
120
+ class FeatureInput:
121
+ def __init__(self, sample_rate=16000, hop_size=160, is_half=False, device=config.device):
122
+ self.fs = sample_rate
123
+ self.hop = hop_size
124
+ self.f0_bin = 256
125
+ self.f0_max = 1100.0
126
+ self.f0_min = 50.0
127
+ self.f0_mel_min = 1127 * np.log(1 + self.f0_min / 700)
128
+ self.f0_mel_max = 1127 * np.log(1 + self.f0_max / 700)
129
+ self.device = device
130
+ self.is_half = is_half
131
+
132
+ def compute_f0_hybrid(self, methods_str, np_arr, hop_length, f0_onnx):
133
+ methods_str = re.search("hybrid\[(.+)\]", methods_str)
134
+ if methods_str: methods = [method.strip() for method in methods_str.group(1).split("+")]
135
+ f0_computation_stack, resampled_stack = [], []
136
+ logger.debug(translations["hybrid_methods"].format(methods=methods))
137
+
138
+ for method in methods:
139
+ f0 = None
140
+ f0_methods = {"pm": lambda: self.get_pm(np_arr), "dio": lambda: self.get_pyworld(np_arr, "dio"), "mangio-crepe-full": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "full", onnx=f0_onnx), "mangio-crepe-large": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "large", onnx=f0_onnx), "mangio-crepe-medium": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "medium", onnx=f0_onnx), "mangio-crepe-small": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "small", onnx=f0_onnx), "mangio-crepe-tiny": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "tiny", onnx=f0_onnx), "crepe-full": lambda: self.get_crepe(np_arr, "full", onnx=f0_onnx), "crepe-large": lambda: self.get_crepe(np_arr, "large", onnx=f0_onnx), "crepe-medium": lambda: self.get_crepe(np_arr, "medium", onnx=f0_onnx), "crepe-small": lambda: self.get_crepe(np_arr, "small", onnx=f0_onnx), "crepe-tiny": lambda: self.get_crepe(np_arr, "tiny", onnx=f0_onnx), "fcpe": lambda: self.get_fcpe(np_arr, int(hop_length), onnx=f0_onnx), "fcpe-legacy": lambda: self.get_fcpe(np_arr, int(hop_length), legacy=True, onnx=f0_onnx), "rmvpe": lambda: self.get_rmvpe(np_arr, onnx=f0_onnx), "rmvpe-legacy": lambda: self.get_rmvpe(np_arr, legacy=True, onnx=f0_onnx), "harvest": lambda: self.get_pyworld(np_arr, "harvest"), "swipe": lambda: self.get_swipe(np_arr), "yin": lambda: self.get_yin(np_arr, int(hop_length), mode="yin"), "pyin": lambda: self.get_yin(np_arr, int(hop_length), mode="pyin")}
141
+ f0 = f0_methods.get(method, lambda: ValueError(translations["method_not_valid"]))()
142
+ f0_computation_stack.append(f0)
143
+
144
+ for f0 in f0_computation_stack:
145
+ resampled_stack.append(np.interp(np.linspace(0, len(f0), (np_arr.size // self.hop)), np.arange(len(f0)), f0))
146
+
147
+ return resampled_stack[0] if len(resampled_stack) == 1 else np.nanmedian(np.vstack(resampled_stack), axis=0)
148
+
149
+ def compute_f0(self, np_arr, f0_method, hop_length, f0_onnx=False):
150
+ f0_methods = {"pm": lambda: self.get_pm(np_arr), "dio": lambda: self.get_pyworld(np_arr, "dio"), "mangio-crepe-full": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "full", onnx=f0_onnx), "mangio-crepe-large": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "large", onnx=f0_onnx), "mangio-crepe-medium": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "medium", onnx=f0_onnx), "mangio-crepe-small": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "small", onnx=f0_onnx), "mangio-crepe-tiny": lambda: self.get_mangio_crepe(np_arr, int(hop_length), "tiny", onnx=f0_onnx), "crepe-full": lambda: self.get_crepe(np_arr, "full", onnx=f0_onnx), "crepe-large": lambda: self.get_crepe(np_arr, "large", onnx=f0_onnx), "crepe-medium": lambda: self.get_crepe(np_arr, "medium", onnx=f0_onnx), "crepe-small": lambda: self.get_crepe(np_arr, "small", onnx=f0_onnx), "crepe-tiny": lambda: self.get_crepe(np_arr, "tiny", onnx=f0_onnx), "fcpe": lambda: self.get_fcpe(np_arr, int(hop_length), onnx=f0_onnx), "fcpe-legacy": lambda: self.get_fcpe(np_arr, int(hop_length), legacy=True, onnx=f0_onnx), "rmvpe": lambda: self.get_rmvpe(np_arr, onnx=f0_onnx), "rmvpe-legacy": lambda: self.get_rmvpe(np_arr, legacy=True, onnx=f0_onnx), "harvest": lambda: self.get_pyworld(np_arr, "harvest"), "swipe": lambda: self.get_swipe(np_arr), "yin": lambda: self.get_yin(np_arr, int(hop_length), mode="yin"), "pyin": lambda: self.get_yin(np_arr, int(hop_length), mode="pyin")}
151
+ return self.compute_f0_hybrid(f0_method, np_arr, int(hop_length), f0_onnx) if "hybrid" in f0_method else f0_methods.get(f0_method, lambda: ValueError(translations["method_not_valid"]))()
152
+
153
+ def get_pm(self, x):
154
+ import parselmouth
155
+
156
+ f0 = (parselmouth.Sound(x, self.fs).to_pitch_ac(time_step=(160 / 16000 * 1000) / 1000, voicing_threshold=0.6, pitch_floor=50, pitch_ceiling=1100).selected_array["frequency"])
157
+ pad_size = ((x.size // self.hop) - len(f0) + 1) // 2
158
+
159
+ if pad_size > 0 or (x.size // self.hop) - len(f0) - pad_size > 0: f0 = np.pad(f0, [[pad_size, (x.size // self.hop) - len(f0) - pad_size]], mode="constant")
160
+ return f0
161
+
162
+ def get_mangio_crepe(self, x, hop_length, model="full", onnx=False):
163
+ from main.library.predictors.CREPE import predict
164
+
165
+ audio = torch.from_numpy(x.astype(np.float32)).to(self.device)
166
+ audio /= torch.quantile(torch.abs(audio), 0.999)
167
+ audio = audio.unsqueeze(0)
168
+ source = predict(audio, self.fs, hop_length, self.f0_min, self.f0_max, model=model, batch_size=hop_length * 2, device=self.device, pad=True, providers=get_providers(), onnx=onnx).squeeze(0).cpu().float().numpy()
169
+ source[source < 0.001] = np.nan
170
+
171
+ return np.nan_to_num(np.interp(np.arange(0, len(source) * (x.size // self.hop), len(source)) / (x.size // self.hop), np.arange(0, len(source)), source))
172
+
173
+ def get_crepe(self, x, model="full", onnx=False):
174
+ from main.library.predictors.CREPE import predict, mean, median
175
+
176
+ f0, pd = predict(torch.tensor(np.copy(x))[None].float(), self.fs, 160, self.f0_min, self.f0_max, model, batch_size=512, device=self.device, return_periodicity=True, providers=get_providers(), onnx=onnx)
177
+ f0, pd = mean(f0, 3), median(pd, 3)
178
+ f0[pd < 0.1] = 0
179
+
180
+ return f0[0].cpu().numpy()
181
+
182
+ def get_fcpe(self, x, hop_length, legacy=False, onnx=False):
183
+ from main.library.predictors.FCPE import FCPE
184
+
185
+ model_fcpe = FCPE(os.path.join("assets", "models", "predictors", ("fcpe_legacy" if legacy else"fcpe") + (".onnx" if onnx else ".pt")), hop_length=int(hop_length), f0_min=int(self.f0_min), f0_max=int(self.f0_max), dtype=torch.float32, device=self.device, sample_rate=self.fs, threshold=0.03 if legacy else 0.006, providers=get_providers(), onnx=onnx, legacy=legacy)
186
+ f0 = model_fcpe.compute_f0(x, p_len=(x.size // self.hop))
187
+
188
+ del model_fcpe
189
+ return f0
190
+
191
+ def get_rmvpe(self, x, legacy=False, onnx=False):
192
+ from main.library.predictors.RMVPE import RMVPE
193
+
194
+ rmvpe_model = RMVPE(os.path.join("assets", "models", "predictors", "rmvpe" + (".onnx" if onnx else ".pt")), is_half=self.is_half, device=self.device, onnx=onnx, providers=get_providers())
195
+ f0 = rmvpe_model.infer_from_audio_with_pitch(x, thred=0.03, f0_min=self.f0_min, f0_max=self.f0_max) if legacy else rmvpe_model.infer_from_audio(x, thred=0.03)
196
+
197
+ del rmvpe_model
198
+ return f0
199
+
200
+ def get_pyworld(self, x, model="harvest"):
201
+ from main.library.predictors.WORLD_WRAPPER import PYWORLD
202
+
203
+ pw = PYWORLD()
204
+ x = x.astype(np.double)
205
+
206
+ if model == "harvest": f0, t = pw.harvest(x, fs=self.fs, f0_ceil=self.f0_max, f0_floor=self.f0_min, frame_period=1000 * self.hop / self.fs)
207
+ elif model == "dio": f0, t = pw.dio(x, fs=self.fs, f0_ceil=self.f0_max, f0_floor=self.f0_min, frame_period=1000 * self.hop / self.fs)
208
+ else: raise ValueError(translations["method_not_valid"])
209
+
210
+ return pw.stonemask(x, self.fs, t, f0)
211
+
212
+ def get_swipe(self, x):
213
+ from main.library.predictors.SWIPE import swipe
214
+
215
+ f0, _ = swipe(x.astype(np.float32), self.fs, f0_floor=self.f0_min, f0_ceil=self.f0_max, frame_period=1000 * self.hop / self.fs)
216
+ return f0
217
+
218
+ def get_yin(self, x, hop_length, mode="yin"):
219
+ import librosa
220
+
221
+ source = np.array(librosa.yin(x.astype(np.float32), sr=self.fs, fmin=self.f0_min, fmax=self.f0_max, hop_length=hop_length) if mode == "yin" else librosa.pyin(x.astype(np.float32), fmin=self.f0_min, fmax=self.f0_max, sr=self.fs, hop_length=hop_length)[0])
222
+ source[source < 0.001] = np.nan
223
+ return np.nan_to_num(np.interp(np.arange(0, len(source) * (x.size // self.hop), len(source)) / (x.size // self.hop), np.arange(0, len(source)), source))
224
+
225
+ def coarse_f0(self, f0):
226
+ return np.rint(np.clip(((1127 * np.log(1 + f0 / 700)) - self.f0_mel_min) * (self.f0_bin - 2) / (self.f0_mel_max - self.f0_mel_min) + 1, 1, self.f0_bin - 1)).astype(int)
227
+
228
+ def process_file(self, file_info, f0_method, hop_length, f0_onnx):
229
+ inp_path, opt_path1, opt_path2, np_arr = file_info
230
+ if os.path.exists(opt_path1 + ".npy") and os.path.exists(opt_path2 + ".npy"): return
231
+
232
+ try:
233
+ feature_pit = self.compute_f0(np_arr, f0_method, hop_length, f0_onnx)
234
+ if isinstance(feature_pit, tuple): feature_pit = feature_pit[0]
235
+ np.save(opt_path2, feature_pit, allow_pickle=False)
236
+ np.save(opt_path1, self.coarse_f0(feature_pit), allow_pickle=False)
237
+ except Exception as e:
238
+ raise RuntimeError(f"{translations['extract_file_error']} {inp_path}: {e}")
239
+
240
+ def process_files(self, files, f0_method, hop_length, f0_onnx, pbar):
241
+ for file_info in files:
242
+ self.process_file(file_info, f0_method, hop_length, f0_onnx)
243
+ pbar.update()
244
+
245
+ def run_pitch_extraction(exp_dir, f0_method, hop_length, num_processes, gpus, f0_onnx, is_half):
246
+ input_root, *output_roots = setup_paths(exp_dir)
247
+ output_root1, output_root2 = output_roots if len(output_roots) == 2 else (output_roots[0], None)
248
+
249
+ paths = [(os.path.join(input_root, name), os.path.join(output_root1, name) if output_root1 else None, os.path.join(output_root2, name) if output_root2 else None, load_audio(logger, os.path.join(input_root, name), 16000)) for name in sorted(os.listdir(input_root)) if "spec" not in name]
250
+ logger.info(translations["extract_f0_method"].format(num_processes=num_processes, f0_method=f0_method))
251
+
252
+ start_time = time.time()
253
+ gpus = gpus.split("-")
254
+ process_partials = []
255
+
256
+ pbar = tqdm.tqdm(total=len(paths), ncols=100, unit="p")
257
+ for idx, gpu in enumerate(gpus):
258
+ feature_input = FeatureInput(device=get_device(gpu) if gpu != "" else "cpu", is_half=is_half)
259
+ process_partials.append((feature_input, paths[idx::len(gpus)]))
260
+
261
+ with ThreadPoolExecutor(max_workers=num_processes) as executor:
262
+ for future in as_completed([executor.submit(FeatureInput.process_files, feature_input, part_paths, f0_method, hop_length, f0_onnx, pbar) for feature_input, part_paths in process_partials]):
263
+ pbar.update(1)
264
+ logger.debug(pbar.format_meter(pbar.n, pbar.total, pbar.format_dict["elapsed"]))
265
+ future.result()
266
+
267
+ pbar.close()
268
+ logger.info(translations["extract_f0_success"].format(elapsed_time=f"{(time.time() - start_time):.2f}"))
269
+
270
+ def extract_features(model, feats, version):
271
+ return torch.as_tensor(model.run([model.get_outputs()[0].name, model.get_outputs()[1].name], {"feats": feats.detach().cpu().numpy()})[0 if version == "v1" else 1], dtype=torch.float32, device=feats.device)
272
+
273
+ def process_file_embedding(file, wav_path, out_path, model, device, version, saved_cfg, embed_suffix, is_half):
274
+ out_file_path = os.path.join(out_path, file.replace("wav", "npy"))
275
+ if os.path.exists(out_file_path): return
276
+ feats = read_wave(os.path.join(wav_path, file), normalize=saved_cfg.task.normalize if saved_cfg else False, is_half=is_half).to(device)
277
+
278
+ with torch.no_grad():
279
+ if embed_suffix == ".pt":
280
+ model = model.to(device).to(torch.float16 if is_half else torch.float32).eval()
281
+ logits = model.extract_features(**{"source": feats, "padding_mask": torch.BoolTensor(feats.shape).fill_(False).to(device), "output_layer": 9 if version == "v1" else 12})
282
+ feats = model.final_proj(logits[0]) if version == "v1" else logits[0]
283
+ elif embed_suffix == ".onnx": feats = extract_features(model, feats, version).to(device)
284
+ elif embed_suffix == ".safetensors":
285
+ model = model.to(device).to(torch.float16 if is_half else torch.float32).eval()
286
+ logits = model(feats)["last_hidden_state"]
287
+ feats = (model.final_proj(logits[0]).unsqueeze(0) if version == "v1" else logits)
288
+ else: raise ValueError(translations["option_not_valid"])
289
+
290
+ feats = feats.squeeze(0).float().cpu().numpy()
291
+ if not np.isnan(feats).any(): np.save(out_file_path, feats, allow_pickle=False)
292
+ else: logger.warning(f"{file} {translations['NaN']}")
293
+
294
+ def run_embedding_extraction(exp_dir, version, gpus, embedder_model, embedders_mode, is_half):
295
+ wav_path, out_path = setup_paths(exp_dir, version)
296
+ logger.info(translations["start_extract_hubert"])
297
+ start_time = time.time()
298
+ models, saved_cfg, embed_suffix = load_embedders_model(embedder_model, embedders_mode, providers=get_providers())
299
+ devices = [get_device(gpu) for gpu in (gpus.split("-") if gpus != "-" else ["cpu"])]
300
+ paths = sorted([file for file in os.listdir(wav_path) if file.endswith(".wav")])
301
+
302
+ if not paths:
303
+ logger.warning(translations["not_found_audio_file"])
304
+ sys.exit(1)
305
+
306
+ pbar = tqdm.tqdm(total=len(paths) * len(devices), ncols=100, unit="p")
307
+ for task in [(file, wav_path, out_path, models, device, version, saved_cfg, embed_suffix, is_half) for file in paths for device in devices]:
308
+ try:
309
+ process_file_embedding(*task)
310
+ except Exception as e:
311
+ raise RuntimeError(f"{translations['process_error']} {task[0]}: {e}")
312
+
313
+ pbar.update(1)
314
+ logger.debug(pbar.format_meter(pbar.n, pbar.total, pbar.format_dict["elapsed"]))
315
+
316
+ pbar.close()
317
+ logger.info(translations["extract_hubert_success"].format(elapsed_time=f"{(time.time() - start_time):.2f}"))
318
+
319
+ def main():
320
+ args = parse_arguments()
321
+ exp_dir = os.path.join("assets", "logs", args.model_name)
322
+ f0_method, hop_length, num_processes, gpus, version, pitch_guidance, sample_rate, embedder_model, f0_onnx, embedders_mode = args.f0_method, args.hop_length, args.cpu_cores, args.gpu, args.rvc_version, args.pitch_guidance, args.sample_rate, args.embedder_model, args.f0_onnx, args.embedders_mode
323
+
324
+ check_predictors(f0_method, f0_onnx); check_embedders(embedder_model, embedders_mode)
325
+ if logger.hasHandlers(): logger.handlers.clear()
326
+ else:
327
+ console_handler = logging.StreamHandler()
328
+ console_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
329
+ console_handler.setFormatter(console_formatter)
330
+ console_handler.setLevel(logging.INFO)
331
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join(exp_dir, "extract.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
332
+ file_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
333
+ file_handler.setFormatter(file_formatter)
334
+ file_handler.setLevel(logging.DEBUG)
335
+ logger.addHandler(console_handler)
336
+ logger.addHandler(file_handler)
337
+ logger.setLevel(logging.DEBUG)
338
+
339
+ log_data = {translations['modelname']: args.model_name, translations['export_process']: exp_dir, translations['f0_method']: f0_method, translations['pretrain_sr']: sample_rate, translations['cpu_core']: num_processes, "Gpu": gpus, "Hop length": hop_length, translations['training_version']: version, translations['extract_f0']: pitch_guidance, translations['hubert_model']: embedder_model, translations["f0_onnx_mode"]: f0_onnx, translations["embed_mode"]: embedders_mode}
340
+ for key, value in log_data.items():
341
+ logger.debug(f"{key}: {value}")
342
+
343
+ pid_path = os.path.join(exp_dir, "extract_pid.txt")
344
+ with open(pid_path, "w") as pid_file:
345
+ pid_file.write(str(os.getpid()))
346
+
347
+ try:
348
+ run_pitch_extraction(exp_dir, f0_method, hop_length, num_processes, gpus, f0_onnx, config.is_half)
349
+ run_embedding_extraction(exp_dir, version, gpus, embedder_model, embedders_mode, config.is_half)
350
+ generate_config(version, sample_rate, exp_dir)
351
+ generate_filelist(pitch_guidance, exp_dir, version, sample_rate)
352
+ except Exception as e:
353
+ logger.error(f"{translations['extract_error']}: {e}")
354
+ import traceback
355
+ logger.debug(traceback.format_exc())
356
+
357
+ if os.path.exists(pid_path): os.remove(pid_path)
358
+ logger.info(f"{translations['extract_success']} {args.model_name}.")
359
+
360
+ if __name__ == "__main__": main()
main/inference/preprocess.py ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import time
4
+ import logging
5
+ import librosa
6
+ import argparse
7
+ import logging.handlers
8
+
9
+ import numpy as np
10
+
11
+ from tqdm import tqdm
12
+ from scipy import signal
13
+ from scipy.io import wavfile
14
+ from distutils.util import strtobool
15
+ from concurrent.futures import ProcessPoolExecutor, as_completed
16
+
17
+ sys.path.append(os.getcwd())
18
+
19
+ from main.library.utils import load_audio
20
+ from main.configs.config import Config
21
+
22
+ logger = logging.getLogger(__name__)
23
+ for l in ["numba.core.byteflow", "numba.core.ssa", "numba.core.interpreter"]:
24
+ logging.getLogger(l).setLevel(logging.ERROR)
25
+
26
+ OVERLAP, MAX_AMPLITUDE, ALPHA, HIGH_PASS_CUTOFF, SAMPLE_RATE_16K = 0.3, 0.9, 0.75, 48, 16000
27
+
28
+ config = Config()
29
+ translations = config.translations
30
+
31
+ def parse_arguments():
32
+ parser = argparse.ArgumentParser()
33
+ parser.add_argument("--model_name", type=str, required=True)
34
+ parser.add_argument("--dataset_path", type=str, default="./dataset")
35
+ parser.add_argument("--sample_rate", type=int, required=True)
36
+ parser.add_argument("--cpu_cores", type=int, default=2)
37
+ parser.add_argument("--cut_preprocess", type=lambda x: bool(strtobool(x)), default=True)
38
+ parser.add_argument("--process_effects", type=lambda x: bool(strtobool(x)), default=False)
39
+ parser.add_argument("--clean_dataset", type=lambda x: bool(strtobool(x)), default=False)
40
+ parser.add_argument("--clean_strength", type=float, default=0.7)
41
+
42
+ return parser.parse_args()
43
+
44
+ class Slicer:
45
+ def __init__(self, sr, threshold = -40.0, min_length = 5000, min_interval = 300, hop_size = 20, max_sil_kept = 5000):
46
+ if not min_length >= min_interval >= hop_size: raise ValueError(translations["min_length>=min_interval>=hop_size"])
47
+ if not max_sil_kept >= hop_size: raise ValueError(translations["max_sil_kept>=hop_size"])
48
+
49
+ min_interval = sr * min_interval / 1000
50
+ self.threshold = 10 ** (threshold / 20.0)
51
+ self.hop_size = round(sr * hop_size / 1000)
52
+ self.win_size = min(round(min_interval), 4 * self.hop_size)
53
+ self.min_length = round(sr * min_length / 1000 / self.hop_size)
54
+ self.min_interval = round(min_interval / self.hop_size)
55
+ self.max_sil_kept = round(sr * max_sil_kept / 1000 / self.hop_size)
56
+
57
+ def _apply_slice(self, waveform, begin, end):
58
+ start_idx = begin * self.hop_size
59
+
60
+ if len(waveform.shape) > 1: return waveform[:, start_idx:min(waveform.shape[1], end * self.hop_size)]
61
+ else: return waveform[start_idx:min(waveform.shape[0], end * self.hop_size)]
62
+
63
+ def slice(self, waveform):
64
+ samples = waveform.mean(axis=0) if len(waveform.shape) > 1 else waveform
65
+ if samples.shape[0] <= self.min_length: return [waveform]
66
+ rms_list = get_rms(y=samples, frame_length=self.win_size, hop_length=self.hop_size).squeeze(0)
67
+ sil_tags = []
68
+ silence_start, clip_start = None, 0
69
+
70
+ for i, rms in enumerate(rms_list):
71
+ if rms < self.threshold:
72
+ if silence_start is None: silence_start = i
73
+ continue
74
+
75
+ if silence_start is None: continue
76
+
77
+ is_leading_silence = silence_start == 0 and i > self.max_sil_kept
78
+ need_slice_middle = (i - silence_start >= self.min_interval and i - clip_start >= self.min_length)
79
+
80
+ if not is_leading_silence and not need_slice_middle:
81
+ silence_start = None
82
+ continue
83
+
84
+ if i - silence_start <= self.max_sil_kept:
85
+ pos = rms_list[silence_start : i + 1].argmin() + silence_start
86
+ sil_tags.append((0, pos) if silence_start == 0 else (pos, pos))
87
+ clip_start = pos
88
+ elif i - silence_start <= self.max_sil_kept * 2:
89
+ pos = rms_list[i - self.max_sil_kept : silence_start + self.max_sil_kept + 1].argmin()
90
+ pos += i - self.max_sil_kept
91
+ pos_r = (rms_list[i - self.max_sil_kept : i + 1].argmin() + i - self.max_sil_kept)
92
+
93
+ if silence_start == 0:
94
+ sil_tags.append((0, pos_r))
95
+ clip_start = pos_r
96
+ else:
97
+ sil_tags.append((min((rms_list[silence_start : silence_start + self.max_sil_kept + 1].argmin() + silence_start), pos), max(pos_r, pos)))
98
+ clip_start = max(pos_r, pos)
99
+ else:
100
+ pos_r = (rms_list[i - self.max_sil_kept : i + 1].argmin() + i - self.max_sil_kept)
101
+ sil_tags.append((0, pos_r) if silence_start == 0 else ((rms_list[silence_start : silence_start + self.max_sil_kept + 1].argmin() + silence_start), pos_r))
102
+ clip_start = pos_r
103
+
104
+ silence_start = None
105
+ total_frames = rms_list.shape[0]
106
+ if (silence_start is not None and total_frames - silence_start >= self.min_interval): sil_tags.append((rms_list[silence_start : min(total_frames, silence_start + self.max_sil_kept) + 1].argmin() + silence_start, total_frames + 1))
107
+
108
+ if not sil_tags: return [waveform]
109
+ else:
110
+ chunks = []
111
+ if sil_tags[0][0] > 0: chunks.append(self._apply_slice(waveform, 0, sil_tags[0][0]))
112
+
113
+ for i in range(len(sil_tags) - 1):
114
+ chunks.append(self._apply_slice(waveform, sil_tags[i][1], sil_tags[i + 1][0]))
115
+
116
+ if sil_tags[-1][1] < total_frames: chunks.append(self._apply_slice(waveform, sil_tags[-1][1], total_frames))
117
+ return chunks
118
+
119
+ def get_rms(y, frame_length=2048, hop_length=512, pad_mode="constant"):
120
+ y = np.pad(y, (int(frame_length // 2), int(frame_length // 2)), mode=pad_mode)
121
+ axis = -1
122
+ x_shape_trimmed = list(y.shape)
123
+ x_shape_trimmed[axis] -= frame_length - 1
124
+ xw = np.moveaxis(np.lib.stride_tricks.as_strided(y, shape=tuple(x_shape_trimmed) + tuple([frame_length]), strides=y.strides + tuple([y.strides[axis]])), -1, axis - 1 if axis < 0 else axis + 1)
125
+ slices = [slice(None)] * xw.ndim
126
+ slices[axis] = slice(0, None, hop_length)
127
+ return np.sqrt(np.mean(np.abs(xw[tuple(slices)]) ** 2, axis=-2, keepdims=True))
128
+
129
+ class PreProcess:
130
+ def __init__(self, sr, exp_dir, per):
131
+ self.slicer = Slicer(sr=sr, threshold=-42, min_length=1500, min_interval=400, hop_size=15, max_sil_kept=500)
132
+ self.sr = sr
133
+ self.b_high, self.a_high = signal.butter(N=5, Wn=HIGH_PASS_CUTOFF, btype="high", fs=self.sr)
134
+ self.per = per
135
+ self.exp_dir = exp_dir
136
+ self.device = "cpu"
137
+ self.gt_wavs_dir = os.path.join(exp_dir, "sliced_audios")
138
+ self.wavs16k_dir = os.path.join(exp_dir, "sliced_audios_16k")
139
+ os.makedirs(self.gt_wavs_dir, exist_ok=True)
140
+ os.makedirs(self.wavs16k_dir, exist_ok=True)
141
+
142
+ def _normalize_audio(self, audio):
143
+ tmp_max = np.abs(audio).max()
144
+ if tmp_max > 2.5: return None
145
+ return (audio / tmp_max * (MAX_AMPLITUDE * ALPHA)) + (1 - ALPHA) * audio
146
+
147
+ def process_audio_segment(self, normalized_audio, sid, idx0, idx1):
148
+ if normalized_audio is None:
149
+ logger.debug(f"{sid}-{idx0}-{idx1}-filtered")
150
+ return
151
+
152
+ wavfile.write(os.path.join(self.gt_wavs_dir, f"{sid}_{idx0}_{idx1}.wav"), self.sr, normalized_audio.astype(np.float32))
153
+ wavfile.write(os.path.join(self.wavs16k_dir, f"{sid}_{idx0}_{idx1}.wav"), SAMPLE_RATE_16K, librosa.resample(normalized_audio, orig_sr=self.sr, target_sr=SAMPLE_RATE_16K, res_type="soxr_vhq").astype(np.float32))
154
+
155
+ def process_audio(self, path, idx0, sid, cut_preprocess, process_effects, clean_dataset, clean_strength):
156
+ try:
157
+ audio = load_audio(logger, path, self.sr)
158
+
159
+ if process_effects:
160
+ audio = signal.lfilter(self.b_high, self.a_high, audio)
161
+ audio = self._normalize_audio(audio)
162
+
163
+ if clean_dataset:
164
+ from main.tools.noisereduce import reduce_noise
165
+ audio = reduce_noise(y=audio, sr=self.sr, prop_decrease=clean_strength, device=config.device)
166
+
167
+ idx1 = 0
168
+ if cut_preprocess:
169
+ for audio_segment in self.slicer.slice(audio):
170
+ i = 0
171
+
172
+ while 1:
173
+ start = int(self.sr * (self.per - OVERLAP) * i)
174
+ i += 1
175
+
176
+ if len(audio_segment[start:]) > (self.per + OVERLAP) * self.sr:
177
+ self.process_audio_segment(audio_segment[start : start + int(self.per * self.sr)], sid, idx0, idx1)
178
+ idx1 += 1
179
+ else:
180
+ self.process_audio_segment(audio_segment[start:], sid, idx0, idx1)
181
+ idx1 += 1
182
+ break
183
+ else: self.process_audio_segment(audio, sid, idx0, idx1)
184
+ except Exception as e:
185
+ raise RuntimeError(f"{translations['process_audio_error']}: {e}")
186
+
187
+ def process_file(args):
188
+ pp, file, cut_preprocess, process_effects, clean_dataset, clean_strength = (args)
189
+ file_path, idx0, sid = file
190
+ pp.process_audio(file_path, idx0, sid, cut_preprocess, process_effects, clean_dataset, clean_strength)
191
+
192
+ def preprocess_training_set(input_root, sr, num_processes, exp_dir, per, cut_preprocess, process_effects, clean_dataset, clean_strength):
193
+ start_time = time.time()
194
+
195
+ pp = PreProcess(sr, exp_dir, per)
196
+ logger.info(translations["start_preprocess"].format(num_processes=num_processes))
197
+ files = []
198
+ idx = 0
199
+
200
+ for root, _, filenames in os.walk(input_root):
201
+ try:
202
+ sid = 0 if root == input_root else int(os.path.basename(root))
203
+
204
+ for f in filenames:
205
+ if f.lower().endswith(("wav", "mp3", "flac", "ogg", "opus", "m4a", "mp4", "aac", "alac", "wma", "aiff", "webm", "ac3")):
206
+ files.append((os.path.join(root, f), idx, sid))
207
+ idx += 1
208
+ except ValueError:
209
+ raise ValueError(f"{translations['not_integer']} '{os.path.basename(root)}'.")
210
+
211
+ with tqdm(total=len(files), ncols=100, unit="f") as pbar:
212
+ with ProcessPoolExecutor(max_workers=num_processes) as executor:
213
+ futures = [executor.submit(process_file, (pp, file, cut_preprocess, process_effects, clean_dataset, clean_strength)) for file in files]
214
+ for future in as_completed(futures):
215
+ try:
216
+ future.result()
217
+ except Exception as e:
218
+ raise RuntimeError(f"{translations['process_error']}: {e}")
219
+ pbar.update(1)
220
+ logger.debug(pbar.format_meter(pbar.n, pbar.total, pbar.format_dict["elapsed"]))
221
+
222
+ elapsed_time = time.time() - start_time
223
+ logger.info(translations["preprocess_success"].format(elapsed_time=f"{elapsed_time:.2f}"))
224
+
225
+ def main():
226
+ args = parse_arguments()
227
+ experiment_directory = os.path.join("assets", "logs", args.model_name)
228
+
229
+ num_processes = args.cpu_cores
230
+ num_processes = 2 if num_processes is None else int(num_processes)
231
+
232
+ dataset, sample_rate, cut_preprocess, preprocess_effects, clean_dataset, clean_strength = args.dataset_path, args.sample_rate, args.cut_preprocess, args.process_effects, args.clean_dataset, args.clean_strength
233
+
234
+ os.makedirs(experiment_directory, exist_ok=True)
235
+
236
+ if logger.hasHandlers(): logger.handlers.clear()
237
+ else:
238
+ console_handler = logging.StreamHandler()
239
+ console_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
240
+ console_handler.setFormatter(console_formatter)
241
+ console_handler.setLevel(logging.INFO)
242
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join(experiment_directory, "preprocess.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
243
+ file_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
244
+ file_handler.setFormatter(file_formatter)
245
+ file_handler.setLevel(logging.DEBUG)
246
+ logger.addHandler(console_handler)
247
+ logger.addHandler(file_handler)
248
+ logger.setLevel(logging.DEBUG)
249
+
250
+ log_data = {translations['modelname']: args.model_name, translations['export_process']: experiment_directory, translations['dataset_folder']: dataset, translations['pretrain_sr']: sample_rate, translations['cpu_core']: num_processes, translations['split_audio']: cut_preprocess, translations['preprocess_effect']: preprocess_effects, translations['clear_audio']: clean_dataset}
251
+ if clean_dataset: log_data[translations['clean_strength']] = clean_strength
252
+
253
+ for key, value in log_data.items():
254
+ logger.debug(f"{key}: {value}")
255
+
256
+ pid_path = os.path.join(experiment_directory, "preprocess_pid.txt")
257
+ with open(pid_path, "w") as pid_file:
258
+ pid_file.write(str(os.getpid()))
259
+
260
+ try:
261
+ preprocess_training_set(dataset, sample_rate, num_processes, experiment_directory, config.per_preprocess, cut_preprocess, preprocess_effects, clean_dataset, clean_strength)
262
+ except Exception as e:
263
+ logger.error(f"{translations['process_audio_error']} {e}")
264
+ import traceback
265
+ logger.debug(traceback.format_exc())
266
+
267
+ if os.path.exists(pid_path): os.remove(pid_path)
268
+ logger.info(f"{translations['preprocess_model_success']} {args.model_name}")
269
+
270
+ if __name__ == "__main__": main()
main/inference/separator_music.py ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import time
4
+ import logging
5
+ import argparse
6
+ import logging.handlers
7
+
8
+ import numpy as np
9
+
10
+ from distutils.util import strtobool
11
+
12
+ sys.path.append(os.getcwd())
13
+
14
+ from main.configs.config import Config
15
+ from main.library.algorithm.separator import Separator
16
+ from main.library.utils import pydub_convert, pydub_load
17
+
18
+ config = Config()
19
+ translations = config.translations
20
+ logger = logging.getLogger(__name__)
21
+
22
+ if logger.hasHandlers(): logger.handlers.clear()
23
+ else:
24
+ console_handler = logging.StreamHandler()
25
+ console_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
26
+ console_handler.setFormatter(console_formatter)
27
+ console_handler.setLevel(logging.INFO)
28
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join("assets", "logs", "separator.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
29
+ file_formatter = logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
30
+ file_handler.setFormatter(file_formatter)
31
+ file_handler.setLevel(logging.DEBUG)
32
+ logger.addHandler(console_handler)
33
+ logger.addHandler(file_handler)
34
+ logger.setLevel(logging.DEBUG)
35
+
36
+ demucs_models = {"HT-Tuned": "htdemucs_ft.yaml", "HT-Normal": "htdemucs.yaml", "HD_MMI": "hdemucs_mmi.yaml", "HT_6S": "htdemucs_6s.yaml"}
37
+ mdx_models = {"Main_340": "UVR-MDX-NET_Main_340.onnx", "Main_390": "UVR-MDX-NET_Main_390.onnx", "Main_406": "UVR-MDX-NET_Main_406.onnx", "Main_427": "UVR-MDX-NET_Main_427.onnx","Main_438": "UVR-MDX-NET_Main_438.onnx", "Inst_full_292": "UVR-MDX-NET-Inst_full_292.onnx", "Inst_HQ_1": "UVR-MDX-NET-Inst_HQ_1.onnx", "Inst_HQ_2": "UVR-MDX-NET-Inst_HQ_2.onnx", "Inst_HQ_3": "UVR-MDX-NET-Inst_HQ_3.onnx", "Inst_HQ_4": "UVR-MDX-NET-Inst_HQ_4.onnx", "Inst_HQ_5": "UVR-MDX-NET-Inst_HQ_5.onnx", "Kim_Vocal_1": "Kim_Vocal_1.onnx", "Kim_Vocal_2": "Kim_Vocal_2.onnx", "Kim_Inst": "Kim_Inst.onnx", "Inst_187_beta": "UVR-MDX-NET_Inst_187_beta.onnx", "Inst_82_beta": "UVR-MDX-NET_Inst_82_beta.onnx", "Inst_90_beta": "UVR-MDX-NET_Inst_90_beta.onnx", "Voc_FT": "UVR-MDX-NET-Voc_FT.onnx", "Crowd_HQ": "UVR-MDX-NET_Crowd_HQ_1.onnx", "MDXNET_9482": "UVR_MDXNET_9482.onnx", "Inst_1": "UVR-MDX-NET-Inst_1.onnx", "Inst_2": "UVR-MDX-NET-Inst_2.onnx", "Inst_3": "UVR-MDX-NET-Inst_3.onnx", "MDXNET_1_9703": "UVR_MDXNET_1_9703.onnx", "MDXNET_2_9682": "UVR_MDXNET_2_9682.onnx", "MDXNET_3_9662": "UVR_MDXNET_3_9662.onnx", "Inst_Main": "UVR-MDX-NET-Inst_Main.onnx", "MDXNET_Main": "UVR_MDXNET_Main.onnx"}
38
+ kara_models = {"Version-1": "UVR_MDXNET_KARA.onnx", "Version-2": "UVR_MDXNET_KARA_2.onnx"}
39
+
40
+ def parse_arguments():
41
+ parser = argparse.ArgumentParser()
42
+ parser.add_argument("--input_path", type=str, required=True)
43
+ parser.add_argument("--output_path", type=str, default="./audios")
44
+ parser.add_argument("--format", type=str, default="wav")
45
+ parser.add_argument("--shifts", type=int, default=2)
46
+ parser.add_argument("--segments_size", type=int, default=256)
47
+ parser.add_argument("--overlap", type=float, default=0.25)
48
+ parser.add_argument("--mdx_hop_length", type=int, default=1024)
49
+ parser.add_argument("--mdx_batch_size", type=int, default=1)
50
+ parser.add_argument("--clean_audio", type=lambda x: bool(strtobool(x)), default=False)
51
+ parser.add_argument("--clean_strength", type=float, default=0.7)
52
+ parser.add_argument("--model_name", type=str, default="HT-Normal")
53
+ parser.add_argument("--kara_model", type=str, default="Version-1")
54
+ parser.add_argument("--backing", type=lambda x: bool(strtobool(x)), default=False)
55
+ parser.add_argument("--mdx_denoise", type=lambda x: bool(strtobool(x)), default=False)
56
+ parser.add_argument("--reverb", type=lambda x: bool(strtobool(x)), default=False)
57
+ parser.add_argument("--backing_reverb", type=lambda x: bool(strtobool(x)), default=False)
58
+ parser.add_argument("--sample_rate", type=int, default=44100)
59
+
60
+ return parser.parse_args()
61
+
62
+ def main():
63
+ start_time = time.time()
64
+ pid_path = os.path.join("assets", "separate_pid.txt")
65
+
66
+ with open(pid_path, "w") as pid_file:
67
+ pid_file.write(str(os.getpid()))
68
+
69
+ try:
70
+ args = parse_arguments()
71
+ input_path, output_path, export_format, shifts, segments_size, overlap, hop_length, batch_size, clean_audio, clean_strength, model_name, kara_model, backing, mdx_denoise, reverb, backing_reverb, sample_rate = args.input_path, args.output_path, args.format, args.shifts, args.segments_size, args.overlap, args.mdx_hop_length, args.mdx_batch_size, args.clean_audio, args.clean_strength, args.model_name, args.kara_model, args.backing, args.mdx_denoise, args.reverb, args.backing_reverb, args.sample_rate
72
+
73
+ if backing_reverb and not reverb:
74
+ logger.warning(translations["turn_on_dereverb"])
75
+ sys.exit(1)
76
+
77
+ if backing_reverb and not backing:
78
+ logger.warning(translations["turn_on_separator_backing"])
79
+ sys.exit(1)
80
+
81
+ input_path = input_path.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
82
+ output_path = os.path.dirname(output_path) or output_path
83
+
84
+ log_data = {translations['audio_path']: input_path, translations['output_path']: output_path, translations['export_format']: export_format, translations['shift']: shifts, translations['segments_size']: segments_size, translations['overlap']: overlap, translations['modelname']: model_name, translations['denoise_mdx']: mdx_denoise, "Hop length": hop_length, translations['batch_size']: batch_size, translations['sr']: sample_rate}
85
+
86
+ if clean_audio:
87
+ log_data[translations['clear_audio']] = clean_audio
88
+ log_data[translations['clean_strength']] = clean_strength
89
+
90
+ if backing:
91
+ log_data[translations['backing_model_ver']] = kara_model
92
+ log_data[translations['separator_backing']] = backing
93
+
94
+ if reverb:
95
+ log_data[translations['dereveb_audio']] = reverb
96
+ log_data[translations['dereveb_backing']] = backing_reverb
97
+
98
+ for key, value in log_data.items():
99
+ logger.debug(f"{key}: {value}")
100
+
101
+ if os.path.isdir(input_path):
102
+ for f in input_path:
103
+ separation(f, output_path, export_format, shifts, overlap, segments_size, model_name, sample_rate, mdx_denoise, hop_length, batch_size, backing, reverb, kara_model, backing_reverb, clean_audio, clean_strength)
104
+ else: separation(input_path, output_path, export_format, shifts, overlap, segments_size, model_name, sample_rate, mdx_denoise, hop_length, batch_size, backing, reverb, kara_model, backing_reverb, clean_audio, clean_strength)
105
+
106
+ except Exception as e:
107
+ logger.error(f"{translations['separator_error']}: {e}")
108
+ import traceback
109
+ logger.debug(traceback.format_exc())
110
+
111
+ if os.path.exists(pid_path): os.remove(pid_path)
112
+ elapsed_time = time.time() - start_time
113
+ logger.info(translations["separator_success"].format(elapsed_time=f"{elapsed_time:.2f}"))
114
+
115
+ def separation(input_path, output_path, export_format, shifts, overlap, segments_size, model_name, sample_rate, mdx_denoise, hop_length, batch_size, backing, reverb, kara_model, backing_reverb, clean_audio, clean_strength):
116
+ filename, _ = os.path.splitext(os.path.basename(input_path))
117
+ output_path = os.path.join(output_path, filename)
118
+ os.makedirs(output_path, exist_ok=True)
119
+
120
+ if model_name in ["HT-Tuned", "HT-Normal", "HD_MMI", "HT_6S"]: vocals, _ = separator_music_demucs(input_path, output_path, export_format, shifts, overlap, segments_size, model_name, sample_rate)
121
+ else: vocals, _ = separator_music_mdx(input_path, output_path, export_format, segments_size, overlap, mdx_denoise, model_name, hop_length, batch_size, sample_rate)
122
+
123
+ if backing: main_vocals, backing_vocals = separator_backing(vocals, output_path, export_format, segments_size, overlap, mdx_denoise, kara_model, hop_length, batch_size, sample_rate)
124
+ if reverb: vocals_no_reverb, main_vocals_no_reverb, backing_vocals_no_reverb = separator_reverb(output_path, export_format, segments_size, overlap, mdx_denoise, reverb, backing_reverb, hop_length, batch_size, sample_rate)
125
+
126
+ original_output = os.path.join(output_path, f"Original_Vocals_No_Reverb.{export_format}") if reverb else os.path.join(output_path, f"Original_Vocals.{export_format}")
127
+ main_output = os.path.join(output_path, f"Main_Vocals_No_Reverb.{export_format}") if reverb and backing_reverb else os.path.join(output_path, f"Main_Vocals.{export_format}")
128
+ backing_output = os.path.join(output_path, f"Backing_Vocals_No_Reverb.{export_format}") if reverb and backing_reverb else os.path.join(output_path, f"Backing_Vocals.{export_format}")
129
+
130
+ if clean_audio:
131
+ import soundfile as sf
132
+
133
+ logger.info(f"{translations['clear_audio']}...")
134
+ vocal_data, vocal_sr = sf.read(vocals_no_reverb if reverb else vocals, dtype=np.float32)
135
+
136
+ from main.tools.noisereduce import reduce_noise
137
+ sf.write(original_output, reduce_noise(y=vocal_data, sr=vocal_sr, prop_decrease=clean_strength), vocal_sr, format=export_format, device=config.device)
138
+
139
+ if backing:
140
+ main_data, main_sr = sf.read(main_vocals_no_reverb if reverb and backing else main_vocals, dtype=np.float32)
141
+ backing_data, backing_sr = sf.read(backing_vocals_no_reverb if reverb and backing_reverb else backing_vocals, dtype=np.float32)
142
+
143
+ sf.write(main_output, reduce_noise(y=main_data, sr=main_sr, prop_decrease=clean_strength), main_sr, format=export_format, device=config.device)
144
+ sf.write(backing_output, reduce_noise(y=backing_data, sr=backing_sr, prop_decrease=clean_strength), backing_sr, format=export_format, device=config.device)
145
+
146
+ logger.info(translations["clean_audio_success"])
147
+
148
+ def separator_music_demucs(input, output, format, shifts, overlap, segments_size, demucs_model, sample_rate):
149
+ if not os.path.exists(input):
150
+ logger.warning(translations["input_not_valid"])
151
+ sys.exit(1)
152
+
153
+ if not os.path.exists(output):
154
+ logger.warning(translations["output_not_valid"])
155
+ sys.exit(1)
156
+
157
+ for i in [f"Original_Vocals.{format}", f"Instruments.{format}"]:
158
+ if os.path.exists(os.path.join(output, i)): os.remove(os.path.join(output, i))
159
+
160
+ logger.info(f"{translations['separator_process_2']}...")
161
+ demucs_output = separator_main(audio_file=input, model_filename=demucs_models.get(demucs_model), output_format=format, output_dir=output, demucs_segment_size=(segments_size / 2), demucs_shifts=shifts, demucs_overlap=overlap, sample_rate=sample_rate)
162
+
163
+ for f in demucs_output:
164
+ path = os.path.join(output, f)
165
+ if not os.path.exists(path): logger.error(translations["not_found"].format(name=path))
166
+
167
+ if '_(Drums)_' in f: drums = path
168
+ elif '_(Bass)_' in f: bass = path
169
+ elif '_(Other)_' in f: other = path
170
+ elif '_(Vocals)_' in f: os.rename(path, os.path.join(output, f"Original_Vocals.{format}"))
171
+
172
+ pydub_convert(pydub_load(drums)).overlay(pydub_convert(pydub_load(bass))).overlay(pydub_convert(pydub_load(other))).export(os.path.join(output, f"Instruments.{format}"), format=format)
173
+
174
+ for f in [drums, bass, other]:
175
+ if os.path.exists(f): os.remove(f)
176
+
177
+ logger.info(translations["separator_success_2"])
178
+ return os.path.join(output, f"Original_Vocals.{format}"), os.path.join(output, f"Instruments.{format}")
179
+
180
+ def separator_backing(input, output, format, segments_size, overlap, denoise, kara_model, hop_length, batch_size, sample_rate):
181
+ if not os.path.exists(input):
182
+ logger.warning(translations["input_not_valid"])
183
+ sys.exit(1)
184
+
185
+ if not os.path.exists(output):
186
+ logger.warning(translations["output_not_valid"])
187
+ sys.exit(1)
188
+
189
+ for f in [f"Main_Vocals.{format}", f"Backing_Vocals.{format}"]:
190
+ if os.path.exists(os.path.join(output, f)): os.remove(os.path.join(output, f))
191
+
192
+ model_2 = kara_models.get(kara_model)
193
+ logger.info(f"{translations['separator_process_backing']}...")
194
+
195
+ backing_outputs = separator_main(audio_file=input, model_filename=model_2, output_format=format, output_dir=output, mdx_segment_size=segments_size, mdx_overlap=overlap, mdx_batch_size=batch_size, mdx_hop_length=hop_length, mdx_enable_denoise=denoise, sample_rate=sample_rate)
196
+ main_output = os.path.join(output, f"Main_Vocals.{format}")
197
+ backing_output = os.path.join(output, f"Backing_Vocals.{format}")
198
+
199
+ for f in backing_outputs:
200
+ path = os.path.join(output, f)
201
+ if not os.path.exists(path): logger.error(translations["not_found"].format(name=path))
202
+
203
+ if '_(Instrumental)_' in f: os.rename(path, backing_output)
204
+ elif '_(Vocals)_' in f: os.rename(path, main_output)
205
+
206
+ logger.info(translations["separator_process_backing_success"])
207
+ return main_output, backing_output
208
+
209
+ def separator_music_mdx(input, output, format, segments_size, overlap, denoise, mdx_model, hop_length, batch_size, sample_rate):
210
+ if not os.path.exists(input):
211
+ logger.warning(translations["input_not_valid"])
212
+ sys.exit(1)
213
+
214
+ if not os.path.exists(output):
215
+ logger.warning(translations["output_not_valid"])
216
+ sys.exit(1)
217
+
218
+ for i in [f"Original_Vocals.{format}", f"Instruments.{format}"]:
219
+ if os.path.exists(os.path.join(output, i)): os.remove(os.path.join(output, i))
220
+
221
+ model_3 = mdx_models.get(mdx_model)
222
+ logger.info(f"{translations['separator_process_2']}...")
223
+
224
+ output_music = separator_main(audio_file=input, model_filename=model_3, output_format=format, output_dir=output, mdx_segment_size=segments_size, mdx_overlap=overlap, mdx_batch_size=batch_size, mdx_hop_length=hop_length, mdx_enable_denoise=denoise, sample_rate=sample_rate)
225
+ original_output, instruments_output = os.path.join(output, f"Original_Vocals.{format}"), os.path.join(output, f"Instruments.{format}")
226
+
227
+ for f in output_music:
228
+ path = os.path.join(output, f)
229
+ if not os.path.exists(path): logger.error(translations["not_found"].format(name=path))
230
+
231
+ if '_(Instrumental)_' in f: os.rename(path, instruments_output)
232
+ elif '_(Vocals)_' in f: os.rename(path, original_output)
233
+
234
+ logger.info(translations["separator_process_backing_success"])
235
+ return original_output, instruments_output
236
+
237
+ def separator_reverb(output, format, segments_size, overlap, denoise, original, backing_reverb, hop_length, batch_size, sample_rate):
238
+ if not os.path.exists(output):
239
+ logger.warning(translations["output_not_valid"])
240
+ sys.exit(1)
241
+
242
+ for i in [f"Original_Vocals_Reverb.{format}", f"Main_Vocals_Reverb.{format}", f"Original_Vocals_No_Reverb.{format}", f"Main_Vocals_No_Reverb.{format}"]:
243
+ if os.path.exists(os.path.join(output, i)): os.remove(os.path.join(output, i))
244
+
245
+ dereveb_path = []
246
+
247
+ if original:
248
+ try:
249
+ dereveb_path.append(os.path.join(output, [f for f in os.listdir(output) if 'Original_Vocals' in f][0]))
250
+ except IndexError:
251
+ logger.warning(translations["not_found_original_vocal"])
252
+ sys.exit(1)
253
+
254
+ if backing_reverb:
255
+ try:
256
+ dereveb_path.append(os.path.join(output, [f for f in os.listdir(output) if 'Main_Vocals' in f][0]))
257
+ except IndexError:
258
+ logger.warning(translations["not_found_main_vocal"])
259
+ sys.exit(1)
260
+
261
+ if backing_reverb:
262
+ try:
263
+ dereveb_path.append(os.path.join(output, [f for f in os.listdir(output) if 'Backing_Vocals' in f][0]))
264
+ except IndexError:
265
+ logger.warning(translations["not_found_backing_vocal"])
266
+ sys.exit(1)
267
+
268
+ for path in dereveb_path:
269
+ if not os.path.exists(path):
270
+ logger.warning(translations["not_found"].format(name=path))
271
+ sys.exit(1)
272
+
273
+ if "Original_Vocals" in path:
274
+ reverb_path, no_reverb_path = os.path.join(output, f"Original_Vocals_Reverb.{format}"), os.path.join(output, f"Original_Vocals_No_Reverb.{format}")
275
+ start_title, end_title = translations["process_original"], translations["process_original_success"]
276
+ elif "Main_Vocals" in path:
277
+ reverb_path, no_reverb_path = os.path.join(output, f"Main_Vocals_Reverb.{format}"), os.path.join(output, f"Main_Vocals_No_Reverb.{format}")
278
+ start_title, end_title = translations["process_main"], translations["process_main_success"]
279
+ elif "Backing_Vocals" in path:
280
+ reverb_path, no_reverb_path = os.path.join(output, f"Backing_Vocals_Reverb.{format}"), os.path.join(output, f"Backing_Vocals_No_Reverb.{format}")
281
+ start_title, end_title = translations["process_backing"], translations["process_backing_success"]
282
+
283
+ logger.info(start_title)
284
+ output_dereveb = separator_main(audio_file=path, model_filename="Reverb_HQ_By_FoxJoy.onnx", output_format=format, output_dir=output, mdx_segment_size=segments_size, mdx_overlap=overlap, mdx_batch_size=batch_size, mdx_hop_length=hop_length, mdx_enable_denoise=denoise, sample_rate=sample_rate)
285
+
286
+ for f in output_dereveb:
287
+ path = os.path.join(output, f)
288
+ if not os.path.exists(path): logger.error(translations["not_found"].format(name=path))
289
+
290
+ if '_(Reverb)_' in f: os.rename(path, reverb_path)
291
+ elif '_(No Reverb)_' in f: os.rename(path, no_reverb_path)
292
+
293
+ logger.info(end_title)
294
+
295
+ return (os.path.join(output, f"Original_Vocals_No_Reverb.{format}") if original else None), (os.path.join(output, f"Main_Vocals_No_Reverb.{format}") if backing_reverb else None), (os.path.join(output, f"Backing_Vocals_No_Reverb.{format}") if backing_reverb else None)
296
+
297
+ def separator_main(audio_file=None, model_filename="UVR-MDX-NET_Main_340.onnx", output_format="wav", output_dir=".", mdx_segment_size=256, mdx_overlap=0.25, mdx_batch_size=1, mdx_hop_length=1024, mdx_enable_denoise=True, demucs_segment_size=256, demucs_shifts=2, demucs_overlap=0.25, sample_rate=44100):
298
+ try:
299
+ separator = Separator(logger=logger, log_formatter=file_formatter, log_level=logging.INFO, output_dir=output_dir, output_format=output_format, output_bitrate=None, normalization_threshold=0.9, output_single_stem=None, invert_using_spec=False, sample_rate=sample_rate, mdx_params={"hop_length": mdx_hop_length, "segment_size": mdx_segment_size, "overlap": mdx_overlap, "batch_size": mdx_batch_size, "enable_denoise": mdx_enable_denoise}, demucs_params={"segment_size": demucs_segment_size, "shifts": demucs_shifts, "overlap": demucs_overlap, "segments_enabled": True})
300
+ separator.load_model(model_filename=model_filename)
301
+
302
+ return separator.separate(audio_file)
303
+ except:
304
+ logger.debug(translations["default_setting"])
305
+ separator = Separator(logger=logger, log_formatter=file_formatter, log_level=logging.INFO, output_dir=output_dir, output_format=output_format, output_bitrate=None, normalization_threshold=0.9, output_single_stem=None, invert_using_spec=False, sample_rate=44100, mdx_params={"hop_length": 1024, "segment_size": 256, "overlap": 0.25, "batch_size": 1, "enable_denoise": mdx_enable_denoise}, demucs_params={"segment_size": 128, "shifts": 2, "overlap": 0.25, "segments_enabled": True})
306
+ separator.load_model(model_filename=model_filename)
307
+
308
+ return separator.separate(audio_file)
309
+
310
+ if __name__ == "__main__": main()
main/inference/train.py ADDED
@@ -0,0 +1,990 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import glob
4
+ import json
5
+ import torch
6
+ import hashlib
7
+ import logging
8
+ import argparse
9
+ import datetime
10
+ import warnings
11
+ import logging.handlers
12
+
13
+ import numpy as np
14
+ import soundfile as sf
15
+ import matplotlib.pyplot as plt
16
+ import torch.distributed as dist
17
+ import torch.utils.data as tdata
18
+ import torch.multiprocessing as mp
19
+
20
+ from tqdm import tqdm
21
+ from collections import OrderedDict
22
+ from random import randint, shuffle
23
+ from torch.utils.checkpoint import checkpoint
24
+ from torch.cuda.amp import GradScaler, autocast
25
+ from torch.utils.tensorboard import SummaryWriter
26
+
27
+ from time import time as ttime
28
+ from torch.nn import functional as F
29
+ from distutils.util import strtobool
30
+ from librosa.filters import mel as librosa_mel_fn
31
+ from torch.nn.parallel import DistributedDataParallel as DDP
32
+ from torch.nn.utils.parametrizations import spectral_norm, weight_norm
33
+
34
+ sys.path.append(os.getcwd())
35
+
36
+ from main.configs.config import Config
37
+ from main.library.algorithm.residuals import LRELU_SLOPE
38
+ from main.library.algorithm.synthesizers import Synthesizer
39
+ from main.library.algorithm.commons import get_padding, slice_segments, clip_grad_value
40
+
41
+ MATPLOTLIB_FLAG = False
42
+ main_config = Config()
43
+ translations = main_config.translations
44
+ warnings.filterwarnings("ignore")
45
+ logging.getLogger("torch").setLevel(logging.ERROR)
46
+
47
+ class HParams:
48
+ def __init__(self, **kwargs):
49
+ for k, v in kwargs.items():
50
+ self[k] = HParams(**v) if isinstance(v, dict) else v
51
+
52
+ def keys(self):
53
+ return self.__dict__.keys()
54
+
55
+ def items(self):
56
+ return self.__dict__.items()
57
+
58
+ def values(self):
59
+ return self.__dict__.values()
60
+
61
+ def __len__(self):
62
+ return len(self.__dict__)
63
+
64
+ def __getitem__(self, key):
65
+ return self.__dict__[key]
66
+
67
+ def __setitem__(self, key, value):
68
+ self.__dict__[key] = value
69
+
70
+ def __contains__(self, key):
71
+ return key in self.__dict__
72
+
73
+ def __repr__(self):
74
+ return repr(self.__dict__)
75
+
76
+ def parse_arguments():
77
+ parser = argparse.ArgumentParser()
78
+ parser.add_argument("--model_name", type=str, required=True)
79
+ parser.add_argument("--rvc_version", type=str, default="v2")
80
+ parser.add_argument("--save_every_epoch", type=int, required=True)
81
+ parser.add_argument("--save_only_latest", type=lambda x: bool(strtobool(x)), default=True)
82
+ parser.add_argument("--save_every_weights", type=lambda x: bool(strtobool(x)), default=True)
83
+ parser.add_argument("--total_epoch", type=int, default=300)
84
+ parser.add_argument("--sample_rate", type=int, required=True)
85
+ parser.add_argument("--batch_size", type=int, default=8)
86
+ parser.add_argument("--gpu", type=str, default="0")
87
+ parser.add_argument("--pitch_guidance", type=lambda x: bool(strtobool(x)), default=True)
88
+ parser.add_argument("--g_pretrained_path", type=str, default="")
89
+ parser.add_argument("--d_pretrained_path", type=str, default="")
90
+ parser.add_argument("--overtraining_detector", type=lambda x: bool(strtobool(x)), default=False)
91
+ parser.add_argument("--overtraining_threshold", type=int, default=50)
92
+ parser.add_argument("--cleanup", type=lambda x: bool(strtobool(x)), default=False)
93
+ parser.add_argument("--cache_data_in_gpu", type=lambda x: bool(strtobool(x)), default=False)
94
+ parser.add_argument("--model_author", type=str)
95
+ parser.add_argument("--vocoder", type=str, default="Default")
96
+ parser.add_argument("--checkpointing", type=lambda x: bool(strtobool(x)), default=False)
97
+ parser.add_argument("--deterministic", type=lambda x: bool(strtobool(x)), default=False)
98
+ parser.add_argument("--benchmark", type=lambda x: bool(strtobool(x)), default=False)
99
+
100
+ return parser.parse_args()
101
+
102
+ args = parse_arguments()
103
+ model_name, save_every_epoch, total_epoch, pretrainG, pretrainD, version, gpus, batch_size, sample_rate, pitch_guidance, save_only_latest, save_every_weights, cache_data_in_gpu, overtraining_detector, overtraining_threshold, cleanup, model_author, vocoder, checkpointing = args.model_name, args.save_every_epoch, args.total_epoch, args.g_pretrained_path, args.d_pretrained_path, args.rvc_version, args.gpu, args.batch_size, args.sample_rate, args.pitch_guidance, args.save_only_latest, args.save_every_weights, args.cache_data_in_gpu, args.overtraining_detector, args.overtraining_threshold, args.cleanup, args.model_author, args.vocoder, args.checkpointing
104
+
105
+ experiment_dir = os.path.join("assets", "logs", model_name)
106
+ training_file_path = os.path.join(experiment_dir, "training_data.json")
107
+ config_save_path = os.path.join(experiment_dir, "config.json")
108
+ torch.backends.cudnn.deterministic = args.deterministic
109
+ torch.backends.cudnn.benchmark = args.benchmark
110
+ lowest_value = {"step": 0, "value": float("inf"), "epoch": 0}
111
+ global_step, last_loss_gen_all, overtrain_save_epoch = 0, 0, 0
112
+ loss_gen_history, smoothed_loss_gen_history, loss_disc_history, smoothed_loss_disc_history = [], [], [], []
113
+
114
+ with open(config_save_path, "r") as f:
115
+ config = json.load(f)
116
+
117
+ config = HParams(**config)
118
+ config.data.training_files = os.path.join(experiment_dir, "filelist.txt")
119
+ logger = logging.getLogger(__name__)
120
+
121
+ if logger.hasHandlers(): logger.handlers.clear()
122
+ else:
123
+ console_handler = logging.StreamHandler()
124
+ console_handler.setFormatter(logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S"))
125
+ console_handler.setLevel(logging.INFO)
126
+ file_handler = logging.handlers.RotatingFileHandler(os.path.join(experiment_dir, "train.log"), maxBytes=5*1024*1024, backupCount=3, encoding='utf-8')
127
+ file_handler.setFormatter(logging.Formatter(fmt="\n%(asctime)s.%(msecs)03d | %(levelname)s | %(module)s | %(message)s", datefmt="%Y-%m-%d %H:%M:%S"))
128
+ file_handler.setLevel(logging.DEBUG)
129
+ logger.addHandler(console_handler)
130
+ logger.addHandler(file_handler)
131
+ logger.setLevel(logging.DEBUG)
132
+
133
+ log_data = {translations['modelname']: model_name, translations["save_every_epoch"]: save_every_epoch, translations["total_e"]: total_epoch, translations["dorg"].format(pretrainG=pretrainG, pretrainD=pretrainD): "", translations['training_version']: version, "Gpu": gpus, translations['batch_size']: batch_size, translations['pretrain_sr']: sample_rate, translations['training_f0']: pitch_guidance, translations['save_only_latest']: save_only_latest, translations['save_every_weights']: save_every_weights, translations['cache_in_gpu']: cache_data_in_gpu, translations['overtraining_detector']: overtraining_detector, translations['threshold']: overtraining_threshold, translations['cleanup_training']: cleanup, translations['memory_efficient_training']: checkpointing}
134
+ if model_author: log_data[translations["model_author"].format(model_author=model_author)] = ""
135
+ if vocoder != "Default": log_data[translations['vocoder']] = vocoder
136
+
137
+ for key, value in log_data.items():
138
+ logger.debug(f"{key}: {value}" if value != "" else f"{key} {value}")
139
+
140
+ def main():
141
+ global training_file_path, last_loss_gen_all, smoothed_loss_gen_history, loss_gen_history, loss_disc_history, smoothed_loss_disc_history, overtrain_save_epoch, model_author, vocoder, checkpointing, gpus
142
+
143
+ try:
144
+ os.environ["MASTER_ADDR"] = "localhost"
145
+ os.environ["MASTER_PORT"] = str(randint(20000, 55555))
146
+
147
+ if torch.cuda.is_available():
148
+ device, gpus = torch.device("cuda"), [int(item) for item in gpus.split("-")]
149
+ n_gpus = len(gpus)
150
+ elif torch.backends.mps.is_available():
151
+ device, gpus = torch.device("mps"), [0]
152
+ n_gpus = 1
153
+ else:
154
+ device, gpus = torch.device("cpu"), [0]
155
+ n_gpus = 1
156
+ logger.warning(translations["not_gpu"])
157
+
158
+ def start():
159
+ children = []
160
+ pid_data = {"process_pids": []}
161
+
162
+ with open(config_save_path, "r") as pid_file:
163
+ try:
164
+ pid_data.update(json.load(pid_file))
165
+ except json.JSONDecodeError:
166
+ pass
167
+
168
+ with open(config_save_path, "w") as pid_file:
169
+ for rank, device_id in enumerate(gpus):
170
+ subproc = mp.Process(target=run, args=(rank, n_gpus, experiment_dir, pretrainG, pretrainD, pitch_guidance, total_epoch, save_every_weights, config, device, device_id, model_author, vocoder, checkpointing))
171
+ children.append(subproc)
172
+ subproc.start()
173
+ pid_data["process_pids"].append(subproc.pid)
174
+
175
+ json.dump(pid_data, pid_file, indent=4)
176
+
177
+ for i in range(n_gpus):
178
+ children[i].join()
179
+
180
+ def load_from_json(file_path):
181
+ if os.path.exists(file_path):
182
+ with open(file_path, "r") as f:
183
+ data = json.load(f)
184
+ return (data.get("loss_disc_history", []), data.get("smoothed_loss_disc_history", []), data.get("loss_gen_history", []), data.get("smoothed_loss_gen_history", []))
185
+ return [], [], [], []
186
+
187
+ def continue_overtrain_detector(training_file_path):
188
+ if overtraining_detector and os.path.exists(training_file_path): (loss_disc_history, smoothed_loss_disc_history, loss_gen_history, smoothed_loss_gen_history) = load_from_json(training_file_path)
189
+
190
+ if cleanup:
191
+ for root, dirs, files in os.walk(experiment_dir, topdown=False):
192
+ for name in files:
193
+ file_path = os.path.join(root, name)
194
+ _, file_extension = os.path.splitext(name)
195
+ if (file_extension == ".0" or (name.startswith("D_") and file_extension == ".pth") or (name.startswith("G_") and file_extension == ".pth") or (file_extension == ".index")): os.remove(file_path)
196
+
197
+ for name in dirs:
198
+ if name == "eval":
199
+ folder_path = os.path.join(root, name)
200
+ for item in os.listdir(folder_path):
201
+ item_path = os.path.join(folder_path, item)
202
+ if os.path.isfile(item_path): os.remove(item_path)
203
+ os.rmdir(folder_path)
204
+
205
+ continue_overtrain_detector(training_file_path)
206
+ start()
207
+ except Exception as e:
208
+ logger.error(f"{translations['training_error']} {e}")
209
+ import traceback
210
+ logger.debug(traceback.format_exc())
211
+
212
+ def plot_spectrogram_to_numpy(spectrogram):
213
+ global MATPLOTLIB_FLAG
214
+
215
+ if not MATPLOTLIB_FLAG:
216
+ plt.switch_backend("Agg")
217
+ MATPLOTLIB_FLAG = True
218
+
219
+ fig, ax = plt.subplots(figsize=(10, 2))
220
+ plt.colorbar(ax.imshow(spectrogram, aspect="auto", origin="lower", interpolation="none"), ax=ax)
221
+ plt.xlabel("Frames")
222
+ plt.ylabel("Channels")
223
+ plt.tight_layout()
224
+ fig.canvas.draw()
225
+ plt.close(fig)
226
+
227
+ try:
228
+ data = np.array(fig.canvas.renderer.buffer_rgba(), dtype=np.uint8).reshape(fig.canvas.get_width_height()[::-1] + (4,))[:, :, :3]
229
+ except:
230
+ data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep="").reshape(fig.canvas.get_width_height()[::-1] + (3,))
231
+
232
+ return data
233
+
234
+ def verify_checkpoint_shapes(checkpoint_path, model):
235
+ checkpoint = torch.load(checkpoint_path, map_location="cpu")
236
+ checkpoint_state_dict = checkpoint["model"]
237
+ try:
238
+ model_state_dict = model.module.load_state_dict(checkpoint_state_dict) if hasattr(model, "module") else model.load_state_dict(checkpoint_state_dict)
239
+ except RuntimeError:
240
+ logger.warning(translations["checkpointing_err"])
241
+ sys.exit(1)
242
+ else: del checkpoint, checkpoint_state_dict, model_state_dict
243
+
244
+ def summarize(writer, global_step, scalars={}, histograms={}, images={}, audios={}, audio_sample_rate=22050):
245
+ for k, v in scalars.items():
246
+ writer.add_scalar(k, v, global_step)
247
+
248
+ for k, v in histograms.items():
249
+ writer.add_histogram(k, v, global_step)
250
+
251
+ for k, v in images.items():
252
+ writer.add_image(k, v, global_step, dataformats="HWC")
253
+
254
+ for k, v in audios.items():
255
+ writer.add_audio(k, v, global_step, audio_sample_rate)
256
+
257
+ def load_checkpoint(checkpoint_path, model, optimizer=None, load_opt=1):
258
+ assert os.path.isfile(checkpoint_path), translations["not_found_checkpoint"].format(checkpoint_path=checkpoint_path)
259
+ checkpoint_dict = replace_keys_in_dict(replace_keys_in_dict(torch.load(checkpoint_path, map_location="cpu"), ".weight_v", ".parametrizations.weight.original1"), ".weight_g", ".parametrizations.weight.original0")
260
+ new_state_dict = {k: checkpoint_dict["model"].get(k, v) for k, v in (model.module.state_dict() if hasattr(model, "module") else model.state_dict()).items()}
261
+
262
+ if hasattr(model, "module"): model.module.load_state_dict(new_state_dict, strict=False)
263
+ else: model.load_state_dict(new_state_dict, strict=False)
264
+
265
+ if optimizer and load_opt == 1: optimizer.load_state_dict(checkpoint_dict.get("optimizer", {}))
266
+ logger.debug(translations["save_checkpoint"].format(checkpoint_path=checkpoint_path, checkpoint_dict=checkpoint_dict['iteration']))
267
+ return (model, optimizer, checkpoint_dict.get("learning_rate", 0), checkpoint_dict["iteration"])
268
+
269
+ def save_checkpoint(model, optimizer, learning_rate, iteration, checkpoint_path):
270
+ state_dict = (model.module.state_dict() if hasattr(model, "module") else model.state_dict())
271
+ torch.save(replace_keys_in_dict(replace_keys_in_dict({"model": state_dict, "iteration": iteration, "optimizer": optimizer.state_dict(), "learning_rate": learning_rate}, ".parametrizations.weight.original1", ".weight_v"), ".parametrizations.weight.original0", ".weight_g"), checkpoint_path)
272
+ logger.info(translations["save_model"].format(checkpoint_path=checkpoint_path, iteration=iteration))
273
+
274
+ def latest_checkpoint_path(dir_path, regex="G_*.pth"):
275
+ checkpoints = sorted(glob.glob(os.path.join(dir_path, regex)), key=lambda f: int("".join(filter(str.isdigit, f))))
276
+ return checkpoints[-1] if checkpoints else None
277
+
278
+ def load_wav_to_torch(full_path):
279
+ data, sample_rate = sf.read(full_path, dtype=np.float32)
280
+ return torch.FloatTensor(data.astype(np.float32)), sample_rate
281
+
282
+ def load_filepaths_and_text(filename, split="|"):
283
+ with open(filename, encoding="utf-8") as f:
284
+ return [line.strip().split(split) for line in f]
285
+
286
+ def feature_loss(fmap_r, fmap_g):
287
+ loss = 0
288
+ for dr, dg in zip(fmap_r, fmap_g):
289
+ for rl, gl in zip(dr, dg):
290
+ loss += torch.mean(torch.abs(rl.float().detach() - gl.float()))
291
+ return loss * 2
292
+
293
+ def discriminator_loss(disc_real_outputs, disc_generated_outputs):
294
+ loss = 0
295
+ r_losses, g_losses = [], []
296
+
297
+ for dr, dg in zip(disc_real_outputs, disc_generated_outputs):
298
+ dr = dr.float()
299
+ dg = dg.float()
300
+ r_loss = torch.mean((1 - dr) ** 2)
301
+ g_loss = torch.mean(dg**2)
302
+ loss += r_loss + g_loss
303
+ r_losses.append(r_loss.item())
304
+ g_losses.append(g_loss.item())
305
+ return loss, r_losses, g_losses
306
+
307
+ def generator_loss(disc_outputs):
308
+ loss = 0
309
+ gen_losses = []
310
+
311
+ for dg in disc_outputs:
312
+ l = torch.mean((1 - dg.float()) ** 2)
313
+ gen_losses.append(l)
314
+ loss += l
315
+ return loss, gen_losses
316
+
317
+ def kl_loss(z_p, logs_q, m_p, logs_p, z_mask):
318
+ z_p = z_p.float()
319
+ logs_q = logs_q.float()
320
+ m_p = m_p.float()
321
+ logs_p = logs_p.float()
322
+ z_mask = z_mask.float()
323
+ kl = logs_p - logs_q - 0.5
324
+ kl += 0.5 * ((z_p - m_p) ** 2) * torch.exp(-2.0 * logs_p)
325
+ return torch.sum(kl * z_mask) / torch.sum(z_mask)
326
+
327
+ class TextAudioLoaderMultiNSFsid(tdata.Dataset):
328
+ def __init__(self, hparams):
329
+ self.audiopaths_and_text = load_filepaths_and_text(hparams.training_files)
330
+ self.max_wav_value = hparams.max_wav_value
331
+ self.sample_rate = hparams.sample_rate
332
+ self.filter_length = hparams.filter_length
333
+ self.hop_length = hparams.hop_length
334
+ self.win_length = hparams.win_length
335
+ self.sample_rate = hparams.sample_rate
336
+ self.min_text_len = getattr(hparams, "min_text_len", 1)
337
+ self.max_text_len = getattr(hparams, "max_text_len", 5000)
338
+ self._filter()
339
+
340
+ def _filter(self):
341
+ audiopaths_and_text_new, lengths = [], []
342
+ for audiopath, text, pitch, pitchf, dv in self.audiopaths_and_text:
343
+ if self.min_text_len <= len(text) and len(text) <= self.max_text_len:
344
+ audiopaths_and_text_new.append([audiopath, text, pitch, pitchf, dv])
345
+ lengths.append(os.path.getsize(audiopath) // (3 * self.hop_length))
346
+
347
+ self.audiopaths_and_text = audiopaths_and_text_new
348
+ self.lengths = lengths
349
+
350
+ def get_sid(self, sid):
351
+ try:
352
+ sid = torch.LongTensor([int(sid)])
353
+ except ValueError as e:
354
+ logger.error(translations["sid_error"].format(sid=sid, e=e))
355
+ sid = torch.LongTensor([0])
356
+ return sid
357
+
358
+ def get_audio_text_pair(self, audiopath_and_text):
359
+ phone, pitch, pitchf = self.get_labels(audiopath_and_text[1], audiopath_and_text[2], audiopath_and_text[3])
360
+ spec, wav = self.get_audio(audiopath_and_text[0])
361
+ dv = self.get_sid(audiopath_and_text[4])
362
+ len_phone = phone.size()[0]
363
+ len_spec = spec.size()[-1]
364
+
365
+ if len_phone != len_spec:
366
+ len_min = min(len_phone, len_spec)
367
+ len_wav = len_min * self.hop_length
368
+ spec, wav, phone = spec[:, :len_min], wav[:, :len_wav], phone[:len_min, :]
369
+ pitch, pitchf = pitch[:len_min], pitchf[:len_min]
370
+ return (spec, wav, phone, pitch, pitchf, dv)
371
+
372
+ def get_labels(self, phone, pitch, pitchf):
373
+ phone = np.repeat(np.load(phone), 2, axis=0)
374
+ n_num = min(phone.shape[0], 900)
375
+ return torch.FloatTensor(phone[:n_num, :]), torch.LongTensor(np.load(pitch)[:n_num]), torch.FloatTensor(np.load(pitchf)[:n_num])
376
+
377
+ def get_audio(self, filename):
378
+ audio, sample_rate = load_wav_to_torch(filename)
379
+ if sample_rate != self.sample_rate: raise ValueError(translations["sr_does_not_match"].format(sample_rate=sample_rate, sample_rate2=self.sample_rate))
380
+ audio_norm = audio.unsqueeze(0)
381
+ spec_filename = filename.replace(".wav", ".spec.pt")
382
+
383
+ if os.path.exists(spec_filename):
384
+ try:
385
+ spec = torch.load(spec_filename)
386
+ except Exception as e:
387
+ logger.error(translations["spec_error"].format(spec_filename=spec_filename, e=e))
388
+ spec = torch.squeeze(spectrogram_torch(audio_norm, self.filter_length, self.hop_length, self.win_length, center=False), 0)
389
+ torch.save(spec, spec_filename, _use_new_zipfile_serialization=False)
390
+ else:
391
+ spec = torch.squeeze(spectrogram_torch(audio_norm, self.filter_length, self.hop_length, self.win_length, center=False), 0)
392
+ torch.save(spec, spec_filename, _use_new_zipfile_serialization=False)
393
+ return spec, audio_norm
394
+
395
+ def __getitem__(self, index):
396
+ return self.get_audio_text_pair(self.audiopaths_and_text[index])
397
+
398
+ def __len__(self):
399
+ return len(self.audiopaths_and_text)
400
+
401
+ class TextAudioCollateMultiNSFsid:
402
+ def __init__(self, return_ids=False):
403
+ self.return_ids = return_ids
404
+
405
+ def __call__(self, batch):
406
+ _, ids_sorted_decreasing = torch.sort(torch.LongTensor([x[0].size(1) for x in batch]), dim=0, descending=True)
407
+ spec_lengths, wave_lengths = torch.LongTensor(len(batch)), torch.LongTensor(len(batch))
408
+ spec_padded, wave_padded = torch.FloatTensor(len(batch), batch[0][0].size(0), max([x[0].size(1) for x in batch])), torch.FloatTensor(len(batch), 1, max([x[1].size(1) for x in batch]))
409
+ spec_padded.zero_()
410
+ wave_padded.zero_()
411
+ max_phone_len = max([x[2].size(0) for x in batch])
412
+ phone_lengths, phone_padded = torch.LongTensor(len(batch)), torch.FloatTensor(len(batch), max_phone_len, batch[0][2].shape[1])
413
+ pitch_padded, pitchf_padded = torch.LongTensor(len(batch), max_phone_len), torch.FloatTensor(len(batch), max_phone_len)
414
+ phone_padded.zero_()
415
+ pitch_padded.zero_()
416
+ pitchf_padded.zero_()
417
+ sid = torch.LongTensor(len(batch))
418
+
419
+ for i in range(len(ids_sorted_decreasing)):
420
+ row = batch[ids_sorted_decreasing[i]]
421
+ spec = row[0]
422
+ spec_padded[i, :, : spec.size(1)] = spec
423
+ spec_lengths[i] = spec.size(1)
424
+ wave = row[1]
425
+ wave_padded[i, :, : wave.size(1)] = wave
426
+ wave_lengths[i] = wave.size(1)
427
+ phone = row[2]
428
+ phone_padded[i, : phone.size(0), :] = phone
429
+ phone_lengths[i] = phone.size(0)
430
+ pitch = row[3]
431
+ pitch_padded[i, : pitch.size(0)] = pitch
432
+ pitchf = row[4]
433
+ pitchf_padded[i, : pitchf.size(0)] = pitchf
434
+ sid[i] = row[5]
435
+ return (phone_padded, phone_lengths, pitch_padded, pitchf_padded, spec_padded, spec_lengths, wave_padded, wave_lengths, sid)
436
+
437
+ class TextAudioLoader(tdata.Dataset):
438
+ def __init__(self, hparams):
439
+ self.audiopaths_and_text = load_filepaths_and_text(hparams.training_files)
440
+ self.max_wav_value = hparams.max_wav_value
441
+ self.sample_rate = hparams.sample_rate
442
+ self.filter_length = hparams.filter_length
443
+ self.hop_length = hparams.hop_length
444
+ self.win_length = hparams.win_length
445
+ self.sample_rate = hparams.sample_rate
446
+ self.min_text_len = getattr(hparams, "min_text_len", 1)
447
+ self.max_text_len = getattr(hparams, "max_text_len", 5000)
448
+ self._filter()
449
+
450
+ def _filter(self):
451
+ audiopaths_and_text_new, lengths = [], []
452
+ for entry in self.audiopaths_and_text:
453
+ if len(entry) >= 3:
454
+ audiopath, text, dv = entry[:3]
455
+ if self.min_text_len <= len(text) and len(text) <= self.max_text_len:
456
+ audiopaths_and_text_new.append([audiopath, text, dv])
457
+ lengths.append(os.path.getsize(audiopath) // (3 * self.hop_length))
458
+
459
+ self.audiopaths_and_text = audiopaths_and_text_new
460
+ self.lengths = lengths
461
+
462
+ def get_sid(self, sid):
463
+ try:
464
+ sid = torch.LongTensor([int(sid)])
465
+ except ValueError as e:
466
+ logger.error(translations["sid_error"].format(sid=sid, e=e))
467
+ sid = torch.LongTensor([0])
468
+ return sid
469
+
470
+ def get_audio_text_pair(self, audiopath_and_text):
471
+ phone = self.get_labels(audiopath_and_text[1])
472
+ spec, wav = self.get_audio(audiopath_and_text[0])
473
+ dv = self.get_sid(audiopath_and_text[2])
474
+ len_phone = phone.size()[0]
475
+ len_spec = spec.size()[-1]
476
+
477
+ if len_phone != len_spec:
478
+ len_min = min(len_phone, len_spec)
479
+ len_wav = len_min * self.hop_length
480
+ spec = spec[:, :len_min]
481
+ wav = wav[:, :len_wav]
482
+ phone = phone[:len_min, :]
483
+ return (spec, wav, phone, dv)
484
+
485
+ def get_labels(self, phone):
486
+ phone = np.repeat(np.load(phone), 2, axis=0)
487
+ return torch.FloatTensor(phone[:min(phone.shape[0], 900), :])
488
+
489
+ def get_audio(self, filename):
490
+ audio, sample_rate = load_wav_to_torch(filename)
491
+ if sample_rate != self.sample_rate: raise ValueError(translations["sr_does_not_match"].format(sample_rate=sample_rate, sample_rate2=self.sample_rate))
492
+ audio_norm = audio.unsqueeze(0)
493
+ spec_filename = filename.replace(".wav", ".spec.pt")
494
+
495
+ if os.path.exists(spec_filename):
496
+ try:
497
+ spec = torch.load(spec_filename)
498
+ except Exception as e:
499
+ logger.error(translations["spec_error"].format(spec_filename=spec_filename, e=e))
500
+ spec = torch.squeeze(spectrogram_torch(audio_norm, self.filter_length, self.hop_length, self.win_length, center=False), 0)
501
+ torch.save(spec, spec_filename, _use_new_zipfile_serialization=False)
502
+ else:
503
+ spec = torch.squeeze(spectrogram_torch(audio_norm, self.filter_length, self.hop_length, self.win_length, center=False), 0)
504
+ torch.save(spec, spec_filename, _use_new_zipfile_serialization=False)
505
+ return spec, audio_norm
506
+
507
+ def __getitem__(self, index):
508
+ return self.get_audio_text_pair(self.audiopaths_and_text[index])
509
+
510
+ def __len__(self):
511
+ return len(self.audiopaths_and_text)
512
+
513
+ class TextAudioCollate:
514
+ def __init__(self, return_ids=False):
515
+ self.return_ids = return_ids
516
+
517
+ def __call__(self, batch):
518
+ _, ids_sorted_decreasing = torch.sort(torch.LongTensor([x[0].size(1) for x in batch]), dim=0, descending=True)
519
+ spec_lengths, wave_lengths = torch.LongTensor(len(batch)), torch.LongTensor(len(batch))
520
+ spec_padded, wave_padded = torch.FloatTensor(len(batch), batch[0][0].size(0), max([x[0].size(1) for x in batch])), torch.FloatTensor(len(batch), 1, max([x[1].size(1) for x in batch]))
521
+ spec_padded.zero_()
522
+ wave_padded.zero_()
523
+ max_phone_len = max([x[2].size(0) for x in batch])
524
+ phone_lengths, phone_padded = torch.LongTensor(len(batch)), torch.FloatTensor(len(batch), max_phone_len, batch[0][2].shape[1])
525
+ phone_padded.zero_()
526
+ sid = torch.LongTensor(len(batch))
527
+ for i in range(len(ids_sorted_decreasing)):
528
+ row = batch[ids_sorted_decreasing[i]]
529
+ spec = row[0]
530
+ spec_padded[i, :, : spec.size(1)] = spec
531
+ spec_lengths[i] = spec.size(1)
532
+ wave = row[1]
533
+ wave_padded[i, :, : wave.size(1)] = wave
534
+ wave_lengths[i] = wave.size(1)
535
+ phone = row[2]
536
+ phone_padded[i, : phone.size(0), :] = phone
537
+ phone_lengths[i] = phone.size(0)
538
+ sid[i] = row[3]
539
+ return (phone_padded, phone_lengths, spec_padded, spec_lengths, wave_padded, wave_lengths, sid)
540
+
541
+ class DistributedBucketSampler(tdata.distributed.DistributedSampler):
542
+ def __init__(self, dataset, batch_size, boundaries, num_replicas=None, rank=None, shuffle=True):
543
+ super().__init__(dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle)
544
+ self.lengths = dataset.lengths
545
+ self.batch_size = batch_size
546
+ self.boundaries = boundaries
547
+ self.buckets, self.num_samples_per_bucket = self._create_buckets()
548
+ self.total_size = sum(self.num_samples_per_bucket)
549
+ self.num_samples = self.total_size // self.num_replicas
550
+
551
+ def _create_buckets(self):
552
+ buckets = [[] for _ in range(len(self.boundaries) - 1)]
553
+ for i in range(len(self.lengths)):
554
+ idx_bucket = self._bisect(self.lengths[i])
555
+ if idx_bucket != -1: buckets[idx_bucket].append(i)
556
+
557
+ for i in range(len(buckets) - 1, -1, -1):
558
+ if len(buckets[i]) == 0:
559
+ buckets.pop(i)
560
+ self.boundaries.pop(i + 1)
561
+
562
+ num_samples_per_bucket = []
563
+ for i in range(len(buckets)):
564
+ len_bucket = len(buckets[i])
565
+ total_batch_size = self.num_replicas * self.batch_size
566
+ num_samples_per_bucket.append(len_bucket + ((total_batch_size - (len_bucket % total_batch_size)) % total_batch_size))
567
+ return buckets, num_samples_per_bucket
568
+
569
+ def __iter__(self):
570
+ g = torch.Generator()
571
+ g.manual_seed(self.epoch)
572
+ indices, batches = [], []
573
+ if self.shuffle:
574
+ for bucket in self.buckets:
575
+ indices.append(torch.randperm(len(bucket), generator=g).tolist())
576
+ else:
577
+ for bucket in self.buckets:
578
+ indices.append(list(range(len(bucket))))
579
+
580
+ for i in range(len(self.buckets)):
581
+ bucket = self.buckets[i]
582
+ len_bucket = len(bucket)
583
+ ids_bucket = indices[i]
584
+ rem = self.num_samples_per_bucket[i] - len_bucket
585
+ ids_bucket = (ids_bucket + ids_bucket * (rem // len_bucket) + ids_bucket[: (rem % len_bucket)])[self.rank :: self.num_replicas]
586
+
587
+ for j in range(len(ids_bucket) // self.batch_size):
588
+ batches.append([bucket[idx] for idx in ids_bucket[j * self.batch_size : (j + 1) * self.batch_size]])
589
+
590
+ if self.shuffle: batches = [batches[i] for i in torch.randperm(len(batches), generator=g).tolist()]
591
+ self.batches = batches
592
+ assert len(self.batches) * self.batch_size == self.num_samples
593
+ return iter(self.batches)
594
+
595
+ def _bisect(self, x, lo=0, hi=None):
596
+ if hi is None: hi = len(self.boundaries) - 1
597
+
598
+ if hi > lo:
599
+ mid = (hi + lo) // 2
600
+ if self.boundaries[mid] < x and x <= self.boundaries[mid + 1]: return mid
601
+ elif x <= self.boundaries[mid]: return self._bisect(x, lo, mid)
602
+ else: return self._bisect(x, mid + 1, hi)
603
+ else: return -1
604
+
605
+ def __len__(self):
606
+ return self.num_samples // self.batch_size
607
+
608
+ class MultiPeriodDiscriminator(torch.nn.Module):
609
+ def __init__(self, version, use_spectral_norm=False, checkpointing=False):
610
+ super(MultiPeriodDiscriminator, self).__init__()
611
+ self.checkpointing = checkpointing
612
+ periods = ([2, 3, 5, 7, 11, 17] if version == "v1" else [2, 3, 5, 7, 11, 17, 23, 37])
613
+ self.discriminators = torch.nn.ModuleList([DiscriminatorS(use_spectral_norm=use_spectral_norm, checkpointing=checkpointing)] + [DiscriminatorP(p, use_spectral_norm=use_spectral_norm, checkpointing=checkpointing) for p in periods])
614
+
615
+ def forward(self, y, y_hat):
616
+ y_d_rs, y_d_gs, fmap_rs, fmap_gs = [], [], [], []
617
+ for d in self.discriminators:
618
+ if self.training and self.checkpointing:
619
+ def forward_discriminator(d, y, y_hat):
620
+ y_d_r, fmap_r = d(y)
621
+ y_d_g, fmap_g = d(y_hat)
622
+ return y_d_r, fmap_r, y_d_g, fmap_g
623
+ y_d_r, fmap_r, y_d_g, fmap_g = checkpoint(forward_discriminator, d, y, y_hat, use_reentrant=False)
624
+ else:
625
+ y_d_r, fmap_r = d(y)
626
+ y_d_g, fmap_g = d(y_hat)
627
+
628
+ y_d_rs.append(y_d_r); fmap_rs.append(fmap_r)
629
+ y_d_gs.append(y_d_g); fmap_gs.append(fmap_g)
630
+ return y_d_rs, y_d_gs, fmap_rs, fmap_gs
631
+
632
+ class DiscriminatorS(torch.nn.Module):
633
+ def __init__(self, use_spectral_norm=False, checkpointing=False):
634
+ super(DiscriminatorS, self).__init__()
635
+ self.checkpointing = checkpointing
636
+ norm_f = spectral_norm if use_spectral_norm else weight_norm
637
+ self.convs = torch.nn.ModuleList([norm_f(torch.nn.Conv1d(1, 16, 15, 1, padding=7)), norm_f(torch.nn.Conv1d(16, 64, 41, 4, groups=4, padding=20)), norm_f(torch.nn.Conv1d(64, 256, 41, 4, groups=16, padding=20)), norm_f(torch.nn.Conv1d(256, 1024, 41, 4, groups=64, padding=20)), norm_f(torch.nn.Conv1d(1024, 1024, 41, 4, groups=256, padding=20)), norm_f(torch.nn.Conv1d(1024, 1024, 5, 1, padding=2))])
638
+ self.conv_post = norm_f(torch.nn.Conv1d(1024, 1, 3, 1, padding=1))
639
+ self.lrelu = torch.nn.LeakyReLU(LRELU_SLOPE)
640
+
641
+ def forward(self, x):
642
+ fmap = []
643
+ for conv in self.convs:
644
+ x = checkpoint(self.lrelu, checkpoint(conv, x, use_reentrant = False), use_reentrant = False) if self.training and self.checkpointing else self.lrelu(conv(x))
645
+ fmap.append(x)
646
+
647
+ x = self.conv_post(x)
648
+ fmap.append(x)
649
+ return torch.flatten(x, 1, -1), fmap
650
+
651
+ class DiscriminatorP(torch.nn.Module):
652
+ def __init__(self, period, kernel_size=5, stride=3, use_spectral_norm=False, checkpointing=False):
653
+ super(DiscriminatorP, self).__init__()
654
+ self.period = period
655
+ self.checkpointing = checkpointing
656
+ norm_f = spectral_norm if use_spectral_norm else weight_norm
657
+ self.convs = torch.nn.ModuleList([norm_f(torch.nn.Conv2d(in_ch, out_ch, (kernel_size, 1), (stride, 1), padding=(get_padding(kernel_size, 1), 0))) for in_ch, out_ch in zip([1, 32, 128, 512, 1024], [32, 128, 512, 1024, 1024])])
658
+ self.conv_post = norm_f(torch.nn.Conv2d(1024, 1, (3, 1), 1, padding=(1, 0)))
659
+ self.lrelu = torch.nn.LeakyReLU(LRELU_SLOPE)
660
+
661
+ def forward(self, x):
662
+ fmap = []
663
+ b, c, t = x.shape
664
+
665
+ if t % self.period != 0: x = F.pad(x, (0, (self.period - (t % self.period))), "reflect")
666
+ x = x.view(b, c, -1, self.period)
667
+
668
+ for conv in self.convs:
669
+ x = checkpoint(self.lrelu, checkpoint(conv, x, use_reentrant = False), use_reentrant = False) if self.training and self.checkpointing else self.lrelu(conv(x))
670
+ fmap.append(x)
671
+
672
+ x = self.conv_post(x)
673
+ fmap.append(x)
674
+ return torch.flatten(x, 1, -1), fmap
675
+
676
+ class EpochRecorder:
677
+ def __init__(self):
678
+ self.last_time = ttime()
679
+
680
+ def record(self):
681
+ now_time = ttime()
682
+ elapsed_time = now_time - self.last_time
683
+ self.last_time = now_time
684
+ return translations["time_or_speed_training"].format(current_time=datetime.datetime.now().strftime("%H:%M:%S"), elapsed_time_str=str(datetime.timedelta(seconds=int(round(elapsed_time, 1)))))
685
+
686
+ def dynamic_range_compression_torch(x, C=1, clip_val=1e-5):
687
+ return torch.log(torch.clamp(x, min=clip_val) * C)
688
+
689
+ def dynamic_range_decompression_torch(x, C=1):
690
+ return torch.exp(x) / C
691
+
692
+ def spectral_normalize_torch(magnitudes):
693
+ return dynamic_range_compression_torch(magnitudes)
694
+
695
+ def spectral_de_normalize_torch(magnitudes):
696
+ return dynamic_range_decompression_torch(magnitudes)
697
+
698
+ mel_basis, hann_window = {}, {}
699
+
700
+ def spectrogram_torch(y, n_fft, hop_size, win_size, center=False):
701
+ global hann_window
702
+
703
+ wnsize_dtype_device = str(win_size) + "_" + str(y.dtype) + "_" + str(y.device)
704
+ if wnsize_dtype_device not in hann_window: hann_window[wnsize_dtype_device] = torch.hann_window(win_size).to(dtype=y.dtype, device=y.device)
705
+ spec = torch.stft(F.pad(y.unsqueeze(1), (int((n_fft - hop_size) / 2), int((n_fft - hop_size) / 2)), mode="reflect").squeeze(1), n_fft, hop_length=hop_size, win_length=win_size, window=hann_window[wnsize_dtype_device], center=center, pad_mode="reflect", normalized=False, onesided=True, return_complex=True)
706
+ return torch.sqrt(spec.real.pow(2) + spec.imag.pow(2) + 1e-6)
707
+
708
+ def spec_to_mel_torch(spec, n_fft, num_mels, sample_rate, fmin, fmax):
709
+ global mel_basis
710
+
711
+ fmax_dtype_device = str(fmax) + "_" + str(spec.dtype) + "_" + str(spec.device)
712
+ if fmax_dtype_device not in mel_basis: mel_basis[fmax_dtype_device] = torch.from_numpy(librosa_mel_fn(sr=sample_rate, n_fft=n_fft, n_mels=num_mels, fmin=fmin, fmax=fmax)).to(dtype=spec.dtype, device=spec.device)
713
+ return spectral_normalize_torch(torch.matmul(mel_basis[fmax_dtype_device], spec))
714
+
715
+ def mel_spectrogram_torch(y, n_fft, num_mels, sample_rate, hop_size, win_size, fmin, fmax, center=False):
716
+ return spec_to_mel_torch(spectrogram_torch(y, n_fft, hop_size, win_size, center), n_fft, num_mels, sample_rate, fmin, fmax)
717
+
718
+ def replace_keys_in_dict(d, old_key_part, new_key_part):
719
+ updated_dict = OrderedDict() if isinstance(d, OrderedDict) else {}
720
+ for key, value in d.items():
721
+ updated_dict[(key.replace(old_key_part, new_key_part) if isinstance(key, str) else key)] = (replace_keys_in_dict(value, old_key_part, new_key_part) if isinstance(value, dict) else value)
722
+ return updated_dict
723
+
724
+ def extract_model(ckpt, sr, pitch_guidance, name, model_path, epoch, step, version, hps, model_author, vocoder):
725
+ try:
726
+ logger.info(translations["savemodel"].format(model_dir=model_path, epoch=epoch, step=step))
727
+ os.makedirs(os.path.dirname(model_path), exist_ok=True)
728
+
729
+ opt = OrderedDict(weight={key: value.half() for key, value in ckpt.items() if "enc_q" not in key})
730
+ opt["config"] = [hps.data.filter_length // 2 + 1, 32, hps.model.inter_channels, hps.model.hidden_channels, hps.model.filter_channels, hps.model.n_heads, hps.model.n_layers, hps.model.kernel_size, hps.model.p_dropout, hps.model.resblock, hps.model.resblock_kernel_sizes, hps.model.resblock_dilation_sizes, hps.model.upsample_rates, hps.model.upsample_initial_channel, hps.model.upsample_kernel_sizes, hps.model.spk_embed_dim, hps.model.gin_channels, hps.data.sample_rate]
731
+ opt["epoch"] = f"{epoch}epoch"
732
+ opt["step"] = step
733
+ opt["sr"] = sr
734
+ opt["f0"] = int(pitch_guidance)
735
+ opt["version"] = version
736
+ opt["creation_date"] = datetime.datetime.now().isoformat()
737
+ opt["model_hash"] = hashlib.sha256(f"{str(ckpt)} {epoch} {step} {datetime.datetime.now().isoformat()}".encode()).hexdigest()
738
+ opt["model_name"] = name
739
+ opt["author"] = model_author
740
+ opt["vocoder"] = vocoder
741
+
742
+ torch.save(replace_keys_in_dict(replace_keys_in_dict(opt, ".parametrizations.weight.original1", ".weight_v"), ".parametrizations.weight.original0", ".weight_g"), model_path)
743
+ except Exception as e:
744
+ logger.error(f"{translations['extract_model_error']}: {e}")
745
+
746
+ def run(rank, n_gpus, experiment_dir, pretrainG, pretrainD, pitch_guidance, custom_total_epoch, custom_save_every_weights, config, device, device_id, model_author, vocoder, checkpointing):
747
+ global global_step
748
+
749
+ if rank == 0: writer_eval = SummaryWriter(log_dir=os.path.join(experiment_dir, "eval"))
750
+ else: writer_eval = None
751
+
752
+ try:
753
+ dist.init_process_group(backend=("gloo" if sys.platform == "win32" or device.type != "cuda" else "nccl"), init_method="env://", world_size=n_gpus, rank=rank)
754
+ except:
755
+ dist.init_process_group(backend=("gloo" if sys.platform == "win32" or device.type != "cuda" else "nccl"), init_method="env://?use_libuv=False", world_size=n_gpus, rank=rank)
756
+
757
+ torch.manual_seed(config.train.seed)
758
+ if torch.cuda.is_available(): torch.cuda.set_device(device_id)
759
+
760
+ train_dataset = TextAudioLoaderMultiNSFsid(config.data) if pitch_guidance else TextAudioLoader(config.data)
761
+ train_loader = tdata.DataLoader(train_dataset, num_workers=4, shuffle=False, pin_memory=True, collate_fn=TextAudioCollateMultiNSFsid() if pitch_guidance else TextAudioCollate(), batch_sampler=DistributedBucketSampler(train_dataset, batch_size * n_gpus, [100, 200, 300, 400, 500, 600, 700, 800, 900], num_replicas=n_gpus, rank=rank, shuffle=True), persistent_workers=True, prefetch_factor=8)
762
+
763
+ net_g, net_d = Synthesizer(config.data.filter_length // 2 + 1, config.train.segment_size // config.data.hop_length, **config.model, use_f0=pitch_guidance, sr=sample_rate, vocoder=vocoder, checkpointing=checkpointing), MultiPeriodDiscriminator(version, config.model.use_spectral_norm, checkpointing=checkpointing)
764
+ net_g, net_d = (net_g.cuda(device_id), net_d.cuda(device_id)) if torch.cuda.is_available() else (net_g.to(device), net_d.to(device))
765
+
766
+ optim_g, optim_d = torch.optim.AdamW(net_g.parameters(), config.train.learning_rate, betas=config.train.betas, eps=config.train.eps), torch.optim.AdamW(net_d.parameters(), config.train.learning_rate, betas=config.train.betas, eps=config.train.eps)
767
+ net_g, net_d = (DDP(net_g, device_ids=[device_id]), DDP(net_d, device_ids=[device_id])) if torch.cuda.is_available() else (DDP(net_g), DDP(net_d))
768
+
769
+ try:
770
+ logger.info(translations["start_training"])
771
+ _, _, _, epoch_str = load_checkpoint((os.path.join(experiment_dir, "D_latest.pth") if save_only_latest else latest_checkpoint_path(experiment_dir, "D_*.pth")), net_d, optim_d)
772
+ _, _, _, epoch_str = load_checkpoint((os.path.join(experiment_dir, "G_latest.pth") if save_only_latest else latest_checkpoint_path(experiment_dir, "G_*.pth")), net_g, optim_g)
773
+ epoch_str += 1
774
+ global_step = (epoch_str - 1) * len(train_loader)
775
+ except:
776
+ epoch_str, global_step = 1, 0
777
+
778
+ if pretrainG != "" and pretrainG != "None":
779
+ if rank == 0:
780
+ verify_checkpoint_shapes(pretrainG, net_g)
781
+ logger.info(translations["import_pretrain"].format(dg="G", pretrain=pretrainG))
782
+
783
+ if hasattr(net_g, "module"): net_g.module.load_state_dict(torch.load(pretrainG, map_location="cpu")["model"])
784
+ else: net_g.load_state_dict(torch.load(pretrainG, map_location="cpu")["model"])
785
+ else: logger.warning(translations["not_using_pretrain"].format(dg="G"))
786
+
787
+ if pretrainD != "" and pretrainD != "None":
788
+ if rank == 0:
789
+ verify_checkpoint_shapes(pretrainD, net_d)
790
+ logger.info(translations["import_pretrain"].format(dg="D", pretrain=pretrainD))
791
+
792
+ if hasattr(net_d, "module"): net_d.module.load_state_dict(torch.load(pretrainD, map_location="cpu")["model"])
793
+ else: net_d.load_state_dict(torch.load(pretrainD, map_location="cpu")["model"])
794
+ else: logger.warning(translations["not_using_pretrain"].format(dg="D"))
795
+
796
+ scheduler_g, scheduler_d = torch.optim.lr_scheduler.ExponentialLR(optim_g, gamma=config.train.lr_decay, last_epoch=epoch_str - 2), torch.optim.lr_scheduler.ExponentialLR(optim_d, gamma=config.train.lr_decay, last_epoch=epoch_str - 2)
797
+ optim_d.step(); optim_g.step()
798
+
799
+ scaler = GradScaler(enabled=main_config.is_half and device.type == "cuda")
800
+ cache = []
801
+
802
+ for info in train_loader:
803
+ phone, phone_lengths, pitch, pitchf, _, _, _, _, sid = info
804
+ reference = (phone.cuda(device_id, non_blocking=True), phone_lengths.cuda(device_id, non_blocking=True), (pitch.cuda(device_id, non_blocking=True) if pitch_guidance else None), (pitchf.cuda(device_id, non_blocking=True) if pitch_guidance else None), sid.cuda(device_id, non_blocking=True)) if device.type == "cuda" else (phone.to(device), phone_lengths.to(device), (pitch.to(device) if pitch_guidance else None), (pitchf.to(device) if pitch_guidance else None), sid.to(device))
805
+ break
806
+
807
+ for epoch in range(epoch_str, total_epoch + 1):
808
+ train_and_evaluate(rank, epoch, config, [net_g, net_d], [optim_g, optim_d], scaler, train_loader, writer_eval, cache, custom_save_every_weights, custom_total_epoch, device, device_id, reference, model_author, vocoder)
809
+ scheduler_g.step(); scheduler_d.step()
810
+
811
+ def train_and_evaluate(rank, epoch, hps, nets, optims, scaler, train_loader, writer, cache, custom_save_every_weights, custom_total_epoch, device, device_id, reference, model_author, vocoder):
812
+ global global_step, lowest_value, loss_disc, consecutive_increases_gen, consecutive_increases_disc
813
+
814
+ if epoch == 1:
815
+ lowest_value = {"step": 0, "value": float("inf"), "epoch": 0}
816
+ last_loss_gen_all, consecutive_increases_gen, consecutive_increases_disc = 0.0, 0, 0
817
+
818
+ net_g, net_d = nets
819
+ optim_g, optim_d = optims
820
+ train_loader.batch_sampler.set_epoch(epoch)
821
+
822
+ net_g.train(); net_d.train()
823
+
824
+ if device.type == "cuda" and cache_data_in_gpu:
825
+ data_iterator = cache
826
+ if cache == []:
827
+ for batch_idx, info in enumerate(train_loader):
828
+ cache.append((batch_idx, [tensor.cuda(device_id, non_blocking=True) for tensor in info]))
829
+ else: shuffle(cache)
830
+ else: data_iterator = enumerate(train_loader)
831
+
832
+ epoch_recorder = EpochRecorder()
833
+ with tqdm(total=len(train_loader), leave=False) as pbar:
834
+ for batch_idx, info in data_iterator:
835
+ if device.type == "cuda" and not cache_data_in_gpu: info = [tensor.cuda(device_id, non_blocking=True) for tensor in info]
836
+ elif device.type != "cuda": info = [tensor.to(device) for tensor in info]
837
+
838
+ phone, phone_lengths, pitch, pitchf, spec, spec_lengths, wave, _, sid = info
839
+ pitch = pitch if pitch_guidance else None
840
+ pitchf = pitchf if pitch_guidance else None
841
+
842
+ with autocast(enabled=main_config.is_half and device.type == "cuda"):
843
+ y_hat, ids_slice, _, z_mask, (_, z_p, m_p, logs_p, _, logs_q) = net_g(phone, phone_lengths, pitch, pitchf, spec, spec_lengths, sid)
844
+ mel = spec_to_mel_torch(spec, config.data.filter_length, config.data.n_mel_channels, config.data.sample_rate, config.data.mel_fmin, config.data.mel_fmax)
845
+ y_mel = slice_segments(mel, ids_slice, config.train.segment_size // config.data.hop_length, dim=3)
846
+
847
+ with autocast(enabled=main_config.is_half and device.type == "cuda"):
848
+ y_hat_mel = mel_spectrogram_torch(y_hat.float().squeeze(1), config.data.filter_length, config.data.n_mel_channels, config.data.sample_rate, config.data.hop_length, config.data.win_length, config.data.mel_fmin, config.data.mel_fmax)
849
+
850
+ wave = slice_segments(wave, ids_slice * config.data.hop_length, config.train.segment_size, dim=3)
851
+ y_d_hat_r, y_d_hat_g, _, _ = net_d(wave, y_hat.detach())
852
+
853
+ with autocast(enabled=main_config.is_half and device.type == "cuda"):
854
+ loss_disc, losses_disc_r, losses_disc_g = discriminator_loss(y_d_hat_r, y_d_hat_g)
855
+
856
+ optim_d.zero_grad()
857
+ scaler.scale(loss_disc).backward()
858
+ scaler.unscale_(optim_d)
859
+ grad_norm_d = clip_grad_value(net_d.parameters(), None)
860
+ scaler.step(optim_d)
861
+
862
+ with autocast(enabled=main_config.is_half and device.type == "cuda"):
863
+ y_d_hat_r, y_d_hat_g, fmap_r, fmap_g = net_d(wave, y_hat)
864
+ with autocast(enabled=main_config.is_half and device.type == "cuda"):
865
+ loss_mel = F.l1_loss(y_mel, y_hat_mel) * config.train.c_mel
866
+ loss_kl = (kl_loss(z_p, logs_q, m_p, logs_p, z_mask) * config.train.c_kl)
867
+ loss_fm = feature_loss(fmap_r, fmap_g)
868
+ loss_gen, losses_gen = generator_loss(y_d_hat_g)
869
+ loss_gen_all = loss_gen + loss_fm + loss_mel + loss_kl
870
+ if loss_gen_all < lowest_value["value"]:
871
+ lowest_value["value"] = loss_gen_all
872
+ lowest_value["step"] = global_step
873
+ lowest_value["epoch"] = epoch
874
+ if epoch > lowest_value["epoch"]: logger.warning(translations["training_warning"])
875
+
876
+ optim_g.zero_grad()
877
+ scaler.scale(loss_gen_all).backward()
878
+ scaler.unscale_(optim_g)
879
+ grad_norm_g = clip_grad_value(net_g.parameters(), None)
880
+ scaler.step(optim_g)
881
+ scaler.update()
882
+
883
+ if rank == 0 and global_step % config.train.log_interval == 0:
884
+ if loss_mel > 75: loss_mel = 75
885
+ if loss_kl > 9: loss_kl = 9
886
+
887
+ scalar_dict = {"loss/g/total": loss_gen_all, "loss/d/total": loss_disc, "learning_rate": optim_g.param_groups[0]["lr"], "grad/norm_d": grad_norm_d, "grad/norm_g": grad_norm_g, "loss/g/fm": loss_fm, "loss/g/mel": loss_mel, "loss/g/kl": loss_kl}
888
+ scalar_dict.update({f"loss/g/{i}": v for i, v in enumerate(losses_gen)})
889
+ scalar_dict.update({f"loss/d_r/{i}": v for i, v in enumerate(losses_disc_r)})
890
+ scalar_dict.update({f"loss/d_g/{i}": v for i, v in enumerate(losses_disc_g)})
891
+
892
+ with torch.no_grad():
893
+ o, *_ = net_g.module.infer(*reference) if hasattr(net_g, "module") else net_g.infer(*reference)
894
+
895
+ summarize(writer=writer, global_step=global_step, images={"slice/mel_org": plot_spectrogram_to_numpy(y_mel[0].data.cpu().numpy()), "slice/mel_gen": plot_spectrogram_to_numpy(y_hat_mel[0].data.cpu().numpy()), "all/mel": plot_spectrogram_to_numpy(mel[0].data.cpu().numpy())}, scalars=scalar_dict, audios={f"gen/audio_{global_step:07d}": o[0, :, :]}, audio_sample_rate=config.data.sample_rate)
896
+
897
+ global_step += 1
898
+ pbar.update(1)
899
+
900
+ def check_overtraining(smoothed_loss_history, threshold, epsilon=0.004):
901
+ if len(smoothed_loss_history) < threshold + 1: return False
902
+ for i in range(-threshold, -1):
903
+ if smoothed_loss_history[i + 1] > smoothed_loss_history[i]: return True
904
+ if abs(smoothed_loss_history[i + 1] - smoothed_loss_history[i]) >= epsilon: return False
905
+ return True
906
+
907
+ def update_exponential_moving_average(smoothed_loss_history, new_value, smoothing=0.987):
908
+ smoothed_value = new_value if not smoothed_loss_history else (smoothing * smoothed_loss_history[-1] + (1 - smoothing) * new_value)
909
+ smoothed_loss_history.append(smoothed_value)
910
+ return smoothed_value
911
+
912
+ def save_to_json(file_path, loss_disc_history, smoothed_loss_disc_history, loss_gen_history, smoothed_loss_gen_history):
913
+ with open(file_path, "w") as f:
914
+ json.dump({"loss_disc_history": loss_disc_history, "smoothed_loss_disc_history": smoothed_loss_disc_history, "loss_gen_history": loss_gen_history, "smoothed_loss_gen_history": smoothed_loss_gen_history}, f)
915
+
916
+ model_add, model_del = [], []
917
+ done = False
918
+
919
+ if rank == 0:
920
+ if epoch % save_every_epoch == False:
921
+ checkpoint_suffix = f"{'latest' if save_only_latest else global_step}.pth"
922
+ save_checkpoint(net_g, optim_g, config.train.learning_rate, epoch, os.path.join(experiment_dir, "G_" + checkpoint_suffix))
923
+ save_checkpoint(net_d, optim_d, config.train.learning_rate, epoch, os.path.join(experiment_dir, "D_" + checkpoint_suffix))
924
+ if custom_save_every_weights: model_add.append(os.path.join("assets", "weights", f"{model_name}_{epoch}e_{global_step}s.pth"))
925
+
926
+ if overtraining_detector and epoch > 1:
927
+ current_loss_disc = float(loss_disc)
928
+ loss_disc_history.append(current_loss_disc)
929
+ smoothed_value_disc = update_exponential_moving_average(smoothed_loss_disc_history, current_loss_disc)
930
+ is_overtraining_disc = check_overtraining(smoothed_loss_disc_history, overtraining_threshold * 2)
931
+
932
+ if is_overtraining_disc: consecutive_increases_disc += 1
933
+ else: consecutive_increases_disc = 0
934
+
935
+ current_loss_gen = float(lowest_value["value"])
936
+ loss_gen_history.append(current_loss_gen)
937
+ smoothed_value_gen = update_exponential_moving_average(smoothed_loss_gen_history, current_loss_gen)
938
+ is_overtraining_gen = check_overtraining(smoothed_loss_gen_history, overtraining_threshold, 0.01)
939
+
940
+ if is_overtraining_gen: consecutive_increases_gen += 1
941
+ else: consecutive_increases_gen = 0
942
+
943
+ if epoch % save_every_epoch == 0: save_to_json(training_file_path, loss_disc_history, smoothed_loss_disc_history, loss_gen_history, smoothed_loss_gen_history)
944
+
945
+ if (is_overtraining_gen and consecutive_increases_gen == overtraining_threshold or is_overtraining_disc and consecutive_increases_disc == (overtraining_threshold * 2)):
946
+ logger.info(translations["overtraining_find"].format(epoch=epoch, smoothed_value_gen=f"{smoothed_value_gen:.3f}", smoothed_value_disc=f"{smoothed_value_disc:.3f}"))
947
+ done = True
948
+ else:
949
+ logger.info(translations["best_epoch"].format(epoch=epoch, smoothed_value_gen=f"{smoothed_value_gen:.3f}", smoothed_value_disc=f"{smoothed_value_disc:.3f}"))
950
+ for file in glob.glob(os.path.join("assets", "weights", f"{model_name}_*e_*s_best_epoch.pth")):
951
+ model_del.append(file)
952
+
953
+ model_add.append(os.path.join("assets", "weights", f"{model_name}_{epoch}e_{global_step}s_best_epoch.pth"))
954
+
955
+ if epoch >= custom_total_epoch:
956
+ logger.info(translations["success_training"].format(epoch=epoch, global_step=global_step, loss_gen_all=round(loss_gen_all.item(), 3)))
957
+ logger.info(translations["training_info"].format(lowest_value_rounded=round(float(lowest_value["value"]), 3), lowest_value_epoch=lowest_value['epoch'], lowest_value_step=lowest_value['step']))
958
+
959
+ pid_file_path = os.path.join(experiment_dir, "config.json")
960
+ with open(pid_file_path, "r") as pid_file:
961
+ pid_data = json.load(pid_file)
962
+
963
+ with open(pid_file_path, "w") as pid_file:
964
+ pid_data.pop("process_pids", None)
965
+ json.dump(pid_data, pid_file, indent=4)
966
+
967
+ if os.path.exists(os.path.join(experiment_dir, "train_pid.txt")): os.remove(os.path.join(experiment_dir, "train_pid.txt"))
968
+ model_add.append(os.path.join("assets", "weights", f"{model_name}_{epoch}e_{global_step}s.pth"))
969
+ done = True
970
+
971
+ for m in model_del:
972
+ os.remove(m)
973
+
974
+ if model_add:
975
+ ckpt = (net_g.module.state_dict() if hasattr(net_g, "module") else net_g.state_dict())
976
+ for m in model_add:
977
+ extract_model(ckpt=ckpt, sr=sample_rate, pitch_guidance=pitch_guidance == True, name=model_name, model_path=m, epoch=epoch, step=global_step, version=version, hps=hps, model_author=model_author, vocoder=vocoder)
978
+
979
+ lowest_value_rounded = round(float(lowest_value["value"]), 3)
980
+
981
+ if epoch > 1 and overtraining_detector: logger.info(translations["model_training_info"].format(model_name=model_name, epoch=epoch, global_step=global_step, epoch_recorder=epoch_recorder.record(), lowest_value_rounded=lowest_value_rounded, lowest_value_epoch=lowest_value['epoch'], lowest_value_step=lowest_value['step'], remaining_epochs_gen=(overtraining_threshold - consecutive_increases_gen), remaining_epochs_disc=((overtraining_threshold * 2) - consecutive_increases_disc), smoothed_value_gen=f"{smoothed_value_gen:.3f}", smoothed_value_disc=f"{smoothed_value_disc:.3f}"))
982
+ elif epoch > 1 and overtraining_detector == False: logger.info(translations["model_training_info_2"].format(model_name=model_name, epoch=epoch, global_step=global_step, epoch_recorder=epoch_recorder.record(), lowest_value_rounded=lowest_value_rounded, lowest_value_epoch=lowest_value['epoch'], lowest_value_step=lowest_value['step']))
983
+ else: logger.info(translations["model_training_info_3"].format(model_name=model_name, epoch=epoch, global_step=global_step, epoch_recorder=epoch_recorder.record()))
984
+
985
+ last_loss_gen_all = loss_gen_all
986
+ if done: os._exit(0)
987
+
988
+ if __name__ == "__main__":
989
+ torch.multiprocessing.set_start_method("spawn")
990
+ main()
main/library/algorithm/commons.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+
3
+
4
+
5
+ def init_weights(m, mean=0.0, std=0.01):
6
+ if m.__class__.__name__.find("Conv") != -1: m.weight.data.normal_(mean, std)
7
+
8
+ def get_padding(kernel_size, dilation=1):
9
+ return int((kernel_size * dilation - dilation) / 2)
10
+
11
+ def convert_pad_shape(pad_shape):
12
+ return [item for sublist in pad_shape[::-1] for item in sublist]
13
+
14
+ def slice_segments(x, ids_str, segment_size = 4, dim = 2):
15
+ if dim == 2: ret = torch.zeros_like(x[:, :segment_size])
16
+ elif dim == 3: ret = torch.zeros_like(x[:, :, :segment_size])
17
+
18
+ for i in range(x.size(0)):
19
+ idx_str = ids_str[i].item()
20
+ idx_end = idx_str + segment_size
21
+
22
+ if dim == 2: ret[i] = x[i, idx_str:idx_end]
23
+ else: ret[i] = x[i, :, idx_str:idx_end]
24
+
25
+ return ret
26
+
27
+ def rand_slice_segments(x, x_lengths=None, segment_size=4):
28
+ b, _, t = x.size()
29
+ if x_lengths is None: x_lengths = t
30
+
31
+ ids_str = (torch.rand([b]).to(device=x.device) * (x_lengths - segment_size + 1)).to(dtype=torch.long)
32
+
33
+ return slice_segments(x, ids_str, segment_size, dim=3), ids_str
34
+
35
+ @torch.jit.script
36
+ def fused_add_tanh_sigmoid_multiply(input_a, input_b, n_channels):
37
+ n_channels_int = n_channels[0]
38
+
39
+ in_act = input_a + input_b
40
+
41
+ return torch.tanh(in_act[:, :n_channels_int, :]) * torch.sigmoid(in_act[:, n_channels_int:, :])
42
+
43
+ def sequence_mask(length, max_length = None):
44
+ if max_length is None: max_length = length.max()
45
+
46
+ return torch.arange(max_length, dtype=length.dtype, device=length.device).unsqueeze(0) < length.unsqueeze(1)
47
+
48
+ def clip_grad_value(parameters, clip_value, norm_type=2):
49
+ if isinstance(parameters, torch.Tensor): parameters = [parameters]
50
+ norm_type = float(norm_type)
51
+
52
+ if clip_value is not None: clip_value = float(clip_value)
53
+ total_norm = 0
54
+
55
+ for p in list(filter(lambda p: p.grad is not None, parameters)):
56
+ total_norm += (p.grad.data.norm(norm_type)).item() ** norm_type
57
+
58
+ if clip_value is not None: p.grad.data.clamp_(min=-clip_value, max=clip_value)
59
+
60
+ return total_norm ** (1.0 / norm_type)