indicconformer-stt-pa-ctc-shabad-preview

This is the acoustic model from a pipeline for live Gurbani captioning, described in karanbirsingh.com/gurbani-captioning. The prototype runs at bani.karanbirsingh.com, where these weights drive a corpus-constrained CTC decoder feeding a state-machine line tracker.

The model is not intended in isolation and therefore we deprioritize raw WER / CER in favor of a benchmark that better reflects the end-to-end problem. We frame the problem, benchmark, and initial baseline here: karanbirsingh/live-gurbani-captioning-benchmark-v1.

CTC-only finetune of ai4bharat/indicconformer_stt_pa_hybrid_ctc_rnnt_large, trained April 2026. The hybrid base ships both CTC and RNNT decoders; this release keeps only the CTC head for streaming and edge deployment.

Intended use

In Gurbani-facing applications, raw transcripts from this model should not be displayed directly to end users. Acoustic outputs should be normalized to real Gurbani before reaching any UI. See more in linked writing.

Files

file size purpose
model.int8.onnx 184 MB INT8-quantized ONNX
model.onnx 480 MB FP32 ONNX
tokenizer.model 242 KB SentencePiece tokenizer
edge-vocab.json 2.6 KB flat vocab list (decoder-side)

Usage

# pip install huggingface_hub onnxruntime sentencepiece numpy
import wave
import numpy as np
import onnxruntime as ort
import sentencepiece as spm
from huggingface_hub import snapshot_download

local = snapshot_download("karansea/indicconformer-stt-pa-ctc-shabad-preview")
sess = ort.InferenceSession(f"{local}/model.int8.onnx", providers=["CPUExecutionProvider"])
sp = spm.SentencePieceProcessor(); sp.Load(f"{local}/tokenizer.model")

# 16 kHz mono float32 waveform, shape [1, T]
with wave.open("clip.wav", "rb") as f:
    assert f.getframerate() == 16000 and f.getnchannels() == 1
    pcm = np.frombuffer(f.readframes(f.getnframes()), dtype=np.int16)
audio = (pcm.astype(np.float32) / 32768.0)[None, :]
audio_len = np.array([audio.shape[1]], dtype=np.int64)

log_probs, out_len = sess.run(
    ["log_probs", "out_len"],
    {"audio": audio, "audio_len": audio_len},
)

# CTC greedy decode (vocab = 256 PA tokens + blank at 256)
BLANK = 256
ids = log_probs[0, :int(out_len[0])].argmax(-1).tolist()
collapsed, prev = [], -1
for i in ids:
    if i != prev and i != BLANK:
        collapsed.append(int(i))
    prev = i
print(sp.decode(collapsed))

I/O signature: audio: float32 [B, T] @ 16 kHz, audio_len: int64 [B] → log_probs: float32 [B, T', 257], out_len: int64 [B]. Vocab is 256 Punjabi (Gurmukhi) SentencePiece pieces + CTC blank at index 256.

Attribution

Base model: AI4Bharat IndicConformer (Punjabi, hybrid CTC-RNNT large), released under MIT.

Finetune by @karansea.

License

MIT (inherits from the base model).

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for karansea/indicconformer-stt-pa-ctc-shabad-preview

Finetuned
(1)
this model