Deep Speech 2: End-to-End Speech Recognition in English and Mandarin
Replace a hand-built speech pipeline with one deep network trained on spectrograms, feed it about 12,000 hours of audio, and engineer the training like a supercomputer job. It then matches human transcribers on several benchmarks.
Start here (no maths needed)
One big neural network, trained on thousands of hours of recorded speech, can turn sound straight into written words.
Think of it like this
When you talk to a voice assistant like Siri, it has to turn your voice into text. Older systems did this in many separate steps, each built by experts. Deep Speech 2 learns the whole job in one go, by listening to about 12,000 hours of people talking along with what they said. That's well over a year of non-stop audio.
How it works
- The sound is turned into a picture of which pitches are loud at each moment.
- The network looks at that picture one tiny slice of time at a time.
- For each slice it guesses a letter, or "blank" if nothing new is happening.
- Repeated letters are squashed together and blanks are removed. "hh_e_ll_ll_oo" becomes "hello".
- Training means checking these guesses against the real words and adjusting, over and over.
Why robots care
You want to shout "stop!" at a robot and have it react right away. That's why the paper also built a version that writes words while you are still speaking, instead of waiting for the end of the sentence.
Try it
- Say "hello" very slowly, stretching each sound. Write down a letter for every beat, using "_" when there's a pause. Then cross out repeats and blanks. Do you get "hello" back?
- In the demo further down, move the Frames T slider to change how many time slices there are. Press Another alignment to see a different way of spelling out "hello" over time. Each one still squashes down to the same word.
Words to know
- Speech recognition
- Turning spoken words into written text.
- Spectrogram
- A picture of sound showing which pitches are loud at each moment.
- Frame
- One tiny slice of time in the audio.
- Blank
- A special symbol meaning "nothing new here".
- CTC
- The training method that lets the network learn without being told which slice goes with which letter.
Going deeper: everything below is the full version, with some maths. On a first read, skim the headings and the "Why it matters for robotics" box, and come back for the rest later.
1. Summary
TL;DR
Classic speech recognisers were pipelines: feature extraction, an acoustic model, a pronunciation dictionary, a language model, each tuned by experts. Deep Speech 2 (DS2) trains one network that maps spectrogram frames straight to characters, using the CTC loss so no frame-by-frame alignment is needed. The same recipe worked for English and Mandarin with almost no language-specific changes. The paper is as much about scale as architecture: 11,940 hours of English, up to about 100M parameters, a training system about 7× faster than their previous one, and a deployment design that keeps latency low.
- Model: 1–3 convolution layers over the spectrogram, up to 7 recurrent layers, a fully connected layer, then a softmax over characters plus a "blank".
- Training tricks: batch normalisation adapted to RNNs, and SortaGrad, which feeds short utterances first in the first epoch.
- Results: on WSJ eval'92, 3.60% WER vs 5.03% for human transcribers. On LibriSpeech test-clean, 5.33% vs 5.83%. On real noisy speech (CHiME), still well behind: 21.79% vs 11.84%.
- Data scaling: WER fell about 40% (relative) for each 10× more training data, following a power law.
- Deployment: forward-only RNNs plus a small look-ahead layer, 16-bit weights and request batching. Median latency 44 ms at 10 concurrent streams, for a 5% relative accuracy cost.
2. The core idea
The network outputs, for every audio frame t, a probability over symbols: letters, space, apostrophe and a special blank (for Mandarin, about 6,000 characters). A transcript is much shorter than the frame sequence, and nobody labels which frame belongs to which letter. CTC solves this by summing over every frame-level path that collapses to the right text:
L(x, y) = −log Σ_{ℓ ∈ Align(x, y)} Π_t p(ℓ_t | x)
collapse(ℓ): merge repeated symbols, then delete blanks
"hh_e_ll_ll_oo" → "hel_lo" → "hello"
ℓ: one alignment, a symbol for each frame.Align(x, y): all alignments that collapse to transcripty. There are many, and a dynamic program sums them efficiently.- The blank lets the network say "nothing new here", and it separates genuine double letters like the "ll" in "hello".
At test time, a beam search combines the network with an n-gram language model:
Q(y) = log p_ctc(y | x) + α · log p_lm(y) + β · word_count(y)
α weights the language model and β stops the search from favouring too-short outputs. Both are tuned on a development set.
Interactive: many alignments, one transcript
A random valid frame-level path for "hello" (_ = blank), and what it collapses to. Change the frame count and see how many paths CTC sums over.
3. Deep dive
Making deep RNNs trainable
Sequence-wise batch norm. Normalising the recurrent term step by step didn't help. What worked was normalising only the input-to-hidden part, with statistics over the whole minibatch and the whole sequence: h_t = f(B(W·h_t^{l−1}) + U·h_{t−1}). The gain grew with depth, about 12% for the deepest network in their comparison. At deployment they use running averages from training, so single utterances work.
SortaGrad. The CTC loss for a long utterance is a product of many probabilities below 1, so long clips have large losses and large gradients early in training. In the first epoch, DS2 sorts minibatches by length, short first, then goes back to random order. It's a cheap curriculum that makes training more stable.
Convolutions and striding. 2D convolutions over time and frequency at the bottom helped most on noisy speech: three 2D layers instead of one 1D layer cut noisy-set WER by 23.9%. Striding shortens the sequence for the RNNs. In English that can leave too few frames per character, so they predict non-overlapping bigrams ("th", "e", …) and can stride by 3.
Scale is part of the method
Training a model took tens of exaFLOPs. Their system ran synchronous SGD across 8–16 GPUs, with a custom all-reduce, a GPU CTC implementation and a custom memory allocator. It sustained about 50 teraFLOP/s on 16 GPUs, so a model trained in 3–5 days instead of weeks. Faster experiments meant more of them. The data table shows a clean power law, an early hint of what Day 25 formalises. They also note that activations, not weights, dominate training memory, the problem Day 24 attacks with re-materialisation.
From research model to product
Bidirectional RNNs must hear the whole utterance before transcribing. For deployment they used forward-only layers plus a row convolution on top, which lets each step peek at a small window of future frames:
r_{t,i} = Σ_{j=1}^{τ+1} W_{i,j} · h_{t+j−1, i}
The deployed Mandarin model used τ = 19, five forward-only recurrent layers and 16-bit arithmetic, which they found didn't measurably change accuracy. Batch Dispatch groups concurrent user requests into small batches on a GPU, trading a little waiting for much better throughput. The deployed system had 6.10% character error vs 5.81% for the research model. For the latency side of this trade-off on small on-device models, see Module 04.
4. Why it matters for robotics
- Voice is a natural robot interface. "Stop", "bring me the red cup", "go back to the dock". DS2 showed one end-to-end model can do this without hand-built pronunciation dictionaries, which is the basis of today's on-robot speech front ends.
- Streaming matters more than benchmark WER. A robot can't wait for the full sentence before it reacts to "stop". The forward-only + small look-ahead design is exactly the latency-vs-accuracy trade a robot needs. Module 04 turns latency into stopping distance.
- Robots are noisy places. Motors, fans and far-field microphones look like the CHiME conditions, where DS2 was still far worse than humans. Test on your robot's own audio, not clean benchmarks.
- WER isn't the metric you care about. For commands, one wrong word can mean a wrong action. Module 04 shows why "exactly right" per command matters more.
- Small batches on the edge. On a robot the batch size is often 1. DS2's finding that RNN inference at small batch is memory-bandwidth bound, and its use of 16-bit weights, still apply to embedded boards.
5. How to study it
- Read sections 3 (architecture) and 7 (deployment) of the paper, about 1.5 h. Skim section 4 on the training system and section 6 on results by condition.
- In the 30u30 Day 22 folder, run
setup.py, thentrain_minimal.pyon the synthetic data, andvisualization.pyto look at spectrograms and outputs. - Read
implementation.py: find the CTC loss, the greedy decoder (collapse repeats, drop blanks) and the sequence-wise batch norm. - Do the exercises: spectrogram, CTC loss and greedy decoding, the RNN with batch norm, SortaGrad, then the full pipeline.
- Stretch: record a few of your own commands, run them through a pretrained open-source CTC model, and measure both WER and "exactly right".
6. Self-check
Why does CTC need a blank symbol?
To output "nothing new" on frames between characters, and to separate genuine repeated letters. Without a blank, "ll" would collapse to "l".
Why are longer utterances harder early in training?
The CTC likelihood is a product over many frames, so long clips have much larger losses and gradients. SortaGrad starts with short ones to keep early training stable.
Why can't a bidirectional RNN stream?
Its backward direction starts at the end of the utterance, so nothing can be output until the speaker finishes. Forward-only layers with a short look-ahead fix that.
What does the language-model term in decoding add?
Knowledge from far more text than the labelled audio. It helps choose between acoustically similar transcripts. Its gain shrank as the acoustic model got deeper.
What did the data-scaling experiment show?
WER fell as a power law in training hours, about 40% relative per 10× data, on both clean and noisy development sets.
7. Further reading
- The original paper
- 30u30 Day 22: implementation, notebook, cheatsheet, exercises
- Next: Day 23, Variational Lossy Autoencoder