A neural codec is an autoencoder with a discrete bottleneck. It does two jobs
at once: it crushes audio to a handful of kilobits per second with startling fidelity,
and it turns a continuous waveform into a short sequence of integers — tokens a
language model can read. This is the hinge of the whole series: everything before it
is signal, everything after it is text. Three live demos build the machinery
from vector quantization up to a full SoundStream / EnCodec pipeline.
VQ-VAE · RVQSoundStream · EnCodec · DACStraight-through · Commitment loss · EMA
1The discrete bottleneck — one architecture, two payoffs
Part 8 built the variational autoencoder: an encoder $E$ that maps audio $\mathbf{x}$ to
a continuous latent $\mathbf{z}$, and a decoder $G$ that reconstructs it. A
neural audio codec keeps that skeleton but forces the latent through a
discrete gate — every frame is snapped to one of a finite set of learned
vectors. That single change buys two things a continuous VAE cannot give you at once.
Compression. A discrete code is just an integer index.
Send indices instead of floats and you get a bitstream — audio at 1.5–12 kbps
that still sounds like speech or music, beating hand-built codecs like Opus at the very
low end.
Tokenization. A finite alphabet of indices is
a vocabulary. The waveform becomes a sentence of tokens, and a transformer can model
$p(\text{token}_t \mid \text{token}_{
The pipeline is deliberately asymmetric to the generative model that will sit on top: the
codec is trained once, offline, to reconstruct audio as faithfully as possible;
the language model is trained separately over the tokens it produces. Get the
codec right and the hard problem of Part 1 — audio is enormous, every sample
entangled — collapses into a sequence-modelling problem no harder than language.
The middle arrow, quantization $Q$, is the whole story. It is where the fidelity is lost,
where the bitrate is set, and where the tokens are born. The rest of this part is an
unpacking of that one operator — first for a single codebook (VQ), then for a stack of
them (RVQ), then wrapped in the convolutional encoder/decoder and adversarial training
that make SoundStream, EnCodec and DAC.
2Vector quantization — snapping a vector to its nearest word
The discrete gate is vector quantization, introduced to deep learning by
the VQ-VAE (van den Oord et al., 2017). Hold a codebook — a learned table of
$K$ vectors $\{\mathbf{e}_k\}_{k=1}^{K}$, each the same dimension as the encoder output.
To quantize an encoder vector $\mathbf{z}_e$, find the nearest codebook entry and pass its
index forward; the decoder reads back that entry $\mathbf{e}_k$.
The problem: you cannot differentiate an $\arg\min$
Nearest-neighbour lookup is a step function — its gradient is zero almost everywhere and
undefined at the boundaries. Back-propagation would have no signal to train the encoder.
The VQ-VAE's trick is the straight-through estimator: on the forward pass
use the quantized $\mathbf{z}_q$; on the backward pass simply copy the gradient
from $\mathbf{z}_q$ straight onto $\mathbf{z}_e$, as if quantization were the identity.
where $\operatorname{sg}[\cdot]$ is the stop-gradient operator (identity forward, zero
derivative backward). The forward value is exactly $\mathbf{e}_{k^\star}$; the backward
value pretends the codebook was transparent. It is biased, but it works.
The losses that move the codebook
Straight-through trains the encoder and decoder, but the codebook vectors themselves get
no gradient from reconstruction. Two extra terms fix that. The codebook loss
pulls each chosen entry toward the encoder output; the commitment loss
pushes the encoder output toward its chosen entry so it does not wander between codes.
The stop-gradients split the responsibility: the codebook term only moves $\mathbf{e}$,
the commitment term only moves $\mathbf{z}_e$, and $\beta\approx0.25$ balances how tightly
the encoder is held to the table. In practice the codebook term is usually replaced by an
exponential moving average (EMA) update — treat each entry as the running
mean of the encoder vectors that selected it, which is more stable than an SGD step.
$$\mathbf{e}_k \leftarrow \frac{\sum_i \mathbb{1}[k_i=k]\,\mathbf{z}_{e,i}}{\sum_i \mathbb{1}[k_i=k]}\quad\text{(as a decaying EMA over batches)}$$
Codebook collapse. The pathology that haunts VQ: a few entries win every
lookup and the rest are never selected, so most of the vocabulary is dead and the
effective bitrate is far below $\log_2 K$. Cures include EMA updates, re-initialising
dead codes to busy encoder outputs (random restarts), lower code dimension, and
L2-normalising both codes and encoder outputs so the $\arg\min$ becomes a cosine
lookup — the DAC recipe in Section 6.
derivation · why the straight-through estimator is the right bias
Write the encoder as $\mathbf{z}_e=E_\theta(\mathbf{x})$ and the reconstruction loss
as $\ell(\hat{\mathbf{x}})=\ell(G(\mathbf{z}_q))$. The exact gradient
$\partial \ell/\partial\theta$ needs $\partial\mathbf{z}_q/\partial\mathbf{z}_e$, which
is zero: perturbing $\mathbf{z}_e$ within a Voronoi cell leaves $k^\star$, hence
$\mathbf{z}_q$, unchanged. The straight-through estimator replaces that Jacobian with
the identity, giving the surrogate
This is exactly correct in the limit of a fine codebook, where
$\mathbf{z}_q\to\mathbf{z}_e$ and quantization is nearly the identity. For a
coarse codebook it is biased, but the bias points the encoder in a direction that
reduces reconstruction error for the code it actually selected — the only thing we can
act on. The commitment term then shrinks $\lVert\mathbf{z}_e-\mathbf{e}_{k^\star}\rVert$,
making the approximation progressively tighter during training.
3Residual VQ — a stack of codebooks refining the leftover
A single codebook of $K$ entries carries only $\log_2 K$ bits per frame. To reach the
fidelity a codec needs you would want an enormous $K$ — but a million-entry codebook is
impossible to train (collapse) and slow to search. Residual vector quantization
sidesteps this: quantize coarsely with codebook 1, take the residual — what
the first code missed — and quantize that with codebook 2, and so on down a
stack of $N_q$ codebooks.
Each stage chips away at the error the previous stages left behind, so the residual
magnitude $\lVert\mathbf{r}_i\rVert$ shrinks geometrically and the reconstruction
$\hat{\mathbf{z}}$ marches toward the true encoder vector. With $N_q$ codebooks of $K$
entries each, the effective vocabulary is $K^{N_q}$ — the reach of a giant codebook — at
the training cost and search cost of $N_q$ small ones.
Left: the input (★) reached by a chain of chosen codewords, one per stage. Right: the residual magnitude collapsing stage by stage. This is the heart of SoundStream / EnCodec.
Fine bitrate control. Because the codebooks are ordered
coarse→fine, you can truncate the stack at decode time: keep the first $n\le N_q$
codes and you have a valid, lower-bitrate reconstruction. One trained codec serves a whole
ladder of bitrates.
Quantizer dropout. To make that truncation actually
work, SoundStream trains with a random number of active stages per step — so every
prefix of the stack is optimised to reconstruct on its own, not just the full depth.
Suppose each codebook's entries are spaced so that the nearest one lands within a ball
of radius proportional to the current residual's scale — i.e. stage $i$ reduces the
residual norm by a roughly constant factor $\rho<1$:
The error falls exponentially in the number of stages, so distortion in dB is
linear in $N_q$: every added codebook buys a roughly constant SNR increment,
exactly the behaviour Demo 5 plots for real audio. The factor $\rho$ improves as
each codebook is trained to tile its own residual distribution — which is why the
per-stage codebooks are learned jointly with the encoder, not fixed.
4SoundStream & EnCodec — the full pipeline
SoundStream (Zeghidour et al., 2021) and EnCodec (Défossez et al., 2022) wrap RVQ
in a fully convolutional, streaming encoder/decoder and train the whole thing
end-to-end with a mixture of reconstruction and adversarial objectives. The result is a
real-time neural codec that runs on a laptop CPU. Hover the blocks below to walk the signal
from waveform to tokens and back.
Hover a block to inspect it. Raw audio → convolutional encoder (downsampling) → RVQ bottleneck (the discrete tokens) → convolutional decoder (upsampling) → audio.
The four pieces
Convolutional encoder. A cascade of strided 1-D convolutions with
residual blocks. Each strided layer downsamples in time (strides like
$2,4,5,8$), so ~$24\,000$ samples per second collapse to ~$75$ latent frames per
second — the total stride is the product, e.g. $320\times$.
RVQ bottleneck. Each latent frame is quantized by the stack of
Section 3 into $N_q$ integer codes. These codes are the transmitted
bitstream and the tokens Part 10 models.
Convolutional decoder. A mirror of the encoder using transposed
convolutions that upsample back to the waveform rate.
Streaming. All convolutions are causal and padding is cached,
so the codec runs frame-by-frame with a fixed, small latency — essential for live calls.
The training objective — reconstruct, and fool a critic
An $\ell_2$ waveform loss alone gives muffled audio (it averages away phase detail, exactly
the Part 1 lesson). Neural codecs instead combine three ingredients, and it is the
combination that yields fidelity.
Term
What it does
Form
Multi-scale STFT
Match magnitude spectrograms at several window sizes — captures both fine pitch and broad spectral shape.
Multiple discriminators (multi-scale & multi-period, as in HiFi-GAN of Part 3) push $\hat{\mathbf{x}}$ onto the manifold of real audio, restoring crispness a regression loss blurs.
A feature-matching loss (match the discriminator's internal activations for real vs fake)
usually joins them to stabilise the GAN. EnCodec adds a small entropy-coding
stage — an arithmetic coder over the code indices — that squeezes a further ~25 %
off the bitrate for free, since the codes are not uniformly used.
Streaming vs quality. Making the convolutions causal costs a little
fidelity (the decoder cannot look ahead) but is what lets EnCodec run in real time inside a
video call. A non-causal variant, trained the same way, scores higher when latency does not
matter — the classic codec trade-off, now learned rather than hand-tuned.
5Bitrate & quality — hear the codebooks add up
The bitrate of an RVQ codec is a single tidy product: the number of frames per second,
times the number of codebooks, times the bits per codebook. Nothing else. That is what
makes RVQ so controllable — every knob in the formula is an integer you can dial.
With EnCodec's $f_r=75$ frames/s, $K=1024$ (10 bits) and $N_q=8$ codebooks you get
$75\times8\times10 = 6000$ bits/s $= 6$ kbps; drop to $N_q=2$ and you are at
$1.5$ kbps — near-telephone quality from 1500 bits a second. Because the stack is
ordered, changing $N_q$ needs no retraining: you just transmit fewer codes.
The demo below runs a residual quantizer over an actual synthesised clip and lets you
hear the trade. Add stages and the reconstruction climbs the SNR curve toward the
original; strip them away and the quantization error becomes audible hiss and grain. Press
original then quantized to A/B them at the current setting.
Left: original (faint) vs reconstruction, and the residual error. Right: SNR climbs ~6 dB per stage as bitrate rises. Drag the slider and listen.
~6 dB per stage. Because each codebook refines the
previous residual, distortion falls geometrically and SNR rises almost linearly with
$N_q$ — the same "each bit buys ~6 dB" rule from Part 1's quantization section,
now delivered by a stack of learned codebooks instead of raw bit depth.
This demo uses per-sample scalar RVQ so it can play in
your browser with no trained model. A real codec quantizes 128-dim latent vectors
with learned codebooks, which is why it reaches CD-like quality at a thousandth of this
demo's nominal bitrate.
6DAC — closing the codebook-usage gap
The Descript Audio Codec (Kumar et al., 2023) took the SoundStream/EnCodec template
and fixed its weakest link: codebook collapse. EnCodec's codebooks were often only
partly used, wasting bitrate. DAC's changes push utilisation close to 100 % and let a
single model compress 44.1 kHz audio — speech, music, environmental sound —
at ~8 kbps with quality that beats EnCodec at 3× the rate.
The three key improvements
Factorized, L2-normalized codes. The encoder output is projected to a
low-dimensional space (e.g. 8-D) for the lookup, and both the code and the query
are L2-normalized so nearest-neighbour becomes a cosine search on a hypersphere.
Low dimension + normalization dramatically raises how many codes get used.
Snake activation. Borrowed from BigVGAN, the periodic activation
$x + \tfrac{1}{\alpha}\sin^2(\alpha x)$ gives the decoder a built-in inductive bias
toward periodic (i.e. pitched, harmonic) signals — a better fit for audio than ReLU.
Quantizer dropout, fixed. DAC noted that naïve quantizer dropout
slightly hurts full-bitrate quality and applies it more carefully, keeping the
bitrate-scalability benefit without the fidelity tax.
$$\text{snake}(x) = x + \frac{1}{\alpha}\sin^2(\alpha x)$$
The lesson is general: the bottleneck was never the RVQ idea but the statistics of
the codebook. Force the codes onto a sphere in a low-dimensional space and the $\arg\min$
spreads its mass, so the bits you paid for are actually spent. DAC is now the default codec
behind many 2024–25 audio language models.
A neural codec is judged by a strange double standard: it must be a great compressor
(low bitrate, high fidelity) and a great tokenizer (codes a language model can
predict). DAC's high codebook usage helps both — every token carries information, so the
downstream transformer never wastes capacity on dead symbols.
7Why discretization unlocks language models
Everything in this part has been building one object: a sequence of integers that stands in
for a waveform. Once audio is a sequence of tokens over a fixed vocabulary, the entire
machinery of language modelling applies unchanged — and that is the subject of Part 10.
A transformer models $p(\text{token}_t \mid \text{token}_{
The RVQ flattening problem. RVQ gives $N_q$ codes per frame, so
the token grid is 2-D (time × codebook), not a 1-D stream. Part 10's whole craft is how
to serialise it: AudioLM's coarse-to-fine stages, MusicGen's delayed-interleaving pattern,
or predicting all $N_q$ codes of a frame in parallel. The codec sets the board; the language
model chooses the move order.
Contrast with classical codecs
Classical codecs — MP3, AAC, Opus — also compress audio hard, but by hand-designed
signal processing: an MDCT into the frequency domain, a psychoacoustic model that discards
what the ear cannot hear, then entropy coding. They are superb compressors and terrible
tokenizers — their bitstream is a tangle of scale factors and Huffman codes with no
learnable, model-friendly structure. See the
DSP & Music
collection's MDCT guide for how the classical side works.
Classical (Opus / MP3)
Neural (EnCodec / DAC)
Transform
Fixed MDCT + psychoacoustic mask
Learned convolutional encoder
Quantizer
Scalar, perceptually weighted
Residual vector quantization
Very-low bitrate
Artefacts, warble below ~6 kbps
Intelligible speech at 1.5 kbps
Output
A bitstream, nothing more
Tokens a transformer can generate
Neither replaces the other: Opus still wins on CPU cost and guaranteed low latency for a
phone call. But only the neural codec doubles as a generative substrate, and that
is why the field adopted it wholesale for synthesis.
8From VQ-VAE to DAC in six years
The discrete-bottleneck idea arrived for images and speech, then was engineered into a
real-time audio compressor in a remarkably tight arc.
2017
VQ-VAE (van den Oord et al.) introduces the learned discrete codebook, the straight-through estimator, and the commitment loss — discretization as a differentiable layer. Part 8 · 9
SoundStream (Zeghidour et al.) fuses a streaming conv encoder/decoder, residual VQ, and adversarial + STFT losses into the first real-time neural audio codec, with quantizer dropout for bitrate scalability. Part 9
2022
EnCodec (Défossez et al.) refines the recipe — multi-scale discriminators, a balancer for the loss mixture, and entropy coding — and ships as an open, high-quality 24/48 kHz codec. AudioLM starts modelling its tokens as a language. Part 9 · 10
2023
DAC (Descript) closes the codebook-usage gap with factorized L2-normalized codes and snake activations; MusicGen generates music directly over EnCodec tokens. Part 9 · 10
2024–25
Single-codebook and semantic codecs (Mimi, WavTokenizer, SpeechTokenizer) trade a little fidelity for far shorter, more predictable token streams — tuned for the language models that consume them. Part 10
→Where to go next
You now have the tokenizer of the neural-audio era: an autoencoder whose discrete
bottleneck compresses sound to kilobits and, in the same breath, emits a sequence of
integers. The obvious next question is what to do with that sequence — and the
answer is to model it exactly as a language.
van den Oord, A., Vinyals, O., Kavukcuoglu, K. (2017). Neural Discrete Representation Learning (VQ-VAE). NeurIPS. arXiv:1711.00937.
Razavi, A., van den Oord, A., Vinyals, O. (2019). Generating Diverse High-Fidelity Images with VQ-VAE-2. NeurIPS.
Zeghidour, N., Luebs, A., Omran, A., Skoglund, J., Tagliasacchi, M. (2021). SoundStream: An End-to-End Neural Audio Codec. IEEE/ACM TASLP. arXiv:2107.03312.
Défossez, A., Copet, J., Synnaeve, G., Adi, Y. (2022). High Fidelity Neural Audio Compression (EnCodec). arXiv:2210.13438.
Kumar, R., Seetharaman, P., Luebs, A., Kumar, I., Kumar, K. (2023). High-Fidelity Audio Compression with Improved RVQGAN (DAC). NeurIPS. arXiv:2306.06546.
Kong, J., Kim, J., Bae, J. (2020). HiFi-GAN: Generative Adversarial Networks for Efficient and High Fidelity Speech Synthesis. NeurIPS.
Borsos, Z. et al. (2022). AudioLM: A Language Modeling Approach to Audio Generation. arXiv:2209.03143.