Downloads · 30 days
217
93% of all-time downloads
ILRDF/whisper-large-v2-formosan-lang-tokens
whisper-large-v2-formosan-lang-tokens is a automatic speech recognition model from ILRDF. Use it when you need speech turned into text. It is set up for transformers. The card lists the license as cc-by-nc-4.0.
This model is a fine-tuned version of ILRDF/whisper-large-v2-formosan-all (itself based on openai/whisper-large-v2) for automatic speech recognition across 42 Formosan indigenous language dialects of Taiwan.
Downloads · 30 days
217
93% of all-time downloads
All-time downloads
233
Public
Parameters
1.5B
3.1 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors3.1 GB · 100%
From the Hugging Face model README
This model is a fine-tuned version of ILRDF/whisper-large-v2-formosan-all (itself based on openai/whisper-large-v2) for automatic speech recognition across 42 Formosan indigenous language dialects of Taiwan.
Unlike the base model - which conditions every dialect on a single placeholder Whisper language token (id, Indonesian) - this model adds one real Whisper-style language token per dialect (e.g. <|ami-x-frng|>), the same mechanism Whisper itself uses for its original ~99 languages, just extended to 42 dialects it was never pretrained on. Each dialect's own added token replaces the usual <|lang|> slot in the decoder prefix, so the model is told exactly which dialect it's transcribing instead of having to infer it (or default to one shared representation for all of them).
42 dialects across 15 language families of Taiwan's Formosan indigenous languages. Each has its own added language token, replacing the <|lang|> slot in the decoder prefix <|startoftranscript|><|lang|><|transcribe|><|notimestamps|>.
| Token | lang_code | Family (EN) | Family (中文) | Dialect (中文) |
|---|---|---|---|---|
<|ami-x-frng|> (id 51865) | ami-x-frng | Amis | 阿美語 | 馬蘭阿美語 |
<|ami-x-iams|> (id 51866) | ami-x-iams | Amis | 阿美語 | 南勢阿美語 |
<|ami-x-pld|> (id 51867) | ami-x-pld | Amis | 阿美語 | 恆春阿美語 |
<|ami-x-pswl|> (id 51868) | ami-x-pswl | Amis | 阿美語 | 海岸阿美語 |
<|ami-x-skl|> (id 51869) | ami-x-skl | Amis | 阿美語 | 秀姑巒阿美語 |
<|bnn-x-bkh|> (id 51870) | bnn-x-bkh | Bunun | 布農語 | 卡群布農語 |
<|bnn-x-bnz|> (id 51871) | bnn-x-bnz | Bunun | 布農語 | 巒群布農語 |
<|bnn-x-isbk|> (id 51872) | bnn-x-isbk | Bunun | 布農語 | 郡群布農語 |
<|bnn-x-td|> (id 51873) | bnn-x-td | Bunun | 布農語 | 卓群布農語 |
<|bnn-x-vtn|> (id 51874) | bnn-x-vtn | Bunun | 布農語 | 丹群布農語 |
<|ckv|> (id 51875) | ckv | Kebalan | 噶瑪蘭語 | 噶瑪蘭語 |
<|dru-x-kgdv|> (id 51876) | dru-x-kgdv | Rukai | 魯凱語 | 多納魯凱語 |
<|dru-x-lbw|> (id 51877) | dru-x-lbw | Rukai | 魯凱語 | 大武魯凱語 |
<|dru-x-ngdr|> (id 51878) | dru-x-ngdr | Rukai | 魯凱語 | 霧臺魯凱語 |
<|dru-x-opnh|> (id 51879) | dru-x-opnh | Rukai | 魯凱語 | 萬山魯凱語 |
<|dru-x-tldr|> (id 51880) | dru-x-tldr | Rukai | 魯凱語 | 茂林魯凱語 |
<|dru-x-trmk|> (id 51881) | dru-x-trmk | Rukai | 魯凱語 | 東魯凱語 |
<|pwn-x-kcdsn|> (id 51882) | pwn-x-kcdsn | Paiwan | 排灣語 | 東排灣語 |
<|pwn-x-pnvn|> (id 51883) | pwn-x-pnvn | Paiwan | 排灣語 | 中排灣語 |
<|pwn-x-vnrn|> (id 51884) | pwn-x-vnrn | Paiwan | 排灣語 | 北排灣語 |
<|pwn-x-ynvl|> (id 51885) | pwn-x-ynvl | Paiwan | 排灣語 | 南排灣語 |
<|pyu-x-ksvk|> (id 51886) | pyu-x-ksvk | Pinuyumayan | 卑南語 | 建和卑南語 |
<|pyu-x-ktrp|> (id 51887) | pyu-x-ktrp | Pinuyumayan | 卑南語 | 知本卑南語 |
<|pyu-x-mkzy|> (id 51888) | pyu-x-mkzy | Pinuyumayan | 卑南語 | 西群卑南語 |
<|pyu-x-pym|> (id 51889) | pyu-x-pym | Pinuyumayan | 卑南語 | 南王卑南語 |
<|ssf|> (id 51890) | ssf | Thau | 邵語 | 邵語 |
<|sxr|> (id 51891) | sxr | Hla'alua | 拉阿魯哇語 | 拉阿魯哇語 |
<|szy|> (id 51892) | szy | Sakizaya | 撒奇萊雅語 | 撒奇萊雅語 |
<|tao|> (id 51893) | tao | Yami | 雅美語 | 雅美語 |
<|tay-x-cql|> (id 51894) | tay-x-cql | Tayal | 泰雅語 | 四季泰雅語 |
<|tay-x-kls|> (id 51895) | tay-x-kls | Tayal | 泰雅語 | 宜蘭澤敖利泰雅語 |
<|tay-x-mtuw|> (id 51896) | tay-x-mtuw | Tayal | 泰雅語 | 汶水泰雅語 |
<|tay-x-plngw|> (id 51897) | tay-x-plngw | Tayal | 泰雅語 | 萬大泰雅語 |
<|tay-x-sql|> (id 51898) | tay-x-sql | Tayal | 泰雅語 | 賽考利克泰雅語 |
<|tay-x-sul|> (id 51899) | tay-x-sul | Tayal | 泰雅語 | 澤敖利泰雅語 |
<|trv-x-td|> (id 51900) | trv-x-td | Truku/Seediq | 太魯閣語/賽德克語 | 都達賽德克語 |
<|trv-x-tgdy|> (id 51901) | trv-x-tgdy | Truku/Seediq | 太魯閣語/賽德克語 | 德固達雅賽德克語 |
<|trv-x-trk|> (id 51902) | trv-x-trk | Truku/Seediq | 太魯閣語/賽德克語 | 德鹿谷賽德克語 |
<|trv-x-truku|> (id 51903) | trv-x-truku | Truku/Seediq | 太魯閣語/賽德克語 | 太魯閣語 |
<|tsu|> (id 51904) | tsu | Cou | 鄒語 | 鄒語 |
<|xnb|> (id 51905) | xnb | Kanakanavu | 卡那卡那富語 | 卡那卡那富語 |
<|xsy|> (id 51906) | xsy | SaySiyat | 賽夏語 | 賽夏語 |
Compared against the base model, ILRDF/whisper-large-v2-formosan-all, on the eval split of every config of formospeech/klokah and formospeech/ithuan_formosan (45 dialect/dataset pairs total). Numbers below are normalized WER/CER (lowercased, light punctuation stripped - see "Text normalization" in the details below for exactly what that means).
Macro-average (mean of each dialect's own metric) across all 45, and separately per dataset:
| Scope | Model | Normalized WER | Normalized CER |
|---|---|---|---|
| All 45 (pooled) | baseline | 10.31 | 2.82 |
| All 45 (pooled) | ours | 7.47 | 2.11 |
formospeech/klokah only (n=42) | baseline | 10.48 | 2.91 |
formospeech/klokah only (n=42) | ours | 7.67 | 2.19 |
formospeech/ithuan_formosan only (n=3) | baseline | 8.04 | 1.59 |
formospeech/ithuan_formosan only (n=3) | ours | 4.75 | 1.01 |
This model beats the baseline's normalized WER/CER on 44/45 and 43/45 dialects respectively (the handful of losses are within ~0.1-0.5 points); on raw, non-normalized WER/CER it wins 45/45.
Noise robustness (MUSAN noise mixed in at the target SNR before transcription, same 45 pairs, macro-averaged):
| Condition | Normalized WER | Normalized CER |
|---|---|---|
| Clean | 7.47 | 2.11 |
| 15 dB SNR | 11.48 | 3.17 |
| 10 dB SNR | 14.75 | 4.30 |
Every number above and in the per-dialect table below is broken down per dataset, per config (dialect), and per split; the pooled figures are macro-averages computed from those per-dialect numbers, not a single blended metric. The model-index metadata in this README's YAML frontmatter carries the same breakdown machine-readably: one results entry per (dataset, config, split) triple, 45 in total, each with its own dataset.type/dataset.name/dataset.config/dataset.split and wer/cer (raw and normalized) metrics - this is what powers the auto-rendered results box on this model's Hub page. Both datasets only ship train/eval splits, and eval is the one used everywhere here - there is no separate held-out test split.
Note on the model-index format used here vs. Hugging Face's Evaluation Results docs: that page documents a newer, separate mechanism (.eval_results/*.yaml files, tied to a dataset repo that's registered as a Hub Benchmark with its own eval.yaml) built for community-submitted, semi-verified leaderboard-style results. Neither formospeech/klokah nor formospeech/ithuan_formosan is registered as a Benchmark, so that mechanism doesn't apply to this model card. The model-index: block above is the older, more widely-supported convention (the same one used to render the standard "Results" table on model pages across the Hub, including the sibling formospeech/whisper-large-v2-taiwanese-hakka-v1 model card) and is what's actually used here.
Both models' predictions and references are lowercased, stripped of ., ,, !, ?, ; and have runs of whitespace collapsed to a single space before computing the normalized metrics - deliberately a small, fixed whitelist rather than stripping every Unicode punctuation/symbol character (e.g. transformers' BasicTextNormalizer), because two characters that look like punctuation are actually meaningful orthography in this data and would otherwise get silently corrupted:
: (colon) marks vowel length in some dialects (Amis, Saisiyat) - e.g. bae:iw, sapi:ihin. A corpus-wide scan found it directly between two letters (i.e. part of a word, not separating sentences) 77-95% of the time in the dialects that use it.⌃) is a meaningful orthographic marker that also occurs in the data.Neither is stripped. Every other punctuation character actually appearing in the training corpora was confirmed (via the same scan) to never occur mid-word, so stripping just those five is safe.
MUSAN noise-subset clips (bilguun/musan-noise, 930 clips) are additively mixed in at a target SNR before transcription, same 45 dialect/dataset pairs as above. Raw (non-normalized) WER/CER for the same three conditions:
| Condition | WER | CER |
|---|---|---|
| Clean | 10.38 | 2.64 |
| 15 dB SNR | 15.05 | 3.85 |
| 10 dB SNR | 18.63 | 5.08 |
All four metrics (WER/CER, raw and normalized) degrade monotonically as SNR decreases, as expected. The Rukai (dru-*) dialects are consistently the most noise-sensitive of the 42, with dru-x-opnh and dru-x-kgdv losing 15-20 points of absolute WER at 10dB SNR - worth keeping in mind for any downstream use in noisy conditions. This is one condition among many possible robustness probes (there's no single agreed-upon standard for which MUSAN subset(s) or SNR range to use for ASR robustness evaluation specifically - MUSAN itself was originally designed for training-time augmentation recipes, not a fixed eval protocol). Results here should be read as "robustness to point-source background noise at moderate SNR," not a full robustness certification.
| lang_code | Family | Dialect | Dataset | norm_WER | Baseline norm_WER | norm_CER | Baseline norm_CER | 15dB norm_WER | 10dB norm_WER |
|---|---|---|---|---|---|---|---|---|---|
ami-x-frng | Amis | 馬蘭阿美語 | klokah | 4.63 | 5.68 | 1.6 | 1.89 | 7.82 | 10.02 |
ami-x-iams | Amis | 南勢阿美語 | klokah | 6.09 | 15.26 | 1.32 | 10.29 | 8.7 | 11.82 |
ami-x-pld | Amis | 恆春阿美語 | klokah | 5.49 | 6.9 | 1.07 | 1.33 | 9.18 | 13.38 |
ami-x-pswl | Amis | 海岸阿美語 | klokah | 3.31 | 3.78 | 0.61 | 0.73 | 6.0 | 8.79 |
ami-x-skl | Amis | 秀姑巒阿美語 | ithuan_formosan | 5.03 | 9.55 | 1.08 | 1.63 | 7.04 | 9.55 |
ami-x-skl | Amis | 秀姑巒阿美語 | klokah | 4.65 | 6.09 | 1.06 | 1.36 | 7.79 | 9.68 |
bnn-x-bkh | Bunun | 卡群布農語 | klokah | 16.71 | 19.66 | 5.18 | 5.29 | 22.45 | 26.75 |
bnn-x-bnz | Bunun | 巒群布農語 | klokah | 7.19 | 21.75 | 2.03 | 3.34 | 12.13 | 16.19 |
bnn-x-isbk | Bunun | 郡群布農語 | klokah | 7.66 | 9.64 | 1.68 | 1.96 | 12.74 | 16.34 |
bnn-x-td | Bunun | 卓群布農語 | klokah | 10.77 | 12.8 | 2.31 | 2.48 | 14.31 | 16.75 |
bnn-x-vtn | Bunun | 丹群布農語 | klokah | 11.69 | 17.71 | 3.8 | 4.32 | 16.26 | 19.6 |
ckv | Kebalan | 噶瑪蘭語 | klokah | 4.58 | 5.09 | 1.22 | 1.37 | 7.61 | 9.64 |
dru-x-kgdv | Rukai | 多納魯凱語 | klokah | 13.63 | 15.05 | 3.41 | 3.77 | 21.77 | 28.0 |
dru-x-lbw | Rukai | 大武魯凱語 | klokah | 9.21 | 10.52 | 2.85 | 3.1 | 15.12 | 20.03 |
dru-x-ngdr | Rukai | 霧臺魯凱語 | klokah | 8.5 | 10.66 | 3.16 | 2.71 | 14.97 | 20.0 |
dru-x-opnh | Rukai | 萬山魯凱語 | klokah | 12.68 | 15.9 | 3.11 | 3.45 | 25.66 | 32.16 |
dru-x-tldr | Rukai | 茂林魯凱語 | klokah | 34.88 | 54.01 | 8.64 | 14.82 | 42.34 | 46.6 |
dru-x-trmk | Rukai | 東魯凱語 | klokah | 11.61 | 13.06 | 2.57 | 2.94 | 17.89 | 23.04 |
pwn-x-kcdsn | Paiwan | 東排灣語 | klokah | 8.7 | 10.1 | 1.89 | 3.44 | 12.53 | 14.62 |
pwn-x-pnvn | Paiwan | 中排灣語 | klokah | 8.1 | 9.35 | 1.8 | 2.13 | 11.29 | 13.84 |
pwn-x-vnrn | Paiwan | 北排灣語 | klokah | 8.6 | 9.7 | 2.13 | 2.34 | 13.32 | 16.97 |
pwn-x-ynvl | Paiwan | 南排灣語 | klokah | 11.32 | 12.56 | 2.71 | 3.03 | 15.15 | 18.24 |
pyu-x-ksvk | Pinuyumayan | 建和卑南語 | klokah | 2.98 | 3.42 | 0.65 | 0.83 | 6.55 | 10.11 |
pyu-x-ktrp | Pinuyumayan | 知本卑南語 | klokah | 3.49 | 3.97 | 0.79 | 0.85 | 6.92 | 10.24 |
pyu-x-mkzy | Pinuyumayan | 西群卑南語 | klokah | 3.85 | 4.52 | 1.29 | 1.45 | 8.04 | 11.26 |
pyu-x-pym | Pinuyumayan | 南王卑南語 | klokah | 2.24 | 8.07 | 0.61 | 1.85 | 5.09 | 7.7 |
ssf | Thau | 邵語 | klokah | 4.72 | 5.31 | 1.66 | 1.84 | 7.24 | 9.62 |
sxr | Hla'alua | 拉阿魯哇語 | klokah | 10.34 | 10.88 | 1.63 | 1.75 | 16.53 | 20.41 |
szy | Sakizaya | 撒奇萊雅語 | klokah | 4.18 | 5.61 | 1.21 | 1.58 | 7.0 | 10.26 |
tao | Yami | 雅美語 | klokah | 9.61 | 10.58 | 3.0 | 3.29 | 14.3 | 18.18 |
tay-x-cql | Tayal | 四季泰雅語 | klokah | 5.05 | 6.23 | 1.71 | 2.01 | 8.63 | 11.76 |
tay-x-kls | Tayal | 宜蘭澤敖利泰雅語 | klokah | 3.03 | 4.43 | 1.29 | 1.65 | 6.2 | 9.13 |
tay-x-mtuw | Tayal | 汶水泰雅語 | klokah | 7.85 | 9.16 | 2.99 | 3.5 | 13.9 | 17.93 |
tay-x-plngw | Tayal | 萬大泰雅語 | klokah | 6.35 | 8.15 | 1.52 | 1.98 | 10.78 | 13.88 |
tay-x-sql | Tayal | 賽考利克泰雅語 | klokah | 4.15 | 5.55 | 1.32 | 1.82 | 7.64 | 11.67 |
tay-x-sul | Tayal | 澤敖利泰雅語 | klokah | 3.51 | 4.4 | 1.24 | 1.54 | 7.45 | 11.38 |
trv-x-td | Truku/Seediq | 都達賽德克語 | klokah | 3.87 | 4.13 | 1.46 | 1.47 | 6.26 | 9.75 |
trv-x-tgdy | Truku/Seediq | 德固達雅賽德克語 | ithuan_formosan | 6.63 | 9.94 | 1.53 | 2.19 | 7.73 | 8.29 |
trv-x-tgdy | Truku/Seediq | 德固達雅賽德克語 | klokah | 4.81 | 4.98 | 2.32 | 2.45 | 8.1 | 10.72 |
trv-x-trk | Truku/Seediq | 德鹿谷賽德克語 | klokah | 6.83 | 6.62 | 4.28 | 4.29 | 8.03 | 9.96 |
trv-x-truku | Truku/Seediq | 太魯閣語 | ithuan_formosan | 2.58 | 4.64 | 0.42 | 0.94 | 2.06 | 3.61 |
trv-x-truku | Truku/Seediq | 太魯閣語 | klokah | 3.8 | 3.89 | 1.86 | 1.8 | 5.53 | 7.32 |
tsu | Cou | 鄒語 | klokah | 8.94 | 9.86 | 3.14 | 3.31 | 12.59 | 15.61 |
xnb | Kanakanavu | 卡那卡那富語 | klokah | 3.66 | 5.81 | 1.14 | 1.72 | 5.51 | 7.8 |
xsy | SaySiyat | 賽夏語 | klokah | 8.78 | 29.18 | 2.85 | 5.12 | 12.32 | 15.02 |
This model is hosted as a gated Hugging Face repository. Before using it:
A read token is sufficient for inference.
pip install -U huggingface_hub
hf auth login
Alternatively, you can provide the token through the HF_TOKEN environment variable:
export HF_TOKEN=hf_xxx
Do not hard-code your Hugging Face token in scripts, notebooks, or public repositories.
If you see an error such as Cannot access gated repo, make sure that:
hf auth whoami shows the expected account;HF_HUB_DISABLE_IMPLICIT_TOKEN is not set.Because each dialect uses its own added language token instead of one of Whisper's built-in languages, the usual pipeline(..., generate_kwargs={"language": ...}) shortcut does not apply here - the convenience language=/task= arguments only recognize Whisper's original ~99 languages. Instead, force the dialect's token directly via decoder_input_ids:
import json
import torch
from huggingface_hub import hf_hub_download
from transformers import WhisperForConditionalGeneration, WhisperProcessor
model_id = "formospeech/whisper-large-v2-formosan-lang-tokens"
device = "cuda:0" if torch.cuda.is_available() else "cpu"
torch_dtype = torch.bfloat16 if torch.cuda.is_available() else torch.float32
processor = WhisperProcessor.from_pretrained(model_id, language="id", task="transcribe")
model = WhisperForConditionalGeneration.from_pretrained(model_id, torch_dtype=torch_dtype).to(device)
# lang_code -> added token id, e.g. "ami-x-frng" -> 51865 (see "Supported dialects" above)
lang_code_to_token_id = json.load(open(hf_hub_download(model_id, "lang_code_to_token_id.json")))
def transcribe(audio_array, sampling_rate, lang_code):
decoder_start_id, _, transcribe_id, notimestamps_id = processor.tokenizer.prefix_tokens
dialect_token_id = lang_code_to_token_id[lang_code]
# Passing decoder_input_ids to Whisper's generate() is taken verbatim (it does NOT
# auto-prepend decoder_start_token_id the way the base GenerationMixin does), so all
# four prefix tokens must be given explicitly here.
decoder_input_ids = torch.tensor(
[[decoder_start_id, dialect_token_id, transcribe_id, notimestamps_id]], device=device
)
input_features = processor.feature_extractor(
audio_array, sampling_rate=sampling_rate, return_tensors="pt"
).input_features.to(device, dtype=torch_dtype)
with torch.no_grad():
generated_ids = model.generate(input_features, decoder_input_ids=decoder_input_ids, max_length=225)
return processor.tokenizer.decode(generated_ids[0], skip_special_tokens=True)
# example: audio_array is a float32 numpy array at 16kHz
# transcribe(audio_array, 16000, "ami-x-frng")
The training of the model was performed with the following hyperparameters:
ILRDF/whisper-large-v2-formosan-all), with the 42 new dialect token embeddings each initialized from that model's own id (Indonesian) token embedding - a linguistically related Austronesian language, per Whisper maintainer guidance on adding new languagesThe learning rate was chosen empirically via a short LR probe (3e-5 / 1e-4 / 3e-4 candidates, ~100 steps each) before committing to a full run - 1e-4 gave the best eval WER among the three.
Every config (dialect) of every dataset's train split was loaded and concatenated:
formospeech/ntu_formosan_corpusformospeech/ilrdf_dictsformospeech/klokahformospeech/ithuan_formosanlang_code_to_token_id.json (included in this repo) is required to look up the correct token id per dialect - see the usage example above.