betterflow — salesken Hindi streaming FastConformer, ONNX int8
A sherpa-onnx-loadable export of
salesken/Hindi-FastConformer-Streaming-ASR,
for on-device Hindi live partials. Mirrored at a pinned revision so a shipped app never depends on an
upstream repo staying reachable.
Files
| file | bytes | sha256 |
|---|---|---|
model.int8.onnx |
174,281,364 | 376b83ebe9b88a5324ca3d525451d76413d969802241c887b048facd6b236b24 |
tokens.txt |
18,364 | 28a457e3435be6751c361aa8978b8374be3b14764355e171a69939ed72711c19 |
Load with sherpa_onnx.OnlineRecognizer.from_nemo_ctc(model=…, tokens=…, feature_dim=80).
Geometry, read from the graph metadata: window_size 121, chunk_shift 112, subsampling_factor 8,
att_context_size [70, 13], vocab 1024 + blank, normalize_type empty.
‼️ Two things that will cost you a day if you re-derive this
1. Do not quantize Conv. The reference export-onnx-ctc.py recipe applies
quantize_dynamic(QUInt8) across all ops. That produces a model which loads, runs, and emits
nothing but blanks. Measured across seven variants:
| ops quantized | WER vs the NeMo reference | bytes |
|---|---|---|
| fp32 | 0.216 | 458,883,819 |
| MatMul only — what this repo ships | 0.189 | 174,281,364 |
| MatMul + Conv (the reference recipe) | 1.000 — empty output | 132,048,392 |
| Conv only, MatMul untouched | 0.973 | 416,953,119 |
So the ~132 MB figure published for the English artefact of this architecture is not reachable without killing the model. 174 MB is the honest int8 size, and int8 costs nothing against fp32 (0.107 vs 0.108 tail-padded).
2. This model needs the librosa mel filterbank, and sherpa-onnx did not set it.
is_librosa defaults false and was never set in sherpa's online CTC path — though it is set in
every other NeMo path (offline CTC, offline transducer, online transducer, parakeet). Feature error
against NeMo's own preprocessor is 4.11 with the wrong filterbank and 0.79 with the right one.
Models declaring normalize_type=per_feature largely absorb that; this one declares no
normalisation, so it does not. Through an unpatched sherpa it produces fluent, on-topic Hindi that
is not what was said. Fixed by one branch in online-recognizer-ctc-impl.h; worth upstreaming.
Measured quality
On vaani-bench-hi (n=200), chunked cache-aware streaming, correct filterbank:
| arm | median WER |
|---|---|
| this export, streaming | 0.328 |
| this export through the unpatched loader | 0.591 |
| offline through NeMo (ceiling) | 0.287 |
First partial arrives at 1,210 ms — 121 frames × 10 ms, an architectural floor that does not improve on faster hardware.
⚠️ Hindi only. 985 of its 1,023 vocabulary entries are Devanagari and 4 contain Latin, so it cannot write English. On code-switched Hindi-English it measures 12 WER points worse than a character-vocabulary model that can. Do not use it for Hinglish.
Licence and provenance
Apache-2.0, inherited from upstream. The base is
nvidia/stt_en_fastconformer_hybrid_large_streaming_multi, fine-tuned on ai4bharat/IndicVoices-ST
— so it must not be evaluated on any AI4Bharat corpus.