[GH-ISSUE #1079] Training Loop Update For Gen vs. Disc #715

Open
opened 2026-10-20 10:02:14 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @an-internet-user001 on GitHub (Aug 23, 2023).
Original GitHub issue: https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/issues/1079

Hello,

I've read i few articles that suggest it may make sense at certain stages/iterations of training to update the training loop where the Generator is updated at a ratio of 2:1 versus the Discriminator. I am a hobbyist at best, and was wondering if anyone could provide insight into where/how to implement this option in the code versus me trying to figure out over the next month :)

Originally created by @an-internet-user001 on GitHub (Aug 23, 2023). Original GitHub issue: https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/issues/1079 Hello, I've read i few articles that suggest it may make sense at certain stages/iterations of training to update the training loop where the Generator is updated at a ratio of 2:1 versus the Discriminator. I am a hobbyist at best, and was wondering if anyone could provide insight into where/how to implement this option in the code versus me trying to figure out over the next month :)
Author
Owner

@RVC-Boss commented on GitHub (Aug 30, 2023):

This is a good trial point, and currently I have maintained it the same as baseline and have not attempted to improve the optimization cycle of G/D.

<!-- gh-comment-id:1698398390 --> @RVC-Boss commented on GitHub (Aug 30, 2023): This is a good trial point, and currently I have maintained it the same as baseline and have not attempted to improve the optimization cycle of G/D.
Author
Owner

@an-internet-user001 commented on GitHub (Aug 30, 2023):

So, i think the place this is determined is here: train_nsf_sim_cache_sid_load_pretrain.py.

I just implemented a loop for when the Generator is updated, as have been having models where the discriminator is outperforming. Too soon to tell how effective this is in my scenario but it's interesting. I think it would be cool if it were possible to manipulate the parameters for each in the GUI before training starts.

if hps.train.fp16_run == True:
            y_hat_mel = y_hat_mel.half()
        wave = commons.slice_segments(
            wave, ids_slice * hps.data.hop_length, hps.train.segment_size
        )  # slice

        # Discriminator
        y_d_hat_r, y_d_hat_g, _, _ = net_d(wave, y_hat.detach())
        with autocast(enabled=False):
            loss_disc, losses_disc_r, losses_disc_g = discriminator_loss(
                y_d_hat_r, y_d_hat_g
            )
    optim_d.zero_grad()
    scaler.scale(loss_disc).backward()
    scaler.unscale_(optim_d)
    grad_norm_d = commons.clip_grad_value_(net_d.parameters(), None)
    scaler.step(optim_d)

    # Update the Generator 2 times
    for _ in range(2):
        with autocast(enabled=hps.train.fp16_run):
            y_d_hat_r, y_d_hat_g, fmap_r, fmap_g = net_d(wave, y_hat)
            with autocast(enabled=False):
                loss_mel = F.l1_loss(y_mel, y_hat_mel) * hps.train.c_mel
                loss_kl = kl_loss(z_p, logs_q, m_p, logs_p, z_mask) * hps.train.c_kl
                loss_fm = feature_loss(fmap_r, fmap_g)
                loss_gen, losses_gen = generator_loss(y_d_hat_g)
                loss_gen_all = loss_gen + loss_fm + loss_mel + loss_kl
        optim_g.zero_grad()
        scaler.scale(loss_gen_all).backward(retain_graph=True)
        scaler.unscale_(optim_g)
        grad_norm_g = commons.clip_grad_value_(net_g.parameters(), None)
        scaler.step(optim_g)
        scaler.update()

    if rank == 0:
        if global_step % hps.train.log_interval == 0:
            lr = optim_g.param_groups[0]["lr"]
            logger.info(
                "Train Epoch: {} [{:.0f}%]".format(
                    epoch, 100.0 * batch_idx / len(train_loader)
<!-- gh-comment-id:1698489000 --> @an-internet-user001 commented on GitHub (Aug 30, 2023): So, i think the place this is determined is here: train_nsf_sim_cache_sid_load_pretrain.py. I just implemented a loop for when the Generator is updated, as have been having models where the discriminator is outperforming. Too soon to tell how effective this is in my scenario but it's interesting. I think it would be cool if it were possible to manipulate the parameters for each in the GUI before training starts. if hps.train.fp16_run == True: y_hat_mel = y_hat_mel.half() wave = commons.slice_segments( wave, ids_slice * hps.data.hop_length, hps.train.segment_size ) # slice # Discriminator y_d_hat_r, y_d_hat_g, _, _ = net_d(wave, y_hat.detach()) with autocast(enabled=False): loss_disc, losses_disc_r, losses_disc_g = discriminator_loss( y_d_hat_r, y_d_hat_g ) optim_d.zero_grad() scaler.scale(loss_disc).backward() scaler.unscale_(optim_d) grad_norm_d = commons.clip_grad_value_(net_d.parameters(), None) scaler.step(optim_d) # Update the Generator 2 times for _ in range(2): with autocast(enabled=hps.train.fp16_run): y_d_hat_r, y_d_hat_g, fmap_r, fmap_g = net_d(wave, y_hat) with autocast(enabled=False): loss_mel = F.l1_loss(y_mel, y_hat_mel) * hps.train.c_mel loss_kl = kl_loss(z_p, logs_q, m_p, logs_p, z_mask) * hps.train.c_kl loss_fm = feature_loss(fmap_r, fmap_g) loss_gen, losses_gen = generator_loss(y_d_hat_g) loss_gen_all = loss_gen + loss_fm + loss_mel + loss_kl optim_g.zero_grad() scaler.scale(loss_gen_all).backward(retain_graph=True) scaler.unscale_(optim_g) grad_norm_g = commons.clip_grad_value_(net_g.parameters(), None) scaler.step(optim_g) scaler.update() if rank == 0: if global_step % hps.train.log_interval == 0: lr = optim_g.param_groups[0]["lr"] logger.info( "Train Epoch: {} [{:.0f}%]".format( epoch, 100.0 * batch_idx / len(train_loader)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
RVC-Project/Retrieval-based-Voice-Conversion-WebUI#715
No description provided.