| 13 | |
| 14 | |
| 15 | class DiffFsTask(FastSpeech2Task): |
| 16 | def build_tts_model(self): |
| 17 | mel_bins = hparams['audio_num_mel_bins'] |
| 18 | self.model = GaussianDiffusion( |
| 19 | phone_encoder=self.phone_encoder, |
| 20 | out_dims=mel_bins, denoise_fn=DIFF_DECODERS[hparams['diff_decoder_type']](hparams), |
| 21 | timesteps=hparams['timesteps'], |
| 22 | loss_type=hparams['diff_loss_type'], |
| 23 | spec_min=hparams['spec_min'], spec_max=hparams['spec_max'], |
| 24 | ) |
| 25 | |
| 26 | def run_model(self, model, sample, return_output=False, infer=False): |
| 27 | txt_tokens = sample['txt_tokens'] # [B, T_t] |
| 28 | target = sample['mels'] # [B, T_s, 80] |
| 29 | mel2ph = sample['mel2ph'] # [B, T_s] |
| 30 | f0 = sample['f0'] |
| 31 | uv = sample['uv'] |
| 32 | energy = sample['energy'] |
| 33 | spk_embed = sample.get('spk_embed') if not hparams['use_spk_id'] else sample.get('spk_ids') |
| 34 | if hparams['pitch_type'] == 'cwt': |
| 35 | cwt_spec = sample[f'cwt_spec'] |
| 36 | f0_mean = sample['f0_mean'] |
| 37 | f0_std = sample['f0_std'] |
| 38 | sample['f0_cwt'] = f0 = model.cwt2f0_norm(cwt_spec, f0_mean, f0_std, mel2ph) |
| 39 | |
| 40 | output = model(txt_tokens, mel2ph=mel2ph, spk_embed=spk_embed, |
| 41 | ref_mels=target, f0=f0, uv=uv, energy=energy, infer=infer) |
| 42 | |
| 43 | losses = {} |
| 44 | if 'diff_loss' in output: |
| 45 | losses['mel'] = output['diff_loss'] |
| 46 | self.add_dur_loss(output['dur'], mel2ph, txt_tokens, losses=losses) |
| 47 | if hparams['use_pitch_embed']: |
| 48 | self.add_pitch_loss(output, sample, losses) |
| 49 | if hparams['use_energy_embed']: |
| 50 | self.add_energy_loss(output['energy_pred'], energy, losses) |
| 51 | if not return_output: |
| 52 | return losses |
| 53 | else: |
| 54 | return losses, output |
| 55 | |
| 56 | def _training_step(self, sample, batch_idx, _): |
| 57 | log_outputs = self.run_model(self.model, sample) |
| 58 | total_loss = sum([v for v in log_outputs.values() if isinstance(v, torch.Tensor) and v.requires_grad]) |
| 59 | log_outputs['batch_size'] = sample['txt_tokens'].size()[0] |
| 60 | log_outputs['lr'] = self.scheduler.get_lr()[0] |
| 61 | return total_loss, log_outputs |
| 62 | |
| 63 | def validation_step(self, sample, batch_idx): |
| 64 | outputs = {} |
| 65 | outputs['losses'] = {} |
| 66 | outputs['losses'], model_out = self.run_model(self.model, sample, return_output=True, infer=False) |
| 67 | outputs['total_loss'] = sum(outputs['losses'].values()) |
| 68 | outputs['nsamples'] = sample['nsamples'] |
| 69 | outputs = utils.tensors_to_scalars(outputs) |
| 70 | if batch_idx < hparams['num_valid_plots']: |
| 71 | _, model_out = self.run_model(self.model, sample, return_output=True, infer=True) |
| 72 | self.plot_mel(batch_idx, sample['mels'], model_out['mel_out']) |
nothing calls this directly
no outgoing calls
no test coverage detected