File size: 1,656 Bytes
fb7fd60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from __future__ import annotations

import torch
import torch.nn as nn


class Decoder4FeatureExtractor(nn.Module):
    """MOSS audio-tokenizer codebook decode plus decoder blocks 0..4."""

    def __init__(
        self,
        audio_tokenizer: nn.Module,
        num_quantizers: int = 32,
        output_dtype: torch.dtype = torch.float16,
    ) -> None:
        super().__init__()
        quantizer = getattr(audio_tokenizer, "quantizer")
        self.quantizers = quantizer.quantizers
        self.output_proj = quantizer.output_proj
        self.decoder_prefix = nn.ModuleList(list(audio_tokenizer.decoder[:5]))
        self.rvq_dim = int(quantizer.rvq_dim)
        self.num_quantizers = int(num_quantizers)
        self.output_dtype = output_dtype

    def forward(self, codes: torch.Tensor, lengths: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
        _, batch, frames = codes.shape
        emb = torch.zeros(batch, self.rvq_dim, frames, device=codes.device, dtype=self.output_dtype)
        for index, quantizer in enumerate(self.quantizers[: self.num_quantizers]):
            if self.output_dtype == torch.float16:
                z_q = quantizer.embed_code(codes[index]).transpose(1, 2).to(self.output_dtype)
                z_q = quantizer.out_proj(z_q)
            else:
                z_q = quantizer.decode_code(codes[index])
            emb = emb + z_q.to(self.output_dtype)
        features = self.output_proj(emb)
        feature_lengths = lengths
        for module in self.decoder_prefix:
            features, feature_lengths = module(features, feature_lengths)
        return features.to(self.output_dtype), feature_lengths