VerifiedarXiv:2006.1147734 min
Multimodal · Speech · Self-supervised learning

wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations

Pretrain a speech model on 53,000 hours of untranscribed speech by hiding short spans of the audio and training it to pick each hidden frame's true discrete code out of 100 distractors. Ten minutes of transcribed audio then fine-tunes it to 4.8% word error rate on LibriSpeech test-clean.

A convolutional encoder turns raw audio into 49 frames per second, a Transformer reads the frames with about half of them masked, and a jointly learned codebook supplies the targets. This page walks through the encoder, the masking, the quantizer, and the loss with the paper's constants, then one training step in full.

Explaining the paperwav2vec 2.0: A Framework for Self-Supervised Learning of Speech RepresentationsBaevski, Zhou, Mohamed, Auli · Facebook AI · NeurIPS 2020 · arXiv:2006.11477 ↗

In 2020 a strong English speech recognizer trained on 960 transcribed hours, and almost none of the world's roughly 7,000 languages has that much transcribed speech.

The 960 hours are LibriSpeech, read audiobooks with transcripts, and the best systems of the time added tens of thousands of hours more through pseudo-labeling. Untranscribed audio, on the other hand, is cheap everywhere. wav2vec 2.0 asks how much of a recognizer can be learned from audio alone, with transcripts used only at the end.

The recipe is the one BERT used for text, adapted to a signal with no vocabulary. Encode the waveform into a sequence of latent frames. Hide about half of them. Ask a Transformer to work out, from the unmasked neighbors, what was hidden. Since a hidden frame is a continuous vector rather than a word, the model also learns a discrete codebook, and the task becomes: among 101 candidate codewords, which one belongs at this masked position? After pre-training on 53,000 hours of LibriVox audio, a linear layer and a Connectionist Temporal Classification (CTC) loss on top of the Transformer turn it into a recognizer. With all 960 labeled hours it reaches 1.8% word error rate (WER) on test-clean and 3.3% on test-other. With ten minutes of labeled audio, 48 recordings, it reaches 4.8% and 8.2%.

The page follows the data: the convolutional encoder, span masking, the Gumbel-softmax quantizer, the contrastive and diversity losses, then one complete training step with tensor shapes, then fine-tuning and the numbers. Every constant comes from the paper or from the authors' fairseq code, which is cited where the paper leaves a mechanism ambiguous.

Waveform to 49 frames per second

Audio at 16 kHz is 16,000 floats per second, and phonemes last tens of milliseconds, so a Transformer over raw samples would attend across hundreds of positions per sound. The feature encoder ff shrinks this first. It is a stack of seven one-dimensional convolutions, each with 512 output channels, followed by layer normalization and a GELU activation. Kernel widths are (10, 3, 3, 3, 3, 2, 2) and strides are (5, 2, 2, 2, 2, 2, 2). The product of the strides is 320 samples, so one output frame covers 20 ms of audio, and the receptive field works out to 400 samples, 25 ms. One second of audio becomes 49 frames (the last partial window is dropped), which the paper reports as a 49 Hz frame rate.

The waveform is normalized to zero mean and unit variance before the first convolution (the LibriSpeech-only BASE model instead normalizes the output of the first convolution and drops the per-block layer normalization). The paper calls the encoder's final output the latent speech representations, a matrix z1,…,zT\mathbf{z}_1,\dots,\mathbf{z}_T with TT rows of 512 numbers. For a 15.6 second training crop of 250,000 samples, T=781T = 781. Those latent frames go two places. A linear layer lifts them from 512 to the Transformer width (768 for the BASE model, 1,024 for LARGE) and they enter the context network. Unchanged copies of the same frames also go to the quantizer, which produces the training targets.

Hover a frame in the figure to see which 25 ms of the waveform it summarizes, and step the depth slider to watch the stride compound through the seven blocks:

Figure 1 · the convolutional feature encoder
7 / 7
One second of audio (16,000 samples) and the frames the encoder produces after each block. At the full depth the stride is 320 samples (20 ms) and each frame summarizes a 400-sample (25 ms) window, highlighted in amber when you hover it; 49 frames cover the second because the last partial window is dropped. Step the slider to see the stride compound.

The context network gg is a standard Transformer encoder: 12 blocks with 8 heads and a 3,072-wide feed-forward layer for BASE (about 95M parameters in total), 24 blocks with 16 heads and 4,096-wide feed-forward for LARGE (about 317M). Instead of fixed sinusoidal position embeddings, a grouped convolution with kernel 128 and 16 groups runs over the input sequence, is passed through a GELU, and is added to the input. A convolution can only see relative offsets, so this acts as a relative position code, and the Transformer's output c1,…,cT\mathbf{c}_1,\dots,\mathbf{c}_T has one 768-dimensional vector per frame, each computed with attention over the whole crop.

Masking spans of latent frames

Masking happens after the encoder and before the Transformer, on the latent frames, never on the waveform. The procedure has two constants. Every frame is a candidate start with probability p=0.065p = 0.065, starts are sampled without replacement, and each start masks itself and the next M−1M - 1 frames with M=10M = 10. Spans may overlap. A masked frame's 768-dimensional input vector is replaced by a single learned vector shared by every masked position (fairseq calls it mask_emb), the analogue of BERT's [MASK] token.

