CoolFace
Modelpublic

AigizK/GigaAM-Bashkir-CV25-ONNX

sourceHugging Facemitupdated 2mo agoView on Hugging Face
0likes22downloads
Model Card

GigaAM Bashkir ASR — ONNX

ONNX Runtime export of `AigizK/GigaAM-Bashkir-CV25`, a character-level CTC ASR model for Bashkir (Башҡорт теле). The source model was fine-tuned from GigaAM Multilingual multilingual_ssl on Mozilla Common Voice 25 Bashkir.

Results

Raw WER is computed after lowercasing and punctuation removal on the complete Common Voice 25 splits, using onnx-asr with batch size 32.

RuntimeValidation WERTest WER
PyTorch checkpoint7.20%7.73%
ONNX FP327.26%7.74%
ONNX dynamic INT87.37%7.80%

Validation contains 14,525 clips (19.467 hours); test contains 14,572 clips (19.885 hours). See evaluation_results.json for exact error counts, hashes, providers, and runtime measurements.

Installation

CPU:

bash
pip install "onnx-asr[cpu,hub]>=0.12,<0.13"

NVIDIA CUDA for FP32:

bash
pip install "onnx-asr[hub]>=0.12,<0.13" onnxruntime-gpu

Usage

FP32

python
import onnx_asr

model = onnx_asr.load_model("AigizK/GigaAM-Bashkir-CV25-ONNX")
print(model.recognize("bashkir_audio.wav"))

INT8 on CPU

python
import onnx_asr

model = onnx_asr.load_model("AigizK/GigaAM-Bashkir-CV25-ONNX", quantization="int8")
print(model.recognize("bashkir_audio.wav"))

NVIDIA GPU

python
import onnx_asr

model = onnx_asr.load_model(
    "AigizK/GigaAM-Bashkir-CV25-ONNX",
    providers=["CUDAExecutionProvider", "CPUExecutionProvider"],
)
print(model.recognize("bashkir_audio.wav"))

Dynamic INT8 contains ConvInteger/MatMulInteger operators and is intended for CPU. Use FP32 with the CUDA Execution Provider on NVIDIA GPUs.

Batch recognition

Passing a list performs one padded batch and is substantially faster on GPU:

python
texts = model.recognize([
    "audio_01.wav",
    "audio_02.wav",
    "audio_03.wav",
    "audio_04.wav",
])
for text in texts:
    print(text)

Group recordings of similar duration to reduce padding overhead.

Configure CPU threads

python
import onnx_asr
import onnxruntime as ort

options = ort.SessionOptions()
options.intra_op_num_threads = 16
options.inter_op_num_threads = 1

model = onnx_asr.load_model(
    "AigizK/GigaAM-Bashkir-CV25-ONNX",
    quantization="int8",
    providers=["CPUExecutionProvider"],
    sess_options=options,
)

Parallel requests with one shared model

python
from concurrent.futures import ThreadPoolExecutor

files = ["audio_01.wav", "audio_02.wav", "audio_03.wav", "audio_04.wav"]
with ThreadPoolExecutor(max_workers=4) as pool:
    texts = list(pool.map(model.recognize, files))

For maximum GPU throughput, prefer a real batch over concurrent batch-1 calls.

NumPy waveform / non-WAV audio

The built-in path reader accepts mono PCM WAV. Decode MP3/FLAC with an audio library and pass a float32 NumPy array:

python
import soundfile as sf

waveform, sample_rate = sf.read("bashkir_audio.flac", dtype="float32")
text = model.recognize(waveform, sample_rate=sample_rate, channel="mean")
print(text)

Token timestamps and log probabilities

python
timestamped_model = model.with_timestamps()
result = timestamped_model.recognize("bashkir_audio.wav")
print(result.text)
print(result.tokens)
print(result.timestamps)
print(result.logprobs)

Long audio with VAD

python
import onnx_asr

vad = onnx_asr.load_vad("silero")
longform_model = model.with_vad(vad)
for segment in longform_model.recognize("long_bashkir_audio.wav"):
    print(segment.start, segment.end, segment.text)

CLI

bash
onnx-asr AigizK/GigaAM-Bashkir-CV25-ONNX bashkir_audio.wav

