Instructions to use litert-community/granite-speech-5.0-2b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT-LM
How to use litert-community/granite-speech-5.0-2b with LiteRT-LM:
# LiteRT-LM runs on various platforms (Android, iOS, Windows, Linux, macOS, IoT, Web/WASM) # and supports many APIs (C++, Python, Kotlin, Swift, JavaScript, Flutter). # For platform-specific integration guides, please refer to the official developer website: # https://ai.google.dev/edge/litert-lm # To try LiteRT-LM, the easiest way is to use our CLI tool. # 1. Install the LiteRT-LM CLI tool: pip install -U litert-lm # 2. Download and run this model locally: # See: https://ai.google.dev/edge/litert-lm/cli # A single .litertlm file in the repo is picked automatically; otherwise the CLI asks which one to run # (or pass its name right after the repo id). litert-lm run \ --from-huggingface-repo=litert-community/granite-speech-5.0-2b \ --prompt="Write me a poem"
- LiteRT
How to use litert-community/granite-speech-5.0-2b with LiteRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
granite-speech-5.0-2b — LiteRT-LM
This repository is a conversion of ibm-granite/granite-speech-5.0-2b to LiteRT-LM, made with litert-torch 0.10.0 and litert-lm-builder 0.19.1 for LiteRT-LM 0.19.1: it takes 16 kHz audio and returns the transcript, and with granite-speech-5.0-2b_ekv2048.litertlm a Galaxy S26 transcribes a 9.9-second clip in 2.44 s, with the first text after 1.21 s (language model and audio encoder on the GPU, mean of 2 processes × 2 calls, 2026-11-07). Speed still being tuned (updates follow).
granite-speech-5.0-2b is IBM's compact speech-language model for multilingual speech recognition and speech translation in English, French, German, Spanish, Portuguese and Japanese (translation also from English to Italian and Mandarin). It has about 2.3 billion parameters: a 16-layer conformer speech encoder, a 2-layer window query transformer that turns every 0.3 s of encoder output into 3 embeddings (10 per second of audio), and a 40-layer Granite language model built from an intermediate checkpoint of granite-4.0-1b-base. The source card recommends segments of up to about 2 minutes. IBM also publishes GGUF files and an ONNX build.
Which file
| File | Audio in one message | Audio encoder runs on | Galaxy S26, 9.9 s clip: first text / full transcript |
|---|---|---|---|
granite-speech-5.0-2b_ekv2048.litertlm (2026-11-07) |
116–152 s (context 2,048 tokens) | GPU | 1.21 s / 2.44 s (language model on the GPU), 1.68 s / 3.37 s (on the CPU) |
granite-speech-5.0-2b.litertlm (2026-11-06) |
234–307 s (context 4,096 tokens) | CPU | 3.83 s / 5.87 s (language model on the GPU), 5.16 s / 7.65 s (on the CPU) |
Use granite-speech-5.0-2b_ekv2048.litertlm unless one message has to hold more than about 2 minutes of audio. The audio range depends on how long the reply is: it is the longest clip that still fits at the highest, the 95th-percentile and the median reply length of our 220 test clips (How to send audio). The phone numbers of both files come from the same sessions on one Galaxy S26 (Performance).
Files
| File | What is inside | Size | sha256 |
|---|---|---|---|
granite-speech-5.0-2b_ekv2048.litertlm |
Three graphs (Section table below): the language model's decoder and token embedding table, and the audio encoder. Language model: int8 weights (one scale per output channel), KV cache of 2,048 tokens, prefill signatures of 64, 256 and 1,024 tokens, no activation-type declaration (on the GPU it runs float16 activations, the runtime's default). Audio encoder (log-mel front end, conformer, query transformer, projection): rewritten in operations the GPU accepts (tensors of rank 4 or less, no GATHER_ND), float16 weights computed in float32, one 24-second window. |
2,824,395,760 B | bf8eb5a8075b4fd3cdb1109a9edf0c247ff2bfb52b95699c31626aae80f3a642 |
granite-speech-5.0-2b.litertlm |
Three graphs, as above. Language model: the same int8 recipe, KV cache of 4,096 tokens, the same prefill signatures; the file asks the GPU for float32 activations. Audio encoder: float16 weights computed in float32, one 36-second window, CPU only. | 2,846,558,336 B | c90a3dae17d3399acbce3f9642a308d65bd0214134ce958562dbb2ef90337265 |
litertlm_manifest.json |
Machine-readable description of both files | 28,531 B |
| Section | Content | _ekv2048 |
granite-speech-5.0-2b.litertlm |
|---|---|---|---|
tf_lite_audio_encoder_hw |
log-mel front end, 16-layer conformer, 2-layer query transformer, projection to the language model | 941,890,544 B | 964,053,120 B |
tf_lite_prefill_decode |
Granite language model, int8 | 1,670,685,616 B | 1,670,685,616 B |
tf_lite_embedder |
token embedding table, int8 | 210,347,376 B | 210,347,376 B |
HF_Tokenizer_Zlib |
the source's tokenizer.json |
1,404,656 B (compressed) | 1,404,656 B (compressed) |
Both files carry the source repository's tokenizer.json byte for byte, a chat template that renders the source's prompt USER: <|audio|>{instruction}\n ASSISTANT: from LiteRT-LM's message parts, the stop token <|end_of_text|> (100257), no start token (the source tokenizer adds none), and the model type generic_model.
How to send audio
- One message holds one audio item, then the instruction as text. Use the prompts of the source card, for example
transcribe the speech with proper punctuation and capitalization.(punctuated transcript),can you transcribe the speech into a written format?(plain transcript),transcribe the speech to text. Keywords: <kw1>, <kw2>, ...(keyword biasing) ortranslate the speech to <language>.(translation). Put the audio first, as the source card's examples do (<|audio|>before the instruction); the template keeps the order of the parts. - Send 16 kHz mono WAV. We sent 16-bit PCM (the 220 test clips) and 32-bit float (the source card's
multilingual_sample.wav); other sample rates, stereo files and other containers were not tested. The runtime cuts the audio into 10 ms frames and gives the encoder fixed windows: 24 s in_ekv2048, 36 s ingranite-speech-5.0-2b.litertlm. The encoder always computes a whole window, also for a short clip: one 24-second window takes 114 ms on an M4 Max GPU (Metal) and 476 ms on its CPU (XNNPACK, 4 threads) (the encoder graph alone in ai-edge-litert 2.3.0, median of 10; a 5.9-second clip took the same time), and inside a LiteRT-LM call on the Galaxy S26 GPU 0.75 s with the language model on the GPU and 1.06 s with it on the CPU (the 9.9-second clip, Performance). Only the audio itself becomes input for the language model (10 positions per second). - Longer audio can go in one message, up to the context. A clip longer than one window is encoded window by window and the windows' outputs are joined. A 62.5-second test clip sent in one message to
_ekv2048differed from the source model's single-pass transcript by 1.29 % word error rate with the language model on the Mac CPU and on the Mac GPU; for scale, the source model's own transcript of the same clip cut in two pieces differed from its single-pass transcript by the same 1.29 %. The context holds the prompt and the reply together. With_ekv2048(2,048 tokens) one message fits about 116 s of audio at the highest reply length of our 220 test clips (in tokens per second of audio), 131 s at their 95th percentile and 152 s at their median; withgranite-speech-5.0-2b.litertlm(4,096 tokens) 234, 264 and 307 s. A message that does not fit is refused with INVALID_ARGUMENT, not cut (seen withgranite-speech-5.0-2b.litertlm: a 421.6-second clip came to 4,236 tokens). - Digital silence at the very end is ignored. The runtime does not tell the encoder how long the clip is, so the encoder takes the last non-zero sample as the end. A file that ends in exact zeros is read as slightly shorter: 19 of our 220 test files end that way (1 to 274 zero samples); on the 5 with 173 to 274 the encoder got one frame fewer than the source model, and the source language model's transcript from that shorter input was unchanged on all 5.
- Audio encoder backend.
_ekv2048: the GPU (audio_backendGPU, the command-line flag--audio-backend gpu), run on the Mac through LiteRT-LM's GPU path (WebGPU) and with OpenCL on a Galaxy S26 and a Pixel 11 Pro; the Metal time above is the encoder graph alone in ai-edge-litert. We did not test this file with the audio encoder on the CPU.granite-speech-5.0-2b.litertlm: the CPU only (--audio-backend cpu); the Mac's GPU delegate refuses several of its encoder's operations, among themGATHER_NDand 5-dimensional tensors, and creating a conversation then fails with INTERNAL. In both files the language model can run on the CPU or the GPU.
Usage
One clip with the LiteRT-LM command-line tool (uvx comes with uv; with pip, pip install litert-lm==0.19.1 and run litert-lm run … instead):
pip install -U huggingface_hub
hf download litert-community/granite-speech-5.0-2b granite-speech-5.0-2b_ekv2048.litertlm --local-dir .
hf download ibm-granite/granite-speech-5.0-2b multilingual_sample.wav --local-dir .
uvx --from litert-lm==0.19.1 litert-lm run granite-speech-5.0-2b_ekv2048.litertlm --backend gpu --audio-backend gpu --attachment multilingual_sample.wav --prompt "transcribe the speech with proper punctuation and capitalization." < /dev/null
The same from Python (pip install litert-lm==0.19.1):
import litert_lm
from litert_lm import Content, Contents, interfaces
engine = litert_lm.Engine(
"granite-speech-5.0-2b_ekv2048.litertlm",
backend=interfaces.Backend.GPU(),
audio_backend=interfaces.Backend.GPU(),
)
conversation = engine.create_conversation(sampler_config=interfaces.SamplerConfig(top_k=1))
message = Contents.of(
Content.AudioFile("multilingual_sample.wav"),
Content.Text("transcribe the speech with proper punctuation and capitalization."),
)
reply = conversation.send_message(message)
print("".join(part["text"] for part in reply["content"] if part["type"] == "text"))
interfaces.Backend.CPU() (or --backend cpu) puts the language model on the CPU; on the Galaxy S26 Backend.CPU(thread_count=6) reached the first text sooner than the default (Performance). With granite-speech-5.0-2b.litertlm, keep the audio encoder on the CPU (audio_backend=interfaces.Backend.CPU(), --audio-backend cpu). On the Mac, the first run of the command-line tool wrote caches next to the model file (about 1.6 GB for the language model on either backend and 7 MB for the audio encoder), and later runs load them.
Use a new conversation for each clip; every number on this card comes from one conversation per clip. From the second message of a conversation on, LiteRT-LM 0.19.1 puts the previous answer's stop token into the context with a zero embedding (read in the runtime's source; these files' language model takes embeddings, not token ids), so a second transcript in one conversation would start from a context the model never saw; we did not measure it on these files.
Performance
Galaxy S26 (Android 16), LiteRT-LM 0.19.1 (the litert-lm-api 0.19.1 Android wheel from PyPI), 2026-11-07, both files in the same sessions. Clip: one streaming call per clip with a new conversation each, after a warm-up clip, the mean of 2 processes × 2 calls. Audio encoding: the call's time minus its prefill and decode, less the same remainder of a text-only call, on the 9.9-second clip. Peak memory: the highest peak resident memory (VmHWM) of these timing processes, GPU buffers not included. CPU work ran at the runtime's default thread count. The phone's thermal governor capped the CPU frequency in most samples of every row (_ekv2048: 22 of 33 with the language model on the GPU, 37 of 41 on the CPU; granite-speech-5.0-2b.litertlm: 45 of 53 and 56 of 59), and in the GPU rows the GPU clock as well, so these are throttled numbers. Creating the engine is not in them.
| File | Language model on | Audio encoder on | 9.9 s clip: first text / full transcript | Audio encoding | Peak memory |
|---|---|---|---|---|---|
_ekv2048 |
GPU | GPU | 1.21 s / 2.44 s | 0.75 s | 2.5 GB |
_ekv2048 |
CPU | GPU | 1.68 s / 3.37 s | 1.06 s | 4.3 GB |
granite-speech-5.0-2b.litertlm |
GPU | CPU | 3.83 s / 5.87 s | 2.85 s | 4.0 GB |
granite-speech-5.0-2b.litertlm |
CPU | CPU | 5.16 s / 7.65 s | 4.12 s | 6.1 GB |
Language model alone on the Galaxy S26 (litert_lm.Benchmark, a forced prefill of 1,024 tokens, then 256 decoded tokens, the mean of runs 2 and 3 in two processes, other sessions of 2026-11-07): in one pair of sessions, a file whose two language-model sections are the same bytes as _ekv2048's gave 933.2 tokens/s prefill and 23.59 tokens/s decode on the GPU and 229.6 and 15.09 on the CPU, and granite-speech-5.0-2b.litertlm 226.6 and 14.88 on the GPU and 137.9 and 10.03 on the CPU; _ekv2048 itself gave 229.2 and 15.34 on the CPU in the thread-count session below.
CPU thread count on the Galaxy S26 (_ekv2048, language model on the CPU, one session, the default and 6 threads alternating, 2 processes each): with Backend.CPU(thread_count=6) the 9.9-second clip took 1.43 s to the first text and 2.91 s in all, against 1.63 s and 3.26 s at the default (4 in the LiteRT-LM 0.19.1 source); over a 5.9, a 9.9 and a 29.4-second clip, 6 threads took 0.85 times the default's time to the first text. The benchmark above was not faster with 6 threads (decode 14.86 against 15.34 tokens/s). 8 threads and other phones were not measured.
Mac M4 Max (128 GB), LiteRT-LM 0.19.1 from PyPI (its Mac GPU path is WebGPU), _ekv2048, 2026-11-07. Language model: litert-lm benchmark granite-speech-5.0-2b_ekv2048.litertlm -p 1024 -d 256 --max-num-tokens 2048 --runs 3 --cache no --backend <cpu|gpu> (CPU at 4 threads). Clip: a 10.0-second FLEURS clip, the third conversation of a process (after a warm-up clip and a 5.9-second clip), median of 5 processes, the audio encoder on the GPU in both rows. Encoder: one 24-second window of the file's encoder graph alone in ai-edge-litert 2.3.0 (GPU: Metal; CPU: XNNPACK, 4 threads), median of 10. Creating the engine took 2.0 s (GPU) and 11.0 s (CPU) in the benchmark runs, which keep no cache (--cache no).
| Language model on | Prefill (tokens/s) | Decode (tokens/s) | Encoder, one 24 s window | 10 s clip: first text / full transcript |
|---|---|---|---|---|
| GPU | 3,373.13 | 109.87 | 114.1 ms (GPU) | 0.226 s / 0.445 s |
| CPU | 841.62 | 36.21 | 476.1 ms (CPU) | 0.410 s / 1.049 s |
Accuracy
220 clips: English = 20 LibriSpeech dev-clean clips + 50 FLEURS en_us test clips; Japanese = 50 FLEURS ja_jp test clips; French, German, Spanish and Portuguese = 25 FLEURS test clips each. The instruction is transcribe the speech with proper punctuation and capitalization., greedy decoding, at most 256 new tokens, one conversation per clip. English is scored with Whisper's English text normalizer, the four other European languages with Whisper's basic normalizer (openai-whisper 20250625), Japanese by characters after NFKC normalization and lowercasing with punctuation and spaces removed. The source model runs in transformers 5.22.1 (bfloat16 weights computed in float32 on the CPU); _ekv2048 runs in LiteRT-LM 0.19.1 on a Mac M4 Max with its audio encoder on the GPU:
| Model | English WER | Japanese CER | French + German + Spanish + Portuguese WER |
|---|---|---|---|
| Source model (transformers) | 4.60 % (73/1,588) | 5.13 % (138/2,689) | 12.10 % (286/2,363) |
_ekv2048, language model on the CPU |
4.41 % (70/1,588) | 5.21 % (140/2,689) | 11.93 % (282/2,363) |
_ekv2048, language model on the GPU |
4.53 % (72/1,588) | 5.24 % (141/2,689) | 12.15 % (287/2,363) |
The pass lines, set before the file was built, were the source model's numbers plus 0.5 points (English) and plus 1.0 point (Japanese, and the four European languages together). No reply was empty, repeated itself or ran to the token limit. The transcripts are character for character the source model's (punctuation and case included) on 180 of the 220 clips with the language model on the CPU and on 195 with it on the GPU. granite-speech-5.0-2b.litertlm is within 0.2 points of these numbers in every group (the block below).
The source card's multilingual_sample.wav (24.9 s, English and then French) with the instruction above keeps both languages in _ekv2048: the transcript differs from the source model's by 0.00 % word error rate with the language model on the CPU and on the GPU, on the Mac (Python and the command-line tool) and on the Galaxy S26.
On a Pixel 11 Pro, a 38-clip subset of the 220 ran with the same instruction and decoding: the 20 LibriSpeech clips, the first 10 Japanese clips and the first 2 French, German, Spanish and Portuguese clips. The lines were the source model's number on these clips plus 0.5 point for English, 1.0 for Japanese and 1.0 for the four European languages together, and in both runs all 38 replies stopped on their own, none empty or repeating:
| Run | English WER | Japanese CER | French + German + Spanish + Portuguese WER |
|---|---|---|---|
| Source model (transformers), the same 38 clips | 2.43 % | 7.26 % | 2.03 % |
_ekv2048, language model on the CPU |
2.21 % | 7.59 % | 2.03 % |
_ekv2048, language model on the GPU |
1.99 % | 7.59 % | 2.03 % |
The Pixel 11 Pro ran _ekv2048 for this check only, not in timing processes. On the Galaxy S26, _ekv2048 ran the timing processes of the Performance table; their transcripts of the three clips were identical to a Mac run of the same file and backend in 4 of 4 processes.
Translation and keyword biasing, against the source model's text: translate the speech to English. on one French, one German and one Spanish FLEURS clip gave the source model's words on the French clip with the language model on either backend and on the Spanish clip with it on the GPU; the German clip differs by one word on both backends ("cultural-determinist" for "cultural-deterministic") and the Spanish clip by one name on the CPU. transcribe the speech to text. Keywords: … on 3 LibriSpeech clips gave the source model's text on 2 of 3 on both backends; the third differs by one word and contains the same keywords as the source model's.
granite-speech-5.0-2b.litertlm: measurements from 2026-11-06
These are the previous card's numbers. Re-timed on 2026-11-07 in the Performance table's sessions, the same file reached the first text in 5.16 s (language model on the CPU) and 3.83 s (GPU) against 4.36 s and 7.47 s here; the phone's throttling differed between the two days, and we did not separate the cause.
Galaxy S26 (Android 16), LiteRT-LM 0.19.1 (the litert-lm-api 0.19.1 Android wheel from PyPI), 2026-11-06. Prefill and decode: litert_lm.Benchmark with a forced prefill of 1,024 tokens, then 256 decoded tokens (at most 2,048 tokens), the mean of runs 2 and 3 in two processes. Clip: one streaming call per clip with a new conversation each, the mean of 2 calls after a warm-up clip. Encoder: the audio encoding inside the call (the call's time minus its prefill and decode), the mean over a 5.9, a 9.9 and a 29.4-second clip. Peak memory: the highest peak resident memory (VmHWM) of our processes on that backend, the accuracy runs included (the timing process itself peaked at 5.1 GB on the CPU and 3.9 GB on the GPU); GPU buffers not included. The audio encoder is on the CPU in both rows, at the runtime's default CPU thread count. The phone's thermal governor capped the CPU frequency in almost every sample of these runs, and in the GPU row the GPU clock as well (thermal status up to 3), so these are throttled numbers; in the GPU row the CPU encoder took 5.6 s against 3.7 s in the CPU row, and we did not separate the cause. Creating the engine is not in these numbers: about 4.3 s on the CPU and 10.0 s on the GPU in a cold process (0.6 s and 6.7 s with the runtime's caches present). On the Pixel 11 Pro of the accuracy check, whose CPU was also capped, the same 9.9-second clip took 32.5 s with the language model on the CPU and 27.7 s on the GPU.
| Phone | Language model on | Prefill (tokens/s) | Decode (tokens/s) | Encoder, one 36 s window | 9.9 s clip: first text / full transcript | Peak memory |
|---|---|---|---|---|---|---|
| Galaxy S26 | CPU | 137.9 | 9.87 | 3,686 ms | 4.36 s / 6.50 s | 6.2 GB |
| Galaxy S26 | GPU | 203.5 | 14.84 | 5,619 ms | 7.47 s / 9.54 s | 3.9 GB |
Mac M4 Max (128 GB), LiteRT-LM 0.19.1 from PyPI. Language model: litert-lm benchmark granite-speech-5.0-2b.litertlm -p 1024 -d 256 --max-num-tokens 2048 --runs 3 --cache no --backend <cpu|gpu>. Clip: a 10.0-second FLEURS clip, the third clip of each process (model loaded, two clips already transcribed), median of 3 processes; the audio encoder on the CPU in every row. Encoder: the file's audio encoder graph alone in the ai-edge-litert 2.3.0 interpreter (XNNPACK, 4 threads), one 36-second window, median of 5.
| Language model on | Prefill (tokens/s) | Decode (tokens/s) | Encoder, one 36 s window | 10 s clip: first text / full transcript |
|---|---|---|---|---|
| GPU | 2,351.68 | 84.18 | 1,069.5 ms | 1.18 s / 1.46 s |
| CPU | 500.55 | 26.65 | 1,069.5 ms | 1.41 s / 2.22 s |
Accuracy on the 220 clips above (Mac M4 Max, the audio encoder on the CPU, the same scoring and pass lines):
| Language model on | English WER | Japanese CER | French + German + Spanish + Portuguese WER |
|---|---|---|---|
| CPU | 4.53 % (72/1,588) | 5.02 % (135/2,689) | 11.93 % (282/2,363) |
| GPU | 4.72 % (75/1,588) | 5.32 % (143/2,689) | 12.06 % (285/2,363) |
The transcripts are character for character the source model's on 181 of the 220 clips with the language model on the CPU and on 209 with it on the GPU. On the phones, the same 38-clip subset with the audio encoder on the CPU passed the same kind of lines in all four runs, and in each run all 38 replies stopped on their own, none empty or repeating:
| Run | English WER | Japanese CER | French + German + Spanish + Portuguese WER |
|---|---|---|---|
| Galaxy S26, language model on the CPU | 2.43 % | 6.11 % | 2.03 % |
| Galaxy S26, language model on the GPU | 2.43 % | 7.26 % | 2.03 % |
| Pixel 11 Pro, language model on the CPU | 2.21 % | 7.43 % | 2.03 % |
| Pixel 11 Pro, language model on the GPU | 2.43 % | 7.26 % | 2.03 % |
With the language model on the GPU, both phones' transcripts of the 38 clips are identical to a Mac GPU reference run of this file on 38 of 38 clips; with it on the CPU, on 33 of 38 on both phones (the same 5 clips differ). Those references are separate Mac runs made for this comparison (CPU at one thread; GPU the text at least two of three processes agreed on), not the 220-clip runs above.
Translation and keyword biasing against the source model's text: translate the speech to English. on the same three FLEURS clips gave the source model's translation word for word on the Mac GPU (3 of 3) and on 2 of 3 on the Mac CPU (one word differs); the keyword prompt on the same 3 LibriSpeech clips gave the source model's text on both (3 of 3).
Limitations
- The audio encoder computes a full window for every clip, also for a short one (24 s in
_ekv2048, 36 s ingranite-speech-5.0-2b.litertlm). A 12-second window was faster but missed the Japanese pass line, so it was not shipped. - No NPU file yet: an audio encoder compiled for the Galaxy S26 NPU passed the 38-clip check but turned the English half of
multilingual_sample.wavinto French, so it is not published. No int4 file: on the CPU an int4 language model prefilled 58 % slower than int8, which lengthens the time to the first text. - With the language model on the CPU, LiteRT-LM quantizes the activations to int8 at run time: in one run per backend the transcripts of
_ekv2048were character for character the source model's on 180 of 220 clips against 195 on the GPU, at error rates within 0.3 points of each other (Accuracy). A second CPU process can print a slightly different transcript of the same clip (in our check ofgranite-speech-5.0-2b.litertlm, two more commas). - The context is 2,048 tokens in
_ekv2048and 4,096 ingranite-speech-5.0-2b.litertlm, prompt and reply together; a message that does not fit is refused, not cut (How to send audio).
Conversion notes
- Source: ibm-granite/granite-speech-5.0-2b at revision
98160169.out_llm.safetensors(the encoder's BPE CTC head) is not used: the speech-to-text model in transformers does not load it. - Runtime: every measurement of the files on this card used LiteRT-LM 0.19.1, which runs the graphs on LiteRT, except the encoder-alone times (the encoder graph alone in ai-edge-litert 2.3.0).
- Language model: litert-torch 0.10.0
export_hfof the Granite decoder taken out of the checkpoint, with the token embedding exported separately, prefill signatures 64, 256 and 1,024, quantization recipedynamic_wi8_afp32; KV cache 2,048 for_ekv2048and 4,096 forgranite-speech-5.0-2b.litertlm. The embedding multiplier (×12) stays in the language model graph, where it also scales the audio rows, as in transformers. - Audio encoder: a PyTorch module that computes what the source's feature extractor, encoder and projector compute on the unpadded clip (the same mel filterbank and window, the clip length taken from the audio, masks for the partial attention block and the padded frames), traced with litert-torch; float16 weights. On the 220 clips above the PyTorch module (in float32) gave the source's number of audio tokens on every clip, and its output fed to the source language model gave the source's transcript on every clip. For
_ekv2048the same computation is written with tensors of rank 4 or less (the relative-position shift as a skew, the convolutions as 2-D convolutions, noGATHER_ND,BROADCAST_TOorDIV), so the GPU delegate takes the whole graph, and exported for a 24-second window; both encoders were judged on the 220 transcripts above. - Packed with litert-lm-builder 0.19.1 (litert-torch 0.10.0's own packing calls a builder API that 0.19 no longer has).
- Reproduce
granite-speech-5.0-2b.litertlm: the scripts are ingranite_speech_2b_work/of hf-to-litertlm, and the commands in its REPRODUCE.md. Run from a clean clone on 2026-11-06, they gave every section of that file with the same bytes (the packer writes a new uuid and creation time into the header on every run).
Updates
- 2026-11-07: added
granite-speech-5.0-2b_ekv2048.litertlm. Its audio encoder runs on the GPU and reads 24-second windows, and its language model has a 2,048-token context and no activation-type declaration; on a Galaxy S26 the 9.9-second clip reached the first text in 1.21 s against 3.83 s forgranite-speech-5.0-2b.litertlmin the same session (both with the language model on the GPU).granite-speech-5.0-2b.litertlmis unchanged (c90a3dae…, 2,846,558,336 B) and stays the file for messages of more than about 2 minutes of audio. New:bf8eb5a8…, 2,824,395,760 B; the tokenizer section is the same bytes. Checked with LiteRT-LM 0.19.1, greedy decoding: 220 clips on a Mac M4 Max with the language model on the CPU and on the GPU (both inside the pass lines), 38 clips on a Pixel 11 Pro on both backends (inside the lines), and the source card's sample on a Galaxy S26 on both backends (both languages kept).
License
Apache License 2.0, the same license as the source model. The files here are converted from ibm-granite/granite-speech-5.0-2b: the weights are quantized, and the prompt template is written for LiteRT-LM as described above.
- Downloads last month
- -
Model tree for litert-community/granite-speech-5.0-2b
Base model
ibm-granite/granite-4.0-1b-base