Skip to content

Commit 432b620

Browse files
committed
feat: add newpytorch UI toggle + improve training UI layout
- Add New PyTorch 2.0+ Format checkbox in training UI - Wire newpytorch flag through training service to runner - Calls configure_weight_norm() before model creation - Training UI: numbered steps, section groupings with headers (Training Parameters, PyTorch Weight Format, Training Options, Pretrain & Dataset, Advanced Settings) - Cleaner accordion labels and button text
1 parent de1b2aa commit 432b620

3 files changed

Lines changed: 93 additions & 60 deletions

File tree

arvc/app/tabs/training/child/training.py

Lines changed: 80 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def training_model_tab():
1515
gr.Markdown(translations["training_markdown"])
1616

1717
# ── Step 1: Dataset Preprocessing ──
18-
with gr.Accordion("Step 1: Dataset Preprocessing", open=True):
18+
with gr.Accordion("1. Dataset Preprocessing", open=True):
1919
training_name = gr.Textbox(
2020
label=translations["modelname"],
2121
info=translations["training_model_name"],
@@ -98,7 +98,7 @@ def training_model_tab():
9898
preprocess_info = gr.Textbox(label=translations["preprocess_info"], value="", interactive=False, lines=2)
9999

100100
# ── Step 2: Feature Extraction ──
101-
with gr.Accordion("Step 2: Feature Extraction", open=False):
101+
with gr.Accordion("2. Feature Extraction", open=False):
102102
with gr.Row(equal_height=False):
103103
with gr.Column(scale=1):
104104
gr.Markdown(f"**{translations['f0_method']}**")
@@ -151,64 +151,87 @@ def training_model_tab():
151151
extract_info = gr.Textbox(label=translations["extract_info"], value="", interactive=False, lines=2)
152152

153153
# ── Step 3: Index Creation ──
154-
with gr.Accordion("Step 3: Index Creation", open=False):
154+
with gr.Accordion("3. Index Creation", open=False):
155155
index_algorithm = gr.Radio(
156156
label=translations["index_algorithm"], info=translations["index_algorithm_info"],
157157
choices=["Auto", "Faiss", "KMeans"], value="Auto", interactive=True,
158158
)
159-
index_button = gr.Button(f"3. {translations['create_index']}", variant="secondary")
159+
index_button = gr.Button(translations["create_index"], variant="secondary")
160160

161161
# ── Step 4: Model Training ──
162-
with gr.Accordion("Step 4: Model Training", open=False):
163-
with gr.Row(equal_height=False):
164-
with gr.Column(scale=1):
165-
total_epochs = gr.Slider(
166-
label=translations["total_epoch"], info=translations["total_epoch_info"],
167-
minimum=1, maximum=10000, value=10, step=1, interactive=True,
168-
)
169-
save_epochs = gr.Slider(
170-
label=translations["save_epoch"], info=translations["save_epoch_info"],
171-
minimum=1, maximum=10000, value=5, step=1, interactive=True,
172-
)
173-
train_batch_size = gr.Slider(
174-
label=translations["batch_size"], info=translations["batch_size_info"],
175-
minimum=1, maximum=64, value=8, step=1, interactive=True,
176-
)
177-
with gr.Column(scale=1):
178-
vocoders = gr.Dropdown(
179-
label=translations["vocoder"], info=translations["vocoder_info"],
180-
choices=get_vocoder_choices(), value=get_vocoder_choices()[0],
181-
interactive=True, allow_custom_value=True,
182-
)
183-
optimizer = gr.Dropdown(
184-
label=translations["optimizer"],
185-
info=translations.get("optimizer_info", "Optimizer in training, AdamW is default."),
186-
value="AdamW", choices=get_optimizer_choices(),
187-
interactive=True, allow_custom_value=False,
188-
)
189-
model_author = gr.Textbox(
190-
label=translations["training_author"],
191-
info=translations["training_author_info"],
192-
value="", placeholder=translations["training_author"], interactive=True,
193-
)
162+
with gr.Accordion("4. Model Training", open=False):
163+
# ── Training Parameters ──
164+
with gr.Group():
165+
gr.Markdown("### Training Parameters")
166+
with gr.Row(equal_height=False):
167+
with gr.Column(scale=1):
168+
total_epochs = gr.Slider(
169+
label=translations["total_epoch"], info=translations["total_epoch_info"],
170+
minimum=1, maximum=10000, value=10, step=1, interactive=True,
171+
)
172+
save_epochs = gr.Slider(
173+
label=translations["save_epoch"], info=translations["save_epoch_info"],
174+
minimum=1, maximum=10000, value=5, step=1, interactive=True,
175+
)
176+
train_batch_size = gr.Slider(
177+
label=translations["batch_size"], info=translations["batch_size_info"],
178+
minimum=1, maximum=64, value=8, step=1, interactive=True,
179+
)
180+
with gr.Column(scale=1):
181+
vocoders = gr.Dropdown(
182+
label=translations["vocoder"], info=translations["vocoder_info"],
183+
choices=get_vocoder_choices(), value=get_vocoder_choices()[0],
184+
interactive=True, allow_custom_value=True,
185+
)
186+
optimizer = gr.Dropdown(
187+
label=translations["optimizer"],
188+
info=translations.get("optimizer_info", "Optimizer in training, AdamW is default."),
189+
value="AdamW", choices=get_optimizer_choices(),
190+
interactive=True, allow_custom_value=False,
191+
)
192+
model_author = gr.Textbox(
193+
label=translations["training_author"],
194+
info=translations["training_author_info"],
195+
value="", placeholder=translations["training_author"], interactive=True,
196+
)
194197

195-
with gr.Row():
196-
cache_in_gpu = gr.Checkbox(label=translations["cache_in_gpu"], info=translations["cache_in_gpu_info"], value=True, interactive=True)
197-
overtraining_detector = gr.Checkbox(label=translations["overtraining_detector"], info=translations["overtraining_detector_info"], value=False, interactive=True)
198-
checkpointing1 = gr.Checkbox(label=translations["memory_efficient_training"], value=False, interactive=True)
199-
with gr.Row():
200-
save_only_latest = gr.Checkbox(label=translations["save_only_latest"], info=translations["save_only_latest_info"], value=True, interactive=True)
201-
save_every_weights = gr.Checkbox(label=translations["save_every_weights"], info=translations["save_every_weights_info"], value=True, interactive=True)
202-
clean_up = gr.Checkbox(label=translations["cleanup_training"], info=translations["cleanup_training_info"], value=False, interactive=True)
203-
with gr.Row():
204-
not_use_pretrain = gr.Checkbox(label=translations["not_use_pretrain_2"], info=translations["not_use_pretrain_info"], value=False, interactive=True)
205-
custom_pretrain = gr.Checkbox(label=translations["custom_pretrain"], info=translations["custom_pretrain_info"], value=False, interactive=True)
206-
custom_dataset = gr.Checkbox(label=translations["custom_dataset"], info=translations["custom_dataset_info"], value=False, interactive=True)
207-
with gr.Row():
208-
multiscale_mel_loss = gr.Checkbox(label=translations["multiscale_mel_loss"], info=translations["multiscale_mel_loss_info"], value=False, interactive=True)
209-
cosine_lr = gr.Checkbox(label="Cosine Annealing LR", info="Use CosineAnnealingLR scheduler for better training quality (recommended)", value=True, interactive=True)
210-
deterministic = gr.Checkbox(label=translations["deterministic"], info=translations["deterministic_info"], value=False, interactive=config.device.startswith("cuda"))
211-
benchmark = gr.Checkbox(label=translations["benchmark"], info=translations["benchmark_info"], value=False, interactive=config.device.startswith("cuda"))
198+
# ── PyTorch Weight Format ──
199+
with gr.Group():
200+
gr.Markdown("### PyTorch Weight Format")
201+
newpytorch = gr.Checkbox(
202+
label="New PyTorch 2.0+ Format",
203+
info="Enable PyTorch 2.0+ parametrization format. Default: OFF = Old format (.weight_g/.weight_v) for broad RVC fork compatibility.",
204+
value=False, interactive=True,
205+
)
206+
207+
# ── Training Options ──
208+
with gr.Group():
209+
gr.Markdown("### Training Options")
210+
with gr.Row():
211+
cache_in_gpu = gr.Checkbox(label=translations["cache_in_gpu"], info=translations["cache_in_gpu_info"], value=True, interactive=True)
212+
overtraining_detector = gr.Checkbox(label=translations["overtraining_detector"], info=translations["overtraining_detector_info"], value=False, interactive=True)
213+
checkpointing1 = gr.Checkbox(label=translations["memory_efficient_training"], value=False, interactive=True)
214+
with gr.Row():
215+
save_only_latest = gr.Checkbox(label=translations["save_only_latest"], info=translations["save_only_latest_info"], value=True, interactive=True)
216+
save_every_weights = gr.Checkbox(label=translations["save_every_weights"], info=translations["save_every_weights_info"], value=True, interactive=True)
217+
clean_up = gr.Checkbox(label=translations["cleanup_training"], info=translations["cleanup_training_info"], value=False, interactive=True)
218+
219+
# ── Pretrain & Dataset ──
220+
with gr.Group():
221+
gr.Markdown("### Pretrain & Dataset")
222+
with gr.Row():
223+
not_use_pretrain = gr.Checkbox(label=translations["not_use_pretrain_2"], info=translations["not_use_pretrain_info"], value=False, interactive=True)
224+
custom_pretrain = gr.Checkbox(label=translations["custom_pretrain"], info=translations["custom_pretrain_info"], value=False, interactive=True)
225+
custom_dataset = gr.Checkbox(label=translations["custom_dataset"], info=translations["custom_dataset_info"], value=False, interactive=True)
226+
227+
# ── Advanced Settings ──
228+
with gr.Group():
229+
gr.Markdown("### Advanced Settings")
230+
with gr.Row():
231+
multiscale_mel_loss = gr.Checkbox(label=translations["multiscale_mel_loss"], info=translations["multiscale_mel_loss_info"], value=False, interactive=True)
232+
cosine_lr = gr.Checkbox(label="Cosine Annealing LR", info="Use CosineAnnealingLR scheduler for better training quality (recommended)", value=True, interactive=True)
233+
deterministic = gr.Checkbox(label=translations["deterministic"], info=translations["deterministic_info"], value=False, interactive=config.device.startswith("cuda"))
234+
benchmark = gr.Checkbox(label=translations["benchmark"], info=translations["benchmark_info"], value=False, interactive=config.device.startswith("cuda"))
212235

213236
dataset_path = gr.Textbox(label=translations["dataset_folder"], value="arvc/assets/dataset", interactive=True, visible=False)
214237
threshold = gr.Slider(minimum=1, maximum=100, value=50, step=1, label=translations["threshold"], interactive=True, visible=False)
@@ -289,11 +312,11 @@ def on_pretrained_sr_select(model, sr):
289312
info=translations["gpu_info_2"], interactive=False,
290313
)
291314

