CoolFace
Apppublic

mosi77/5

sourceHugging Facemitupdated 2y agoView on Hugging Face
0likes
train.py870 linesDownload Raw Back to train
1import os
2import subprocess
3import sys
4import shutil
5import gradio as gr
6from assets.i18n.i18n import I18nAuto
7from core import (
8    run_preprocess_script,
9    run_extract_script,
10    run_train_script,
11    run_index_script,
12    run_prerequisites_script,
13)
14from rvc.configs.config import max_vram_gpu, get_gpu_info
15from rvc.lib.utils import format_title
16from tabs.settings.restart import restart_applio
17
18i18n = I18nAuto()
19now_dir = os.getcwd()
20sys.path.append(now_dir)
21
22pretraineds_v1 = [
23    (
24        "pretrained_v1/",
25        [
26            "D32k.pth",
27            "D40k.pth",
28            "D48k.pth",
29            "G32k.pth",
30            "G40k.pth",
31            "G48k.pth",
32            "f0D32k.pth",
33            "f0D40k.pth",
34            "f0D48k.pth",
35            "f0G32k.pth",
36            "f0G40k.pth",
37            "f0G48k.pth",
38        ],
39    ),
40]
41
42folder_mapping = {
43    "pretrained_v1/": "rvc/pretraineds/pretrained_v1/",
44}
45
46sup_audioext = {
47    "wav",
48    "mp3",
49    "flac",
50    "ogg",
51    "opus",
52    "m4a",
53    "mp4",
54    "aac",
55    "alac",
56    "wma",
57    "aiff",
58    "webm",
59    "ac3",
60}
61
62# Custom Pretraineds
63pretraineds_custom_path = os.path.join(
64    now_dir, "rvc", "pretraineds", "pretraineds_custom"
65)
66
67pretraineds_custom_path_relative = os.path.relpath(pretraineds_custom_path, now_dir)
68
69custom_embedder_root = os.path.join(now_dir, "rvc", "embedders", "embedders_custom")
70custom_embedder_root_relative = os.path.relpath(custom_embedder_root, now_dir)
71
72os.makedirs(custom_embedder_root, exist_ok=True)
73os.makedirs(pretraineds_custom_path_relative, exist_ok=True)
74
75
76def get_pretrained_list(suffix):
77    return [
78        os.path.join(dirpath, filename)
79        for dirpath, _, filenames in os.walk(pretraineds_custom_path_relative)
80        for filename in filenames
81        if filename.endswith(".pth") and suffix in filename
82    ]
83
84
85pretraineds_list_d = get_pretrained_list("D")
86pretraineds_list_g = get_pretrained_list("G")
87
88
89def refresh_custom_pretraineds():
90    return (
91        {"choices": sorted(get_pretrained_list("G")), "__type__": "update"},
92        {"choices": sorted(get_pretrained_list("D")), "__type__": "update"},
93    )
94
95
96# Dataset Creator
97datasets_path = os.path.join(now_dir, "assets", "datasets")
98
99if not os.path.exists(datasets_path):
100    os.makedirs(datasets_path)
101
102datasets_path_relative = os.path.relpath(datasets_path, now_dir)
103
104
105def get_datasets_list():
106    return [
107        dirpath
108        for dirpath, _, filenames in os.walk(datasets_path_relative)
109        if any(filename.endswith(tuple(sup_audioext)) for filename in filenames)
110    ]
111
112
113def refresh_datasets():
114    return {"choices": sorted(get_datasets_list()), "__type__": "update"}
115
116
117# Model Names
118models_path = os.path.join(now_dir, "logs")
119
120
121def get_models_list():
122    return [
123        os.path.basename(dirpath)
124        for dirpath in os.listdir(models_path)
125        if os.path.isdir(os.path.join(models_path, dirpath))
126        and all(excluded not in dirpath for excluded in ["zips", "mute"])
127    ]
128
129
130def refresh_models():
131    return {"choices": sorted(get_models_list()), "__type__": "update"}
132
133
134# Refresh Models and Datasets
135def refresh_models_and_datasets():
136    return (
137        {"choices": sorted(get_models_list()), "__type__": "update"},
138        {"choices": sorted(get_datasets_list()), "__type__": "update"},
139    )
140
141
142# Refresh Custom Pretraineds
143def get_embedder_custom_list():
144    return [
145        os.path.join(dirpath, filename)
146        for dirpath, _, filenames in os.walk(custom_embedder_root_relative)
147        for filename in filenames
148        if filename.endswith(".pt")
149    ]
150
151
152def refresh_custom_embedder_list():
153    return {"choices": sorted(get_embedder_custom_list()), "__type__": "update"}
154
155
156# Drop Model
157def save_drop_model(dropbox):
158    if ".pth" not in dropbox:
159        gr.Info(
160            i18n(
161                "The file you dropped is not a valid pretrained file. Please try again."
162            )
163        )
164    else:
165        file_name = os.path.basename(dropbox)
166        pretrained_path = os.path.join(pretraineds_custom_path_relative, file_name)
167        if os.path.exists(pretrained_path):
168            os.remove(pretrained_path)
169        os.rename(dropbox, pretrained_path)
170        gr.Info(
171            i18n(
172                "Click the refresh button to see the pretrained file in the dropdown menu."
173            )
174        )
175    return None
176
177
178# Drop Dataset
179def save_drop_dataset_audio(dropbox, dataset_name):
180    if not dataset_name:
181        gr.Info("Please enter a valid dataset name. Please try again.")
182        return None, None
183    else:
184        file_extension = os.path.splitext(dropbox)[1][1:].lower()
185        if file_extension not in sup_audioext:
186            gr.Info("The file you dropped is not a valid audio file. Please try again.")
187        else:
188            dataset_name = format_title(dataset_name)
189            audio_file = format_title(os.path.basename(dropbox))
190            dataset_path = os.path.join(now_dir, "assets", "datasets", dataset_name)
191            if not os.path.exists(dataset_path):
192                os.makedirs(dataset_path)
193            destination_path = os.path.join(dataset_path, audio_file)
194            if os.path.exists(destination_path):
195                os.remove(destination_path)
196            os.rename(dropbox, destination_path)
197            gr.Info(
198                i18n(
199                    "The audio file has been successfully added to the dataset. Please click the preprocess button."
200                )
201            )
202            dataset_path = os.path.dirname(destination_path)
203            relative_dataset_path = os.path.relpath(dataset_path, now_dir)
204
205            return None, relative_dataset_path
206
207
208# Drop Custom Embedder
209def save_drop_custom_embedder(dropbox):
210    if ".pt" not in dropbox:
211        gr.Info(
212            i18n("The file you dropped is not a valid embedder file. Please try again.")
213        )
214    else:
215        file_name = os.path.basename(dropbox)
216        custom_embedder_path = os.path.join(custom_embedder_root, file_name)
217        if os.path.exists(custom_embedder_path):
218            os.remove(custom_embedder_path)
219        os.rename(dropbox, custom_embedder_path)
220        gr.Info(
221            i18n(
222                "Click the refresh button to see the embedder file in the dropdown menu."
223            )
224        )
225    return None
226
227
228# Export
229## Get Pth and Index Files
230def get_pth_list():
231    return [
232        os.path.relpath(os.path.join(dirpath, filename), now_dir)
233        for dirpath, _, filenames in os.walk(models_path)
234        for filename in filenames
235        if filename.endswith(".pth")
236    ]
237
238
239def get_index_list():
240    return [
241        os.path.relpath(os.path.join(dirpath, filename), now_dir)
242        for dirpath, _, filenames in os.walk(models_path)
243        for filename in filenames
244        if filename.endswith(".index") and "trained" not in filename
245    ]
246
247
248def refresh_pth_and_index_list():
249    return (
250        {"choices": sorted(get_pth_list()), "__type__": "update"},
251        {"choices": sorted(get_index_list()), "__type__": "update"},
252    )
253
254
255## Export Pth and Index Files
256def export_pth(pth_path):
257    if pth_path and os.path.exists(pth_path):
258        return pth_path
259    return None
260
261
262def export_index(index_path):
263    if index_path and os.path.exists(index_path):
264        return index_path
265    return None
266
267
268## Upload to Google Drive
269def upload_to_google_drive(pth_path, index_path):
270    def upload_file(file_path):
271        if file_path:
272            try:
273                gr.Info(f"Uploading {pth_path} to Google Drive...")
274                google_drive_folder = "/content/drive/MyDrive/ApplioExported"
275                if not os.path.exists(google_drive_folder):
276                    os.makedirs(google_drive_folder)
277                google_drive_file_path = os.path.join(
278                    google_drive_folder, os.path.basename(file_path)
279                )
280                if os.path.exists(google_drive_file_path):
281                    os.remove(google_drive_file_path)
282                shutil.copy2(file_path, google_drive_file_path)
283                gr.Info("File uploaded successfully.")
284            except Exception as error:
285                print(error)
286                gr.Info("Error uploading to Google Drive")
287
288    upload_file(pth_path)
289    upload_file(index_path)
290
291
292# Train Tab
293def train_tab():
294    with gr.Accordion(i18n("Preprocess")):
295        with gr.Row():
296            with gr.Column():
297                model_name = gr.Dropdown(
298                    label=i18n("Model Name"),
299                    info=i18n("Name of the new model."),
300                    choices=get_models_list(),
301                    value="my-project",
302                    interactive=True,
303                    allow_custom_value=True,
304                )
305                dataset_path = gr.Dropdown(
306                    label=i18n("Dataset Path"),
307                    info=i18n("Path to the dataset folder."),
308                    # placeholder=i18n("Enter dataset path"),
309                    choices=get_datasets_list(),
310                    allow_custom_value=True,
311                    interactive=True,
312                )
313                refresh = gr.Button(i18n("Refresh"))
314                dataset_creator = gr.Checkbox(
315                    label=i18n("Dataset Creator"),
316                    value=False,
317                    interactive=True,
318                    visible=True,
319                )
320
321                with gr.Column(visible=False) as dataset_creator_settings:
322                    with gr.Accordion(i18n("Dataset Creator")):
323                        dataset_name = gr.Textbox(
324                            label=i18n("Dataset Name"),
325                            info=i18n("Name of the new dataset."),
326                            placeholder=i18n("Enter dataset name"),
327                            interactive=True,
328                        )
329                        upload_audio_dataset = gr.File(
330                            label=i18n("Upload Audio Dataset"),
331                            type="filepath",
332                            interactive=True,
333                        )
334
335            with gr.Column():
336                sampling_rate = gr.Radio(
337                    label=i18n("Sampling Rate"),
338                    info=i18n("The sampling rate of the audio files."),
339                    choices=["32000", "40000", "48000"],
340                    value="40000",
341                    interactive=True,
342                )
343
344                rvc_version = gr.Radio(
345                    label=i18n("RVC Version"),
346                    info=i18n("The RVC version of the model."),
347                    choices=["v1", "v2"],
348                    value="v2",
349                    interactive=True,
350                )
351
352        preprocess_output_info = gr.Textbox(
353            label=i18n("Output Information"),
354            info=i18n("The output information will be displayed here."),
355            value="",
356            max_lines=8,
357            interactive=False,
358        )
359
360        with gr.Row():
361            preprocess_button = gr.Button(i18n("Preprocess Dataset"))
362            preprocess_button.click(
363                fn=run_preprocess_script,
364                inputs=[model_name, dataset_path, sampling_rate],
365                outputs=[preprocess_output_info],
366                api_name="preprocess_dataset",
367            )
368
369    with gr.Accordion(i18n("Extract")):
370        with gr.Row():
371            hop_length = gr.Slider(
372                1,
373                512,
374                128,
375                step=1,
376                label=i18n("Hop Length"),
377                info=i18n(
378                    "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."
379                ),
380                visible=False,
381                interactive=True,
382            )
383        with gr.Row():
384            with gr.Column():
385                f0method = gr.Radio(
386                    label=i18n("Pitch extraction algorithm"),
387                    info=i18n(
388                        "Pitch extraction algorithm to use for the audio conversion. The default algorithm is rmvpe, which is recommended for most cases."
389                    ),
390                    choices=["pm", "dio", "crepe", "crepe-tiny", "harvest", "rmvpe"],
391                    value="rmvpe",
392                    interactive=True,
393                )
394                embedder_model = gr.Radio(
395                    label=i18n("Embedder Model"),
396                    info=i18n("Model used for learning speaker embedding."),
397                    choices=["hubert", "contentvec", "custom"],
398                    value="hubert",
399                    interactive=True,
400                )
401                with gr.Column(visible=False) as embedder_custom:
402                    with gr.Accordion(i18n("Custom Embedder"), open=True):
403                        embedder_upload_custom = gr.File(
404                            label=i18n("Upload Custom Embedder"),
405                            type="filepath",
406                            interactive=True,
407                        )
408                        embedder_custom_refresh = gr.Button(i18n("Refresh"))
409                        embedder_model_custom = gr.Dropdown(
410                            label=i18n("Custom Embedder"),
411                            info=i18n(
412                                "Select the custom embedder to use for the conversion."
413                            ),
414                            choices=sorted(get_embedder_custom_list()),
415                            interactive=True,
416                            allow_custom_value=True,
417                        )
418
419        extract_output_info = gr.Textbox(
420            label=i18n("Output Information"),
421            info=i18n("The output information will be displayed here."),
422            value="",
423            max_lines=8,
424            interactive=False,
425        )
426        extract_button = gr.Button(i18n("Extract Features"))
427        extract_button.click(
428            fn=run_extract_script,
429            inputs=[
430                model_name,
431                rvc_version,
432                f0method,
433                hop_length,
434                sampling_rate,
435                embedder_model,
436                embedder_model_custom,
437            ],
438            outputs=[extract_output_info],
439            api_name="extract_features",
440        )
441
442    with gr.Accordion(i18n("Train")):
443        with gr.Row():
444            batch_size = gr.Slider(
445                1,
446                50,
447                max_vram_gpu(0),
448                step=1,
449                label=i18n("Batch Size"),
450                info=i18n(
451                    "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."
452                ),
453                interactive=True,
454            )
455            save_every_epoch = gr.Slider(
456                1,
457                100,
458                10,
459                step=1,
460                label=i18n("Save Every Epoch"),
461                info=i18n("Determine at how many epochs the model will saved at."),
462                interactive=True,
463            )
464            total_epoch = gr.Slider(
465                1,
466                10000,
467                500,
468                step=1,
469                label=i18n("Total Epoch"),
470                info=i18n(
471                    "Specifies the overall quantity of epochs for the model training process."
472                ),
473                interactive=True,
474            )
475        with gr.Row():
476            pitch_guidance = gr.Checkbox(
477                label=i18n("Pitch Guidance"),
478                info=i18n(
479                    "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."
480                ),
481                value=True,
482                interactive=True,
483            )
484            pretrained = gr.Checkbox(
485                label=i18n("Pretrained"),
486                info=i18n(
487                    "Utilize pretrained models when training your own. This approach reduces training duration and enhances overall quality."
488                ),
489                value=True,
490                interactive=True,
491            )
492            save_only_latest = gr.Checkbox(
493                label=i18n("Save Only Latest"),
494                info=i18n(
495                    "Enabling this setting will result in the G and D files saving only their most recent versions, effectively conserving storage space."
496                ),
497                value=False,
498                interactive=True,
499            )
500            save_every_weights = gr.Checkbox(
501                label=i18n("Save Every Weights"),
502                info=i18n(
503                    "This setting enables you to save the weights of the model at the conclusion of each epoch."
504                ),
505                value=True,
506                interactive=True,
507            )
508            custom_pretrained = gr.Checkbox(
509                label=i18n("Custom Pretrained"),
510                info=i18n(
511                    "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."
512                ),
513                value=False,
514                interactive=True,
515            )
516            multiple_gpu = gr.Checkbox(
517                label=i18n("GPU Settings"),
518                info=(
519                    i18n(
520                        "Sets advanced GPU settings, recommended for users with better GPU architecture."
521                    )
522                ),
523                value=False,
524                interactive=True,
525            )
526            overtraining_detector = gr.Checkbox(
527                label=i18n("Overtraining Detector"),
528                info=i18n(
529                    "Detect overtraining to prevent the model from learning the training data too well and losing the ability to generalize to new data."
530                ),
531                value=False,
532                interactive=True,
533            )
534            sync_graph = gr.Checkbox(
535                label=i18n("Sync Graph"),
536                info=i18n(
537                    "Synchronize the graph of the tensorbaord. Only enable this setting if you are training a new model."
538                ),
539                value=False,
540                interactive=True,
541            )
542
543        with gr.Row():
544            with gr.Column(visible=False) as pretrained_custom_settings:
545                with gr.Accordion(i18n("Pretrained Custom Settings")):
546                    upload_pretrained = gr.File(
547                        label=i18n("Upload Pretrained Model"),
548                        type="filepath",
549                        interactive=True,
550                    )
551                    refresh_custom_pretaineds_button = gr.Button(
552                        i18n("Refresh Custom Pretraineds")
553                    )
554                    g_pretrained_path = gr.Dropdown(
555                        label=i18n("Custom Pretrained G"),
556                        info=i18n(
557                            "Select the custom pretrained model for the generator."
558                        ),
559                        choices=sorted(pretraineds_list_g),
560                        interactive=True,
561                        allow_custom_value=True,
562                    )
563                    d_pretrained_path = gr.Dropdown(
564                        label=i18n("Custom Pretrained D"),
565                        info=i18n(
566                            "Select the custom pretrained model for the discriminator."
567                        ),
568                        choices=sorted(pretraineds_list_d),
569                        interactive=True,
570                        allow_custom_value=True,
571                    )
572            with gr.Column(visible=False) as gpu_custom_settings:
573                with gr.Accordion(i18n("GPU Settings")):
574                    gpu = gr.Textbox(
575                        label=i18n("GPU Number"),
576                        info=i18n(
577                            "Specify the number of GPUs you wish to utilize for training by entering them separated by hyphens (-)."
578                        ),
579                        placeholder=i18n("0 to ∞ separated by -"),
580                        value="0",
581                        interactive=True,
582                    )
583                    gr.Textbox(
584                        label=i18n("GPU Information"),
585                        info=i18n("The GPU information will be displayed here."),
586                        value=get_gpu_info(),
587                        interactive=False,
588                    )
589            with gr.Column(visible=False) as overtraining_settings:
590                with gr.Accordion(i18n("Overtraining Detector Settings")):
591                    overtraining_threshold = gr.Slider(
592                        1,
593                        100,
594                        50,
595                        step=1,
596                        label=i18n("Overtraining Threshold"),
597                        info=i18n(
598                            "Set the maximum number of epochs you want your model to stop training if no improvement is detected."
599                        ),
600                        interactive=True,
601                    )
602
603        with gr.Row():
604            train_output_info = gr.Textbox(
605                label=i18n("Output Information"),
606                info=i18n("The output information will be displayed here."),
607                value="",
608                max_lines=8,
609                interactive=False,
610            )
611
612        with gr.Row():
613            train_button = gr.Button(i18n("Start Training"))
614            train_button.click(
615                fn=run_train_script,
616                inputs=[
617                    model_name,
618                    rvc_version,
619                    save_every_epoch,
620                    save_only_latest,
621                    save_every_weights,
622                    total_epoch,
623                    sampling_rate,
624                    batch_size,
625                    gpu,
626                    pitch_guidance,
627                    overtraining_detector,
628                    overtraining_threshold,
629                    pretrained,
630                    custom_pretrained,
631                    sync_graph,
632                    g_pretrained_path,
633                    d_pretrained_path,
634                ],
635                outputs=[train_output_info],
636                api_name="start_training",
637            )
638
639            stop_train_button = gr.Button(
640                i18n("Stop Training & Restart Applio"), visible=False
641            )
642            stop_train_button.click(
643                fn=restart_applio,
644                inputs=[],
645                outputs=[],
646            )
647
648            index_button = gr.Button(i18n("Generate Index"))
649            index_button.click(
650                fn=run_index_script,
651                inputs=[model_name, rvc_version],
652                outputs=[train_output_info],
653                api_name="generate_index",
654            )
655
656    with gr.Accordion(i18n("Export Model"), open=False):
657        if not os.name == "nt":
658            gr.Markdown(
659                i18n(
660                    "The button 'Upload' is only for google colab: Uploads the exported files to the ApplioExported folder in your Google Drive."
661                )
662            )
663        with gr.Row():
664            with gr.Column():
665                pth_file_export = gr.File(
666                    label=i18n("Exported Pth file"),
667                    type="filepath",
668                    value=None,
669                    interactive=False,
670                )
671                pth_dropdown_export = gr.Dropdown(
672                    label=i18n("Pth file"),
673                    info=i18n("Select the pth file to be exported"),
674                    choices=get_pth_list(),
675                    value=None,
676                    interactive=True,
677                    allow_custom_value=True,
678                )
679            with gr.Column():
680                index_file_export = gr.File(
681                    label=i18n("Exported Index File"),
682                    type="filepath",
683                    value=None,
684                    interactive=False,
685                )
686                index_dropdown_export = gr.Dropdown(
687                    label=i18n("Index File"),
688                    info=i18n("Select the index file to be exported"),
689                    choices=get_index_list(),
690                    value=None,
691                    interactive=True,
692                    allow_custom_value=True,
693                )
694        with gr.Row():
695            with gr.Column():
696                refresh_export = gr.Button(i18n("Refresh"))
697                if not os.name == "nt":
698                    upload_exported = gr.Button(i18n("Upload"), variant="primary")
699                    upload_exported.click(
700                        fn=upload_to_google_drive,
701                        inputs=[pth_dropdown_export, index_dropdown_export],
702                        outputs=[],
703                    )
704
705            def toggle_visible(checkbox):
706                return {"visible": checkbox, "__type__": "update"}
707
708            def toggle_visible_hop_length(f0method):
709                if f0method == "crepe" or f0method == "crepe-tiny":
710                    return {"visible": True, "__type__": "update"}
711                return {"visible": False, "__type__": "update"}
712
713            def toggle_pretrained(pretrained, custom_pretrained):
714                if custom_pretrained == False:
715                    return {"visible": pretrained, "__type__": "update"}, {
716                        "visible": False,
717                        "__type__": "update",
718                    }
719                else:
720                    return {"visible": pretrained, "__type__": "update"}, {
721                        "visible": pretrained,
722                        "__type__": "update",
723                    }
724
725            def enable_stop_train_button():
726                return {"visible": False, "__type__": "update"}, {
727                    "visible": True,
728                    "__type__": "update",
729                }
730
731            def disable_stop_train_button():
732                return {"visible": True, "__type__": "update"}, {
733                    "visible": False,
734                    "__type__": "update",
735                }
736
737            def download_prerequisites(version):
738                for remote_folder, file_list in pretraineds_v1:
739                    local_folder = folder_mapping.get(remote_folder, "")
740                    missing = False
741                    for file in file_list:
742                        destination_path = os.path.join(local_folder, file)
743                        if not os.path.exists(destination_path):
744                            missing = True
745                if version == "v1" and missing == True:
746                    gr.Info(
747                        "Downloading prerequisites... Please wait till it finishes to start preprocessing."
748                    )
749                    run_prerequisites_script("True", "False", "True", "True")
750                    gr.Info(
751                        "Prerequisites downloaded successfully, you may now start preprocessing."
752                    )
753
754            def toggle_visible_embedder_custom(embedder_model):
755                if embedder_model == "custom":
756                    return {"visible": True, "__type__": "update"}
757                return {"visible": False, "__type__": "update"}
758
759            rvc_version.change(
760                fn=download_prerequisites,
761                inputs=[rvc_version],
762                outputs=[],
763            )
764
765            refresh.click(
766                fn=refresh_models_and_datasets,
767                inputs=[],
768                outputs=[model_name, dataset_path],
769            )
770
771            dataset_creator.change(
772                fn=toggle_visible,
773                inputs=[dataset_creator],
774                outputs=[dataset_creator_settings],
775            )
776
777            upload_audio_dataset.upload(
778                fn=save_drop_dataset_audio,
779                inputs=[upload_audio_dataset, dataset_name],
780                outputs=[upload_audio_dataset, dataset_path],
781            )
782
783            f0method.change(
784                fn=toggle_visible_hop_length,
785                inputs=[f0method],
786                outputs=[hop_length],
787            )
788
789            embedder_model.change(
790                fn=toggle_visible_embedder_custom,
791                inputs=[embedder_model],
792                outputs=[embedder_custom],
793            )
794            embedder_upload_custom.upload(
795                fn=save_drop_custom_embedder,
796                inputs=[embedder_upload_custom],
797                outputs=[embedder_upload_custom],
798            )
799            embedder_custom_refresh.click(
800                fn=refresh_custom_embedder_list,
801                inputs=[],
802                outputs=[embedder_model_custom],
803            )
804
805            pretrained.change(
806                fn=toggle_pretrained,
807                inputs=[pretrained, custom_pretrained],
808                outputs=[custom_pretrained, pretrained_custom_settings],
809            )
810
811            custom_pretrained.change(
812                fn=toggle_visible,
813                inputs=[custom_pretrained],
814                outputs=[pretrained_custom_settings],
815            )
816
817            refresh_custom_pretaineds_button.click(
818                fn=refresh_custom_pretraineds,
819                inputs=[],
820                outputs=[g_pretrained_path, d_pretrained_path],
821            )
822
823            upload_pretrained.upload(
824                fn=save_drop_model,
825                inputs=[upload_pretrained],
826                outputs=[upload_pretrained],
827            )
828
829            overtraining_detector.change(
830                fn=toggle_visible,
831                inputs=[overtraining_detector],
832                outputs=[overtraining_settings],
833            )
834
835            multiple_gpu.change(
836                fn=toggle_visible,
837                inputs=[multiple_gpu],
838                outputs=[gpu_custom_settings],
839            )
840
841            train_button.click(
842                fn=enable_stop_train_button,
843                inputs=[],
844                outputs=[train_button, stop_train_button],
845            )
846
847            train_output_info.change(
848                fn=disable_stop_train_button,
849                inputs=[],
850                outputs=[train_button, stop_train_button],
851            )
852
853            pth_dropdown_export.change(
854                fn=export_pth,
855                inputs=[pth_dropdown_export],
856                outputs=[pth_file_export],
857            )
858
859            index_dropdown_export.change(
860                fn=export_index,
861                inputs=[index_dropdown_export],
862                outputs=[index_file_export],
863            )
864
865            refresh_export.click(
866                fn=refresh_pth_and_index_list,
867                inputs=[],
868                outputs=[pth_dropdown_export, index_dropdown_export],
869            )
870