The two constants imply the coverage. A frame stays unmasked only if none of the 10 candidate start positions ending at the frame itself fired, so the masked fraction is about 1−(1−0.065)10≈0.491 - (1 - 0.065)^{10} \approx 0.49. Because spans overlap and merge, the average contiguous masked run is longer than 10: the paper reports a mean of 14.7 frames, or 299 ms, with a median of 10 and a maximum near 100 frames in a 15 second crop. A simulation with the fairseq sampler (starts sampled without replacement, ⌊pT+u⌋\lfloor pT + u \rfloor of them) reproduces 49.1% and 14.7.

Why spans instead of individual frames? Adjacent 20 ms frames are nearly identical, so a single masked frame can be filled in by copying a neighbor, and the pretext task (the masked-prediction problem the model trains on before it sees any transcript) teaches nothing. The ablation in the paper's Appendix A confirms it: with span length 1 the self-supervised accuracy goes up and the downstream recognizer gets worse. Drag both sliders to the paper's values and read the coverage, then push MM to 1 and to 20:

Figure 2 · span masking on the latent frames
0.065
10
200 frames (4 s) masked the way fairseq samples it: ⌊pT+u⌋\lfloor pT + u \rfloor start indices without replacement, each expanded to MM frames, overlaps allowed. Amber frames are masked; white ticks are the sampled starts; the histogram counts merged masked runs. At the paper's p=0.065p = 0.065, M=10M = 10 about 49% is masked and the mean run is near 14.7 frames. Set M=1M = 1 to see the task the ablation calls trivial: isolated 20 ms holes.

The quantizer: two codebooks of 320

A masked-prediction loss needs a target. For text the target is a word index and the loss is a softmax over the vocabulary. A 512-dimensional speech frame has no index, so wav2vec 2.0 builds one with a learned product quantizer: G=2G = 2 codebooks (the paper says groups), each holding V=320V = 320 entries, each entry a vector of 128 numbers for BASE. A frame is quantized by picking one entry from each codebook and concatenating the two picks into a 256-dimensional vector, which a linear layer maps to the target qt\mathbf{q}_t. Two codebooks of 320 give 3202=102,400320^2 = 102{,}400 distinct codewords from only 640640 stored vectors of 128 numbers; a single codebook with that many codewords would need 102,400 stored vectors of 256 numbers.

Picking an entry is an argmax, which has no gradient, and the codebook has to be learned jointly with everything else. The paper uses the Gumbel-softmax with the straight-through estimator. A linear layer maps the 512-dimensional frame zt\mathbf{z}_t to G⋅V=640G \cdot V = 640 logits l∈R2×320\mathbf{l} \in \mathbb{R}^{2 \times 320}. For codebook gg, the probability of entry vv is

pg,v=exp⁡((lg,v+nv)/τ)∑k=1Vexp⁡((lg,k+nk)/τ),n=−log⁡(−log⁡u),u∼U(0,1)p_{g,v} = \frac{\exp\big((l_{g,v} + n_v)/\tau\big)}{\sum_{k=1}^{V} \exp\big((l_{g,k} + n_k)/\tau\big)}, \qquad n = -\log(-\log u),\quad u \sim \mathcal{U}(0,1)pg,v=exp⁡((lg,v+nv)/τ)∑k=1Vexp⁡((lg,k+nk)/τ),n=−log⁡(−log⁡u),u∼U(0,1)\begin{gathered} p_{g,v} = \frac{\exp\big((l_{g,v} + n_v)/\tau\big)}{\sum_{k=1}^{V} \exp\big((l_{g,k} + n_k)/\tau\big)}, \\ n = -\log(-\log u),\quad u \sim \mathcal{U}(0,1) \end{gathered}
(1)