292-
training_button = gr.Button(f"4. {translations['training_model']}", variant="primary")
315+
training_button = gr.Button(translations["training_model"], variant="primary")
293316
training_info = gr.Textbox(label=translations["train_info"], value="", interactive=False, lines=4)
294317

295318
# ── Export Model ──
296-
with gr.Accordion("Export Model", open=False):
319+
with gr.Accordion("5. Export Model", open=False):
297320
with gr.Row():
298321
model_file = gr.Dropdown(
299322
label=translations["model_name"], choices=model_name,
@@ -306,7 +329,7 @@ def on_pretrained_sr_select(model, sr):
306329
interactive=True, allow_custom_value=True,
307330
)
308331
with gr.Row():
309-
refresh_file = gr.Button(f"1. {translations['refresh']}")
332+
refresh_file = gr.Button(translations["refresh"])
310333
zip_model = gr.Button(translations["zip_model"], variant="primary")
311334
zip_output = gr.File(label=translations["output_zip"], file_types=[".zip"], interactive=False, visible=False)
312335

@@ -376,7 +399,7 @@ def on_pretrained_sr_select(model, sr):
376399
not_use_pretrain, custom_pretrain, pretrained_G, pretrained_D, overtraining_detector,
377400
threshold, clean_up, cache_in_gpu, model_author, vocoders, checkpointing1,
378401
deterministic, benchmark, optimizer, rms_extract, custom_reference, reference_name,
379-
multiscale_mel_loss, cosine_lr
402+
multiscale_mel_loss, cosine_lr, newpytorch
380403
],
381404
outputs=[training_info],
382405
api_name="training_model"

