Instructions to use tachiwin/Tachiwin-Audio-ID-Onnx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- speechbrain
How to use tachiwin/Tachiwin-Audio-ID-Onnx with speechbrain:
# interface not specified in config.json
- Notebooks
- Google Colab
- Kaggle
English · Español
Tachiwin Audio Language ID — ONNX
ONNX build of Tachiwin Audio Language ID, for on-device and in-browser inference.
This repository holds the ONNX export of the spoken language identification model: an ECAPA-TDNN that takes a short recording and returns which variant of the indigenous languages of Mexico is being spoken, as one of 128 classes with calibrated probabilities. The SpeechBrain feature front-end is baked into the graph — STFT as DFT matrices, HTK mel filterbank, log-mel in dB and sentence-level mean normalisation — so at inference time nothing else is needed: no SpeechBrain, no PyTorch, no WASM FFT, only onnxruntime (or onnxruntime-web in a browser). It is what https://tachiwin.org/identificador/clasificador loads to identify languages client side, where the audio never leaves the device.
Source model · https://huggingface.co/tachiwin/Tachiwin-Audio-ID | Demo · https://huggingface.co/spaces/tachiwin/classifier | Web app · https://tachiwin.org/identificador/clasificador | Dataset · https://huggingface.co/datasets/tachiwin/tachiwin_multilingual_audio
Graph contract
frames float32 [batch, frames, 400] audio framed and Hamming-windowed by the client
lengths float32 [batch] relative lengths (1.0 = full frame stack)
-> logits float32 [batch, 128] scale * cosine similarity (temperature NOT applied)
Client-side framing: 16 kHz mono input, n_fft=400, win_length=400, hop_length=160, center=True (zero pad of 200 on each side) and a periodic Hamming window. The graph does not apply the temperature: divide the logits by T = 1.5311099290847778, take log_softmax per chunk, average the log-probabilities over chunks and then softmax.
import json
import numpy as np
import onnxruntime as ort
CODE = json.load(open("labels.json"))["classes"] # index -> language code
T = 1.5311099290847778
sess = ort.InferenceSession("model.fp16w.onnx", providers=["CPUExecutionProvider"])
logits = sess.run(None, {"frames": frames, "lengths": np.ones(1, np.float32)})[0] # [1, 128]
logp = logits[0] / T # temperature calibration
logp = logp - np.logaddexp.reduce(logp) # log_softmax
probs = np.exp(logp) # calibrated probabilities
for i in np.argsort(-probs)[:5]:
print(CODE[i], round(float(probs[i]), 4))
frames is the only input you have to build; the framing parameters above are the whole recipe, and the reference client (scripts/lid/bench_ortweb.mjs in the web app repository) is the tested implementation. Clips longer than 10.0 s are cut into 6.0 s windows with a 3.0 s hop and averaged; anything shorter than 0.5 s is padded.
Files
| File | Size | Notes |
|---|---|---|
model.onnx |
85.5 MB | fp32 reference — a9175a1f28db9fc3… |
model.fp16w.onnx |
43.1 MB | fp16 kernels, fp32 maths (default in the web app) — 60b4ca16c4802f8e… |
manifest.json |
— | Index: artifact names, SHA-256, sizes, framing constants, calibration, parity, latency and mirrors |
labels.json |
— | classes (index → code, the order is the output order) and info (code → language, superlanguage, family) |
lang_stats.json |
— | Per-variant support and recall, carried over from the source model |
metrics.json |
— | Metrics of the source model, carried over |
samples.json + samples/*.wav |
— | 22 reference clips with ground truth, used as the export parity set and as the web UI demos |
selftest.json |
— | Deterministic smoke test: seeded audio, expected fbank frame and expected top-3 |
Parity and latency
Exported from the source model with opset 17 (torch 2.5.1+cpu):
- 44/44 top-1 agreement with the PyTorch/SpeechBrain pipeline,
max |Δp| = 0.000501. - Frame-count invariant: identical logits at T = 60, 251, 761, 1200 frames (max |Δlogit| ≤ 6.9e-06).
- Native onnxruntime CPU: ≈ 86.2 ms per 5 s clip with
model.fp16w.onnx, 103.0 ms withmodel.onnx. The browser WebAssembly path is roughly 8–10× slower on a desktop CPU;bench_ortweb.mjsin the web app repository prints the current numbers for the exact artifact you serve.
Stats
Evaluation of the source model on its test split (8,109 clips, 111 variants), inherited here because the exported graph is equivalent to it:
| Metric | Test [95 % CI] |
|---|---|
| Top-1 accuracy | 0.906 [0.899, 0.912] |
| Top-3 accuracy | 0.973 [0.970, 0.977] |
| Macro F1 | 0.784 [0.761, 0.803] |
| Macro recall | 0.804 [0.784, 0.826] |
| Family accuracy | 0.966 [0.962, 0.970] |
| Superlanguage accuracy | 0.948 [0.943, 0.953] |
| ECE (calibrated) | 0.020 |
The full breakdown — per-family results, best and worst variants, confusion pairs, confidence and duration behaviour, optimism diagnostics — is in the source model card and in lang_stats.json.
Mirrors
Any host serving the same layout works. The web app tries, in order:
https://huggingface.co/tachiwin/Tachiwin-Audio-ID-Onnx/resolve/mainhttps://hf-mirror.com/tachiwin/Tachiwin-Audio-ID-Onnx/resolve/mainhttps://modelscope.cn/models/tachiwin/Tachiwin-Audio-ID-Onnx/resolve/master
Limitations
- Temperature is the client's job. The graph returns cosine logits; skip the division by T and the probabilities are badly over-confident.
manifest.jsoncarries the constant. - The front-end is frozen into the graph. Changing the framing, the mel filterbank or the normalisation means re-exporting, not re-wiring.
model.fp16w.onnxis fp16 kernels with fp32 maths: ≈ 43 MB instead of 85 MB with a numerical difference well under the sampling noise, but if you need bit-level reproduction usemodel.onnx.- Latency is device-dependent. The figures above are a T-class desktop CPU; mobile browsers are slower and vary by several times.
- Inherited from the source model: closed set with no "other" class, so out-of-scope audio still gets a confident label; splits are random per clip with no speaker identifier, so the metrics are probably optimistic; 15 of the 111 evaluated variants have fewer than 5 test clips; a few class codes are catalogue additions rather than strict ISO 639-3.
Citation
@misc{tachiwin_audio_language_id_onnx,
title = {Tachiwin Audio Language ID (ONNX): on-device spoken language identification for the indigenous languages of Mexico},
author = {{Tachiwin}},
howpublished = {\url{https://huggingface.co/tachiwin/Tachiwin-Audio-ID-Onnx}},
year = {2026},
note = {Update the URL, version and date when a new version is released}
}
Tachiwin
Tachiwin is an indigenous, Mexican, community-led, non-profit and open-source initiative that develops Artificial Intelligence technologies for the 68 indigenous languages of Mexico and their 364 variants, guided by technological sovereignty, ethics, collaboration and open knowledge and putting technology at the service of the communities that speak them. This ONNX build exists so the identifier can run entirely on the speaker's own device, offline, without sending audio anywhere.
- Website · https://tachiwin.org
- Hugging Face · https://huggingface.co/tachiwin
- GitHub · https://github.com/tachiwin
- Contact · admin@tachiwin.org
- Support · https://tachiwin.org/donate
In memory of our founder, Fidencio Hernández Hernández (1990–2025). Wix klakgapastakgan kin xkuti.
Model tree for tachiwin/Tachiwin-Audio-ID-Onnx
Base model
speechbrain/lang-id-voxlingua107-ecapaDataset used to train tachiwin/Tachiwin-Audio-ID-Onnx
Evaluation results
- Top-1 accuracy on Tachiwin multilingual audio (test split)test set self-reported0.906
- Top-3 accuracy on Tachiwin multilingual audio (test split)test set self-reported0.974
- Macro F1 on Tachiwin multilingual audio (test split)test set self-reported0.784
- Macro recall on Tachiwin multilingual audio (test split)test set self-reported0.804
- Family accuracy on Tachiwin multilingual audio (test split)test set self-reported0.966
- Superlanguage accuracy on Tachiwin multilingual audio (test split)test set self-reported0.948