Views
No views yet
dkhokhlov/whisper-tiny-hqq-4bit.dkhokhlov/whisper-base-hqq-4bit — HQQ 4-bit, whisper-base (CPU eval)dkhokhlov/whisper-small-hqq-4bit — HQQ 4-bit, whisper-small (A10 GPU eval)openai/whisper-tiny (fp32)dkhokhlov/whisper-cascadeopenai/whisper-tiny quantized
with HQQ 4-bit
grouped quantization for CPU inference. Resident weight RAM (fp16 compute) is
57.53 MB, 23.8% smaller than the unquantized fp16 model
(75.52 MB). fp16 compute is WER-neutral; the published WER benchmark uses
fp32 compute for cross-model comparability. The key setting is mixed
precision: the whole encoder stack and fc1 are kept at 8-bit, the remaining
decoder linears are 4-bit (see the repo README for the full config and the
config-sweep ablation).fleurs en_us, n=100) WER is 0.1367 vs 0.1381 fp32 (-1.0%),
within n=100 noise. HQQ is within 5% relative of fp32 on every tested config
(5 fleurs + 4 talkbank).fleurs en_us, n=100, fp32 compute):| Metric | unquantized fp32 | HQQ 4-bit | Delta % |
|---|---|---|---|
| WER | 0.1381 | 0.1367 | -1.0% |
| Resident RAM (fp16) | 75.52 MB | 57.53 MB | -23.8% |
| Samples succeeded | 100 / 100 | 100 / 100 | - |
whisper-base/whisper-small, and the size-by-component breakdown are in
the repo README.language to force a language when it is known.1import hqq_asr
2pipe = hqq_asr.build_pipeline("dkhokhlov/whisper-tiny-hqq-4bit", quant="hqq")
3text = pipe({"array": audio, "sampling_rate": 16000})["text"] # auto-detect
4text = pipe({"array": audio, "sampling_rate": 16000},
5 generate_kwargs={"language": "spanish", "task": "transcribe"})["text"] # forcemake asr MODEL_ASR=dkhokhlov/whisper-tiny-hqq-4bit QUANT=hqq AUDIO=clip.wavencoder_model.onnx + decoder_model_merged.onnx —
a fp16-only graph (zero fp32 ops). It uses eager attention so the attention
scale stays a fp16 Mul (SDPA would decompose it to Sqrt→Div in fp32).
On CPU ONNX Runtime it runs ~4.4× slower than the fp32 export (ORT-CPU
upcasts fp16→fp32 internally — fp16 is not a primary CPU compute format, so
the slowdown is expected) but loads ~29% less RAM.encoder_model-fp32.onnx + decoder_model_merged-fp32.onnx — the
recommended CPU compute and the benchmark compute. Faster on CPU ORT; matches
the published fp32 WER benchmark.W_q and the per-group scale/zero as ONNX
initializers and emit the unpack + dequant as standard ONNX ops (opset 18), so
each graph carries the exact HQQ weights, not a re-dequantized dense copy.
Whisper is an encoder-decoder model, so each export is two ONNX graphs; the
autoregressive generation loop (argmax, KV-cache, EOS stop) runs in Python in
ORTModelForSpeechSeq2Seq, calling the encoder once and the decoder once per
token:| File (fp16 / fp32) | Role | Input | Output | Runs |
|---|---|---|---|---|
encoder_model.onnx / encoder_model-fp32.onnx | encoder | audio mel-spectrogram | hidden states | once per utterance |
decoder_model_merged.onnx / decoder_model_merged-fp32.onnx | decoder | encoder hidden states + KV cache | next text token | once per token (loop) |
1import hqq_asr
2pipe = hqq_asr.build_pipeline("dkhokhlov/whisper-tiny-hqq-4bit", quant="onnx")
3text = pipe({"array": audio, "sampling_rate": 16000})["text"]HQQ_COMPUTE_DTYPE=fp32 for the
fp32 export):make onnx HQQ_REPO=dkhokhlov/whisper-tiny-hqq-4bit ONNX_OUT=build/whisper-tiny-hqq-onnx-fp16
make hqq-reference HQQ_REPO=dkhokhlov/whisper-tiny-hqq-4bit EVAL_OUT=build/hqq_reference_tiny_fp16.json
make eval-onnx ONNX_OUT=build/whisper-tiny-hqq-onnx-fp16 \
HQQ_REFERENCE_MANIFEST=build/hqq_reference_tiny_fp16.json EVAL_OUT=build/eval_onnx_tiny_fp16.jsondocs/onnx.md in the repo.# 1. Quantize locally (writes whisper-tiny-hqq-4bit/).
python quantize.py
# 2. Measure baseline WER (fp32).
EVAL_LIMIT=100 MODEL_ASR=openai/whisper-tiny EVAL_CONFIG=en_us \
EVAL_OUT=eval_baseline.json python eval_wer.py
# 3. Measure HQQ WER.
EVAL_LIMIT=100 QUANT=hqq MODEL_ASR=./whisper-tiny-hqq-4bit EVAL_CONFIG=en_us \
EVAL_OUT=eval_hqq.json python eval_wer.py
# 4. Telephone benchmark (talkbank segment split).
EVAL_DATASET=diabolocom/talkbank_4_stt EVAL_CONFIG=en EVAL_SPLIT=segment EVAL_LIMIT=100 \
MODEL_ASR=openai/whisper-tiny EVAL_OUT=talkbank_en_fp32.json python eval_wer.py
# 5. Publish (needs a Hugging Face write token).
PUSH=1 HQQ_REPO=dkhokhlov/whisper-tiny-hqq-4bit python quantize.pyopenai/whisper-tiny
(Apache-2.0) and HQQ. The quantized
weights inherit the openai/whisper license terms.fleurs, talkbank telephone, cross-reference), and the
resident-RAM-by-component breakdown are in the repo
README. Per-config WER
evidence JSONs are committed under eval_multilingual/ and eval_telephone/
in dkhokhlov/whisper-cascade.