# Copyright 2026 Tencent. # token2wav: audio token codes -> waveform (inference only) # Pipeline: Token -> Latent (flow matching) -> Waveform (BigVGAN) import math from collections import OrderedDict, namedtuple import numpy as np import torch import torch.nn as nn import torch.nn.functional as F from einops import rearrange from torch.nn.utils import weight_norm from vllm_omni.model_executor.models.common.alias_free_activation import AliasFreeActivation1d from vllm_omni.model_executor.models.common.snake_activation import SnakeBeta # --------------- Utilities --------------- class JsonHParams: def __init__(self, **kwargs): for k, v in kwargs.items(): if isinstance(v, dict): v = JsonHParams(**v) if isinstance(v, str) and v.lower() in ["non", "none", "nil", "null"]: v = None self[k] = v def keys(self): return self.__dict__.keys() def items(self): return self.__dict__.items() def values(self): return self.__dict__.values() def __len__(self): return len(self.__dict__) def __getitem__(self, key): return getattr(self, key) def __setitem__(self, key, value): return setattr(self, key, value) def __contains__(self, key): return key in self.__dict__ def __repr__(self): return self.__dict__.__repr__() def get(self, key, default=None): return self.__dict__.get(key, default) def exists(val): return val is not None def eval_decorator(fn): def inner(model, *args, **kwargs): was_training = model.training model.eval() out = fn(model, *args, **kwargs) model.train(was_training) return out return inner def init_weights(m, mean=0.0, std=0.01): classname = m.__class__.__name__ if classname.find("Conv") != -1: m.weight.data.normal_(mean, std) def get_padding(kernel_size, dilation=1): return int((kernel_size * dilation - dilation) / 2) def modulate(x, shift, scale): return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1) def rotate_half(x): x1, x2 = x.chunk(2, dim=-1) return torch.cat((-x2, x1), dim=-1) @torch.autocast(enabled=False, device_type="cuda") def apply_rotary_pos_emb(pos, t): return t * pos.cos() + rotate_half(t) * pos.sin() # sinc, kaiser_sinc_filter1d removed — now in common.alias_free_activation # --------------- Basic Layers --------------- class Dropout(nn.Module): def __init__(self, p: float = 0.5, inplace: bool = False, force_drop: bool = False, **kwargs): super().__init__() if p < 0.0 or p > 1.0: raise ValueError(f"dropout probability has to be between 0 and 1, but got {p}") self.p = p self.inplace = inplace self.force_drop = force_drop def forward(self, x, **kwargs): return F.dropout(x, p=self.p, training=True if self.force_drop else self.training, inplace=self.inplace) class EmbeddingTable(nn.Embedding): def __init__(self, num_embeddings: int, embedding_dim: int, pad_id=-1, **kwargs): super().__init__(num_embeddings, embedding_dim, **kwargs) nn.init.normal_(self.weight, 0.0, embedding_dim**-0.5) self.pad_id = pad_id self.output_dim = embedding_dim def forward(self, x): if self.pad_id is not None: mask = x == self.pad_id x = x.masked_fill(mask, 0) outputs = super().forward(x) if self.pad_id is not None: outputs = outputs.masked_fill(mask.unsqueeze(-1), 0.0) return outputs class Linear(nn.Linear): def __init__( self, in_channels: int, out_channels: int, bias: bool = True, w_init_gain: str = "linear", activation=None, **kwargs, ): super().__init__(in_channels, out_channels, bias=bias) self.activation = activation if activation is not None else nn.Identity() self.output_dim = out_channels if w_init_gain is not None: if isinstance(w_init_gain, str): gain = nn.init.calculate_gain(w_init_gain) else: gain = w_init_gain nn.init.xavier_uniform_(self.weight, gain=gain) if bias: nn.init.constant_(self.bias, 0.0) def forward(self, x, **kwargs): return self.activation(super().forward(x)) class Conv1d(nn.Conv1d): def __init__( self, in_channels: int, out_channels: int, kernel_size: int = 1, stride: int = 1, dilation: int = 1, groups: int = 1, padding_mode: str = "zeros", bias: bool = True, padding=None, causal: bool = False, bn: bool = False, activation=None, w_init_gain=None, input_transpose: bool = False, **kwargs, ): self.causal = causal if padding is None: if causal: padding = 0 self.left_padding = dilation * (kernel_size - 1) else: padding = get_padding(kernel_size, dilation) super().__init__( in_channels, out_channels, kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, padding_mode=padding_mode, bias=bias, ) self.in_channels = in_channels self.transpose = input_transpose self.bn = nn.BatchNorm1d(out_channels) if bn else nn.Identity() self.activation = activation if activation is not None else nn.Identity() if w_init_gain is not None: nn.init.xavier_uniform_(self.weight, gain=nn.init.calculate_gain(w_init_gain)) def forward(self, x): if self.transpose or x.size(1) != self.in_channels: assert x.size(2) == self.in_channels x = x.transpose(1, 2) self.transpose = True if self.causal: x = F.pad(x.unsqueeze(2), (self.left_padding, 0, 0, 0)).squeeze(2) outputs = self.activation(self.bn(super().forward(x))) return outputs.transpose(1, 2) if self.transpose else outputs class ConvTranspose1d(nn.ConvTranspose1d): def __init__( self, in_channels: int, out_channels: int, kernel_size: int, stride: int = 1, output_padding: int = 0, groups: int = 1, bias: bool = True, dilation: int = 1, padding=None, padding_mode: str = "zeros", causal: bool = False, input_transpose: bool = False, **kwargs, ): if padding is None: padding = 0 if causal else (kernel_size - stride) // 2 if causal: assert padding == 0, "padding is not allowed in causal ConvTranspose1d." assert kernel_size == 2 * stride, "kernel_size must be equal to 2*stride in Causal ConvTranspose1d." super().__init__( in_channels, out_channels, kernel_size, stride=stride, padding=padding, output_padding=output_padding, groups=groups, bias=bias, dilation=dilation, padding_mode=padding_mode, ) self.causal = causal self.stride = stride self.transpose = input_transpose def forward(self, x): if self.transpose or x.size(1) != self.in_channels: assert x.size(2) == self.in_channels x = x.transpose(1, 2) self.transpose = True x = super().forward(x) if self.causal: x = x[:, :, : -self.stride] return x.transpose(1, 2) if self.transpose else x class ConvPositionEmbed(nn.Module): def __init__(self, hidden_size: int, kernel_size: int = 31, groups: int = 16): super().__init__() self.conv = Conv1d( hidden_size, hidden_size, kernel_size, groups=groups, input_transpose=True, activation=nn.GELU() ) def forward(self, x, mask=None): if mask is not None: mask = mask[..., None] x = x.masked_fill(~mask, 0.0) x = self.conv(x) if mask is not None: x = x.masked_fill(~mask, 0.0) return x # --------------- Anti-aliasing (BigVGAN) --------------- # LowPassFilter1d, UpSample1d, DownSample1d, Activation1d removed — # now provided by common.alias_free_activation.AliasFreeActivation1d # --------------- Activations --------------- # SnakeBeta removed — now in common.snake_activation (with alpha_logscale support) # --------------- Attention --------------- AttentionConfig = namedtuple("AttentionConfig", ["enable_flash", "enable_math", "enable_mem_efficient"]) class RotaryEmbedding(nn.Module): def __init__(self, dim, theta=50000): super().__init__() inv_freq = 1.0 / (theta ** (torch.arange(0, dim, 2).float() / dim)) self.register_buffer("inv_freq", inv_freq) @property def device(self): return self.inv_freq.device @torch.autocast(enabled=False, device_type="cuda") def forward(self, t): if not torch.is_tensor(t): t = torch.arange(t, device=self.device) t = t.type_as(self.inv_freq) freqs = torch.einsum("i , j -> i j", t, self.inv_freq) freqs = torch.cat((freqs, freqs), dim=-1) return freqs class MultiHeadAttention(nn.Module): def __init__( self, hidden_size: int, num_heads: int = 8, qkv_bias: bool = False, qk_norm: bool = False, attn_drop: float = 0.0, dropout: float = 0.0, max_position_embeddings: int = 4096, norm_layer: nn.Module = nn.LayerNorm, rotary_bias: bool = False, **kwargs, ): super().__init__() assert hidden_size % num_heads == 0, "hidden_size should be divisible by num_heads" self.num_heads = num_heads self.head_dim = hidden_size // num_heads self.scale = self.head_dim**-0.5 self.max_position_embeddings = max_position_embeddings self.rotary_bias = rotary_bias self.q_proj = Linear(hidden_size, hidden_size, bias=qkv_bias) self.k_proj = Linear(hidden_size, hidden_size, bias=qkv_bias) self.v_proj = Linear(hidden_size, hidden_size, bias=qkv_bias) self.q_norm = norm_layer(self.head_dim) if qk_norm else nn.Identity() self.k_norm = norm_layer(self.head_dim) if qk_norm else nn.Identity() self.attn_drop = Dropout(attn_drop) self.o_proj = Linear(hidden_size, hidden_size) self.o_dropout = Dropout(dropout) self.cpu_config = AttentionConfig(True, True, True) device_properties = torch.cuda.get_device_properties(torch.device("cuda")) if device_properties.major == 8 and device_properties.minor == 0: self.cuda_config = AttentionConfig(True, True, True) else: self.cuda_config = AttentionConfig(False, True, True) if self.rotary_bias: self.rotary = RotaryEmbedding(self.head_dim) def forward(self, q, k=None, v=None, mask=None): k = k or q v = v or q B, L, C = q.shape B, S, C = v.shape if mask is not None: if mask.ndim == 2: assert L == S mask = rearrange(mask, "b j -> b 1 1 j") mask = mask.expand(-1, self.num_heads, L, -1) elif mask.ndim == 3: assert mask.size(1) == L and mask.size(2) == S mask = mask.unsqueeze(1).expand(-1, self.num_heads, -1, -1) q, k, v = self.q_proj(q), self.k_proj(k), self.v_proj(v) q = rearrange(q, "b n (h d) -> b h n d", h=self.num_heads) k = rearrange(k, "b n (h d) -> b h n d", h=self.num_heads) v = rearrange(v, "b n (h d) -> b h n d", h=self.num_heads) q, k = self.q_norm(q), self.k_norm(k) config = self.cuda_config if q.is_cuda else self.cpu_config attn_bias = torch.zeros(B, self.num_heads, L, S, dtype=q.dtype, device=q.device) if self.rotary_bias: if L == S: rotary_emb = self.rotary(L) q, k = map(lambda x: apply_rotary_pos_emb(rotary_emb, x), (q, k)) else: q_rotary_emb = self.rotary(L) k_rotary_emb = self.rotary(S) q = apply_rotary_pos_emb(q_rotary_emb, q) k = apply_rotary_pos_emb(k_rotary_emb, k) if mask is not None: attn_bias.masked_fill_(mask.logical_not(), float("-inf")) with torch.backends.cuda.sdp_kernel(**config._asdict()): out = F.scaled_dot_product_attention( q, k, v, attn_mask=attn_bias, dropout_p=self.attn_drop.p if self.training else 0.0 ) out = rearrange(out, "b h n d -> b n (h d)") out = self.o_dropout(self.o_proj(out)) return out # --------------- DiT Modules --------------- class TimestepEmbedder(nn.Module): def __init__(self, hidden_size, frequency_embedding_size=256): super().__init__() self.mlp = nn.Sequential( Linear(frequency_embedding_size, hidden_size, bias=True), nn.SiLU(), Linear(hidden_size, hidden_size, bias=True), ) self.frequency_embedding_size = frequency_embedding_size @staticmethod def timestep_embedding(t, dim, max_period=10000): half = dim // 2 freqs = torch.exp(-math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half).to( device=t.device ) args = t[:, None].float() * freqs[None] embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) if dim % 2: embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) return embedding def forward(self, t): t_freq = self.timestep_embedding(t, self.frequency_embedding_size) t_emb = self.mlp(t_freq) return t_emb class FinalLayer(nn.Module): def __init__(self, hidden_size, output_size): super().__init__() self.adaLN_modulation = nn.Sequential(nn.SiLU(), nn.Linear(hidden_size, 2 * hidden_size, bias=True)) self.norm = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6) self.linear = Linear(hidden_size, output_size, bias=True) def forward(self, x, c, mask=None): shift, scale = self.adaLN_modulation(c).chunk(2, dim=1) x = modulate(self.norm(x), shift, scale) x = self.linear(x) return x # --------------- Transformer --------------- class Mlp(nn.Module): def __init__(self, hidden_size, ffn_hidden_size=4096, act_layer=nn.GELU, dropout=0.0, **kwargs): super().__init__() self.fc1 = Linear(hidden_size, ffn_hidden_size) self.act = act_layer() self.fc2 = Linear(ffn_hidden_size, hidden_size) self.drop = Dropout(dropout) def forward(self, x, **kwargs): x = self.fc1(x) x = self.act(x) x = self.drop(x) x = self.fc2(x) x = self.drop(x) return x class TransformerBlock(nn.Module): def __init__( self, attention: nn.Module, ffn: nn.Module, hidden_size: int = 1024, modulation: bool = False, eps: float = 1e-6, **kwargs, ): super().__init__() self.norm1 = nn.LayerNorm(hidden_size, elementwise_affine=not modulation, eps=eps) self.norm2 = nn.LayerNorm(hidden_size, elementwise_affine=not modulation, eps=eps) self.attn = attention self.ffn = ffn self.modulation = modulation if modulation: self.modulation_layer = nn.Sequential(nn.SiLU(), Linear(hidden_size, 6 * hidden_size, bias=True)) nn.init.constant_(self.modulation_layer[-1].weight, 0.0) nn.init.constant_(self.modulation_layer[-1].bias, 0.0) def forward(self, x, condition=None, mask=None): if condition is None: assert not self.modulation, "Without global condition, must set modulation to False" else: assert self.modulation, "With global condition, must set modulation to True" shift_attn, scale_attn, gate_attn, shift_ffn, scale_ffn, gate_ffn = self.modulation_layer(condition).chunk( 6, dim=1 ) if condition is not None: x = x + gate_attn.unsqueeze(1) * self.attn(modulate(self.norm1(x), shift_attn, scale_attn), mask=mask) else: x = x + self.attn(self.norm1(x), mask=mask) if condition is not None: x = x + gate_ffn.unsqueeze(1) * self.ffn(modulate(self.norm2(x), shift_ffn, scale_ffn)) else: x = x + self.ffn(self.norm2(x), mask=mask) return x # --------------- Flow Matching: Token -> Latent --------------- class Token2latentFlowMatching(nn.Module): def __init__(self, config): super().__init__() self.config = config self.model_dim = config.transformer.hidden_size self.token_input_dim = config.get("token_input_dim", self.model_dim) self.target_dim = config.z_dim self.spkr_embed_dim = config.get("spkr_embed_dim", 512) self.cond_proj = Linear(self.model_dim + self.spkr_embed_dim, self.model_dim) self.token_pad_id = -1 if config.upsample_factor > 1: self.token_proj = nn.Sequential( Linear(self.token_input_dim, self.model_dim, bias=True), ConvTranspose1d( self.model_dim, self.model_dim, stride=config.upsample_factor, kernel_size=config.upsample_factor * 2, ), ) else: self.token_proj = Linear(self.token_input_dim, self.model_dim) self.transformer_input_proj = Linear(self.model_dim + self.target_dim * 2, self.model_dim) self.time_embedder = TimestepEmbedder(self.model_dim) self.conv_embed = ConvPositionEmbed(hidden_size=self.model_dim, kernel_size=31, groups=16) self.blocks = nn.ModuleList() for _ in range(config.transformer.num_layers): attn_block = MultiHeadAttention(**config.transformer) ffn_block = Mlp(act_layer=lambda: nn.GELU(approximate="tanh"), **config.transformer) self.blocks.append(TransformerBlock(attn_block, ffn_block, **config.transformer)) self.output_layer = FinalLayer(config.transformer.hidden_size, self.target_dim) def cond_mask_spkr_embed(self, x, spkr_embed): b, device = x.size(0), x.device if not exists(spkr_embed): spkr_embed = torch.zeros(b, self.spkr_embed_dim, device=device, dtype=x.dtype) return spkr_embed def vectorfield_forward(self, inputs, times, self_attn_mask, g_cond=None): t = self.time_embedder(times) if g_cond is None: c = t else: cond_inp = torch.cat([t, g_cond], dim=-1) c = self.cond_proj(cond_inp) ut = self.transformer_input_proj(inputs) ut = self.conv_embed(ut, mask=self_attn_mask) + ut for block in self.blocks: ut = block(ut, c, mask=self_attn_mask) ut = self.output_layer(ut, c) return ut @eval_decorator @torch.no_grad() def inference( self, *, token: torch.Tensor, prefix_target: torch.Tensor | None = None, spkr_embed: torch.Tensor | None = None, s_steps: int | None = 10, cfg_alpha: float | None = 2.0, rescale_logits: bool = False, **kwargs, ): b, device = token.size(0), token.device assert b == 1, "Only support batch_size == 1 when inference" token = self.token_proj(token) ge = self.cond_mask_spkr_embed(token, spkr_embed) tgt_lens = token.size(1) latent_cond = torch.zeros(b, tgt_lens, self.target_dim).to(device) if prefix_target is not None: latent_cond[:, : prefix_target.size(1), :] = prefix_target sample, _ = self.sample( tokens=token, audio=latent_cond, steps=s_steps, alpha=cfg_alpha, g_cond=ge, rescale_logits=rescale_logits ) return sample def sample(self, tokens, audio, steps, alpha=None, g_cond=None, rescale_logits=False): noise = torch.randn([audio.size(0), audio.shape[1], self.target_dim], device=audio.device) times = torch.linspace(0, 1, steps, device=audio.device) def solver(t, z): if alpha is None: output = torch.cat([tokens, audio, z], dim=-1) return self.vectorfield_forward(inputs=output, times=t.unsqueeze(0), self_attn_mask=None, g_cond=g_cond) tokens_empty = torch.zeros(*audio.shape[:2], self.model_dim, device=tokens.device, dtype=tokens.dtype) tokens_t = torch.cat([tokens_empty, tokens], dim=0) audio_t = torch.cat([audio, audio], dim=0) audio_noizy_t = torch.cat([z, z], dim=0) t_t = torch.stack([t, t], dim=0) c = g_cond if g_cond is not None: c = torch.cat([g_cond, g_cond], dim=0) output = torch.cat([tokens_t, audio_t, audio_noizy_t], dim=-1) predicted_mix = self.vectorfield_forward(inputs=output, times=t_t, self_attn_mask=None, g_cond=c) predicted_conditioned = predicted_mix[1].unsqueeze(0) predicted_unconditioned = predicted_mix[0].unsqueeze(0) prediction = predicted_conditioned + (predicted_conditioned - predicted_unconditioned) * alpha prediction_rescaled = predicted_conditioned.std() * (prediction / prediction.std()) if rescale_logits: return prediction_rescaled else: return prediction try: from torchdiffeq import odeint except ImportError: raise ImportError("Covo-Audio code2wav requires `torchdiffeq`. Install it with: pip install torchdiffeq") trajectory = odeint(solver, noise, times, atol=1e-5, rtol=1e-5, method="midpoint") return trajectory[-1], trajectory class Token2latentFlowMatchingWithEmbed(Token2latentFlowMatching): def __init__(self, config, **kwargs): super().__init__(config) self.vocab_size = config.token_vocab_size self.token_embedding = EmbeddingTable( num_embeddings=self.vocab_size, embedding_dim=self.token_input_dim, pad_id=self.token_pad_id ) def inference( self, *, token, prefix_target=None, spkr_embed=None, s_steps=10, cfg_alpha=2, rescale_logits=False, **kwargs ): token = self.token_embedding(token) return super().inference( token=token, prefix_target=prefix_target, spkr_embed=spkr_embed, s_steps=s_steps, cfg_alpha=cfg_alpha, rescale_logits=rescale_logits, **kwargs, ) # --------------- Vocoder: Latent -> Waveform (BigVGAN) --------------- class AMPBlock1(torch.nn.Module): def __init__(self, h, channels, kernel_size=3, dilation=(1, 3, 5), causal=True): super().__init__() self.h = h self.convs1 = nn.ModuleList( [ weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[0], causal=causal)), weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[1], causal=causal)), weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=dilation[2], causal=causal)), ] ) self.convs1.apply(init_weights) self.convs2 = nn.ModuleList( [ weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1, causal=causal)), weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1, causal=causal)), weight_norm(Conv1d(channels, channels, kernel_size, 1, dilation=1, causal=causal)), ] ) self.convs2.apply(init_weights) self.num_layers = len(self.convs1) + len(self.convs2) self.activations = nn.ModuleList( [ AliasFreeActivation1d(activation=SnakeBeta(channels, alpha_logscale=h.snake_logscale)) for _ in range(self.num_layers) ] ) def forward(self, x): acts1, acts2 = self.activations[::2], self.activations[1::2] for c1, c2, a1, a2 in zip(self.convs1, self.convs2, acts1, acts2): xt = a1(x) xt = c1(xt) xt = a2(xt) xt = c2(xt) x = xt + x return x class BigVGANFlowVAE(nn.Module): def __init__(self, h): super().__init__() self.config = h self.h = h causal = h.causal self.hop_size = np.prod(h.downsample_rates) self.num_kernels = len(h.resblock_kernel_sizes) self.num_upsamples = len(h.upsample_rates) self.conv_pre = weight_norm(Conv1d(h.latent_dim, h.upsample_initial_channel, 7, 1, causal=False)) self.ups = nn.ModuleList() for i, (u, k) in enumerate(zip(h.upsample_rates, h.upsample_kernel_sizes)): self.ups.append( nn.ModuleList( [ weight_norm( ConvTranspose1d( h.upsample_initial_channel // (2**i), h.upsample_initial_channel // (2 ** (i + 1)), k, u, causal=causal, ) ) ] ) ) self.resblocks = nn.ModuleList() for i in range(len(self.ups)): ch = h.upsample_initial_channel // (2 ** (i + 1)) for j, (k, d) in enumerate(zip(h.resblock_kernel_sizes, h.resblock_dilation_sizes)): self.resblocks.append(AMPBlock1(h, ch, k, d, causal=causal)) activation_post = SnakeBeta(ch, alpha_logscale=h.snake_logscale) self.activation_post = AliasFreeActivation1d(activation=activation_post) self.conv_post = weight_norm(Conv1d(ch, 1, 7, 1, causal=causal)) for i in range(len(self.ups)): self.ups[i].apply(init_weights) self.conv_post.apply(init_weights) def inference_from_latents(self, x, do_sample=True, noise_scale=1.0): if self.h.use_vae and do_sample: assert x.size(1) == self.h.latent_dim * 2, f"Input must be like [B, D, H], got {x.shape}" m_q, logs_q = torch.split(x, self.h.latent_dim, dim=1) x = m_q + torch.randn_like(m_q) * torch.exp(logs_q) * noise_scale else: assert x.size(1) == self.h.latent_dim, f"Input must be like [B, D, H], got {x.shape}" x = self.conv_pre(x) for i in range(self.num_upsamples): for i_up in range(len(self.ups[i])): x = self.ups[i][i_up](x) xs = None for j in range(self.num_kernels): if xs is None: xs = self.resblocks[i * self.num_kernels + j](x) else: xs += self.resblocks[i * self.num_kernels + j](x) x = xs / self.num_kernels x = self.activation_post(x) x = self.conv_post(x) x = torch.tanh(x) return x # --------------- Token2WavDecoder --------------- class Token2WavDecoder(nn.Module): def __init__(self, config, **kwargs): super().__init__() self.config = config self.wavegan = BigVGANFlowVAE(config.wavegan) self.wavegan_hop_size = np.prod(config.wavegan.downsample_rates) self.global_mean_var = getattr(config, "global_mean_var", None) if self.global_mean_var is not None: mean_var_data = torch.from_numpy(np.load(self.global_mean_var)).float().squeeze() global_mean, global_var = mean_var_data.chunk(2, 0) self.register_buffer("global_mean", global_mean) self.register_buffer("global_var", global_var) self.token2latent = Token2latentFlowMatchingWithEmbed(config.token2latent) self.upsample_factor = self.token2latent.config.get("upsample_factor", 1) self.wav_input_sr = config.get("wav_input_sr", 24000) self.trainable_module = ["wavegan", "token2latent"] def state_dict(self): param_dict = OrderedDict() for name in self.trainable_module: state = self.get_submodule(name).state_dict(prefix=f"{name}.") param_dict.update(state) return param_dict def load_state_dict(self, param_dict): for name in self.trainable_module: module_state = OrderedDict() name_len = len(name) for k, v in param_dict.items(): if k.startswith(f"{name}."): new_k = k[name_len + 1 :] module_state[new_k] = v self.get_submodule(name).load_state_dict(module_state, strict=False) @torch.no_grad() def preprocess_infer_data(self, data): zero_spkr = data.get("zero_spkr", False) token = data["target_token"] prefix_target = None res_prefix_len = 0 prompt_token = data.get("prompt_token", None) prompt_latent = data.get("prompt_latent", None) if exists(prompt_token): token = torch.cat([prompt_token, token], dim=1) if exists(prompt_latent): prefix_target = prompt_latent res_prefix_len = prompt_latent.shape[1] spkr_embed = None if not zero_spkr: spkr_embed = data.get("spkr_embed", None) res = {"token": token, "prefix_target": prefix_target, "spkr_embed": spkr_embed} return res, res_prefix_len @eval_decorator @torch.no_grad() def inference(self, data, **kwargs): infer_data, prefix_len = self.preprocess_infer_data(data) prefix_target = infer_data["prefix_target"] res_latents = self.token2latent.inference(**infer_data, **kwargs) if self.global_mean_var is not None: res_latents = self.global_mean + res_latents * torch.sqrt(self.global_var) if exists(prefix_target): prefix_target = self.global_mean + prefix_target * torch.sqrt(self.global_var) if exists(prefix_target): res_latents[:, : prefix_target.shape[1]] = prefix_target res_latents = res_latents[:, prefix_len:] audio = self.wavegan.inference_from_latents(res_latents.transpose(1, 2), do_sample=False) return audio