| import random |
| import torch |
| import torch.nn as nn |
|
|
| class AccousticTransformer(nn.Module): |
| def __init__(self, max_seq_len, phonemes_vocab, emb_dim, n_head, max_time_frames): |
| super(AccousticTransformer, self).__init__() |
| self.embedding = nn.Embedding(phonemes_vocab, emb_dim) |
|
|
| self.pos_embedding = nn.Embedding(max_seq_len, emb_dim) |
|
|
| self.mel_pos_embedding = nn.Embedding(max_time_frames, emb_dim) |
|
|
| self.encoder_layer = nn.TransformerEncoderLayer( |
| d_model=emb_dim, |
| nhead=n_head, |
| dim_feedforward=2048, |
| dropout=0.1, |
| batch_first=True |
| ) |
|
|
| self.encoder = nn.TransformerEncoder( |
| self.encoder_layer, |
| num_layers=6 |
| ) |
|
|
| self.decoder_layer = nn.TransformerDecoderLayer( |
| d_model=emb_dim, |
| nhead=n_head, |
| dim_feedforward=2048, |
| dropout=0.1, |
| batch_first=True |
| ) |
| self.decoder = nn.TransformerDecoder( |
| self.decoder_layer, |
| num_layers=6 |
| ) |
| |
| self.duration_predictor = DurationPredictor(emb_dim=emb_dim) |
| self.length_regulator = LengthRegulator() |
|
|
| self.output_layer = nn.Linear(emb_dim, 80) |
|
|
| def forward(self, X, gt_durations = None): |
| |
| positions = torch.arange(X.shape[1], device=X.device) |
| X = self.embedding(X) + self.pos_embedding(positions) |
| encoder_output = self.encoder(X) |
|
|
| predicted_durations = self.duration_predictor(encoder_output) |
|
|
| if gt_durations is not None: |
| durations = gt_durations |
| else: |
| durations = predicted_durations.round().long() |
|
|
| expanded = self.length_regulator(encoder_output, durations) |
|
|
| mel_positions = torch.arange(expanded.shape[1], device=expanded.device) |
| expanded = expanded + self.mel_pos_embedding(mel_positions) |
|
|
| decoder_output = self.decoder( |
| tgt=expanded, |
| memory=encoder_output |
| ) |
|
|
| predicted_mel = self.output_layer(decoder_output) |
| predicted_mel = predicted_mel.transpose(1,2) |
|
|
| return predicted_mel, predicted_durations |
|
|
|
|
| class DurationPredictor(nn.Module): |
| def __init__(self, emb_dim): |
| super(DurationPredictor, self).__init__() |
| self.conv1 = nn.Conv1d( |
| in_channels= emb_dim, |
| out_channels= emb_dim, |
| kernel_size= 3, |
| padding= 1 |
| ) |
|
|
| self.conv2 = nn.Conv1d( |
| in_channels= emb_dim, |
| out_channels= emb_dim, |
| kernel_size= 3, |
| padding= 1 |
| ) |
|
|
| self.norm1 = nn.LayerNorm(emb_dim) |
| |
|
|
| self.norm2 = nn.LayerNorm(emb_dim) |
|
|
| self.linear = nn.Linear(emb_dim, 1) |
| |
| |
| |
|
|
| |
| |
|
|
| self.output_activation = nn.ReLU() |
| |
|
|
| self.activation = nn.GELU() |
|
|
| def forward(self, x): |
| |
| x = x.transpose(1,2) |
| x = self.conv1(x) |
| |
| x = x.transpose(1,2) |
| |
| |
| x = self.norm1(x) |
| x = self.activation(x) |
|
|
| |
| x = x.transpose(1,2) |
| x = self.conv2(x) |
| x = x.transpose(1,2) |
| x = self.norm2(x) |
| x = self.activation(x) |
|
|
| |
| x = self.linear(x) |
| x = self.output_activation(x) |
| x = x.squeeze(-1) |
| |
| |
| return x |
|
|
| class LengthRegulator(nn.Module): |
| def __init__(self): |
| super(LengthRegulator, self).__init__() |
|
|
| def forward(self, encoder_output, durations): |
| |
| |
|
|
| batch_size = encoder_output.shape[0] |
| outputs = [] |
|
|
| for i in range(batch_size): |
|
|
| expanded = torch.repeat_interleave( |
| input=encoder_output[i], |
| repeats=durations[i].long(), |
| |
| |
| dim=0 |
| ) |
|
|
| outputs.append(expanded) |
|
|
| |
| |
| |
|
|
| output = torch.nn.utils.rnn.pad_sequence( |
| sequences=outputs, |
| batch_first = True, |
| |
| padding_value = 0.0 |
| ) |
|
|
| |
| return output |