Files
wehub-resource-sync 94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

647 lines
23 KiB
Python

# Copied and adapted from: https://github.com/descriptinc/descript-audio-codec
# SPDX-License-Identifier: MIT
import math
from bisect import bisect_right
from typing import Union
import torch
import torch.nn.functional as F
from einops import rearrange
from torch import nn
from sglang.multimodal_gen.configs.models.vaes.dac import DacVAEConfig
from sglang.multimodal_gen.runtime.managers.memory_managers.layerwise_offload import (
LayerwiseOffloadableModuleMixin,
)
from sglang.multimodal_gen.runtime.models.vaes.common import (
DiagonalGaussianDistribution,
)
def _snake(x, alpha):
shape = x.shape
x = x.reshape(shape[0], shape[1], -1)
x = x + (alpha + 1e-9).reciprocal() * torch.sin(alpha * x).pow(2)
x = x.reshape(shape)
return x
# Scripting this brings model speed up 1.4x
snake = torch.jit.script(_snake)
# ROCm HIPRTC can fail to compile the scripted bf16 Snake kernel.
def _should_use_eager_snake_on_rocm_bf16(x: torch.Tensor, alpha: torch.Tensor) -> bool:
return (
torch.version.hip is not None
and (x.is_cuda or alpha.is_cuda)
and (x.dtype == torch.bfloat16 or alpha.dtype == torch.bfloat16)
)
class Snake1d(nn.Module):
def __init__(self, channels):
super().__init__()
self.alpha = nn.Parameter(torch.ones(1, channels, 1))
def forward(self, x):
if _should_use_eager_snake_on_rocm_bf16(x, self.alpha):
return _snake(x, self.alpha)
return snake(x, self.alpha)
class VectorQuantize(nn.Module):
"""
Implementation of VQ similar to Karpathy's repo:
https://github.com/karpathy/deep-vector-quantization
Additionally uses following tricks from Improved VQGAN
(https://arxiv.org/pdf/2110.04627.pdf):
1. Factorized codes: Perform nearest neighbor lookup in low-dimensional space
for improved codebook usage
2. l2-normalized codes: Converts euclidean distance to cosine similarity which
improves training stability
"""
def __init__(self, input_dim: int, codebook_size: int, codebook_dim: int):
super().__init__()
self.codebook_size = codebook_size
self.codebook_dim = codebook_dim
self.in_proj = nn.Conv1d(input_dim, codebook_dim, kernel_size=1)
self.out_proj = nn.Conv1d(codebook_dim, input_dim, kernel_size=1)
self.codebook = nn.Embedding(codebook_size, codebook_dim)
def forward(self, z):
"""Quantize the input tensor using a fixed codebook and return the corresponding codebook vectors.
Args:
z (torch.Tensor): Input tensor with shape ``[B, D, T]``.
Returns:
tuple: A tuple containing:
- z_q (torch.Tensor): Quantized continuous representation with shape ``[B, D, T]``.
- commitment_loss (torch.Tensor): Commitment loss scalar to train encoder to predict
vectors closer to codebook entries.
- codebook_loss (torch.Tensor): Codebook loss scalar to update the codebook.
- indices (torch.Tensor): Codebook indices (quantized discrete representation) with shape ``[B, T]``.
- z_e (torch.Tensor): Projected latents (continuous representation before quantization) with shape ``[B, D, T]``.
"""
# Factorized codes (ViT-VQGAN) Project input into low-dimensional space
z_e = self.in_proj(z) # z_e : (B x D x T)
z_q, indices = self.decode_latents(z_e)
commitment_loss = F.mse_loss(z_e, z_q.detach(), reduction="none").mean([1, 2])
codebook_loss = F.mse_loss(z_q, z_e.detach(), reduction="none").mean([1, 2])
z_q = (
z_e + (z_q - z_e).detach()
) # noop in forward pass, straight-through gradient estimator in backward pass
z_q = self.out_proj(z_q)
return z_q, commitment_loss, codebook_loss, indices, z_e
def embed_code(self, embed_id):
return F.embedding(embed_id, self.codebook.weight)
def decode_code(self, embed_id):
return self.embed_code(embed_id).transpose(1, 2)
def decode_latents(self, latents):
encodings = rearrange(latents, "b d t -> (b t) d")
codebook = self.codebook.weight # codebook: (N x D)
# L2 normalize encodings and codebook (ViT-VQGAN)
encodings = F.normalize(encodings)
codebook = F.normalize(codebook)
# Compute euclidean distance with codebook
dist = (
encodings.pow(2).sum(1, keepdim=True)
- 2 * encodings @ codebook.t()
+ codebook.pow(2).sum(1, keepdim=True).t()
)
indices = rearrange((-dist).max(1)[1], "(b t) -> b t", b=latents.size(0))
z_q = self.decode_code(indices)
return z_q, indices
class ResidualVectorQuantize(nn.Module):
"""
Introduced in SoundStream: An end2end neural audio codec
https://arxiv.org/abs/2107.03312
"""
def __init__(
self,
input_dim: int = 512,
n_codebooks: int = 9,
codebook_size: int = 1024,
codebook_dim: Union[int, list] = 8,
quantizer_dropout: float = 0.0,
):
super().__init__()
if isinstance(codebook_dim, int):
codebook_dim = [codebook_dim for _ in range(n_codebooks)]
self.n_codebooks = n_codebooks
self.codebook_dim = codebook_dim
self.codebook_size = codebook_size
dim_offsets = [0]
for dim in self.codebook_dim:
dim_offsets.append(dim_offsets[-1] + dim)
self._codebook_dim_offsets = tuple(dim_offsets)
self.quantizers = nn.ModuleList(
[
VectorQuantize(input_dim, codebook_size, codebook_dim[i])
for i in range(n_codebooks)
]
)
self.quantizer_dropout = quantizer_dropout
def forward(self, z, n_quantizers: int = None):
"""Quantize the input tensor using a fixed set of codebooks and return the corresponding codebook vectors.
Args:
z (torch.Tensor): Input tensor with shape ``[B, D, T]``.
n_quantizers (int, optional): Number of quantizers to use. If ``None``,
all quantizers are used. When ``n_quantizers`` < ``self.n_codebooks``,
quantizer dropout is applied. Note: if ``self.quantizer_dropout`` > 0
and in training mode, this argument is ignored and a random number of
quantizers is used.
Returns:
tuple: A tuple containing:
- z_q (torch.Tensor): Quantized continuous representation with shape ``[B, D, T]``.
- codes (torch.Tensor): Codebook indices for each codebook with shape ``[B, N, T]``
(quantized discrete representation of input).
- latents (torch.Tensor): Projected latents with shape ``[B, N*D, T]``
(continuous representation before quantization).
- commitment_loss (torch.Tensor): Commitment loss scalar to train encoder to predict
vectors closer to codebook entries.
- codebook_loss (torch.Tensor): Codebook loss scalar to update the codebook.
"""
z_q = 0
residual = z
commitment_loss = 0
codebook_loss = 0
codebook_indices = []
latents = []
if n_quantizers is None:
n_quantizers = self.n_codebooks
quantizers = self.quantizers
if self.training:
batch_size = z.shape[0]
device = z.device
n_quantizers = torch.full(
(batch_size,),
self.n_codebooks + 1,
device=device,
dtype=torch.long,
)
if self.quantizer_dropout > 0:
dropout = torch.randint(
1,
self.n_codebooks + 1,
(batch_size,),
device=device,
)
n_dropout = int(batch_size * self.quantizer_dropout)
if n_dropout > 0:
n_quantizers[:n_dropout] = dropout[:n_dropout]
for i, quantizer in enumerate(quantizers):
z_q_i, commitment_loss_i, codebook_loss_i, indices_i, z_e_i = quantizer(
residual
)
# Create mask to apply quantizer dropout
mask = i < n_quantizers
z_q = z_q + z_q_i * mask[:, None, None]
residual = residual - z_q_i
# Sum losses
commitment_loss += (commitment_loss_i * mask).mean()
codebook_loss += (codebook_loss_i * mask).mean()
codebook_indices.append(indices_i)
latents.append(z_e_i)
else:
for i, quantizer in enumerate(quantizers):
if i >= n_quantizers:
break
z_q_i, commitment_loss_i, codebook_loss_i, indices_i, z_e_i = quantizer(
residual
)
z_q = z_q + z_q_i
residual = residual - z_q_i
commitment_loss += commitment_loss_i.mean()
codebook_loss += codebook_loss_i.mean()
codebook_indices.append(indices_i)
latents.append(z_e_i)
codes = torch.stack(codebook_indices, dim=1)
latents = torch.cat(latents, dim=1)
return z_q, codes, latents, commitment_loss, codebook_loss
def from_codes(self, codes: torch.Tensor):
"""Reconstruct the continuous representation from quantized codes.
Args:
codes (torch.Tensor): Quantized discrete representation with shape ``[B, N, T]``.
Returns:
tuple: A tuple containing:
- z_q (torch.Tensor): Quantized continuous representation with shape ``[B, D, T]``.
- z_p (torch.Tensor): Concatenated latent space representation with shape ``[B, N*D, T]``.
- codes (torch.Tensor): Original input codebook indices with shape ``[B, N, T]``.
"""
z_q = 0.0
z_p = []
n_codebooks = codes.shape[1]
for i in range(n_codebooks):
z_p_i = self.quantizers[i].decode_code(codes[:, i, :])
z_p.append(z_p_i)
z_q_i = self.quantizers[i].out_proj(z_p_i)
z_q = z_q + z_q_i
return z_q, torch.cat(z_p, dim=1), codes
def from_latents(self, latents: torch.Tensor):
"""Reconstruct the continuous representation from unquantized latents.
Args:
latents (torch.Tensor): Continuous representation after projection with shape ``[B, N*D, T]``.
Returns:
tuple: A tuple containing:
- z_q (torch.Tensor): Quantized representation of full-projected space with shape ``[B, D, T]``.
- z_p (torch.Tensor): Quantized representation of latent space with shape ``[B, N*D, T]``.
- codes (torch.Tensor): Codebook indices with shape ``[B, N, T]``.
"""
z_q = 0
z_p = []
codes = []
dims = self._codebook_dim_offsets
n_codebooks = bisect_right(dims, latents.shape[1]) - 1
for i in range(n_codebooks):
j, k = dims[i], dims[i + 1]
z_p_i, codes_i = self.quantizers[i].decode_latents(latents[:, j:k, :])
z_p.append(z_p_i)
codes.append(codes_i)
z_q_i = self.quantizers[i].out_proj(z_p_i)
z_q = z_q + z_q_i
return z_q, torch.cat(z_p, dim=1), torch.stack(codes, dim=1)
class ResidualUnit(nn.Module):
def __init__(self, dim: int = 16, dilation: int = 1):
super().__init__()
pad = ((7 - 1) * dilation) // 2
self.block = nn.Sequential(
Snake1d(dim),
nn.Conv1d(dim, dim, kernel_size=7, dilation=dilation, padding=pad),
Snake1d(dim),
nn.Conv1d(dim, dim, kernel_size=1),
)
def forward(self, x):
y = self.block(x)
pad = (x.shape[-1] - y.shape[-1]) // 2
if pad > 0:
x = x[..., pad:-pad]
return x + y
class EncoderBlock(nn.Module):
def __init__(self, dim: int = 16, stride: int = 1):
super().__init__()
self.block = nn.Sequential(
ResidualUnit(dim // 2, dilation=1),
ResidualUnit(dim // 2, dilation=3),
ResidualUnit(dim // 2, dilation=9),
Snake1d(dim // 2),
nn.Conv1d(
dim // 2,
dim,
kernel_size=2 * stride,
stride=stride,
padding=math.ceil(stride / 2),
),
)
def forward(self, x):
return self.block(x)
class Encoder(nn.Module):
def __init__(
self,
d_model: int = 64,
strides: list = [2, 4, 8, 8],
d_latent: int = 64,
):
super().__init__()
# Create first convolution
self.block = [nn.Conv1d(1, d_model, kernel_size=7, padding=3)]
# Create EncoderBlocks that double channels as they downsample by `stride`
for stride in strides:
d_model *= 2
self.block += [EncoderBlock(d_model, stride=stride)]
# Create last convolution
self.block += [
Snake1d(d_model),
nn.Conv1d(d_model, d_latent, kernel_size=3, padding=1),
]
# Wrap black into nn.Sequential
self.block = nn.Sequential(*self.block)
self.enc_dim = d_model
def forward(self, x):
return self.block(x)
class DecoderBlock(nn.Module):
def __init__(self, input_dim: int = 16, output_dim: int = 8, stride: int = 1):
super().__init__()
self.block = nn.Sequential(
Snake1d(input_dim),
nn.ConvTranspose1d(
input_dim,
output_dim,
kernel_size=2 * stride,
stride=stride,
padding=math.ceil(stride / 2),
output_padding=stride % 2,
),
ResidualUnit(output_dim, dilation=1),
ResidualUnit(output_dim, dilation=3),
ResidualUnit(output_dim, dilation=9),
)
def forward(self, x):
return self.block(x)
class Decoder(nn.Module):
def __init__(
self,
input_channel,
channels,
rates,
d_out: int = 1,
):
super().__init__()
# Add first conv layer
layers = [nn.Conv1d(input_channel, channels, kernel_size=7, padding=3)]
# Add upsampling + MRF blocks
for i, stride in enumerate(rates):
input_dim = channels // 2**i
output_dim = channels // 2 ** (i + 1)
layers += [DecoderBlock(input_dim, output_dim, stride)]
# Add final conv layer
layers += [
Snake1d(output_dim),
nn.Conv1d(output_dim, d_out, kernel_size=7, padding=3),
nn.Tanh(),
]
self.model = nn.Sequential(*layers)
def forward(self, x):
return self.model(x)
class DAC(nn.Module, LayerwiseOffloadableModuleMixin):
layerwise_offload_dit_group_enabled = False
layer_names = ["encoder.block", "decoder.model"]
def __init__(
self,
config: DacVAEConfig,
):
super().__init__()
self.continuous = config.continuous
self.decoder_dim = config.decoder_dim
self.decoder_rates = config.decoder_rates
self.encoder_dim = config.encoder_dim
self.encoder_rates = config.encoder_rates
self.hop_length = math.prod(config.encoder_rates)
self.sample_rate = config.sample_rate
if config.latent_dim is None:
latent_dim = config.encoder_dim * (2 ** len(config.encoder_rates))
else:
latent_dim = config.latent_dim
self.latent_dim = latent_dim
if config.load_encoder:
self.encoder = Encoder(config.encoder_dim, config.encoder_rates, latent_dim)
if not config.continuous:
self.n_codebooks = config.n_codebooks
self.codebook_size = config.codebook_size
self.codebook_dim = config.codebook_dim
self.quantizer = ResidualVectorQuantize(
input_dim=latent_dim,
n_codebooks=config.n_codebooks,
codebook_size=config.codebook_size,
codebook_dim=config.codebook_dim,
quantizer_dropout=config.quantizer_dropout,
)
else:
self.quant_conv = torch.nn.Conv1d(latent_dim, 2 * latent_dim, 1)
self.post_quant_conv = torch.nn.Conv1d(latent_dim, latent_dim, 1)
if config.load_decoder:
self.decoder = Decoder(
latent_dim,
config.decoder_dim,
config.decoder_rates,
)
self.apply(self.init_weights)
@staticmethod
def init_weights(m):
if isinstance(m, nn.Conv1d):
nn.init.trunc_normal_(m.weight, std=0.02)
nn.init.constant_(m.bias, 0)
@property
def dtype(self):
return next(self.parameters()).dtype
@property
def device(self):
return next(self.parameters()).device
def preprocess(self, audio_data, sample_rate):
if sample_rate is None:
sample_rate = self.sample_rate
assert sample_rate == self.sample_rate
length = audio_data.shape[-1]
right_pad = math.ceil(length / self.hop_length) * self.hop_length - length
audio_data = nn.functional.pad(audio_data, (0, right_pad))
return audio_data
def encode(
self,
audio_data: torch.Tensor,
n_quantizers: int = None,
):
"""Encode audio data into latent representations.
This method processes audio through the encoder network and optionally applies
vector quantization (in VQ mode) or projects to a Gaussian distribution (in
continuous mode) to produce latent representations.
Args:
audio_data (torch.Tensor): Audio data to encode, with shape ``[B, 1, T]``.
n_quantizers (int, optional): Number of quantizers to use. If ``None``,
all quantizers are used. Only applicable in VQ mode (``continuous=False``).
Returns:
tuple: A tuple containing:
- z (torch.Tensor): Encoded representation. In VQ mode, this is the
quantized continuous representation with shape ``[B, D, T]``. In
continuous mode, this is a ``DiagonalGaussianDistribution`` object.
- codes (torch.Tensor or None): Codebook indices with shape ``[B, N, T]``
in VQ mode, ``None`` in continuous mode.
- latents (torch.Tensor or None): Projected latents with shape ``[B, N*D, T]``
in VQ mode, ``None`` in continuous mode.
- commitment_loss (torch.Tensor): Commitment loss scalar.
- codebook_loss (torch.Tensor): Codebook loss scalar.
Note:
In continuous mode, the encoded representation is projected through a
quantization convolution layer and wrapped in a ``DiagonalGaussianDistribution``
for VAE training.
"""
z = self.encoder(audio_data) # [B x D x T]
if not self.continuous:
z, codes, latents, commitment_loss, codebook_loss = self.quantizer(
z, n_quantizers
)
else:
z = self.quant_conv(z) # [B x 2D x T]
z = DiagonalGaussianDistribution(z)
codes, latents, commitment_loss, codebook_loss = None, None, 0, 0
return z, codes, latents, commitment_loss, codebook_loss
def decode(self, z: torch.Tensor):
"""Decode latent representations back to audio waveforms.
This method takes latent representations (either quantized from VQ mode or sampled
from the posterior in continuous mode) and reconstructs the corresponding audio
through the decoder network.
Args:
z (torch.Tensor): Latent representation to decode, with shape ``[B, D, T]``.
In VQ mode (``continuous=False``), this is the quantized continuous
representation. In continuous mode (``continuous=True``), this is sampled
from the posterior distribution.
Returns:
torch.Tensor: Decoded audio data with shape ``[B, 1, T']``. The output length
T' is determined by the decoder's upsampling rates and may differ from the
input temporal dimension T.
Note:
In continuous mode (``continuous=True``), the input is first passed through
a post-quantization convolution layer before being fed to the decoder.
"""
if not self.continuous:
audio = self.decoder(z)
else:
z = self.post_quant_conv(z)
audio = self.decoder(z)
return audio
def forward(
self,
audio_data: torch.Tensor,
sample_rate: int = None,
n_quantizers: int = None,
):
"""Model forward pass.
Args:
audio_data (torch.Tensor): Audio to encode, shape [B, 1, T].
sample_rate (int, optional): Sample rate in Hz. Defaults to
``self.sample_rate`` when ``None``.
n_quantizers (int, optional): Number of quantizers to use. When ``None``,
all quantizers are used. Only used in VQ mode (``continuous=False``).
Returns:
dict: A dictionary containing different keys depending on the mode:
**VQ Mode (``continuous=False``):**
- "audio" (torch.Tensor): Decoded audio, shape [B, 1, length].
- "z" (torch.Tensor): Quantized continuous representation, shape [B, D, T].
- "codes" (torch.Tensor): Codebook indices, shape [B, N, T].
- "latents" (torch.Tensor): Projected latents, shape [B, N*D, T].
- "vq/commitment_loss" (torch.Tensor): Commitment loss.
- "vq/codebook_loss" (torch.Tensor): Codebook loss.
**Continuous Mode (``continuous=True``):**
- "audio" (torch.Tensor): Decoded audio, shape [B, 1, length].
- "z" (torch.Tensor): Latent representation, shape [B, D, T].
- "kl_loss" (torch.Tensor): KL divergence loss (for VAE training).
"""
length = audio_data.shape[-1]
audio_data = self.preprocess(audio_data, sample_rate)
if not self.continuous:
z, codes, latents, commitment_loss, codebook_loss = self.encode(
audio_data, n_quantizers
)
x = self.decode(z)
return {
"audio": x[..., :length],
"z": z,
"codes": codes,
"latents": latents,
"vq/commitment_loss": commitment_loss,
"vq/codebook_loss": codebook_loss,
}
else:
posterior, _, _, _, _ = self.encode(audio_data, n_quantizers)
z = posterior.sample()
x = self.decode(z)
kl_loss = posterior.kl(dims=(1, 2))
kl_loss = kl_loss.mean()
return {
"audio": x[..., :length],
"z": z,
"kl_loss": kl_loss,
}
EntryClass = DAC