CoolFace
Apppublic

fighter-programmer/voicegen

sourceHugging Faceupdated 4y agoView on Hugging Face
0likes
attentions.py301 linesDownload Raw Back to root
1import math2import torch3from torch import nn4from torch.nn import functional as F5 6import commons7from modules import LayerNorm8   9 10class Encoder(nn.Module):11  def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., window_size=4, **kwargs):12    super().__init__()13    self.hidden_channels = hidden_channels14    self.filter_channels = filter_channels15    self.n_heads = n_heads16    self.n_layers = n_layers17    self.kernel_size = kernel_size18    self.p_dropout = p_dropout19    self.window_size = window_size20 21    self.drop = nn.Dropout(p_dropout)22    self.attn_layers = nn.ModuleList()23    self.norm_layers_1 = nn.ModuleList()24    self.ffn_layers = nn.ModuleList()25    self.norm_layers_2 = nn.ModuleList()26    for i in range(self.n_layers):27      self.attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, window_size=window_size))28      self.norm_layers_1.append(LayerNorm(hidden_channels))29      self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout))30      self.norm_layers_2.append(LayerNorm(hidden_channels))31 32  def forward(self, x, x_mask):33    attn_mask = x_mask.unsqueeze(2) * x_mask.unsqueeze(-1)34    x = x * x_mask35    for i in range(self.n_layers):36      y = self.attn_layers[i](x, x, attn_mask)37      y = self.drop(y)38      x = self.norm_layers_1[i](x + y)39 40      y = self.ffn_layers[i](x, x_mask)41      y = self.drop(y)42      x = self.norm_layers_2[i](x + y)43    x = x * x_mask44    return x45 46 47class Decoder(nn.Module):48  def __init__(self, hidden_channels, filter_channels, n_heads, n_layers, kernel_size=1, p_dropout=0., proximal_bias=False, proximal_init=True, **kwargs):49    super().__init__()50    self.hidden_channels = hidden_channels51    self.filter_channels = filter_channels52    self.n_heads = n_heads53    self.n_layers = n_layers54    self.kernel_size = kernel_size55    self.p_dropout = p_dropout56    self.proximal_bias = proximal_bias57    self.proximal_init = proximal_init58 59    self.drop = nn.Dropout(p_dropout)60    self.self_attn_layers = nn.ModuleList()61    self.norm_layers_0 = nn.ModuleList()62    self.encdec_attn_layers = nn.ModuleList()63    self.norm_layers_1 = nn.ModuleList()64    self.ffn_layers = nn.ModuleList()65    self.norm_layers_2 = nn.ModuleList()66    for i in range(self.n_layers):67      self.self_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout, proximal_bias=proximal_bias, proximal_init=proximal_init))68      self.norm_layers_0.append(LayerNorm(hidden_channels))69      self.encdec_attn_layers.append(MultiHeadAttention(hidden_channels, hidden_channels, n_heads, p_dropout=p_dropout))70      self.norm_layers_1.append(LayerNorm(hidden_channels))71      self.ffn_layers.append(FFN(hidden_channels, hidden_channels, filter_channels, kernel_size, p_dropout=p_dropout, causal=True))72      self.norm_layers_2.append(LayerNorm(hidden_channels))73 74  def forward(self, x, x_mask, h, h_mask):75    """76    x: decoder input77    h: encoder output78    """79    self_attn_mask = commons.subsequent_mask(x_mask.size(2)).to(device=x.device, dtype=x.dtype)80    encdec_attn_mask = h_mask.unsqueeze(2) * x_mask.unsqueeze(-1)81    x = x * x_mask82    for i in range(self.n_layers):83      y = self.self_attn_layers[i](x, x, self_attn_mask)84      y = self.drop(y)85      x = self.norm_layers_0[i](x + y)86 87      y = self.encdec_attn_layers[i](x, h, encdec_attn_mask)88      y = self.drop(y)89      x = self.norm_layers_1[i](x + y)90      91      y = self.ffn_layers[i](x, x_mask)92      y = self.drop(y)93      x = self.norm_layers_2[i](x + y)94    x = x * x_mask95    return x96 97 98class MultiHeadAttention(nn.Module):99  def __init__(self, channels, out_channels, n_heads, p_dropout=0., window_size=None, heads_share=True, block_length=None, proximal_bias=False, proximal_init=False):100    super().__init__()101    assert channels % n_heads == 0102 103    self.channels = channels104    self.out_channels = out_channels105    self.n_heads = n_heads106    self.p_dropout = p_dropout107    self.window_size = window_size108    self.heads_share = heads_share109    self.block_length = block_length110    self.proximal_bias = proximal_bias111    self.proximal_init = proximal_init112    self.attn = None113 114    self.k_channels = channels // n_heads115    self.conv_q = nn.Conv1d(channels, channels, 1)116    self.conv_k = nn.Conv1d(channels, channels, 1)117    self.conv_v = nn.Conv1d(channels, channels, 1)118    self.conv_o = nn.Conv1d(channels, out_channels, 1)119    self.drop = nn.Dropout(p_dropout)120 121    if window_size is not None:122      n_heads_rel = 1 if heads_share else n_heads123      rel_stddev = self.k_channels**-0.5124      self.emb_rel_k = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)125      self.emb_rel_v = nn.Parameter(torch.randn(n_heads_rel, window_size * 2 + 1, self.k_channels) * rel_stddev)126 127    nn.init.xavier_uniform_(self.conv_q.weight)128    nn.init.xavier_uniform_(self.conv_k.weight)129    nn.init.xavier_uniform_(self.conv_v.weight)130    if proximal_init:131      with torch.no_grad():132        self.conv_k.weight.copy_(self.conv_q.weight)133        self.conv_k.bias.copy_(self.conv_q.bias)134      135  def forward(self, x, c, attn_mask=None):136    q = self.conv_q(x)137    k = self.conv_k(c)138    v = self.conv_v(c)139    140    x, self.attn = self.attention(q, k, v, mask=attn_mask)141 142    x = self.conv_o(x)143    return x144 145  def attention(self, query, key, value, mask=None):146    # reshape [b, d, t] -> [b, n_h, t, d_k]147    b, d, t_s, t_t = (*key.size(), query.size(2))148    query = query.view(b, self.n_heads, self.k_channels, t_t).transpose(2, 3)149    key = key.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)150    value = value.view(b, self.n_heads, self.k_channels, t_s).transpose(2, 3)151 152    scores = torch.matmul(query / math.sqrt(self.k_channels), key.transpose(-2, -1))153    if self.window_size is not None:154      assert t_s == t_t, "Relative attention is only available for self-attention."155      key_relative_embeddings = self._get_relative_embeddings(self.emb_rel_k, t_s)156      rel_logits = self._matmul_with_relative_keys(query /math.sqrt(self.k_channels), key_relative_embeddings)157      scores_local = self._relative_position_to_absolute_position(rel_logits)158      scores = scores + scores_local159    if self.proximal_bias:160      assert t_s == t_t, "Proximal bias is only available for self-attention."161      scores = scores + self._attention_bias_proximal(t_s).to(device=scores.device, dtype=scores.dtype)162    if mask is not None:163      scores = scores.masked_fill(mask == 0, -1e4)164      if self.block_length is not None:165        assert t_s == t_t, "Local attention is only available for self-attention."166        block_mask = torch.ones_like(scores).triu(-self.block_length).tril(self.block_length)167        scores = scores.masked_fill(block_mask == 0, -1e4)168    p_attn = F.softmax(scores, dim=-1) # [b, n_h, t_t, t_s]169    p_attn = self.drop(p_attn)170    output = torch.matmul(p_attn, value)171    if self.window_size is not None:172      relative_weights = self._absolute_position_to_relative_position(p_attn)173      value_relative_embeddings = self._get_relative_embeddings(self.emb_rel_v, t_s)174      output = output + self._matmul_with_relative_values(relative_weights, value_relative_embeddings)175    output = output.transpose(2, 3).contiguous().view(b, d, t_t) # [b, n_h, t_t, d_k] -> [b, d, t_t]176    return output, p_attn177 178  def _matmul_with_relative_values(self, x, y):179    """180    x: [b, h, l, m]181    y: [h or 1, m, d]182    ret: [b, h, l, d]183    """184    ret = torch.matmul(x, y.unsqueeze(0))185    return ret186 187  def _matmul_with_relative_keys(self, x, y):188    """189    x: [b, h, l, d]190    y: [h or 1, m, d]191    ret: [b, h, l, m]192    """193    ret = torch.matmul(x, y.unsqueeze(0).transpose(-2, -1))194    return ret195 196  def _get_relative_embeddings(self, relative_embeddings, length):197    max_relative_position = 2 * self.window_size + 1198    # Pad first before slice to avoid using cond ops.199    pad_length = max(length - (self.window_size + 1), 0)200    slice_start_position = max((self.window_size + 1) - length, 0)201    slice_end_position = slice_start_position + 2 * length - 1202    if pad_length > 0:203      padded_relative_embeddings = F.pad(204          relative_embeddings,205          commons.convert_pad_shape([[0, 0], [pad_length, pad_length], [0, 0]]))206    else:207      padded_relative_embeddings = relative_embeddings208    used_relative_embeddings = padded_relative_embeddings[:,slice_start_position:slice_end_position]209    return used_relative_embeddings210 211  def _relative_position_to_absolute_position(self, x):212    """213    x: [b, h, l, 2*l-1]214    ret: [b, h, l, l]215    """216    batch, heads, length, _ = x.size()217    # Concat columns of pad to shift from relative to absolute indexing.218    x = F.pad(x, commons.convert_pad_shape([[0,0],[0,0],[0,0],[0,1]]))219 220    # Concat extra elements so to add up to shape (len+1, 2*len-1).221    x_flat = x.view([batch, heads, length * 2 * length])222    x_flat = F.pad(x_flat, commons.convert_pad_shape([[0,0],[0,0],[0,length-1]]))223 224    # Reshape and slice out the padded elements.225    x_final = x_flat.view([batch, heads, length+1, 2*length-1])[:, :, :length, length-1:]226    return x_final227 228  def _absolute_position_to_relative_position(self, x):229    """230    x: [b, h, l, l]231    ret: [b, h, l, 2*l-1]232    """233    batch, heads, length, _ = x.size()234    # padd along column235    x = F.pad(x, commons.convert_pad_shape([[0, 0], [0, 0], [0, 0], [0, length-1]]))236    x_flat = x.view([batch, heads, length**2 + length*(length -1)])237    # add 0's in the beginning that will skew the elements after reshape238    x_flat = F.pad(x_flat, commons.convert_pad_shape([[0, 0], [0, 0], [length, 0]]))239    x_final = x_flat.view([batch, heads, length, 2*length])[:,:,:,1:]240    return x_final241 242  def _attention_bias_proximal(self, length):243    """Bias for self-attention to encourage attention to close positions.244    Args:245      length: an integer scalar.246    Returns:247      a Tensor with shape [1, 1, length, length]248    """249    r = torch.arange(length, dtype=torch.float32)250    diff = torch.unsqueeze(r, 0) - torch.unsqueeze(r, 1)251    return torch.unsqueeze(torch.unsqueeze(-torch.log1p(torch.abs(diff)), 0), 0)252 253 254class FFN(nn.Module):255  def __init__(self, in_channels, out_channels, filter_channels, kernel_size, p_dropout=0., activation=None, causal=False):256    super().__init__()257    self.in_channels = in_channels258    self.out_channels = out_channels259    self.filter_channels = filter_channels260    self.kernel_size = kernel_size261    self.p_dropout = p_dropout262    self.activation = activation263    self.causal = causal264 265    if causal:266      self.padding = self._causal_padding267    else:268      self.padding = self._same_padding269 270    self.conv_1 = nn.Conv1d(in_channels, filter_channels, kernel_size)271    self.conv_2 = nn.Conv1d(filter_channels, out_channels, kernel_size)272    self.drop = nn.Dropout(p_dropout)273 274  def forward(self, x, x_mask):275    x = self.conv_1(self.padding(x * x_mask))276    if self.activation == "gelu":277      x = x * torch.sigmoid(1.702 * x)278    else:279      x = torch.relu(x)280    x = self.drop(x)281    x = self.conv_2(self.padding(x * x_mask))282    return x * x_mask283  284  def _causal_padding(self, x):285    if self.kernel_size == 1:286      return x287    pad_l = self.kernel_size - 1288    pad_r = 0289    padding = [[0, 0], [0, 0], [pad_l, pad_r]]290    x = F.pad(x, commons.convert_pad_shape(padding))291    return x292 293  def _same_padding(self, x):294    if self.kernel_size == 1:295      return x296    pad_l = (self.kernel_size - 1) // 2297    pad_r = self.kernel_size // 2298    padding = [[0, 0], [0, 0], [pad_l, pad_r]]299    x = F.pad(x, commons.convert_pad_shape(padding))300    return x301