Instructions to use litert-community/LFM3-Audio-2B-LiteRT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT-LM
How to use litert-community/LFM3-Audio-2B-LiteRT 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/LFM3-Audio-2B-LiteRT \ --prompt="Write me a poem"
- LiteRT
How to use litert-community/LFM3-Audio-2B-LiteRT 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
LFM3-Audio-2B β LiteRT
LFM3-Audio-2B on Android phones and Mac, with no network. Text or speech goes in; text comes out through LiteRT-LM 0.18.1 from one .litertlm file. Speech out needs four more LiteRT graphs (here) and a loop in your app. On a Galaxy S26 the GPU writes 40.6 tokens per second, and one second of speech takes 0.40 s to make; on a Pixel 8a, 13 tokens per second and 0.81 s. We checked English only. Converted from LiquidAI/LFM3-Audio-2B with litert-torch and litert-lm-builder 0.18.1, run with LiteRT 2.3.0; measured 2026-10-29 (the Pixel 8a's speech output 2026-10-31).
LFM3-Audio-2B is Liquid AI's audio model. It takes text or speech in and answers with text, speech, or both: speech recognition, text to speech, voice chat, questions about a recording, and tool calls. The source card lists 18 languages for transcription, synthesis and translation, and says voice chat supports English only.
What runs where
| You want | Use | Checked on |
|---|---|---|
| Text from text or from speech (transcription, questions, chat) | the .litertlm file with LiteRT-LM 0.18.1, CPU or GPU |
Galaxy S26 (GPU), Pixel 8a (GPU), Mac (CPU and GPU) |
| Speech (text to speech, spoken answers) | the .litertlm file plus the speech graphs below, run by your own loop |
Galaxy S26, Pixel 8a (Android app) |
LiteRT-LM alone does not produce speech. LiteRT-LM feeds the model token ids; in speech mode the next input is an embedding (the sum of 12 codebook embeddings), which LiteRT-LM cannot feed, so your app runs the loop (Speech output, below).
Files
| File | What it is | Runs on | Size | sha256 |
|---|---|---|---|---|
lfm3-audio-2b_int4_b128_c2048_h30.litertlm |
The model for LiteRT-LM: int4 decoder, int8 embedder, audio encoder (fp16 linear weights), tokenizer and chat template. 2,048-token context. | CPU, GPU | 1,531,232,624 B (1.53 GB) | 5168b79a795d1737e789f22a84f5830e808f45a3ba2d3a02099b4d291bda4f02 |
lfm3_audio_depth_proj_r4b.tflite |
Speech output: projects the decoder's last hidden state for the depth decoder, once per 80 ms frame | CPU | 100,713,664 B | 66789aa754112d69fcc7bb857d317466af52af8b1686c1b327fa9fa11217476d |
lfm3_audio_depth_pass_r4b.tflite |
Speech output: one depth-decoder pass in float32; three passes reveal the 12 codes of a frame | CPU | 334,104,044 B | 5f684777daf8c73dc4a95b314fe559cb329f8a7976791ed7ecfdfa78ae93dfe7 |
lfm3_audio_depth_pass_r4b_int8.tflite |
The same pass with int8 weights and float32 activations | CPU | 84,562,624 B | b2489155633c78cd9c9630f439e9b3cc4cfa96df9364c5315a8a08a010ea1947 |
lfm3_audio_depth_pass_r5b_aot.tflite |
The same pass compiled ahead of time for the Snapdragon SM8850 NPU (Galaxy S26) | NPU (SM8850 only) | 169,584,336 B | e3bdb0ed185190ba7b0881af250e585385e04360c6a614e712801287a8f1bfd4 |
lfm3_audio_frame_embed_f32.tflite |
Speech output: turns a frame's 12 codes into the decoder's next input | CPU | 198,281,752 B | d042be62b439630e55feed86bc9ae630db70674ba924d4752c4d5dfc3a44472d |
lfm3_audio_codec_decoder_f12_r4b2.tflite |
Speech output: audio codec decoder, 12 frames (0.96 s) of codes to 24 kHz audio frames per call | GPU (fp32) or CPU | 152,498,860 B | 9dbbbcf870c1be4e166b77c1948ca4e34e8e069780236c15066f1d3c8ed52cbd |
LICENSE |
The source model's license file, unchanged | 10,574 B | ||
litertlm_manifest.json |
Machine-readable description of the .litertlm file |
Your speech loop reads one pass file: the int8 file on a CPU, or the NPU file on a Galaxy S26. The float32 file is the same pass before quantization. The speech numbers below are for the int8 and NPU files unless a line names the float32 pass. The suffixes in the file names are build labels; the app reads these names as they are. The .litertlm file holds the source repository's tokenizer.json byte for byte.
Performance
Galaxy S26 (SM-S942Q, Snapdragon SM8850, Android 16):
| Task | Runs on | Result |
|---|---|---|
| Text: 1,024-token prompt, then 256 tokens | GPU | prefill 1,295.4 tokens/s, decode 40.61 tokens/s, first token after 0.81β0.82 s |
| Audio input: one 30 s window through the audio encoder | GPU | 94.4 ms per window (3.1 ms per second of audio) |
| Speech output (Android app) | decoder CPU, depth-decoder pass NPU (its projection CPU), codec GPU | 0.40 s per second of speech, real-time factor 0.44, first audio after 0.71 s |
Pixel 8a (Tensor G3, Android 16):
| Task | Runs on | Result |
|---|---|---|
| Text: answers to short questions | GPU | decode 12.95 tokens/s (median of 7 answers, not the 1,024-token test), first token after 1.14 s |
| Audio input: one 30 s window through the audio encoder | GPU | 360.7 ms per window (12 ms per second of audio) |
| Speech output (Android app) | decoder and depth decoder CPU (its pass from the int8 file), codec GPU | 0.81 s per second of speech, real-time factor 0.88, first audio after 1.50 s |
Mac (Apple M4 Max), text: 1,024-token prompt, then 256 tokens:
| Runs on | Prefill (tokens/s) | Decode (tokens/s) | First token |
|---|---|---|---|
| GPU (WebGPU) | 3,898 | 167.88 | 0.27 s |
| CPU | 354 | 64.19 | 2.90 s |
- Text and audio-input rows on the phones:
litert_lm_advanced_mainbuilt from the LiteRT-LM v0.18.1 tag,--benchmark --benchmark_prefill_tokens=1024 --benchmark_decode_tokens=256 --max_num_tokens=2048for text,--audio_backend=gpufor audio. Each Galaxy S26 number is the mean of two runs (four for audio). On the Galaxy S26 GPU the text run peaked at 951β975 MiB process memory plus 2.08 GB of GPU memory. - The Galaxy S26 rows and the Pixel 8a audio row used a copy of this file that differs only in the chat template (the Pixel 8a text row ran the earlier build named under Mac rows): it adds the system turn
Perform ASR in English.when a conversation starts with audio, because the phone command-line tool has no system-message flag. - The audio encoder always reads a full 30 s window, so a short clip takes as long as a 30 s one.
- Speech output: the Android app (LiteRT 2.3.0) speaking one English sentence of about 10 s, with the source card's sampling; the mean of three answers after one warm-up answer, two runs per phone. "Per second of speech" counts the time after the prompt; the real-time factor counts the whole answer. On this sentence both phones spoke faster than real time (the Pixel 8a's six measured answers at real-time factors 0.83 to 0.94). In the same Pixel 8a session the float32 pass took 1.24 s per second of speech (real-time factor 1.31). The Galaxy S26 row was measured on 2026-10-29, the Pixel 8a row on 2026-10-31.
- Mac rows: litert-lm 0.18.1 (Python), the runtime's default thread count, two processes, each a warm-up then two runs. They were measured on an earlier build of this file with the same decoder, embedder, tokenizer and template bytes (only the audio encoder differs).
Quality
Checks (source model = LiquidAI/LFM3-Audio-2B in PyTorch, float32; phone rows are compared with the Mac):
- Transcription, 110 English clips (the first 100 of FLEURS en_us test and 10 of LibriSpeech dev-clean), system prompt
Perform ASR in English., greedy, Mac CPU: word error rate 5.558 % (140 errors in 2,519 words in each of three runs), the source model 5.518 % (139 errors). - On the phones, 10 LibriSpeech clips: the Galaxy S26 GPU wrote the same text as the Mac for 10 of 10; the Pixel 8a GPU for 9 of 10 (the tenth has no comma after "art").
- Audio encoder: the same number of audio tokens as the source model on 20 of 20 clips; the lowest cosine similarity of any token was 0.99997.
- Text questions: 8 short questions, all 8 correct on the Mac CPU. On the Galaxy S26 GPU and the Pixel 8a GPU (the earlier build with the same decoder bytes) all 8 were correct and equal to the Mac's answers.
- Speech output, 20 English sentences, two seeds each, the source card's sampling; the speech was transcribed by Whisper (base.en) and compared with the sentence: word error rate 0.0165 on the Galaxy S26 (the depth-decoder pass on the NPU), 0.0215 on the Galaxy S26 (the float32 pass on the CPU), 0.0215 on the Pixel 8a (the int8 pass; 0.0251 with the float32 pass), against 0.0218 for the source model's own speech. The speech was as long as the source model's (median length ratio 1.0).
- Text and speech together (system prompt
Respond with interleaved text and audio.), 5 questions, with the float32 pass on the CPU: on both phones the speech said what the text said (word error rate 0 on four answers, 0.0769 on one).
Usage
Text from text or speech (LiteRT-LM)
With the LiteRT-LM command-line tool:
pip install -U huggingface_hub
hf download litert-community/LFM3-Audio-2B-LiteRT lfm3-audio-2b_int4_b128_c2048_h30.litertlm --local-dir .
uvx --from litert-lm==0.18.1 litert-lm run lfm3-audio-2b_int4_b128_c2048_h30.litertlm --backend gpu --cache no --prompt "What is the capital of Japan? Answer briefly." < /dev/null
uvx --from litert-lm==0.18.1 litert-lm run lfm3-audio-2b_int4_b128_c2048_h30.litertlm --backend gpu --cache no --attachment speech.wav --prompt "What does the speaker talk about?" < /dev/null
< /dev/null stops the tool from waiting on the terminal. speech.wav is your recording (16 kHz mono). The model may think before it answers; the tool then prints the thought between [thought] and [/thought].
From Python (pip install litert-lm==0.18.1), a transcription with the source card's system prompt:
import litert_lm
MODEL = "lfm3-audio-2b_int4_b128_c2048_h30.litertlm"
def text(reply):
return "".join(part["text"] for part in reply["content"] if part.get("type") == "text")
# One Engine per conversation (Known issues).
with litert_lm.Engine(MODEL, backend=litert_lm.Backend.GPU(), audio_backend=litert_lm.Backend.CPU(),
cache_dir=":nocache") as engine:
with engine.create_conversation(messages=[{"role": "system", "content": "Perform ASR in English."}]) as conversation:
reply = conversation.send_message({"role": "user", "content": [{"type": "audio", "path": "speech.wav"}]})
print(text(reply))
Speech output
Speech needs a loop around the decoder and four of the graphs above:
- Each decoder step makes one 80 ms frame.
- The depth decoder reveals the frame's 12 codes in three passes (4 + 4 + 4, MaskGIT order).
- The frame embedding turns the 12 codes into the decoder's next input.
- Every 12 frames, the codec decoder makes 0.96 s of 24 kHz audio, and the app overlap-adds it.
The source card's settings for speech: system prompt Perform TTS in <language> using a <gender> voice. with the assistant turn started by <|audio_start|>, or Respond with interleaved text and audio. with <|mixed_start|>; audio temperature 1.0, top-k 128, repetition penalty 1.1 over 4,096 frames.
An Android sample app that runs this loop with these files is open for review as a pull request to google-ai-edge/litert-samples: voicemail_summary. It tells you, in your language, what an English voicemail says.
Known issues
- Create one Engine per conversation: on LiteRT-LM, a conversation started on an Engine that already served another one continues from that conversation's running state (LiteRT-LM issue #3165). This model keeps a running short-convolution state.
- Multi-turn chat: from the second message, LiteRT-LM 0.18.1 feeds the previous answer's stop token to the model as a zero vector. This is a runtime behaviour for every file with a separate embedder, read in the runtime's source and not measured here. One question per Engine avoids it.
- The context is 2,048 tokens (the source model: 32K). One second of input audio takes 12.5 tokens; one second of speech output takes 12.5 decoder steps.
- Audio input is read in 30 s windows. LiteRT-LM cuts a longer recording into 30 s windows with no overlap. Exact-zero samples at the end of a clip count as padding.
- The chat template has no thinking switch. In text answers the model sometimes thinks first: before 5 of the 8 short answers on the Galaxy S26 GPU and 6 of 8 on the Pixel 8a GPU (every answer was correct). LiteRT-LM returns the thought separately.
- Tool calls come back as message text; your app parses them.
- The file carries no sampler settings, so LiteRT-LM answers greedily unless your app sets a sampler.
- Greedy speech codes are not the same on every CPU and thread count. With the float32 depth-decoder pass, the two phones and a Mac with one thread gave the same speech codes for the same input, and a Mac with eight threads differed in all 3 test sentences. With the int8 pass the two phones gave the same codes as each other (3 of 3 sentences) and not a Mac's at one thread (0 of 3).
- The NPU file runs only on Snapdragon SM8850 phones (the Galaxy S26 here). It was compiled with QAIRT 2.47; the app ran it with LiteRT 2.3.0 and QAIRT 2.50's runtime libraries, which an Android app has to bundle itself.
Conversion notes
- Source: LiquidAI/LFM3-Audio-2B at revision
9d49701c. A later commit (cddb56b5, 2026-10-29) changed only the README. - Decoder: exported with litert-torch (commit f61d0b7 of its main branch, torch 2.14.0, transformers 5.20.2) through an LFM3 extension; the token embedder is a separate section, and the decoder also returns its last hidden state (the input of the depth decoder). Prefill signatures of 1,024, 256, 64, 16, 4 and 1 tokens, KV cache of 2,048. Quantized with ai-edge-quantizer-nightly 0.10.0.dev20261023: every fully connected weight int4 (blockwise, 128 weights per block, symmetric) except the tied text head, which is int8 per channel; the embedding table int8 per channel. Block scales are floored at 2^-14 before rounding (XNNPACK refuses smaller ones); this raised 720 scales in 3 tensors.
- Audio encoder: the log-mel features, the encoder and the projector in one graph that reads 16 kHz PCM (3,000 frames of 160 samples = 30 s) and writes up to 375 rows plus a mask of the valid rows; fully connected weights in fp16.
- Speech graphs: exported with litert-torch 0.10.0 (torch 2.14.0), float32. The int8 pass is the float32 pass quantized with ai-edge-quantizer 0.10.0's
dynamic_wi8_afp32recipe: int8 per-channel weights in its 36 fully connected layers and its embedding table, float32 activations, which are quantized to int8 on the fly during inference (the recipe's dynamic quantization). The NPU pass is the depth pass with its sigmoid and SiLU written withexp, compiled for the SM8850 with ai-edge-litert 2.2.0 and QAIRT 2.47 (396 of 396 operations on the NPU). - Reproduce:
lfm3audio_work/convert_lfm3_audio.shin github.com/john-rocky/hf-to-litertlm converts the source to these files. Run on 2026-10-31, it rebuilt every section of the.litertlmfile and the five CPU and GPU speech graphs, the int8 pass among them, byte for byte. The NPU file comes out with different bytes on every compile, so the one here is the file the Galaxy S26 measurements ran. - Chat template: the source template with three edits. Earlier assistant turns render without their thought (LiteRT-LM keeps a conversation's earlier prompt as a prefix of the next one, so a turn must render the same after a later message). The two
generationtags are removed and 13.get("β¦")lookups are written as["β¦"], which keeps the rendered text and lets LiteRT-LM's template engine run the file.
License
LFM Open License v1.0, the same license as the source model (LICENSE). The files here are converted from LiquidAI/LFM3-Audio-2B: the decoder weights are quantized to int4 and int8, the audio encoder's fully connected weights are stored in fp16, the speech parts are re-exported as LiteRT graphs (one depth-decoder pass also with int8 weights), and the chat template is changed as described under Conversion notes. Section 5 of the license does not license commercial use by an organization with annual revenue of 10 million US dollars or more (a qualified non-profit's non-commercial or research use is exempt).
- Downloads last month
- 121
Model tree for litert-community/LFM3-Audio-2B-LiteRT
Base model
LiquidAI/LFM3-Audio-2B