WAV vs MP3 for Training Data
Short answer. WAV stores uncompressed PCM: 16-bit mono at 16 kHz is 32 kB per second, 115 MB per hour, 115 GB for 1,000 hours. MP3 at 128 kbps is 58 MB per hour, half the size, and at 32 kbps it is 14 MB per hour, an eighth, at a quality cost that shows up as a WER increase in the model you train on it. For training data the rule is simple: archive in WAV or FLAC, ship lossless, and use a lossy format only when the storage saving is worth an accuracy loss you have actually measured.
How to do it
Do the storage arithmetic before choosing a format
1,000 hours at 16 kHz, 16-bit, mono is 115 GB. The same 1,000 hours at 48 kHz, 24-bit, mono is 518 GB. FLAC on speech typically compresses to 50 to 60% of the PCM size, so the 16 kHz corpus becomes roughly 60 GB, and MP3 at 128 kbps is 58 GB. Those two numbers being nearly identical is the argument: FLAC is lossless and MP3 at 128 kbps is not, and at that bitrate you are not buying meaningful space.
The savings only become real at low bitrates. MP3 at 64 kbps is 29 GB and at 32 kbps is 14 GB, an 8x reduction against WAV. That is a real saving and it comes with a real accuracy cost, which is why the decision should follow a measurement rather than a preference.
What a perceptual codec actually removes
MP3 transforms overlapping windows into the frequency domain, quantizes the coefficients coarsely, and decides how coarsely using a psychoacoustic masking model: content that a human listener would not notice is discarded first. That is the correct trade for playback and the wrong one for training, because the model is not a human listener and does not have the same masking curve.
The discarded content concentrates in low-energy, high-frequency regions — which is where fricatives live. The codec also quantizes the stereo image and the fine temporal structure, and it introduces pre-echo around transients, which for speech means plosives. At 128 kbps most of this is small; at 32 kbps it is the dominant part of the signal in those bands.
Measure the round trip on your own data, not on a chart
Two measurements. Signal-to-noise ratio of the decoded signal against the original is cheap and gives you a rough sense of the magnitude: at 128 kbps expect roughly 20 to 30 dB on speech, at 32 kbps below 15 dB. SNR alone is misleading for a perceptual codec, because the error is deliberately concentrated where it is least audible, so a low SNR can still sound fine.
The measurement that matters is the downstream one: run your recognizer on the clean corpus and on the transcoded corpus, and compare WER. On speech at 128 kbps the change is usually under a point, which is inside the confidence interval and therefore not evidence of anything. At 32 kbps the change is visible, and it appears on the noisy and accented subsets first. If you cannot run the downstream test, transcode a small sample and compare WER on that; it is still better than guessing.
Bitrate is not the only knob, and the others cost more
Encoding a 16 kHz source at a 44.1 kHz sample rate triples the storage and adds no information, because the content above 8 kHz does not exist. Downsampling to 8 kHz before encoding saves more space than dropping the bitrate from 128 to 64, and it costs more accuracy because it removes the fricative band outright.
Mono versus stereo doubles the size for speech that is effectively mono. Encoder implementation matters as well: two encoders at the same nominal bitrate can differ by several dB of measured error, because the bitrate is a target and not a guarantee. If you specify a lossy format in a data contract, specify the encoder and the settings, not just the format name.
The rule that survives all of this
Keep the master in WAV, and keep a FLAC copy as the distribution format if size matters. Transcode to a lossy format only at the edge, for a preview, a streaming delivery, or a specific consumer that asked for it. Never transcode a lossy file to another lossy format, because the artifacts compound: encoding an MP3 to MP3 at a lower bitrate produces audible and measurable degradation far worse than a single encode at the lower bitrate.
One caveat in the other direction. If your product runs on MP3 or Opus audio, training on lossless audio creates a mismatch, and fine-tuning on the codec the product actually uses is worth more than a fraction of a WER point. The rule is not "lossless always" — it is "know which codec the deployment uses and match it."
Code
File size and round-trip error for the same 10-second signal in three lossless or uncompressed encodings, plus the storage arithmetic for 1,000 hours.
import io
import numpy as np
import soundfile as sf
SR = 16000
rng = np.random.default_rng(0)
t = np.arange(SR * 10) / SR
sig = 0.6 * np.sin(2 * np.pi * 200 * t) + 0.25 * np.sin(2 * np.pi * 3300 * t)
sig = sig + 0.02 * rng.normal(size=t.size)
sig = (sig / np.max(np.abs(sig))).astype(np.float32)
def roundtrip(fmt, subtype):
buf = io.BytesIO()
sf.write(buf, sig, SR, format=fmt, subtype=subtype)
size = buf.getbuffer().nbytes
buf.seek(0)
y, _ = sf.read(buf, dtype='float32')
err = y[:len(sig)] - sig[:len(y)]
snr = 10.0 * np.log10((sig ** 2).sum() / ((err ** 2).sum() + 1e-12))
return size, snr
print('the same 10-second signal, three encodings:')
for fmt, sub in (('WAV', 'PCM_16'), ('WAV', 'PCM_U8'), ('FLAC', 'PCM_16')):
size, snr = roundtrip(fmt, sub)
print(' %-4s %-7s %7.1f kB %6.1f MB/hour round-trip SNR %6.1f dB'
% (fmt, sub, size / 1024.0, size * 360.0 / 1e6, snr))
try:
size, snr = roundtrip('MP3', 'MPEG_LAYER_III')
print(' MP3 default %7.1f kB %6.1f MB/hour round-trip SNR %6.1f dB'
% (size / 1024.0, size * 360.0 / 1e6, snr))
except Exception as exc:
print(' MP3 encoder not present in this libsndfile build (%s).'
% type(exc).__name__)
print(' sizes below are computed from the bitrate, which is exact.')
print()
print('storage for 1,000 hours of mono speech:')
for name, bps in (('WAV PCM_16 at 16 kHz', 16000 * 2),
('FLAC PCM_16, about 0.55x', 16000 * 2 * 0.55),
('MP3 at 128 kbps', 128000 / 8),
('MP3 at 64 kbps', 64000 / 8),
('MP3 at 32 kbps', 32000 / 8)):
print(' %-26s %6.1f GB' % (name, bps * 3600.0 * 1000.0 / 1e9)) - pip install numpy soundfile. soundfile needs libsndfile, which ships with it in the wheels for macOS, Linux, and Windows.
- Expected output: PCM_16 and FLAC both come back at roughly 96 dB of round-trip SNR, because FLAC stores 16-bit integers and the float signal is quantized to 16 bits either way. FLAC is smaller and identical in quality, which is the whole case for it.
- PCM_U8 comes back around 45 dB. That is the cost of 8 bits, and it is audible.
- The MP3 line needs libsndfile 1.1.0 or newer. If it is missing, the script says so and still prints the size table, which is exact because MP3 size is fully determined by the bitrate.
- The 1,000-hour table is the number to remember: FLAC at about 60 GB and MP3 at 128 kbps at about 58 GB for the same corpus.
Where this goes wrong
Transcoding an already-lossy file to another lossy format
Each encode discards content using a masking model, and the second encode is working on audio that has already had the first model applied. The artifacts do not just add, they compound in the low-level regions where the second encoder now finds less to mask. An MP3 at 128 kbps re-encoded to 64 kbps is worse than a single encode at 64 kbps, and the difference is measurable in WER. Always encode from the lossless master.
Assuming FLAC saves space on everything
FLAC compresses speech well because speech has predictable structure, but a corpus of noisy recordings, or audio with a high noise floor, compresses much less — sometimes only 20%. The 0.55 factor is a rule of thumb for clean speech. Measure on a sample of your own corpus before you plan storage around it.
Comparing lossy formats by bitrate alone
Two encoders at 128 kbps produce different amounts of error, because the bitrate is a target rather than a guarantee and the psychoacoustic model differs. Opus at 32 kbps is widely reported to beat MP3 at 64 kbps on speech, and the ordering flips again at high bitrates for music. A format specification in a data contract has to name the encoder and the version, not just the format.
Ignoring the sample rate when computing the size saving
The saving from a lossy codec is relative to the PCM you would otherwise store, and that depends on the sample rate and bit depth. Dropping from 48 kHz 24-bit to 16 kHz 16-bit PCM is already a 4.5x reduction with no codec at all, and it costs the same high-frequency content a lossy codec would remove. Decide the sample rate first, then the codec; choosing a codec to fix a storage problem created by an unnecessarily high sample rate is solving the wrong problem.
Training on lossless audio and deploying on a codec
If the product receives Opus from a browser or MP3 from an archive, the training distribution and the deployment distribution differ in exactly the bands the codec altered. Fine-tuning on a small amount of audio encoded with the deployment codec at the deployment bitrate usually recovers more than the codec cost in the first place. The direction of the mismatch matters, and it is the opposite of what most teams assume.
When to buy the data instead of building the pipeline
Buy when you need the corpus in a single format with a documented provenance chain, which is harder to assemble than to encode: a corpus that has been re-encoded, resampled, and partially upsampled by three different vendors is not something you can fix at the format level. Buy when you need matched-format audio for a deployment codec — real Opus or MP3 at the bitrate the product uses, not a transcoded approximation — because that mismatch is worth more accuracy than the storage is worth money. Buy when the corpus is large enough that the format decision is a five-figure storage difference, since that is when the arithmetic in this page stops being academic. If you are recording your own audio, record lossless and encode a copy later; the master is the only thing that cannot be recreated.
More technical reference
-
Opus Audio Codec
opus audio codec
-
Beamforming Microphone Array
beamforming microphone array
-
Neural Speech Codec
neural speech codec
-
Word Error Rate (WER)
word error rate
-
Character Error Rate (CER)
character error rate
-
Speaker Diarization
speaker diarization
Need data for WAV vs MP3 for Training Data?
Tell us the language, the hours, and what the data needs to look like. You will get a real number and a real timeline — not a range. If we cannot source it well, we will tell you that instead.
- Pilot batch before the full run, so problems surface early.
- Consent documentation delivered with the data.
- No medical or clinical data. No recorded telephone calls.