onnx-asr accepts mono PCM WAV paths directly. It also accepts a float32 NumPy waveform and a sample_rate argument when audio is decoded by another library. The output is lowercase Bashkir text without punctuation.

Performance benchmark

Higher × realtime is better: 100× means 100 seconds of audio are processed in one second. Audio was decoded to mono 16 kHz and preloaded into RAM. Timed sections include feature extraction, ONNX inference, and greedy CTC decoding; Hub download, model loading/graph optimization, MP3 decoding, and disk I/O are excluded.

Hardware and software:

  • —AMD EPYC 7452, 32 physical cores / 64 threads
  • —NVIDIA GeForce RTX 3090 24 GB
  • —NVIDIA GeForce RTX 5090 32 GB
  • —onnx-asr 0.12.0, ONNX Runtime 1.23.2, Python 3.11
  • —deterministic, evenly spaced rows from Common Voice 25 Bashkir test

Batch size

Same 96 clips / 466.704 seconds of audio for every row. CPU uses 32 ONNX Runtime intra-op threads. GPU uses the CUDA Execution Provider.

RuntimeBatchClips/sAudio speedp50 batch latency
CPU FP3216.933.7×138.1 ms
CPU FP3286.933.6×1213.8 ms
CPU FP32327.536.5×4103.1 ms
CPU INT816.330.4×149.2 ms
CPU INT884.923.8×1659.3 ms
CPU INT8324.823.5×6590.4 ms
RTX 3090 FP32114.369.7×67.9 ms
RTX 3090 FP328110.2535.7×74.4 ms
RTX 3090 FP3232153.3745.1×202.5 ms
RTX 5090 FP32123.8115.9×40.3 ms
RTX 5090 FP328178.6868.3×46.6 ms
RTX 5090 FP3232379.31844.0×86.0 ms

CPU intra-op thread scaling

Batch size 8; same 24 clips / 117.324 seconds of audio.

ORT threadsFP32INT8
15.2×5.0×
29.6×8.8×
417.2×14.1×
826.5×19.8×
1634.1×24.3×
3238.0×27.6×

Parallel batch-1 requests

One shared model, Python ThreadPoolExecutor, same 32 clips / 158.580 seconds. CPU sessions use 8 intra-op threads.

Runtime1 worker2 workers4 workers
CPU FP3229.0×41.0×54.4×
CPU INT824.9×40.5×58.6×
RTX 3090 FP3276.6×101.5×143.8×
RTX 5090 FP32129.1×154.1×203.0×

Key observations:

  • —RTX 5090 reaches about 1844× realtime at batch 32; RTX 3090 reaches about 745×.
  • —Batching is much more effective than concurrent batch-1 calls on GPU.
  • —On this EPYC, FP32 is faster than dynamic INT8. INT8's main benefit here is the 4× smaller artifact and lower memory/storage usage; speed depends on CPU instruction support and ONNX Runtime kernels.
  • —Four parallel CPU requests reach about 54× realtime FP32 and 59× INT8 aggregate throughput.
  • —Results are hardware- and workload-specific. Benchmark your expected audio lengths and concurrency.

Full-precision values and methodology are in benchmark_results.json; the reproducible runner is benchmark_onnx.py.

Artifacts

  • —multilingual_bashkir_ctc.onnx: FP32 encoder and 43-class CTC head.
  • —multilingual_bashkir_ctc.int8.onnx: dynamic unsigned INT8 quantization for CPU.
  • —multilingual_vocab.txt: 42 Bashkir characters plus CTC blank at index 42.
  • —config.json: model configuration used by onnx-asr.
  • —benchmark_results.json: complete CPU/GPU benchmark output.
  • —benchmark_onnx.py: reproducible benchmark runner.

INT8 was produced with ONNX Runtime dynamic quantization, using unsigned 8-bit weights and activations with per-tensor scales. FP32 was evaluated with the CUDA Execution Provider; INT8 was evaluated with the CPU Execution Provider.

Limitations

  • —Trained and evaluated on read speech from Common Voice; conversational and noisy speech may differ.
  • —Greedy CTC decoding only; no external language model.
  • —No capitalization or punctuation prediction.

License

MIT License. Commercial use, modification, redistribution, and private use are permitted. Retain the copyright and license notice when redistributing.