arvc/engine/training/runner/train.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def __contains__(self, key):
9191
latest_checkpoint_path,
9292
plot_spectrogram_to_numpy,
9393
)
94-
from arvc.engine.models.weight_norm import convert_old_to_new
94+
from arvc.engine.models.weight_norm import convert_old_to_new, configure_weight_norm, use_new_pytorch
9595

9696
from arvc.utils.variables import config as main_config
9797
from arvc.utils.variables import configs as main_configs
@@ -134,6 +134,7 @@ def parse_arguments():
134134
parser.add_argument("--compile_model", type=lambda x: bool(strtobool(x)), default=False, help="Use torch.compile() on generator for PyTorch 2.x speedup")
135135
parser.add_argument("--use_8bit_adam", type=lambda x: bool(strtobool(x)), default=False, help="Use 8-bit Adam optimizer for lower VRAM (requires bitsandbytes)")
136136
parser.add_argument("--grad_accum_steps", type=int, default=1, help="Gradient accumulation steps (reduces VRAM usage with larger effective batch sizes)")
137+
parser.add_argument("--newpytorch", type=lambda x: bool(strtobool(x)), default=False, help="Use PyTorch 2.0+ parametrization format. Default: old format for RVC fork compatibility.")
137138

138139
return parser.parse_args()
139140

