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 1.37 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.

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; three passes reveal the 12 codes of a frame CPU 334,104,044 B 5f684777daf8c73dc4a95b314fe559cb329f8a7976791ed7ecfdfa78ae93dfe7
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

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, codec GPU 1.37 s per second of speech, real-time factor 1.45, first audio after 2.06 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_main built from the LiteRT-LM v0.18.1 tag, --benchmark --benchmark_prefill_tokens=1024 --benchmark_decode_tokens=256 --max_num_tokens=2048 for text, --audio_backend=gpu for 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 the Galaxy S26 spoke faster than real time and the Pixel 8a did not.
  • 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 (depth decoder on the NPU), 0.0215 on the Galaxy S26 (depth decoder on the CPU), 0.0251 on the Pixel 8a, 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: 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:

  1. Each decoder step makes one 80 ms frame.
  2. The depth decoder reveals the frame's 12 codes in three passes (4 + 4 + 4, MaskGIT order).
  3. The frame embedding turns the 12 codes into the decoder's next input.
  4. 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 depend on the CPU thread count. For the same input the two phones gave the same speech codes, and so did a Mac with one thread; with eight threads the Mac's codes differed in all 3 test sentences.
  • 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 NPU pass is the depth pass with its sigmoid and SiLU written with exp, 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.sh in github.com/john-rocky/hf-to-litertlm converts the source to these files. Run on 2026-10-29, it rebuilt every section of the .litertlm file and the four CPU and GPU speech graphs 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 generation tags 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, 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
31
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for litert-community/LFM3-Audio-2B-LiteRT

Quantized
(11)
this model