where τ\tau is a temperature and nn is Gumbel noise, one fresh draw per logit. The paper typesets the temperature as exp⁡(l+n)/τ\exp(l + n)/\tau, outside the exponential, where it cancels between numerator and denominator and would have no effect. Equation (1) above puts it inside, which is what the Gumbel-softmax paper defines and what the code does (PyTorch's gumbel_softmax computes softmax((logits + gumbels) / tau)).

Adding Gumbel noise and taking the argmax is exactly a sample from the categorical distribution softmax(lg)\mathrm{softmax}(\mathbf{l}_g) (the Gumbel-max trick), so the pick is random when two logits are close and deterministic when one dominates. The forward pass uses the hard argmax i=arg⁡max⁡vpg,vi = \arg\max_v p_{g,v} and returns the codebook entry eg,ie_{g,i} as a one-hot selection. The backward pass differentiates the soft probabilities pgp_g in place of the one-hot: PyTorch implements this as y_hard - y_soft.detach() + y_soft, which has the value of the hard pick and the gradient of the soft one. So the logits, the linear layer producing them, and through it the convolutional encoder all receive gradient from the loss on qt\mathbf{q}_t. The output is computed as ∑vyg,v eg,v\sum_v y_{g,v}\, e_{g,v}, where ygy_g is the straight-through selection above (one-hot in value), so the sum equals the selected entry eg,ie_{g,i} and that codebook vector receives gradient.

The temperature is annealed. It starts at 2, is multiplied by 0.999995 after every update, and is floored at 0.5 for BASE and 0.1 for LARGE. Reaching 0.5 from 2 takes about 277,000 updates, so BASE (400,000 updates) spends its last third at the floor. Early on the soft probabilities are flat, so many codebook entries get gradient for each frame; late, they approach the one-hot pick and the estimator's bias shrinks. Drag the temperature and resample the noise to see how often the argmax changes:

Figure 3 · Gumbel-softmax over one codebook
2.00
Sixteen of one codebook's 320 entries, fixed logits, one draw of Gumbel noise. Teal bars are the soft probabilities softmax((l+n)/τ)\mathrm{softmax}((\mathbf{l}+\mathbf{n})/\tau) that the backward pass differentiates; the amber box is the hard argmax the forward pass emits. Gray dots count how often each entry wins over 2,000 noise draws: that distribution is softmax(l)\mathrm{softmax}(\mathbf{l}) and does not move with τ\tau. Drag τ\tau from 2 to 0.05 and resample.

After pre-training the quantizer is discarded. Appendix D of the paper checks what it learned by running the LARGE model over TIMIT, a corpus with hand-labeled phonemes, and counting which phoneme co-occurs with each codeword. Many codewords fire for one specific phoneme, although no phoneme labels were used in pre-training; the silence label, which is 22% of TIMIT, is spread over many codewords.

The contrastive loss

For each masked position tt the Transformer emits a context vector ct\mathbf{c}_t. The quantizer emits the target qt\mathbf{q}_t from the unmasked frame at the same position. The loss scores qt\mathbf{q}_t against K+1K + 1 candidates Qt\mathbf{Q}_t: the true one plus K=100K = 100 distractors, which are the quantized targets of other masked positions in the same utterance, sampled uniformly. With cosine similarity sim(a,b)=a⊤b/∥a∥∥b∥sim(\mathbf{a},\mathbf{b}) = \mathbf{a}^{\top}\mathbf{b} / \lVert\mathbf{a}\rVert\lVert\mathbf{b}\rVert and a temperature κ=0.1\kappa = 0.1,

Lm=−log⁡exp⁡(sim(ct,qt)/κ)∑q~∼Qtexp⁡(sim(ct,q~)/κ)\mathcal{L}_m = -\log \frac{\exp\big(sim(\mathbf{c}_t, \mathbf{q}_t)/\kappa\big)}{\sum_{\tilde{\mathbf{q}} \sim \mathbf{Q}_t} \exp\big(sim(\mathbf{c}_t, \tilde{\mathbf{q}})/\kappa\big)}
(3)

Read (3) as a 101-way classification problem whose logits are cosine similarities divided by 0.1, with the true codeword in class 0, and the loss is the cross-entropy of that classification. In the code, ct\mathbf{c}_t is first projected from 768 to 256 dimensions by a linear layer so that it can be compared with the 256-dimensional targets; the paper does not mention this projection. If a distractor happens to be the identical codeword to the positive (two frames quantized the same way), the code sets its logit to −∞-\infty so it is not counted as a wrong answer. That rule has a consequence: the fewer distinct codewords the quantizer uses, the fewer effective distractors each masked frame faces, and a codebook collapsed to one entry would leave none and a loss of zero. The diversity loss in the next section rules this out.

This form is the InfoNCE loss from contrastive predictive coding (CPC), and it comes with a bound: for NN candidates including the positive, I(ct;qt)≥log⁡N−LmI(\mathbf{c}_t;\mathbf{q}_t) \ge \log N - \mathcal{L}_m. With N=101N = 101 the constant is log⁡101≈4.62\log 101 \approx 4.62 nats, so a model whose loss averages 1.5 nats has, under the assumptions of the CPC derivation, at least 3.1 nats of mutual information between its context vector and the quantized frame it could not see. A model that gives every candidate the same score sits at Lm=log⁡101\mathcal{L}_m = \log 101 and the bound says nothing. Distractors are drawn from the same utterance because distractors from other speakers would be easy to reject by voice alone, and the model would learn speaker identity instead of content. The ablation confirms that taking 50 of the 100 negatives from other utterances in the batch raises dev WER from 7.97 to 8.79.

The figure lays out one masked position: the positive and 100 distractors as points on the cosine axis, the softmax after dividing by κ\kappa, and the resulting loss next to the log⁡(K+1)\log(K+1) ceiling. Drag κ\kappa toward 1 and watch the probabilities flatten; drag KK to 1 and the task becomes a coin flip:

Figure 4 · the contrastive loss at one masked position
0.10
100
0.60
Top: the context vector's cosine similarity to the true target and to KK distractors. Bottom: the softmax over all K+1K+1 candidates after dividing by κ\kappa, sorted. The loss is −log⁡-\log of the amber bar; the meter compares it with log⁡(K+1)\log(K+1), where a model that scores every candidate equally sits. At κ=1\kappa = 1 a 0.6 positive against 0.55 distractors is nearly a tie; at 0.1 the same gap is 0.5 nats of logit.

The diversity loss

A quantizer trained only through (3) is rewarded for collapsing: every distractor that shares the positive's codeword is discarded, so a codebook using 20 of its 320 entries faces fewer effective distractors than one using all 320, and the task gets easier as the codebook shrinks. Appendix F reports what happens with the diversity term removed: dev WER rises from 7.97 to 8.48. The diversity loss, borrowed from Dieleman et al. (2018), maximizes the entropy of the average selection distribution. Let pˉg\bar{p}_g be the softmax over codebook gg's logits (no Gumbel noise, no temperature) averaged over all masked frames in the batch. Then

Ld=1GV∑g=1G−H(pˉg)=1GV∑g=1G∑v=1Vpˉg,vlog⁡pˉg,v\mathcal{L}_d = \frac{1}{GV} \sum_{g=1}^{G} -H(\bar{p}_g) = \frac{1}{GV} \sum_{g=1}^{G} \sum_{v=1}^{V} \bar{p}_{g,v} \log \bar{p}_{g,v}
(4)

Minimizing negative entropy maximizes entropy, and the entropy of a distribution over 320 entries is maximal when all 320 are used equally often. Because of the averaging, this penalizes uneven usage across the batch rather than confident picks within a frame: each frame can be confidently assigned to one entry while the batch as a whole spreads across all of them. The total pre-training objective is

L=Lm+α Ld,α=0.1\mathcal{L} = \mathcal{L}_m + \alpha\,\mathcal{L}_d, \qquad \alpha = 0.1
(2)

The code implements a different function with the same minimizer. It computes each codebook's perplexity exp⁡H(pˉg)\exp H(\bar{p}_g), the effective number of entries in use, and penalizes (GV−∑gexp⁡H(pˉg))/GV(GV - \sum_g \exp H(\bar{p}_g)) / GV. That is 0 when both codebooks use all 320 entries uniformly and about 0.997 when each has collapsed to one entry. The paper's footnote calls the two "equivalent"; they share a minimum but their gradients differ, and the perplexity version is what α=0.1\alpha = 0.1 was tuned against. Setting α\alpha to 0.2 gives 8.58 with a large seed variance, which the authors describe as slight instability. Drag the usage histogram to concentrate mass on a few entries and read the entropy, perplexity, and both forms of the penalty:

Figure 5 · codebook usage and the diversity loss
0.35
The batch-averaged selection distribution pˉ\bar{p} over one codebook's 320 entries, from uniform to collapsed. The readouts give its entropy, its perplexity (the effective number of entries in use), the paper's (4), and the perplexity form the code minimizes, (GV−∑geHg)/GV(GV - \sum_g e^{H_g})/GV, for two identical codebooks. Both are smallest at uniform usage; only their scale and gradient differ.

One training step, with shapes

The pieces assembled for the BASE model on LibriSpeech, one crop of one utterance. Batches are built by cropping 250,000 samples (15.6 s) from each recording and packing crops up to 1.4 million samples per GPU; on 64 V100 GPUs that is about 1.6 hours of audio per update. Training runs 400,000 updates with Adam, a linear warm-up over the first 8% (32,000 updates) to a peak learning rate of 5×10−45 \times 10^{-4}, then linear decay; it takes 1.6 days. LARGE uses 128 GPUs, 2.7 hours of audio per update, 250,000 updates for LibriSpeech (2.3 days) and 600,000 for LibriVox (5.2 days).

# one pre-training step, BASE model, one 15.6 s crop (250,000 samples)
wav = normalize(crop)                       # [250000]  zero mean, unit var
z   = conv_encoder(wav)                     # [781, 512] 20 ms per frame
q_in = z                                    # quantizer sees UNMASKED z
x   = post_proj(z)                          # [781, 768]
mask = sample_spans(T=781, p=0.065, M=10)   # ~382 masked frames (49%)
x[mask] = mask_emb                          # one learned 768-vector
c   = transformer(x)                        # [781, 768] full context
c_m = final_proj(c[mask])                   # [382, 256]

logits = weight_proj(q_in[mask])            # [382, 640] = 2 groups x 320
probs  = gumbel_softmax(logits.view(382, 2, 320), tau)   # hard one-hot fwd
e      = pick_codewords(probs)              # [382, 2, 128] -> cat -> [382, 256]
q_m    = project_q(e)                       # [382, 256] the targets

negs = sample_other_masked(q_m, K=100)      # [100, 382, 256] same utterance
sim  = cosine(c_m, cat([q_m, negs])) / 0.1  # [101, 382]  kappa = 0.1
L_m  = cross_entropy(sim.T, target=0)       # summed over 382 masked frames
L_d  = (640 - sum_g perplexity(mean_probs_g)) / 640   # codebook usage
loss = L_m + 0.1 * 382 * L_d + 10 * 382 * mean(z ** 2)  # fairseq weights
loss.backward()   # grads: transformer, projections, codebooks, encoder (x0.1)

Three things in the listing are code facts the paper does not spell out. The diversity loss (and, for LibriSpeech runs, the feature penalty described next) is multiplied by the number of masked frames: the contrastive loss is a sum over masked frames, not a mean, so this scaling keeps α=0.1\alpha = 0.1 a per-frame weight. For the LibriSpeech-only runs an L2 penalty on the encoder output (weight 10 in fairseq) and a 0.1 multiplier on the encoder's gradient regularize the convolutional stack, whose 4 million parameters otherwise overfit to 960 hours; neither is used for the 53,000 hour LibriVox run. And the quantizer is evaluated on the unmasked features at the masked positions only, so pˉg\bar{p}_g in (4) averages over the roughly 382 masked frames per crop, not all 781.

The gradient reaches every parameter: the Transformer and its final projection through ct\mathbf{c}_t; the codebook vectors, the logit layer, and (scaled by 0.1) the convolutional encoder through qt\mathbf{q}_t and the straight-through estimator; and the encoder a second time through the Transformer's input. Appendix F reports that blocking the gradient from the quantizer into the encoder raises dev WER from 7.97 to 8.41, so the encoder needs both paths. Dropout of 0.1 is applied inside the Transformer, on the encoder output, and on the quantizer input, and whole Transformer layers are dropped with probability 0.05 (BASE) or 0.2 (LARGE) during LibriSpeech pre-training. The checkpoint with the lowest Lm\mathcal{L}_m on held-out audio is kept.

Fine-tuning with CTC

Pre-training produces a network that maps audio to 49 context vectors per second and has never seen a letter. To make a recognizer, a randomly initialized linear layer maps each ct\mathbf{c}_t to CC output classes. For LibriSpeech these are characters: the paper counts 29 character tokens plus a word boundary token; the fairseq dictionary adds a blank and its own special symbols, for 32 outputs in total. The quantizer, its projection, and the contrastive head are removed.

Frames outnumber characters by roughly three to one (a 15.6 s crop has 781 frames and about 230 characters), and nobody knows which frames belong to which letter. Connectionist Temporal Classification (CTC) handles this without an alignment. It predicts one of the 32 symbols per frame, defines the output of a frame sequence by collapsing repeated symbols and then deleting blanks (so h h ε e l ε l l o reads hello, and the blank between the two l's is what lets a double letter survive), and the loss is the negative log of the total probability of every frame sequence that collapses to the transcript:

p(Y∣X)=∑A∈AX,Y∏t=1Tpt(at∣X)p(Y \mid X) = \sum_{A \in \mathcal{A}_{X,Y}} \prod_{t=1}^{T} p_t(a_t \mid X)

The sum has exponentially many terms and is computed exactly by a forward-backward dynamic program in the same spirit as HMM training. CTC treats the per-frame outputs as conditionally independent given the audio, which is why decoding pairs it with a language model.

# fine-tuning: characters from frames, CTC
z = conv_encoder(wav)        # frozen after pre-training
c = transformer(mask_aug(z)) # SpecAugment-style span masks on z
y = linear(c)                # [T, 32]: 26 letters, ', |, blank, ...
loss = ctc(log_softmax(y), transcript)   # sums over all alignments
# decode: greedy collapse, or beam search with a word-level LM

The fine-tuning schedule protects the pre-trained weights. The convolutional encoder is frozen throughout. For the first 10,000 updates only the new linear layer trains, so that random output weights do not send large gradients into the Transformer; then the Transformer trains too. The learning rate warms up for 10% of updates, holds for 40%, and decays for the remaining 50%. Peak rates are small: 2×10−52 \times 10^{-5} or 3×10−53 \times 10^{-5} for the Libri-light subsets (the 10 minute, 1 hour, and 10 hour label sets) and 10−410^{-4} for the 960 hour set. The number of updates scales with the data: 12,000 for ten minutes, 13,000 for one hour, 20,000 for ten hours, 50,000 for 100 hours, 320,000 for 960 hours. A SpecAugment-style augmentation masks spans of ten latent frames (reusing mask_emb) and spans of 64 channels (set to zero) during fine-tuning; the paper credits it with delaying overfitting on the smallest subsets, where 12,000 updates at 1,600 seconds of audio per batch amount to about 32,000 passes over the same 600 seconds of recordings.

Decoding adds a language model (LM) trained on the LibriSpeech text corpus: either a 4-gram model or a 20-block Transformer LM with width 1,280. Beam search combines the acoustic log-probabilities with a weighted LM score and a per-word insertion penalty; the two weights are tuned by Bayesian optimization on dev-other (128 trials), with beam 1,500 for the 4-gram and 500 for the Transformer at test time. The acoustic model emits characters while the LM scores words, which the paper notes delays LM feedback compared with the word-piece vocabularies used by competing systems.

Results: 10 minutes of labels

The headline experiments hold the pre-trained model fixed and vary the amount of transcribed audio: 10 minutes, 1 hour, 10 hours (the Libri-light subsets, drawn from LibriSpeech), 100 hours (train-clean-100), and all 960 hours. WER is reported on test-clean (read speech from easier speakers) and test-other (harder speakers and recording conditions). The pre-training corpus is LibriSpeech's own 960 hours without transcripts (LS-960) or 53,200 hours of LibriVox (LV-60k).

Labeled dataBASE, LS-960LARGE, LS-960LARGE, LV-60kPrior best
10 min6.9 / 12.96.8 / 10.84.8 / 8.216.3 / 25.2 (Discrete BERT)
1 hour4.0 / 9.33.9 / 7.62.9 / 5.89.0 / 17.6 (Discrete BERT)
10 hours3.2 / 7.83.2 / 6.12.6 / 4.95.9 / 14.1 (Discrete BERT)
100 hours2.6 / 6.32.3 / 5.02.0 / 4.03.72 / 7.11 (Iter. pseudo-labeling, LV-60k)
960 hours2.1 / 4.82.0 / 4.11.8 / 3.31.7 / 3.4 (Noisy student)

Test-clean / test-other WER in percent, all with the Transformer LM (Tables 1 and 2 of the paper); the last column is the best published row at each budget in Table 1. Three comparisons from that table. The paper takes iterative self-training (Noisy student) as the previous state of the art on 100 hours among systems that, like wav2vec 2.0 LS-960, use only LibriSpeech audio as unlabeled data: 4.2 / 8.6. The LARGE LS-960 model fine-tuned on the same 100 hours gets 2.3 / 5.0, a relative reduction of 45% and 42%. With one hour of labels the same model, at 3.9 / 7.6, is still ahead of that 100 hour system: 100 times less transcribed audio and the same unlabeled audio. And with ten minutes and LibriVox pre-training, 4.8 / 8.2 is better than every 100 hour system in Table 1 except iterative pseudo-labeling with LibriVox (3.72 / 7.11).

The language model does more work when labels are scarce. Without any LM, the ten minute LV-60k model is at 40.2 / 38.7; the 4-gram brings that to 6.6 / 10.3 and the Transformer LM to 4.8 / 8.2. At 960 hours the no-LM number is 2.2 / 4.5, and the Transformer LM only trims it to 1.8 / 3.3. The ten minute acoustic model has learned the sounds but has seen too few words to spell them; the error tables in Appendix E are dominated by phonetic spellings such as "are" transcribed as "ar", which a word-level LM corrects. Toggle the LM and the test set in the figure and read the three curves:

Figure 6 · WER against labeled audio (Tables 9 and 10)
Three pre-trained models fine-tuned on 10 minutes to 960 hours of transcribed audio, log axes. LARGE on LibriVox stays below the others at every budget. Switch to "no LM" to see how much of the 10 minute result the language model supplies (40.2 to 4.8 on test-clean) and how little it adds at 960 hours (2.2 to 1.8).

On the full 960 hours the LARGE LV-60k model's 1.8 / 3.3 is a new best on test-other and within 0.1 of Noisy student's 1.7 on test-clean. Trained from scratch without pre-training, the same LARGE network reaches 2.1 / 4.6, worse than the 1.9 / 4.1 of ContextNet, a purely supervised model trained on the same 960 labeled hours and the architecture Noisy student builds on. The LARGE network on its own is therefore not the source of the gain; pre-training is. On TIMIT phoneme recognition, fine-tuned without any LM, LARGE LS-960 gets a phone error rate of 7.4 on dev and 8.3 on test against 9.6 / 11.6 for the previous best, vq-wav2vec; the paper quotes this as a 23% / 29% relative reduction (the test figure computes to 28.4%).

Two more effects are visible in the table. Going from BASE to LARGE on the same LS-960 audio helps most on test-other, the noisier set (12.9 to 10.8 at ten minutes). Going from LS-960 to LV-60k, 55 times more unlabeled audio with the same LARGE architecture, helps at every label budget, and most at the smallest (10.8 to 8.2). Section 5.1 of the paper quotes the ten minute LV-60k result as 5.2 / 8.6; the abstract, the conclusion, and Table 1 all say 4.8 / 8.2, and the table is the number used here.

Why quantize targets, not inputs

The earlier pipeline, vq-wav2vec followed by a BERT over the discrete codes, quantized the frames once and fed the codes to the Transformer as input and used them as targets. wav2vec 2.0 keeps the Transformer input continuous and quantizes only the target. The paper tests all four combinations in a reduced setup: BASE pre-trained on LS-960 for 250,000 updates with p=0.075p = 0.075, fine-tuned on 10 hours, three fine-tuning seeds, dev WER averaged over dev-clean and dev-other.

Figure 7 · inputs and targets, continuous or quantized (Table 4)
Dev WER in the reduced ablation setup, mean and standard deviation over three fine-tuning seeds. Click a cell. The teal cell is the design the paper ships. The two continuous-input cells also list the pretext-task training accuracy: the continuous target is easier to identify (78% against 62%) and gives a worse recognizer.

Continuous input with quantized targets, 7.97, wins. Quantizing the input as well, the vq-wav2vec design, gives 12.18: the Transformer loses whatever the codebook could not represent. Keeping everything continuous gives 8.58, and the paper reports that the training accuracy of picking the correct latent rises from 62% to 78% when the target is continuous. The pretext task got easier and the recognizer got worse, because a continuous target carries speaker and background detail that identifies the frame without any phonetic knowledge. Adding an MLP on the continuous target (8.51) or separate encoders for input and target (8.90) does not close the gap.

The remaining ablations in Appendices A and F are small. Mask length 8, 12, or 15 instead of 10 costs 0.2 to 0.5 WER. Sampling span lengths from a distribution instead of a fixed 10, without overlap, is worse in every variant tried (the best, Poisson with mean 15, gives 8.13). Doubling the negatives to 200 (8.12) or sampling them from any time step rather than masked ones (8.07) changes little. Removing the Gumbel noise gives 8.73 with a seed standard deviation of 0.42, twenty times the baseline's 0.02. Four codebooks of 18 entries (9.02) is worse and eight codebooks of 8 (8.13) is close. Widening the receptive field to 30 ms (7.99) or the positional convolution to kernel 256 (8.14) does nothing.

What the paper does not settle

The framework has costs and open ends the paper states or that follow-up work exposed. The acoustic model emits characters through CTC while the strongest contemporaries used word pieces and sequence-to-sequence decoders; the authors expect further gains from both and did not test them. The 1.8 / 3.3 result needs a Transformer language model and a beam of 500; the model on its own is at 2.2 / 4.5. Pre-training LARGE on LibriVox took 128 V100 GPUs for 5.2 days; most users start from the released checkpoints.

The contrastive objective itself was the first part to be replaced. HuBERT (2021) keeps the encoder, the span masking, and the Transformer, but predicts cluster assignments from an offline k-means over features with a plain cross-entropy, and matches or improves on wav2vec 2.0 at every label budget; data2vec (2022) predicts a teacher network's continuous layer averages and drops the codebook altogether. Both results suggest that what mattered in wav2vec 2.0 was masked prediction of a target derived from the unmasked signal, and that the quantizer plus InfoNCE was one workable way to make that target discrete rather than the essential one. Table 4 points the same way: fully continuous training still works, only 0.6 WER behind (8.58 against 7.97), far from the 12.18 of quantizing both.

The label-budget result stands regardless of which objective later won. A 5,760-fold drop in transcribed audio, from 960 hours to 10 minutes, costs 3.0 points of test-clean WER (1.8 to 4.8) after pre-training on 53,000 hours of untranscribed speech, and ten minutes of transcription is within reach for most of the 7,000 languages the paper's introduction counts.

Provenance Verified against primary literatureHow we verify
Baevski, Zhou, Mohamed, Auli (NeurIPS 2020), arXiv:2006.11477v3Equations (1) to (4), Sections 2 to 5, Tables 1 to 4, Appendices A, B, D, F. All WER, PER, and hyperparameter values are quoted from the tables, not the running text.
fairseq wav2vec2.py (facebookresearch/fairseq, main)final_proj projects c_t from 768 to 256 before the cosine (line 416, 771); project_q maps the concatenated codewords to final_dim (377); mask_emb is one learned uniform-initialized vector (400); negatives are drawn from other masked positions with the self index skipped (499 to 556); negatives equal to the positive get logit -inf (557 to 576); the quantizer runs on unmasked features at masked positions (721 to 733); extra losses are (num_vars - perplexity) / num_vars and the feature L2 penalty (818 to 830).
fairseq gumbel_vector_quantizer.py; wav2vec_criterion.py; wav2vec2_base_librispeech.yamlF.gumbel_softmax(x, tau, hard=True) in training and plain argmax at inference; avg_probs is a softmax with no noise or temperature averaged over batch and time; loss_weights [0.1, 10] are multiplied by the number of masked frames because the InfoNCE term is a sum; mask_prob 0.65 with mask_length 10 equals the paper's p = 0.065 because the code draws mask_prob * T / M starts; latent_temp (2, 0.5, 0.999995); feature_grad_mult 0.1; Adam betas (0.9, 0.98), weight decay 0.01, warm-up 32,000 of 400,000 updates.
fairseq data_utils.compute_mask_indicesStart indices are drawn without replacement, floor(p*T + u) of them with u uniform, then expanded to M frames with overlap allowed. Our simulation of this sampler gives 49.1% coverage and a 14.7-frame mean merged span at p = 0.065, M = 10, T = 781, matching Section 4.2.
van den Oord, Li, Vinyals (2018), arXiv:1807.03748InfoNCE loss (their eq. 4) and the bound I(x; c) >= log N - L_N with N counting the positive and all negatives; tighter as N grows.
Jang, Gu, Poole (ICLR 2017), arXiv:1611.01144; torch.nn.functional.gumbel_softmaxGumbel-softmax sample y_i = exp((log pi_i + g_i)/tau) / sum_j exp((log pi_j + g_j)/tau) with the temperature inside the exponential; Gumbel noise -log(-log u); straight-through estimator as hard forward, soft backward (y_hard - y_soft.detach() + y_soft).
Baevski, Schneider, Auli, vq-wav2vec (ICLR 2020), arXiv:1910.05453Origin of the G = 2, V = 320 Gumbel product quantizer and of the equation typeset with the temperature outside the exponential, which wav2vec 2.0 reproduces.
Dieleman, van den Oord, Simonyan (2018), arXiv:1806.10474Diversity loss as the negative entropy of the batch-averaged selection distribution; codebook collapse described there for VQ-VAEs.
Graves et al. (ICML 2006); Hannun, Distill 2017CTC: collapse repeats then remove blanks; p(Y|X) sums over all alignments; conditional independence across frames.
Kahn et al., Libri-light (2020), arXiv:1912.07875The 10 minute, 1 hour, and 10 hour limited-supervision subsets of LibriSpeech and the roughly 60,000 hours of LibriVox audio.
Hsu et al., HuBERT (2021); Baevski et al., data2vec (2022)The follow-ups named in the last section, read from their abstracts.
correctionEquation (1) as printed places the Gumbel-softmax temperature outside the exponential, exp(l + n)/tau, where it cancels between numerator and denominator and has no effect; the Gumbel-softmax definition and the fairseq code (F.gumbel_softmax) use exp((l + n)/tau), which is what this page teaches. The same typesetting appears in the vq-wav2vec paper it inherits from. Two smaller points: Section 5.1 quotes the ten minute LV-60k result as 5.2/8.6 WER while the abstract, conclusion, and Table 1 give 4.8/8.2 (the table is used here); and the TIMIT relative PER reduction quoted as 23%/29% computes to 22.9%/28.4% from Table 3. Footnote 2 calls the perplexity form of the diversity loss 'equivalent' to the entropy form; they share a minimizer but are different functions with different gradients, and the perplexity form is what the released code optimizes.

Questions you might still have

?

Why not predict the masked frame directly, the way BERT predicts a masked word?
A word is one of 30,000 discrete tokens, so a softmax over the vocabulary is a well-posed target. A speech frame is a 512-dimensional continuous vector with no vocabulary. Regressing it with a squared error lets the model win by predicting a blurry average, and reconstructing it in full rewards speaker and microphone detail that does not help transcription. The quantizer manufactures a vocabulary of 102,400 codewords, and the contrastive loss only needs the true codeword to score higher than 100 distractors. The BERT explainer on this site covers the text version.

?

The targets come from the same network that is being trained. Why does the model not collapse to a trivial solution?
Three things prevent it. The quantizer output for a masked frame comes from the unmasked encoder feature at that position, which the Transformer never sees, so the context vector has to predict it from the neighbors. The distractors come from other masked positions of the same utterance, so the model cannot reject them by speaker or channel. And the diversity loss pushes codebook usage toward uniform. Without it the codebook could collapse onto a few entries, and since the code discards any distractor identical to the positive, a fully collapsed codebook would leave no distractors at all and a contrastive loss of zero.

?

What does the temperature in the contrastive loss do?
Cosine similarity lives in [-1, 1]. Dividing by kappa = 0.1 stretches that to [-10, 10] before the softmax, so a positive at similarity 0.9 and a distractor at 0.7 differ by 2 nats instead of 0.2. Without the division the softmax over 101 candidates is nearly flat and the gradient is tiny. With too small a kappa the loss is dominated by the single hardest distractor.

?

Does the 4.8% number mean a model trained on ten minutes of speech?
No. The model saw 53,000 hours of untranscribed LibriVox audio during pre-training, then ten minutes (48 recordings) of transcribed audio during fine-tuning, and the 4.8% word error rate on test-clean also uses a Transformer language model trained on the LibriSpeech text corpus. Without any language model the same model gets 40.2% on test-clean.

?

Why are the inputs to the Transformer continuous but the targets quantized?
The paper tested all four combinations (Table 4). Continuous inputs keep the most information for building context, and quantized targets stop the model from matching speaker and background detail that a continuous target would carry. Quantizing both, which is what the earlier vq-wav2vec plus BERT pipeline did, was the worst of the four at 12.18% dev WER against 7.97% for the chosen design.

?

How does this relate to Whisper?
Whisper takes the opposite bet: 680,000 hours of weakly labeled transcripts and plain supervised training, no self-supervised stage. wav2vec 2.0 shows how far unlabeled audio plus a few minutes of transcripts can go, which matters for the thousands of languages with no large transcribed corpus. The Whisper explainer on this site covers the supervised side.

?

Is wav2vec 2.0 still used?
The pre-trained checkpoints are still a standard starting point for low-resource speech recognition and for speaker, emotion, and language identification, and the architecture (conv encoder, span masking, Transformer) carried into HuBERT, data2vec, and XLS-R. Later work mostly replaced the contrastive objective with prediction of clustered or teacher targets, which the last section discusses.

Footnotes & further reading

  1. The paper: Baevski, Zhou, Mohamed, Auli, wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations (Facebook AI, NeurIPS 2020). Code and checkpoints in fairseq.
  2. The masked-prediction recipe for text: Devlin et al., BERT, explained on this site at /bert/.
  3. The InfoNCE loss and its mutual-information bound: van den Oord, Li, Vinyals, Representation Learning with Contrastive Predictive Coding (2018). The same loss with a temperature over cosine similarities appears in CLIP.
  4. Gumbel-softmax and the straight-through estimator: Jang, Gu, Poole, Categorical Reparameterization with Gumbel-Softmax (ICLR 2017), and concurrently Maddison, Mnih, Teh, The Concrete Distribution.
  5. The predecessor whose quantizer this paper adopts: Baevski, Schneider, Auli, vq-wav2vec (ICLR 2020), and the original wav2vec (2019). Product quantization itself: Jégou, Douze, Schmid, Product Quantization for Nearest Neighbor Search (TPAMI 2011).
  6. The diversity loss: Dieleman, van den Oord, Simonyan, The Challenge of Realistic Music Generation (NeurIPS 2018), Section 3.2.
  7. CTC: Graves, Fernández, Gomez, Schmidhuber, Connectionist Temporal Classification (ICML 2006); a visual walkthrough by Hannun at Distill.
  8. Data: Panayotov et al., LibriSpeech (2015); Kahn et al., Libri-light (2020) for the 10 minute, 1 hour, and 10 hour subsets and the LibriVox audio.
  9. The baselines in Table 1: Park et al., Improved Noisy Student Training for ASR (2020) and Baevski et al., Effectiveness of self-supervised pre-training for speech recognition (Discrete BERT, 2019).
  10. Successors: Hsu et al., HuBERT (2021); Baevski et al., data2vec (2022). The supervised alternative at scale: Whisper.