@@ -172,6 +173,7 @@ def parse_arguments():
172173
compile_model,
173174
use_8bit_adam,
174175
grad_accum_steps,
176+
newpytorch,
175177
) = (
176178
args.model_name,
177179
args.save_every_epoch,
@@ -201,8 +203,16 @@ def parse_arguments():
201203
args.compile_model,
202204
args.use_8bit_adam,
203205
args.grad_accum_steps,
206+
args.newpytorch,
204207
)
205208

209+
# ── Configure weight_norm mode BEFORE any model creation ──
210+
configure_weight_norm(newpytorch)
211+
if newpytorch:
212+
if __name__ == "__main__": print(f"[Advanced-RVC] PyTorch weight format: NEW (2.0+ parametrization)")
213+
else:
214+
if __name__ == "__main__": print(f"[Advanced-RVC] PyTorch weight format: OLD (weight_norm, RVC fork compatible)")
215+
206216
# Discriminator version: use v3 discriminator for non-HiFi-GAN vocoders
207217
disc_version = version if vocoder not in ["RefineGAN", "BigVGAN"] else "v3"
208218

arvc/services/training.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def create_index(model_name, rvc_version, index_algorithm):
144144
for log in log_read(done, "create_index"):
145145
yield log
146146

147-
def training(model_name, rvc_version, save_every_epoch, save_only_latest, save_every_weights, total_epoch, sample_rate, batch_size, gpu, pitch_guidance, not_pretrain, custom_pretrained, pretrain_g, pretrain_d, detector, threshold, clean_up, cache, model_author, vocoder, checkpointing, deterministic, benchmark, optimizer, energy_use, custom_reference=False, reference_name="", multiscale_mel_loss=False, cosine_lr=False):
147+
def training(model_name, rvc_version, save_every_epoch, save_only_latest, save_every_weights, total_epoch, sample_rate, batch_size, gpu, pitch_guidance, not_pretrain, custom_pretrained, pretrain_g, pretrain_d, detector, threshold, clean_up, cache, model_author, vocoder, checkpointing, deterministic, benchmark, optimizer, energy_use, custom_reference=False, reference_name="", multiscale_mel_loss=False, cosine_lr=False, newpytorch=False):
148148
sr = int(float(sample_rate.rstrip("k")) * 1000)
149149
if not model_name: return gr_warning(translations["provide_name"])
150150

@@ -303,7 +303,7 @@ def _download_pretrained(file_url, file_path, url_sources):
303303

304304
gr_info(translations["start"].format(start=translations["training"]))
305305

306-
p = subprocess.Popen(f'{python} {configs["train_path"]} --model_name "{model_name}" --rvc_version {rvc_version} --save_every_epoch {save_every_epoch} --save_only_latest {save_only_latest} --save_every_weights {save_every_weights} --total_epoch {total_epoch} --batch_size {batch_size} --gpu {gpu} --pitch_guidance {pitch_guidance} --overtraining_detector {detector} --overtraining_threshold {threshold} --cleanup {clean_up} --cache_data_in_gpu {cache} --g_pretrained_path "{pretrained_G}" --d_pretrained_path "{pretrained_D}" --model_author "{model_author}" --vocoder "{vocoder}" --checkpointing {checkpointing} --deterministic {deterministic} --benchmark {benchmark} --optimizer {optimizer} --energy_use {energy_use} --use_custom_reference {custom_reference} --reference_path {reference_path} --multiscale_mel_loss {multiscale_mel_loss} --use_cosine_annealing_lr {cosine_lr}', shell=True)
306+
p = subprocess.Popen(f'{python} {configs["train_path"]} --model_name "{model_name}" --rvc_version {rvc_version} --save_every_epoch {save_every_epoch} --save_only_latest {save_only_latest} --save_every_weights {save_every_weights} --total_epoch {total_epoch} --batch_size {batch_size} --gpu {gpu} --pitch_guidance {pitch_guidance} --overtraining_detector {detector} --overtraining_threshold {threshold} --cleanup {clean_up} --cache_data_in_gpu {cache} --g_pretrained_path "{pretrained_G}" --d_pretrained_path "{pretrained_D}" --model_author "{model_author}" --vocoder "{vocoder}" --checkpointing {checkpointing} --deterministic {deterministic} --benchmark {benchmark} --optimizer {optimizer} --energy_use {energy_use} --use_custom_reference {custom_reference} --reference_path {reference_path} --multiscale_mel_loss {multiscale_mel_loss} --use_cosine_annealing_lr {cosine_lr} --newpytorch {newpytorch}', shell=True)
307307
done = [False]
308308

309309
with open(os.path.join(model_dir, "train_pid.txt"), "w") as pid_file:

0 commit comments

Comments
 (0)