GGUF + pure-C++ runtime in CrispASR — OmniASR-CTC-1B
We've added OmniASR-CTC-1B to CrispASR as the omniasr backend (src/omniasr.cpp). The same backend covers the CTC variants (300M, 1B) and the autoregressive LLM variants (300M, 1B) — dispatched by GGUF metadata.
Three OmniASR-specific things were non-obvious and worth flagging:
- Input must be
layer_norm(waveform)— zero mean, unit variance. Without this, the CTC head emits mostly blanks. wav2vec2-style models all need this; OmniASR isn't an exception. - CTC blank = token 0 (
<s>), not token 1 (<pad>). fairseq2 puts the BOS at the blank slot; HF's wav2vec2 convention uses<pad>. We output text by removing consecutive duplicates + dropping special tokens (no separate "remove blanks" pass needed). pos_conv padding = K // 2(=64 for K=128), not(K-1)//2. The extra padding element gives correct same-padding behaviour for fairseq2'sConv1d.
Architecture: 7-layer CNN feature extractor (320× downsampling) + Linear(512→1024) + 24-layer transformer (d=1024, 16 heads, FFN=4096, pre-norm, GELU) + CTC head (Linear(1024→9812), SentencePiece tokenizer). Raw 16 kHz PCM input — no mel features.
The 1B variant scales to 48 encoder layers + d=1280. 1600+ languages at 551 MB Q4_K.
Pre-quantised GGUFs (Apache-2.0): cstr/omniASR-CTC-1B-GGUF
./build/bin/crispasr --backend omniasr -m omniasr-ctc-1b-q4_k.gguf -l de \
-f audio.wav --punc-model fullstop-punc-q4_k.gguf
(CTC = no native punctuation; --punc-model fullstop-punc-q4_k.gguf covers DE/EN/FR/IT, fireredpunc-q8_0.gguf covers EN+CN.) Sister repos: CTC-300M, LLM-300M, LLM-1B.