Asymmetric audio vae encode decode
Skill kjuhwa/skills-hub/skills/audio/asymmetric-audio-vae-encode-decode
Self-correcting knowledge corpus for Claude Code — 9 stable shape clusters, bias-correction pipeline baked into contribution flow. 47 papers, 45 techniques, 1.1k skills.
npx -y skills add kjuhwa/skills-hub --skill asymmetric-audio-vae-encode-decodeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Build an AudioVAE with a 16kHz encoder and 48kHz decoder for built-in super-resolution
SKILL.md
4.5 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it
AudioVAE with 16kHz encoder + 48kHz decoder for built-in super-resolution
When to use
Use this pattern when your input audio is available at 16kHz (e.g., telephone recordings, ASR training data) but your output should be broadcast-quality 48kHz. The asymmetric design avoids paying the compute cost of 48kHz encoding, while the decoder learns to reconstruct the high-frequency content, eliminating the need for a separate upsampler module at inference time.
This is a structural choice for audio codec / VAE design, not an inference trick — bake it in at model definition time.
Pattern
Encoder (16kHz path)
import torch
import torch.nn as nn
class AudioEncoder16k(nn.Module):
"""Encodes 16kHz waveforms into latent patches."""
def __init__(self, in_channels=1, latent_dim=64, patch_size=320):
super().__init__()
# patch_size=320 @ 16kHz = 20ms patches
self.conv_in = nn.Conv1d(in_channels, 64, kernel_size=7, padding=3)
self.encoder_blocks = nn.Sequential(
nn.Conv1d(64, 128, kernel_size=4, stride=2, padding=1), # 8kHz
nn.ELU(),
nn.Conv1d(128, 256, kernel_size=4, stride=2, padding=1), # 4kHz
nn.ELU(),
nn.Conv1d(256, latent_dim * 2, kernel_size=1), # mean + logvar
)
def forward(self, x_16k: torch.Tensor):
# x_16k: [B, 1, T_16k]
h = self.conv_in(x_16k)
h = self.encoder_blocks(h)
mean, logvar = h.chunk(2, dim=1)
return mean, logvar
Decoder (48kHz path — 3× upsampling built in)
class AudioDecoder48k(nn.Module):
"""Decodes latent patches to 48kHz waveforms via learned upsampling."""
def __init__(self, latent_dim=64, out_channels=1):
super().__init__()
self.conv_in = nn.Conv1d(latent_dim, 256, kernel_size=1)
self.decoder_blocks = nn.Sequential(
# 4kHz latent → 8kHz
nn.ConvTranspose1d(256, 128, kernel_size=4, stride=2, padding=1),
nn.ELU(),
# 8kHz → 16kHz
nn.ConvTranspose1d(128, 64, kernel_size=4, stride=2, padding=1),
nn.ELU(),
# 16kHz → 48kHz (3×)
nn.ConvTranspose1d(64, 32, kernel_size=6, stride=3, padding=1),
nn.ELU(),
)
self.conv_out = nn.Conv1d(32, out_channels, kernel_size=7, padding=3)
def forward(self, z: torch.Tensor):
# z: [B, latent_dim, T_latent]
h = self.conv_in(z)
h = self.decoder_blocks(h)
return torch.tanh(self.conv_out(h)) # [B, 1, T_48k]
VAE wrapper
class AsymmetricAudioVAE(nn.Module):
def __init__(self):
super().__init__()
self.encoder = AudioEncoder16k()
self.decoder = AudioDecoder48k()
def encode(self, x_16k):
mean, logvar = self.encoder(x_16k)
std = torch.exp(0.5 * logvar)
z = mean + std * torch.randn_like(std)
return z, mean, logvar
def decode(self, z):
return self.decoder(z)
def forward(self, x_16k):
z, mean, logvar = self.encode(x_16k)
x_48k_hat = self.decode(z)
return x_48k_hat, mean, logvar
Inference: encode at 16kHz, decode to 48kHz
# Typical inference usage
vae = AsymmetricAudioVAE().eval()
with torch.no_grad():
z, _, _ = vae.encode(waveform_16k) # cheap 16kHz encode
audio_48k = vae.decode(z) # full 48kHz output
Source reference
- Upstream:
OpenBMB/VoxCPM@main/13605c5a - Key files:
src/voxcpm/modules/audiovae/audio_vae_v2.py:1-100+— full asymmetric VAE with encoder/decoder blocks and ConvTranspose1d upsampling
Notes
- The 3× upsampling stride in the decoder (
stride=3) must be set carefully — kernel size should be2*strideand paddingstride//2to avoid aliasing. - Training requires a 48kHz ground-truth target even though encoding is 16kHz; ensure your dataset pipeline provides both.
- Do not apply a separate torch-audio or librosa resampler at inference — the decoder's upsampling is the resampler.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most video audio skills give in ~1.2k tokens
Counted across 622 of the 795 authors here whose files we hold, read 2026-08-07
- Read individual rule files for detailed explanationsin 21 of 622, across 10 files
- Render final videoin 13 of 622, across 6 files
- Use WAV PCM 16kHz mono audio formatin 12 of 622, across 3 files
- Use this skill when dealing with Remotion codein 11 of 622, across 4 files
- Save generated audio to a WAV filein 11 of 622, across 4 files
- Handle conversion errors gracefullyin 10 of 622, across 6 files
- Add captions to videos alwaysin 10 of 622, across 4 files
- Generate music from text descriptions using MusicGenin 9 of 622, across 2 files
- Do not skip pipeline layersin 9 of 622, across 3 files
- Do not make one tool do everythingin 9 of 622, across 3 files
- Use Azure Document Intelligence for complex PDFsin 9 of 622, across 4 files
- Never ask the user to paste their full API keyin 9 of 622, across 3 files
Said here and by no other author read
- set decoder stride to three for upsampling
- set kernel size to twice the stride
- set padding to half the stride
- provide 48kHz ground-truth audio for training
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.