CoolFace
Apppublic

mosibi/RVC_HFv2

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
model.py203 linesDownload Raw Back to demucs
1# Copyright (c) Facebook, Inc. and its affiliates.2# All rights reserved.3#4# This source code is licensed under the license found in the5# LICENSE file in the root directory of this source tree.6 7import math8 9import julius10from torch import nn11 12from .utils import capture_init, center_trim13 14 15class BLSTM(nn.Module):16    def __init__(self, dim, layers=1):17        super().__init__()18        self.lstm = nn.LSTM(bidirectional=True, num_layers=layers, hidden_size=dim, input_size=dim)19        self.linear = nn.Linear(2 * dim, dim)20 21    def forward(self, x):22        x = x.permute(2, 0, 1)23        x = self.lstm(x)[0]24        x = self.linear(x)25        x = x.permute(1, 2, 0)26        return x27 28 29def rescale_conv(conv, reference):30    std = conv.weight.std().detach()31    scale = (std / reference)**0.532    conv.weight.data /= scale33    if conv.bias is not None:34        conv.bias.data /= scale35 36 37def rescale_module(module, reference):38    for sub in module.modules():39        if isinstance(sub, (nn.Conv1d, nn.ConvTranspose1d)):40            rescale_conv(sub, reference)41 42 43class Demucs(nn.Module):44    @capture_init45    def __init__(self,46                 sources,47                 audio_channels=2,48                 channels=64,49                 depth=6,50                 rewrite=True,51                 glu=True,52                 rescale=0.1,53                 resample=True,54                 kernel_size=8,55                 stride=4,56                 growth=2.,57                 lstm_layers=2,58                 context=3,59                 normalize=False,60                 samplerate=44100,61                 segment_length=4 * 10 * 44100):62        """63        Args:64            sources (list[str]): list of source names65            audio_channels (int): stereo or mono66            channels (int): first convolution channels67            depth (int): number of encoder/decoder layers68            rewrite (bool): add 1x1 convolution to each encoder layer69                and a convolution to each decoder layer.70                For the decoder layer, `context` gives the kernel size.71            glu (bool): use glu instead of ReLU72            resample_input (bool): upsample x2 the input and downsample /2 the output.73            rescale (int): rescale initial weights of convolutions74                to get their standard deviation closer to `rescale`75            kernel_size (int): kernel size for convolutions76            stride (int): stride for convolutions77            growth (float): multiply (resp divide) number of channels by that78                for each layer of the encoder (resp decoder)79            lstm_layers (int): number of lstm layers, 0 = no lstm80            context (int): kernel size of the convolution in the81                decoder before the transposed convolution. If > 1,82                will provide some context from neighboring time83                steps.84            samplerate (int): stored as meta information for easing85                future evaluations of the model.86            segment_length (int): stored as meta information for easing87                future evaluations of the model. Length of the segments on which88                the model was trained.89        """90 91        super().__init__()92        self.audio_channels = audio_channels93        self.sources = sources94        self.kernel_size = kernel_size95        self.context = context96        self.stride = stride97        self.depth = depth98        self.resample = resample99        self.channels = channels100        self.normalize = normalize101        self.samplerate = samplerate102        self.segment_length = segment_length103 104        self.encoder = nn.ModuleList()105        self.decoder = nn.ModuleList()106 107        if glu:108            activation = nn.GLU(dim=1)109            ch_scale = 2110        else:111            activation = nn.ReLU()112            ch_scale = 1113        in_channels = audio_channels114        for index in range(depth):115            encode = []116            encode += [nn.Conv1d(in_channels, channels, kernel_size, stride), nn.ReLU()]117            if rewrite:118                encode += [nn.Conv1d(channels, ch_scale * channels, 1), activation]119            self.encoder.append(nn.Sequential(*encode))120 121            decode = []122            if index > 0:123                out_channels = in_channels124            else:125                out_channels = len(self.sources) * audio_channels126            if rewrite:127                decode += [nn.Conv1d(channels, ch_scale * channels, context), activation]128            decode += [nn.ConvTranspose1d(channels, out_channels, kernel_size, stride)]129            if index > 0:130                decode.append(nn.ReLU())131            self.decoder.insert(0, nn.Sequential(*decode))132            in_channels = channels133            channels = int(growth * channels)134 135        channels = in_channels136 137        if lstm_layers:138            self.lstm = BLSTM(channels, lstm_layers)139        else:140            self.lstm = None141 142        if rescale:143            rescale_module(self, reference=rescale)144 145    def valid_length(self, length):146        """147        Return the nearest valid length to use with the model so that148        there is no time steps left over in a convolutions, e.g. for all149        layers, size of the input - kernel_size % stride = 0.150 151        If the mixture has a valid length, the estimated sources152        will have exactly the same length when context = 1. If context > 1,153        the two signals can be center trimmed to match.154 155        For training, extracts should have a valid length.For evaluation156        on full tracks we recommend passing `pad = True` to :method:`forward`.157        """158        if self.resample:159            length *= 2160        for _ in range(self.depth):161            length = math.ceil((length - self.kernel_size) / self.stride) + 1162            length = max(1, length)163            length += self.context - 1164        for _ in range(self.depth):165            length = (length - 1) * self.stride + self.kernel_size166 167        if self.resample:168            length = math.ceil(length / 2)169        return int(length)170 171    def forward(self, mix):172        x = mix173 174        if self.normalize:175            mono = mix.mean(dim=1, keepdim=True)176            mean = mono.mean(dim=-1, keepdim=True)177            std = mono.std(dim=-1, keepdim=True)178        else:179            mean = 0180            std = 1181 182        x = (x - mean) / (1e-5 + std)183 184        if self.resample:185            x = julius.resample_frac(x, 1, 2)186 187        saved = []188        for encode in self.encoder:189            x = encode(x)190            saved.append(x)191        if self.lstm:192            x = self.lstm(x)193        for decode in self.decoder:194            skip = center_trim(saved.pop(-1), x)195            x = x + skip196            x = decode(x)197 198        if self.resample:199            x = julius.resample_frac(x, 2, 1)200        x = x * std + mean201        x = x.view(x.size(0), len(self.sources), self.audio_channels, x.size(-1))202        return x203