LES-eg2-665M-asr-en
lee1jun/LES-eg2-665M-asr-en
- 作者
- lee1jun
- 任务
- 语音识别
- 下载量
- 68
- 点赞数
- 14
- 趋势分
- 14
- 许可证
- apache-2.0
- 收录时间
- 2026/11/14
language: en license: apache-2.0 library_name: transformers pipeline_tag: automatic-speech-recognition inference: false base_model: google/embeddinggemma-2 tags: [ctc, embeddinggemma, word-ctc, custom-code] datasets: [openslr/librispeech_asr, MLCommons/peoples_speech, facebook/voxpopuli, edinburghcstr/ami, mozilla-foundation/common_voice_17_0, parler-tts/mls_eng, nvidia/Granary]
LES-eg2-665M-asr-en
English speech recognition from a frozen EmbeddingGemma 2: an 88M reader reads its audio as words of its own text-embedding space (LibriSpeech test-clean WER 1.74 greedy, 1.58 with the n-gram LM and reranker; Results).
Listen, Embed and Select (LES): EmbeddingGemma 2 listens, an 88M reader embeds every 40 ms of audio in its text-embedding space, and the closest words are selected.
EmbeddingGemma 2 ("eg2" in the model name) is used exactly as it is: its weights are not changed and it gives the same embeddings as before. A trained reader of 88M parameters turns the hidden states of its audio encoder and backbone into word-level CTC outputs, scored against EmbeddingGemma 2's own text embeddings of 407,736 words.
- Accuracy: LibriSpeech test-clean WER 1.74 greedy, 1.61 with the n-gram LM and 1.58 with the reranker (Open ASR Leaderboard normaliser); seven more English test sets in the Results table.
- Vocabulary control: add words, or replace the whole word table, without retraining (Your own word table).
- Raw outputs for your own re-ranking: the scored 32-best list, every frame's word candidates, scoring of any hypothesis and a search over your own candidates (Re-ranking).
- Embeddings from the same pass: EmbeddingGemma 2's own audio and text embeddings (EmbeddingGemma 2 embeddings).
- Permissive: trained only on permissively licensed data (no GigaSpeech, SPGISpeech, TED-LIUM or Fisher), so the
model files can be used commercially under Apache License 2.0 (Training data,
NOTICE).
How it works
EmbeddingGemma 2 runs as its audio-language configuration (577M parameters in the paper): the audio encoder (two downsampling convolution layers and twelve conformer layers, USM architecture) turns Mel filterbank inputs into 25 soft tokens per second (d_A = 1536), the audio adapter projects them to the backbone's model dimension (d_M = 512), and the 24-layer bidirectional backbone processes them. The reader reads, for every soft token, the backbone input and its 24 layer outputs, the twelve conformer layers and the audio encoder output; it gives a blank logit and a unit vector that is compared by cosine with the word table, i.e. EmbeddingGemma 2 text embeddings (mean pooling, linear projection to d = 768, l2-normalisation) of every word.
Speech and words therefore meet in one embedding space. Each 40 ms soft token becomes a vector z(t) among the text embeddings of the vocabulary; greedy decoding emits the nearest word row when s · cos beats the blank logit, and the beam decoders keep the 16 nearest rows of every frame as candidates. The figure shows real cosines for one frame of "carriage" in a LibriSpeech dev-clean utterance, zoomed in twice: from the whole space to the target around z(t), then to the scores. The nearest row is "carriage" (cosine 0.46); the next ones, at 0.31-0.32, are words related in meaning (chariot, hearse) and spelling variants found in the vocabulary (carrage, carridge), all far below "carriage" and close to the blank head's score b(t)/s = 0.31.
| Part | Parameters | Trained here |
|---|---|---|
| EmbeddingGemma 2 audio encoder (2 downsampling conv + 12 conformer layers) | 304.8M | no (frozen) |
| EmbeddingGemma 2 audio adapter (1536 → 512) | 0.8M | no (frozen) |
| EmbeddingGemma 2 backbone (24 bidirectional layers, embedder included) | 271.0M | no (frozen) |
| EmbeddingGemma 2, audio-language configuration (577M in the paper) | 576.6M | |
| Reader (12 x 768 Transformer, word-CTC head) | 88.0M | yes |
| Total at inference (greedy, beam) | 664.6M | |
+ reranker heads (decoder="rerank" only) | 6.44M | yes |
+ no-LM reranker heads (decoder="rerank", profile="no_lm", instead of the ones above) | 6.44M | yes |
| Total with the second pass | 671.1M |
The word table (word_table.safetensors, 407,736 x 768, stored as row-wise INT8) is a cache of EmbeddingGemma 2
text embeddings, so it is not counted again. The vision encoder (167M) is not loaded.
Usage
pip install "torch>=2.11" torchvision "transformers>=5.20" safetensors numpy soundfile soxr
# torchvision: EmbeddingGemma 2's processor loads its image / video parts even for audio
pip install https://github.com/kpu/kenlm/archive/master.zip # only for the beam decoders with the n-gram LM
pip install "sentence-transformers>=6.1" # only for add_words / set_vocabulary
import soundfile as sf
from transformers import AutoModel
model = AutoModel.from_pretrained("lee1jun/LES-eg2-665M-asr-en", trust_remote_code=True).to("cuda").eval()
audio, sr = sf.read("speech.flac", dtype="float32")
model.transcribe(audio, sampling_rate=sr) # greedy: "the transcript"
model.transcribe(audio, sampling_rate=sr, decoder="beam") # + n-gram LM (downloads lee1jun/LES-eg2-asr-en-lm-4gram)
model.transcribe(audio, sampling_rate=sr, decoder="rerank") # + the beam's 32-best list re-ranked by the reranker heads
model.transcribe(audio, sampling_rate=sr, decoder="rerank", profile="no_lm") # second pass without the n-gram LM
model.transcribe([a1, a2, a3]) # batches, any lengths
r = model.transcribe(audio, sampling_rate=sr, return_timestamps=True)
# {"text": ..., "duration": ..., "words": [{"word", "start", "end", "confidence"}, ...]}
r = model.transcribe(audio, sampling_rate=sr, decoder="rerank", return_nbest=True, return_candidates=True)
# {"text": ..., "nbest": [{"text", "words", "score", "ctc", "lmf", "n", "reranker", "chosen"}, ...],
# "candidates": [{"time", "blank", "words": [(word, cosine, log p), ...]}, ...]}
EmbeddingGemma 2 (google/embeddinggemma-2, revision 914f7f89142e33e77833254d9c9b90c3cef7303b) is downloaded on
first use and used frozen, without its vision encoder; its weights are not part of this repository. Audio at any
sampling rate is resampled to 16 kHz.
Decoding options
| Option | Values |
|---|---|
decoder | "greedy" (default), "beam" (word-CTC prefix beam search with n-gram shallow fusion), "rerank" (the beam's 32-best list re-ranked by the reranker heads) |
lm | beam decoders: a KenLM binary / ARPA path or a Hub repo id; default lee1jun/LES-eg2-asr-en-lm-4gram |
profile | beam decoders: "lm" (default) or "no_lm": no n-gram LM, so no download and no kenlm (alpha 0, beta 0; "rerank" uses its own reranker heads, see The reranker) |
alpha, beta, weights | LM weight, word bonus and the N-best rescoring weights {"ctc", "lmf", "n", "reranker"}; defaults from decoding.json (alpha 0.15, beta 1.0, weights ctc 1, lmf 0.2, n 1, reranker 2, one setting for every domain) |
gate | greedy: "config" (dev-calibrated blank gate: none in this build, so every frame is scanned; gate=31.0 skips about 20 % of LibriSpeech frames without changing LibriSpeech dev transcripts, but changes 0.5 % of AMI and 3 % of TED-LIUM dev transcripts), "exact" (provably lossless), None (scan every frame), a float |
bonus | greedy: bonus added to words seen in training (seen_vocab.json) |
return_timestamps | word start / end in seconds (spike-based, shifted back by the fitted delay 0.24 s; centres, not boundaries) and a confidence (cosine margin; below 0.02 is low) |
return_nbest | beam decoders, inputs up to 40 s: adds "nbest", the scored 32-best list with the parts of each score (Your own re-ranking and search) |
return_candidates, top_k, candidates_blank_max, candidates_format | every decoder: adds "candidates", each frame's top_k (16) nearest word rows with cosine and log-probability, for the frames whose blank probability is at most candidates_blank_max (0.999, the frames the beam search expands; None: every frame); candidates_format="arrays": numpy arrays over every frame (Your own re-ranking and search) |
return_embedding, embedding_dim | adds "embedding", EmbeddingGemma 2's own audio embedding (below); embedding_dim 512 / 256 / 128 keeps the leading dimensions |
long_form_s, window_s, overlap_s | audio over 40 s is decoded in 28 s windows overlapping by at least 4 s; long_form_s=None decodes one sequence |
batch_seconds | padded audio per EmbeddingGemma 2 batch (default 300) |
model.second_pass(lm, decoder=...) returns the beam decoder as an object for repeated use (build it again after
changing the word table).
Your own word table
model.add_words(["embeddinggemma", "huggingface"]) # new vocabulary without retraining
model.set_vocabulary(["turn", "left", "right", "stop"]) # own word table: outputs only these words
model.reset_vocabulary() # back to the shipped table
The decoders can only output words of the table, so the table is also a vocabulary control. add_words extends it.
set_vocabulary(words) replaces it with exactly your list (commands, names, a domain glossary). Words already in the
table keep their rows; other words get rows from EmbeddingGemma 2 by the training recipe (needs
sentence-transformers). The reader is not retrained, and reset_vocabulary() restores the shipped table.
Speech outside the list comes out as the nearest listed words or, mostly, as nothing; there is no explicit
rejection. The beam decoders still apply the n-gram LM. model.save_pretrained(dir) saves the custom table (without
this card).
EmbeddingGemma 2 embeddings
The model also returns EmbeddingGemma 2's own embedding (768-d, L2-normalised: the vector of
SentenceTransformer("google/embeddinggemma-2").encode(...)), alone or together with the transcript:
r = model.transcribe(audio, sampling_rate=sr, return_embedding=True) # {"text": ..., "embedding": tensor [768]}
e = model.embed_audio(audio, sampling_rate=sr) # embedding only (no reader, no word table)
q = model.embed_text("quarterly revenue guidance", prompt_name="query") # text in the same space
score = q @ e # cosine: text-to-audio search
model.embed_audio([a1, a2], dim=256) # Matryoshka sizes 512 / 256 / 128
return_embedding pools the EmbeddingGemma 2 pass the decoder already runs, so for audio up to 40 s the embedding
costs nothing extra (audio decoded in windows, and audio of 29-30 s, takes one more EmbeddingGemma 2 pass). Up to 30 s
the vectors equal sentence-transformers' (cosine ≥ 0.997, bf16 rounding). Longer audio is mean-pooled over 25 s
pieces so that the whole input counts, whereas sentence-transformers encodes only the first 30 s. embed_text takes
EmbeddingGemma 2's prompt names ("query", "document", ...; default none) or a literal prompt= and needs no
sentence-transformers.
Results
| Model, decoding | Params | LS clean | LS other | TED-LIUM 3 | VoxPopuli | Earnings-22 | AMI | GigaSpeech | SPGISpeech | Mean |
|---|---|---|---|---|---|---|---|---|---|---|
| This model, greedy (default) | 665M (88M) | 1.74 | 4.51 | 4.15 | 7.02 | 13.31 | 11.18 | 9.60 | 3.58 | 6.89 |
This model, decoder="beam" (n-gram LM) | 665M (88M) | 1.61 | 4.12 | 3.99 | 6.77 | 13.07 | 10.77 | 9.47 | 3.56 | 6.67 |
This model, decoder="rerank" (n-gram LM + reranker) | 671M (94M) | 1.58 | 4.00 | 3.88 | 6.74 | 12.82 | 10.75 | 9.34 | 3.68 | 6.60 |
This model, decoder="beam", profile="no_lm" (no LM) | 665M (88M) | 1.74 | 4.51 | 4.13 | 6.98 | 13.24 | 11.14 | 9.58 | 3.57 | 6.86 |
This model, decoder="rerank", profile="no_lm" (no LM, own reranker) | 671M (94M) | 1.75 | 4.53 | 4.03 | 7.02 | 13.20 | 11.03 | 9.48 | 3.69 | 6.84 |
| nvidia/parakeet-tdt-0.6b-v2, greedy | 618M | 1.29 | 2.71 | 3.09 | 5.64 | 10.89 | 10.41 | 8.27 | 1.91 | 5.53 |
| nvidia/parakeet-ctc-1.1b, greedy | 1,063M | 1.51 | 3.25 | 3.19 | 6.27 | 12.90 | 14.67 | 8.86 | 3.67 | 6.79 |
| openai/whisper-large-v3, greedy | 1,543M | 1.50 | 3.12 | 3.56 | 8.66 | 10.89 | 14.69 | 8.46 | 2.68 | 6.70 |
- Metric: word error rate (%) with the Open ASR Leaderboard text normaliser. Test sets: LibriSpeech test-clean / test-other, TED-LIUM 3 test (1,142 utterances) and the Open ASR Leaderboard test sets of VoxPopuli, Earnings-22, AMI (IHM), GigaSpeech and SPGISpeech. Mean is the mean of the eight WERs. Params: every weight loaded for inference; for this model, in parentheses, the weights trained here (the 88M reader, plus the 6.44M reranker heads for
"rerank"), EmbeddingGemma 2 being frozen. - Beam decoders: the CC BY 4.0 word 4-gram of the LM repository (alpha 0.15, beta 1, beam 64).
"rerank"re-ranks the beam's 32-best list with the reranker heads and the weights indecoding.json. - Tuning: one setting for all eight sets, chosen on LibriSpeech, VoxPopuli and AMI development audio. No test set and no Earnings-22 audio or text was used for training or tuning. Tuning each domain on its own development split did not help on average (mean 6.62 instead of 6.60 with the reranker).
- Reproducibility: computed with the research implementation on these weights (full-precision word table, 120 s batches). This repository's remote code (INT8 table) reproduces the greedy numbers on LibriSpeech: 2,582 / 2,620 and 2,844 / 2,939 transcripts identical, WER 1.74 / 4.49 against 1.74 / 4.51.
"beam"and"rerank"give the research pipeline's transcript for 1,549 of 1,600 spot-checked decodes (200 utterances each of 4 test sets). - Without the n-gram LM:
profile="no_lm"(no LM download, no kenlm;"rerank"uses its own reranker heads) gives means of 6.86 ("beam") and 6.84 ("rerank"), against 6.67 and 6.60 with the LM: the n-gram LM brings most of the second pass's gain. - Other models: greedy decoding of the public checkpoints, run by us on the same audio, references, normaliser and scorer (Parakeet: NeMo; Whisper: transformers, fp16, English, Whisper's long-form decoding for the 0.1 % of inputs over 30 s). Params counts every weight loaded for inference. They were trained on other data (see their model cards). The scorer is the current leaderboard code, which merges split compounds ("shop boy" = "shop-boy"), so every row is lower than figures computed with a plain word edit distance (Parakeet-TDT on LibriSpeech test-clean: 1.29 here, 1.66 without merging).
N-best candidates
Each 40 ms frame offers several word rows; the beam search takes the 16 nearest per frame (the figure shows the top 5 for four words of a LibriSpeech dev-other utterance). Greedy decoding takes the top row of every frame, the beam search with the n-gram LM and the reranker choose a path through the candidates, and the oracle is the best path the list contains.
The beam's 32-best list (31.5 distinct hypotheses on average) holds much better transcripts than the decoders pick. The table gives the WER if the best hypothesis among the first k were picked (oracle WER, same normaliser and scorer):
| Best of the first k | LS clean | LS other | TED-LIUM 3 | VoxPopuli | Earnings-22 | AMI | GigaSpeech | SPGISpeech | Mean |
|---|---|---|---|---|---|---|---|---|---|
k = 1 (decoder="beam") | 1.61 | 4.12 | 3.99 | 6.77 | 13.07 | 10.77 | 9.47 | 3.56 | 6.67 |
| k = 2 | 1.12 | 3.22 | 3.15 | 5.88 | 11.62 | 8.64 | 8.34 | 2.69 | 5.58 |
| k = 5 | 0.76 | 2.45 | 2.45 | 4.96 | 10.07 | 6.60 | 7.26 | 1.98 | 4.57 |
| k = 10 | 0.64 | 2.04 | 2.05 | 4.46 | 9.14 | 5.55 | 6.58 | 1.62 | 4.01 |
| k = 32 | 0.48 | 1.61 | 1.55 | 3.77 | 7.96 | 4.20 | 5.68 | 1.19 | 3.31 |
Choosing the best of the top 10 would lower the mean WER from 6.67 to 4.01. The included reranker recovers 0.07 of that gap (mean 6.60); see Your own re-ranking and search.
Re-ranking
The reranker
decoder="rerank" re-scores the beam's 32-best list: each hypothesis gets
score = 1 · ctc + 0.2 · lmf + 1 · n + 2 · reranker (the weights in decoding.json), and the largest wins. ctc is
the hypothesis' CTC log-likelihood over the frame candidates, lmf its n-gram log-probability (natural log, with the
end of sentence), n its word count and reranker the score of the reranker heads (reranker_heads.safetensors).
- What it reads. A small Transformer (3 pre-norm layers, d = 256, 4 attention heads; 2.15M parameters per head, three heads from three training seeds whose scores are averaged, 6.44M in all) reads one hypothesis at a time. Each word is one token, the sum of its EmbeddingGemma 2 table row, the reader's frame vector at the word's best frame in its Viterbi CTC alignment (and the cosine between the two), and 14 numbers: the word's log-probability at that frame, whether and where it is among the frame's 16 candidates, the frame's blank log-probability, the frame's best log-probability and the margin to it, the length of the word's CTC segment and the gap to the previous word, its n-gram log-probability, a function-word flag, its length in characters, its position in the utterance, and two N-best consensus shares (the part of the list, weighted by the softmax of the hypotheses' scores, that has the same word within two frames, or anywhere). A summary token carries the hypothesis' ctc, lmf and n relative to the beam's best hypothesis; it gives the score.
- How it was trained. Listwise: for each utterance, the softmax of the scores over its 32-best list is trained towards softmax(−word errors / τ) with a cross-entropy loss, so the heads learn to rank hypotheses by their errors. The lists come from about 23,000 held-out utterances of AMI, VoxPopuli and The People's Speech (audio and text outside the training data of the reader and of the n-gram LM, so the lists show real errors), decoded by this model with the n-gram LM; permissive data only, no test or Earnings-22 audio. The four weights were then tuned on the pooled LibriSpeech, VoxPopuli and AMI development audio.
- Without the n-gram LM (
profile="no_lm"):reranker_heads_nolm.safetensorshas the same architecture and training, on 32-best lists decoded without any n-gram LM (alpha 0, beta 0), with the LM inputs (lmf and each word's n-gram log-probability) set to zero; the consensus shares weight the hypotheses without the LM, and score = ctc + 2 · reranker. - What it brings. Mean WER 6.67 → 6.60 with the LM and 6.86 → 6.84 without.
- Caveats. The consensus shares and the scores relative to the beam's best depend on the list, so reranker scores compare only within one list. Trained on three domains; on SPGISpeech it is slightly worse than the plain beam (3.68 vs 3.56).
Your own re-ranking and search
The 32-best list holds much better transcripts than the decoders pick. Choosing the best hypothesis of the list would give a mean WER of 3.31 (best of the first 10: 4.01; AMI 10.75 → 4.20, Earnings-22 12.82 → 7.96; see the oracle table), against 6.60 with the included reranker, which recovers only 0.07 of the 2.66 points between the best beam (6.67) and the best of the first 10. Better re-ranking is where this model has the most room: a stronger language model, domain knowledge, or a better learned reranker can turn much of that gap into real gains, so please try your own. The decoders return their own scores, so you can recombine them, add your own, or run your own search:
import numpy as np
# 1. your own weights or features on the 32-best list (here an external LM score of each text, my_lm)
r = model.transcribe(audio, sampling_rate=sr, decoder="rerank", return_nbest=True)
best = max(r["nbest"], key=lambda h: h["ctc"] + 0.5 * h["lmf"] + h["n"] + 2 * h["reranker"] + my_lm(h["text"]))
# 2. hypotheses from anywhere (an LLM's correction, another recogniser), scored together with the 32-best list
s = model.score_hypotheses(audio, ["the corrected sentence"], sampling_rate=sr)
# the 32-best entries (the same scores as above) + yours: {..., "given": True, "in_nbest": False, "oov": []}
# 3. your own search over the frame candidates, without another audio pass
c = model.transcribe(audio, sampling_rate=sr, return_candidates=True, candidates_format="arrays")["candidates"]
c["logp"][c["ids"] == model.vocab.index("uh")] = -np.inf # e.g. forbid a word, or bias / re-weight "logp"
nbest = model.beam_search(c, alpha=0.3, beta=0.5, nbest=10) # any KenLM binary / ARPA file via lm=
return_nbestentries (beam order) hold the tablewords, the partsctc,lmf,nandreranker(Nonefor"beam"), the decoder'sscore(ctc + alpha · lmf + beta · n for"beam"; the weighted sum above for"rerank") andchosen. For"rerank", recombining the parts withdecoding.json's weights reproduces the decoder's choice; for"beam"the choice is the search's own first hypothesis, whose pruned search score can rank differently fromscore.return_candidatesgives, per frame,time(shifted back like word times),blank(its probability) andwordsas(word, cosine, log p), best first; p is the softmax over the blank logit and s · cos with every row, as the beam decoders' candidates.candidates_format="arrays"gives numpy arrays over every frame:timeandlp_blank[T],ids(indices intomodel.vocab),cosandlogp[T, top_k], plus the fingerprint of the word table they index.score_hypotheses(audio, hypotheses, decoder="rerank", include_nbest=True, lm=, alpha=, beta=, weights=)runs one EmbeddingGemma 2 pass (inputs up to 40 s;long_form_s=Nonefor longer ones) and scores each hypothesis, a string or a list of table words, like an N-best entry. Withinclude_nbestit returns the beam's own 32-best entries unchanged, then each of your hypotheses scored as one more entry of that list, so yours change neither the 32-best scores nor each other;include_nbest=Falsescores only yours, as one list. Words outside the table are listed inoov(never a candidate, read as a zero row by the reranker:add_wordsthem first);chosenmarks the largest score.beam_search(candidates, lm=, alpha=, beta=, beam=, nbest=)is the beam decoders' search oncandidates_format="arrays"candidates (one dict or a list); on unchanged candidates of an input up to 40 s it returnsdecoder="beam"'s N-best list. Candidates made beforeadd_words/set_vocabularyare refused.profile="no_lm"works forscore_hypothesesandbeam_searchtoo (no kenlm needed).
Training data
| Corpus | Licence | Hours |
|---|---|---|
| LibriSpeech 960 h | CC BY 4.0 | 960 |
| Libri-light small + medium (our LibriSpeech-only reader's pseudo-labels) | public domain audio | 4,991 |
| The People's Speech, clean | CC BY 4.0 | 5,864 |
| VoxPopuli English, transcribed | CC0 1.0 | 415 |
| AMI IHM | CC BY 4.0 | 72 |
| Common Voice 17.0 English | CC0 1.0 | 1,575 |
| Multilingual LibriSpeech English (15k h subset) | CC BY 4.0 | 13,959 |
| Granary pseudo-labels: YODAS2 English (CC BY 3.0 videos) | CC BY 4.0 | 14,979 |
| Granary pseudo-labels: VoxPopuli unlabelled English | CC BY 4.0 (audio CC0) | 3,032 |
| Total | 45,847 |
Segments over 29 s were dropped. Transcripts are lower-cased and normalised to words; an utterance is kept only if every word is in the LibriSpeech vocabulary or occurs at least 3 times in these corpora. Sessions and videos that overlap evaluation sets were removed (Open ASR VoxPopuli test sessions; word 10-grams shared with evaluation references, e.g. YouTube re-uploads of GigaSpeech test talks).
Training: the reader was trained on LibriSpeech 960 h, then on the mix above (2 epochs on a 27.7k h subset, then 4 epochs on all of it), with EmbeddingGemma 2 frozen throughout. A 17,000-step partial run of the mix (about half an epoch) was the starting point of the final 4 epochs. The 4 epochs follow one cosine learning-rate schedule. Greedy mean WER of the eight sets at the start of epochs 3 and 4 and at the end: 7.35, 7.01 and 6.89; the last epoch still improved every set.
Limitations
- English only; lower-case words without punctuation or casing. Numbers come out as words.
- Non-streaming. Word times are spike-based estimates of word centres.
- Words outside the table can only be produced after
add_words. - Pseudo-labelled training data (Granary, Libri-light) carries the errors of the labelling models.
Acknowledgements and related work
This project started from an idea we took from the Embedding Gemma Transcribe Mac app: reading EmbeddingGemma 2's audio as words of its own text space. We thank the authors of the projects below.
Readers that score EmbeddingGemma 2 text embeddings of words (as this model does):
| Project | Language | What it is |
|---|---|---|
| Embedding Gemma Transcribe | English | macOS app: frozen audio encoder and a trained reader that maps every audio slice to the closest of about 229,000 word embeddings, plus a punctuation model (weights not public) |
| mlboydaisuke/EmbeddingGemma-2-Transcribe-Reader (code, Core AI, LiteRT) | English | open reproduction: 19.6M reader, scale × cosine against 200,000 word rows plus a blank logit, CTC on LibriSpeech 960 h; iOS, macOS and Android apps |
| karim23657/fa-eg2-persian | Persian | the same reader with a Persian word table |
Other speech recognisers on the EmbeddingGemma 2 audio encoder (subword or character outputs):
| Project | Language | What it is |
|---|---|---|
| mstkyvz/embeddinggemma2-turkish-stt | Turkish | character CTC reader, LoRA adapter, 4-gram LM |
| kuchris/embeddinggemma2asr-cantonese (code) | Cantonese | frozen encoder, 20.8M CTC reader over characters and English words |
| Steveeeeeeen/embeddinggemma2-en-* | English | CTC, RNN-T, TDT and other heads trained on 1,000 h of YODAS / Granary |
| harshit2312/stt-gemma_embedding-2 | English | frozen encoder, 13M causal CTC head, subword 6-gram LM, Core ML |
| AigizK/EmbeddingGemma2-Bashkir-CV25 | Bashkir | Transformer CTC reader over Gemma tokens |
| tc3oliver/Embed2ASR-v1 (code) | English, Mandarin | frozen encoder, 9.66M GRU-CTC reader |
| MaorB/embeddinggemma-2-asr-hebrew-english-streaming | Hebrew, English | top encoder layers fine-tuned, streaming transducer over word pieces |
| 0xanto/eg2-tamil | Tamil | top 2 encoder layers fine-tuned, CTC over 1,024 BPE units |
| bringagi/gemma-stt-hindi | Hindi | top 2 encoder layers fine-tuned, character CTC, word 3-gram LM |
Licence
Code: Apache 2.0 (LICENSE-CODE). Model files: Apache License 2.0 (LICENSE). EmbeddingGemma 2 keeps its own terms
and the Gemma Prohibited Use Policy; the n-gram LM (lee1jun/LES-eg2-asr-en-lm-4gram) is CC BY 4.0. Attributions: NOTICE.
Citation
If you use this model, please cite it:
@misc{les_eg2_665m_asr_en,
title = "{LES-eg2-665M-asr-en}: English Speech Recognition from a Frozen {EmbeddingGemma 2} with a Word-Embedding {CTC} Reader",
author = {lee1jun},
year = {2026},
month = nov,
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/lee1jun/LES-eg2-665M-asr-en}},
note = {n-gram LM: \url{https://huggingface.co/lee1jun/LES-eg2-asr-en-lm-4gram}}
}
This model builds on EmbeddingGemma 2:
@article{embeddinggemma2,
title = {EmbeddingGemma 2: Unified and Efficient Multimodal Representations},
author = {Schechter Vera, Henrique and Dua, Sahil and others},
journal = {arXiv preprint arXiv:2610.37364},
year = {2026}
}
Files
| File | Size |
|---|---|
LICENSE | 0.01 MiB |
LICENSE-CODE | 0.01 MiB |
NOTICE | 0.00 MiB |
PROVENANCE.json | 0.00 MiB |
README.md | 0.03 MiB |
architecture.png | 0.24 MiB |
architecture.svg | 0.01 MiB |
config.json | 0.00 MiB |
config.yaml | 0.00 MiB |
configuration_eg2_word_ctc.py | 0.00 MiB |
decoding.json | 0.00 MiB |
embedding_space.png | 0.35 MiB |
embedding_space.svg | 0.07 MiB |
model.safetensors | 335.79 MiB |
modeling_eg2_word_ctc.py | 0.07 MiB |
nbest_paths.png | 0.18 MiB |
nbest_paths.svg | 0.01 MiB |
requirements.txt | 0.00 MiB |
reranker_heads.safetensors | 24.58 MiB |
reranker_heads_nolm.safetensors | 24.58 MiB |
secondpass_eg2.py | 0.03 MiB |
seen_vocab.json | 4.30 MiB |
vocab.json | 4.54 MiB |
word_table.safetensors | 300.19 MiB |
Author
lee1jun (contact: lee1jun@kaist.ac.kr)
内容来源:Hugging Face 模型卡
在 Hugging Face 查看