jlopez00 commited on
Commit
1378843
1 Parent(s): f017d24

Upload folder using huggingface_hub

Browse files
.gitignore CHANGED
@@ -4,5 +4,6 @@ __pycache__/
4
  *.pyc
5
  .env
6
  assets/audios/
7
- logs/male-1/
8
  rvc/models/
 
 
4
  *.pyc
5
  .env
6
  assets/audios/
7
+ logs/
8
  rvc/models/
9
+ voices/
.vscode/launch.json CHANGED
@@ -4,6 +4,15 @@
4
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
  "version": "0.2.0",
6
  "configurations": [
 
 
 
 
 
 
 
 
 
7
  {
8
  "name": "App",
9
  "type": "debugpy",
 
4
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
  "version": "0.2.0",
6
  "configurations": [
7
+ {
8
+ "name": "upload-voices",
9
+ "type": "debugpy",
10
+ "request": "launch",
11
+ "program": "tts_service/cli.py",
12
+ "args": ["service", "upload-voices", "voices"],
13
+ "console": "integratedTerminal",
14
+ "justMyCode": false
15
+ },
16
  {
17
  "name": "App",
18
  "type": "debugpy",
.vscode/settings.json CHANGED
@@ -1,12 +1,12 @@
1
  {
2
  "editor.codeActionsOnSave": {
3
- "source.organizeImports": "never",
4
- "source.unusedImports": "never"
5
  },
6
  "editor.detectIndentation": false,
7
  "editor.formatOnPaste": true,
8
- "editor.formatOnSave": false,
9
- "editor.formatOnSaveMode": "modifications",
10
  "editor.formatOnType": true,
11
  "editor.renderWhitespace": "all",
12
  "editor.rulers": [132],
@@ -32,9 +32,9 @@
32
  "prettier.tabWidth": 4,
33
  "editor.defaultFormatter": "esbenp.prettier-vscode"
34
  },
35
- // "[python]": {
36
- // "editor.defaultFormatter": "charliermarsh.ruff"
37
- // },
38
  "[yaml]": {
39
  "editor.defaultFormatter": "kiliantyler.kubernetes-yaml-formatter-x"
40
  }
 
1
  {
2
  "editor.codeActionsOnSave": {
3
+ "source.organizeImports": "always",
4
+ "source.unusedImports": "always"
5
  },
6
  "editor.detectIndentation": false,
7
  "editor.formatOnPaste": true,
8
+ "editor.formatOnSave": true,
9
+ "editor.formatOnSaveMode": "file",
10
  "editor.formatOnType": true,
11
  "editor.renderWhitespace": "all",
12
  "editor.rulers": [132],
 
32
  "prettier.tabWidth": 4,
33
  "editor.defaultFormatter": "esbenp.prettier-vscode"
34
  },
35
+ "[python]": {
36
+ "editor.defaultFormatter": "charliermarsh.ruff"
37
+ },
38
  "[yaml]": {
39
  "editor.defaultFormatter": "kiliantyler.kubernetes-yaml-formatter-x"
40
  }
assets/i18n/i18n.py CHANGED
@@ -45,8 +45,5 @@ class I18nAuto:
45
  language_files = [path.stem for path in Path(self.LANGUAGE_PATH).glob("*.json")]
46
  return language_files
47
 
48
- def _language_exists(self, language):
49
- return (Path(self.LANGUAGE_PATH) / f"{language}.json").exists()
50
-
51
  def __call__(self, key):
52
  return self.language_map.get(key, key)
 
45
  language_files = [path.stem for path in Path(self.LANGUAGE_PATH).glob("*.json")]
46
  return language_files
47
 
 
 
 
48
  def __call__(self, key):
49
  return self.language_map.get(key, key)
assets/themes/loadThemes.py CHANGED
@@ -21,63 +21,6 @@ def read_json_file(filename):
21
  return json.load(json_file)
22
 
23
 
24
- def get_class(filename):
25
- """Retrieve the name of the first class found in the specified Python file."""
26
- with open(filename, "r", encoding="utf8") as file:
27
- for line in file:
28
- if "class " in line:
29
- class_name = line.split("class ")[1].split(":")[0].split("(")[0].strip()
30
- return class_name
31
- return None
32
-
33
-
34
- def get_theme_list():
35
- """Compile a list of available themes from Python files and a JSON file."""
36
- themes_from_files = [
37
- os.path.splitext(name)[0]
38
- for root, _, files in os.walk(folder)
39
- for name in files
40
- if name.endswith(".py") and root == folder
41
- ]
42
-
43
- json_file_path = os.path.join(folder, "theme_list.json")
44
- themes_from_url = []
45
-
46
- try:
47
- themes_from_url = [item["id"] for item in read_json_file(json_file_path)]
48
- except FileNotFoundError:
49
- print("theme_list.json not found, proceeding with available files only.")
50
-
51
- return list(set(themes_from_files + themes_from_url))
52
-
53
-
54
- def select_theme(name):
55
- """Select a theme by its name, updating the configuration file accordingly."""
56
- selected_file = f"{name}.py"
57
- full_path = os.path.join(folder, selected_file)
58
-
59
- config_data = read_json_file(config_file)
60
-
61
- if not os.path.exists(full_path):
62
- config_data["theme"]["file"] = None
63
- config_data["theme"]["class"] = name
64
- else:
65
- class_found = get_class(full_path)
66
- if class_found:
67
- config_data["theme"]["file"] = selected_file
68
- config_data["theme"]["class"] = class_found
69
- else:
70
- print(f"Theme class not found in {selected_file}.")
71
- return
72
-
73
- with open(config_file, "w", encoding="utf8") as json_file:
74
- json.dump(config_data, json_file, indent=2)
75
-
76
- message = f"Theme {name} successfully selected. Restart the application."
77
- print(message)
78
- gr.Info(message)
79
-
80
-
81
  def load_theme():
82
  """Load the selected theme based on the configuration file."""
83
  try:
@@ -99,17 +42,3 @@ def load_theme():
99
  except Exception as error:
100
  print(f"An error occurred while loading the theme: {error}")
101
  return None
102
-
103
-
104
- def read_current_theme():
105
- """Read the current theme class from the configuration file."""
106
- try:
107
- config_data = read_json_file(config_file)
108
- selected_file = config_data["theme"]["file"]
109
- class_name = config_data["theme"]["class"]
110
-
111
- return class_name if class_name else "ParityError/Interstellar"
112
-
113
- except Exception as error:
114
- print(f"An error occurred loading the theme: {error}")
115
- return "ParityError/Interstellar"
 
21
  return json.load(json_file)
22
 
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  def load_theme():
25
  """Load the selected theme based on the configuration file."""
26
  try:
 
42
  except Exception as error:
43
  print(f"An error occurred while loading the theme: {error}")
44
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
core/__init__.py CHANGED
@@ -1,41 +1,16 @@
1
  import os
2
- import sys
3
- import json
4
- import argparse
5
  import subprocess
 
6
  from functools import lru_cache
7
- from distutils.util import strtobool
8
-
9
- now_dir = os.getcwd()
10
- sys.path.append(now_dir)
11
 
12
- current_script_directory = os.path.dirname(os.path.realpath(__file__))
13
- logs_path = os.path.join(current_script_directory, "logs")
14
-
15
- from rvc.lib.tools.prerequisites_download import prequisites_download_pipeline
16
- from rvc.train.process.model_blender import model_blender
17
- from rvc.train.process.model_information import model_information
18
- from rvc.train.process.extract_small_model import extract_small_model
19
- from rvc.lib.tools.analyzer import analyze_audio
20
- from rvc.lib.tools.launch_tensorboard import launch_tensorboard_pipeline
21
  from rvc.lib.tools.model_download import model_download_pipeline
 
 
 
22
 
23
  python = sys.executable
24
 
25
 
26
- # Get TTS Voices -> https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4
27
- @lru_cache(maxsize=1) # Cache only one result since the file is static
28
- def load_voices_data():
29
- with open(
30
- os.path.join("rvc", "lib", "tools", "tts_voices.json"), "r", encoding="utf-8"
31
- ) as file:
32
- return json.load(file)
33
-
34
-
35
- voices_data = load_voices_data()
36
- locales = list({voice["Locale"] for voice in voices_data})
37
-
38
-
39
  @lru_cache(maxsize=None)
40
  def import_voice_converter():
41
  from rvc.infer.infer import VoiceConverter
@@ -43,587 +18,85 @@ def import_voice_converter():
43
  return VoiceConverter()
44
 
45
 
46
- @lru_cache(maxsize=1)
47
- def get_config():
48
- from rvc.configs.config import Config
49
-
50
- return Config()
51
-
52
-
53
- # Infer
54
- def run_infer_script(
55
- pitch: int,
56
- filter_radius: int,
57
- index_rate: float,
58
- volume_envelope: int,
59
- protect: float,
60
- hop_length: int,
61
- f0_method: str,
62
- input_path: str,
63
- output_path: str,
64
- pth_path: str,
65
- index_path: str,
66
- split_audio: bool,
67
- f0_autotune: bool,
68
- f0_autotune_strength: float,
69
- clean_audio: bool,
70
- clean_strength: float,
71
- export_format: str,
72
- upscale_audio: bool,
73
- f0_file: str,
74
- embedder_model: str,
75
- embedder_model_custom: str | None = None,
76
- formant_shifting: bool = False,
77
- formant_qfrency: float = 1.0,
78
- formant_timbre: float = 1.0,
79
- post_process: bool = False,
80
- reverb: bool = False,
81
- pitch_shift: bool = False,
82
- limiter: bool = False,
83
- gain: bool = False,
84
- distortion: bool = False,
85
- chorus: bool = False,
86
- bitcrush: bool = False,
87
- clipping: bool = False,
88
- compressor: bool = False,
89
- delay: bool = False,
90
- reverb_room_size: float = 0.5,
91
- reverb_damping: float = 0.5,
92
- reverb_wet_gain: float = 0.5,
93
- reverb_dry_gain: float = 0.5,
94
- reverb_width: float = 0.5,
95
- reverb_freeze_mode: float = 0.5,
96
- pitch_shift_semitones: float = 0.0,
97
- limiter_threshold: float = -6,
98
- limiter_release_time: float = 0.01,
99
- gain_db: float = 0.0,
100
- distortion_gain: float = 25,
101
- chorus_rate: float = 1.0,
102
- chorus_depth: float = 0.25,
103
- chorus_center_delay: float = 7,
104
- chorus_feedback: float = 0.0,
105
- chorus_mix: float = 0.5,
106
- bitcrush_bit_depth: int = 8,
107
- clipping_threshold: float = -6,
108
- compressor_threshold: float = 0,
109
- compressor_ratio: float = 1,
110
- compressor_attack: float = 1.0,
111
- compressor_release: float = 100,
112
- delay_seconds: float = 0.5,
113
- delay_feedback: float = 0.0,
114
- delay_mix: float = 0.5,
115
- sid: int = 0,
116
- ):
117
- kwargs = {
118
- "audio_input_path": input_path,
119
- "audio_output_path": output_path,
120
- "model_path": pth_path,
121
- "index_path": index_path,
122
- "pitch": pitch,
123
- "filter_radius": filter_radius,
124
- "index_rate": index_rate,
125
- "volume_envelope": volume_envelope,
126
- "protect": protect,
127
- "hop_length": hop_length,
128
- "f0_method": f0_method,
129
- "pth_path": pth_path,
130
- "index_path": index_path,
131
- "split_audio": split_audio,
132
- "f0_autotune": f0_autotune,
133
- "f0_autotune_strength": f0_autotune_strength,
134
- "clean_audio": clean_audio,
135
- "clean_strength": clean_strength,
136
- "export_format": export_format,
137
- "upscale_audio": upscale_audio,
138
- "f0_file": f0_file,
139
- "embedder_model": embedder_model,
140
- "embedder_model_custom": embedder_model_custom,
141
- "post_process": post_process,
142
- "formant_shifting": formant_shifting,
143
- "formant_qfrency": formant_qfrency,
144
- "formant_timbre": formant_timbre,
145
- "reverb": reverb,
146
- "pitch_shift": pitch_shift,
147
- "limiter": limiter,
148
- "gain": gain,
149
- "distortion": distortion,
150
- "chorus": chorus,
151
- "bitcrush": bitcrush,
152
- "clipping": clipping,
153
- "compressor": compressor,
154
- "delay": delay,
155
- "reverb_room_size": reverb_room_size,
156
- "reverb_damping": reverb_damping,
157
- "reverb_wet_level": reverb_wet_gain,
158
- "reverb_dry_level": reverb_dry_gain,
159
- "reverb_width": reverb_width,
160
- "reverb_freeze_mode": reverb_freeze_mode,
161
- "pitch_shift_semitones": pitch_shift_semitones,
162
- "limiter_threshold": limiter_threshold,
163
- "limiter_release": limiter_release_time,
164
- "gain_db": gain_db,
165
- "distortion_gain": distortion_gain,
166
- "chorus_rate": chorus_rate,
167
- "chorus_depth": chorus_depth,
168
- "chorus_delay": chorus_center_delay,
169
- "chorus_feedback": chorus_feedback,
170
- "chorus_mix": chorus_mix,
171
- "bitcrush_bit_depth": bitcrush_bit_depth,
172
- "clipping_threshold": clipping_threshold,
173
- "compressor_threshold": compressor_threshold,
174
- "compressor_ratio": compressor_ratio,
175
- "compressor_attack": compressor_attack,
176
- "compressor_release": compressor_release,
177
- "delay_seconds": delay_seconds,
178
- "delay_feedback": delay_feedback,
179
- "delay_mix": delay_mix,
180
- "sid": sid,
181
- }
182
- infer_pipeline = import_voice_converter()
183
- infer_pipeline.convert_audio(
184
- **kwargs,
185
- )
186
- return f"File {input_path} inferred successfully.", output_path.replace(
187
- ".wav", f".{export_format.lower()}"
188
- )
189
-
190
-
191
- # Batch infer
192
- def run_batch_infer_script(
193
- pitch: int,
194
- filter_radius: int,
195
- index_rate: float,
196
- volume_envelope: int,
197
- protect: float,
198
- hop_length: int,
199
- f0_method: str,
200
- input_folder: str,
201
- output_folder: str,
202
- pth_path: str,
203
- index_path: str,
204
- split_audio: bool,
205
- f0_autotune: bool,
206
- f0_autotune_strength: float,
207
- clean_audio: bool,
208
- clean_strength: float,
209
- export_format: str,
210
- upscale_audio: bool,
211
- f0_file: str,
212
- embedder_model: str,
213
- embedder_model_custom: str | None = None,
214
- formant_shifting: bool = False,
215
- formant_qfrency: float = 1.0,
216
- formant_timbre: float = 1.0,
217
- post_process: bool = False,
218
- reverb: bool = False,
219
- pitch_shift: bool = False,
220
- limiter: bool = False,
221
- gain: bool = False,
222
- distortion: bool = False,
223
- chorus: bool = False,
224
- bitcrush: bool = False,
225
- clipping: bool = False,
226
- compressor: bool = False,
227
- delay: bool = False,
228
- reverb_room_size: float = 0.5,
229
- reverb_damping: float = 0.5,
230
- reverb_wet_gain: float = 0.5,
231
- reverb_dry_gain: float = 0.5,
232
- reverb_width: float = 0.5,
233
- reverb_freeze_mode: float = 0.5,
234
- pitch_shift_semitones: float = 0.0,
235
- limiter_threshold: float = -6,
236
- limiter_release_time: float = 0.01,
237
- gain_db: float = 0.0,
238
- distortion_gain: float = 25,
239
- chorus_rate: float = 1.0,
240
- chorus_depth: float = 0.25,
241
- chorus_center_delay: float = 7,
242
- chorus_feedback: float = 0.0,
243
- chorus_mix: float = 0.5,
244
- bitcrush_bit_depth: int = 8,
245
- clipping_threshold: float = -6,
246
- compressor_threshold: float = 0,
247
- compressor_ratio: float = 1,
248
- compressor_attack: float = 1.0,
249
- compressor_release: float = 100,
250
- delay_seconds: float = 0.5,
251
- delay_feedback: float = 0.0,
252
- delay_mix: float = 0.5,
253
- sid: int = 0,
254
- ):
255
- kwargs = {
256
- "audio_input_paths": input_folder,
257
- "audio_output_path": output_folder,
258
- "model_path": pth_path,
259
- "index_path": index_path,
260
- "pitch": pitch,
261
- "filter_radius": filter_radius,
262
- "index_rate": index_rate,
263
- "volume_envelope": volume_envelope,
264
- "protect": protect,
265
- "hop_length": hop_length,
266
- "f0_method": f0_method,
267
- "pth_path": pth_path,
268
- "index_path": index_path,
269
- "split_audio": split_audio,
270
- "f0_autotune": f0_autotune,
271
- "f0_autotune_strength": f0_autotune_strength,
272
- "clean_audio": clean_audio,
273
- "clean_strength": clean_strength,
274
- "export_format": export_format,
275
- "upscale_audio": upscale_audio,
276
- "f0_file": f0_file,
277
- "embedder_model": embedder_model,
278
- "embedder_model_custom": embedder_model_custom,
279
- "post_process": post_process,
280
- "formant_shifting": formant_shifting,
281
- "formant_qfrency": formant_qfrency,
282
- "formant_timbre": formant_timbre,
283
- "reverb": reverb,
284
- "pitch_shift": pitch_shift,
285
- "limiter": limiter,
286
- "gain": gain,
287
- "distortion": distortion,
288
- "chorus": chorus,
289
- "bitcrush": bitcrush,
290
- "clipping": clipping,
291
- "compressor": compressor,
292
- "delay": delay,
293
- "reverb_room_size": reverb_room_size,
294
- "reverb_damping": reverb_damping,
295
- "reverb_wet_level": reverb_wet_gain,
296
- "reverb_dry_level": reverb_dry_gain,
297
- "reverb_width": reverb_width,
298
- "reverb_freeze_mode": reverb_freeze_mode,
299
- "pitch_shift_semitones": pitch_shift_semitones,
300
- "limiter_threshold": limiter_threshold,
301
- "limiter_release": limiter_release_time,
302
- "gain_db": gain_db,
303
- "distortion_gain": distortion_gain,
304
- "chorus_rate": chorus_rate,
305
- "chorus_depth": chorus_depth,
306
- "chorus_delay": chorus_center_delay,
307
- "chorus_feedback": chorus_feedback,
308
- "chorus_mix": chorus_mix,
309
- "bitcrush_bit_depth": bitcrush_bit_depth,
310
- "clipping_threshold": clipping_threshold,
311
- "compressor_threshold": compressor_threshold,
312
- "compressor_ratio": compressor_ratio,
313
- "compressor_attack": compressor_attack,
314
- "compressor_release": compressor_release,
315
- "delay_seconds": delay_seconds,
316
- "delay_feedback": delay_feedback,
317
- "delay_mix": delay_mix,
318
- "sid": sid,
319
- }
320
- infer_pipeline = import_voice_converter()
321
- infer_pipeline.convert_audio_batch(
322
- **kwargs,
323
- )
324
-
325
- return f"Files from {input_folder} inferred successfully."
326
-
327
-
328
  # TTS
329
  def run_tts_script(
330
- tts_file: str,
331
  tts_text: str,
332
- tts_voice: str,
333
  tts_rate: int,
334
- pitch: int,
335
- filter_radius: int,
336
- index_rate: float,
337
- volume_envelope: int,
338
- protect: float,
339
- hop_length: int,
340
- f0_method: str,
341
- output_tts_path: str,
342
- output_rvc_path: str,
343
- pth_path: str,
344
- index_path: str,
345
- split_audio: bool,
346
- f0_autotune: bool,
347
- f0_autotune_strength: float,
348
- clean_audio: bool,
349
- clean_strength: float,
350
- export_format: str,
351
- upscale_audio: bool,
352
- f0_file: str,
353
- embedder_model: str,
354
- embedder_model_custom: str | None = None,
355
- sid: int = 0,
356
- ):
357
-
358
  tts_script_path = os.path.join("rvc", "lib", "tools", "tts.py")
359
 
360
- if os.path.exists(output_tts_path):
361
- os.remove(output_tts_path)
362
- dirname = os.path.dirname(output_tts_path)
363
- if not os.path.exists(dirname):
364
- os.makedirs(dirname)
365
-
366
- command_tts = [
367
- *map(
368
- str,
369
- [
370
- python,
371
- tts_script_path,
372
- tts_file,
373
- tts_text,
374
- tts_voice,
375
- tts_rate,
376
- output_tts_path,
377
- ],
378
- ),
379
- ]
380
- subprocess.run(command_tts)
381
- infer_pipeline = import_voice_converter()
382
- infer_pipeline.convert_audio(
383
- pitch=pitch,
384
- filter_radius=filter_radius,
385
- index_rate=index_rate,
386
- volume_envelope=volume_envelope,
387
- protect=protect,
388
- hop_length=hop_length,
389
- f0_method=f0_method,
390
- audio_input_path=output_tts_path,
391
- audio_output_path=output_rvc_path,
392
- model_path=pth_path,
393
- index_path=index_path,
394
- split_audio=split_audio,
395
- f0_autotune=f0_autotune,
396
- f0_autotune_strength=f0_autotune_strength,
397
- clean_audio=clean_audio,
398
- clean_strength=clean_strength,
399
- export_format=export_format,
400
- upscale_audio=upscale_audio,
401
- f0_file=f0_file,
402
- embedder_model=embedder_model,
403
- embedder_model_custom=embedder_model_custom,
404
- sid=sid,
405
- formant_shifting=None,
406
- formant_qfrency=None,
407
- formant_timbre=None,
408
- post_process=None,
409
- reverb=None,
410
- pitch_shift=None,
411
- limiter=None,
412
- gain=None,
413
- distortion=None,
414
- chorus=None,
415
- bitcrush=None,
416
- clipping=None,
417
- compressor=None,
418
- delay=None,
419
- sliders=None,
420
- )
421
-
422
- return f"Text {tts_text} synthesized successfully.", output_rvc_path.replace(
423
- ".wav", f".{export_format.lower()}"
424
- )
425
-
426
-
427
- # Preprocess
428
- def run_preprocess_script(
429
- model_name: str,
430
- dataset_path: str,
431
- sample_rate: int,
432
- cpu_cores: int,
433
- cut_preprocess: bool,
434
- process_effects: bool,
435
- noise_reduction: bool,
436
- clean_strength: float,
437
- ):
438
- config = get_config()
439
- per = 3.0 if config.is_half else 3.7
440
- preprocess_script_path = os.path.join("rvc", "train", "preprocess", "preprocess.py")
441
- command = [
442
- python,
443
- preprocess_script_path,
444
- *map(
445
- str,
446
- [
447
- os.path.join(logs_path, model_name),
448
- dataset_path,
449
- sample_rate,
450
- per,
451
- cpu_cores,
452
- cut_preprocess,
453
- process_effects,
454
- noise_reduction,
455
- clean_strength,
456
- ],
457
- ),
458
- ]
459
- subprocess.run(command)
460
- return f"Model {model_name} preprocessed successfully."
461
-
462
-
463
- # Extract
464
- def run_extract_script(
465
- model_name: str,
466
- rvc_version: str,
467
- f0_method: str,
468
- hop_length: int,
469
- cpu_cores: int,
470
- gpu: int,
471
- sample_rate: int,
472
- embedder_model: str,
473
- embedder_model_custom: str | None = None,
474
- ):
475
-
476
- model_path = os.path.join(logs_path, model_name)
477
- extract = os.path.join("rvc", "train", "extract", "extract.py")
478
-
479
- command_1 = [
480
- python,
481
- extract,
482
- *map(
483
- str,
484
- [
485
- model_path,
486
- f0_method,
487
- hop_length,
488
- cpu_cores,
489
- gpu,
490
- rvc_version,
491
- sample_rate,
492
- embedder_model,
493
- embedder_model_custom,
494
- ],
495
- ),
496
- ]
497
-
498
- subprocess.run(command_1)
499
-
500
- return f"Model {model_name} extracted successfully."
501
-
502
-
503
- # Train
504
- def run_train_script(
505
- model_name: str,
506
- rvc_version: str,
507
- save_every_epoch: int,
508
- save_only_latest: bool,
509
- save_every_weights: bool,
510
- total_epoch: int,
511
- sample_rate: int,
512
- batch_size: int,
513
- gpu: int,
514
- pitch_guidance: bool,
515
- overtraining_detector: bool,
516
- overtraining_threshold: int,
517
- pretrained: bool,
518
- cleanup: bool,
519
- index_algorithm: str = "Auto",
520
- cache_data_in_gpu: bool = False,
521
- custom_pretrained: bool = False,
522
- g_pretrained_path: str | None = None,
523
- d_pretrained_path: str | None = None,
524
- ):
525
-
526
- if pretrained == True:
527
- from rvc.lib.tools.pretrained_selector import pretrained_selector
528
-
529
- if custom_pretrained == False:
530
- pg, pd = pretrained_selector(bool(pitch_guidance))[str(rvc_version)][
531
- int(sample_rate)
532
- ]
533
- else:
534
- if g_pretrained_path is None or d_pretrained_path is None:
535
- raise ValueError(
536
- "Please provide the path to the pretrained G and D models."
537
- )
538
- pg, pd = g_pretrained_path, d_pretrained_path
539
- else:
540
- pg, pd = "", ""
541
-
542
- train_script_path = os.path.join("rvc", "train", "train.py")
543
- command = [
544
- python,
545
- train_script_path,
546
- *map(
547
- str,
548
- [
549
- model_name,
550
- save_every_epoch,
551
- total_epoch,
552
- pg,
553
- pd,
554
- rvc_version,
555
- gpu,
556
- batch_size,
557
- sample_rate,
558
- pitch_guidance,
559
- save_only_latest,
560
- save_every_weights,
561
- cache_data_in_gpu,
562
- overtraining_detector,
563
- overtraining_threshold,
564
- cleanup,
565
- ],
566
- ),
567
- ]
568
- subprocess.run(command)
569
- run_index_script(model_name, rvc_version, index_algorithm)
570
- return f"Model {model_name} trained successfully."
571
-
572
-
573
- # Index
574
- def run_index_script(model_name: str, rvc_version: str, index_algorithm: str):
575
- index_script_path = os.path.join("rvc", "train", "process", "extract_index.py")
576
- command = [
577
- python,
578
- index_script_path,
579
- os.path.join(logs_path, model_name),
580
- rvc_version,
581
- index_algorithm,
582
- ]
583
-
584
- subprocess.run(command)
585
- return f"Index file for {model_name} generated successfully."
586
-
587
-
588
- # Model extract
589
- def run_model_extract_script(
590
- pth_path: str,
591
- model_name: str,
592
- sample_rate: int,
593
- pitch_guidance: bool,
594
- rvc_version: str,
595
- epoch: int,
596
- step: int,
597
- ):
598
- extract_small_model(
599
- pth_path, model_name, sample_rate, pitch_guidance, rvc_version, epoch, step
600
- )
601
- return f"Model {model_name} extracted successfully."
602
-
603
-
604
- # Model information
605
- def run_model_information_script(pth_path: str):
606
- print(model_information(pth_path))
607
- return model_information(pth_path)
608
-
609
-
610
- # Model blender
611
- def run_model_blender_script(
612
- model_name: str, pth_path_1: str, pth_path_2: str, ratio: float
613
- ):
614
- message, model_blended = model_blender(model_name, pth_path_1, pth_path_2, ratio)
615
- return message, model_blended
616
-
617
-
618
- # Tensorboard
619
- def run_tensorboard_script():
620
- launch_tensorboard_pipeline()
621
 
622
 
623
  # Download
624
  def run_download_script(model_link: str):
625
  model_download_pipeline(model_link)
626
- return f"Model downloaded successfully."
627
 
628
 
629
  # Prerequisites
@@ -633,7 +106,7 @@ def run_prerequisites_script(
633
  pretraineds_v2_f0: bool,
634
  pretraineds_v2_nof0: bool,
635
  models: bool,
636
- exe: bool,
637
  ):
638
  prequisites_download_pipeline(
639
  pretraineds_v1_f0,
@@ -641,1918 +114,6 @@ def run_prerequisites_script(
641
  pretraineds_v2_f0,
642
  pretraineds_v2_nof0,
643
  models,
644
- exe,
645
  )
646
  return "Prerequisites installed successfully."
647
-
648
-
649
- # Audio analyzer
650
- def run_audio_analyzer_script(
651
- input_path: str, save_plot_path: str = "logs/audio_analysis.png"
652
- ):
653
- audio_info, plot_path = analyze_audio(input_path, save_plot_path)
654
- print(
655
- f"Audio info of {input_path}: {audio_info}",
656
- f"Audio file {input_path} analyzed successfully. Plot saved at: {plot_path}",
657
- )
658
- return audio_info, plot_path
659
-
660
-
661
- # Parse arguments
662
- def parse_arguments():
663
- parser = argparse.ArgumentParser(
664
- description="Run the main.py script with specific parameters."
665
- )
666
- subparsers = parser.add_subparsers(
667
- title="subcommands", dest="mode", help="Choose a mode"
668
- )
669
-
670
- # Parser for 'infer' mode
671
- infer_parser = subparsers.add_parser("infer", help="Run inference")
672
- pitch_description = (
673
- "Set the pitch of the audio. Higher values result in a higher pitch."
674
- )
675
- infer_parser.add_argument(
676
- "--pitch",
677
- type=int,
678
- help=pitch_description,
679
- choices=range(-24, 25),
680
- default=0,
681
- )
682
- filter_radius_description = "Apply median filtering to the extracted pitch values if this value is greater than or equal to three. This can help reduce breathiness in the output audio."
683
- infer_parser.add_argument(
684
- "--filter_radius",
685
- type=int,
686
- help=filter_radius_description,
687
- choices=range(11),
688
- default=3,
689
- )
690
- index_rate_description = "Control the influence of the index file on the output. Higher values mean stronger influence. Lower values can help reduce artifacts but may result in less accurate voice cloning."
691
- infer_parser.add_argument(
692
- "--index_rate",
693
- type=float,
694
- help=index_rate_description,
695
- choices=[i / 100.0 for i in range(0, 101)],
696
- default=0.3,
697
- )
698
- volume_envelope_description = "Control the blending of the output's volume envelope. A value of 1 means the output envelope is fully used."
699
- infer_parser.add_argument(
700
- "--volume_envelope",
701
- type=float,
702
- help=volume_envelope_description,
703
- choices=[i / 100.0 for i in range(0, 101)],
704
- default=1,
705
- )
706
- protect_description = "Protect consonants and breathing sounds from artifacts. A value of 0.5 offers the strongest protection, while lower values may reduce the protection level but potentially mitigate the indexing effect."
707
- infer_parser.add_argument(
708
- "--protect",
709
- type=float,
710
- help=protect_description,
711
- choices=[i / 1000.0 for i in range(0, 501)],
712
- default=0.33,
713
- )
714
- hop_length_description = "Only applicable for the Crepe pitch extraction method. Determines the time it takes for the system to react to a significant pitch change. Smaller values require more processing time but can lead to better pitch accuracy."
715
- infer_parser.add_argument(
716
- "--hop_length",
717
- type=int,
718
- help=hop_length_description,
719
- choices=range(1, 513),
720
- default=128,
721
- )
722
- f0_method_description = "Choose the pitch extraction algorithm for the conversion. 'rmvpe' is the default and generally recommended."
723
- infer_parser.add_argument(
724
- "--f0_method",
725
- type=str,
726
- help=f0_method_description,
727
- choices=[
728
- "crepe",
729
- "crepe-tiny",
730
- "rmvpe",
731
- "fcpe",
732
- "hybrid[crepe+rmvpe]",
733
- "hybrid[crepe+fcpe]",
734
- "hybrid[rmvpe+fcpe]",
735
- "hybrid[crepe+rmvpe+fcpe]",
736
- ],
737
- default="rmvpe",
738
- )
739
- infer_parser.add_argument(
740
- "--output_rvc_path",
741
- type=str,
742
- help="Full path to the output RVC file.",
743
- required=True,
744
- )
745
- infer_parser.add_argument(
746
- "--output_tts_path",
747
- type=str,
748
- help="Full path to the output TTS audio file.",
749
- required=True,
750
- )
751
- pth_path_description = "Full path to the RVC model file (.pth)."
752
- infer_parser.add_argument(
753
- "--pth_path", type=str, help=pth_path_description, required=True
754
- )
755
- index_path_description = "Full path to the index file (.index)."
756
- infer_parser.add_argument(
757
- "--index_path", type=str, help=index_path_description, required=True
758
- )
759
- split_audio_description = "Split the audio into smaller segments before inference. This can improve the quality of the output for longer audio files."
760
- infer_parser.add_argument(
761
- "--split_audio",
762
- type=lambda x: bool(strtobool(x)),
763
- choices=[True, False],
764
- help=split_audio_description,
765
- default=False,
766
- )
767
- f0_autotune_description = "Apply a light autotune to the inferred audio. Particularly useful for singing voice conversions."
768
- infer_parser.add_argument(
769
- "--f0_autotune",
770
- type=lambda x: bool(strtobool(x)),
771
- choices=[True, False],
772
- help=f0_autotune_description,
773
- default=False,
774
- )
775
- f0_autotune_strength_description = "Set the autotune strength - the more you increase it the more it will snap to the chromatic grid."
776
- infer_parser.add_argument(
777
- "--f0_autotune_strength",
778
- type=float,
779
- help=f0_autotune_strength_description,
780
- choices=[(i / 10) for i in range(11)],
781
- default=1.0,
782
- )
783
- clean_audio_description = "Clean the output audio using noise reduction algorithms. Recommended for speech conversions."
784
- infer_parser.add_argument(
785
- "--clean_audio",
786
- type=lambda x: bool(strtobool(x)),
787
- choices=[True, False],
788
- help=clean_audio_description,
789
- default=False,
790
- )
791
- clean_strength_description = "Adjust the intensity of the audio cleaning process. Higher values result in stronger cleaning, but may lead to a more compressed sound."
792
- infer_parser.add_argument(
793
- "--clean_strength",
794
- type=float,
795
- help=clean_strength_description,
796
- choices=[(i / 10) for i in range(11)],
797
- default=0.7,
798
- )
799
- export_format_description = "Select the desired output audio format."
800
- infer_parser.add_argument(
801
- "--export_format",
802
- type=str,
803
- help=export_format_description,
804
- choices=["WAV", "MP3", "FLAC", "OGG", "M4A"],
805
- default="WAV",
806
- )
807
- embedder_model_description = (
808
- "Choose the model used for generating speaker embeddings."
809
- )
810
- infer_parser.add_argument(
811
- "--embedder_model",
812
- type=str,
813
- help=embedder_model_description,
814
- choices=[
815
- "contentvec",
816
- "chinese-hubert-base",
817
- "japanese-hubert-base",
818
- "korean-hubert-base",
819
- "custom",
820
- ],
821
- default="contentvec",
822
- )
823
- embedder_model_custom_description = "Specify the path to a custom model for speaker embedding. Only applicable if 'embedder_model' is set to 'custom'."
824
- infer_parser.add_argument(
825
- "--embedder_model_custom",
826
- type=str,
827
- help=embedder_model_custom_description,
828
- default=None,
829
- )
830
- upscale_audio_description = "Upscale the input audio to a higher quality before processing. This can improve the overall quality of the output, especially for low-quality input audio."
831
- infer_parser.add_argument(
832
- "--upscale_audio",
833
- type=lambda x: bool(strtobool(x)),
834
- choices=[True, False],
835
- help=upscale_audio_description,
836
- default=False,
837
- )
838
- f0_file_description = "Full path to an external F0 file (.f0). This allows you to use pre-computed pitch values for the input audio."
839
- infer_parser.add_argument(
840
- "--f0_file",
841
- type=str,
842
- help=f0_file_description,
843
- default=None,
844
- )
845
- formant_shifting_description = "Apply formant shifting to the input audio. This can help adjust the timbre of the voice."
846
- infer_parser.add_argument(
847
- "--formant_shifting",
848
- type=lambda x: bool(strtobool(x)),
849
- choices=[True, False],
850
- help=formant_shifting_description,
851
- default=False,
852
- required=False,
853
- )
854
- formant_qfrency_description = "Control the frequency of the formant shifting effect. Higher values result in a more pronounced effect."
855
- infer_parser.add_argument(
856
- "--formant_qfrency",
857
- type=float,
858
- help=formant_qfrency_description,
859
- default=1.0,
860
- required=False,
861
- )
862
- formant_timbre_description = "Control the timbre of the formant shifting effect. Higher values result in a more pronounced effect."
863
- infer_parser.add_argument(
864
- "--formant_timbre",
865
- type=float,
866
- help=formant_timbre_description,
867
- default=1.0,
868
- required=False,
869
- )
870
- sid_description = "Speaker ID for multi-speaker models."
871
- infer_parser.add_argument(
872
- "--sid",
873
- type=int,
874
- help=sid_description,
875
- default=0,
876
- required=False,
877
- )
878
- post_process_description = "Apply post-processing effects to the output audio."
879
- infer_parser.add_argument(
880
- "--post_process",
881
- type=lambda x: bool(strtobool(x)),
882
- choices=[True, False],
883
- help=post_process_description,
884
- default=False,
885
- required=False,
886
- )
887
- reverb_description = "Apply reverb effect to the output audio."
888
- infer_parser.add_argument(
889
- "--reverb",
890
- type=lambda x: bool(strtobool(x)),
891
- choices=[True, False],
892
- help=reverb_description,
893
- default=False,
894
- required=False,
895
- )
896
-
897
- pitch_shift_description = "Apply pitch shifting effect to the output audio."
898
- infer_parser.add_argument(
899
- "--pitch_shift",
900
- type=lambda x: bool(strtobool(x)),
901
- choices=[True, False],
902
- help=pitch_shift_description,
903
- default=False,
904
- required=False,
905
- )
906
-
907
- limiter_description = "Apply limiter effect to the output audio."
908
- infer_parser.add_argument(
909
- "--limiter",
910
- type=lambda x: bool(strtobool(x)),
911
- choices=[True, False],
912
- help=limiter_description,
913
- default=False,
914
- required=False,
915
- )
916
-
917
- gain_description = "Apply gain effect to the output audio."
918
- infer_parser.add_argument(
919
- "--gain",
920
- type=lambda x: bool(strtobool(x)),
921
- choices=[True, False],
922
- help=gain_description,
923
- default=False,
924
- required=False,
925
- )
926
-
927
- distortion_description = "Apply distortion effect to the output audio."
928
- infer_parser.add_argument(
929
- "--distortion",
930
- type=lambda x: bool(strtobool(x)),
931
- choices=[True, False],
932
- help=distortion_description,
933
- default=False,
934
- required=False,
935
- )
936
-
937
- chorus_description = "Apply chorus effect to the output audio."
938
- infer_parser.add_argument(
939
- "--chorus",
940
- type=lambda x: bool(strtobool(x)),
941
- choices=[True, False],
942
- help=chorus_description,
943
- default=False,
944
- required=False,
945
- )
946
-
947
- bitcrush_description = "Apply bitcrush effect to the output audio."
948
- infer_parser.add_argument(
949
- "--bitcrush",
950
- type=lambda x: bool(strtobool(x)),
951
- choices=[True, False],
952
- help=bitcrush_description,
953
- default=False,
954
- required=False,
955
- )
956
-
957
- clipping_description = "Apply clipping effect to the output audio."
958
- infer_parser.add_argument(
959
- "--clipping",
960
- type=lambda x: bool(strtobool(x)),
961
- choices=[True, False],
962
- help=clipping_description,
963
- default=False,
964
- required=False,
965
- )
966
-
967
- compressor_description = "Apply compressor effect to the output audio."
968
- infer_parser.add_argument(
969
- "--compressor",
970
- type=lambda x: bool(strtobool(x)),
971
- choices=[True, False],
972
- help=compressor_description,
973
- default=False,
974
- required=False,
975
- )
976
-
977
- delay_description = "Apply delay effect to the output audio."
978
- infer_parser.add_argument(
979
- "--delay",
980
- type=lambda x: bool(strtobool(x)),
981
- choices=[True, False],
982
- help=delay_description,
983
- default=False,
984
- required=False,
985
- )
986
-
987
- reverb_room_size_description = "Control the room size of the reverb effect. Higher values result in a larger room size."
988
- infer_parser.add_argument(
989
- "--reverb_room_size",
990
- type=float,
991
- help=reverb_room_size_description,
992
- default=0.5,
993
- required=False,
994
- )
995
-
996
- reverb_damping_description = "Control the damping of the reverb effect. Higher values result in a more damped sound."
997
- infer_parser.add_argument(
998
- "--reverb_damping",
999
- type=float,
1000
- help=reverb_damping_description,
1001
- default=0.5,
1002
- required=False,
1003
- )
1004
-
1005
- reverb_wet_gain_description = "Control the wet gain of the reverb effect. Higher values result in a stronger reverb effect."
1006
- infer_parser.add_argument(
1007
- "--reverb_wet_gain",
1008
- type=float,
1009
- help=reverb_wet_gain_description,
1010
- default=0.5,
1011
- required=False,
1012
- )
1013
-
1014
- reverb_dry_gain_description = "Control the dry gain of the reverb effect. Higher values result in a stronger dry signal."
1015
- infer_parser.add_argument(
1016
- "--reverb_dry_gain",
1017
- type=float,
1018
- help=reverb_dry_gain_description,
1019
- default=0.5,
1020
- required=False,
1021
- )
1022
-
1023
- reverb_width_description = "Control the stereo width of the reverb effect. Higher values result in a wider stereo image."
1024
- infer_parser.add_argument(
1025
- "--reverb_width",
1026
- type=float,
1027
- help=reverb_width_description,
1028
- default=0.5,
1029
- required=False,
1030
- )
1031
-
1032
- reverb_freeze_mode_description = "Control the freeze mode of the reverb effect. Higher values result in a stronger freeze effect."
1033
- infer_parser.add_argument(
1034
- "--reverb_freeze_mode",
1035
- type=float,
1036
- help=reverb_freeze_mode_description,
1037
- default=0.5,
1038
- required=False,
1039
- )
1040
-
1041
- pitch_shift_semitones_description = "Control the pitch shift in semitones. Positive values increase the pitch, while negative values decrease it."
1042
- infer_parser.add_argument(
1043
- "--pitch_shift_semitones",
1044
- type=float,
1045
- help=pitch_shift_semitones_description,
1046
- default=0.0,
1047
- required=False,
1048
- )
1049
-
1050
- limiter_threshold_description = "Control the threshold of the limiter effect. Higher values result in a stronger limiting effect."
1051
- infer_parser.add_argument(
1052
- "--limiter_threshold",
1053
- type=float,
1054
- help=limiter_threshold_description,
1055
- default=-6,
1056
- required=False,
1057
- )
1058
-
1059
- limiter_release_time_description = "Control the release time of the limiter effect. Higher values result in a longer release time."
1060
- infer_parser.add_argument(
1061
- "--limiter_release_time",
1062
- type=float,
1063
- help=limiter_release_time_description,
1064
- default=0.01,
1065
- required=False,
1066
- )
1067
-
1068
- gain_db_description = "Control the gain in decibels. Positive values increase the gain, while negative values decrease it."
1069
- infer_parser.add_argument(
1070
- "--gain_db",
1071
- type=float,
1072
- help=gain_db_description,
1073
- default=0.0,
1074
- required=False,
1075
- )
1076
-
1077
- distortion_gain_description = "Control the gain of the distortion effect. Higher values result in a stronger distortion effect."
1078
- infer_parser.add_argument(
1079
- "--distortion_gain",
1080
- type=float,
1081
- help=distortion_gain_description,
1082
- default=25,
1083
- required=False,
1084
- )
1085
-
1086
- chorus_rate_description = "Control the rate of the chorus effect. Higher values result in a faster chorus effect."
1087
- infer_parser.add_argument(
1088
- "--chorus_rate",
1089
- type=float,
1090
- help=chorus_rate_description,
1091
- default=1.0,
1092
- required=False,
1093
- )
1094
-
1095
- chorus_depth_description = "Control the depth of the chorus effect. Higher values result in a stronger chorus effect."
1096
- infer_parser.add_argument(
1097
- "--chorus_depth",
1098
- type=float,
1099
- help=chorus_depth_description,
1100
- default=0.25,
1101
- required=False,
1102
- )
1103
-
1104
- chorus_center_delay_description = "Control the center delay of the chorus effect. Higher values result in a longer center delay."
1105
- infer_parser.add_argument(
1106
- "--chorus_center_delay",
1107
- type=float,
1108
- help=chorus_center_delay_description,
1109
- default=7,
1110
- required=False,
1111
- )
1112
-
1113
- chorus_feedback_description = "Control the feedback of the chorus effect. Higher values result in a stronger feedback effect."
1114
- infer_parser.add_argument(
1115
- "--chorus_feedback",
1116
- type=float,
1117
- help=chorus_feedback_description,
1118
- default=0.0,
1119
- required=False,
1120
- )
1121
-
1122
- chorus_mix_description = "Control the mix of the chorus effect. Higher values result in a stronger chorus effect."
1123
- infer_parser.add_argument(
1124
- "--chorus_mix",
1125
- type=float,
1126
- help=chorus_mix_description,
1127
- default=0.5,
1128
- required=False,
1129
- )
1130
-
1131
- bitcrush_bit_depth_description = "Control the bit depth of the bitcrush effect. Higher values result in a stronger bitcrush effect."
1132
- infer_parser.add_argument(
1133
- "--bitcrush_bit_depth",
1134
- type=int,
1135
- help=bitcrush_bit_depth_description,
1136
- default=8,
1137
- required=False,
1138
- )
1139
-
1140
- clipping_threshold_description = "Control the threshold of the clipping effect. Higher values result in a stronger clipping effect."
1141
- infer_parser.add_argument(
1142
- "--clipping_threshold",
1143
- type=float,
1144
- help=clipping_threshold_description,
1145
- default=-6,
1146
- required=False,
1147
- )
1148
-
1149
- compressor_threshold_description = "Control the threshold of the compressor effect. Higher values result in a stronger compressor effect."
1150
- infer_parser.add_argument(
1151
- "--compressor_threshold",
1152
- type=float,
1153
- help=compressor_threshold_description,
1154
- default=0,
1155
- required=False,
1156
- )
1157
-
1158
- compressor_ratio_description = "Control the ratio of the compressor effect. Higher values result in a stronger compressor effect."
1159
- infer_parser.add_argument(
1160
- "--compressor_ratio",
1161
- type=float,
1162
- help=compressor_ratio_description,
1163
- default=1,
1164
- required=False,
1165
- )
1166
-
1167
- compressor_attack_description = "Control the attack of the compressor effect. Higher values result in a stronger compressor effect."
1168
- infer_parser.add_argument(
1169
- "--compressor_attack",
1170
- type=float,
1171
- help=compressor_attack_description,
1172
- default=1.0,
1173
- required=False,
1174
- )
1175
-
1176
- compressor_release_description = "Control the release of the compressor effect. Higher values result in a stronger compressor effect."
1177
- infer_parser.add_argument(
1178
- "--compressor_release",
1179
- type=float,
1180
- help=compressor_release_description,
1181
- default=100,
1182
- required=False,
1183
- )
1184
-
1185
- delay_seconds_description = "Control the delay time in seconds. Higher values result in a longer delay time."
1186
- infer_parser.add_argument(
1187
- "--delay_seconds",
1188
- type=float,
1189
- help=delay_seconds_description,
1190
- default=0.5,
1191
- required=False,
1192
- )
1193
- delay_feedback_description = "Control the feedback of the delay effect. Higher values result in a stronger feedback effect."
1194
- infer_parser.add_argument(
1195
- "--delay_feedback",
1196
- type=float,
1197
- help=delay_feedback_description,
1198
- default=0.0,
1199
- required=False,
1200
- )
1201
- delay_mix_description = "Control the mix of the delay effect. Higher values result in a stronger delay effect."
1202
- infer_parser.add_argument(
1203
- "--delay_mix",
1204
- type=float,
1205
- help=delay_mix_description,
1206
- default=0.5,
1207
- required=False,
1208
- )
1209
-
1210
- # Parser for 'batch_infer' mode
1211
- batch_infer_parser = subparsers.add_parser(
1212
- "batch_infer",
1213
- help="Run batch inference",
1214
- )
1215
- batch_infer_parser.add_argument(
1216
- "--pitch",
1217
- type=int,
1218
- help=pitch_description,
1219
- choices=range(-24, 25),
1220
- default=0,
1221
- )
1222
- batch_infer_parser.add_argument(
1223
- "--filter_radius",
1224
- type=int,
1225
- help=filter_radius_description,
1226
- choices=range(11),
1227
- default=3,
1228
- )
1229
- batch_infer_parser.add_argument(
1230
- "--index_rate",
1231
- type=float,
1232
- help=index_rate_description,
1233
- choices=[i / 100.0 for i in range(0, 101)],
1234
- default=0.3,
1235
- )
1236
- batch_infer_parser.add_argument(
1237
- "--volume_envelope",
1238
- type=float,
1239
- help=volume_envelope_description,
1240
- choices=[i / 100.0 for i in range(0, 101)],
1241
- default=1,
1242
- )
1243
- batch_infer_parser.add_argument(
1244
- "--protect",
1245
- type=float,
1246
- help=protect_description,
1247
- choices=[i / 1000.0 for i in range(0, 501)],
1248
- default=0.33,
1249
- )
1250
- batch_infer_parser.add_argument(
1251
- "--hop_length",
1252
- type=int,
1253
- help=hop_length_description,
1254
- choices=range(1, 513),
1255
- default=128,
1256
- )
1257
- batch_infer_parser.add_argument(
1258
- "--f0_method",
1259
- type=str,
1260
- help=f0_method_description,
1261
- choices=[
1262
- "crepe",
1263
- "crepe-tiny",
1264
- "rmvpe",
1265
- "fcpe",
1266
- "hybrid[crepe+rmvpe]",
1267
- "hybrid[crepe+fcpe]",
1268
- "hybrid[rmvpe+fcpe]",
1269
- "hybrid[crepe+rmvpe+fcpe]",
1270
- ],
1271
- default="rmvpe",
1272
- )
1273
- batch_infer_parser.add_argument(
1274
- "--input_folder",
1275
- type=str,
1276
- help="Path to the folder containing input audio files.",
1277
- required=True,
1278
- )
1279
- batch_infer_parser.add_argument(
1280
- "--output_folder",
1281
- type=str,
1282
- help="Path to the folder for saving output audio files.",
1283
- required=True,
1284
- )
1285
- batch_infer_parser.add_argument(
1286
- "--pth_path", type=str, help=pth_path_description, required=True
1287
- )
1288
- batch_infer_parser.add_argument(
1289
- "--index_path", type=str, help=index_path_description, required=True
1290
- )
1291
- batch_infer_parser.add_argument(
1292
- "--split_audio",
1293
- type=lambda x: bool(strtobool(x)),
1294
- choices=[True, False],
1295
- help=split_audio_description,
1296
- default=False,
1297
- )
1298
- batch_infer_parser.add_argument(
1299
- "--f0_autotune",
1300
- type=lambda x: bool(strtobool(x)),
1301
- choices=[True, False],
1302
- help=f0_autotune_description,
1303
- default=False,
1304
- )
1305
- batch_infer_parser.add_argument(
1306
- "--f0_autotune_strength",
1307
- type=float,
1308
- help=clean_strength_description,
1309
- choices=[(i / 10) for i in range(11)],
1310
- default=1.0,
1311
- )
1312
- batch_infer_parser.add_argument(
1313
- "--clean_audio",
1314
- type=lambda x: bool(strtobool(x)),
1315
- choices=[True, False],
1316
- help=clean_audio_description,
1317
- default=False,
1318
- )
1319
- batch_infer_parser.add_argument(
1320
- "--clean_strength",
1321
- type=float,
1322
- help=clean_strength_description,
1323
- choices=[(i / 10) for i in range(11)],
1324
- default=0.7,
1325
- )
1326
- batch_infer_parser.add_argument(
1327
- "--export_format",
1328
- type=str,
1329
- help=export_format_description,
1330
- choices=["WAV", "MP3", "FLAC", "OGG", "M4A"],
1331
- default="WAV",
1332
- )
1333
- batch_infer_parser.add_argument(
1334
- "--embedder_model",
1335
- type=str,
1336
- help=embedder_model_description,
1337
- choices=[
1338
- "contentvec",
1339
- "chinese-hubert-base",
1340
- "japanese-hubert-base",
1341
- "korean-hubert-base",
1342
- "custom",
1343
- ],
1344
- default="contentvec",
1345
- )
1346
- batch_infer_parser.add_argument(
1347
- "--embedder_model_custom",
1348
- type=str,
1349
- help=embedder_model_custom_description,
1350
- default=None,
1351
- )
1352
- batch_infer_parser.add_argument(
1353
- "--upscale_audio",
1354
- type=lambda x: bool(strtobool(x)),
1355
- choices=[True, False],
1356
- help=upscale_audio_description,
1357
- default=False,
1358
- )
1359
- batch_infer_parser.add_argument(
1360
- "--f0_file",
1361
- type=str,
1362
- help=f0_file_description,
1363
- default=None,
1364
- )
1365
- batch_infer_parser.add_argument(
1366
- "--formant_shifting",
1367
- type=lambda x: bool(strtobool(x)),
1368
- choices=[True, False],
1369
- help=formant_shifting_description,
1370
- default=False,
1371
- required=False,
1372
- )
1373
- batch_infer_parser.add_argument(
1374
- "--formant_qfrency",
1375
- type=float,
1376
- help=formant_qfrency_description,
1377
- default=1.0,
1378
- required=False,
1379
- )
1380
- batch_infer_parser.add_argument(
1381
- "--formant_timbre",
1382
- type=float,
1383
- help=formant_timbre_description,
1384
- default=1.0,
1385
- required=False,
1386
- )
1387
- batch_infer_parser.add_argument(
1388
- "--sid",
1389
- type=int,
1390
- help=sid_description,
1391
- default=0,
1392
- required=False,
1393
- )
1394
- batch_infer_parser.add_argument(
1395
- "--post_process",
1396
- type=lambda x: bool(strtobool(x)),
1397
- choices=[True, False],
1398
- help=post_process_description,
1399
- default=False,
1400
- required=False,
1401
- )
1402
- batch_infer_parser.add_argument(
1403
- "--reverb",
1404
- type=lambda x: bool(strtobool(x)),
1405
- choices=[True, False],
1406
- help=reverb_description,
1407
- default=False,
1408
- required=False,
1409
- )
1410
-
1411
- batch_infer_parser.add_argument(
1412
- "--pitch_shift",
1413
- type=lambda x: bool(strtobool(x)),
1414
- choices=[True, False],
1415
- help=pitch_shift_description,
1416
- default=False,
1417
- required=False,
1418
- )
1419
-
1420
- batch_infer_parser.add_argument(
1421
- "--limiter",
1422
- type=lambda x: bool(strtobool(x)),
1423
- choices=[True, False],
1424
- help=limiter_description,
1425
- default=False,
1426
- required=False,
1427
- )
1428
-
1429
- batch_infer_parser.add_argument(
1430
- "--gain",
1431
- type=lambda x: bool(strtobool(x)),
1432
- choices=[True, False],
1433
- help=gain_description,
1434
- default=False,
1435
- required=False,
1436
- )
1437
-
1438
- batch_infer_parser.add_argument(
1439
- "--distortion",
1440
- type=lambda x: bool(strtobool(x)),
1441
- choices=[True, False],
1442
- help=distortion_description,
1443
- default=False,
1444
- required=False,
1445
- )
1446
-
1447
- batch_infer_parser.add_argument(
1448
- "--chorus",
1449
- type=lambda x: bool(strtobool(x)),
1450
- choices=[True, False],
1451
- help=chorus_description,
1452
- default=False,
1453
- required=False,
1454
- )
1455
-
1456
- batch_infer_parser.add_argument(
1457
- "--bitcrush",
1458
- type=lambda x: bool(strtobool(x)),
1459
- choices=[True, False],
1460
- help=bitcrush_description,
1461
- default=False,
1462
- required=False,
1463
- )
1464
-
1465
- batch_infer_parser.add_argument(
1466
- "--clipping",
1467
- type=lambda x: bool(strtobool(x)),
1468
- choices=[True, False],
1469
- help=clipping_description,
1470
- default=False,
1471
- required=False,
1472
- )
1473
-
1474
- batch_infer_parser.add_argument(
1475
- "--compressor",
1476
- type=lambda x: bool(strtobool(x)),
1477
- choices=[True, False],
1478
- help=compressor_description,
1479
- default=False,
1480
- required=False,
1481
- )
1482
-
1483
- batch_infer_parser.add_argument(
1484
- "--delay",
1485
- type=lambda x: bool(strtobool(x)),
1486
- choices=[True, False],
1487
- help=delay_description,
1488
- default=False,
1489
- required=False,
1490
- )
1491
-
1492
- batch_infer_parser.add_argument(
1493
- "--reverb_room_size",
1494
- type=float,
1495
- help=reverb_room_size_description,
1496
- default=0.5,
1497
- required=False,
1498
- )
1499
-
1500
- batch_infer_parser.add_argument(
1501
- "--reverb_damping",
1502
- type=float,
1503
- help=reverb_damping_description,
1504
- default=0.5,
1505
- required=False,
1506
- )
1507
-
1508
- batch_infer_parser.add_argument(
1509
- "--reverb_wet_gain",
1510
- type=float,
1511
- help=reverb_wet_gain_description,
1512
- default=0.5,
1513
- required=False,
1514
- )
1515
-
1516
- batch_infer_parser.add_argument(
1517
- "--reverb_dry_gain",
1518
- type=float,
1519
- help=reverb_dry_gain_description,
1520
- default=0.5,
1521
- required=False,
1522
- )
1523
-
1524
- batch_infer_parser.add_argument(
1525
- "--reverb_width",
1526
- type=float,
1527
- help=reverb_width_description,
1528
- default=0.5,
1529
- required=False,
1530
- )
1531
-
1532
- batch_infer_parser.add_argument(
1533
- "--reverb_freeze_mode",
1534
- type=float,
1535
- help=reverb_freeze_mode_description,
1536
- default=0.5,
1537
- required=False,
1538
- )
1539
-
1540
- batch_infer_parser.add_argument(
1541
- "--pitch_shift_semitones",
1542
- type=float,
1543
- help=pitch_shift_semitones_description,
1544
- default=0.0,
1545
- required=False,
1546
- )
1547
-
1548
- batch_infer_parser.add_argument(
1549
- "--limiter_threshold",
1550
- type=float,
1551
- help=limiter_threshold_description,
1552
- default=-6,
1553
- required=False,
1554
- )
1555
-
1556
- batch_infer_parser.add_argument(
1557
- "--limiter_release_time",
1558
- type=float,
1559
- help=limiter_release_time_description,
1560
- default=0.01,
1561
- required=False,
1562
- )
1563
- batch_infer_parser.add_argument(
1564
- "--gain_db",
1565
- type=float,
1566
- help=gain_db_description,
1567
- default=0.0,
1568
- required=False,
1569
- )
1570
-
1571
- batch_infer_parser.add_argument(
1572
- "--distortion_gain",
1573
- type=float,
1574
- help=distortion_gain_description,
1575
- default=25,
1576
- required=False,
1577
- )
1578
-
1579
- batch_infer_parser.add_argument(
1580
- "--chorus_rate",
1581
- type=float,
1582
- help=chorus_rate_description,
1583
- default=1.0,
1584
- required=False,
1585
- )
1586
-
1587
- batch_infer_parser.add_argument(
1588
- "--chorus_depth",
1589
- type=float,
1590
- help=chorus_depth_description,
1591
- default=0.25,
1592
- required=False,
1593
- )
1594
- batch_infer_parser.add_argument(
1595
- "--chorus_center_delay",
1596
- type=float,
1597
- help=chorus_center_delay_description,
1598
- default=7,
1599
- required=False,
1600
- )
1601
-
1602
- batch_infer_parser.add_argument(
1603
- "--chorus_feedback",
1604
- type=float,
1605
- help=chorus_feedback_description,
1606
- default=0.0,
1607
- required=False,
1608
- )
1609
-
1610
- batch_infer_parser.add_argument(
1611
- "--chorus_mix",
1612
- type=float,
1613
- help=chorus_mix_description,
1614
- default=0.5,
1615
- required=False,
1616
- )
1617
-
1618
- batch_infer_parser.add_argument(
1619
- "--bitcrush_bit_depth",
1620
- type=int,
1621
- help=bitcrush_bit_depth_description,
1622
- default=8,
1623
- required=False,
1624
- )
1625
-
1626
- batch_infer_parser.add_argument(
1627
- "--clipping_threshold",
1628
- type=float,
1629
- help=clipping_threshold_description,
1630
- default=-6,
1631
- required=False,
1632
- )
1633
-
1634
- batch_infer_parser.add_argument(
1635
- "--compressor_threshold",
1636
- type=float,
1637
- help=compressor_threshold_description,
1638
- default=0,
1639
- required=False,
1640
- )
1641
-
1642
- batch_infer_parser.add_argument(
1643
- "--compressor_ratio",
1644
- type=float,
1645
- help=compressor_ratio_description,
1646
- default=1,
1647
- required=False,
1648
- )
1649
-
1650
- batch_infer_parser.add_argument(
1651
- "--compressor_attack",
1652
- type=float,
1653
- help=compressor_attack_description,
1654
- default=1.0,
1655
- required=False,
1656
- )
1657
-
1658
- batch_infer_parser.add_argument(
1659
- "--compressor_release",
1660
- type=float,
1661
- help=compressor_release_description,
1662
- default=100,
1663
- required=False,
1664
- )
1665
- batch_infer_parser.add_argument(
1666
- "--delay_seconds",
1667
- type=float,
1668
- help=delay_seconds_description,
1669
- default=0.5,
1670
- required=False,
1671
- )
1672
- batch_infer_parser.add_argument(
1673
- "--delay_feedback",
1674
- type=float,
1675
- help=delay_feedback_description,
1676
- default=0.0,
1677
- required=False,
1678
- )
1679
- batch_infer_parser.add_argument(
1680
- "--delay_mix",
1681
- type=float,
1682
- help=delay_mix_description,
1683
- default=0.5,
1684
- required=False,
1685
- )
1686
-
1687
- # Parser for 'tts' mode
1688
- tts_parser = subparsers.add_parser("tts", help="Run TTS inference")
1689
- tts_parser.add_argument(
1690
- "--tts_file", type=str, help="File with a text to be synthesized", required=True
1691
- )
1692
- tts_parser.add_argument(
1693
- "--tts_text", type=str, help="Text to be synthesized", required=True
1694
- )
1695
- tts_parser.add_argument(
1696
- "--tts_voice",
1697
- type=str,
1698
- help="Voice to be used for TTS synthesis.",
1699
- choices=locales,
1700
- required=True,
1701
- )
1702
- tts_parser.add_argument(
1703
- "--tts_rate",
1704
- type=int,
1705
- help="Control the speaking rate of the TTS. Values range from -100 (slower) to 100 (faster).",
1706
- choices=range(-100, 101),
1707
- default=0,
1708
- )
1709
- tts_parser.add_argument(
1710
- "--pitch",
1711
- type=int,
1712
- help=pitch_description,
1713
- choices=range(-24, 25),
1714
- default=0,
1715
- )
1716
- tts_parser.add_argument(
1717
- "--filter_radius",
1718
- type=int,
1719
- help=filter_radius_description,
1720
- choices=range(11),
1721
- default=3,
1722
- )
1723
- tts_parser.add_argument(
1724
- "--index_rate",
1725
- type=float,
1726
- help=index_rate_description,
1727
- choices=[(i / 10) for i in range(11)],
1728
- default=0.3,
1729
- )
1730
- tts_parser.add_argument(
1731
- "--volume_envelope",
1732
- type=float,
1733
- help=volume_envelope_description,
1734
- choices=[(i / 10) for i in range(11)],
1735
- default=1,
1736
- )
1737
- tts_parser.add_argument(
1738
- "--protect",
1739
- type=float,
1740
- help=protect_description,
1741
- choices=[(i / 10) for i in range(6)],
1742
- default=0.33,
1743
- )
1744
- tts_parser.add_argument(
1745
- "--hop_length",
1746
- type=int,
1747
- help=hop_length_description,
1748
- choices=range(1, 513),
1749
- default=128,
1750
- )
1751
- tts_parser.add_argument(
1752
- "--f0_method",
1753
- type=str,
1754
- help=f0_method_description,
1755
- choices=[
1756
- "crepe",
1757
- "crepe-tiny",
1758
- "rmvpe",
1759
- "fcpe",
1760
- "hybrid[crepe+rmvpe]",
1761
- "hybrid[crepe+fcpe]",
1762
- "hybrid[rmvpe+fcpe]",
1763
- "hybrid[crepe+rmvpe+fcpe]",
1764
- ],
1765
- default="rmvpe",
1766
- )
1767
- tts_parser.add_argument(
1768
- "--output_tts_path",
1769
- type=str,
1770
- help="Full path to save the synthesized TTS audio.",
1771
- required=True,
1772
- )
1773
- tts_parser.add_argument(
1774
- "--output_rvc_path",
1775
- type=str,
1776
- help="Full path to save the voice-converted audio using the synthesized TTS.",
1777
- required=True,
1778
- )
1779
- tts_parser.add_argument(
1780
- "--pth_path", type=str, help=pth_path_description, required=True
1781
- )
1782
- tts_parser.add_argument(
1783
- "--index_path", type=str, help=index_path_description, required=True
1784
- )
1785
- tts_parser.add_argument(
1786
- "--split_audio",
1787
- type=lambda x: bool(strtobool(x)),
1788
- choices=[True, False],
1789
- help=split_audio_description,
1790
- default=False,
1791
- )
1792
- tts_parser.add_argument(
1793
- "--f0_autotune",
1794
- type=lambda x: bool(strtobool(x)),
1795
- choices=[True, False],
1796
- help=f0_autotune_description,
1797
- default=False,
1798
- )
1799
- tts_parser.add_argument(
1800
- "--f0_autotune_strength",
1801
- type=float,
1802
- help=clean_strength_description,
1803
- choices=[(i / 10) for i in range(11)],
1804
- default=1.0,
1805
- )
1806
- tts_parser.add_argument(
1807
- "--clean_audio",
1808
- type=lambda x: bool(strtobool(x)),
1809
- choices=[True, False],
1810
- help=clean_audio_description,
1811
- default=False,
1812
- )
1813
- tts_parser.add_argument(
1814
- "--clean_strength",
1815
- type=float,
1816
- help=clean_strength_description,
1817
- choices=[(i / 10) for i in range(11)],
1818
- default=0.7,
1819
- )
1820
- tts_parser.add_argument(
1821
- "--export_format",
1822
- type=str,
1823
- help=export_format_description,
1824
- choices=["WAV", "MP3", "FLAC", "OGG", "M4A"],
1825
- default="WAV",
1826
- )
1827
- tts_parser.add_argument(
1828
- "--embedder_model",
1829
- type=str,
1830
- help=embedder_model_description,
1831
- choices=[
1832
- "contentvec",
1833
- "chinese-hubert-base",
1834
- "japanese-hubert-base",
1835
- "korean-hubert-base",
1836
- "custom",
1837
- ],
1838
- default="contentvec",
1839
- )
1840
- tts_parser.add_argument(
1841
- "--embedder_model_custom",
1842
- type=str,
1843
- help=embedder_model_custom_description,
1844
- default=None,
1845
- )
1846
- tts_parser.add_argument(
1847
- "--upscale_audio",
1848
- type=lambda x: bool(strtobool(x)),
1849
- choices=[True, False],
1850
- help=upscale_audio_description,
1851
- default=False,
1852
- )
1853
- tts_parser.add_argument(
1854
- "--f0_file",
1855
- type=str,
1856
- help=f0_file_description,
1857
- default=None,
1858
- )
1859
-
1860
- # Parser for 'preprocess' mode
1861
- preprocess_parser = subparsers.add_parser(
1862
- "preprocess", help="Preprocess a dataset for training."
1863
- )
1864
- preprocess_parser.add_argument(
1865
- "--model_name", type=str, help="Name of the model to be trained.", required=True
1866
- )
1867
- preprocess_parser.add_argument(
1868
- "--dataset_path", type=str, help="Path to the dataset directory.", required=True
1869
- )
1870
- preprocess_parser.add_argument(
1871
- "--sample_rate",
1872
- type=int,
1873
- help="Target sampling rate for the audio data.",
1874
- choices=[32000, 40000, 48000],
1875
- required=True,
1876
- )
1877
- preprocess_parser.add_argument(
1878
- "--cpu_cores",
1879
- type=int,
1880
- help="Number of CPU cores to use for preprocessing.",
1881
- choices=range(1, 65),
1882
- )
1883
- preprocess_parser.add_argument(
1884
- "--cut_preprocess",
1885
- type=lambda x: bool(strtobool(x)),
1886
- choices=[True, False],
1887
- help="Cut the dataset into smaller segments for faster preprocessing.",
1888
- default=True,
1889
- required=False,
1890
- )
1891
- preprocess_parser.add_argument(
1892
- "--process_effects",
1893
- type=lambda x: bool(strtobool(x)),
1894
- choices=[True, False],
1895
- help="Disable all filters during preprocessing.",
1896
- default=False,
1897
- required=False,
1898
- )
1899
- preprocess_parser.add_argument(
1900
- "--noise_reduction",
1901
- type=lambda x: bool(strtobool(x)),
1902
- choices=[True, False],
1903
- help="Enable noise reduction during preprocessing.",
1904
- default=False,
1905
- required=False,
1906
- )
1907
- preprocess_parser.add_argument(
1908
- "--noise_reduction_strength",
1909
- type=float,
1910
- help="Strength of the noise reduction filter.",
1911
- choices=[(i / 10) for i in range(11)],
1912
- default=0.7,
1913
- required=False,
1914
- )
1915
-
1916
- # Parser for 'extract' mode
1917
- extract_parser = subparsers.add_parser(
1918
- "extract", help="Extract features from a dataset."
1919
- )
1920
- extract_parser.add_argument(
1921
- "--model_name", type=str, help="Name of the model.", required=True
1922
- )
1923
- extract_parser.add_argument(
1924
- "--rvc_version",
1925
- type=str,
1926
- help="Version of the RVC model ('v1' or 'v2').",
1927
- choices=["v1", "v2"],
1928
- default="v2",
1929
- )
1930
- extract_parser.add_argument(
1931
- "--f0_method",
1932
- type=str,
1933
- help="Pitch extraction method to use.",
1934
- choices=[
1935
- "crepe",
1936
- "crepe-tiny",
1937
- "rmvpe",
1938
- ],
1939
- default="rmvpe",
1940
- )
1941
- extract_parser.add_argument(
1942
- "--hop_length",
1943
- type=int,
1944
- help="Hop length for feature extraction. Only applicable for Crepe pitch extraction.",
1945
- choices=range(1, 513),
1946
- default=128,
1947
- )
1948
- extract_parser.add_argument(
1949
- "--cpu_cores",
1950
- type=int,
1951
- help="Number of CPU cores to use for feature extraction (optional).",
1952
- choices=range(1, 65),
1953
- default=None,
1954
- )
1955
- extract_parser.add_argument(
1956
- "--gpu",
1957
- type=int,
1958
- help="GPU device to use for feature extraction (optional).",
1959
- default="-",
1960
- )
1961
- extract_parser.add_argument(
1962
- "--sample_rate",
1963
- type=int,
1964
- help="Target sampling rate for the audio data.",
1965
- choices=[32000, 40000, 48000],
1966
- required=True,
1967
- )
1968
- extract_parser.add_argument(
1969
- "--embedder_model",
1970
- type=str,
1971
- help=embedder_model_description,
1972
- choices=[
1973
- "contentvec",
1974
- "chinese-hubert-base",
1975
- "japanese-hubert-base",
1976
- "korean-hubert-base",
1977
- "custom",
1978
- ],
1979
- default="contentvec",
1980
- )
1981
- extract_parser.add_argument(
1982
- "--embedder_model_custom",
1983
- type=str,
1984
- help=embedder_model_custom_description,
1985
- default=None,
1986
- )
1987
-
1988
- # Parser for 'train' mode
1989
- train_parser = subparsers.add_parser("train", help="Train an RVC model.")
1990
- train_parser.add_argument(
1991
- "--model_name", type=str, help="Name of the model to be trained.", required=True
1992
- )
1993
- train_parser.add_argument(
1994
- "--rvc_version",
1995
- type=str,
1996
- help="Version of the RVC model to train ('v1' or 'v2').",
1997
- choices=["v1", "v2"],
1998
- default="v2",
1999
- )
2000
- train_parser.add_argument(
2001
- "--save_every_epoch",
2002
- type=int,
2003
- help="Save the model every specified number of epochs.",
2004
- choices=range(1, 101),
2005
- required=True,
2006
- )
2007
- train_parser.add_argument(
2008
- "--save_only_latest",
2009
- type=lambda x: bool(strtobool(x)),
2010
- choices=[True, False],
2011
- help="Save only the latest model checkpoint.",
2012
- default=False,
2013
- )
2014
- train_parser.add_argument(
2015
- "--save_every_weights",
2016
- type=lambda x: bool(strtobool(x)),
2017
- choices=[True, False],
2018
- help="Save model weights every epoch.",
2019
- default=True,
2020
- )
2021
- train_parser.add_argument(
2022
- "--total_epoch",
2023
- type=int,
2024
- help="Total number of epochs to train for.",
2025
- choices=range(1, 10001),
2026
- default=1000,
2027
- )
2028
- train_parser.add_argument(
2029
- "--sample_rate",
2030
- type=int,
2031
- help="Sampling rate of the training data.",
2032
- choices=[32000, 40000, 48000],
2033
- required=True,
2034
- )
2035
- train_parser.add_argument(
2036
- "--batch_size",
2037
- type=int,
2038
- help="Batch size for training.",
2039
- choices=range(1, 51),
2040
- default=8,
2041
- )
2042
- train_parser.add_argument(
2043
- "--gpu",
2044
- type=str,
2045
- help="GPU device to use for training (e.g., '0').",
2046
- default="0",
2047
- )
2048
- train_parser.add_argument(
2049
- "--pitch_guidance",
2050
- type=lambda x: bool(strtobool(x)),
2051
- choices=[True, False],
2052
- help="Enable or disable pitch guidance during training.",
2053
- default=True,
2054
- )
2055
- train_parser.add_argument(
2056
- "--pretrained",
2057
- type=lambda x: bool(strtobool(x)),
2058
- choices=[True, False],
2059
- help="Use a pretrained model for initialization.",
2060
- default=True,
2061
- )
2062
- train_parser.add_argument(
2063
- "--custom_pretrained",
2064
- type=lambda x: bool(strtobool(x)),
2065
- choices=[True, False],
2066
- help="Use a custom pretrained model.",
2067
- default=False,
2068
- )
2069
- train_parser.add_argument(
2070
- "--g_pretrained_path",
2071
- type=str,
2072
- nargs="?",
2073
- default=None,
2074
- help="Path to the pretrained generator model file.",
2075
- )
2076
- train_parser.add_argument(
2077
- "--d_pretrained_path",
2078
- type=str,
2079
- nargs="?",
2080
- default=None,
2081
- help="Path to the pretrained discriminator model file.",
2082
- )
2083
- train_parser.add_argument(
2084
- "--overtraining_detector",
2085
- type=lambda x: bool(strtobool(x)),
2086
- choices=[True, False],
2087
- help="Enable overtraining detection.",
2088
- default=False,
2089
- )
2090
- train_parser.add_argument(
2091
- "--overtraining_threshold",
2092
- type=int,
2093
- help="Threshold for overtraining detection.",
2094
- choices=range(1, 101),
2095
- default=50,
2096
- )
2097
- train_parser.add_argument(
2098
- "--cleanup",
2099
- type=lambda x: bool(strtobool(x)),
2100
- choices=[True, False],
2101
- help="Cleanup previous training attempt.",
2102
- default=False,
2103
- )
2104
- train_parser.add_argument(
2105
- "--cache_data_in_gpu",
2106
- type=lambda x: bool(strtobool(x)),
2107
- choices=[True, False],
2108
- help="Cache training data in GPU memory.",
2109
- default=False,
2110
- )
2111
- train_parser.add_argument(
2112
- "--index_algorithm",
2113
- type=str,
2114
- choices=["Auto", "Faiss", "KMeans"],
2115
- help="Choose the method for generating the index file.",
2116
- default="Auto",
2117
- required=False,
2118
- )
2119
-
2120
- # Parser for 'index' mode
2121
- index_parser = subparsers.add_parser(
2122
- "index", help="Generate an index file for an RVC model."
2123
- )
2124
- index_parser.add_argument(
2125
- "--model_name", type=str, help="Name of the model.", required=True
2126
- )
2127
- index_parser.add_argument(
2128
- "--rvc_version",
2129
- type=str,
2130
- help="Version of the RVC model ('v1' or 'v2').",
2131
- choices=["v1", "v2"],
2132
- default="v2",
2133
- )
2134
- index_parser.add_argument(
2135
- "--index_algorithm",
2136
- type=str,
2137
- choices=["Auto", "Faiss", "KMeans"],
2138
- help="Choose the method for generating the index file.",
2139
- default="Auto",
2140
- required=False,
2141
- )
2142
-
2143
- # Parser for 'model_extract' mode
2144
- model_extract_parser = subparsers.add_parser(
2145
- "model_extract", help="Extract a specific epoch from a trained model."
2146
- )
2147
- model_extract_parser.add_argument(
2148
- "--pth_path", type=str, help="Path to the main .pth model file.", required=True
2149
- )
2150
- model_extract_parser.add_argument(
2151
- "--model_name", type=str, help="Name of the model.", required=True
2152
- )
2153
- model_extract_parser.add_argument(
2154
- "--sample_rate",
2155
- type=int,
2156
- help="Sampling rate of the extracted model.",
2157
- choices=[32000, 40000, 48000],
2158
- required=True,
2159
- )
2160
- model_extract_parser.add_argument(
2161
- "--pitch_guidance",
2162
- type=lambda x: bool(strtobool(x)),
2163
- choices=[True, False],
2164
- help="Enable or disable pitch guidance for the extracted model.",
2165
- required=True,
2166
- )
2167
- model_extract_parser.add_argument(
2168
- "--rvc_version",
2169
- type=str,
2170
- help="Version of the extracted RVC model ('v1' or 'v2').",
2171
- choices=["v1", "v2"],
2172
- default="v2",
2173
- )
2174
- model_extract_parser.add_argument(
2175
- "--epoch",
2176
- type=int,
2177
- help="Epoch number to extract from the model.",
2178
- choices=range(1, 10001),
2179
- required=True,
2180
- )
2181
- model_extract_parser.add_argument(
2182
- "--step",
2183
- type=str,
2184
- help="Step number to extract from the model (optional).",
2185
- required=False,
2186
- )
2187
-
2188
- # Parser for 'model_information' mode
2189
- model_information_parser = subparsers.add_parser(
2190
- "model_information", help="Display information about a trained model."
2191
- )
2192
- model_information_parser.add_argument(
2193
- "--pth_path", type=str, help="Path to the .pth model file.", required=True
2194
- )
2195
-
2196
- # Parser for 'model_blender' mode
2197
- model_blender_parser = subparsers.add_parser(
2198
- "model_blender", help="Fuse two RVC models together."
2199
- )
2200
- model_blender_parser.add_argument(
2201
- "--model_name", type=str, help="Name of the new fused model.", required=True
2202
- )
2203
- model_blender_parser.add_argument(
2204
- "--pth_path_1",
2205
- type=str,
2206
- help="Path to the first .pth model file.",
2207
- required=True,
2208
- )
2209
- model_blender_parser.add_argument(
2210
- "--pth_path_2",
2211
- type=str,
2212
- help="Path to the second .pth model file.",
2213
- required=True,
2214
- )
2215
- model_blender_parser.add_argument(
2216
- "--ratio",
2217
- type=float,
2218
- help="Ratio for blending the two models (0.0 to 1.0).",
2219
- choices=[(i / 10) for i in range(11)],
2220
- default=0.5,
2221
- )
2222
-
2223
- # Parser for 'tensorboard' mode
2224
- subparsers.add_parser(
2225
- "tensorboard", help="Launch TensorBoard for monitoring training progress."
2226
- )
2227
-
2228
- # Parser for 'download' mode
2229
- download_parser = subparsers.add_parser(
2230
- "download", help="Download a model from a provided link."
2231
- )
2232
- download_parser.add_argument(
2233
- "--model_link", type=str, help="Direct link to the model file.", required=True
2234
- )
2235
-
2236
- # Parser for 'prerequisites' mode
2237
- prerequisites_parser = subparsers.add_parser(
2238
- "prerequisites", help="Install prerequisites for RVC."
2239
- )
2240
- prerequisites_parser.add_argument(
2241
- "--pretraineds_v1_f0",
2242
- type=lambda x: bool(strtobool(x)),
2243
- choices=[True, False],
2244
- default=False,
2245
- help="Download pretrained models for RVC v1.",
2246
- )
2247
- prerequisites_parser.add_argument(
2248
- "--pretraineds_v2_f0",
2249
- type=lambda x: bool(strtobool(x)),
2250
- choices=[True, False],
2251
- default=True,
2252
- help="Download pretrained models for RVC v2.",
2253
- )
2254
- prerequisites_parser.add_argument(
2255
- "--pretraineds_v1_nof0",
2256
- type=lambda x: bool(strtobool(x)),
2257
- choices=[True, False],
2258
- default=False,
2259
- help="Download non f0 pretrained models for RVC v1.",
2260
- )
2261
- prerequisites_parser.add_argument(
2262
- "--pretraineds_v2_nof0",
2263
- type=lambda x: bool(strtobool(x)),
2264
- choices=[True, False],
2265
- default=False,
2266
- help="Download non f0 pretrained models for RVC v2.",
2267
- )
2268
- prerequisites_parser.add_argument(
2269
- "--models",
2270
- type=lambda x: bool(strtobool(x)),
2271
- choices=[True, False],
2272
- default=True,
2273
- help="Download additional models.",
2274
- )
2275
- prerequisites_parser.add_argument(
2276
- "--exe",
2277
- type=lambda x: bool(strtobool(x)),
2278
- choices=[True, False],
2279
- default=True,
2280
- help="Download required executables.",
2281
- )
2282
-
2283
- # Parser for 'audio_analyzer' mode
2284
- audio_analyzer = subparsers.add_parser(
2285
- "audio_analyzer", help="Analyze an audio file."
2286
- )
2287
- audio_analyzer.add_argument(
2288
- "--input_path", type=str, help="Path to the input audio file.", required=True
2289
- )
2290
-
2291
- return parser.parse_args()
2292
-
2293
-
2294
- def main():
2295
- if len(sys.argv) == 1:
2296
- print("Please run the script with '-h' for more information.")
2297
- sys.exit(1)
2298
-
2299
- args = parse_arguments()
2300
-
2301
- try:
2302
- if args.mode == "infer":
2303
- run_infer_script(
2304
- pitch=args.pitch,
2305
- filter_radius=args.filter_radius,
2306
- index_rate=args.index_rate,
2307
- volume_envelope=args.volume_envelope,
2308
- protect=args.protect,
2309
- hop_length=args.hop_length,
2310
- f0_method=args.f0_method,
2311
- input_path=args.input_path,
2312
- output_path=args.output_path,
2313
- pth_path=args.pth_path,
2314
- index_path=args.index_path,
2315
- split_audio=args.split_audio,
2316
- f0_autotune=args.f0_autotune,
2317
- f0_autotune_strength=args.f0_autotune_strength,
2318
- clean_audio=args.clean_audio,
2319
- clean_strength=args.clean_strength,
2320
- export_format=args.export_format,
2321
- embedder_model=args.embedder_model,
2322
- embedder_model_custom=args.embedder_model_custom,
2323
- upscale_audio=args.upscale_audio,
2324
- f0_file=args.f0_file,
2325
- formant_shifting=args.formant_shifting,
2326
- formant_qfrency=args.formant_qfrency,
2327
- formant_timbre=args.formant_timbre,
2328
- sid=args.sid,
2329
- post_process=args.post_process,
2330
- reverb=args.reverb,
2331
- pitch_shift=args.pitch_shift,
2332
- limiter=args.limiter,
2333
- gain=args.gain,
2334
- distortion=args.distortion,
2335
- chorus=args.chorus,
2336
- bitcrush=args.bitcrush,
2337
- clipping=args.clipping,
2338
- compressor=args.compressor,
2339
- delay=args.delay,
2340
- reverb_room_size=args.reverb_room_size,
2341
- reverb_damping=args.reverb_damping,
2342
- reverb_wet_gain=args.reverb_wet_gain,
2343
- reverb_dry_gain=args.reverb_dry_gain,
2344
- reverb_width=args.reverb_width,
2345
- reverb_freeze_mode=args.reverb_freeze_mode,
2346
- pitch_shift_semitones=args.pitch_shift_semitones,
2347
- limiter_threshold=args.limiter_threshold,
2348
- limiter_release_time=args.limiter_release_time,
2349
- gain_db=args.gain_db,
2350
- distortion_gain=args.distortion_gain,
2351
- chorus_rate=args.chorus_rate,
2352
- chorus_depth=args.chorus_depth,
2353
- chorus_center_delay=args.chorus_center_delay,
2354
- chorus_feedback=args.chorus_feedback,
2355
- chorus_mix=args.chorus_mix,
2356
- bitcrush_bit_depth=args.bitcrush_bit_depth,
2357
- clipping_threshold=args.clipping_threshold,
2358
- compressor_threshold=args.compressor_threshold,
2359
- compressor_ratio=args.compressor_ratio,
2360
- compressor_attack=args.compressor_attack,
2361
- compressor_release=args.compressor_release,
2362
- delay_seconds=args.delay_seconds,
2363
- delay_feedback=args.delay_feedback,
2364
- delay_mix=args.delay_mix,
2365
- )
2366
- elif args.mode == "batch_infer":
2367
- run_batch_infer_script(
2368
- pitch=args.pitch,
2369
- filter_radius=args.filter_radius,
2370
- index_rate=args.index_rate,
2371
- volume_envelope=args.volume_envelope,
2372
- protect=args.protect,
2373
- hop_length=args.hop_length,
2374
- f0_method=args.f0_method,
2375
- input_folder=args.input_folder,
2376
- output_folder=args.output_folder,
2377
- pth_path=args.pth_path,
2378
- index_path=args.index_path,
2379
- split_audio=args.split_audio,
2380
- f0_autotune=args.f0_autotune,
2381
- f0_autotune_strength=args.f0_autotune_strength,
2382
- clean_audio=args.clean_audio,
2383
- clean_strength=args.clean_strength,
2384
- export_format=args.export_format,
2385
- embedder_model=args.embedder_model,
2386
- embedder_model_custom=args.embedder_model_custom,
2387
- upscale_audio=args.upscale_audio,
2388
- f0_file=args.f0_file,
2389
- formant_shifting=args.formant_shifting,
2390
- formant_qfrency=args.formant_qfrency,
2391
- formant_timbre=args.formant_timbre,
2392
- sid=args.sid,
2393
- post_process=args.post_process,
2394
- reverb=args.reverb,
2395
- pitch_shift=args.pitch_shift,
2396
- limiter=args.limiter,
2397
- gain=args.gain,
2398
- distortion=args.distortion,
2399
- chorus=args.chorus,
2400
- bitcrush=args.bitcrush,
2401
- clipping=args.clipping,
2402
- compressor=args.compressor,
2403
- delay=args.delay,
2404
- reverb_room_size=args.reverb_room_size,
2405
- reverb_damping=args.reverb_damping,
2406
- reverb_wet_gain=args.reverb_wet_gain,
2407
- reverb_dry_gain=args.reverb_dry_gain,
2408
- reverb_width=args.reverb_width,
2409
- reverb_freeze_mode=args.reverb_freeze_mode,
2410
- pitch_shift_semitones=args.pitch_shift_semitones,
2411
- limiter_threshold=args.limiter_threshold,
2412
- limiter_release_time=args.limiter_release_time,
2413
- gain_db=args.gain_db,
2414
- distortion_gain=args.distortion_gain,
2415
- chorus_rate=args.chorus_rate,
2416
- chorus_depth=args.chorus_depth,
2417
- chorus_center_delay=args.chorus_center_delay,
2418
- chorus_feedback=args.chorus_feedback,
2419
- chorus_mix=args.chorus_mix,
2420
- bitcrush_bit_depth=args.bitcrush_bit_depth,
2421
- clipping_threshold=args.clipping_threshold,
2422
- compressor_threshold=args.compressor_threshold,
2423
- compressor_ratio=args.compressor_ratio,
2424
- compressor_attack=args.compressor_attack,
2425
- compressor_release=args.compressor_release,
2426
- delay_seconds=args.delay_seconds,
2427
- delay_feedback=args.delay_feedback,
2428
- delay_mix=args.delay_mix,
2429
- )
2430
- elif args.mode == "tts":
2431
- run_tts_script(
2432
- tts_file=args.tts_file,
2433
- tts_text=args.tts_text,
2434
- tts_voice=args.tts_voice,
2435
- tts_rate=args.tts_rate,
2436
- pitch=args.pitch,
2437
- filter_radius=args.filter_radius,
2438
- index_rate=args.index_rate,
2439
- volume_envelope=args.volume_envelope,
2440
- protect=args.protect,
2441
- hop_length=args.hop_length,
2442
- f0_method=args.f0_method,
2443
- output_rvc_path=args.output_rvc_path,
2444
- output_tts_path=args.output_tts_path,
2445
- pth_path=args.pth_path,
2446
- index_path=args.index_path,
2447
- split_audio=args.split_audio,
2448
- f0_autotune=args.f0_autotune,
2449
- f0_autotune_strength=args.f0_autotune_strength,
2450
- clean_audio=args.clean_audio,
2451
- clean_strength=args.clean_strength,
2452
- export_format=args.export_format,
2453
- embedder_model=args.embedder_model,
2454
- embedder_model_custom=args.embedder_model_custom,
2455
- upscale_audio=args.upscale_audio,
2456
- f0_file=args.f0_file,
2457
- )
2458
- elif args.mode == "preprocess":
2459
- run_preprocess_script(
2460
- model_name=args.model_name,
2461
- dataset_path=args.dataset_path,
2462
- sample_rate=args.sample_rate,
2463
- cpu_cores=args.cpu_cores,
2464
- cut_preprocess=args.cut_preprocess,
2465
- process_effects=args.process_effects,
2466
- noise_reduction=args.noise_reduction,
2467
- clean_strength=args.noise_reduction_strength,
2468
- )
2469
- elif args.mode == "extract":
2470
- run_extract_script(
2471
- model_name=args.model_name,
2472
- rvc_version=args.rvc_version,
2473
- f0_method=args.f0_method,
2474
- hop_length=args.hop_length,
2475
- cpu_cores=args.cpu_cores,
2476
- gpu=args.gpu,
2477
- sample_rate=args.sample_rate,
2478
- embedder_model=args.embedder_model,
2479
- embedder_model_custom=args.embedder_model_custom,
2480
- )
2481
- elif args.mode == "train":
2482
- run_train_script(
2483
- model_name=args.model_name,
2484
- rvc_version=args.rvc_version,
2485
- save_every_epoch=args.save_every_epoch,
2486
- save_only_latest=args.save_only_latest,
2487
- save_every_weights=args.save_every_weights,
2488
- total_epoch=args.total_epoch,
2489
- sample_rate=args.sample_rate,
2490
- batch_size=args.batch_size,
2491
- gpu=args.gpu,
2492
- pitch_guidance=args.pitch_guidance,
2493
- overtraining_detector=args.overtraining_detector,
2494
- overtraining_threshold=args.overtraining_threshold,
2495
- pretrained=args.pretrained,
2496
- custom_pretrained=args.custom_pretrained,
2497
- cleanup=args.cleanup,
2498
- index_algorithm=args.index_algorithm,
2499
- cache_data_in_gpu=args.cache_data_in_gpu,
2500
- g_pretrained_path=args.g_pretrained_path,
2501
- d_pretrained_path=args.d_pretrained_path,
2502
- )
2503
- elif args.mode == "index":
2504
- run_index_script(
2505
- model_name=args.model_name,
2506
- rvc_version=args.rvc_version,
2507
- index_algorithm=args.index_algorithm,
2508
- )
2509
- elif args.mode == "model_extract":
2510
- run_model_extract_script(
2511
- pth_path=args.pth_path,
2512
- model_name=args.model_name,
2513
- sample_rate=args.sample_rate,
2514
- pitch_guidance=args.pitch_guidance,
2515
- rvc_version=args.rvc_version,
2516
- epoch=args.epoch,
2517
- step=args.step,
2518
- )
2519
- elif args.mode == "model_information":
2520
- run_model_information_script(
2521
- pth_path=args.pth_path,
2522
- )
2523
- elif args.mode == "model_blender":
2524
- run_model_blender_script(
2525
- model_name=args.model_name,
2526
- pth_path_1=args.pth_path_1,
2527
- pth_path_2=args.pth_path_2,
2528
- ratio=args.ratio,
2529
- )
2530
- elif args.mode == "tensorboard":
2531
- run_tensorboard_script()
2532
- elif args.mode == "download":
2533
- run_download_script(
2534
- model_link=args.model_link,
2535
- )
2536
- elif args.mode == "prerequisites":
2537
- run_prerequisites_script(
2538
- pretraineds_v1_f0=args.pretraineds_v1_f0,
2539
- pretraineds_v1_nof0=args.pretraineds_v1_nof0,
2540
- pretraineds_v2_f0=args.pretraineds_v2_f0,
2541
- pretraineds_v2_nof0=args.pretraineds_v2_nof0,
2542
- models=args.models,
2543
- exe=args.exe,
2544
- )
2545
- elif args.mode == "audio_analyzer":
2546
- run_audio_analyzer_script(
2547
- input_path=args.input_path,
2548
- )
2549
- except Exception as error:
2550
- print(f"An error occurred during execution: {error}")
2551
-
2552
- import traceback
2553
-
2554
- traceback.print_exc()
2555
-
2556
-
2557
- if __name__ == "__main__":
2558
- main()
 
1
  import os
 
 
 
2
  import subprocess
3
+ import sys
4
  from functools import lru_cache
 
 
 
 
5
 
 
 
 
 
 
 
 
 
 
6
  from rvc.lib.tools.model_download import model_download_pipeline
7
+ from rvc.lib.tools.prerequisites_download import prequisites_download_pipeline
8
+ from tts_service.utils import cache_path
9
+ from tts_service.voices import voice_manager
10
 
11
  python = sys.executable
12
 
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  @lru_cache(maxsize=None)
15
  def import_voice_converter():
16
  from rvc.infer.infer import VoiceConverter
 
18
  return VoiceConverter()
19
 
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  # TTS
22
  def run_tts_script(
 
23
  tts_text: str,
24
+ voice_name: str,
25
  tts_rate: int,
26
+ ) -> tuple[str, str]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  tts_script_path = os.path.join("rvc", "lib", "tools", "tts.py")
28
 
29
+ voice = voice_manager.voices[voice_name]
30
+ format = "wav"
31
+
32
+ output_tts_path = cache_path(voice.tts, tts_text, extension=format)
33
+ if not os.path.exists(output_tts_path):
34
+ command_tts = [
35
+ *map(
36
+ str,
37
+ [
38
+ python,
39
+ tts_script_path,
40
+ "", # tts_file
41
+ tts_text,
42
+ voice.tts,
43
+ tts_rate,
44
+ output_tts_path,
45
+ ],
46
+ ),
47
+ ]
48
+ subprocess.run(command_tts)
49
+
50
+ output_rvc_path = cache_path(voice.tts, voice.name, tts_text, extension=format)
51
+ if not os.path.exists(output_rvc_path):
52
+ infer_pipeline = import_voice_converter()
53
+ infer_pipeline.convert_audio(
54
+ pitch=voice.pitch,
55
+ filter_radius=voice.filter_radius,
56
+ index_rate=voice.index_rate,
57
+ volume_envelope=voice.rms_mix_rate,
58
+ protect=voice.protect,
59
+ hop_length=voice.hop_length,
60
+ f0_method=voice.f0_method,
61
+ audio_input_path=str(output_tts_path),
62
+ audio_output_path=str(output_rvc_path),
63
+ model_path=voice.model,
64
+ index_path=voice.index,
65
+ split_audio=False,
66
+ f0_autotune=voice.autotune is not None,
67
+ f0_autotune_strength=voice.autotune,
68
+ clean_audio=voice.clean is not None,
69
+ clean_strength=voice.clean,
70
+ export_format=format.upper(),
71
+ upscale_audio=voice.upscale,
72
+ f0_file=None,
73
+ embedder_model=voice.embedder_model,
74
+ embedder_model_custom=None,
75
+ sid=0,
76
+ formant_shifting=None,
77
+ formant_qfrency=None,
78
+ formant_timbre=None,
79
+ post_process=None,
80
+ reverb=None,
81
+ pitch_shift=None,
82
+ limiter=None,
83
+ gain=None,
84
+ distortion=None,
85
+ chorus=None,
86
+ bitcrush=None,
87
+ clipping=None,
88
+ compressor=None,
89
+ delay=None,
90
+ sliders=None,
91
+ )
92
+
93
+ return "Text synthesized successfully.", str(output_rvc_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
 
96
  # Download
97
  def run_download_script(model_link: str):
98
  model_download_pipeline(model_link)
99
+ return "Model downloaded successfully."
100
 
101
 
102
  # Prerequisites
 
106
  pretraineds_v2_f0: bool,
107
  pretraineds_v2_nof0: bool,
108
  models: bool,
109
+ voices: bool,
110
  ):
111
  prequisites_download_pipeline(
112
  pretraineds_v1_f0,
 
114
  pretraineds_v2_f0,
115
  pretraineds_v2_nof0,
116
  models,
117
+ voices,
118
  )
119
  return "Prerequisites installed successfully."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
poetry.lock CHANGED
@@ -316,6 +316,479 @@ files = [
316
  {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"},
317
  ]
318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  [[package]]
320
  name = "certifi"
321
  version = "2023.7.22"
@@ -1715,6 +2188,17 @@ MarkupSafe = ">=2.0"
1715
  [package.extras]
1716
  i18n = ["Babel (>=2.7)"]
1717
 
 
 
 
 
 
 
 
 
 
 
 
1718
  [[package]]
1719
  name = "joblib"
1720
  version = "1.4.2"
@@ -3810,6 +4294,20 @@ files = [
3810
  [package.dependencies]
3811
  six = ">=1.5"
3812
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3813
  [[package]]
3814
  name = "python-multipart"
3815
  version = "0.0.17"
@@ -4382,6 +4880,23 @@ files = [
4382
  {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"},
4383
  ]
4384
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4385
  [[package]]
4386
  name = "safetensors"
4387
  version = "0.4.5"
@@ -5358,6 +5873,17 @@ rich = ">=10.11.0"
5358
  shellingham = ">=1.3.0"
5359
  typing-extensions = ">=3.7.4.3"
5360
 
 
 
 
 
 
 
 
 
 
 
 
5361
  [[package]]
5362
  name = "types-beautifulsoup4"
5363
  version = "4.12.0.20241020"
@@ -5372,6 +5898,20 @@ files = [
5372
  [package.dependencies]
5373
  types-html5lib = "*"
5374
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5375
  [[package]]
5376
  name = "types-html5lib"
5377
  version = "1.1.11.20241018"
@@ -5420,30 +5960,27 @@ files = [
5420
  urllib3 = ">=2"
5421
 
5422
  [[package]]
5423
- name = "types-six"
5424
- version = "1.16.21.20241105"
5425
- description = "Typing stubs for six"
5426
  optional = false
5427
  python-versions = ">=3.8"
5428
  files = [
5429
- {file = "types-six-1.16.21.20241105.tar.gz", hash = "sha256:ce3534c38079ec3242f4a20376283eb265a3837f80592b0ecacb14bd41acc29e"},
5430
- {file = "types_six-1.16.21.20241105-py3-none-any.whl", hash = "sha256:8b4b29e5c8fe7f1131be8f3cb7cedbcd8bb889707336f32c3fb332c9b1c71991"},
5431
  ]
5432
 
5433
  [[package]]
5434
- name = "types-tqdm"
5435
- version = "4.67.0.20241119"
5436
- description = "Typing stubs for tqdm"
5437
  optional = false
5438
  python-versions = ">=3.8"
5439
  files = [
5440
- {file = "types-tqdm-4.67.0.20241119.tar.gz", hash = "sha256:1769e0e94d5e6d8fa814965f9cf3d9928376dd15dabcbcb784bb8769081092b4"},
5441
- {file = "types_tqdm-4.67.0.20241119-py3-none-any.whl", hash = "sha256:a18d4eb62db0d35c52707ae13d821b5a57970755273ecb56e133ccc0ac7e7c79"},
5442
  ]
5443
 
5444
- [package.dependencies]
5445
- types-requests = "*"
5446
-
5447
  [[package]]
5448
  name = "typing-extensions"
5449
  version = "4.12.2"
@@ -5579,6 +6116,20 @@ platformdirs = ">=3.9.1,<5"
5579
  docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
5580
  test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
5581
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5582
  [[package]]
5583
  name = "wcwidth"
5584
  version = "0.2.13"
@@ -5797,4 +6348,4 @@ propcache = ">=0.2.0"
5797
  [metadata]
5798
  lock-version = "2.0"
5799
  python-versions = "~3.10"
5800
- content-hash = "1efb5efb494c33cb4fcc0cae070f9afd155b114529b98360ea2277dea26aafac"
 
316
  {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"},
317
  ]
318
 
319
+ [[package]]
320
+ name = "boto3"
321
+ version = "1.35.70"
322
+ description = "The AWS SDK for Python"
323
+ optional = false
324
+ python-versions = ">=3.8"
325
+ files = [
326
+ {file = "boto3-1.35.70-py3-none-any.whl", hash = "sha256:ca385708f83f01b3f27d9d675880d2458cb3b40ed1e25da688f551454ed0c112"},
327
+ {file = "boto3-1.35.70.tar.gz", hash = "sha256:121dce8c7102eea6a6047d46bcd74e8a24dac793a4a3857de4f4bad9c12566fd"},
328
+ ]
329
+
330
+ [package.dependencies]
331
+ botocore = ">=1.35.70,<1.36.0"
332
+ jmespath = ">=0.7.1,<2.0.0"
333
+ s3transfer = ">=0.10.0,<0.11.0"
334
+
335
+ [package.extras]
336
+ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
337
+
338
+ [[package]]
339
+ name = "boto3-stubs"
340
+ version = "1.35.70"
341
+ description = "Type annotations for boto3 1.35.70 generated with mypy-boto3-builder 8.3.1"
342
+ optional = false
343
+ python-versions = ">=3.8"
344
+ files = [
345
+ {file = "boto3_stubs-1.35.70-py3-none-any.whl", hash = "sha256:509d720396e839bf1bbe5a8786beba5b8360f79ab0faeb1ee4a3def224400ffc"},
346
+ {file = "boto3_stubs-1.35.70.tar.gz", hash = "sha256:920040a940accfdb5fbc7703128c0997fa5e23701f641c9ef0b43a5266f6c110"},
347
+ ]
348
+
349
+ [package.dependencies]
350
+ botocore-stubs = "*"
351
+ types-s3transfer = "*"
352
+ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""}
353
+
354
+ [package.extras]
355
+ accessanalyzer = ["mypy-boto3-accessanalyzer (>=1.35.0,<1.36.0)"]
356
+ account = ["mypy-boto3-account (>=1.35.0,<1.36.0)"]
357
+ acm = ["mypy-boto3-acm (>=1.35.0,<1.36.0)"]
358
+ acm-pca = ["mypy-boto3-acm-pca (>=1.35.0,<1.36.0)"]
359
+ all = ["mypy-boto3-accessanalyzer (>=1.35.0,<1.36.0)", "mypy-boto3-account (>=1.35.0,<1.36.0)", "mypy-boto3-acm (>=1.35.0,<1.36.0)", "mypy-boto3-acm-pca (>=1.35.0,<1.36.0)", "mypy-boto3-amp (>=1.35.0,<1.36.0)", "mypy-boto3-amplify (>=1.35.0,<1.36.0)", "mypy-boto3-amplifybackend (>=1.35.0,<1.36.0)", "mypy-boto3-amplifyuibuilder (>=1.35.0,<1.36.0)", "mypy-boto3-apigateway (>=1.35.0,<1.36.0)", "mypy-boto3-apigatewaymanagementapi (>=1.35.0,<1.36.0)", "mypy-boto3-apigatewayv2 (>=1.35.0,<1.36.0)", "mypy-boto3-appconfig (>=1.35.0,<1.36.0)", "mypy-boto3-appconfigdata (>=1.35.0,<1.36.0)", "mypy-boto3-appfabric (>=1.35.0,<1.36.0)", "mypy-boto3-appflow (>=1.35.0,<1.36.0)", "mypy-boto3-appintegrations (>=1.35.0,<1.36.0)", "mypy-boto3-application-autoscaling (>=1.35.0,<1.36.0)", "mypy-boto3-application-insights (>=1.35.0,<1.36.0)", "mypy-boto3-application-signals (>=1.35.0,<1.36.0)", "mypy-boto3-applicationcostprofiler (>=1.35.0,<1.36.0)", "mypy-boto3-appmesh (>=1.35.0,<1.36.0)", "mypy-boto3-apprunner (>=1.35.0,<1.36.0)", "mypy-boto3-appstream (>=1.35.0,<1.36.0)", "mypy-boto3-appsync (>=1.35.0,<1.36.0)", "mypy-boto3-apptest (>=1.35.0,<1.36.0)", "mypy-boto3-arc-zonal-shift (>=1.35.0,<1.36.0)", "mypy-boto3-artifact (>=1.35.0,<1.36.0)", "mypy-boto3-athena (>=1.35.0,<1.36.0)", "mypy-boto3-auditmanager (>=1.35.0,<1.36.0)", "mypy-boto3-autoscaling (>=1.35.0,<1.36.0)", "mypy-boto3-autoscaling-plans (>=1.35.0,<1.36.0)", "mypy-boto3-b2bi (>=1.35.0,<1.36.0)", "mypy-boto3-backup (>=1.35.0,<1.36.0)", "mypy-boto3-backup-gateway (>=1.35.0,<1.36.0)", "mypy-boto3-batch (>=1.35.0,<1.36.0)", "mypy-boto3-bcm-data-exports (>=1.35.0,<1.36.0)", "mypy-boto3-bcm-pricing-calculator (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-agent (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-agent-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-bedrock-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-billing (>=1.35.0,<1.36.0)", "mypy-boto3-billingconductor (>=1.35.0,<1.36.0)", "mypy-boto3-braket (>=1.35.0,<1.36.0)", "mypy-boto3-budgets (>=1.35.0,<1.36.0)", "mypy-boto3-ce (>=1.35.0,<1.36.0)", "mypy-boto3-chatbot (>=1.35.0,<1.36.0)", "mypy-boto3-chime (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-identity (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-media-pipelines (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-meetings (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-messaging (>=1.35.0,<1.36.0)", "mypy-boto3-chime-sdk-voice (>=1.35.0,<1.36.0)", "mypy-boto3-cleanrooms (>=1.35.0,<1.36.0)", "mypy-boto3-cleanroomsml (>=1.35.0,<1.36.0)", "mypy-boto3-cloud9 (>=1.35.0,<1.36.0)", "mypy-boto3-cloudcontrol (>=1.35.0,<1.36.0)", "mypy-boto3-clouddirectory (>=1.35.0,<1.36.0)", "mypy-boto3-cloudformation (>=1.35.0,<1.36.0)", "mypy-boto3-cloudfront (>=1.35.0,<1.36.0)", "mypy-boto3-cloudfront-keyvaluestore (>=1.35.0,<1.36.0)", "mypy-boto3-cloudhsm (>=1.35.0,<1.36.0)", "mypy-boto3-cloudhsmv2 (>=1.35.0,<1.36.0)", "mypy-boto3-cloudsearch (>=1.35.0,<1.36.0)", "mypy-boto3-cloudsearchdomain (>=1.35.0,<1.36.0)", "mypy-boto3-cloudtrail (>=1.35.0,<1.36.0)", "mypy-boto3-cloudtrail-data (>=1.35.0,<1.36.0)", "mypy-boto3-cloudwatch (>=1.35.0,<1.36.0)", "mypy-boto3-codeartifact (>=1.35.0,<1.36.0)", "mypy-boto3-codebuild (>=1.35.0,<1.36.0)", "mypy-boto3-codecatalyst (>=1.35.0,<1.36.0)", "mypy-boto3-codecommit (>=1.35.0,<1.36.0)", "mypy-boto3-codeconnections (>=1.35.0,<1.36.0)", "mypy-boto3-codedeploy (>=1.35.0,<1.36.0)", "mypy-boto3-codeguru-reviewer (>=1.35.0,<1.36.0)", "mypy-boto3-codeguru-security (>=1.35.0,<1.36.0)", "mypy-boto3-codeguruprofiler (>=1.35.0,<1.36.0)", "mypy-boto3-codepipeline (>=1.35.0,<1.36.0)", "mypy-boto3-codestar-connections (>=1.35.0,<1.36.0)", "mypy-boto3-codestar-notifications (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-identity (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-idp (>=1.35.0,<1.36.0)", "mypy-boto3-cognito-sync (>=1.35.0,<1.36.0)", "mypy-boto3-comprehend (>=1.35.0,<1.36.0)", "mypy-boto3-comprehendmedical (>=1.35.0,<1.36.0)", "mypy-boto3-compute-optimizer (>=1.35.0,<1.36.0)", "mypy-boto3-config (>=1.35.0,<1.36.0)", "mypy-boto3-connect (>=1.35.0,<1.36.0)", "mypy-boto3-connect-contact-lens (>=1.35.0,<1.36.0)", "mypy-boto3-connectcampaigns (>=1.35.0,<1.36.0)", "mypy-boto3-connectcampaignsv2 (>=1.35.0,<1.36.0)", "mypy-boto3-connectcases (>=1.35.0,<1.36.0)", "mypy-boto3-connectparticipant (>=1.35.0,<1.36.0)", "mypy-boto3-controlcatalog (>=1.35.0,<1.36.0)", "mypy-boto3-controltower (>=1.35.0,<1.36.0)", "mypy-boto3-cost-optimization-hub (>=1.35.0,<1.36.0)", "mypy-boto3-cur (>=1.35.0,<1.36.0)", "mypy-boto3-customer-profiles (>=1.35.0,<1.36.0)", "mypy-boto3-databrew (>=1.35.0,<1.36.0)", "mypy-boto3-dataexchange (>=1.35.0,<1.36.0)", "mypy-boto3-datapipeline (>=1.35.0,<1.36.0)", "mypy-boto3-datasync (>=1.35.0,<1.36.0)", "mypy-boto3-datazone (>=1.35.0,<1.36.0)", "mypy-boto3-dax (>=1.35.0,<1.36.0)", "mypy-boto3-deadline (>=1.35.0,<1.36.0)", "mypy-boto3-detective (>=1.35.0,<1.36.0)", "mypy-boto3-devicefarm (>=1.35.0,<1.36.0)", "mypy-boto3-devops-guru (>=1.35.0,<1.36.0)", "mypy-boto3-directconnect (>=1.35.0,<1.36.0)", "mypy-boto3-discovery (>=1.35.0,<1.36.0)", "mypy-boto3-dlm (>=1.35.0,<1.36.0)", "mypy-boto3-dms (>=1.35.0,<1.36.0)", "mypy-boto3-docdb (>=1.35.0,<1.36.0)", "mypy-boto3-docdb-elastic (>=1.35.0,<1.36.0)", "mypy-boto3-drs (>=1.35.0,<1.36.0)", "mypy-boto3-ds (>=1.35.0,<1.36.0)", "mypy-boto3-ds-data (>=1.35.0,<1.36.0)", "mypy-boto3-dynamodb (>=1.35.0,<1.36.0)", "mypy-boto3-dynamodbstreams (>=1.35.0,<1.36.0)", "mypy-boto3-ebs (>=1.35.0,<1.36.0)", "mypy-boto3-ec2 (>=1.35.0,<1.36.0)", "mypy-boto3-ec2-instance-connect (>=1.35.0,<1.36.0)", "mypy-boto3-ecr (>=1.35.0,<1.36.0)", "mypy-boto3-ecr-public (>=1.35.0,<1.36.0)", "mypy-boto3-ecs (>=1.35.0,<1.36.0)", "mypy-boto3-efs (>=1.35.0,<1.36.0)", "mypy-boto3-eks (>=1.35.0,<1.36.0)", "mypy-boto3-eks-auth (>=1.35.0,<1.36.0)", "mypy-boto3-elastic-inference (>=1.35.0,<1.36.0)", "mypy-boto3-elasticache (>=1.35.0,<1.36.0)", "mypy-boto3-elasticbeanstalk (>=1.35.0,<1.36.0)", "mypy-boto3-elastictranscoder (>=1.35.0,<1.36.0)", "mypy-boto3-elb (>=1.35.0,<1.36.0)", "mypy-boto3-elbv2 (>=1.35.0,<1.36.0)", "mypy-boto3-emr (>=1.35.0,<1.36.0)", "mypy-boto3-emr-containers (>=1.35.0,<1.36.0)", "mypy-boto3-emr-serverless (>=1.35.0,<1.36.0)", "mypy-boto3-entityresolution (>=1.35.0,<1.36.0)", "mypy-boto3-es (>=1.35.0,<1.36.0)", "mypy-boto3-events (>=1.35.0,<1.36.0)", "mypy-boto3-evidently (>=1.35.0,<1.36.0)", "mypy-boto3-finspace (>=1.35.0,<1.36.0)", "mypy-boto3-finspace-data (>=1.35.0,<1.36.0)", "mypy-boto3-firehose (>=1.35.0,<1.36.0)", "mypy-boto3-fis (>=1.35.0,<1.36.0)", "mypy-boto3-fms (>=1.35.0,<1.36.0)", "mypy-boto3-forecast (>=1.35.0,<1.36.0)", "mypy-boto3-forecastquery (>=1.35.0,<1.36.0)", "mypy-boto3-frauddetector (>=1.35.0,<1.36.0)", "mypy-boto3-freetier (>=1.35.0,<1.36.0)", "mypy-boto3-fsx (>=1.35.0,<1.36.0)", "mypy-boto3-gamelift (>=1.35.0,<1.36.0)", "mypy-boto3-geo-maps (>=1.35.0,<1.36.0)", "mypy-boto3-geo-places (>=1.35.0,<1.36.0)", "mypy-boto3-geo-routes (>=1.35.0,<1.36.0)", "mypy-boto3-glacier (>=1.35.0,<1.36.0)", "mypy-boto3-globalaccelerator (>=1.35.0,<1.36.0)", "mypy-boto3-glue (>=1.35.0,<1.36.0)", "mypy-boto3-grafana (>=1.35.0,<1.36.0)", "mypy-boto3-greengrass (>=1.35.0,<1.36.0)", "mypy-boto3-greengrassv2 (>=1.35.0,<1.36.0)", "mypy-boto3-groundstation (>=1.35.0,<1.36.0)", "mypy-boto3-guardduty (>=1.35.0,<1.36.0)", "mypy-boto3-health (>=1.35.0,<1.36.0)", "mypy-boto3-healthlake (>=1.35.0,<1.36.0)", "mypy-boto3-iam (>=1.35.0,<1.36.0)", "mypy-boto3-identitystore (>=1.35.0,<1.36.0)", "mypy-boto3-imagebuilder (>=1.35.0,<1.36.0)", "mypy-boto3-importexport (>=1.35.0,<1.36.0)", "mypy-boto3-inspector (>=1.35.0,<1.36.0)", "mypy-boto3-inspector-scan (>=1.35.0,<1.36.0)", "mypy-boto3-inspector2 (>=1.35.0,<1.36.0)", "mypy-boto3-internetmonitor (>=1.35.0,<1.36.0)", "mypy-boto3-iot (>=1.35.0,<1.36.0)", "mypy-boto3-iot-data (>=1.35.0,<1.36.0)", "mypy-boto3-iot-jobs-data (>=1.35.0,<1.36.0)", "mypy-boto3-iot1click-devices (>=1.35.0,<1.36.0)", "mypy-boto3-iot1click-projects (>=1.35.0,<1.36.0)", "mypy-boto3-iotanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-iotdeviceadvisor (>=1.35.0,<1.36.0)", "mypy-boto3-iotevents (>=1.35.0,<1.36.0)", "mypy-boto3-iotevents-data (>=1.35.0,<1.36.0)", "mypy-boto3-iotfleethub (>=1.35.0,<1.36.0)", "mypy-boto3-iotfleetwise (>=1.35.0,<1.36.0)", "mypy-boto3-iotsecuretunneling (>=1.35.0,<1.36.0)", "mypy-boto3-iotsitewise (>=1.35.0,<1.36.0)", "mypy-boto3-iotthingsgraph (>=1.35.0,<1.36.0)", "mypy-boto3-iottwinmaker (>=1.35.0,<1.36.0)", "mypy-boto3-iotwireless (>=1.35.0,<1.36.0)", "mypy-boto3-ivs (>=1.35.0,<1.36.0)", "mypy-boto3-ivs-realtime (>=1.35.0,<1.36.0)", "mypy-boto3-ivschat (>=1.35.0,<1.36.0)", "mypy-boto3-kafka (>=1.35.0,<1.36.0)", "mypy-boto3-kafkaconnect (>=1.35.0,<1.36.0)", "mypy-boto3-kendra (>=1.35.0,<1.36.0)", "mypy-boto3-kendra-ranking (>=1.35.0,<1.36.0)", "mypy-boto3-keyspaces (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-archived-media (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-media (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-signaling (>=1.35.0,<1.36.0)", "mypy-boto3-kinesis-video-webrtc-storage (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisanalyticsv2 (>=1.35.0,<1.36.0)", "mypy-boto3-kinesisvideo (>=1.35.0,<1.36.0)", "mypy-boto3-kms (>=1.35.0,<1.36.0)", "mypy-boto3-lakeformation (>=1.35.0,<1.36.0)", "mypy-boto3-lambda (>=1.35.0,<1.36.0)", "mypy-boto3-launch-wizard (>=1.35.0,<1.36.0)", "mypy-boto3-lex-models (>=1.35.0,<1.36.0)", "mypy-boto3-lex-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-lexv2-models (>=1.35.0,<1.36.0)", "mypy-boto3-lexv2-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager-linux-subscriptions (>=1.35.0,<1.36.0)", "mypy-boto3-license-manager-user-subscriptions (>=1.35.0,<1.36.0)", "mypy-boto3-lightsail (>=1.35.0,<1.36.0)", "mypy-boto3-location (>=1.35.0,<1.36.0)", "mypy-boto3-logs (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutequipment (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutmetrics (>=1.35.0,<1.36.0)", "mypy-boto3-lookoutvision (>=1.35.0,<1.36.0)", "mypy-boto3-m2 (>=1.35.0,<1.36.0)", "mypy-boto3-machinelearning (>=1.35.0,<1.36.0)", "mypy-boto3-macie2 (>=1.35.0,<1.36.0)", "mypy-boto3-mailmanager (>=1.35.0,<1.36.0)", "mypy-boto3-managedblockchain (>=1.35.0,<1.36.0)", "mypy-boto3-managedblockchain-query (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-agreement (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-catalog (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-deployment (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-entitlement (>=1.35.0,<1.36.0)", "mypy-boto3-marketplace-reporting (>=1.35.0,<1.36.0)", "mypy-boto3-marketplacecommerceanalytics (>=1.35.0,<1.36.0)", "mypy-boto3-mediaconnect (>=1.35.0,<1.36.0)", "mypy-boto3-mediaconvert (>=1.35.0,<1.36.0)", "mypy-boto3-medialive (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackage (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackage-vod (>=1.35.0,<1.36.0)", "mypy-boto3-mediapackagev2 (>=1.35.0,<1.36.0)", "mypy-boto3-mediastore (>=1.35.0,<1.36.0)", "mypy-boto3-mediastore-data (>=1.35.0,<1.36.0)", "mypy-boto3-mediatailor (>=1.35.0,<1.36.0)", "mypy-boto3-medical-imaging (>=1.35.0,<1.36.0)", "mypy-boto3-memorydb (>=1.35.0,<1.36.0)", "mypy-boto3-meteringmarketplace (>=1.35.0,<1.36.0)", "mypy-boto3-mgh (>=1.35.0,<1.36.0)", "mypy-boto3-mgn (>=1.35.0,<1.36.0)", "mypy-boto3-migration-hub-refactor-spaces (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhub-config (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhuborchestrator (>=1.35.0,<1.36.0)", "mypy-boto3-migrationhubstrategy (>=1.35.0,<1.36.0)", "mypy-boto3-mq (>=1.35.0,<1.36.0)", "mypy-boto3-mturk (>=1.35.0,<1.36.0)", "mypy-boto3-mwaa (>=1.35.0,<1.36.0)", "mypy-boto3-neptune (>=1.35.0,<1.36.0)", "mypy-boto3-neptune-graph (>=1.35.0,<1.36.0)", "mypy-boto3-neptunedata (>=1.35.0,<1.36.0)", "mypy-boto3-network-firewall (>=1.35.0,<1.36.0)", "mypy-boto3-networkmanager (>=1.35.0,<1.36.0)", "mypy-boto3-networkmonitor (>=1.35.0,<1.36.0)", "mypy-boto3-notifications (>=1.35.0,<1.36.0)", "mypy-boto3-notificationscontacts (>=1.35.0,<1.36.0)", "mypy-boto3-oam (>=1.35.0,<1.36.0)", "mypy-boto3-omics (>=1.35.0,<1.36.0)", "mypy-boto3-opensearch (>=1.35.0,<1.36.0)", "mypy-boto3-opensearchserverless (>=1.35.0,<1.36.0)", "mypy-boto3-opsworks (>=1.35.0,<1.36.0)", "mypy-boto3-opsworkscm (>=1.35.0,<1.36.0)", "mypy-boto3-organizations (>=1.35.0,<1.36.0)", "mypy-boto3-osis (>=1.35.0,<1.36.0)", "mypy-boto3-outposts (>=1.35.0,<1.36.0)", "mypy-boto3-panorama (>=1.35.0,<1.36.0)", "mypy-boto3-partnercentral-selling (>=1.35.0,<1.36.0)", "mypy-boto3-payment-cryptography (>=1.35.0,<1.36.0)", "mypy-boto3-payment-cryptography-data (>=1.35.0,<1.36.0)", "mypy-boto3-pca-connector-ad (>=1.35.0,<1.36.0)", "mypy-boto3-pca-connector-scep (>=1.35.0,<1.36.0)", "mypy-boto3-pcs (>=1.35.0,<1.36.0)", "mypy-boto3-personalize (>=1.35.0,<1.36.0)", "mypy-boto3-personalize-events (>=1.35.0,<1.36.0)", "mypy-boto3-personalize-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-pi (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-email (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-sms-voice (>=1.35.0,<1.36.0)", "mypy-boto3-pinpoint-sms-voice-v2 (>=1.35.0,<1.36.0)", "mypy-boto3-pipes (>=1.35.0,<1.36.0)", "mypy-boto3-polly (>=1.35.0,<1.36.0)", "mypy-boto3-pricing (>=1.35.0,<1.36.0)", "mypy-boto3-privatenetworks (>=1.35.0,<1.36.0)", "mypy-boto3-proton (>=1.35.0,<1.36.0)", "mypy-boto3-qapps (>=1.35.0,<1.36.0)", "mypy-boto3-qbusiness (>=1.35.0,<1.36.0)", "mypy-boto3-qconnect (>=1.35.0,<1.36.0)", "mypy-boto3-qldb (>=1.35.0,<1.36.0)", "mypy-boto3-qldb-session (>=1.35.0,<1.36.0)", "mypy-boto3-quicksight (>=1.35.0,<1.36.0)", "mypy-boto3-ram (>=1.35.0,<1.36.0)", "mypy-boto3-rbin (>=1.35.0,<1.36.0)", "mypy-boto3-rds (>=1.35.0,<1.36.0)", "mypy-boto3-rds-data (>=1.35.0,<1.36.0)", "mypy-boto3-redshift (>=1.35.0,<1.36.0)", "mypy-boto3-redshift-data (>=1.35.0,<1.36.0)", "mypy-boto3-redshift-serverless (>=1.35.0,<1.36.0)", "mypy-boto3-rekognition (>=1.35.0,<1.36.0)", "mypy-boto3-repostspace (>=1.35.0,<1.36.0)", "mypy-boto3-resiliencehub (>=1.35.0,<1.36.0)", "mypy-boto3-resource-explorer-2 (>=1.35.0,<1.36.0)", "mypy-boto3-resource-groups (>=1.35.0,<1.36.0)", "mypy-boto3-resourcegroupstaggingapi (>=1.35.0,<1.36.0)", "mypy-boto3-robomaker (>=1.35.0,<1.36.0)", "mypy-boto3-rolesanywhere (>=1.35.0,<1.36.0)", "mypy-boto3-route53 (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-cluster (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-control-config (>=1.35.0,<1.36.0)", "mypy-boto3-route53-recovery-readiness (>=1.35.0,<1.36.0)", "mypy-boto3-route53domains (>=1.35.0,<1.36.0)", "mypy-boto3-route53profiles (>=1.35.0,<1.36.0)", "mypy-boto3-route53resolver (>=1.35.0,<1.36.0)", "mypy-boto3-rum (>=1.35.0,<1.36.0)", "mypy-boto3-s3 (>=1.35.0,<1.36.0)", "mypy-boto3-s3control (>=1.35.0,<1.36.0)", "mypy-boto3-s3outposts (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-a2i-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-edge (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-featurestore-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-geospatial (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-metrics (>=1.35.0,<1.36.0)", "mypy-boto3-sagemaker-runtime (>=1.35.0,<1.36.0)", "mypy-boto3-savingsplans (>=1.35.0,<1.36.0)", "mypy-boto3-scheduler (>=1.35.0,<1.36.0)", "mypy-boto3-schemas (>=1.35.0,<1.36.0)", "mypy-boto3-sdb (>=1.35.0,<1.36.0)", "mypy-boto3-secretsmanager (>=1.35.0,<1.36.0)", "mypy-boto3-securityhub (>=1.35.0,<1.36.0)", "mypy-boto3-securitylake (>=1.35.0,<1.36.0)", "mypy-boto3-serverlessrepo (>=1.35.0,<1.36.0)", "mypy-boto3-service-quotas (>=1.35.0,<1.36.0)", "mypy-boto3-servicecatalog (>=1.35.0,<1.36.0)", "mypy-boto3-servicecatalog-appregistry (>=1.35.0,<1.36.0)", "mypy-boto3-servicediscovery (>=1.35.0,<1.36.0)", "mypy-boto3-ses (>=1.35.0,<1.36.0)", "mypy-boto3-sesv2 (>=1.35.0,<1.36.0)", "mypy-boto3-shield (>=1.35.0,<1.36.0)", "mypy-boto3-signer (>=1.35.0,<1.36.0)", "mypy-boto3-simspaceweaver (>=1.35.0,<1.36.0)", "mypy-boto3-sms (>=1.35.0,<1.36.0)", "mypy-boto3-sms-voice (>=1.35.0,<1.36.0)", "mypy-boto3-snow-device-management (>=1.35.0,<1.36.0)", "mypy-boto3-snowball (>=1.35.0,<1.36.0)", "mypy-boto3-sns (>=1.35.0,<1.36.0)", "mypy-boto3-socialmessaging (>=1.35.0,<1.36.0)", "mypy-boto3-sqs (>=1.35.0,<1.36.0)", "mypy-boto3-ssm (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-contacts (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-incidents (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-quicksetup (>=1.35.0,<1.36.0)", "mypy-boto3-ssm-sap (>=1.35.0,<1.36.0)", "mypy-boto3-sso (>=1.35.0,<1.36.0)", "mypy-boto3-sso-admin (>=1.35.0,<1.36.0)", "mypy-boto3-sso-oidc (>=1.35.0,<1.36.0)", "mypy-boto3-stepfunctions (>=1.35.0,<1.36.0)", "mypy-boto3-storagegateway (>=1.35.0,<1.36.0)", "mypy-boto3-sts (>=1.35.0,<1.36.0)", "mypy-boto3-supplychain (>=1.35.0,<1.36.0)", "mypy-boto3-support (>=1.35.0,<1.36.0)", "mypy-boto3-support-app (>=1.35.0,<1.36.0)", "mypy-boto3-swf (>=1.35.0,<1.36.0)", "mypy-boto3-synthetics (>=1.35.0,<1.36.0)", "mypy-boto3-taxsettings (>=1.35.0,<1.36.0)", "mypy-boto3-textract (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-influxdb (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-query (>=1.35.0,<1.36.0)", "mypy-boto3-timestream-write (>=1.35.0,<1.36.0)", "mypy-boto3-tnb (>=1.35.0,<1.36.0)", "mypy-boto3-transcribe (>=1.35.0,<1.36.0)", "mypy-boto3-transfer (>=1.35.0,<1.36.0)", "mypy-boto3-translate (>=1.35.0,<1.36.0)", "mypy-boto3-trustedadvisor (>=1.35.0,<1.36.0)", "mypy-boto3-verifiedpermissions (>=1.35.0,<1.36.0)", "mypy-boto3-voice-id (>=1.35.0,<1.36.0)", "mypy-boto3-vpc-lattice (>=1.35.0,<1.36.0)", "mypy-boto3-waf (>=1.35.0,<1.36.0)", "mypy-boto3-waf-regional (>=1.35.0,<1.36.0)", "mypy-boto3-wafv2 (>=1.35.0,<1.36.0)", "mypy-boto3-wellarchitected (>=1.35.0,<1.36.0)", "mypy-boto3-wisdom (>=1.35.0,<1.36.0)", "mypy-boto3-workdocs (>=1.35.0,<1.36.0)", "mypy-boto3-workmail (>=1.35.0,<1.36.0)", "mypy-boto3-workmailmessageflow (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces-thin-client (>=1.35.0,<1.36.0)", "mypy-boto3-workspaces-web (>=1.35.0,<1.36.0)", "mypy-boto3-xray (>=1.35.0,<1.36.0)"]
360
+ amp = ["mypy-boto3-amp (>=1.35.0,<1.36.0)"]
361
+ amplify = ["mypy-boto3-amplify (>=1.35.0,<1.36.0)"]
362
+ amplifybackend = ["mypy-boto3-amplifybackend (>=1.35.0,<1.36.0)"]
363
+ amplifyuibuilder = ["mypy-boto3-amplifyuibuilder (>=1.35.0,<1.36.0)"]
364
+ apigateway = ["mypy-boto3-apigateway (>=1.35.0,<1.36.0)"]
365
+ apigatewaymanagementapi = ["mypy-boto3-apigatewaymanagementapi (>=1.35.0,<1.36.0)"]
366
+ apigatewayv2 = ["mypy-boto3-apigatewayv2 (>=1.35.0,<1.36.0)"]
367
+ appconfig = ["mypy-boto3-appconfig (>=1.35.0,<1.36.0)"]
368
+ appconfigdata = ["mypy-boto3-appconfigdata (>=1.35.0,<1.36.0)"]
369
+ appfabric = ["mypy-boto3-appfabric (>=1.35.0,<1.36.0)"]
370
+ appflow = ["mypy-boto3-appflow (>=1.35.0,<1.36.0)"]
371
+ appintegrations = ["mypy-boto3-appintegrations (>=1.35.0,<1.36.0)"]
372
+ application-autoscaling = ["mypy-boto3-application-autoscaling (>=1.35.0,<1.36.0)"]
373
+ application-insights = ["mypy-boto3-application-insights (>=1.35.0,<1.36.0)"]
374
+ application-signals = ["mypy-boto3-application-signals (>=1.35.0,<1.36.0)"]
375
+ applicationcostprofiler = ["mypy-boto3-applicationcostprofiler (>=1.35.0,<1.36.0)"]
376
+ appmesh = ["mypy-boto3-appmesh (>=1.35.0,<1.36.0)"]
377
+ apprunner = ["mypy-boto3-apprunner (>=1.35.0,<1.36.0)"]
378
+ appstream = ["mypy-boto3-appstream (>=1.35.0,<1.36.0)"]
379
+ appsync = ["mypy-boto3-appsync (>=1.35.0,<1.36.0)"]
380
+ apptest = ["mypy-boto3-apptest (>=1.35.0,<1.36.0)"]
381
+ arc-zonal-shift = ["mypy-boto3-arc-zonal-shift (>=1.35.0,<1.36.0)"]
382
+ artifact = ["mypy-boto3-artifact (>=1.35.0,<1.36.0)"]
383
+ athena = ["mypy-boto3-athena (>=1.35.0,<1.36.0)"]
384
+ auditmanager = ["mypy-boto3-auditmanager (>=1.35.0,<1.36.0)"]
385
+ autoscaling = ["mypy-boto3-autoscaling (>=1.35.0,<1.36.0)"]
386
+ autoscaling-plans = ["mypy-boto3-autoscaling-plans (>=1.35.0,<1.36.0)"]
387
+ b2bi = ["mypy-boto3-b2bi (>=1.35.0,<1.36.0)"]
388
+ backup = ["mypy-boto3-backup (>=1.35.0,<1.36.0)"]
389
+ backup-gateway = ["mypy-boto3-backup-gateway (>=1.35.0,<1.36.0)"]
390
+ batch = ["mypy-boto3-batch (>=1.35.0,<1.36.0)"]
391
+ bcm-data-exports = ["mypy-boto3-bcm-data-exports (>=1.35.0,<1.36.0)"]
392
+ bcm-pricing-calculator = ["mypy-boto3-bcm-pricing-calculator (>=1.35.0,<1.36.0)"]
393
+ bedrock = ["mypy-boto3-bedrock (>=1.35.0,<1.36.0)"]
394
+ bedrock-agent = ["mypy-boto3-bedrock-agent (>=1.35.0,<1.36.0)"]
395
+ bedrock-agent-runtime = ["mypy-boto3-bedrock-agent-runtime (>=1.35.0,<1.36.0)"]
396
+ bedrock-runtime = ["mypy-boto3-bedrock-runtime (>=1.35.0,<1.36.0)"]
397
+ billing = ["mypy-boto3-billing (>=1.35.0,<1.36.0)"]
398
+ billingconductor = ["mypy-boto3-billingconductor (>=1.35.0,<1.36.0)"]
399
+ boto3 = ["boto3 (==1.35.70)", "botocore (==1.35.70)"]
400
+ braket = ["mypy-boto3-braket (>=1.35.0,<1.36.0)"]
401
+ budgets = ["mypy-boto3-budgets (>=1.35.0,<1.36.0)"]
402
+ ce = ["mypy-boto3-ce (>=1.35.0,<1.36.0)"]
403
+ chatbot = ["mypy-boto3-chatbot (>=1.35.0,<1.36.0)"]
404
+ chime = ["mypy-boto3-chime (>=1.35.0,<1.36.0)"]
405
+ chime-sdk-identity = ["mypy-boto3-chime-sdk-identity (>=1.35.0,<1.36.0)"]
406
+ chime-sdk-media-pipelines = ["mypy-boto3-chime-sdk-media-pipelines (>=1.35.0,<1.36.0)"]
407
+ chime-sdk-meetings = ["mypy-boto3-chime-sdk-meetings (>=1.35.0,<1.36.0)"]
408
+ chime-sdk-messaging = ["mypy-boto3-chime-sdk-messaging (>=1.35.0,<1.36.0)"]
409
+ chime-sdk-voice = ["mypy-boto3-chime-sdk-voice (>=1.35.0,<1.36.0)"]
410
+ cleanrooms = ["mypy-boto3-cleanrooms (>=1.35.0,<1.36.0)"]
411
+ cleanroomsml = ["mypy-boto3-cleanroomsml (>=1.35.0,<1.36.0)"]
412
+ cloud9 = ["mypy-boto3-cloud9 (>=1.35.0,<1.36.0)"]
413
+ cloudcontrol = ["mypy-boto3-cloudcontrol (>=1.35.0,<1.36.0)"]
414
+ clouddirectory = ["mypy-boto3-clouddirectory (>=1.35.0,<1.36.0)"]
415
+ cloudformation = ["mypy-boto3-cloudformation (>=1.35.0,<1.36.0)"]
416
+ cloudfront = ["mypy-boto3-cloudfront (>=1.35.0,<1.36.0)"]
417
+ cloudfront-keyvaluestore = ["mypy-boto3-cloudfront-keyvaluestore (>=1.35.0,<1.36.0)"]
418
+ cloudhsm = ["mypy-boto3-cloudhsm (>=1.35.0,<1.36.0)"]
419
+ cloudhsmv2 = ["mypy-boto3-cloudhsmv2 (>=1.35.0,<1.36.0)"]
420
+ cloudsearch = ["mypy-boto3-cloudsearch (>=1.35.0,<1.36.0)"]
421
+ cloudsearchdomain = ["mypy-boto3-cloudsearchdomain (>=1.35.0,<1.36.0)"]
422
+ cloudtrail = ["mypy-boto3-cloudtrail (>=1.35.0,<1.36.0)"]
423
+ cloudtrail-data = ["mypy-boto3-cloudtrail-data (>=1.35.0,<1.36.0)"]
424
+ cloudwatch = ["mypy-boto3-cloudwatch (>=1.35.0,<1.36.0)"]
425
+ codeartifact = ["mypy-boto3-codeartifact (>=1.35.0,<1.36.0)"]
426
+ codebuild = ["mypy-boto3-codebuild (>=1.35.0,<1.36.0)"]
427
+ codecatalyst = ["mypy-boto3-codecatalyst (>=1.35.0,<1.36.0)"]
428
+ codecommit = ["mypy-boto3-codecommit (>=1.35.0,<1.36.0)"]
429
+ codeconnections = ["mypy-boto3-codeconnections (>=1.35.0,<1.36.0)"]
430
+ codedeploy = ["mypy-boto3-codedeploy (>=1.35.0,<1.36.0)"]
431
+ codeguru-reviewer = ["mypy-boto3-codeguru-reviewer (>=1.35.0,<1.36.0)"]
432
+ codeguru-security = ["mypy-boto3-codeguru-security (>=1.35.0,<1.36.0)"]
433
+ codeguruprofiler = ["mypy-boto3-codeguruprofiler (>=1.35.0,<1.36.0)"]
434
+ codepipeline = ["mypy-boto3-codepipeline (>=1.35.0,<1.36.0)"]
435
+ codestar-connections = ["mypy-boto3-codestar-connections (>=1.35.0,<1.36.0)"]
436
+ codestar-notifications = ["mypy-boto3-codestar-notifications (>=1.35.0,<1.36.0)"]
437
+ cognito-identity = ["mypy-boto3-cognito-identity (>=1.35.0,<1.36.0)"]
438
+ cognito-idp = ["mypy-boto3-cognito-idp (>=1.35.0,<1.36.0)"]
439
+ cognito-sync = ["mypy-boto3-cognito-sync (>=1.35.0,<1.36.0)"]
440
+ comprehend = ["mypy-boto3-comprehend (>=1.35.0,<1.36.0)"]
441
+ comprehendmedical = ["mypy-boto3-comprehendmedical (>=1.35.0,<1.36.0)"]
442
+ compute-optimizer = ["mypy-boto3-compute-optimizer (>=1.35.0,<1.36.0)"]
443
+ config = ["mypy-boto3-config (>=1.35.0,<1.36.0)"]
444
+ connect = ["mypy-boto3-connect (>=1.35.0,<1.36.0)"]
445
+ connect-contact-lens = ["mypy-boto3-connect-contact-lens (>=1.35.0,<1.36.0)"]
446
+ connectcampaigns = ["mypy-boto3-connectcampaigns (>=1.35.0,<1.36.0)"]
447
+ connectcampaignsv2 = ["mypy-boto3-connectcampaignsv2 (>=1.35.0,<1.36.0)"]
448
+ connectcases = ["mypy-boto3-connectcases (>=1.35.0,<1.36.0)"]
449
+ connectparticipant = ["mypy-boto3-connectparticipant (>=1.35.0,<1.36.0)"]
450
+ controlcatalog = ["mypy-boto3-controlcatalog (>=1.35.0,<1.36.0)"]
451
+ controltower = ["mypy-boto3-controltower (>=1.35.0,<1.36.0)"]
452
+ cost-optimization-hub = ["mypy-boto3-cost-optimization-hub (>=1.35.0,<1.36.0)"]
453
+ cur = ["mypy-boto3-cur (>=1.35.0,<1.36.0)"]
454
+ customer-profiles = ["mypy-boto3-customer-profiles (>=1.35.0,<1.36.0)"]
455
+ databrew = ["mypy-boto3-databrew (>=1.35.0,<1.36.0)"]
456
+ dataexchange = ["mypy-boto3-dataexchange (>=1.35.0,<1.36.0)"]
457
+ datapipeline = ["mypy-boto3-datapipeline (>=1.35.0,<1.36.0)"]
458
+ datasync = ["mypy-boto3-datasync (>=1.35.0,<1.36.0)"]
459
+ datazone = ["mypy-boto3-datazone (>=1.35.0,<1.36.0)"]
460
+ dax = ["mypy-boto3-dax (>=1.35.0,<1.36.0)"]
461
+ deadline = ["mypy-boto3-deadline (>=1.35.0,<1.36.0)"]
462
+ detective = ["mypy-boto3-detective (>=1.35.0,<1.36.0)"]
463
+ devicefarm = ["mypy-boto3-devicefarm (>=1.35.0,<1.36.0)"]
464
+ devops-guru = ["mypy-boto3-devops-guru (>=1.35.0,<1.36.0)"]
465
+ directconnect = ["mypy-boto3-directconnect (>=1.35.0,<1.36.0)"]
466
+ discovery = ["mypy-boto3-discovery (>=1.35.0,<1.36.0)"]
467
+ dlm = ["mypy-boto3-dlm (>=1.35.0,<1.36.0)"]
468
+ dms = ["mypy-boto3-dms (>=1.35.0,<1.36.0)"]
469
+ docdb = ["mypy-boto3-docdb (>=1.35.0,<1.36.0)"]
470
+ docdb-elastic = ["mypy-boto3-docdb-elastic (>=1.35.0,<1.36.0)"]
471
+ drs = ["mypy-boto3-drs (>=1.35.0,<1.36.0)"]
472
+ ds = ["mypy-boto3-ds (>=1.35.0,<1.36.0)"]
473
+ ds-data = ["mypy-boto3-ds-data (>=1.35.0,<1.36.0)"]
474
+ dynamodb = ["mypy-boto3-dynamodb (>=1.35.0,<1.36.0)"]
475
+ dynamodbstreams = ["mypy-boto3-dynamodbstreams (>=1.35.0,<1.36.0)"]
476
+ ebs = ["mypy-boto3-ebs (>=1.35.0,<1.36.0)"]
477
+ ec2 = ["mypy-boto3-ec2 (>=1.35.0,<1.36.0)"]
478
+ ec2-instance-connect = ["mypy-boto3-ec2-instance-connect (>=1.35.0,<1.36.0)"]
479
+ ecr = ["mypy-boto3-ecr (>=1.35.0,<1.36.0)"]
480
+ ecr-public = ["mypy-boto3-ecr-public (>=1.35.0,<1.36.0)"]
481
+ ecs = ["mypy-boto3-ecs (>=1.35.0,<1.36.0)"]
482
+ efs = ["mypy-boto3-efs (>=1.35.0,<1.36.0)"]
483
+ eks = ["mypy-boto3-eks (>=1.35.0,<1.36.0)"]
484
+ eks-auth = ["mypy-boto3-eks-auth (>=1.35.0,<1.36.0)"]
485
+ elastic-inference = ["mypy-boto3-elastic-inference (>=1.35.0,<1.36.0)"]
486
+ elasticache = ["mypy-boto3-elasticache (>=1.35.0,<1.36.0)"]
487
+ elasticbeanstalk = ["mypy-boto3-elasticbeanstalk (>=1.35.0,<1.36.0)"]
488
+ elastictranscoder = ["mypy-boto3-elastictranscoder (>=1.35.0,<1.36.0)"]
489
+ elb = ["mypy-boto3-elb (>=1.35.0,<1.36.0)"]
490
+ elbv2 = ["mypy-boto3-elbv2 (>=1.35.0,<1.36.0)"]
491
+ emr = ["mypy-boto3-emr (>=1.35.0,<1.36.0)"]
492
+ emr-containers = ["mypy-boto3-emr-containers (>=1.35.0,<1.36.0)"]
493
+ emr-serverless = ["mypy-boto3-emr-serverless (>=1.35.0,<1.36.0)"]
494
+ entityresolution = ["mypy-boto3-entityresolution (>=1.35.0,<1.36.0)"]
495
+ es = ["mypy-boto3-es (>=1.35.0,<1.36.0)"]
496
+ essential = ["mypy-boto3-cloudformation (>=1.35.0,<1.36.0)", "mypy-boto3-dynamodb (>=1.35.0,<1.36.0)", "mypy-boto3-ec2 (>=1.35.0,<1.36.0)", "mypy-boto3-lambda (>=1.35.0,<1.36.0)", "mypy-boto3-rds (>=1.35.0,<1.36.0)", "mypy-boto3-s3 (>=1.35.0,<1.36.0)", "mypy-boto3-sqs (>=1.35.0,<1.36.0)"]
497
+ events = ["mypy-boto3-events (>=1.35.0,<1.36.0)"]
498
+ evidently = ["mypy-boto3-evidently (>=1.35.0,<1.36.0)"]
499
+ finspace = ["mypy-boto3-finspace (>=1.35.0,<1.36.0)"]
500
+ finspace-data = ["mypy-boto3-finspace-data (>=1.35.0,<1.36.0)"]
501
+ firehose = ["mypy-boto3-firehose (>=1.35.0,<1.36.0)"]
502
+ fis = ["mypy-boto3-fis (>=1.35.0,<1.36.0)"]
503
+ fms = ["mypy-boto3-fms (>=1.35.0,<1.36.0)"]
504
+ forecast = ["mypy-boto3-forecast (>=1.35.0,<1.36.0)"]
505
+ forecastquery = ["mypy-boto3-forecastquery (>=1.35.0,<1.36.0)"]
506
+ frauddetector = ["mypy-boto3-frauddetector (>=1.35.0,<1.36.0)"]
507
+ freetier = ["mypy-boto3-freetier (>=1.35.0,<1.36.0)"]
508
+ fsx = ["mypy-boto3-fsx (>=1.35.0,<1.36.0)"]
509
+ full = ["boto3-stubs-full"]
510
+ gamelift = ["mypy-boto3-gamelift (>=1.35.0,<1.36.0)"]
511
+ geo-maps = ["mypy-boto3-geo-maps (>=1.35.0,<1.36.0)"]
512
+ geo-places = ["mypy-boto3-geo-places (>=1.35.0,<1.36.0)"]
513
+ geo-routes = ["mypy-boto3-geo-routes (>=1.35.0,<1.36.0)"]
514
+ glacier = ["mypy-boto3-glacier (>=1.35.0,<1.36.0)"]
515
+ globalaccelerator = ["mypy-boto3-globalaccelerator (>=1.35.0,<1.36.0)"]
516
+ glue = ["mypy-boto3-glue (>=1.35.0,<1.36.0)"]
517
+ grafana = ["mypy-boto3-grafana (>=1.35.0,<1.36.0)"]
518
+ greengrass = ["mypy-boto3-greengrass (>=1.35.0,<1.36.0)"]
519
+ greengrassv2 = ["mypy-boto3-greengrassv2 (>=1.35.0,<1.36.0)"]
520
+ groundstation = ["mypy-boto3-groundstation (>=1.35.0,<1.36.0)"]
521
+ guardduty = ["mypy-boto3-guardduty (>=1.35.0,<1.36.0)"]
522
+ health = ["mypy-boto3-health (>=1.35.0,<1.36.0)"]
523
+ healthlake = ["mypy-boto3-healthlake (>=1.35.0,<1.36.0)"]
524
+ iam = ["mypy-boto3-iam (>=1.35.0,<1.36.0)"]
525
+ identitystore = ["mypy-boto3-identitystore (>=1.35.0,<1.36.0)"]
526
+ imagebuilder = ["mypy-boto3-imagebuilder (>=1.35.0,<1.36.0)"]
527
+ importexport = ["mypy-boto3-importexport (>=1.35.0,<1.36.0)"]
528
+ inspector = ["mypy-boto3-inspector (>=1.35.0,<1.36.0)"]
529
+ inspector-scan = ["mypy-boto3-inspector-scan (>=1.35.0,<1.36.0)"]
530
+ inspector2 = ["mypy-boto3-inspector2 (>=1.35.0,<1.36.0)"]
531
+ internetmonitor = ["mypy-boto3-internetmonitor (>=1.35.0,<1.36.0)"]
532
+ iot = ["mypy-boto3-iot (>=1.35.0,<1.36.0)"]
533
+ iot-data = ["mypy-boto3-iot-data (>=1.35.0,<1.36.0)"]
534
+ iot-jobs-data = ["mypy-boto3-iot-jobs-data (>=1.35.0,<1.36.0)"]
535
+ iot1click-devices = ["mypy-boto3-iot1click-devices (>=1.35.0,<1.36.0)"]
536
+ iot1click-projects = ["mypy-boto3-iot1click-projects (>=1.35.0,<1.36.0)"]
537
+ iotanalytics = ["mypy-boto3-iotanalytics (>=1.35.0,<1.36.0)"]
538
+ iotdeviceadvisor = ["mypy-boto3-iotdeviceadvisor (>=1.35.0,<1.36.0)"]
539
+ iotevents = ["mypy-boto3-iotevents (>=1.35.0,<1.36.0)"]
540
+ iotevents-data = ["mypy-boto3-iotevents-data (>=1.35.0,<1.36.0)"]
541
+ iotfleethub = ["mypy-boto3-iotfleethub (>=1.35.0,<1.36.0)"]
542
+ iotfleetwise = ["mypy-boto3-iotfleetwise (>=1.35.0,<1.36.0)"]
543
+ iotsecuretunneling = ["mypy-boto3-iotsecuretunneling (>=1.35.0,<1.36.0)"]
544
+ iotsitewise = ["mypy-boto3-iotsitewise (>=1.35.0,<1.36.0)"]
545
+ iotthingsgraph = ["mypy-boto3-iotthingsgraph (>=1.35.0,<1.36.0)"]
546
+ iottwinmaker = ["mypy-boto3-iottwinmaker (>=1.35.0,<1.36.0)"]
547
+ iotwireless = ["mypy-boto3-iotwireless (>=1.35.0,<1.36.0)"]
548
+ ivs = ["mypy-boto3-ivs (>=1.35.0,<1.36.0)"]
549
+ ivs-realtime = ["mypy-boto3-ivs-realtime (>=1.35.0,<1.36.0)"]
550
+ ivschat = ["mypy-boto3-ivschat (>=1.35.0,<1.36.0)"]
551
+ kafka = ["mypy-boto3-kafka (>=1.35.0,<1.36.0)"]
552
+ kafkaconnect = ["mypy-boto3-kafkaconnect (>=1.35.0,<1.36.0)"]
553
+ kendra = ["mypy-boto3-kendra (>=1.35.0,<1.36.0)"]
554
+ kendra-ranking = ["mypy-boto3-kendra-ranking (>=1.35.0,<1.36.0)"]
555
+ keyspaces = ["mypy-boto3-keyspaces (>=1.35.0,<1.36.0)"]
556
+ kinesis = ["mypy-boto3-kinesis (>=1.35.0,<1.36.0)"]
557
+ kinesis-video-archived-media = ["mypy-boto3-kinesis-video-archived-media (>=1.35.0,<1.36.0)"]
558
+ kinesis-video-media = ["mypy-boto3-kinesis-video-media (>=1.35.0,<1.36.0)"]
559
+ kinesis-video-signaling = ["mypy-boto3-kinesis-video-signaling (>=1.35.0,<1.36.0)"]
560
+ kinesis-video-webrtc-storage = ["mypy-boto3-kinesis-video-webrtc-storage (>=1.35.0,<1.36.0)"]
561
+ kinesisanalytics = ["mypy-boto3-kinesisanalytics (>=1.35.0,<1.36.0)"]
562
+ kinesisanalyticsv2 = ["mypy-boto3-kinesisanalyticsv2 (>=1.35.0,<1.36.0)"]
563
+ kinesisvideo = ["mypy-boto3-kinesisvideo (>=1.35.0,<1.36.0)"]
564
+ kms = ["mypy-boto3-kms (>=1.35.0,<1.36.0)"]
565
+ lakeformation = ["mypy-boto3-lakeformation (>=1.35.0,<1.36.0)"]
566
+ lambda = ["mypy-boto3-lambda (>=1.35.0,<1.36.0)"]
567
+ launch-wizard = ["mypy-boto3-launch-wizard (>=1.35.0,<1.36.0)"]
568
+ lex-models = ["mypy-boto3-lex-models (>=1.35.0,<1.36.0)"]
569
+ lex-runtime = ["mypy-boto3-lex-runtime (>=1.35.0,<1.36.0)"]
570
+ lexv2-models = ["mypy-boto3-lexv2-models (>=1.35.0,<1.36.0)"]
571
+ lexv2-runtime = ["mypy-boto3-lexv2-runtime (>=1.35.0,<1.36.0)"]
572
+ license-manager = ["mypy-boto3-license-manager (>=1.35.0,<1.36.0)"]
573
+ license-manager-linux-subscriptions = ["mypy-boto3-license-manager-linux-subscriptions (>=1.35.0,<1.36.0)"]
574
+ license-manager-user-subscriptions = ["mypy-boto3-license-manager-user-subscriptions (>=1.35.0,<1.36.0)"]
575
+ lightsail = ["mypy-boto3-lightsail (>=1.35.0,<1.36.0)"]
576
+ location = ["mypy-boto3-location (>=1.35.0,<1.36.0)"]
577
+ logs = ["mypy-boto3-logs (>=1.35.0,<1.36.0)"]
578
+ lookoutequipment = ["mypy-boto3-lookoutequipment (>=1.35.0,<1.36.0)"]
579
+ lookoutmetrics = ["mypy-boto3-lookoutmetrics (>=1.35.0,<1.36.0)"]
580
+ lookoutvision = ["mypy-boto3-lookoutvision (>=1.35.0,<1.36.0)"]
581
+ m2 = ["mypy-boto3-m2 (>=1.35.0,<1.36.0)"]
582
+ machinelearning = ["mypy-boto3-machinelearning (>=1.35.0,<1.36.0)"]
583
+ macie2 = ["mypy-boto3-macie2 (>=1.35.0,<1.36.0)"]
584
+ mailmanager = ["mypy-boto3-mailmanager (>=1.35.0,<1.36.0)"]
585
+ managedblockchain = ["mypy-boto3-managedblockchain (>=1.35.0,<1.36.0)"]
586
+ managedblockchain-query = ["mypy-boto3-managedblockchain-query (>=1.35.0,<1.36.0)"]
587
+ marketplace-agreement = ["mypy-boto3-marketplace-agreement (>=1.35.0,<1.36.0)"]
588
+ marketplace-catalog = ["mypy-boto3-marketplace-catalog (>=1.35.0,<1.36.0)"]
589
+ marketplace-deployment = ["mypy-boto3-marketplace-deployment (>=1.35.0,<1.36.0)"]
590
+ marketplace-entitlement = ["mypy-boto3-marketplace-entitlement (>=1.35.0,<1.36.0)"]
591
+ marketplace-reporting = ["mypy-boto3-marketplace-reporting (>=1.35.0,<1.36.0)"]
592
+ marketplacecommerceanalytics = ["mypy-boto3-marketplacecommerceanalytics (>=1.35.0,<1.36.0)"]
593
+ mediaconnect = ["mypy-boto3-mediaconnect (>=1.35.0,<1.36.0)"]
594
+ mediaconvert = ["mypy-boto3-mediaconvert (>=1.35.0,<1.36.0)"]
595
+ medialive = ["mypy-boto3-medialive (>=1.35.0,<1.36.0)"]
596
+ mediapackage = ["mypy-boto3-mediapackage (>=1.35.0,<1.36.0)"]
597
+ mediapackage-vod = ["mypy-boto3-mediapackage-vod (>=1.35.0,<1.36.0)"]
598
+ mediapackagev2 = ["mypy-boto3-mediapackagev2 (>=1.35.0,<1.36.0)"]
599
+ mediastore = ["mypy-boto3-mediastore (>=1.35.0,<1.36.0)"]
600
+ mediastore-data = ["mypy-boto3-mediastore-data (>=1.35.0,<1.36.0)"]
601
+ mediatailor = ["mypy-boto3-mediatailor (>=1.35.0,<1.36.0)"]
602
+ medical-imaging = ["mypy-boto3-medical-imaging (>=1.35.0,<1.36.0)"]
603
+ memorydb = ["mypy-boto3-memorydb (>=1.35.0,<1.36.0)"]
604
+ meteringmarketplace = ["mypy-boto3-meteringmarketplace (>=1.35.0,<1.36.0)"]
605
+ mgh = ["mypy-boto3-mgh (>=1.35.0,<1.36.0)"]
606
+ mgn = ["mypy-boto3-mgn (>=1.35.0,<1.36.0)"]
607
+ migration-hub-refactor-spaces = ["mypy-boto3-migration-hub-refactor-spaces (>=1.35.0,<1.36.0)"]
608
+ migrationhub-config = ["mypy-boto3-migrationhub-config (>=1.35.0,<1.36.0)"]
609
+ migrationhuborchestrator = ["mypy-boto3-migrationhuborchestrator (>=1.35.0,<1.36.0)"]
610
+ migrationhubstrategy = ["mypy-boto3-migrationhubstrategy (>=1.35.0,<1.36.0)"]
611
+ mq = ["mypy-boto3-mq (>=1.35.0,<1.36.0)"]
612
+ mturk = ["mypy-boto3-mturk (>=1.35.0,<1.36.0)"]
613
+ mwaa = ["mypy-boto3-mwaa (>=1.35.0,<1.36.0)"]
614
+ neptune = ["mypy-boto3-neptune (>=1.35.0,<1.36.0)"]
615
+ neptune-graph = ["mypy-boto3-neptune-graph (>=1.35.0,<1.36.0)"]
616
+ neptunedata = ["mypy-boto3-neptunedata (>=1.35.0,<1.36.0)"]
617
+ network-firewall = ["mypy-boto3-network-firewall (>=1.35.0,<1.36.0)"]
618
+ networkmanager = ["mypy-boto3-networkmanager (>=1.35.0,<1.36.0)"]
619
+ networkmonitor = ["mypy-boto3-networkmonitor (>=1.35.0,<1.36.0)"]
620
+ notifications = ["mypy-boto3-notifications (>=1.35.0,<1.36.0)"]
621
+ notificationscontacts = ["mypy-boto3-notificationscontacts (>=1.35.0,<1.36.0)"]
622
+ oam = ["mypy-boto3-oam (>=1.35.0,<1.36.0)"]
623
+ omics = ["mypy-boto3-omics (>=1.35.0,<1.36.0)"]
624
+ opensearch = ["mypy-boto3-opensearch (>=1.35.0,<1.36.0)"]
625
+ opensearchserverless = ["mypy-boto3-opensearchserverless (>=1.35.0,<1.36.0)"]
626
+ opsworks = ["mypy-boto3-opsworks (>=1.35.0,<1.36.0)"]
627
+ opsworkscm = ["mypy-boto3-opsworkscm (>=1.35.0,<1.36.0)"]
628
+ organizations = ["mypy-boto3-organizations (>=1.35.0,<1.36.0)"]
629
+ osis = ["mypy-boto3-osis (>=1.35.0,<1.36.0)"]
630
+ outposts = ["mypy-boto3-outposts (>=1.35.0,<1.36.0)"]
631
+ panorama = ["mypy-boto3-panorama (>=1.35.0,<1.36.0)"]
632
+ partnercentral-selling = ["mypy-boto3-partnercentral-selling (>=1.35.0,<1.36.0)"]
633
+ payment-cryptography = ["mypy-boto3-payment-cryptography (>=1.35.0,<1.36.0)"]
634
+ payment-cryptography-data = ["mypy-boto3-payment-cryptography-data (>=1.35.0,<1.36.0)"]
635
+ pca-connector-ad = ["mypy-boto3-pca-connector-ad (>=1.35.0,<1.36.0)"]
636
+ pca-connector-scep = ["mypy-boto3-pca-connector-scep (>=1.35.0,<1.36.0)"]
637
+ pcs = ["mypy-boto3-pcs (>=1.35.0,<1.36.0)"]
638
+ personalize = ["mypy-boto3-personalize (>=1.35.0,<1.36.0)"]
639
+ personalize-events = ["mypy-boto3-personalize-events (>=1.35.0,<1.36.0)"]
640
+ personalize-runtime = ["mypy-boto3-personalize-runtime (>=1.35.0,<1.36.0)"]
641
+ pi = ["mypy-boto3-pi (>=1.35.0,<1.36.0)"]
642
+ pinpoint = ["mypy-boto3-pinpoint (>=1.35.0,<1.36.0)"]
643
+ pinpoint-email = ["mypy-boto3-pinpoint-email (>=1.35.0,<1.36.0)"]
644
+ pinpoint-sms-voice = ["mypy-boto3-pinpoint-sms-voice (>=1.35.0,<1.36.0)"]
645
+ pinpoint-sms-voice-v2 = ["mypy-boto3-pinpoint-sms-voice-v2 (>=1.35.0,<1.36.0)"]
646
+ pipes = ["mypy-boto3-pipes (>=1.35.0,<1.36.0)"]
647
+ polly = ["mypy-boto3-polly (>=1.35.0,<1.36.0)"]
648
+ pricing = ["mypy-boto3-pricing (>=1.35.0,<1.36.0)"]
649
+ privatenetworks = ["mypy-boto3-privatenetworks (>=1.35.0,<1.36.0)"]
650
+ proton = ["mypy-boto3-proton (>=1.35.0,<1.36.0)"]
651
+ qapps = ["mypy-boto3-qapps (>=1.35.0,<1.36.0)"]
652
+ qbusiness = ["mypy-boto3-qbusiness (>=1.35.0,<1.36.0)"]
653
+ qconnect = ["mypy-boto3-qconnect (>=1.35.0,<1.36.0)"]
654
+ qldb = ["mypy-boto3-qldb (>=1.35.0,<1.36.0)"]
655
+ qldb-session = ["mypy-boto3-qldb-session (>=1.35.0,<1.36.0)"]
656
+ quicksight = ["mypy-boto3-quicksight (>=1.35.0,<1.36.0)"]
657
+ ram = ["mypy-boto3-ram (>=1.35.0,<1.36.0)"]
658
+ rbin = ["mypy-boto3-rbin (>=1.35.0,<1.36.0)"]
659
+ rds = ["mypy-boto3-rds (>=1.35.0,<1.36.0)"]
660
+ rds-data = ["mypy-boto3-rds-data (>=1.35.0,<1.36.0)"]
661
+ redshift = ["mypy-boto3-redshift (>=1.35.0,<1.36.0)"]
662
+ redshift-data = ["mypy-boto3-redshift-data (>=1.35.0,<1.36.0)"]
663
+ redshift-serverless = ["mypy-boto3-redshift-serverless (>=1.35.0,<1.36.0)"]
664
+ rekognition = ["mypy-boto3-rekognition (>=1.35.0,<1.36.0)"]
665
+ repostspace = ["mypy-boto3-repostspace (>=1.35.0,<1.36.0)"]
666
+ resiliencehub = ["mypy-boto3-resiliencehub (>=1.35.0,<1.36.0)"]
667
+ resource-explorer-2 = ["mypy-boto3-resource-explorer-2 (>=1.35.0,<1.36.0)"]
668
+ resource-groups = ["mypy-boto3-resource-groups (>=1.35.0,<1.36.0)"]
669
+ resourcegroupstaggingapi = ["mypy-boto3-resourcegroupstaggingapi (>=1.35.0,<1.36.0)"]
670
+ robomaker = ["mypy-boto3-robomaker (>=1.35.0,<1.36.0)"]
671
+ rolesanywhere = ["mypy-boto3-rolesanywhere (>=1.35.0,<1.36.0)"]
672
+ route53 = ["mypy-boto3-route53 (>=1.35.0,<1.36.0)"]
673
+ route53-recovery-cluster = ["mypy-boto3-route53-recovery-cluster (>=1.35.0,<1.36.0)"]
674
+ route53-recovery-control-config = ["mypy-boto3-route53-recovery-control-config (>=1.35.0,<1.36.0)"]
675
+ route53-recovery-readiness = ["mypy-boto3-route53-recovery-readiness (>=1.35.0,<1.36.0)"]
676
+ route53domains = ["mypy-boto3-route53domains (>=1.35.0,<1.36.0)"]
677
+ route53profiles = ["mypy-boto3-route53profiles (>=1.35.0,<1.36.0)"]
678
+ route53resolver = ["mypy-boto3-route53resolver (>=1.35.0,<1.36.0)"]
679
+ rum = ["mypy-boto3-rum (>=1.35.0,<1.36.0)"]
680
+ s3 = ["mypy-boto3-s3 (>=1.35.0,<1.36.0)"]
681
+ s3control = ["mypy-boto3-s3control (>=1.35.0,<1.36.0)"]
682
+ s3outposts = ["mypy-boto3-s3outposts (>=1.35.0,<1.36.0)"]
683
+ sagemaker = ["mypy-boto3-sagemaker (>=1.35.0,<1.36.0)"]
684
+ sagemaker-a2i-runtime = ["mypy-boto3-sagemaker-a2i-runtime (>=1.35.0,<1.36.0)"]
685
+ sagemaker-edge = ["mypy-boto3-sagemaker-edge (>=1.35.0,<1.36.0)"]
686
+ sagemaker-featurestore-runtime = ["mypy-boto3-sagemaker-featurestore-runtime (>=1.35.0,<1.36.0)"]
687
+ sagemaker-geospatial = ["mypy-boto3-sagemaker-geospatial (>=1.35.0,<1.36.0)"]
688
+ sagemaker-metrics = ["mypy-boto3-sagemaker-metrics (>=1.35.0,<1.36.0)"]
689
+ sagemaker-runtime = ["mypy-boto3-sagemaker-runtime (>=1.35.0,<1.36.0)"]
690
+ savingsplans = ["mypy-boto3-savingsplans (>=1.35.0,<1.36.0)"]
691
+ scheduler = ["mypy-boto3-scheduler (>=1.35.0,<1.36.0)"]
692
+ schemas = ["mypy-boto3-schemas (>=1.35.0,<1.36.0)"]
693
+ sdb = ["mypy-boto3-sdb (>=1.35.0,<1.36.0)"]
694
+ secretsmanager = ["mypy-boto3-secretsmanager (>=1.35.0,<1.36.0)"]
695
+ securityhub = ["mypy-boto3-securityhub (>=1.35.0,<1.36.0)"]
696
+ securitylake = ["mypy-boto3-securitylake (>=1.35.0,<1.36.0)"]
697
+ serverlessrepo = ["mypy-boto3-serverlessrepo (>=1.35.0,<1.36.0)"]
698
+ service-quotas = ["mypy-boto3-service-quotas (>=1.35.0,<1.36.0)"]
699
+ servicecatalog = ["mypy-boto3-servicecatalog (>=1.35.0,<1.36.0)"]
700
+ servicecatalog-appregistry = ["mypy-boto3-servicecatalog-appregistry (>=1.35.0,<1.36.0)"]
701
+ servicediscovery = ["mypy-boto3-servicediscovery (>=1.35.0,<1.36.0)"]
702
+ ses = ["mypy-boto3-ses (>=1.35.0,<1.36.0)"]
703
+ sesv2 = ["mypy-boto3-sesv2 (>=1.35.0,<1.36.0)"]
704
+ shield = ["mypy-boto3-shield (>=1.35.0,<1.36.0)"]
705
+ signer = ["mypy-boto3-signer (>=1.35.0,<1.36.0)"]
706
+ simspaceweaver = ["mypy-boto3-simspaceweaver (>=1.35.0,<1.36.0)"]
707
+ sms = ["mypy-boto3-sms (>=1.35.0,<1.36.0)"]
708
+ sms-voice = ["mypy-boto3-sms-voice (>=1.35.0,<1.36.0)"]
709
+ snow-device-management = ["mypy-boto3-snow-device-management (>=1.35.0,<1.36.0)"]
710
+ snowball = ["mypy-boto3-snowball (>=1.35.0,<1.36.0)"]
711
+ sns = ["mypy-boto3-sns (>=1.35.0,<1.36.0)"]
712
+ socialmessaging = ["mypy-boto3-socialmessaging (>=1.35.0,<1.36.0)"]
713
+ sqs = ["mypy-boto3-sqs (>=1.35.0,<1.36.0)"]
714
+ ssm = ["mypy-boto3-ssm (>=1.35.0,<1.36.0)"]
715
+ ssm-contacts = ["mypy-boto3-ssm-contacts (>=1.35.0,<1.36.0)"]
716
+ ssm-incidents = ["mypy-boto3-ssm-incidents (>=1.35.0,<1.36.0)"]
717
+ ssm-quicksetup = ["mypy-boto3-ssm-quicksetup (>=1.35.0,<1.36.0)"]
718
+ ssm-sap = ["mypy-boto3-ssm-sap (>=1.35.0,<1.36.0)"]
719
+ sso = ["mypy-boto3-sso (>=1.35.0,<1.36.0)"]
720
+ sso-admin = ["mypy-boto3-sso-admin (>=1.35.0,<1.36.0)"]
721
+ sso-oidc = ["mypy-boto3-sso-oidc (>=1.35.0,<1.36.0)"]
722
+ stepfunctions = ["mypy-boto3-stepfunctions (>=1.35.0,<1.36.0)"]
723
+ storagegateway = ["mypy-boto3-storagegateway (>=1.35.0,<1.36.0)"]
724
+ sts = ["mypy-boto3-sts (>=1.35.0,<1.36.0)"]
725
+ supplychain = ["mypy-boto3-supplychain (>=1.35.0,<1.36.0)"]
726
+ support = ["mypy-boto3-support (>=1.35.0,<1.36.0)"]
727
+ support-app = ["mypy-boto3-support-app (>=1.35.0,<1.36.0)"]
728
+ swf = ["mypy-boto3-swf (>=1.35.0,<1.36.0)"]
729
+ synthetics = ["mypy-boto3-synthetics (>=1.35.0,<1.36.0)"]
730
+ taxsettings = ["mypy-boto3-taxsettings (>=1.35.0,<1.36.0)"]
731
+ textract = ["mypy-boto3-textract (>=1.35.0,<1.36.0)"]
732
+ timestream-influxdb = ["mypy-boto3-timestream-influxdb (>=1.35.0,<1.36.0)"]
733
+ timestream-query = ["mypy-boto3-timestream-query (>=1.35.0,<1.36.0)"]
734
+ timestream-write = ["mypy-boto3-timestream-write (>=1.35.0,<1.36.0)"]
735
+ tnb = ["mypy-boto3-tnb (>=1.35.0,<1.36.0)"]
736
+ transcribe = ["mypy-boto3-transcribe (>=1.35.0,<1.36.0)"]
737
+ transfer = ["mypy-boto3-transfer (>=1.35.0,<1.36.0)"]
738
+ translate = ["mypy-boto3-translate (>=1.35.0,<1.36.0)"]
739
+ trustedadvisor = ["mypy-boto3-trustedadvisor (>=1.35.0,<1.36.0)"]
740
+ verifiedpermissions = ["mypy-boto3-verifiedpermissions (>=1.35.0,<1.36.0)"]
741
+ voice-id = ["mypy-boto3-voice-id (>=1.35.0,<1.36.0)"]
742
+ vpc-lattice = ["mypy-boto3-vpc-lattice (>=1.35.0,<1.36.0)"]
743
+ waf = ["mypy-boto3-waf (>=1.35.0,<1.36.0)"]
744
+ waf-regional = ["mypy-boto3-waf-regional (>=1.35.0,<1.36.0)"]
745
+ wafv2 = ["mypy-boto3-wafv2 (>=1.35.0,<1.36.0)"]
746
+ wellarchitected = ["mypy-boto3-wellarchitected (>=1.35.0,<1.36.0)"]
747
+ wisdom = ["mypy-boto3-wisdom (>=1.35.0,<1.36.0)"]
748
+ workdocs = ["mypy-boto3-workdocs (>=1.35.0,<1.36.0)"]
749
+ workmail = ["mypy-boto3-workmail (>=1.35.0,<1.36.0)"]
750
+ workmailmessageflow = ["mypy-boto3-workmailmessageflow (>=1.35.0,<1.36.0)"]
751
+ workspaces = ["mypy-boto3-workspaces (>=1.35.0,<1.36.0)"]
752
+ workspaces-thin-client = ["mypy-boto3-workspaces-thin-client (>=1.35.0,<1.36.0)"]
753
+ workspaces-web = ["mypy-boto3-workspaces-web (>=1.35.0,<1.36.0)"]
754
+ xray = ["mypy-boto3-xray (>=1.35.0,<1.36.0)"]
755
+
756
+ [[package]]
757
+ name = "botocore"
758
+ version = "1.35.70"
759
+ description = "Low-level, data-driven core of boto 3."
760
+ optional = false
761
+ python-versions = ">=3.8"
762
+ files = [
763
+ {file = "botocore-1.35.70-py3-none-any.whl", hash = "sha256:ba8a4797cf7c5d9c237e67a62692f5146e895613fd3e6a43b00b66f3a8c7fc73"},
764
+ {file = "botocore-1.35.70.tar.gz", hash = "sha256:18d1bb505722d9efd50c50719ed8de7284bfe6d3908a9e08756a7646e549da21"},
765
+ ]
766
+
767
+ [package.dependencies]
768
+ jmespath = ">=0.7.1,<2.0.0"
769
+ python-dateutil = ">=2.1,<3.0.0"
770
+ urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""}
771
+
772
+ [package.extras]
773
+ crt = ["awscrt (==0.22.0)"]
774
+
775
+ [[package]]
776
+ name = "botocore-stubs"
777
+ version = "1.35.70"
778
+ description = "Type annotations and code completion for botocore"
779
+ optional = false
780
+ python-versions = ">=3.8"
781
+ files = [
782
+ {file = "botocore_stubs-1.35.70-py3-none-any.whl", hash = "sha256:d717620186b925495bb76870b504ddc28d012c5353b24396214021440a0a0a0a"},
783
+ {file = "botocore_stubs-1.35.70.tar.gz", hash = "sha256:f79e34cc5be1857c3c952cb934500e8555fde3f90534169ccadc400f219a4890"},
784
+ ]
785
+
786
+ [package.dependencies]
787
+ types-awscrt = "*"
788
+
789
+ [package.extras]
790
+ botocore = ["botocore"]
791
+
792
  [[package]]
793
  name = "certifi"
794
  version = "2023.7.22"
 
2188
  [package.extras]
2189
  i18n = ["Babel (>=2.7)"]
2190
 
2191
+ [[package]]
2192
+ name = "jmespath"
2193
+ version = "1.0.1"
2194
+ description = "JSON Matching Expressions"
2195
+ optional = false
2196
+ python-versions = ">=3.7"
2197
+ files = [
2198
+ {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"},
2199
+ {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"},
2200
+ ]
2201
+
2202
  [[package]]
2203
  name = "joblib"
2204
  version = "1.4.2"
 
4294
  [package.dependencies]
4295
  six = ">=1.5"
4296
 
4297
+ [[package]]
4298
+ name = "python-dotenv"
4299
+ version = "1.0.1"
4300
+ description = "Read key-value pairs from a .env file and set them as environment variables"
4301
+ optional = false
4302
+ python-versions = ">=3.8"
4303
+ files = [
4304
+ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
4305
+ {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
4306
+ ]
4307
+
4308
+ [package.extras]
4309
+ cli = ["click (>=5.0)"]
4310
+
4311
  [[package]]
4312
  name = "python-multipart"
4313
  version = "0.0.17"
 
4880
  {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"},
4881
  ]
4882
 
4883
+ [[package]]
4884
+ name = "s3transfer"
4885
+ version = "0.10.4"
4886
+ description = "An Amazon S3 Transfer Manager"
4887
+ optional = false
4888
+ python-versions = ">=3.8"
4889
+ files = [
4890
+ {file = "s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e"},
4891
+ {file = "s3transfer-0.10.4.tar.gz", hash = "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7"},
4892
+ ]
4893
+
4894
+ [package.dependencies]
4895
+ botocore = ">=1.33.2,<2.0a.0"
4896
+
4897
+ [package.extras]
4898
+ crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"]
4899
+
4900
  [[package]]
4901
  name = "safetensors"
4902
  version = "0.4.5"
 
5873
  shellingham = ">=1.3.0"
5874
  typing-extensions = ">=3.7.4.3"
5875
 
5876
+ [[package]]
5877
+ name = "types-awscrt"
5878
+ version = "0.23.1"
5879
+ description = "Type annotations and code completion for awscrt"
5880
+ optional = false
5881
+ python-versions = ">=3.8"
5882
+ files = [
5883
+ {file = "types_awscrt-0.23.1-py3-none-any.whl", hash = "sha256:0d362a5d62d68ca4216f458172f41c1123ec04791d68364de8ee8b61b528b262"},
5884
+ {file = "types_awscrt-0.23.1.tar.gz", hash = "sha256:a20b425dabb258bc3d07a5e7de503fd9558dd1542d72de796e74e402c6d493b2"},
5885
+ ]
5886
+
5887
  [[package]]
5888
  name = "types-beautifulsoup4"
5889
  version = "4.12.0.20241020"
 
5898
  [package.dependencies]
5899
  types-html5lib = "*"
5900
 
5901
+ [[package]]
5902
+ name = "types-boto3"
5903
+ version = "1.0.2"
5904
+ description = "Proxy package for boto3-stubs"
5905
+ optional = false
5906
+ python-versions = "*"
5907
+ files = [
5908
+ {file = "types-boto3-1.0.2.tar.gz", hash = "sha256:15f3ffad0314e40a0708fec25f94891414f93260202422bf8b19b6913853c983"},
5909
+ {file = "types_boto3-1.0.2-py3-none-any.whl", hash = "sha256:a6a88e94d59d887839863a64095493956efc148e747206880a7eb47d90ae8398"},
5910
+ ]
5911
+
5912
+ [package.dependencies]
5913
+ boto3-stubs = "*"
5914
+
5915
  [[package]]
5916
  name = "types-html5lib"
5917
  version = "1.1.11.20241018"
 
5960
  urllib3 = ">=2"
5961
 
5962
  [[package]]
5963
+ name = "types-s3transfer"
5964
+ version = "0.10.4"
5965
+ description = "Type annotations and code completion for s3transfer"
5966
  optional = false
5967
  python-versions = ">=3.8"
5968
  files = [
5969
+ {file = "types_s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:22ac1aabc98f9d7f2928eb3fb4d5c02bf7435687f0913345a97dd3b84d0c217d"},
5970
+ {file = "types_s3transfer-0.10.4.tar.gz", hash = "sha256:03123477e3064c81efe712bf9d372c7c72f2790711431f9baa59cf96ea607267"},
5971
  ]
5972
 
5973
  [[package]]
5974
+ name = "types-six"
5975
+ version = "1.16.21.20241105"
5976
+ description = "Typing stubs for six"
5977
  optional = false
5978
  python-versions = ">=3.8"
5979
  files = [
5980
+ {file = "types-six-1.16.21.20241105.tar.gz", hash = "sha256:ce3534c38079ec3242f4a20376283eb265a3837f80592b0ecacb14bd41acc29e"},
5981
+ {file = "types_six-1.16.21.20241105-py3-none-any.whl", hash = "sha256:8b4b29e5c8fe7f1131be8f3cb7cedbcd8bb889707336f32c3fb332c9b1c71991"},
5982
  ]
5983
 
 
 
 
5984
  [[package]]
5985
  name = "typing-extensions"
5986
  version = "4.12.2"
 
6116
  docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
6117
  test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
6118
 
6119
+ [[package]]
6120
+ name = "vulture"
6121
+ version = "2.13"
6122
+ description = "Find dead code"
6123
+ optional = false
6124
+ python-versions = ">=3.8"
6125
+ files = [
6126
+ {file = "vulture-2.13-py2.py3-none-any.whl", hash = "sha256:34793ba60488e7cccbecdef3a7fe151656372ef94fdac9fe004c52a4000a6d44"},
6127
+ {file = "vulture-2.13.tar.gz", hash = "sha256:78248bf58f5eaffcc2ade306141ead73f437339950f80045dce7f8b078e5a1aa"},
6128
+ ]
6129
+
6130
+ [package.dependencies]
6131
+ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
6132
+
6133
  [[package]]
6134
  name = "wcwidth"
6135
  version = "0.2.13"
 
6348
  [metadata]
6349
  lock-version = "2.0"
6350
  python-versions = "~3.10"
6351
+ content-hash = "edbf4967508fd1d767c1ce0b9d98e11b967086e4307c902bae34c7e143a131b9"
pyproject.toml CHANGED
@@ -19,13 +19,15 @@ tts-service = "tts_service.cli:main"
19
 
20
  [tool.poetry.dependencies]
21
  python = "~3.10"
22
- regex = "^2024.11.6"
23
  numpy = "1.23.5"
24
- tqdm = "^4.67.1"
 
 
25
  requests = ">=2.31.0,<2.32.0"
26
  six = "^1.16.0"
 
27
  wget = "^3.2"
28
- pandas = "^2.2.3"
29
 
30
  [tool.poetry.group.ml.dependencies]
31
  torch = "2.3.1"
@@ -51,6 +53,7 @@ ipykernel = "^6.29.5"
51
  pipdeptree = "^2.23.4"
52
  pre-commit = "^4.0.1"
53
  ruff = "^0.7.4"
 
54
 
55
  [tool.poetry.group.test.dependencies]
56
  pytest = "^8.3.3"
@@ -58,12 +61,12 @@ pytest-cov = "^6.0.0"
58
 
59
  [tool.poetry.group.typing.dependencies]
60
  mypy = "^1.13.0"
61
- types-requests = "^2.32.0.20241016"
62
- types-tqdm = "^4.67.0.20241119"
63
- types-six = "^1.16.21.20241105"
64
  types-beautifulsoup4 = "^4.12.0.20241020"
 
65
  types-regex = "^2024.11.6.20241108"
66
- pandas-stubs = "^2.2.3.241009"
 
67
 
68
 
69
  [tool.poetry.group.ui.dependencies]
@@ -92,6 +95,7 @@ edge-tts = "6.1.9"
92
 
93
  [tool.ruff]
94
  line-length = 132
 
95
 
96
  [tool.ruff.lint]
97
  select = [
@@ -113,6 +117,8 @@ select = [
113
  [tool.mypy]
114
  packages = "assets,core,rvc,tabs,tts_service,tests"
115
  check_untyped_defs = true
 
 
116
 
117
  [[tool.mypy.overrides]]
118
  module = [
@@ -143,6 +149,7 @@ module = [
143
  "rvc.train.preprocess.slicer",
144
  "rvc.train.process.extract_small_model",
145
  "tabs.extra.f0_extractor.f0_extractor",
 
146
  ]
147
  ignore_errors = true
148
 
@@ -171,11 +178,30 @@ module = [
171
  "torchaudio.*",
172
  "torchcrepe",
173
  "torchfcpe",
 
174
  "transformers",
175
  "wget",
176
  ]
177
  ignore_missing_imports = true
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  [build-system]
180
  requires = ["poetry-core"]
181
  build-backend = "poetry.core.masonry.api"
 
19
 
20
  [tool.poetry.dependencies]
21
  python = "~3.10"
22
+ boto3 = "^1.35.70"
23
  numpy = "1.23.5"
24
+ pandas = "^2.2.3"
25
+ python-dotenv = "^1.0.1"
26
+ regex = "^2024.11.6"
27
  requests = ">=2.31.0,<2.32.0"
28
  six = "^1.16.0"
29
+ tqdm = "^4.67.1"
30
  wget = "^3.2"
 
31
 
32
  [tool.poetry.group.ml.dependencies]
33
  torch = "2.3.1"
 
53
  pipdeptree = "^2.23.4"
54
  pre-commit = "^4.0.1"
55
  ruff = "^0.7.4"
56
+ vulture = "^2.13"
57
 
58
  [tool.poetry.group.test.dependencies]
59
  pytest = "^8.3.3"
 
61
 
62
  [tool.poetry.group.typing.dependencies]
63
  mypy = "^1.13.0"
64
+ pandas-stubs = "^2.2.3.241009"
 
 
65
  types-beautifulsoup4 = "^4.12.0.20241020"
66
+ types-boto3 = "^1.0.2"
67
  types-regex = "^2024.11.6.20241108"
68
+ types-requests = "^2.32.0.20241016"
69
+ types-six = "^1.16.21.20241105"
70
 
71
 
72
  [tool.poetry.group.ui.dependencies]
 
95
 
96
  [tool.ruff]
97
  line-length = 132
98
+ include = ["tts-service/**/*.py"]
99
 
100
  [tool.ruff.lint]
101
  select = [
 
117
  [tool.mypy]
118
  packages = "assets,core,rvc,tabs,tts_service,tests"
119
  check_untyped_defs = true
120
+ explicit_package_bases = true
121
+ namespace_packages = true
122
 
123
  [[tool.mypy.overrides]]
124
  module = [
 
149
  "rvc.train.preprocess.slicer",
150
  "rvc.train.process.extract_small_model",
151
  "tabs.extra.f0_extractor.f0_extractor",
152
+ "tts_service.whitelist",
153
  ]
154
  ignore_errors = true
155
 
 
178
  "torchaudio.*",
179
  "torchcrepe",
180
  "torchfcpe",
181
+ "tqdm",
182
  "transformers",
183
  "wget",
184
  ]
185
  ignore_missing_imports = true
186
 
187
+ [[tool.mypy.overrides]]
188
+ module = [
189
+ "rvc.lib.tools.prerequisites_download",
190
+ "tts_service.cli",
191
+ "tts_service.utils",
192
+ ]
193
+ warn_unused_configs = true
194
+ disallow_any_generics = true
195
+ disallow_subclassing_any = true
196
+ disallow_untyped_calls = true
197
+ disallow_untyped_defs = true
198
+ disallow_incomplete_defs = true
199
+ check_untyped_defs = true
200
+ disallow_untyped_decorators = true
201
+ warn_unused_ignores = true
202
+ warn_return_any = true
203
+ no_implicit_reexport = true
204
+
205
  [build-system]
206
  requires = ["poetry-core"]
207
  build-backend = "poetry.core.masonry.api"
requirements.txt CHANGED
@@ -105,6 +105,12 @@ bibtexparser==2.0.0b7 ; python_version >= "3.10" and python_version < "3.11" \
105
  blinker==1.9.0 ; python_version >= "3.10" and python_version < "3.11" \
106
  --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \
107
  --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc
 
 
 
 
 
 
108
  certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.11" \
109
  --hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
110
  --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
@@ -629,6 +635,9 @@ itsdangerous==2.2.0 ; python_version >= "3.10" and python_version < "3.11" \
629
  jinja2==3.1.4 ; python_version >= "3.10" and python_version < "3.11" \
630
  --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \
631
  --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d
 
 
 
632
  joblib==1.4.2 ; python_version >= "3.10" and python_version < "3.11" \
633
  --hash=sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6 \
634
  --hash=sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e
@@ -1529,6 +1538,9 @@ pypresence==4.3.0 ; python_version >= "3.10" and python_version < "3.11" \
1529
  python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "3.11" \
1530
  --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \
1531
  --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427
 
 
 
1532
  pytz==2024.2 ; python_version >= "3.10" and python_version < "3.11" \
1533
  --hash=sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a \
1534
  --hash=sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725
@@ -1787,6 +1799,9 @@ rpds-py==0.21.0 ; python_version >= "3.10" and python_version < "3.11" \
1787
  --hash=sha256:f983e4c2f603c95dde63df633eec42955508eefd8d0f0e6d236d31a044c882d7 \
1788
  --hash=sha256:faa5e8496c530f9c71f2b4e1c49758b06e5f4055e17144906245c99fa6d45356 \
1789
  --hash=sha256:fed5dfefdf384d6fe975cc026886aece4f292feaf69d0eeb716cfd3c5a4dd8be
 
 
 
1790
  safetensors==0.4.5 ; python_version >= "3.10" and python_version < "3.11" \
1791
  --hash=sha256:01c8f00da537af711979e1b42a69a8ec9e1d7112f208e0e9b8a35d2c381085ef \
1792
  --hash=sha256:023b6e5facda76989f4cba95a861b7e656b87e225f61811065d5c501f78cdb3f \
 
105
  blinker==1.9.0 ; python_version >= "3.10" and python_version < "3.11" \
106
  --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \
107
  --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc
108
+ boto3==1.35.70 ; python_version >= "3.10" and python_version < "3.11" \
109
+ --hash=sha256:121dce8c7102eea6a6047d46bcd74e8a24dac793a4a3857de4f4bad9c12566fd \
110
+ --hash=sha256:ca385708f83f01b3f27d9d675880d2458cb3b40ed1e25da688f551454ed0c112
111
+ botocore==1.35.70 ; python_version >= "3.10" and python_version < "3.11" \
112
+ --hash=sha256:18d1bb505722d9efd50c50719ed8de7284bfe6d3908a9e08756a7646e549da21 \
113
+ --hash=sha256:ba8a4797cf7c5d9c237e67a62692f5146e895613fd3e6a43b00b66f3a8c7fc73
114
  certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.11" \
115
  --hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
116
  --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
 
635
  jinja2==3.1.4 ; python_version >= "3.10" and python_version < "3.11" \
636
  --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \
637
  --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d
638
+ jmespath==1.0.1 ; python_version >= "3.10" and python_version < "3.11" \
639
+ --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \
640
+ --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe
641
  joblib==1.4.2 ; python_version >= "3.10" and python_version < "3.11" \
642
  --hash=sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6 \
643
  --hash=sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e
 
1538
  python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "3.11" \
1539
  --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \
1540
  --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427
1541
+ python-dotenv==1.0.1 ; python_version >= "3.10" and python_version < "3.11" \
1542
+ --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \
1543
+ --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a
1544
  pytz==2024.2 ; python_version >= "3.10" and python_version < "3.11" \
1545
  --hash=sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a \
1546
  --hash=sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725
 
1799
  --hash=sha256:f983e4c2f603c95dde63df633eec42955508eefd8d0f0e6d236d31a044c882d7 \
1800
  --hash=sha256:faa5e8496c530f9c71f2b4e1c49758b06e5f4055e17144906245c99fa6d45356 \
1801
  --hash=sha256:fed5dfefdf384d6fe975cc026886aece4f292feaf69d0eeb716cfd3c5a4dd8be
1802
+ s3transfer==0.10.4 ; python_version >= "3.10" and python_version < "3.11" \
1803
+ --hash=sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e \
1804
+ --hash=sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7
1805
  safetensors==0.4.5 ; python_version >= "3.10" and python_version < "3.11" \
1806
  --hash=sha256:01c8f00da537af711979e1b42a69a8ec9e1d7112f208e0e9b8a35d2c381085ef \
1807
  --hash=sha256:023b6e5facda76989f4cba95a861b7e656b87e225f61811065d5c501f78cdb3f \
rvc/configs/config.py CHANGED
@@ -34,26 +34,13 @@ class Config:
34
  if self.device.startswith("cuda")
35
  else None
36
  )
37
- self.json_config = self.load_config_json()
38
  self.gpu_mem = None
39
  self.x_pad, self.x_query, self.x_center, self.x_max = self.device_config()
40
 
41
- def load_config_json(self) -> dict:
42
- configs = {}
43
- for config_file in version_config_paths:
44
- config_path = os.path.join("rvc", "configs", config_file)
45
- with open(config_path, "r") as f:
46
- configs[config_file] = json.load(f)
47
- return configs
48
-
49
  def has_mps(self) -> bool:
50
  # Check if Metal Performance Shaders are available - for macOS 12.3+.
51
  return torch.backends.mps.is_available()
52
 
53
- def has_xpu(self) -> bool:
54
- # Check if XPU is available.
55
- return hasattr(torch, "xpu") and torch.xpu.is_available()
56
-
57
  def set_precision(self, precision):
58
  if precision not in ["fp32", "fp16"]:
59
  raise ValueError("Invalid precision type. Must be 'fp32' or 'fp16'.")
@@ -91,21 +78,6 @@ class Config:
91
 
92
  return f"Overwritten preprocess and config.json to use {precision}."
93
 
94
- def get_precision(self):
95
- if not version_config_paths:
96
- raise FileNotFoundError("No configuration paths provided.")
97
-
98
- full_config_path = os.path.join("rvc", "configs", version_config_paths[0])
99
- try:
100
- with open(full_config_path, "r") as f:
101
- config = json.load(f)
102
- fp16_run_value = config["train"].get("fp16_run", False)
103
- precision = "fp16" if fp16_run_value else "fp32"
104
- return precision
105
- except FileNotFoundError:
106
- print(f"File not found: {full_config_path}")
107
- return None
108
-
109
  def device_config(self) -> tuple:
110
  if self.device.startswith("cuda"):
111
  self.set_cuda_config()
@@ -142,38 +114,3 @@ class Config:
142
  self.gpu_mem = torch.cuda.get_device_properties(i_device).total_memory // (
143
  1024**3
144
  )
145
-
146
-
147
- def max_vram_gpu(gpu):
148
- if torch.cuda.is_available():
149
- gpu_properties = torch.cuda.get_device_properties(gpu)
150
- total_memory_gb = round(gpu_properties.total_memory / 1024 / 1024 / 1024)
151
- return total_memory_gb
152
- else:
153
- return "8"
154
-
155
-
156
- def get_gpu_info():
157
- ngpu = torch.cuda.device_count()
158
- gpu_infos = []
159
- if torch.cuda.is_available() or ngpu != 0:
160
- for i in range(ngpu):
161
- gpu_name = torch.cuda.get_device_name(i)
162
- mem = int(
163
- torch.cuda.get_device_properties(i).total_memory / 1024 / 1024 / 1024
164
- + 0.4
165
- )
166
- gpu_infos.append(f"{i}: {gpu_name} ({mem} GB)")
167
- if len(gpu_infos) > 0:
168
- gpu_info = "\n".join(gpu_infos)
169
- else:
170
- gpu_info = "Unfortunately, there is no compatible GPU available to support your training."
171
- return gpu_info
172
-
173
-
174
- def get_number_of_gpus():
175
- if torch.cuda.is_available():
176
- num_gpus = torch.cuda.device_count()
177
- return "-".join(map(str, range(num_gpus)))
178
- else:
179
- return "-"
 
34
  if self.device.startswith("cuda")
35
  else None
36
  )
 
37
  self.gpu_mem = None
38
  self.x_pad, self.x_query, self.x_center, self.x_max = self.device_config()
39
 
 
 
 
 
 
 
 
 
40
  def has_mps(self) -> bool:
41
  # Check if Metal Performance Shaders are available - for macOS 12.3+.
42
  return torch.backends.mps.is_available()
43
 
 
 
 
 
44
  def set_precision(self, precision):
45
  if precision not in ["fp32", "fp16"]:
46
  raise ValueError("Invalid precision type. Must be 'fp32' or 'fp16'.")
 
78
 
79
  return f"Overwritten preprocess and config.json to use {precision}."
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  def device_config(self) -> tuple:
82
  if self.device.startswith("cuda"):
83
  self.set_cuda_config()
 
114
  self.gpu_mem = torch.cuda.get_device_properties(i_device).total_memory // (
115
  1024**3
116
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
rvc/infer/infer.py CHANGED
@@ -58,7 +58,6 @@ class VoiceConverter:
58
  self.vc = None # Voice conversion pipeline instance
59
  self.cpt = None # Checkpoint for loading model weights
60
  self.version = None # Model version
61
- self.n_spk = None # Number of speakers in the model
62
  self.use_f0 = None # Whether the model uses F0
63
  self.loaded_model = None
64
 
@@ -356,72 +355,6 @@ class VoiceConverter:
356
  print(f"An error occurred during audio conversion: {error}")
357
  print(traceback.format_exc())
358
 
359
- def convert_audio_batch(
360
- self,
361
- audio_input_paths: str,
362
- audio_output_path: str,
363
- **kwargs,
364
- ):
365
- """
366
- Performs voice conversion on a batch of input audio files.
367
-
368
- Args:
369
- audio_input_paths (str): List of paths to the input audio files.
370
- audio_output_path (str): Path to the output audio file.
371
- resample_sr (int, optional): Resample sampling rate. Default is 0.
372
- sid (int, optional): Speaker ID. Default is 0.
373
- **kwargs: Additional keyword arguments.
374
- """
375
- pid = os.getpid()
376
- try:
377
- with open(
378
- os.path.join(now_dir, "assets", "infer_pid.txt"), "w"
379
- ) as pid_file:
380
- pid_file.write(str(pid))
381
- start_time = time.time()
382
- print(f"Converting audio batch '{audio_input_paths}'...")
383
- audio_files = [
384
- f
385
- for f in os.listdir(audio_input_paths)
386
- if f.endswith(
387
- (
388
- "wav",
389
- "mp3",
390
- "flac",
391
- "ogg",
392
- "opus",
393
- "m4a",
394
- "mp4",
395
- "aac",
396
- "alac",
397
- "wma",
398
- "aiff",
399
- "webm",
400
- "ac3",
401
- )
402
- )
403
- ]
404
- print(f"Detected {len(audio_files)} audio files for inference.")
405
- for a in audio_files:
406
- new_input = os.path.join(audio_input_paths, a)
407
- new_output = os.path.splitext(a)[0] + "_output.wav"
408
- new_output = os.path.join(audio_output_path, new_output)
409
- if os.path.exists(new_output):
410
- continue
411
- self.convert_audio(
412
- audio_input_path=new_input,
413
- audio_output_path=new_output,
414
- **kwargs,
415
- )
416
- print(f"Conversion completed at '{audio_input_paths}'.")
417
- elapsed_time = time.time() - start_time
418
- print(f"Batch conversion completed in {elapsed_time:.2f} seconds.")
419
- except Exception as error:
420
- print(f"An error occurred during audio batch conversion: {error}")
421
- print(traceback.format_exc())
422
- finally:
423
- os.remove(os.path.join(now_dir, "assets", "infer_pid.txt"))
424
-
425
  def get_vc(self, weight_root, sid):
426
  """
427
  Loads the voice conversion model and sets up the pipeline.
@@ -447,8 +380,8 @@ class VoiceConverter:
447
  Cleans up the model and releases resources.
448
  """
449
  if self.hubert_model is not None:
450
- del self.net_g, self.n_spk, self.vc, self.hubert_model, self.tgt_sr
451
- self.hubert_model = self.net_g = self.n_spk = self.vc = self.tgt_sr = None
452
  if torch.cuda.is_available():
453
  torch.cuda.empty_cache()
454
 
@@ -500,4 +433,3 @@ class VoiceConverter:
500
  """
501
  if self.cpt is not None:
502
  self.vc = VC(self.tgt_sr, self.config)
503
- self.n_spk = self.cpt["config"][-3]
 
58
  self.vc = None # Voice conversion pipeline instance
59
  self.cpt = None # Checkpoint for loading model weights
60
  self.version = None # Model version
 
61
  self.use_f0 = None # Whether the model uses F0
62
  self.loaded_model = None
63
 
 
355
  print(f"An error occurred during audio conversion: {error}")
356
  print(traceback.format_exc())
357
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  def get_vc(self, weight_root, sid):
359
  """
360
  Loads the voice conversion model and sets up the pipeline.
 
380
  Cleans up the model and releases resources.
381
  """
382
  if self.hubert_model is not None:
383
+ del self.net_g, self.vc, self.hubert_model, self.tgt_sr
384
+ self.hubert_model = self.net_g = self.vc = self.tgt_sr = None
385
  if torch.cuda.is_available():
386
  torch.cuda.empty_cache()
387
 
 
433
  """
434
  if self.cpt is not None:
435
  self.vc = VC(self.tgt_sr, self.config)
 
rvc/infer/pipeline.py CHANGED
@@ -145,7 +145,6 @@ class Pipeline:
145
  self.t_query = self.sample_rate * self.x_query
146
  self.t_center = self.sample_rate * self.x_center
147
  self.t_max = self.sample_rate * self.x_max
148
- self.time_step = self.window / self.sample_rate * 1000
149
  self.f0_min = 50
150
  self.f0_max = 1100
151
  self.f0_mel_min = 1127 * np.log(1 + self.f0_min / 700)
 
145
  self.t_query = self.sample_rate * self.x_query
146
  self.t_center = self.sample_rate * self.x_center
147
  self.t_max = self.sample_rate * self.x_max
 
148
  self.f0_min = 50
149
  self.f0_max = 1100
150
  self.f0_mel_min = 1127 * np.log(1 + self.f0_min / 700)
rvc/lib/algorithm/commons.py CHANGED
@@ -40,23 +40,6 @@ def convert_pad_shape(pad_shape):
40
  return pad_shape
41
 
42
 
43
- def kl_divergence(m_p, logs_p, m_q, logs_q):
44
- """
45
- Calculate the KL divergence between two distributions.
46
-
47
- Args:
48
- m_p: The mean of the first distribution.
49
- logs_p: The log of the standard deviation of the first distribution.
50
- m_q: The mean of the second distribution.
51
- logs_q: The log of the standard deviation of the second distribution.
52
- """
53
- kl = (logs_q - logs_p) - 0.5
54
- kl += (
55
- 0.5 * (torch.exp(2.0 * logs_p) + ((m_p - m_q) ** 2)) * torch.exp(-2.0 * logs_q)
56
- )
57
- return kl
58
-
59
-
60
  def slice_segments(
61
  x: torch.Tensor, ids_str: torch.Tensor, segment_size: int = 4, dim: int = 2
62
  ):
@@ -103,42 +86,6 @@ def rand_slice_segments(x, x_lengths=None, segment_size=4):
103
  return ret, ids_str
104
 
105
 
106
- def get_timing_signal_1d(length, channels, min_timescale=1.0, max_timescale=1.0e4):
107
- """
108
- Generate a 1D timing signal.
109
-
110
- Args:
111
- length: The length of the signal.
112
- channels: The number of channels of the signal.
113
- min_timescale: The minimum timescale.
114
- max_timescale: The maximum timescale.
115
- """
116
- position = torch.arange(length, dtype=torch.float)
117
- num_timescales = channels // 2
118
- log_timescale_increment = math.log(float(max_timescale) / float(min_timescale)) / (
119
- num_timescales - 1
120
- )
121
- inv_timescales = min_timescale * torch.exp(
122
- torch.arange(num_timescales, dtype=torch.float) * -log_timescale_increment
123
- )
124
- scaled_time = position.unsqueeze(0) * inv_timescales.unsqueeze(1)
125
- signal = torch.cat([torch.sin(scaled_time), torch.cos(scaled_time)], 0)
126
- signal = torch.nn.functional.pad(signal, [0, 0, 0, channels % 2])
127
- signal = signal.view(1, channels, length)
128
- return signal
129
-
130
-
131
- def subsequent_mask(length):
132
- """
133
- Generate a subsequent mask.
134
-
135
- Args:
136
- length: The length of the sequence.
137
- """
138
- mask = torch.tril(torch.ones(length, length)).unsqueeze(0).unsqueeze(0)
139
- return mask
140
-
141
-
142
  @torch.jit.script
143
  def fused_add_tanh_sigmoid_multiply(input_a, input_b, n_channels):
144
  """
 
40
  return pad_shape
41
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  def slice_segments(
44
  x: torch.Tensor, ids_str: torch.Tensor, segment_size: int = 4, dim: int = 2
45
  ):
 
86
  return ret, ids_str
87
 
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  @torch.jit.script
90
  def fused_add_tanh_sigmoid_multiply(input_a, input_b, n_channels):
91
  """
rvc/lib/algorithm/generators.py CHANGED
@@ -127,7 +127,6 @@ class SineGen(torch.nn.Module):
127
  sine_amp=0.1,
128
  noise_std=0.003,
129
  voiced_threshold=0,
130
- flag_for_pulse=False,
131
  ):
132
  super(SineGen, self).__init__()
133
  self.sine_amp = sine_amp
 
127
  sine_amp=0.1,
128
  noise_std=0.003,
129
  voiced_threshold=0,
 
130
  ):
131
  super(SineGen, self).__init__()
132
  self.sine_amp = sine_amp
rvc/lib/algorithm/nsf.py CHANGED
@@ -84,7 +84,6 @@ class GeneratorNSF(torch.nn.Module):
84
 
85
  self.num_kernels = len(resblock_kernel_sizes)
86
  self.num_upsamples = len(upsample_rates)
87
- self.f0_upsamp = torch.nn.Upsample(scale_factor=math.prod(upsample_rates))
88
  self.m_source = SourceModuleHnNSF(
89
  sample_rate=sr, harmonic_num=0, is_half=is_half
90
  )
 
84
 
85
  self.num_kernels = len(resblock_kernel_sizes)
86
  self.num_upsamples = len(upsample_rates)
 
87
  self.m_source = SourceModuleHnNSF(
88
  sample_rate=sr, harmonic_num=0, is_half=is_half
89
  )
rvc/lib/predictors/FCPE.py CHANGED
@@ -60,22 +60,10 @@ def load_wav_to_torch(full_path, target_sr=None, return_empty_on_exception=False
60
  return data, sample_rate
61
 
62
 
63
- def dynamic_range_compression(x, C=1, clip_val=1e-5):
64
- return np.log(np.clip(x, a_min=clip_val, a_max=None) * C)
65
-
66
-
67
- def dynamic_range_decompression(x, C=1):
68
- return np.exp(x) / C
69
-
70
-
71
  def dynamic_range_compression_torch(x, C=1, clip_val=1e-5):
72
  return torch.log(torch.clamp(x, min=clip_val) * C)
73
 
74
 
75
- def dynamic_range_decompression_torch(x, C=1):
76
- return torch.exp(x) / C
77
-
78
-
79
  class STFT:
80
  def __init__(
81
  self,
@@ -235,10 +223,6 @@ def default(val, d):
235
  return val if exists(val) else d
236
 
237
 
238
- def cast_tuple(val):
239
- return (val,) if not isinstance(val, tuple) else val
240
-
241
-
242
  class PCmer(nn.Module):
243
  def __init__(
244
  self,
@@ -469,7 +453,6 @@ class SelfAttention(nn.Module):
469
  local_heads=0,
470
  local_window_size=256,
471
  nb_features=None,
472
- feature_redraw_interval=1000,
473
  generalized_attention=False,
474
  kernel_fn=nn.ReLU(),
475
  qr_uniform_q=False,
@@ -521,8 +504,6 @@ class SelfAttention(nn.Module):
521
  context=None,
522
  mask=None,
523
  context_mask=None,
524
- name=None,
525
- inference=False,
526
  **kwargs,
527
  ):
528
  _, _, _, h, gh = *x.shape, self.heads, self.global_heads
@@ -827,9 +808,6 @@ class F0Predictor(object):
827
  def compute_f0(self, wav, p_len):
828
  pass
829
 
830
- def compute_f0_uv(self, wav, p_len):
831
- pass
832
-
833
 
834
  class FCPEF0Predictor(F0Predictor):
835
  def __init__(
@@ -908,13 +886,3 @@ class FCPEF0Predictor(F0Predictor):
908
  f0.cpu().numpy() if p_len is None else np.zeros(p_len)
909
  )
910
  return self.post_process(x, self.sample_rate, f0, p_len)[0]
911
-
912
- def compute_f0_uv(self, wav, p_len=None):
913
- x = torch.FloatTensor(wav).to(self.dtype).to(self.device)
914
- p_len = x.shape[0] // self.hop_length if p_len is None else p_len
915
- f0 = self.fcpe(x, sr=self.sample_rate, threshold=self.threshold)[0, :, 0]
916
- if torch.all(f0 == 0):
917
- return f0.cpu().numpy() if p_len is None else np.zeros(p_len), (
918
- f0.cpu().numpy() if p_len is None else np.zeros(p_len)
919
- )
920
- return self.post_process(x, self.sample_rate, f0, p_len)
 
60
  return data, sample_rate
61
 
62
 
 
 
 
 
 
 
 
 
63
  def dynamic_range_compression_torch(x, C=1, clip_val=1e-5):
64
  return torch.log(torch.clamp(x, min=clip_val) * C)
65
 
66
 
 
 
 
 
67
  class STFT:
68
  def __init__(
69
  self,
 
223
  return val if exists(val) else d
224
 
225
 
 
 
 
 
226
  class PCmer(nn.Module):
227
  def __init__(
228
  self,
 
453
  local_heads=0,
454
  local_window_size=256,
455
  nb_features=None,
 
456
  generalized_attention=False,
457
  kernel_fn=nn.ReLU(),
458
  qr_uniform_q=False,
 
504
  context=None,
505
  mask=None,
506
  context_mask=None,
 
 
507
  **kwargs,
508
  ):
509
  _, _, _, h, gh = *x.shape, self.heads, self.global_heads
 
808
  def compute_f0(self, wav, p_len):
809
  pass
810
 
 
 
 
811
 
812
  class FCPEF0Predictor(F0Predictor):
813
  def __init__(
 
886
  f0.cpu().numpy() if p_len is None else np.zeros(p_len)
887
  )
888
  return self.post_process(x, self.sample_rate, f0, p_len)[0]
 
 
 
 
 
 
 
 
 
 
rvc/lib/predictors/RMVPE.py CHANGED
@@ -134,7 +134,6 @@ class Encoder(nn.Module):
134
  in_channels = out_channels
135
  out_channels *= 2
136
  in_size //= 2
137
- self.out_size = in_size
138
  self.out_channel = out_channels
139
 
140
  def forward(self, x: torch.Tensor):
 
134
  in_channels = out_channels
135
  out_channels *= 2
136
  in_size //= 2
 
137
  self.out_channel = out_channels
138
 
139
  def forward(self, x: torch.Tensor):
rvc/lib/tools/gdown.py CHANGED
@@ -24,10 +24,6 @@ class FileURLRetrievalError(Exception):
24
  pass
25
 
26
 
27
- class FolderContentsMaximumLimitError(Exception):
28
- pass
29
-
30
-
31
  def parse_url(url, warning=True):
32
  """Parse URLs especially for Google Drive links.
33
 
@@ -126,7 +122,6 @@ def _get_session(proxy, use_cookies, return_cookies_file=False):
126
  )
127
 
128
  if proxy is not None:
129
- sess.proxies = {"http": proxy, "https": proxy}
130
  print("Using proxy:", proxy, file=sys.stderr)
131
 
132
  cookies_file = os.path.join(HOME, ".cache/gdown/cookies.json")
 
24
  pass
25
 
26
 
 
 
 
 
27
  def parse_url(url, warning=True):
28
  """Parse URLs especially for Google Drive links.
29
 
 
122
  )
123
 
124
  if proxy is not None:
 
125
  print("Using proxy:", proxy, file=sys.stderr)
126
 
127
  cookies_file = os.path.join(HOME, ".cache/gdown/cookies.json")
rvc/lib/tools/model_download.py CHANGED
@@ -42,20 +42,6 @@ def search_pth_index(folder):
42
  return pth_paths, index_paths
43
 
44
 
45
- def get_mediafire_download_link(url):
46
- response = requests.get(url)
47
- response.raise_for_status()
48
- soup = BeautifulSoup(response.text, "html.parser")
49
- download_button = soup.find(
50
- "a", {"class": "input popsok", "aria-label": "Download file"}
51
- )
52
- if download_button:
53
- download_link = download_button.get("href")
54
- return download_link
55
- else:
56
- return None
57
-
58
-
59
  def download_from_url(url):
60
  os.makedirs(zips_path, exist_ok=True)
61
  if url != "":
@@ -271,14 +257,6 @@ def extract_and_show_progress(zipfile_path, unzips_path):
271
  return False
272
 
273
 
274
- def unzip_file(zip_path, zip_file_name):
275
- zip_file_path = os.path.join(zip_path, zip_file_name + ".zip")
276
- extract_path = os.path.join(file_path, zip_file_name)
277
- with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
278
- zip_ref.extractall(extract_path)
279
- os.remove(zip_file_path)
280
-
281
-
282
  def model_download_pipeline(url: str):
283
  try:
284
  verify = download_from_url(url)
 
42
  return pth_paths, index_paths
43
 
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  def download_from_url(url):
46
  os.makedirs(zips_path, exist_ok=True)
47
  if url != "":
 
257
  return False
258
 
259
 
 
 
 
 
 
 
 
 
260
  def model_download_pipeline(url: str):
261
  try:
262
  verify = download_from_url(url)
rvc/lib/tools/prerequisites_download.py CHANGED
@@ -1,7 +1,10 @@
1
  import os
2
  from concurrent.futures import ThreadPoolExecutor
3
- from tqdm import tqdm
4
  import requests
 
 
 
5
 
6
  url_base = "https://huggingface.co/IAHispano/Applio/resolve/main/Resources"
7
 
@@ -45,9 +48,6 @@ pretraineds_v2_list = [
45
  ]
46
  models_list = [("predictors/", ["rmvpe.pt", "fcpe.pt"])]
47
  embedders_list = [("embedders/contentvec/", ["pytorch_model.bin", "config.json"])]
48
- executables_list = [
49
- ("", ["ffmpeg.exe", "ffprobe.exe"]),
50
- ]
51
 
52
  folder_mapping_list = {
53
  "pretrained_v1/": "rvc/models/pretraineds/pretrained_v1/",
@@ -58,7 +58,7 @@ folder_mapping_list = {
58
  }
59
 
60
 
61
- def get_file_size_if_missing(file_list):
62
  """
63
  Calculate the total size of files to be downloaded only if they do not exist locally.
64
  """
@@ -74,7 +74,7 @@ def get_file_size_if_missing(file_list):
74
  return total_size
75
 
76
 
77
- def download_file(url, destination_path, global_bar):
78
  """
79
  Download a file from the given URL to the specified destination path,
80
  updating the global progress bar as data is downloaded.
@@ -91,7 +91,7 @@ def download_file(url, destination_path, global_bar):
91
  global_bar.update(len(data))
92
 
93
 
94
- def download_mapping_files(file_mapping_list, global_bar):
95
  """
96
  Download all files in the provided file mapping list using a thread pool executor,
97
  and update the global progress bar as downloads progress.
@@ -104,16 +104,14 @@ def download_mapping_files(file_mapping_list, global_bar):
104
  destination_path = os.path.join(local_folder, file)
105
  if not os.path.exists(destination_path):
106
  url = f"{url_base}/{remote_folder}{file}"
107
- futures.append(
108
- executor.submit(
109
- download_file, url, destination_path, global_bar
110
- )
111
- )
112
  for future in futures:
113
  future.result()
114
 
115
 
116
- def split_pretraineds(pretrained_list):
 
 
117
  f0_list = []
118
  non_f0_list = []
119
  for folder, files in pretrained_list:
@@ -126,22 +124,18 @@ def split_pretraineds(pretrained_list):
126
  return f0_list, non_f0_list
127
 
128
 
129
- pretraineds_v1_f0_list, pretraineds_v1_nof0_list = split_pretraineds(
130
- pretraineds_v1_list
131
- )
132
- pretraineds_v2_f0_list, pretraineds_v2_nof0_list = split_pretraineds(
133
- pretraineds_v2_list
134
- )
135
 
136
 
137
  def calculate_total_size(
138
- pretraineds_v1_f0,
139
- pretraineds_v1_nof0,
140
- pretraineds_v2_f0,
141
- pretraineds_v2_nof0,
142
- models,
143
- exe,
144
- ):
145
  """
146
  Calculate the total size of all files to be downloaded based on selected categories.
147
  """
@@ -149,23 +143,23 @@ def calculate_total_size(
149
  if models:
150
  total_size += get_file_size_if_missing(models_list)
151
  total_size += get_file_size_if_missing(embedders_list)
152
- if exe and os.name == "nt":
153
- total_size += get_file_size_if_missing(executables_list)
154
  total_size += get_file_size_if_missing(pretraineds_v1_f0)
155
  total_size += get_file_size_if_missing(pretraineds_v1_nof0)
156
  total_size += get_file_size_if_missing(pretraineds_v2_f0)
157
  total_size += get_file_size_if_missing(pretraineds_v2_nof0)
 
 
158
  return total_size
159
 
160
 
161
  def prequisites_download_pipeline(
162
- pretraineds_v1_f0,
163
- pretraineds_v1_nof0,
164
- pretraineds_v2_f0,
165
- pretraineds_v2_nof0,
166
- models,
167
- exe,
168
- ):
169
  """
170
  Manage the download pipeline for different categories of files.
171
  """
@@ -175,21 +169,14 @@ def prequisites_download_pipeline(
175
  pretraineds_v2_f0_list if pretraineds_v2_f0 else [],
176
  pretraineds_v2_nof0_list if pretraineds_v2_nof0 else [],
177
  models,
178
- exe,
179
  )
180
 
181
  if total_size > 0:
182
- with tqdm(
183
- total=total_size, unit="iB", unit_scale=True, desc="Downloading all files"
184
- ) as global_bar:
185
  if models:
186
  download_mapping_files(models_list, global_bar)
187
  download_mapping_files(embedders_list, global_bar)
188
- if exe:
189
- if os.name == "nt":
190
- download_mapping_files(executables_list, global_bar)
191
- else:
192
- print("No executables needed")
193
  if pretraineds_v1_f0:
194
  download_mapping_files(pretraineds_v1_f0_list, global_bar)
195
  if pretraineds_v1_nof0:
@@ -198,5 +185,7 @@ def prequisites_download_pipeline(
198
  download_mapping_files(pretraineds_v2_f0_list, global_bar)
199
  if pretraineds_v2_nof0:
200
  download_mapping_files(pretraineds_v2_nof0_list, global_bar)
 
 
201
  else:
202
  pass
 
1
  import os
2
  from concurrent.futures import ThreadPoolExecutor
3
+
4
  import requests
5
+ from tqdm import tqdm
6
+
7
+ from tts_service.voices import voice_manager
8
 
9
  url_base = "https://huggingface.co/IAHispano/Applio/resolve/main/Resources"
10
 
 
48
  ]
49
  models_list = [("predictors/", ["rmvpe.pt", "fcpe.pt"])]
50
  embedders_list = [("embedders/contentvec/", ["pytorch_model.bin", "config.json"])]
 
 
 
51
 
52
  folder_mapping_list = {
53
  "pretrained_v1/": "rvc/models/pretraineds/pretrained_v1/",
 
58
  }
59
 
60
 
61
+ def get_file_size_if_missing(file_list: list[tuple[str, list[str]]]) -> int:
62
  """
63
  Calculate the total size of files to be downloaded only if they do not exist locally.
64
  """
 
74
  return total_size
75
 
76
 
77
+ def download_file(url: str, destination_path: str, global_bar: tqdm) -> None:
78
  """
79
  Download a file from the given URL to the specified destination path,
80
  updating the global progress bar as data is downloaded.
 
91
  global_bar.update(len(data))
92
 
93
 
94
+ def download_mapping_files(file_mapping_list: list[tuple[str, list[str]]], global_bar: tqdm) -> None:
95
  """
96
  Download all files in the provided file mapping list using a thread pool executor,
97
  and update the global progress bar as downloads progress.
 
104
  destination_path = os.path.join(local_folder, file)
105
  if not os.path.exists(destination_path):
106
  url = f"{url_base}/{remote_folder}{file}"
107
+ futures.append(executor.submit(download_file, url, destination_path, global_bar))
 
 
 
 
108
  for future in futures:
109
  future.result()
110
 
111
 
112
+ def split_pretraineds(
113
+ pretrained_list: list[tuple[str, list[str]]],
114
+ ) -> tuple[list[tuple[str, list[str]]], list[tuple[str, list[str]]]]:
115
  f0_list = []
116
  non_f0_list = []
117
  for folder, files in pretrained_list:
 
124
  return f0_list, non_f0_list
125
 
126
 
127
+ pretraineds_v1_f0_list, pretraineds_v1_nof0_list = split_pretraineds(pretraineds_v1_list)
128
+ pretraineds_v2_f0_list, pretraineds_v2_nof0_list = split_pretraineds(pretraineds_v2_list)
 
 
 
 
129
 
130
 
131
  def calculate_total_size(
132
+ pretraineds_v1_f0: list[tuple[str, list[str]]],
133
+ pretraineds_v1_nof0: list[tuple[str, list[str]]],
134
+ pretraineds_v2_f0: list[tuple[str, list[str]]],
135
+ pretraineds_v2_nof0: list[tuple[str, list[str]]],
136
+ models: bool,
137
+ voices: bool,
138
+ ) -> int:
139
  """
140
  Calculate the total size of all files to be downloaded based on selected categories.
141
  """
 
143
  if models:
144
  total_size += get_file_size_if_missing(models_list)
145
  total_size += get_file_size_if_missing(embedders_list)
 
 
146
  total_size += get_file_size_if_missing(pretraineds_v1_f0)
147
  total_size += get_file_size_if_missing(pretraineds_v1_nof0)
148
  total_size += get_file_size_if_missing(pretraineds_v2_f0)
149
  total_size += get_file_size_if_missing(pretraineds_v2_nof0)
150
+ if voices:
151
+ total_size += voice_manager.get_voices_size_if_missing()
152
  return total_size
153
 
154
 
155
  def prequisites_download_pipeline(
156
+ pretraineds_v1_f0: bool,
157
+ pretraineds_v1_nof0: bool,
158
+ pretraineds_v2_f0: bool,
159
+ pretraineds_v2_nof0: bool,
160
+ models: bool,
161
+ voices: bool,
162
+ ) -> None:
163
  """
164
  Manage the download pipeline for different categories of files.
165
  """
 
169
  pretraineds_v2_f0_list if pretraineds_v2_f0 else [],
170
  pretraineds_v2_nof0_list if pretraineds_v2_nof0 else [],
171
  models,
172
+ voices,
173
  )
174
 
175
  if total_size > 0:
176
+ with tqdm(total=total_size, unit="iB", unit_scale=True, desc="Downloading all files") as global_bar:
 
 
177
  if models:
178
  download_mapping_files(models_list, global_bar)
179
  download_mapping_files(embedders_list, global_bar)
 
 
 
 
 
180
  if pretraineds_v1_f0:
181
  download_mapping_files(pretraineds_v1_f0_list, global_bar)
182
  if pretraineds_v1_nof0:
 
185
  download_mapping_files(pretraineds_v2_f0_list, global_bar)
186
  if pretraineds_v2_nof0:
187
  download_mapping_files(pretraineds_v2_nof0_list, global_bar)
188
+ if voices:
189
+ voice_manager.download_voice_files(global_bar)
190
  else:
191
  pass
rvc/lib/utils.py CHANGED
@@ -5,9 +5,6 @@ import numpy as np
5
  import re
6
  import unicodedata
7
  import wget
8
- import subprocess
9
- from pydub import AudioSegment
10
- import tempfile
11
  from torch import nn
12
 
13
  import logging
@@ -35,20 +32,6 @@ class HubertModelWithFinalProj(HubertModel):
35
  self.final_proj = nn.Linear(config.hidden_size, config.classifier_proj_size)
36
 
37
 
38
- def load_audio(file, sample_rate):
39
- try:
40
- file = file.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
41
- audio, sr = sf.read(file)
42
- if len(audio.shape) > 1:
43
- audio = librosa.to_mono(audio.T)
44
- if sr != sample_rate:
45
- audio = librosa.resample(audio, orig_sr=sr, target_sr=sample_rate)
46
- except Exception as error:
47
- raise RuntimeError(f"An error occurred loading the audio: {error}")
48
-
49
- return audio.flatten()
50
-
51
-
52
  def load_audio_infer(
53
  file,
54
  sample_rate,
 
5
  import re
6
  import unicodedata
7
  import wget
 
 
 
8
  from torch import nn
9
 
10
  import logging
 
32
  self.final_proj = nn.Linear(config.hidden_size, config.classifier_proj_size)
33
 
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  def load_audio_infer(
36
  file,
37
  sample_rate,
rvc/train/mel_processing.py CHANGED
@@ -15,17 +15,6 @@ def dynamic_range_compression_torch(x, C=1, clip_val=1e-5):
15
  return torch.log(torch.clamp(x, min=clip_val) * C)
16
 
17
 
18
- def dynamic_range_decompression_torch(x, C=1):
19
- """
20
- Dynamic range decompression using exp.
21
-
22
- Args:
23
- x (torch.Tensor): Input tensor.
24
- C (float, optional): Scaling factor. Defaults to 1.
25
- """
26
- return torch.exp(x) / C
27
-
28
-
29
  def spectral_normalize_torch(magnitudes):
30
  """
31
  Spectral normalization using dynamic range compression.
@@ -36,16 +25,6 @@ def spectral_normalize_torch(magnitudes):
36
  return dynamic_range_compression_torch(magnitudes)
37
 
38
 
39
- def spectral_de_normalize_torch(magnitudes):
40
- """
41
- Spectral de-normalization using dynamic range decompression.
42
-
43
- Args:
44
- magnitudes (torch.Tensor): Normalized spectrogram.
45
- """
46
- return dynamic_range_decompression_torch(magnitudes)
47
-
48
-
49
  mel_basis = {}
50
  hann_window = {}
51
 
 
15
  return torch.log(torch.clamp(x, min=clip_val) * C)
16
 
17
 
 
 
 
 
 
 
 
 
 
 
 
18
  def spectral_normalize_torch(magnitudes):
19
  """
20
  Spectral normalization using dynamic range compression.
 
25
  return dynamic_range_compression_torch(magnitudes)
26
 
27
 
 
 
 
 
 
 
 
 
 
 
28
  mel_basis = {}
29
  hann_window = {}
30
 
rvc/train/process/extract_small_model.py CHANGED
@@ -19,165 +19,3 @@ def replace_keys_in_dict(d, old_key_part, new_key_part):
19
  value = replace_keys_in_dict(value, old_key_part, new_key_part)
20
  updated_dict[new_key] = value
21
  return updated_dict
22
-
23
-
24
- def extract_small_model(
25
- path: str,
26
- name: str,
27
- sr: int,
28
- pitch_guidance: bool,
29
- version: str,
30
- epoch: int,
31
- step: int,
32
- ):
33
- try:
34
- ckpt = torch.load(path, map_location="cpu")
35
- pth_file = f"{name}.pth"
36
- pth_file_old_version_path = os.path.join("logs", f"{pth_file}_old_version.pth")
37
- opt = OrderedDict(
38
- weight={
39
- key: value.half() for key, value in ckpt.items() if "enc_q" not in key
40
- }
41
- )
42
- if "model" in ckpt:
43
- ckpt = ckpt["model"]
44
- opt = OrderedDict()
45
- opt["weight"] = {}
46
- for key in ckpt.keys():
47
- if "enc_q" in key:
48
- continue
49
- opt["weight"][key] = ckpt[key].half()
50
- if sr == "40000":
51
- opt["config"] = [
52
- 1025,
53
- 32,
54
- 192,
55
- 192,
56
- 768,
57
- 2,
58
- 6,
59
- 3,
60
- 0,
61
- "1",
62
- [3, 7, 11],
63
- [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
64
- [10, 10, 2, 2],
65
- 512,
66
- [16, 16, 4, 4],
67
- 109,
68
- 256,
69
- 40000,
70
- ]
71
- elif sr == "48000":
72
- if version == "v1":
73
- opt["config"] = [
74
- 1025,
75
- 32,
76
- 192,
77
- 192,
78
- 768,
79
- 2,
80
- 6,
81
- 3,
82
- 0,
83
- "1",
84
- [3, 7, 11],
85
- [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
86
- [10, 6, 2, 2, 2],
87
- 512,
88
- [16, 16, 4, 4, 4],
89
- 109,
90
- 256,
91
- 48000,
92
- ]
93
- else:
94
- opt["config"] = [
95
- 1025,
96
- 32,
97
- 192,
98
- 192,
99
- 768,
100
- 2,
101
- 6,
102
- 3,
103
- 0,
104
- "1",
105
- [3, 7, 11],
106
- [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
107
- [12, 10, 2, 2],
108
- 512,
109
- [24, 20, 4, 4],
110
- 109,
111
- 256,
112
- 48000,
113
- ]
114
- elif sr == "32000":
115
- if version == "v1":
116
- opt["config"] = [
117
- 513,
118
- 32,
119
- 192,
120
- 192,
121
- 768,
122
- 2,
123
- 6,
124
- 3,
125
- 0,
126
- "1",
127
- [3, 7, 11],
128
- [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
129
- [10, 4, 2, 2, 2],
130
- 512,
131
- [16, 16, 4, 4, 4],
132
- 109,
133
- 256,
134
- 32000,
135
- ]
136
- else:
137
- opt["config"] = [
138
- 513,
139
- 32,
140
- 192,
141
- 192,
142
- 768,
143
- 2,
144
- 6,
145
- 3,
146
- 0,
147
- "1",
148
- [3, 7, 11],
149
- [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
150
- [10, 8, 2, 2],
151
- 512,
152
- [20, 16, 4, 4],
153
- 109,
154
- 256,
155
- 32000,
156
- ]
157
-
158
- opt["epoch"] = epoch
159
- opt["step"] = step
160
- opt["sr"] = sr
161
- opt["f0"] = int(pitch_guidance)
162
- opt["version"] = version
163
- opt["creation_date"] = datetime.datetime.now().isoformat()
164
-
165
- hash_input = f"{str(ckpt)} {epoch} {step} {datetime.datetime.now().isoformat()}"
166
- model_hash = hashlib.sha256(hash_input.encode()).hexdigest()
167
- opt["model_hash"] = model_hash
168
-
169
- model = torch.load(pth_file_old_version_path, map_location=torch.device("cpu"))
170
- torch.save(
171
- replace_keys_in_dict(
172
- replace_keys_in_dict(
173
- model, ".parametrizations.weight.original1", ".weight_v"
174
- ),
175
- ".parametrizations.weight.original0",
176
- ".weight_g",
177
- ),
178
- pth_file_old_version_path,
179
- )
180
- os.remove(pth_file_old_version_path)
181
- os.rename(pth_file_old_version_path, pth_file)
182
- except Exception as error:
183
- print(f"An error occurred extracting the model: {error}")
 
19
  value = replace_keys_in_dict(value, old_key_part, new_key_part)
20
  updated_dict[new_key] = value
21
  return updated_dict
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
rvc/train/process/model_blender.py CHANGED
@@ -12,57 +12,3 @@ def extract(ckpt):
12
  continue
13
  opt["weight"][key] = a[key]
14
  return opt
15
-
16
-
17
- def model_blender(name, path1, path2, ratio):
18
- try:
19
- message = f"Model {path1} and {path2} are merged with alpha {ratio}."
20
- ckpt1 = torch.load(path1, map_location="cpu")
21
- ckpt2 = torch.load(path2, map_location="cpu")
22
-
23
- if ckpt1["sr"] != ckpt2["sr"]:
24
- return "The sample rates of the two models are not the same."
25
-
26
- cfg = ckpt1["config"]
27
- cfg_f0 = ckpt1["f0"]
28
- cfg_version = ckpt1["version"]
29
- cfg_sr = ckpt1["sr"]
30
-
31
- if "model" in ckpt1:
32
- ckpt1 = extract(ckpt1)
33
- else:
34
- ckpt1 = ckpt1["weight"]
35
- if "model" in ckpt2:
36
- ckpt2 = extract(ckpt2)
37
- else:
38
- ckpt2 = ckpt2["weight"]
39
-
40
- if sorted(list(ckpt1.keys())) != sorted(list(ckpt2.keys())):
41
- return "Fail to merge the models. The model architectures are not the same."
42
-
43
- opt = OrderedDict()
44
- opt["weight"] = {}
45
- for key in ckpt1.keys():
46
- if key == "emb_g.weight" and ckpt1[key].shape != ckpt2[key].shape:
47
- min_shape0 = min(ckpt1[key].shape[0], ckpt2[key].shape[0])
48
- opt["weight"][key] = (
49
- ratio * (ckpt1[key][:min_shape0].float())
50
- + (1 - ratio) * (ckpt2[key][:min_shape0].float())
51
- ).half()
52
- else:
53
- opt["weight"][key] = (
54
- ratio * (ckpt1[key].float()) + (1 - ratio) * (ckpt2[key].float())
55
- ).half()
56
-
57
- opt["config"] = cfg
58
- opt["sr"] = cfg_sr
59
- opt["f0"] = cfg_f0
60
- opt["version"] = cfg_version
61
- opt["info"] = message
62
-
63
- torch.save(opt, os.path.join("logs", f"{name}.pth"))
64
- print(message)
65
- return message, os.path.join("logs", f"{name}.pth")
66
- except Exception as error:
67
- print(f"An error occurred blending the models: {error}")
68
- return error
 
12
  continue
13
  opt["weight"][key] = a[key]
14
  return opt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
rvc/train/train.py CHANGED
@@ -27,7 +27,7 @@ sys.path.append(os.path.join(now_dir))
27
  # Zluda hijack
28
  import rvc.lib.zluda
29
 
30
- from utils import (
31
  HParams,
32
  plot_spectrogram_to_numpy,
33
  summarize,
@@ -37,13 +37,13 @@ from utils import (
37
  load_wav_to_torch,
38
  )
39
 
40
- from losses import (
41
  discriminator_loss,
42
  feature_loss,
43
  generator_loss,
44
  kl_loss,
45
  )
46
- from mel_processing import mel_spectrogram_torch, spec_to_mel_torch
47
 
48
  from rvc.train.process.extract_model import extract_model
49
 
@@ -56,7 +56,6 @@ total_epoch = int(sys.argv[3])
56
  pretrainG = sys.argv[4]
57
  pretrainD = sys.argv[5]
58
  version = sys.argv[6]
59
- gpus = sys.argv[7]
60
  batch_size = int(sys.argv[8])
61
  sample_rate = int(sys.argv[9])
62
  pitch_guidance = strtobool(sys.argv[10])
@@ -70,7 +69,6 @@ cleanup = strtobool(sys.argv[16])
70
  current_dir = os.getcwd()
71
  experiment_dir = os.path.join(current_dir, "logs", model_name)
72
  config_save_path = os.path.join(experiment_dir, "config.json")
73
- dataset_path = os.path.join(experiment_dir, "sliced_audios")
74
 
75
  with open(config_save_path, "r") as f:
76
  config = json.load(f)
@@ -81,8 +79,6 @@ torch.backends.cudnn.deterministic = False
81
  torch.backends.cudnn.benchmark = False
82
 
83
  global_step = 0
84
- last_loss_gen_all = 0
85
- overtrain_save_epoch = 0
86
  loss_gen_history = []
87
  smoothed_loss_gen_history = []
88
  loss_disc_history = []
@@ -139,7 +135,7 @@ def main():
139
  """
140
  Main function to start the training process.
141
  """
142
- 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
143
 
144
  os.environ["MASTER_ADDR"] = "localhost"
145
  os.environ["MASTER_PORT"] = str(randint(20000, 55555))
@@ -322,7 +318,7 @@ def run(
322
  torch.cuda.set_device(rank)
323
 
324
  # Create datasets and dataloaders
325
- from data_utils import (
326
  DistributedBucketSampler,
327
  TextAudioCollateMultiNSFsid,
328
  TextAudioLoaderMultiNSFsid,
@@ -533,7 +529,6 @@ def train_and_evaluate(
533
 
534
  if epoch == 1:
535
  lowest_value = {"step": 0, "value": float("inf"), "epoch": 0}
536
- last_loss_gen_all = 0.0
537
  consecutive_increases_gen = 0
538
  consecutive_increases_disc = 0
539
 
@@ -888,7 +883,6 @@ def train_and_evaluate(
888
  + f" | Number of epochs remaining for overtraining: g/total: {remaining_epochs_gen} d/total: {remaining_epochs_disc} | smoothed_loss_gen={smoothed_value_gen:.3f} | smoothed_loss_disc={smoothed_value_disc:.3f}"
889
  )
890
  print(record)
891
- last_loss_gen_all = loss_gen_all
892
 
893
  if done:
894
  os._exit(2333333)
@@ -953,8 +947,3 @@ def save_to_json(
953
  }
954
  with open(file_path, "w") as f:
955
  json.dump(data, f)
956
-
957
-
958
- if __name__ == "__main__":
959
- torch.multiprocessing.set_start_method("spawn")
960
- main()
 
27
  # Zluda hijack
28
  import rvc.lib.zluda
29
 
30
+ from .utils import (
31
  HParams,
32
  plot_spectrogram_to_numpy,
33
  summarize,
 
37
  load_wav_to_torch,
38
  )
39
 
40
+ from .losses import (
41
  discriminator_loss,
42
  feature_loss,
43
  generator_loss,
44
  kl_loss,
45
  )
46
+ from .mel_processing import mel_spectrogram_torch, spec_to_mel_torch
47
 
48
  from rvc.train.process.extract_model import extract_model
49
 
 
56
  pretrainG = sys.argv[4]
57
  pretrainD = sys.argv[5]
58
  version = sys.argv[6]
 
59
  batch_size = int(sys.argv[8])
60
  sample_rate = int(sys.argv[9])
61
  pitch_guidance = strtobool(sys.argv[10])
 
69
  current_dir = os.getcwd()
70
  experiment_dir = os.path.join(current_dir, "logs", model_name)
71
  config_save_path = os.path.join(experiment_dir, "config.json")
 
72
 
73
  with open(config_save_path, "r") as f:
74
  config = json.load(f)
 
79
  torch.backends.cudnn.benchmark = False
80
 
81
  global_step = 0
 
 
82
  loss_gen_history = []
83
  smoothed_loss_gen_history = []
84
  loss_disc_history = []
 
135
  """
136
  Main function to start the training process.
137
  """
138
+ global training_file_path, smoothed_loss_gen_history, loss_gen_history, loss_disc_history, smoothed_loss_disc_history
139
 
140
  os.environ["MASTER_ADDR"] = "localhost"
141
  os.environ["MASTER_PORT"] = str(randint(20000, 55555))
 
318
  torch.cuda.set_device(rank)
319
 
320
  # Create datasets and dataloaders
321
+ from .data_utils import (
322
  DistributedBucketSampler,
323
  TextAudioCollateMultiNSFsid,
324
  TextAudioLoaderMultiNSFsid,
 
529
 
530
  if epoch == 1:
531
  lowest_value = {"step": 0, "value": float("inf"), "epoch": 0}
 
532
  consecutive_increases_gen = 0
533
  consecutive_increases_disc = 0
534
 
 
883
  + f" | Number of epochs remaining for overtraining: g/total: {remaining_epochs_gen} d/total: {remaining_epochs_disc} | smoothed_loss_gen={smoothed_value_gen:.3f} | smoothed_loss_disc={smoothed_value_disc:.3f}"
884
  )
885
  print(record)
 
886
 
887
  if done:
888
  os._exit(2333333)
 
947
  }
948
  with open(file_path, "w") as f:
949
  json.dump(data, f)
 
 
 
 
 
tabs/plugins/plugins.py CHANGED
@@ -11,24 +11,3 @@ now_dir = os.getcwd()
11
  sys.path.append(now_dir)
12
 
13
  plugins_core.check_new_folders()
14
-
15
-
16
- def plugins_tab():
17
- with gr.TabItem(i18n("Plugin Installer")):
18
- dropbox = gr.File(
19
- label=i18n("Drag your plugin.zip to install it"),
20
- type="filepath",
21
- )
22
-
23
- dropbox.upload(
24
- fn=plugins_core.save_plugin_dropbox,
25
- inputs=[dropbox],
26
- outputs=[dropbox],
27
- )
28
-
29
- for plugin in os.listdir(os.path.join(now_dir, "tabs", "plugins", "installed")):
30
- plugin_main = f"tabs.plugins.installed.{plugin}.plugin"
31
- plugin_import = importlib.import_module(plugin_main)
32
-
33
- with gr.TabItem(plugin):
34
- plugin_import.applio_plugin()
 
11
  sys.path.append(now_dir)
12
 
13
  plugins_core.check_new_folders()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tabs/plugins/plugins_core.py CHANGED
@@ -37,65 +37,6 @@ def save_existing_folders(existing_folders):
37
  json.dump(config, file, indent=2)
38
 
39
 
40
- def save_plugin_dropbox(dropbox):
41
- if "zip" not in dropbox:
42
- raise gr.Error(
43
- message="The file you dropped is not a valid plugin.zip. Please try again."
44
- )
45
- else:
46
- file_name = os.path.basename(dropbox)
47
- folder_name = file_name.split(".zip")[0]
48
- folder_path = os.path.join(plugins_path, folder_name)
49
- zip_file_path = os.path.join(plugins_path, file_name)
50
-
51
- if os.path.exists(folder_name):
52
- os.remove(folder_name)
53
-
54
- shutil.move(dropbox, os.path.join(plugins_path, file_name))
55
- print("Proceeding with the extraction...")
56
-
57
- with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
58
- zip_ref.extractall(plugins_path)
59
- os.remove(zip_file_path)
60
-
61
- if os.path.exists(os.path.join(folder_path, "requirements.txt")):
62
- if os.name == "nt":
63
- subprocess.run(
64
- [
65
- os.path.join("env", "python.exe"),
66
- "-m",
67
- "pip",
68
- "install",
69
- "-r",
70
- os.path.join(folder_path, "requirements.txt"),
71
- ]
72
- )
73
- else:
74
- subprocess.run(
75
- [
76
- "python",
77
- "-m",
78
- "pip",
79
- "install",
80
- "-r",
81
- os.path.join(folder_path, "requirements.txt"),
82
- ]
83
- )
84
- else:
85
- print("No requirements.txt file found in the plugin folder.")
86
-
87
- save_existing_folders(get_existing_folders() + [folder_name])
88
-
89
- print(
90
- f"{folder_name} plugin installed in {plugins_path}! Restarting applio to apply the changes."
91
- )
92
- gr.Info(
93
- f"{folder_name} plugin installed in {plugins_path}! Restarting applio to apply the changes."
94
- )
95
- restart_applio()
96
- return None
97
-
98
-
99
  def check_new_folders():
100
  existing_folders = get_existing_folders()
101
  new_folders = set(current_folders) - set(existing_folders)
 
37
  json.dump(config, file, indent=2)
38
 
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  def check_new_folders():
41
  existing_folders = get_existing_folders()
42
  new_folders = set(current_folders) - set(existing_folders)
tabs/settings/sections/restart.py CHANGED
@@ -6,33 +6,6 @@ import json
6
  now_dir = os.getcwd()
7
 
8
 
9
- def stop_train(model_name: str):
10
- pid_file_path = os.path.join(now_dir, "logs", model_name, "config.json")
11
- try:
12
- with open(pid_file_path, "r") as pid_file:
13
- pid_data = json.load(pid_file)
14
- pids = pid_data.get("process_pids", [])
15
- with open(pid_file_path, "w") as pid_file:
16
- pid_data.pop("process_pids", None)
17
- json.dump(pid_data, pid_file, indent=4)
18
- for pid in pids:
19
- os.kill(pid, 9)
20
- except:
21
- pass
22
-
23
-
24
- def stop_infer():
25
- pid_file_path = os.path.join(now_dir, "assets", "infer_pid.txt")
26
- try:
27
- with open(pid_file_path, "r") as pid_file:
28
- pids = [int(pid) for pid in pid_file.readlines()]
29
- for pid in pids:
30
- os.kill(pid, 9)
31
- os.remove(pid_file_path)
32
- except:
33
- pass
34
-
35
-
36
  def restart_applio():
37
  if os.name != "nt":
38
  os.system("clear")
@@ -45,14 +18,3 @@ def restart_applio():
45
  from assets.i18n.i18n import I18nAuto
46
 
47
  i18n = I18nAuto()
48
-
49
-
50
- def restart_tab():
51
- with gr.Row():
52
- with gr.Column():
53
- restart_button = gr.Button(i18n("Restart Applio"))
54
- restart_button.click(
55
- fn=restart_applio,
56
- inputs=[],
57
- outputs=[],
58
- )
 
6
  now_dir = os.getcwd()
7
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  def restart_applio():
10
  if os.name != "nt":
11
  os.system("clear")
 
18
  from assets.i18n.i18n import I18nAuto
19
 
20
  i18n = I18nAuto()
 
 
 
 
 
 
 
 
 
 
 
tabs/train/train.py CHANGED
@@ -1,77 +1,21 @@
1
  import os
2
  import shutil
3
  import sys
4
- from multiprocessing import cpu_count
5
 
6
  import gradio as gr
7
 
8
  from assets.i18n.i18n import I18nAuto
9
- from core import (
10
- run_extract_script,
11
- run_index_script,
12
- run_preprocess_script,
13
- run_prerequisites_script,
14
- run_train_script,
15
- )
16
- from rvc.configs.config import get_gpu_info, get_number_of_gpus, max_vram_gpu
17
- from rvc.lib.utils import format_title
18
- from tabs.settings.sections.restart import stop_train
19
 
20
  i18n = I18nAuto()
21
  now_dir = os.getcwd()
22
  sys.path.append(now_dir)
23
 
24
- pretraineds_v1 = [
25
- (
26
- "pretrained_v1/",
27
- [
28
- "D32k.pth",
29
- "D40k.pth",
30
- "D48k.pth",
31
- "G32k.pth",
32
- "G40k.pth",
33
- "G48k.pth",
34
- "f0D32k.pth",
35
- "f0D40k.pth",
36
- "f0D48k.pth",
37
- "f0G32k.pth",
38
- "f0G40k.pth",
39
- "f0G48k.pth",
40
- ],
41
- ),
42
- ]
43
-
44
- folder_mapping = {
45
- "pretrained_v1/": "rvc/models/pretraineds/pretrained_v1/",
46
- }
47
-
48
- sup_audioext = {
49
- "wav",
50
- "mp3",
51
- "flac",
52
- "ogg",
53
- "opus",
54
- "m4a",
55
- "mp4",
56
- "aac",
57
- "alac",
58
- "wma",
59
- "aiff",
60
- "webm",
61
- "ac3",
62
- }
63
-
64
  # Custom Pretraineds
65
- pretraineds_custom_path = os.path.join(
66
- now_dir, "rvc", "models", "pretraineds", "pretraineds_custom"
67
- )
68
 
69
  pretraineds_custom_path_relative = os.path.relpath(pretraineds_custom_path, now_dir)
70
 
71
- custom_embedder_root = os.path.join(
72
- now_dir, "rvc", "models", "embedders", "embedders_custom"
73
- )
74
- custom_embedder_root_relative = os.path.relpath(custom_embedder_root, now_dir)
75
 
76
  os.makedirs(custom_embedder_root, exist_ok=True)
77
  os.makedirs(pretraineds_custom_path_relative, exist_ok=True)
@@ -86,968 +30,22 @@ def get_pretrained_list(suffix):
86
  ]
87
 
88
 
89
- pretraineds_list_d = get_pretrained_list("D")
90
- pretraineds_list_g = get_pretrained_list("G")
91
-
92
-
93
- def refresh_custom_pretraineds():
94
- return (
95
- {"choices": sorted(get_pretrained_list("G")), "__type__": "update"},
96
- {"choices": sorted(get_pretrained_list("D")), "__type__": "update"},
97
- )
98
-
99
-
100
  # Dataset Creator
101
  datasets_path = os.path.join(now_dir, "assets", "datasets")
102
 
103
  if not os.path.exists(datasets_path):
104
  os.makedirs(datasets_path)
105
 
106
- datasets_path_relative = os.path.relpath(datasets_path, now_dir)
107
-
108
-
109
- def get_datasets_list():
110
- return [
111
- dirpath
112
- for dirpath, _, filenames in os.walk(datasets_path_relative)
113
- if any(filename.endswith(tuple(sup_audioext)) for filename in filenames)
114
- ]
115
-
116
-
117
- def refresh_datasets():
118
- return {"choices": sorted(get_datasets_list()), "__type__": "update"}
119
-
120
-
121
- # Model Names
122
- models_path = os.path.join(now_dir, "logs")
123
-
124
-
125
- def get_models_list():
126
- return [
127
- os.path.basename(dirpath)
128
- for dirpath in os.listdir(models_path)
129
- if os.path.isdir(os.path.join(models_path, dirpath))
130
- and all(excluded not in dirpath for excluded in ["zips", "mute", "reference"])
131
- ]
132
-
133
-
134
- def refresh_models():
135
- return {"choices": sorted(get_models_list()), "__type__": "update"}
136
-
137
-
138
- # Refresh Models and Datasets
139
- def refresh_models_and_datasets():
140
- return (
141
- {"choices": sorted(get_models_list()), "__type__": "update"},
142
- {"choices": sorted(get_datasets_list()), "__type__": "update"},
143
- )
144
-
145
-
146
- # Refresh Custom Embedders
147
- def get_embedder_custom_list():
148
- return [
149
- os.path.join(dirpath, dirname)
150
- for dirpath, dirnames, _ in os.walk(custom_embedder_root_relative)
151
- for dirname in dirnames
152
- ]
153
-
154
-
155
- def refresh_custom_embedder_list():
156
- return {"choices": sorted(get_embedder_custom_list()), "__type__": "update"}
157
-
158
 
159
  # Drop Model
160
  def save_drop_model(dropbox):
161
  if ".pth" not in dropbox:
162
- gr.Info(
163
- i18n(
164
- "The file you dropped is not a valid pretrained file. Please try again."
165
- )
166
- )
167
  else:
168
  file_name = os.path.basename(dropbox)
169
  pretrained_path = os.path.join(pretraineds_custom_path_relative, file_name)
170
  if os.path.exists(pretrained_path):
171
  os.remove(pretrained_path)
172
  shutil.copy(dropbox, pretrained_path)
173
- gr.Info(
174
- i18n(
175
- "Click the refresh button to see the pretrained file in the dropdown menu."
176
- )
177
- )
178
  return None
179
-
180
-
181
- # Drop Dataset
182
- def save_drop_dataset_audio(dropbox, dataset_name):
183
- if not dataset_name:
184
- gr.Info("Please enter a valid dataset name. Please try again.")
185
- return None, None
186
- else:
187
- file_extension = os.path.splitext(dropbox)[1][1:].lower()
188
- if file_extension not in sup_audioext:
189
- gr.Info("The file you dropped is not a valid audio file. Please try again.")
190
- else:
191
- dataset_name = format_title(dataset_name)
192
- audio_file = format_title(os.path.basename(dropbox))
193
- dataset_path = os.path.join(now_dir, "assets", "datasets", dataset_name)
194
- if not os.path.exists(dataset_path):
195
- os.makedirs(dataset_path)
196
- destination_path = os.path.join(dataset_path, audio_file)
197
- if os.path.exists(destination_path):
198
- os.remove(destination_path)
199
- shutil.copy(dropbox, destination_path)
200
- gr.Info(
201
- i18n(
202
- "The audio file has been successfully added to the dataset. Please click the preprocess button."
203
- )
204
- )
205
- dataset_path = os.path.dirname(destination_path)
206
- relative_dataset_path = os.path.relpath(dataset_path, now_dir)
207
-
208
- return None, relative_dataset_path
209
-
210
-
211
- # Drop Custom Embedder
212
- def create_folder_and_move_files(folder_name, bin_file, config_file):
213
- if not folder_name:
214
- return "Folder name must not be empty."
215
-
216
- folder_name = os.path.join(custom_embedder_root, folder_name)
217
- os.makedirs(folder_name, exist_ok=True)
218
-
219
- if bin_file:
220
- bin_file_path = os.path.join(folder_name, os.path.basename(bin_file))
221
- shutil.copy(bin_file, bin_file_path)
222
-
223
- if config_file:
224
- config_file_path = os.path.join(folder_name, os.path.basename(config_file))
225
- shutil.copy(config_file, config_file_path)
226
-
227
- return f"Files moved to folder {folder_name}"
228
-
229
-
230
- def refresh_embedders_folders():
231
- custom_embedders = [
232
- os.path.join(dirpath, dirname)
233
- for dirpath, dirnames, _ in os.walk(custom_embedder_root_relative)
234
- for dirname in dirnames
235
- ]
236
- return custom_embedders
237
-
238
-
239
- # Export
240
- ## Get Pth and Index Files
241
- def get_pth_list():
242
- return [
243
- os.path.relpath(os.path.join(dirpath, filename), now_dir)
244
- for dirpath, _, filenames in os.walk(models_path)
245
- for filename in filenames
246
- if filename.endswith(".pth")
247
- ]
248
-
249
-
250
- def get_index_list():
251
- return [
252
- os.path.relpath(os.path.join(dirpath, filename), now_dir)
253
- for dirpath, _, filenames in os.walk(models_path)
254
- for filename in filenames
255
- if filename.endswith(".index") and "trained" not in filename
256
- ]
257
-
258
-
259
- def refresh_pth_and_index_list():
260
- return (
261
- {"choices": sorted(get_pth_list()), "__type__": "update"},
262
- {"choices": sorted(get_index_list()), "__type__": "update"},
263
- )
264
-
265
-
266
- ## Export Pth and Index Files
267
- def export_pth(pth_path):
268
- if pth_path and os.path.exists(pth_path):
269
- return pth_path
270
- return None
271
-
272
-
273
- def export_index(index_path):
274
- if index_path and os.path.exists(index_path):
275
- return index_path
276
- return None
277
-
278
-
279
- ## Upload to Google Drive
280
- def upload_to_google_drive(pth_path, index_path):
281
- def upload_file(file_path):
282
- if file_path:
283
- try:
284
- gr.Info(f"Uploading {pth_path} to Google Drive...")
285
- google_drive_folder = "/content/drive/MyDrive/ApplioExported"
286
- if not os.path.exists(google_drive_folder):
287
- os.makedirs(google_drive_folder)
288
- google_drive_file_path = os.path.join(
289
- google_drive_folder, os.path.basename(file_path)
290
- )
291
- if os.path.exists(google_drive_file_path):
292
- os.remove(google_drive_file_path)
293
- shutil.copy2(file_path, google_drive_file_path)
294
- gr.Info("File uploaded successfully.")
295
- except Exception as error:
296
- print(f"An error occurred uploading to Google Drive: {error}")
297
- gr.Info("Error uploading to Google Drive")
298
-
299
- upload_file(pth_path)
300
- upload_file(index_path)
301
-
302
-
303
- # Train Tab
304
- def train_tab():
305
- with gr.Row():
306
- model_name = gr.Dropdown(
307
- label=i18n("Model Name"),
308
- info=i18n("Name of the new model."),
309
- choices=get_models_list(),
310
- value="my-project",
311
- interactive=True,
312
- allow_custom_value=True,
313
- )
314
- sampling_rate = gr.Radio(
315
- label=i18n("Sampling Rate"),
316
- info=i18n("The sampling rate of the audio files."),
317
- choices=["32000", "40000", "48000"],
318
- value="40000",
319
- interactive=True,
320
- )
321
- rvc_version = gr.Radio(
322
- label=i18n("Model Architecture"),
323
- info=i18n("Version of the model architecture."),
324
- choices=["v1", "v2"],
325
- value="v2",
326
- interactive=True,
327
- visible=False,
328
- )
329
- with gr.Accordion(i18n("Preprocess")):
330
- dataset_path = gr.Dropdown(
331
- label=i18n("Dataset Path"),
332
- info=i18n("Path to the dataset folder."),
333
- # placeholder=i18n("Enter dataset path"),
334
- choices=get_datasets_list(),
335
- allow_custom_value=True,
336
- interactive=True,
337
- )
338
- dataset_creator = gr.Checkbox(
339
- label=i18n("Dataset Creator"),
340
- value=False,
341
- interactive=True,
342
- visible=True,
343
- )
344
- with gr.Column(visible=False) as dataset_creator_settings:
345
- with gr.Accordion(i18n("Dataset Creator")):
346
- dataset_name = gr.Textbox(
347
- label=i18n("Dataset Name"),
348
- info=i18n("Name of the new dataset."),
349
- placeholder=i18n("Enter dataset name"),
350
- interactive=True,
351
- )
352
- upload_audio_dataset = gr.File(
353
- label=i18n("Upload Audio Dataset"),
354
- type="filepath",
355
- interactive=True,
356
- )
357
- refresh = gr.Button(i18n("Refresh"))
358
-
359
- with gr.Accordion(i18n("Advanced Settings"), open=False):
360
- cpu_cores_preprocess = gr.Slider(
361
- 1,
362
- min(cpu_count(), 32), # max 32 parallel processes
363
- min(cpu_count(), 32),
364
- step=1,
365
- label=i18n("CPU Cores"),
366
- info=i18n(
367
- "The number of CPU cores to use in the preprocess. The default setting are your cpu cores, which is recommended for most cases."
368
- ),
369
- interactive=True,
370
- )
371
- with gr.Row():
372
- cut_preprocess = gr.Checkbox(
373
- label=i18n("Audio cutting"),
374
- info=i18n(
375
- "It's recommended to deactivate this option if your dataset has already been processed."
376
- ),
377
- value=True,
378
- interactive=True,
379
- visible=True,
380
- )
381
- process_effects = gr.Checkbox(
382
- label=i18n("Process effects"),
383
- info=i18n(
384
- "It's recommended to deactivate this option if your dataset has already been processed."
385
- ),
386
- value=True,
387
- interactive=True,
388
- visible=True,
389
- )
390
- with gr.Row():
391
- noise_reduction = gr.Checkbox(
392
- label=i18n("Noise Reduction"),
393
- info=i18n(
394
- "It's recommended keep deactivate this option if your dataset has already been processed."
395
- ),
396
- value=False,
397
- interactive=True,
398
- visible=True,
399
- )
400
- clean_strength = gr.Slider(
401
- minimum=0,
402
- maximum=1,
403
- label=i18n("Noise Reduction Strength"),
404
- info=i18n(
405
- "Set the clean-up level to the audio you want, the more you increase it the more it will clean up, but it is possible that the audio will be more compressed."
406
- ),
407
- visible=False,
408
- value=0.5,
409
- interactive=True,
410
- )
411
- preprocess_output_info = gr.Textbox(
412
- label=i18n("Output Information"),
413
- info=i18n("The output information will be displayed here."),
414
- value="",
415
- max_lines=8,
416
- interactive=False,
417
- )
418
-
419
- with gr.Row():
420
- preprocess_button = gr.Button(i18n("Preprocess Dataset"))
421
- preprocess_button.click(
422
- fn=run_preprocess_script,
423
- inputs=[
424
- model_name,
425
- dataset_path,
426
- sampling_rate,
427
- cpu_cores_preprocess,
428
- cut_preprocess,
429
- process_effects,
430
- noise_reduction,
431
- clean_strength,
432
- ],
433
- outputs=[preprocess_output_info],
434
- )
435
-
436
- with gr.Accordion(i18n("Extract")):
437
- with gr.Row():
438
- f0_method = gr.Radio(
439
- label=i18n("Pitch extraction algorithm"),
440
- info=i18n(
441
- "Pitch extraction algorithm to use for the audio conversion. The default algorithm is rmvpe, which is recommended for most cases."
442
- ),
443
- choices=["crepe", "crepe-tiny", "rmvpe"],
444
- value="rmvpe",
445
- interactive=True,
446
- )
447
-
448
- embedder_model = gr.Radio(
449
- label=i18n("Embedder Model"),
450
- info=i18n("Model used for learning speaker embedding."),
451
- choices=[
452
- "contentvec",
453
- "chinese-hubert-base",
454
- "japanese-hubert-base",
455
- "korean-hubert-base",
456
- "custom",
457
- ],
458
- value="contentvec",
459
- interactive=True,
460
- )
461
-
462
- hop_length = gr.Slider(
463
- 1,
464
- 512,
465
- 128,
466
- step=1,
467
- label=i18n("Hop Length"),
468
- info=i18n(
469
- "Denotes the duration it takes for the system to transition to a significant pitch change. Smaller hop lengths require more time for inference but tend to yield higher pitch accuracy."
470
- ),
471
- visible=False,
472
- interactive=True,
473
- )
474
- with gr.Row(visible=False) as embedder_custom:
475
- with gr.Accordion("Custom Embedder", open=True):
476
- with gr.Row():
477
- embedder_model_custom = gr.Dropdown(
478
- label="Select Custom Embedder",
479
- choices=refresh_embedders_folders(),
480
- interactive=True,
481
- allow_custom_value=True,
482
- )
483
- refresh_embedders_button = gr.Button("Refresh embedders")
484
- folder_name_input = gr.Textbox(label="Folder Name", interactive=True)
485
- with gr.Row():
486
- bin_file_upload = gr.File(
487
- label="Upload .bin", type="filepath", interactive=True
488
- )
489
- config_file_upload = gr.File(
490
- label="Upload .json", type="filepath", interactive=True
491
- )
492
- move_files_button = gr.Button("Move files to custom embedder folder")
493
-
494
- with gr.Accordion(
495
- i18n(
496
- "We prioritize running the model extraction on the GPU for faster performance. If you prefer to use the CPU, simply leave the GPU field blank."
497
- ),
498
- open=False,
499
- ):
500
- with gr.Row():
501
- with gr.Column():
502
- cpu_cores_extract = gr.Slider(
503
- 1,
504
- min(cpu_count(), 32), # max 32 parallel processes
505
- min(cpu_count(), 32),
506
- step=1,
507
- label=i18n("CPU Cores"),
508
- info=i18n(
509
- "The number of CPU cores to use in the extraction process. The default setting are your cpu cores, which is recommended for most cases."
510
- ),
511
- interactive=True,
512
- )
513
-
514
- with gr.Column():
515
- gpu_extract = gr.Textbox(
516
- label=i18n("GPU Number"),
517
- info=i18n(
518
- "Specify the number of GPUs you wish to utilize for extracting by entering them separated by hyphens (-)."
519
- ),
520
- placeholder=i18n("0 to ∞ separated by -"),
521
- value=str(get_number_of_gpus()),
522
- interactive=True,
523
- )
524
- gr.Textbox(
525
- label=i18n("GPU Information"),
526
- info=i18n("The GPU information will be displayed here."),
527
- value=get_gpu_info(),
528
- interactive=False,
529
- )
530
-
531
- extract_output_info = gr.Textbox(
532
- label=i18n("Output Information"),
533
- info=i18n("The output information will be displayed here."),
534
- value="",
535
- max_lines=8,
536
- interactive=False,
537
- )
538
- extract_button = gr.Button(i18n("Extract Features"))
539
- extract_button.click(
540
- fn=run_extract_script,
541
- inputs=[
542
- model_name,
543
- rvc_version,
544
- f0_method,
545
- hop_length,
546
- cpu_cores_extract,
547
- gpu_extract,
548
- sampling_rate,
549
- embedder_model,
550
- embedder_model_custom,
551
- ],
552
- outputs=[extract_output_info],
553
- )
554
-
555
- with gr.Accordion(i18n("Training")):
556
- with gr.Row():
557
- batch_size = gr.Slider(
558
- 1,
559
- 50,
560
- max_vram_gpu(0),
561
- step=1,
562
- label=i18n("Batch Size"),
563
- info=i18n(
564
- "It's advisable to align it with the available VRAM of your GPU. A setting of 4 offers improved accuracy but slower processing, while 8 provides faster and standard results."
565
- ),
566
- interactive=True,
567
- )
568
- save_every_epoch = gr.Slider(
569
- 1,
570
- 100,
571
- 10,
572
- step=1,
573
- label=i18n("Save Every Epoch"),
574
- info=i18n("Determine at how many epochs the model will saved at."),
575
- interactive=True,
576
- )
577
- total_epoch = gr.Slider(
578
- 1,
579
- 10000,
580
- 500,
581
- step=1,
582
- label=i18n("Total Epoch"),
583
- info=i18n(
584
- "Specifies the overall quantity of epochs for the model training process."
585
- ),
586
- interactive=True,
587
- )
588
- with gr.Accordion(i18n("Advanced Settings"), open=False):
589
- with gr.Row():
590
- with gr.Column():
591
- save_only_latest = gr.Checkbox(
592
- label=i18n("Save Only Latest"),
593
- info=i18n(
594
- "Enabling this setting will result in the G and D files saving only their most recent versions, effectively conserving storage space."
595
- ),
596
- value=True,
597
- interactive=True,
598
- )
599
- save_every_weights = gr.Checkbox(
600
- label=i18n("Save Every Weights"),
601
- info=i18n(
602
- "This setting enables you to save the weights of the model at the conclusion of each epoch."
603
- ),
604
- value=True,
605
- interactive=True,
606
- )
607
- pretrained = gr.Checkbox(
608
- label=i18n("Pretrained"),
609
- info=i18n(
610
- "Utilize pretrained models when training your own. This approach reduces training duration and enhances overall quality."
611
- ),
612
- value=True,
613
- interactive=True,
614
- )
615
- with gr.Column():
616
- cleanup = gr.Checkbox(
617
- label=i18n("Fresh Training"),
618
- info=i18n(
619
- "Enable this setting only if you are training a new model from scratch or restarting the training. Deletes all previously generated weights and tensorboard logs."
620
- ),
621
- value=False,
622
- interactive=True,
623
- )
624
- cache_dataset_in_gpu = gr.Checkbox(
625
- label=i18n("Cache Dataset in GPU"),
626
- info=i18n(
627
- "Cache the dataset in GPU memory to speed up the training process."
628
- ),
629
- value=False,
630
- interactive=True,
631
- )
632
- pitch_guidance = gr.Checkbox(
633
- label=i18n("Pitch Guidance"),
634
- info=i18n(
635
- "By employing pitch guidance, it becomes feasible to mirror the intonation of the original voice, including its pitch. This feature is particularly valuable for singing and other scenarios where preserving the original melody or pitch pattern is essential."
636
- ),
637
- value=True,
638
- interactive=True,
639
- )
640
- with gr.Column():
641
- custom_pretrained = gr.Checkbox(
642
- label=i18n("Custom Pretrained"),
643
- info=i18n(
644
- "Utilizing custom pretrained models can lead to superior results, as selecting the most suitable pretrained models tailored to the specific use case can significantly enhance performance."
645
- ),
646
- value=False,
647
- interactive=True,
648
- )
649
- with gr.Column(visible=False) as pretrained_custom_settings:
650
- with gr.Accordion(i18n("Pretrained Custom Settings")):
651
- upload_pretrained = gr.File(
652
- label=i18n("Upload Pretrained Model"),
653
- type="filepath",
654
- interactive=True,
655
- )
656
- refresh_custom_pretaineds_button = gr.Button(
657
- i18n("Refresh Custom Pretraineds")
658
- )
659
- g_pretrained_path = gr.Dropdown(
660
- label=i18n("Custom Pretrained G"),
661
- info=i18n(
662
- "Select the custom pretrained model for the generator."
663
- ),
664
- choices=sorted(pretraineds_list_g),
665
- interactive=True,
666
- allow_custom_value=True,
667
- )
668
- d_pretrained_path = gr.Dropdown(
669
- label=i18n("Custom Pretrained D"),
670
- info=i18n(
671
- "Select the custom pretrained model for the discriminator."
672
- ),
673
- choices=sorted(pretraineds_list_d),
674
- interactive=True,
675
- allow_custom_value=True,
676
- )
677
- multiple_gpu = gr.Checkbox(
678
- label=i18n("GPU Settings"),
679
- info=(
680
- i18n(
681
- "Sets advanced GPU settings, recommended for users with better GPU architecture."
682
- )
683
- ),
684
- value=False,
685
- interactive=True,
686
- )
687
- with gr.Column(visible=False) as gpu_custom_settings:
688
- with gr.Accordion(i18n("GPU Settings")):
689
- gpu = gr.Textbox(
690
- label=i18n("GPU Number"),
691
- info=i18n(
692
- "Specify the number of GPUs you wish to utilize for training by entering them separated by hyphens (-)."
693
- ),
694
- placeholder=i18n("0 to ∞ separated by -"),
695
- value=str(get_number_of_gpus()),
696
- interactive=True,
697
- )
698
- gr.Textbox(
699
- label=i18n("GPU Information"),
700
- info=i18n("The GPU information will be displayed here."),
701
- value=get_gpu_info(),
702
- interactive=False,
703
- )
704
- overtraining_detector = gr.Checkbox(
705
- label=i18n("Overtraining Detector"),
706
- info=i18n(
707
- "Detect overtraining to prevent the model from learning the training data too well and losing the ability to generalize to new data."
708
- ),
709
- value=False,
710
- interactive=True,
711
- )
712
- with gr.Column(visible=False) as overtraining_settings:
713
- with gr.Accordion(i18n("Overtraining Detector Settings")):
714
- overtraining_threshold = gr.Slider(
715
- 1,
716
- 100,
717
- 50,
718
- step=1,
719
- label=i18n("Overtraining Threshold"),
720
- info=i18n(
721
- "Set the maximum number of epochs you want your model to stop training if no improvement is detected."
722
- ),
723
- interactive=True,
724
- )
725
- index_algorithm = gr.Radio(
726
- label=i18n("Index Algorithm"),
727
- info=i18n(
728
- "KMeans is a clustering algorithm that divides the dataset into K clusters. This setting is particularly useful for large datasets."
729
- ),
730
- choices=["Auto", "Faiss", "KMeans"],
731
- value="Auto",
732
- interactive=True,
733
- )
734
-
735
- with gr.Row():
736
- train_output_info = gr.Textbox(
737
- label=i18n("Output Information"),
738
- info=i18n("The output information will be displayed here."),
739
- value="",
740
- max_lines=8,
741
- interactive=False,
742
- )
743
-
744
- with gr.Row():
745
- train_button = gr.Button(i18n("Start Training"))
746
- train_button.click(
747
- fn=run_train_script,
748
- inputs=[
749
- model_name,
750
- rvc_version,
751
- save_every_epoch,
752
- save_only_latest,
753
- save_every_weights,
754
- total_epoch,
755
- sampling_rate,
756
- batch_size,
757
- gpu,
758
- pitch_guidance,
759
- overtraining_detector,
760
- overtraining_threshold,
761
- pretrained,
762
- cleanup,
763
- index_algorithm,
764
- cache_dataset_in_gpu,
765
- custom_pretrained,
766
- g_pretrained_path,
767
- d_pretrained_path,
768
- ],
769
- outputs=[train_output_info],
770
- )
771
-
772
- stop_train_button = gr.Button(i18n("Stop Training"), visible=False)
773
- stop_train_button.click(
774
- fn=stop_train,
775
- inputs=[model_name],
776
- outputs=[],
777
- )
778
-
779
- index_button = gr.Button(i18n("Generate Index"))
780
- index_button.click(
781
- fn=run_index_script,
782
- inputs=[model_name, rvc_version, index_algorithm],
783
- outputs=[train_output_info],
784
- )
785
-
786
- with gr.Accordion(i18n("Export Model"), open=False):
787
- if not os.name == "nt":
788
- gr.Markdown(
789
- i18n(
790
- "The button 'Upload' is only for google colab: Uploads the exported files to the ApplioExported folder in your Google Drive."
791
- )
792
- )
793
- with gr.Row():
794
- with gr.Column():
795
- pth_file_export = gr.File(
796
- label=i18n("Exported Pth file"),
797
- type="filepath",
798
- value=None,
799
- interactive=False,
800
- )
801
- pth_dropdown_export = gr.Dropdown(
802
- label=i18n("Pth file"),
803
- info=i18n("Select the pth file to be exported"),
804
- choices=get_pth_list(),
805
- value=None,
806
- interactive=True,
807
- allow_custom_value=True,
808
- )
809
- with gr.Column():
810
- index_file_export = gr.File(
811
- label=i18n("Exported Index File"),
812
- type="filepath",
813
- value=None,
814
- interactive=False,
815
- )
816
- index_dropdown_export = gr.Dropdown(
817
- label=i18n("Index File"),
818
- info=i18n("Select the index file to be exported"),
819
- choices=get_index_list(),
820
- value=None,
821
- interactive=True,
822
- allow_custom_value=True,
823
- )
824
- with gr.Row():
825
- with gr.Column():
826
- refresh_export = gr.Button(i18n("Refresh"))
827
- if not os.name == "nt":
828
- upload_exported = gr.Button(i18n("Upload"), variant="primary")
829
- upload_exported.click(
830
- fn=upload_to_google_drive,
831
- inputs=[pth_dropdown_export, index_dropdown_export],
832
- outputs=[],
833
- )
834
-
835
- def toggle_visible(checkbox):
836
- return {"visible": checkbox, "__type__": "update"}
837
-
838
- def toggle_visible_hop_length(f0_method):
839
- if f0_method == "crepe" or f0_method == "crepe-tiny":
840
- return {"visible": True, "__type__": "update"}
841
- return {"visible": False, "__type__": "update"}
842
-
843
- def toggle_pretrained(pretrained, custom_pretrained):
844
- if custom_pretrained == False:
845
- return {"visible": pretrained, "__type__": "update"}, {
846
- "visible": False,
847
- "__type__": "update",
848
- }
849
- else:
850
- return {"visible": pretrained, "__type__": "update"}, {
851
- "visible": pretrained,
852
- "__type__": "update",
853
- }
854
-
855
- def enable_stop_train_button():
856
- return {"visible": False, "__type__": "update"}, {
857
- "visible": True,
858
- "__type__": "update",
859
- }
860
-
861
- def disable_stop_train_button():
862
- return {"visible": True, "__type__": "update"}, {
863
- "visible": False,
864
- "__type__": "update",
865
- }
866
-
867
- def download_prerequisites(version, pitch_guidance):
868
- if version == "v1":
869
- if pitch_guidance:
870
- gr.Info(
871
- "Checking for v1 prerequisites with pitch guidance... Missing files will be downloaded. If you already have them, this step will be skipped."
872
- )
873
- run_prerequisites_script(
874
- pretraineds_v1_f0=True,
875
- pretraineds_v1_nof0=False,
876
- pretraineds_v2_f0=False,
877
- pretraineds_v2_nof0=False,
878
- models=False,
879
- exe=False,
880
- )
881
- else:
882
- gr.Info(
883
- "Checking for v1 prerequisites without pitch guidance... Missing files will be downloaded. If you already have them, this step will be skipped."
884
- )
885
- run_prerequisites_script(
886
- pretraineds_v1_f0=False,
887
- pretraineds_v1_nof0=True,
888
- pretraineds_v2_f0=False,
889
- pretraineds_v2_nof0=False,
890
- models=False,
891
- exe=False,
892
- )
893
- elif version == "v2":
894
- if pitch_guidance:
895
- gr.Info(
896
- "Checking for v2 prerequisites with pitch guidance... Missing files will be downloaded. If you already have them, this step will be skipped."
897
- )
898
- run_prerequisites_script(
899
- pretraineds_v1_f0=False,
900
- pretraineds_v1_nof0=False,
901
- pretraineds_v2_f0=True,
902
- pretraineds_v2_nof0=False,
903
- models=False,
904
- exe=False,
905
- )
906
- else:
907
- gr.Info(
908
- "Checking for v2 prerequisites without pitch guidance... Missing files will be downloaded. If you already have them, this step will be skipped."
909
- )
910
- run_prerequisites_script(
911
- pretraineds_v1_f0=False,
912
- pretraineds_v1_nof0=False,
913
- pretraineds_v2_f0=False,
914
- pretraineds_v2_nof0=True,
915
- models=False,
916
- exe=False,
917
- )
918
- gr.Info(
919
- "Prerequisites check complete. Missing files were downloaded, and you may now start preprocessing."
920
- )
921
-
922
- def toggle_visible_embedder_custom(embedder_model):
923
- if embedder_model == "custom":
924
- return {"visible": True, "__type__": "update"}
925
- return {"visible": False, "__type__": "update"}
926
-
927
- def update_slider_visibility(noise_reduction):
928
- return gr.update(visible=noise_reduction)
929
-
930
- noise_reduction.change(
931
- fn=update_slider_visibility,
932
- inputs=noise_reduction,
933
- outputs=clean_strength,
934
- )
935
- rvc_version.change(
936
- fn=download_prerequisites,
937
- inputs=[rvc_version, pitch_guidance],
938
- outputs=[],
939
- )
940
-
941
- pitch_guidance.change(
942
- fn=download_prerequisites,
943
- inputs=[rvc_version, pitch_guidance],
944
- outputs=[],
945
- )
946
-
947
- refresh.click(
948
- fn=refresh_models_and_datasets,
949
- inputs=[],
950
- outputs=[model_name, dataset_path],
951
- )
952
-
953
- dataset_creator.change(
954
- fn=toggle_visible,
955
- inputs=[dataset_creator],
956
- outputs=[dataset_creator_settings],
957
- )
958
-
959
- upload_audio_dataset.upload(
960
- fn=save_drop_dataset_audio,
961
- inputs=[upload_audio_dataset, dataset_name],
962
- outputs=[upload_audio_dataset, dataset_path],
963
- )
964
-
965
- f0_method.change(
966
- fn=toggle_visible_hop_length,
967
- inputs=[f0_method],
968
- outputs=[hop_length],
969
- )
970
-
971
- embedder_model.change(
972
- fn=toggle_visible_embedder_custom,
973
- inputs=[embedder_model],
974
- outputs=[embedder_custom],
975
- )
976
- embedder_model.change(
977
- fn=toggle_visible_embedder_custom,
978
- inputs=[embedder_model],
979
- outputs=[embedder_custom],
980
- )
981
- move_files_button.click(
982
- fn=create_folder_and_move_files,
983
- inputs=[folder_name_input, bin_file_upload, config_file_upload],
984
- outputs=[],
985
- )
986
- refresh_embedders_button.click(
987
- fn=refresh_embedders_folders, inputs=[], outputs=[embedder_model_custom]
988
- )
989
- pretrained.change(
990
- fn=toggle_pretrained,
991
- inputs=[pretrained, custom_pretrained],
992
- outputs=[custom_pretrained, pretrained_custom_settings],
993
- )
994
-
995
- custom_pretrained.change(
996
- fn=toggle_visible,
997
- inputs=[custom_pretrained],
998
- outputs=[pretrained_custom_settings],
999
- )
1000
-
1001
- refresh_custom_pretaineds_button.click(
1002
- fn=refresh_custom_pretraineds,
1003
- inputs=[],
1004
- outputs=[g_pretrained_path, d_pretrained_path],
1005
- )
1006
-
1007
- upload_pretrained.upload(
1008
- fn=save_drop_model,
1009
- inputs=[upload_pretrained],
1010
- outputs=[upload_pretrained],
1011
- )
1012
-
1013
- overtraining_detector.change(
1014
- fn=toggle_visible,
1015
- inputs=[overtraining_detector],
1016
- outputs=[overtraining_settings],
1017
- )
1018
-
1019
- multiple_gpu.change(
1020
- fn=toggle_visible,
1021
- inputs=[multiple_gpu],
1022
- outputs=[gpu_custom_settings],
1023
- )
1024
-
1025
- train_button.click(
1026
- fn=enable_stop_train_button,
1027
- inputs=[],
1028
- outputs=[train_button, stop_train_button],
1029
- )
1030
-
1031
- train_output_info.change(
1032
- fn=disable_stop_train_button,
1033
- inputs=[],
1034
- outputs=[train_button, stop_train_button],
1035
- )
1036
-
1037
- pth_dropdown_export.change(
1038
- fn=export_pth,
1039
- inputs=[pth_dropdown_export],
1040
- outputs=[pth_file_export],
1041
- )
1042
-
1043
- index_dropdown_export.change(
1044
- fn=export_index,
1045
- inputs=[index_dropdown_export],
1046
- outputs=[index_file_export],
1047
- )
1048
-
1049
- refresh_export.click(
1050
- fn=refresh_pth_and_index_list,
1051
- inputs=[],
1052
- outputs=[pth_dropdown_export, index_dropdown_export],
1053
- )
 
1
  import os
2
  import shutil
3
  import sys
 
4
 
5
  import gradio as gr
6
 
7
  from assets.i18n.i18n import I18nAuto
 
 
 
 
 
 
 
 
 
 
8
 
9
  i18n = I18nAuto()
10
  now_dir = os.getcwd()
11
  sys.path.append(now_dir)
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # Custom Pretraineds
14
+ pretraineds_custom_path = os.path.join(now_dir, "rvc", "models", "pretraineds", "pretraineds_custom")
 
 
15
 
16
  pretraineds_custom_path_relative = os.path.relpath(pretraineds_custom_path, now_dir)
17
 
18
+ custom_embedder_root = os.path.join(now_dir, "rvc", "models", "embedders", "embedders_custom")
 
 
 
19
 
20
  os.makedirs(custom_embedder_root, exist_ok=True)
21
  os.makedirs(pretraineds_custom_path_relative, exist_ok=True)
 
30
  ]
31
 
32
 
 
 
 
 
 
 
 
 
 
 
 
33
  # Dataset Creator
34
  datasets_path = os.path.join(now_dir, "assets", "datasets")
35
 
36
  if not os.path.exists(datasets_path):
37
  os.makedirs(datasets_path)
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  # Drop Model
41
  def save_drop_model(dropbox):
42
  if ".pth" not in dropbox:
43
+ gr.Info(i18n("The file you dropped is not a valid pretrained file. Please try again."))
 
 
 
 
44
  else:
45
  file_name = os.path.basename(dropbox)
46
  pretrained_path = os.path.join(pretraineds_custom_path_relative, file_name)
47
  if os.path.exists(pretrained_path):
48
  os.remove(pretrained_path)
49
  shutil.copy(dropbox, pretrained_path)
50
+ gr.Info(i18n("Click the refresh button to see the pretrained file in the dropdown menu."))
 
 
 
 
51
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tabs/tts/tts.py CHANGED
@@ -1,343 +1,39 @@
1
- import json
2
- import os
3
- import random
4
- import sys
5
-
6
  import gradio as gr
7
 
8
- now_dir = os.getcwd()
9
- sys.path.append(now_dir)
10
-
11
  from assets.i18n.i18n import I18nAuto
12
  from core import run_tts_script
13
- from tabs.inference.inference import (
14
- change_choices,
15
- create_folder_and_move_files,
16
- get_indexes,
17
- get_speakers_id,
18
- match_index,
19
- names,
20
- refresh_embedders_folders,
21
- )
22
 
23
  i18n = I18nAuto()
24
 
25
- default_weight = random.choice(names) if names else ""
26
-
27
- with open(
28
- os.path.join("rvc", "lib", "tools", "tts_voices.json"), "r", encoding="utf-8"
29
- ) as file:
30
- tts_voices_data = json.load(file)
31
-
32
- short_names = [voice.get("ShortName", "") for voice in tts_voices_data]
33
-
34
-
35
- def process_input(file_path):
36
- try:
37
- with open(file_path, "r", encoding="utf-8") as file:
38
- file.read()
39
- gr.Info(f"The file has been loaded!")
40
- return file_path, file_path
41
- except UnicodeDecodeError:
42
- gr.Info(f"The file has to be in UTF-8 encoding.")
43
- return None, None
44
-
45
 
46
  # TTS tab
47
  def tts_tab():
48
- with gr.Column():
49
  with gr.Row():
50
- model_file = gr.Dropdown(
51
  label=i18n("Voice Model"),
52
- info=i18n("Select the voice model to use for the conversion."),
53
- choices=sorted(names, key=lambda path: os.path.getsize(path)),
54
- interactive=True,
55
- value=default_weight,
56
- allow_custom_value=True,
57
- )
58
- best_default_index_path = match_index(model_file.value)
59
- index_file = gr.Dropdown(
60
- label=i18n("Index File"),
61
- info=i18n("Select the index file to use for the conversion."),
62
- choices=get_indexes(),
63
- value=best_default_index_path,
64
- interactive=True,
65
- allow_custom_value=True,
66
- )
67
- with gr.Row():
68
- unload_button = gr.Button(i18n("Unload Voice"))
69
- refresh_button = gr.Button(i18n("Refresh"))
70
-
71
- unload_button.click(
72
- fn=lambda: (
73
- {"value": "", "__type__": "update"},
74
- {"value": "", "__type__": "update"},
75
- ),
76
- inputs=[],
77
- outputs=[model_file, index_file],
78
- )
79
-
80
- model_file.select(
81
- fn=lambda model_file_value: match_index(model_file_value),
82
- inputs=[model_file],
83
- outputs=[index_file],
84
- )
85
-
86
- gr.Markdown(
87
- i18n(
88
- f"Applio is a Speech-to-Speech conversion software, utilizing EdgeTTS as middleware for running the Text-to-Speech (TTS) component. Read more about it [here!](https://docs.applio.org/getting-started/tts#disclaimer)"
89
- )
90
- )
91
- tts_voice = gr.Dropdown(
92
- label=i18n("TTS Voices"),
93
- info=i18n("Select the TTS voice to use for the conversion."),
94
- choices=short_names,
95
- interactive=True,
96
- value=None,
97
- )
98
-
99
- tts_rate = gr.Slider(
100
- minimum=-100,
101
- maximum=100,
102
- step=1,
103
- label=i18n("TTS Speed"),
104
- info=i18n("Increase or decrease TTS speed."),
105
- value=0,
106
- interactive=True,
107
- )
108
-
109
- with gr.Tabs():
110
- with gr.Tab(label="Text to Speech"):
111
- tts_text = gr.Textbox(
112
- label=i18n("Text to Synthesize"),
113
- info=i18n("Enter the text to synthesize."),
114
- placeholder=i18n("Enter text to synthesize"),
115
- lines=3,
116
- )
117
- with gr.Tab(label="File to Speech"):
118
- txt_file = gr.File(
119
- label=i18n("Upload a .txt file"),
120
- type="filepath",
121
- )
122
- input_tts_path = gr.Textbox(
123
- label=i18n("Input path for text file"),
124
- placeholder=i18n(
125
- "The path to the text file that contains content for text to speech."
126
- ),
127
- value="",
128
- interactive=True,
129
  )
130
 
131
- with gr.Accordion(i18n("Advanced Settings"), open=False):
132
- with gr.Column():
133
- output_tts_path = gr.Textbox(
134
- label=i18n("Output Path for TTS Audio"),
135
- placeholder=i18n("Enter output path"),
136
- value=os.path.join(now_dir, "assets", "audios", "tts_output.wav"),
137
- interactive=True,
138
- )
139
- output_rvc_path = gr.Textbox(
140
- label=i18n("Output Path for RVC Audio"),
141
- placeholder=i18n("Enter output path"),
142
- value=os.path.join(now_dir, "assets", "audios", "tts_rvc_output.wav"),
143
- interactive=True,
144
- )
145
- export_format = gr.Radio(
146
- label=i18n("Export Format"),
147
- info=i18n("Select the format to export the audio."),
148
- choices=["WAV", "MP3", "FLAC", "OGG", "M4A"],
149
- value="WAV",
150
- interactive=True,
151
- )
152
- sid = gr.Dropdown(
153
- label=i18n("Speaker ID"),
154
- info=i18n("Select the speaker ID to use for the conversion."),
155
- choices=get_speakers_id(model_file.value),
156
- value=0,
157
- interactive=True,
158
- )
159
- split_audio = gr.Checkbox(
160
- label=i18n("Split Audio"),
161
- info=i18n(
162
- "Split the audio into chunks for inference to obtain better results in some cases."
163
- ),
164
- visible=True,
165
- value=False,
166
- interactive=True,
167
- )
168
- autotune = gr.Checkbox(
169
- label=i18n("Autotune"),
170
- info=i18n(
171
- "Apply a soft autotune to your inferences, recommended for singing conversions."
172
- ),
173
- visible=True,
174
- value=False,
175
- interactive=True,
176
- )
177
- autotune_strength = gr.Slider(
178
- minimum=0,
179
- maximum=1,
180
- label=i18n("Autotune Strength"),
181
- info=i18n(
182
- "Set the autotune strength - the more you increase it the more it will snap to the chromatic grid."
183
- ),
184
- visible=False,
185
- value=1,
186
- interactive=True,
187
- )
188
- clean_audio = gr.Checkbox(
189
- label=i18n("Clean Audio"),
190
- info=i18n(
191
- "Clean your audio output using noise detection algorithms, recommended for speaking audios."
192
- ),
193
- visible=True,
194
- value=True,
195
- interactive=True,
196
- )
197
- clean_strength = gr.Slider(
198
- minimum=0,
199
- maximum=1,
200
- label=i18n("Clean Strength"),
201
- info=i18n(
202
- "Set the clean-up level to the audio you want, the more you increase it the more it will clean up, but it is possible that the audio will be more compressed."
203
- ),
204
- visible=True,
205
- value=0.5,
206
- interactive=True,
207
- )
208
- upscale_audio = gr.Checkbox(
209
- label=i18n("Upscale Audio"),
210
- info=i18n(
211
- "Upscale the audio to a higher quality, recommended for low-quality audios. (It could take longer to process the audio)"
212
- ),
213
- visible=True,
214
- value=False,
215
- interactive=True,
216
- )
217
- pitch = gr.Slider(
218
- minimum=-24,
219
- maximum=24,
220
  step=1,
221
- label=i18n("Pitch"),
222
- info=i18n(
223
- "Set the pitch of the audio, the higher the value, the higher the pitch."
224
- ),
225
  value=0,
226
  interactive=True,
227
  )
228
- filter_radius = gr.Slider(
229
- minimum=0,
230
- maximum=7,
231
- label=i18n("Filter Radius"),
232
- info=i18n(
233
- "If the number is greater than or equal to three, employing median filtering on the collected tone results has the potential to decrease respiration."
234
- ),
235
- value=3,
236
- step=1,
237
- interactive=True,
238
- )
239
- index_rate = gr.Slider(
240
- minimum=0,
241
- maximum=1,
242
- label=i18n("Search Feature Ratio"),
243
- info=i18n(
244
- "Influence exerted by the index file; a higher value corresponds to greater influence. However, opting for lower values can help mitigate artifacts present in the audio."
245
- ),
246
- value=0.75,
247
- interactive=True,
248
- )
249
- rms_mix_rate = gr.Slider(
250
- minimum=0,
251
- maximum=1,
252
- label=i18n("Volume Envelope"),
253
- info=i18n(
254
- "Substitute or blend with the volume envelope of the output. The closer the ratio is to 1, the more the output envelope is employed."
255
- ),
256
- value=1,
257
- interactive=True,
258
- )
259
- protect = gr.Slider(
260
- minimum=0,
261
- maximum=0.5,
262
- label=i18n("Protect Voiceless Consonants"),
263
- info=i18n(
264
- "Safeguard distinct consonants and breathing sounds to prevent electro-acoustic tearing and other artifacts. Pulling the parameter to its maximum value of 0.5 offers comprehensive protection. However, reducing this value might decrease the extent of protection while potentially mitigating the indexing effect."
265
- ),
266
- value=0.5,
267
- interactive=True,
268
- )
269
- hop_length = gr.Slider(
270
- minimum=1,
271
- maximum=512,
272
- step=1,
273
- label=i18n("Hop Length"),
274
- info=i18n(
275
- "Denotes the duration it takes for the system to transition to a significant pitch change. Smaller hop lengths require more time for inference but tend to yield higher pitch accuracy."
276
- ),
277
- value=128,
278
- interactive=True,
279
- )
280
- f0_method = gr.Radio(
281
- label=i18n("Pitch extraction algorithm"),
282
- info=i18n(
283
- "Pitch extraction algorithm to use for the audio conversion. The default algorithm is rmvpe, which is recommended for most cases."
284
- ),
285
- choices=[
286
- "crepe",
287
- "crepe-tiny",
288
- "rmvpe",
289
- "fcpe",
290
- "hybrid[rmvpe+fcpe]",
291
- ],
292
- value="rmvpe",
293
- interactive=True,
294
- )
295
- embedder_model = gr.Radio(
296
- label=i18n("Embedder Model"),
297
- info=i18n("Model used for learning speaker embedding."),
298
- choices=[
299
- "contentvec",
300
- "chinese-hubert-base",
301
- "japanese-hubert-base",
302
- "korean-hubert-base",
303
- "custom",
304
- ],
305
- value="contentvec",
306
- interactive=True,
307
- )
308
- with gr.Column(visible=False) as embedder_custom:
309
- with gr.Accordion(i18n("Custom Embedder"), open=True):
310
- with gr.Row():
311
- embedder_model_custom = gr.Dropdown(
312
- label=i18n("Select Custom Embedder"),
313
- choices=refresh_embedders_folders(),
314
- interactive=True,
315
- allow_custom_value=True,
316
- )
317
- refresh_embedders_button = gr.Button(i18n("Refresh embedders"))
318
- folder_name_input = gr.Textbox(
319
- label=i18n("Folder Name"), interactive=True
320
- )
321
- with gr.Row():
322
- bin_file_upload = gr.File(
323
- label=i18n("Upload .bin"),
324
- type="filepath",
325
- interactive=True,
326
- )
327
- config_file_upload = gr.File(
328
- label=i18n("Upload .json"),
329
- type="filepath",
330
- interactive=True,
331
- )
332
- move_files_button = gr.Button(
333
- i18n("Move files to custom embedder folder")
334
- )
335
- f0_file = gr.File(
336
- label=i18n(
337
- "The f0 curve represents the variations in the base frequency of a voice over time, showing how pitch rises and falls."
338
- ),
339
- visible=True,
340
- )
341
 
342
  convert_button = gr.Button(i18n("Convert"))
343
 
@@ -348,78 +44,12 @@ def tts_tab():
348
  )
349
  vc_output2 = gr.Audio(label=i18n("Export Audio"))
350
 
351
- def toggle_visible(checkbox):
352
- return {"visible": checkbox, "__type__": "update"}
353
-
354
- def toggle_visible_embedder_custom(embedder_model):
355
- if embedder_model == "custom":
356
- return {"visible": True, "__type__": "update"}
357
- return {"visible": False, "__type__": "update"}
358
-
359
- autotune.change(
360
- fn=toggle_visible,
361
- inputs=[autotune],
362
- outputs=[autotune_strength],
363
- )
364
- clean_audio.change(
365
- fn=toggle_visible,
366
- inputs=[clean_audio],
367
- outputs=[clean_strength],
368
- )
369
- refresh_button.click(
370
- fn=change_choices,
371
- inputs=[model_file],
372
- outputs=[model_file, index_file, sid],
373
- )
374
- txt_file.upload(
375
- fn=process_input,
376
- inputs=[txt_file],
377
- outputs=[input_tts_path, txt_file],
378
- )
379
- embedder_model.change(
380
- fn=toggle_visible_embedder_custom,
381
- inputs=[embedder_model],
382
- outputs=[embedder_custom],
383
- )
384
- move_files_button.click(
385
- fn=create_folder_and_move_files,
386
- inputs=[folder_name_input, bin_file_upload, config_file_upload],
387
- outputs=[],
388
- )
389
- refresh_embedders_button.click(
390
- fn=lambda: gr.update(choices=refresh_embedders_folders()),
391
- inputs=[],
392
- outputs=[embedder_model_custom],
393
- )
394
  convert_button.click(
395
  fn=run_tts_script,
396
  inputs=[
397
- input_tts_path,
398
  tts_text,
399
- tts_voice,
400
  tts_rate,
401
- pitch,
402
- filter_radius,
403
- index_rate,
404
- rms_mix_rate,
405
- protect,
406
- hop_length,
407
- f0_method,
408
- output_tts_path,
409
- output_rvc_path,
410
- model_file,
411
- index_file,
412
- split_audio,
413
- autotune,
414
- autotune_strength,
415
- clean_audio,
416
- clean_strength,
417
- export_format,
418
- upscale_audio,
419
- f0_file,
420
- embedder_model,
421
- embedder_model_custom,
422
- sid,
423
  ],
424
  outputs=[vc_output1, vc_output2],
425
  )
 
 
 
 
 
 
1
  import gradio as gr
2
 
 
 
 
3
  from assets.i18n.i18n import I18nAuto
4
  from core import run_tts_script
5
+ from tts_service.voices import voice_manager
 
 
 
 
 
 
 
 
6
 
7
  i18n = I18nAuto()
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  # TTS tab
11
  def tts_tab():
12
+ with gr.Column(): # noqa: SIM117
13
  with gr.Row():
14
+ voice_name = gr.Dropdown(
15
  label=i18n("Voice Model"),
16
+ info=i18n("Select the voice model."),
17
+ choices=voice_manager.voice_names,
18
+ value=voice_manager.voice_names[0],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  )
20
 
21
+ tts_rate = gr.Slider(
22
+ minimum=-100,
23
+ maximum=100,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  step=1,
25
+ label=i18n("TTS Speed"),
26
+ info=i18n("Increase or decrease TTS speed."),
 
 
27
  value=0,
28
  interactive=True,
29
  )
30
+
31
+ tts_text = gr.Textbox(
32
+ label=i18n("Text to Synthesize"),
33
+ info=i18n("Enter the text to synthesize."),
34
+ placeholder=i18n("Enter text to synthesize"),
35
+ lines=3,
36
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  convert_button = gr.Button(i18n("Convert"))
39
 
 
44
  )
45
  vc_output2 = gr.Audio(label=i18n("Export Audio"))
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  convert_button.click(
48
  fn=run_tts_script,
49
  inputs=[
 
50
  tts_text,
51
+ voice_name,
52
  tts_rate,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ],
54
  outputs=[vc_output1, vc_output2],
55
  )
tts_service/app.py CHANGED
@@ -1,36 +1,26 @@
1
- import gradio as gr
2
- import sys
3
- import os
4
  import logging
 
 
 
5
 
6
- # Constants
7
- DEFAULT_PORT = 6969
8
- MAX_PORT_ATTEMPTS = 10
 
 
 
 
 
9
 
10
  # Set up logging
11
  logging.getLogger("uvicorn").setLevel(logging.WARNING)
12
  logging.getLogger("httpx").setLevel(logging.WARNING)
13
 
14
- # Add current directory to sys.path
15
- now_dir = os.getcwd()
16
- sys.path.append(now_dir)
17
-
18
- # Zluda hijack
19
- import rvc.lib.zluda
20
-
21
  # Import Tabs
22
- from tabs.inference.inference import inference_tab
23
- from tabs.train.train import train_tab
24
- from tabs.extra.extra import extra_tab
25
- from tabs.report.report import report_tab
26
- from tabs.download.download import download_tab
27
- from tabs.tts.tts import tts_tab
28
- from tabs.voice_blender.voice_blender import voice_blender_tab
29
- from tabs.plugins.plugins import plugins_tab
30
- from tabs.settings.settings import settings_tab
31
 
32
  # Run prerequisites
33
- from core import run_prerequisites_script
34
 
35
  run_prerequisites_script(
36
  pretraineds_v1_f0=False,
@@ -38,75 +28,31 @@ run_prerequisites_script(
38
  pretraineds_v2_f0=True,
39
  pretraineds_v2_nof0=False,
40
  models=True,
41
- exe=True,
42
  )
43
 
44
  # Initialize i18n
45
- from assets.i18n.i18n import I18nAuto
46
 
47
  i18n = I18nAuto()
48
 
49
- # Start Discord presence if enabled
50
- from tabs.settings.sections.presence import load_config_presence
51
-
52
- if load_config_presence():
53
- from assets.discord_presence import RPCManager
54
-
55
- RPCManager.start_presence()
56
-
57
  # Check installation
58
- import assets.installation_checker as installation_checker
59
 
60
  installation_checker.check_installation()
61
 
62
  # Start Flask server if enabled
63
- from assets.flask.server import start_flask, load_config_flask
64
-
65
- if load_config_flask():
66
- print("Starting Flask server")
67
- start_flask()
68
-
69
- # Load theme
70
- import assets.themes.loadThemes as loadThemes
71
 
72
  my_applio = loadThemes.load_theme() or "ParityError/Interstellar"
73
 
74
  # Define Gradio interface
75
  with gr.Blocks(theme=my_applio, title="Applio", css="footer{display:none !important}") as Applio:
76
- gr.Markdown("# Applio")
77
- gr.Markdown(i18n("A simple, high-quality voice conversion tool focused on ease of use and performance."))
78
- gr.Markdown(
79
- i18n(
80
- "[Support](https://discord.gg/urxFjYmYYh) — [Discord Bot](https://discord.com/oauth2/authorize?client_id=1144714449563955302&permissions=1376674695271&scope=bot%20applications.commands) — [Find Voices](https://applio.org/models) — [GitHub](https://github.com/IAHispano/Applio)"
81
- )
82
- )
83
- with gr.Tab(i18n("Inference")):
84
- inference_tab()
85
-
86
- with gr.Tab(i18n("Training")):
87
- train_tab()
88
-
89
  with gr.Tab(i18n("TTS")):
90
  tts_tab()
91
 
92
- with gr.Tab(i18n("Voice Blender")):
93
- voice_blender_tab()
94
-
95
- with gr.Tab(i18n("Plugins")):
96
- plugins_tab()
97
-
98
  with gr.Tab(i18n("Download")):
99
  download_tab()
100
 
101
- with gr.Tab(i18n("Report a Bug")):
102
- report_tab()
103
-
104
- with gr.Tab(i18n("Extra")):
105
- extra_tab()
106
-
107
- with gr.Tab(i18n("Settings")):
108
- settings_tab()
109
-
110
 
111
  def launch_gradio():
112
  Applio.launch(
@@ -116,23 +62,5 @@ def launch_gradio():
116
  )
117
 
118
 
119
- def get_port_from_args():
120
- if "--port" in sys.argv:
121
- port_index = sys.argv.index("--port") + 1
122
- if port_index < len(sys.argv):
123
- return int(sys.argv[port_index])
124
- return DEFAULT_PORT
125
-
126
-
127
  if __name__ == "__main__":
128
- port = get_port_from_args()
129
- for _ in range(MAX_PORT_ATTEMPTS):
130
- try:
131
- launch_gradio()
132
- break
133
- except OSError:
134
- print(f"Failed to launch on port {port}, trying again on port {port - 1}...")
135
- port -= 1
136
- except Exception as error:
137
- print(f"An error occurred launching Gradio: {error}")
138
- break
 
 
 
 
1
  import logging
2
+ import sys
3
+
4
+ import gradio as gr
5
 
6
+ import assets.installation_checker as installation_checker
7
+ import assets.themes.loadThemes as loadThemes
8
+ from assets.i18n.i18n import I18nAuto
9
+ from core import run_prerequisites_script
10
+ from tabs.download.download import download_tab
11
+ from tabs.plugins import plugins_core
12
+ from tabs.tts.tts import tts_tab
13
+ from tts_service.utils import env_bool
14
 
15
  # Set up logging
16
  logging.getLogger("uvicorn").setLevel(logging.WARNING)
17
  logging.getLogger("httpx").setLevel(logging.WARNING)
18
 
 
 
 
 
 
 
 
19
  # Import Tabs
20
+
21
+ plugins_core.check_new_folders()
 
 
 
 
 
 
 
22
 
23
  # Run prerequisites
 
24
 
25
  run_prerequisites_script(
26
  pretraineds_v1_f0=False,
 
28
  pretraineds_v2_f0=True,
29
  pretraineds_v2_nof0=False,
30
  models=True,
31
+ voices=not env_bool("OFFLINE", False),
32
  )
33
 
34
  # Initialize i18n
 
35
 
36
  i18n = I18nAuto()
37
 
 
 
 
 
 
 
 
 
38
  # Check installation
 
39
 
40
  installation_checker.check_installation()
41
 
42
  # Start Flask server if enabled
 
 
 
 
 
 
 
 
43
 
44
  my_applio = loadThemes.load_theme() or "ParityError/Interstellar"
45
 
46
  # Define Gradio interface
47
  with gr.Blocks(theme=my_applio, title="Applio", css="footer{display:none !important}") as Applio:
48
+ gr.Markdown("# Text-to-Speech Playground")
49
+ gr.Markdown(i18n("Select a voice model, enter text, and press 'Convert' to synthesize speech."))
 
 
 
 
 
 
 
 
 
 
 
50
  with gr.Tab(i18n("TTS")):
51
  tts_tab()
52
 
 
 
 
 
 
 
53
  with gr.Tab(i18n("Download")):
54
  download_tab()
55
 
 
 
 
 
 
 
 
 
 
56
 
57
  def launch_gradio():
58
  Applio.launch(
 
62
  )
63
 
64
 
 
 
 
 
 
 
 
 
65
  if __name__ == "__main__":
66
+ launch_gradio()
 
 
 
 
 
 
 
 
 
 
tts_service/cli.py CHANGED
@@ -1,5 +1,12 @@
 
 
 
 
1
  import click
2
  from click_help_colors import HelpColorsGroup
 
 
 
3
 
4
 
5
  @click.group(
@@ -16,8 +23,52 @@ def main() -> None:
16
  def serve(share: bool) -> None:
17
  """Start the TTS Service"""
18
  from tts_service.app import Applio
 
19
  Applio.launch(share=share)
20
 
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  if __name__ == "__main__":
23
  main()
 
1
+ import os
2
+ from pathlib import Path
3
+
4
+ import boto3
5
  import click
6
  from click_help_colors import HelpColorsGroup
7
+ from dotenv import load_dotenv
8
+
9
+ load_dotenv()
10
 
11
 
12
  @click.group(
 
23
  def serve(share: bool) -> None:
24
  """Start the TTS Service"""
25
  from tts_service.app import Applio
26
+
27
  Applio.launch(share=share)
28
 
29
 
30
+ @main.group()
31
+ def service() -> None:
32
+ """Manages the deployed service."""
33
+
34
+
35
+ @service.command()
36
+ @click.option("--bucket", "-b", default=lambda: os.environ["BUCKET"], help="the bucket to upload voices to")
37
+ @click.option("--prefix", "-p", default=lambda: os.environ["VOICES_KEY_PREFIX"], help="the prefix to use for the keys")
38
+ @click.option("--delete", is_flag=True, help="delete extraneous files from dest")
39
+ @click.option("--dry-run", "-n", is_flag=True, help="perform a trial run with no changes made")
40
+ @click.argument("directory", type=click.Path(exists=True, file_okay=False, path_type=Path), nargs=1)
41
+ def upload_voices(bucket: str, prefix: str, delete: bool, dry_run: bool, directory: Path) -> None:
42
+ """Upload voices to the service"""
43
+ s3 = boto3.client("s3")
44
+ prefix = prefix.strip("/")
45
+ names = set()
46
+ for path in directory.glob("*.pth"):
47
+ names.add(path.name)
48
+ with path.open("rb") as file:
49
+ if dry_run:
50
+ click.echo(f"Would upload {path.name} to {bucket}/{prefix}")
51
+ else:
52
+ s3.put_object(Bucket=bucket, Key=f"{prefix}/{path.name}", Body=file)
53
+ # s3.upload_fileobj(file, bucket, f"{prefix}/{path.name}")
54
+ if not names:
55
+ raise click.ClickException(f"no voices found in directory {directory}")
56
+ deleted = 0
57
+ if delete:
58
+ paginator = s3.get_paginator("list_objects_v2")
59
+ for page in paginator.paginate(Bucket=bucket, Prefix=prefix):
60
+ for obj in page["Contents"]:
61
+ key = obj["Key"]
62
+ if key.split("/")[-1] not in names:
63
+ if dry_run:
64
+ click.echo(f"Would delete {key}")
65
+ else:
66
+ s3.delete_object(Bucket=bucket, Key=key)
67
+ deleted += 1
68
+ deleted_message = f", {deleted} deleted" if delete else ""
69
+ if not dry_run:
70
+ click.echo(f"{bucket}/{prefix}: {len(names)} voices uploaded{deleted_message}")
71
+
72
+
73
  if __name__ == "__main__":
74
  main()
tts_service/utils.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import hashlib
2
+ import os
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+
7
+ class Unspecified:
8
+ pass
9
+
10
+
11
+ UNSPECIFIED = Unspecified()
12
+ FALSISH_STRINGS = {"", "0", "false", "n", "no", "off", "disabled"}
13
+
14
+
15
+ def env_str(name: str, default: str | Unspecified = UNSPECIFIED) -> str:
16
+ value = os.environ.get(name)
17
+ if value is None:
18
+ if isinstance(default, Unspecified):
19
+ raise ValueError(f"environment variable {name} is not set")
20
+ return default
21
+ return value
22
+
23
+
24
+ def env_bool(name: str, default: bool | Unspecified = UNSPECIFIED) -> bool:
25
+ value = os.environ.get(name)
26
+ if value is None:
27
+ if isinstance(default, Unspecified):
28
+ raise ValueError(f"environment variable {name} is not set")
29
+ return default
30
+ return value.lower() not in FALSISH_STRINGS
31
+
32
+
33
+ def data_dir(name: str) -> Path:
34
+ rv = Path(env_str("DATA_DIR", "/var/tts-service")) / name
35
+ if not rv.exists():
36
+ os.makedirs(rv)
37
+ return Path(rv)
38
+
39
+
40
+ def cache_path(*keys: Any, extension: str | None = None) -> Path:
41
+ key = "\0".join(str(k) for k in keys)
42
+ hash = hashlib.md5(key.encode()).hexdigest()
43
+ dir_path = data_dir("cache") / hash[0:2]
44
+ if not dir_path.exists():
45
+ os.makedirs(dir_path)
46
+ name = f"{hash[2:]}"
47
+ if extension:
48
+ name += f".{extension}"
49
+ return dir_path / name
tts_service/voices.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from dataclasses import dataclass
3
+ from functools import cached_property
4
+ from pathlib import Path
5
+ from typing import Any, Generator
6
+
7
+ import boto3
8
+ from pydantic import BaseModel, Field, TypeAdapter
9
+ from tqdm import tqdm
10
+
11
+ from .utils import data_dir, env_str
12
+
13
+
14
+ @dataclass
15
+ class S3VoiceObj:
16
+ key: str
17
+ size: int
18
+
19
+ @property
20
+ def name(self) -> str:
21
+ return self.key.split("/")[-1]
22
+
23
+ @classmethod
24
+ def from_s3_obj(cls, obj: Any) -> "S3VoiceObj":
25
+ return S3VoiceObj(key=obj["Key"], size=obj["Size"])
26
+
27
+
28
+ class Voice(BaseModel):
29
+ name: str
30
+ model: str
31
+ tts: str
32
+ index: str = ""
33
+ autotune: float | None = None
34
+ clean: float | None = 0.5
35
+ upscale: bool = False
36
+ pitch: int = 0
37
+ filter_radius: int = 3
38
+ index_rate: float = 0.75
39
+ rms_mix_rate: float = 1
40
+ protect: float = 0.5
41
+ hop_length: int = 128
42
+ f0_method: str = "rmvpe"
43
+ embedder_model: str = "contentvec"
44
+
45
+
46
+ class TTSVoice(BaseModel):
47
+ name: str = Field(alias="ShortName")
48
+
49
+
50
+ class VoiceManager:
51
+ def __init__(self) -> None:
52
+ self.s3 = boto3.client("s3")
53
+ self.bucket = env_str("BUCKET")
54
+ self.prefix = env_str("VOICES_KEY_PREFIX")
55
+ self.voices_dir = Path(data_dir("voices"))
56
+
57
+ def _iter_s3_objects(self) -> Generator[S3VoiceObj, None, None]:
58
+ response = self.s3.list_objects_v2(Bucket=self.bucket, Prefix=self.prefix)
59
+ for obj in response.get("Contents", []):
60
+ yield S3VoiceObj.from_s3_obj(obj)
61
+
62
+ def get_voices_size_if_missing(self) -> int:
63
+ """
64
+ Calculate the total size of the voice files only if they do not exist locally.
65
+ """
66
+ total_size = 0
67
+ paths: set[Path] = set()
68
+ for obj in self._iter_s3_objects():
69
+ destination_path = self.voices_dir / obj.name
70
+ paths.add(destination_path)
71
+ if not destination_path.exists() or destination_path.stat().st_size != obj.size:
72
+ total_size += obj.size
73
+
74
+ for path in self.voices_dir.glob("*"):
75
+ if path not in paths:
76
+ path.unlink()
77
+
78
+ return total_size
79
+
80
+ def download_voice_files(self, progress_bar: tqdm) -> None:
81
+ """
82
+ Download all voice files from s3 updating the global progress bar.
83
+ """
84
+
85
+ def callback(bytes_amount: int) -> None:
86
+ progress_bar.update(bytes_amount)
87
+
88
+ for obj in self._iter_s3_objects():
89
+ destination_path = self.voices_dir / obj.name
90
+ if not destination_path.exists() or destination_path.stat().st_size != obj.size:
91
+ self.s3.download_file(Bucket=self.bucket, Key=obj.key, Filename=destination_path, Callback=callback)
92
+
93
+ @cached_property
94
+ def tts_voices(self) -> dict[str, TTSVoice]:
95
+ path = Path("rvc/lib/tools/tts_voices.json")
96
+ voices = TypeAdapter(list[TTSVoice]).validate_json(path.read_bytes())
97
+ return {v.name: v for v in voices}
98
+
99
+ @property
100
+ def voice_names(self) -> list[str]:
101
+ return list(self.voices.keys())
102
+
103
+ @cached_property
104
+ def voices(self) -> dict[str, Voice]:
105
+ rv = {}
106
+ for path in self.voices_dir.glob("*.json"):
107
+ voice = Voice.model_validate_json(path.read_bytes())
108
+ model_path = self.voices_dir / f"{voice.model}"
109
+ if not model_path.exists():
110
+ logging.warning("Voice %s missing model %s", voice.name, voice.model)
111
+ elif voice.tts not in self.tts_voices:
112
+ logging.warning("Voice %s references invalid tts %s", voice.name, voice.model)
113
+ else:
114
+ voice.model = str(model_path)
115
+ rv[voice.name] = voice
116
+ return rv
117
+
118
+
119
+ voice_manager = VoiceManager()
tts_service/whitelist.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ _.secondary_100 # unused attribute (assets/themes/Applio.py:44)
2
+ _.secondary_200 # unused attribute (assets/themes/Applio.py:45)
3
+ _.secondary_300 # unused attribute (assets/themes/Applio.py:46)
4
+ _.secondary_400 # unused attribute (assets/themes/Applio.py:47)
5
+ _.secondary_50 # unused attribute (assets/themes/Applio.py:48)
6
+ _.secondary_500 # unused attribute (assets/themes/Applio.py:49)
7
+ _.secondary_600 # unused attribute (assets/themes/Applio.py:50)
8
+ _.secondary_700 # unused attribute (assets/themes/Applio.py:51)
9
+ _.secondary_800 # unused attribute (assets/themes/Applio.py:52)
10
+ _.secondary_900 # unused attribute (assets/themes/Applio.py:53)
11
+ _.secondary_950 # unused attribute (assets/themes/Applio.py:54)
12
+ __getattr__ # unused function (rvc/lib/predictors/FCPE.py:799)
13
+ _.graph # unused attribute (rvc/lib/zluda.py:33)
14
+ _.enabled # unused attribute (rvc/lib/zluda.py:40)
15
+ rvc # unused import (rvc/train/extract/extract.py:19)
16
+ _.nprobe # unused attribute (rvc/train/process/extract_index.py:76)
17
+ rvc # unused import (rvc/train/train.py:28)
18
+ _.deterministic # unused attribute (rvc/train/train.py:80)
19
+ _.benchmark # unused attribute (rvc/train/train.py:81)
20
+ losses_disc_g # unused variable (rvc/train/train.py:632)
21
+ losses_disc_r # unused variable (rvc/train/train.py:632)
22
+ losses_gen # unused variable (rvc/train/train.py:651)
23
+ components # unused variable (tabs/report/report.py:55)
24
+ rvc # unused import (tts_service/app.py:19)