sea-asr-ph β€” fast Filipino (Tagalog) and Taglish speech recognition on EmbeddingGemma 2 (CTC)

Pixel ML builds video intelligence for Southeast Asian media. These are the speech models we run for Southeast Asian media: captions, search, clips. Open weights, open data, runs on your GPU β€” or on a CPU.

Google's EmbeddingGemma 2 audio encoder with a CTC head, trained by Pixel ML on Creative Commons Filipino (Tagalog) and Taglish speech.

Speed: about 24x faster and cheaper per audio hour than batched Whisper large-v3 on the same H100 (FLEURS fil test). About 3,800x real time on H100, 860x on A10G, and faster than real time on a laptop CPU (sea-asr-id: 4.4x on Apple M2 Max, 8 threads). One pass, no autoregressive decode, streaming in 0.48 s chunks. Word timestamps and SRT/VTT output included.

RA 10905 requires closed captions on newscasts and pre-scripted programs in the Philippines; this model makes Filipino captioning affordable on one GPU.

No human-transcribed Filipino YouTube corpus existed. We made the labels: PixelML/sea-asr-ph-data. Trained on CC-BY YouTube. No purchased data.

Results

Same H100 for every open model, greedy decoding, one normaliser for all (quanphid/text.py), WER % (lower is better). Avg = mean of the two test sets. Speed = audio seconds / wall seconds on FLEURS fil, batched, model load excluded. Params = Hugging Face safetensors total (ours: counted from this repo).

Model Params Avg Speed (Γ— RT) FLEURS fil test (928) PH conversational, silver (934)
Whisper large-v3 1,543M 14.0 160 10.6 17.4
Whisper large-v3-turbo 809M 14.3 274 11.1 17.5
sea-asr-ph 364M 18.6 3,817 17.2 20.1
Whisper medium 764M 18.6 220 16.5 20.7
Whisper small 242M 25.1 348 25.6 24.5
omniASR CTC-1B ⚠ ~1B β€” 1,053–1,157 14.0 β€”
omniASR CTC-300M ⚠ ~0.3B β€” 1,319–3,058 20.7 β€”
Qwen3-ASR-1.7B 2,349M β€” 2,015 23.8 β€”
Qwen3-ASR-0.6B 938M β€” 1,570 36.1 β€”
Gemini 3.5 Transcribe (closed API) β€” β€” β€” 6.8 β€”
sea-asr-ph, streaming 0.48 s 364M β€” 931 19.0 β€”

Size class. Under 0.5B parameters, sea-asr-ph is the most accurate open model we tested on both test sets. It ties Whisper medium (2Γ— its size) on both, at about 17Γ— its speed. Paired 95 % CI of the WER difference (sea-asr-ph βˆ’ Whisper medium): FLEURS +0.6 [βˆ’0.1, +1.3], silver βˆ’0.5 [βˆ’2.0, +0.5]. Larger Whisper models are more accurate.

  • PH conversational, silver: 934 segments (2.68 h) from 150 held-out CC-BY YouTube videos that no sea-asr-ph run saw. Reference = Qwen3-ASR-1.7B text that agreed with omniASR CTC (CER ≀ 0.10); no human check yet. Qwen3-ASR and omniASR made the references, so they are not scored on it; Whisper and sea-asr-ph had no part in them.
  • ⚠ omniASR was trained on FLEURS (Meta, arXiv 2511.09690): its FLEURS row is not a held-out score.

Error tail on FLEURS fil, as % of reference words β€” sea-asr-ph: substitutions 12.6, deletions 2.9, insertions 1.6; Whisper large-v3: substitutions 8.4, deletions 1.1, insertions 1.1. No system had utterances with WER > 100 % on this set; CTC cannot loop by design (no autoregressive decoder).

Same-GPU setup: Whisper via faster-whisper fp16, beam 5, Silero VAD, batch 16 clips; ours 600 s of padded audio per forward pass. A Whisper setup tuned for throughput would narrow the gap. On an A10G: sea-asr-ph 860x, Whisper large-v3 59x real time. Ours: speed from the previous checkpoint of the same architecture and size (this checkpoint measured 3,640Γ— in a separate run); WER from this checkpoint.

The labels come from Whisper large-v3; on read speech (FLEURS) Whisper large-v3 is more accurate. Gemini is a closed benchmark row only; its outputs were not used for training (Gemini API terms).

Use

Try it in the browser: seanphan/sea-asr-ph-demo (CPU; upload or record audio, get text, word timings and SRT).

pip install "git+https://github.com/PixelML/sea-asr@v0.1.0"
from sea_asr import SeaASR, to_srt

asr = SeaASR.from_pretrained("PixelML/sea-asr-ph")          # device="cuda" or "cpu"
print(asr.transcribe("clip.wav"))

out = asr.transcribe("newscast.wav", return_words=True)    # {"text", "words": [{"word", "start", "end"}]}
open("newscast.srt", "w").write(to_srt(out["words"]))

Cues: at most 2 lines Γ— 32 characters, at most 6 s. Input: 16 kHz mono (other rates are resampled). Inputs longer than 30 s are cut at quiet points; timestamps stay on the original timeline.

Limits

  • Lower case, no punctuation; caption-ready output needs a punctuation + casing restorer (next, on the EG2 text backbone).
  • Machine labels from Whisper large-v3: the model inherits Whisper's errors and does not beat it on read speech.
  • Use greedy decoding. We do not ship an n-gram LM.
  • Other Philippine languages (Cebuano, Ilocano, …) are not supported and not evaluated.
  • Do not use for speaker identification or surveillance.

Training

6,859 CC-BY YouTube videos (1,918.2 h) labelled with Whisper large-v3 (language-ID gate), + FLEURS train, 8Γ—H100, two stages from the base: 3,000 steps on the first 782 h, then 4,000 steps on all data. Labels: PixelML/sea-asr-ph-data. Inference code: PixelML/sea-asr (v0.1.0); the training recipe follows.

Roadmap: punctuation + casing head; Malay, Vietnamese, Thai.

Credits

Licence

Apache-2.0. Base encoder EmbeddingGemma 2 is Apache-2.0; deployments must adhere to the Gemma Prohibited Use Policy.

Downloads last month
41
Safetensors
Model size
0.1B params
Tensor type
F32
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for PixelML/sea-asr-ph

Finetuned
(116)
this model

Space using PixelML/sea-asr-ph 1