CTC speech recognition for Indonesian and Tagalog/Taglish. Inference only (the training recipe follows in a later release). Apache-2.0. Models: PixelML/sea-asr-ph.
pip install "git+https://github.com/PixelML/sea-asr@v0.1.0" # Python >= 3.12
pip install -e . # from a clonePinned: torch 2.14.1, transformers 5.19.0, huggingface_hub 2.1.1, safetensors 0.8.0, numpy 2.5.3.
The first load downloads the encoder from the Hugging Face Hub (accept the Gemma terms and log in if needed).
from sea_asr import SeaASR, to_srt, to_vtt
asr = SeaASR.from_pretrained("PixelML/sea-asr-ph") # HF repo id (+ revision=...) or a local dir
print(asr.transcribe("clip.flac")) # one string
texts = asr.transcribe(["a.flac", "b.flac"]) # list in, list out (batched)
out = asr.transcribe("talk.flac", return_words=True) # {"text", "words": [{"word", "start", "end"}]}
open("talk.srt", "w").write(to_srt(out["words"]))
open("talk.vtt", "w").write(to_vtt(out["words"]))Example SRT output (id-v3 on the first FLEURS-id test clips, joined into one 80 s file):
1
00:00:00,880 --> 00:00:04,120
tim tim virtual memiliki standar
keunggulan yang sama dengan tim
2
00:00:04,320 --> 00:00:10,320
konvensional tetapi ada sedikit
perbedaan segera setelah
pip install "sea_asr[lm] @ git+https://github.com/PixelML/sea-asr@v0.2.1" # adds pyctcdecode 0.5.0 + kenlm (pinned commit)asr = SeaASR.from_pretrained("PixelML/sea-asr-id", lm="path/to/lm") # or lm="<hf-repo>" with an lm/ folder
asr = SeaASR.from_pretrained("PixelML/sea-asr-id", lm="path/to/lm", alpha=0.4, beta=1.0, beam=32, lm_workers=8)
asr = SeaASR.from_pretrained("PixelML/sea-asr-id", lm="PixelML/sea-asr-id", rescore=True, rescore_beam=128)python -m sea_asr --model PixelML/sea-asr-id --lm path/to/lm clip.flac --srt out/The LM directory holds a KenLM binary (*.bin, or *.arpa), unigrams.txt, and lm_config.json with the tuned
{"alpha": …, "beta": …, "beam": …, "rescore_beam": …} (beam = plain LM decode, rescore_beam = N-best list
for rescoring); arguments override the file. Greedy decoding stays the default. The beam search runs in Python on
the CPU, in-process by default (lm_workers=1); lm_workers=N uses a pool of N processes, which was about 2x faster
on a 12-core Mac and slower on a 32-vCPU H100 host, so measure on yours. Runs of near-certain blank frames are
collapsed before the search (compress_blanks=True, the default; word times stay on the original timeline);
compress_blanks=False or --no-compress-blanks searches every frame. Beam-search CPU time with v0.2.1 defaults
(beam 128, FLEURS-id dev): about 5 s per audio hour on the H100 host.
pip install "sea_asr[rescore] @ git+https://github.com/PixelML/sea-asr@v0.2.1"asr = SeaASR.from_pretrained("PixelML/sea-asr-id", lm="PixelML/sea-asr-id", rescore=True)A second pass reranks the LM beam search's 32 best hypotheses with a causal LM, by default Sailor2-1B pinned to
a commit (about 2 GB of GPU memory in bf16). rescore=True needs lm=.
Cues have at most 2 lines of 32 characters and last at most 6 s. Inputs longer than 30 s are cut at quiet points
and the timestamps stay on the original timeline. Input: a file path, a float32 16 kHz mono array, or an
(array, sample_rate) tuple (resampled with soxr). On CUDA the model runs under bf16 autocast; on CPU in float32.
python -m sea_asr.convert runs/my-run/best out/my-run # training checkpoint -> sea_asr formatpytest tests/ # CPU unit tests (test_lm, test_rescore, test_beams_workers need sea_asr[lm])- Base encoder: Google DeepMind, EmbeddingGemma 2 (914f7f89)
- Encoder implementation: Hugging Face, transformers (v5.19.0)
- Data: YODAS (ESPnet/CMU, 52c5a1b9); FLEURS (Google, 70bb2e84); CC-BY YouTube creators listed in each model's ATTRIBUTION
- Teachers: Qwen3-ASR-1.7B (Alibaba Qwen, 7278e1e7); Whisper large-v3 (OpenAI, openai/whisper) as Systran/faster-whisper-large-v3 (
edaa852e) via faster-whisper 1.2.1 (SYSTRAN) - LM decoding (optional extra): KenLM by Kenneth Heafield (kpu/kenlm @ 4cb443e6); pyctcdecode by Kensho Technologies (kensho-technologies/pyctcdecode 0.5.0)
- Rescoring LM (optional): Sailor2-1B, Sea AI Lab (sail/Sailor2-1B @ 75c2856f, Apache-2.0)
- Test sets: FLEURS test (Google, same revision)
- Recipe: Quan Nguyen (@qnguyen3), QUAN-Transcribe — https://github.com/qnguyen3/QUAN-Transcribe (4f45e02)
Apache-2.0. Base encoder EmbeddingGemma 2 is Apache-2.0; deployments must adhere to the Gemma Prohibited Use Policy.