Audio8-TTS-Realistic-0.6b โ€” LiteRT

This repository is a conversion of Edge0/Audio8-TTS-Realistic-0.6b to LiteRT, made with litert-torch 0.9.4 and ai-edge-quantizer 0.9.0 for LiteRT 2.2.0: in the Android app under android/, a Pixel 11 Pro speaks an 18-token English sentence (5.48 s of audio) at a real-time factor of 0.884, and a Galaxy S26 at 0.725 (6.36 s of audio), each the median of 6 runs (2026-11-02). The real-time factor is the time from text to samples divided by the length of the speech: below 1, the speech is ready before it would have finished playing.

Edge0/Audio8-TTS-Realistic-0.6b is a text-to-speech model by Edge0 with zero-shot voice cloning in 23 languages at 44.1 kHz, built on Audio8-TTS-Preview-0.6b. It uses a DualAR design inspired by Fish Audio S2 Pro: a 24-layer slow transformer predicts one semantic token per audio frame (2,048 samples, 46 ms), a 4-layer fast transformer predicts the frame's 10 codec codebooks one at a time, and a neural codec turns the frames into audio. A reference recording and its exact transcript set the voice; the model also speaks without a reference.

This repository holds five LiteRT graphs (slow AR, fast AR, the codec decoder in two window sizes, the codec encoder), the source repository's tokenizer, two reference voices, a Python host loop for desktops and an Android sample app. The two autoregressive graphs hold int8 weights with float activations (dynamic-range quantization) and run on the CPU. In the app the codec decoder runs on the GPU; if the GPU's output fails a check at load, the same file runs on the CPU.

Quick start (Python, desktop)

pip install ai-edge-litert tokenizers soundfile scipy numpy huggingface_hub
hf download litert-community/Audio8-TTS-Realistic-0.6b --local-dir audio8r
cd audio8r
python audio8_tts_litert.py --model-dir . --text "Hello from LiteRT, fully on device." \
    --voice voices/en_librispeech_1272 --out hello.wav
# Japanese with the bundled Japanese voice
python audio8_tts_litert.py --model-dir . --text "ไปŠๆ—ฅใฏๅคฉๆฐ—ใŒ่‰ฏใ„ใฎใงใ€ๅ…ฌๅœ’ใพใงๆ•ฃๆญฉใซ่กŒใใพใ—ใ‚‡ใ†ใ€‚" \
    --voice voices/ja_funasr_example --out konnichiwa.wav
# clone your own voice from a clip of up to 10 s and its exact transcript
python audio8_tts_litert.py --model-dir . --register-voice me.wav --ref-text "exact transcript of me.wav" --voice-out voices/me
python audio8_tts_litert.py --model-dir . --text "This sentence is spoken in my voice." --voice voices/me --out me_out.wav
# without a reference voice
python audio8_tts_litert.py --model-dir . --text "This utterance does not use a reference voice." --out noref.wav

The host loop runs every graph on the CPU through the ai-edge-litert Interpreter (--threads, default 4). It uses the sampler of the source repository's generation_config.json (temperature 0.7, top-p 0.9, top-k 50, at most 512 frames) and the vendor's repetition-aware re-draw; --temperature, --top-p, --top-k, --max-new-tokens and --seed change them. The source model card's own example samples at temperature 0.8, top-p 0.95, top-k 50.

Android

The app under android/ (Kotlin, LiteRT 2.2.0 CompiledModel API) speaks a typed sentence in one of the two bundled voices, or in your own voice: "Record my voice (10 s)" records you reading a sentence it shows, and that sentence becomes the voice's transcript. Both AR graphs run on the CPU with 4 threads; the slow AR updates its KV cache in place. At load the app runs the GPU codec decoder on one test window and compares its output with the CPU's on the same file; the GPU decodes when the correlation is 0.99 or more, the CPU otherwise. A sentence may have up to 49 tokens. Build, install and file push steps: android/README.md. The app's code is under the MIT license (android/LICENSE).

Files

File Bytes Role
slow_ar_int8.tflite 551,890,704 Slow AR, 24 layers. Signatures prefill_256 (up to 256 prompt positions per call) and decode. The KV cache of 1,024 positions is 48 graph inputs and outputs. Returns the 4,097 logits the sampler picks from (4,096 semantic tokens and the end of speech) and the hidden state for the fast AR. Dynamic int8 weights (per channel), int8 embedding tables.
fast_ar_int8.tflite 67,780,320 Fast AR step, 4 layers, with a 10-position KV cache as graph input and output. Called 10 times per frame: position 0 takes the slow AR's hidden state, positions 1 to 9 the previous codebook token. Dynamic int8 weights, int8 embedding table.
codec_decoder_fp16_T128.tflite 261,633,152 Codec decoder for up to 128 frames (5.9 s) per call, float16 weights, rewritten for mobile GPUs (see Codec decoder on the GPU).
codec_decoder_fp16_T192.tflite 261,829,760 The same decoder for up to 192 frames (8.9 s) per call.
codec_encoder_fp16_10s.tflite 419,269,280 Codec encoder for voice registration: 10.03 s of 44.1 kHz audio to 10 ร— 216 codes.
tokenizer.json 12,217,872 The source repository's tokenizer (Qwen2 BPE with the semantic and role tokens), unchanged.
voices/en_librispeech_1272/, voices/ja_funasr_example/ 7,310 Two reference voices (codec codes and transcript): an English LibriSpeech dev-clean speaker (CC BY 4.0) and the Japanese example clip of FunAudioLLM/Fun-ASR-Nano-2512 (Apache-2.0).
audio8_tts_litert.py 13,303 Python host loop: prompt, chunked prefill, the vendor's sampler, the fast AR loop, windowed codec decode, voice registration.
android/ Android sample app with its own README and license.
LICENSE, NOTICE 11,357, 95 The source repository's files.
SHA256SUMS SHA-256 of every other file.

The codec checkpoint and the codec code are the same files in the Realistic and Preview source repositories, so the codec graphs come from litert-community/Audio8-TTS-Preview-0.6b: the encoder unchanged, the two decoders rewritten. The two voices are that repository's files.

Codec decoder on the GPU

As published in the Preview repository, the two codec decoders give a wrong output on the LiteRT GPU accelerator: on a Pixel 11 Pro and a Galaxy S26 (OpenCL, LiteRT 2.2.0 and 2.3.2) and on an Apple M4 Max (Metal), at the GPU's default precision (float16) and at float32. The decoders here carry three graph changes:

  • Before two MUL operators whose non-constant operand (computed at run time) has rank 2 and the output rank 3, a RESHAPE gives the operand the output's shape. The GPU accelerator lays such a rank-2 tensor out differently from a rank-3 one, and the MUL then multiplied the wrong elements, at float32 too. The RESHAPE keeps the values and their order.
  • Each RMSNorm squares its input scaled by 1/16, with epsilon scaled by 1/256 and the result scaled back. Unscaled, one square reaches 121,972.6 and the 1,024-channel sums of squares about 76,500, both more than float16 holds (65,504), and the output stops depending on the codes. Powers of two only move the exponent, so the CPU result is the same.
  • The attention mask's โˆ’1e9 becomes โˆ’30000. In float16 โˆ’1e9 is โˆ’inf, and in the 192-frame decoder a row with no finite score turned into NaN.

On an Apple M4 Max CPU, the rewritten decoders give the original's output byte for byte on all 32 test code sequences (15 for 128 frames, 17 for 192). On the GPUs of both phones at the default precision, their output correlates with that CPU output at 0.9998 or more on every speech test sequence, and the Pixel 11 Pro run in Accuracy decodes on the GPU. The rewrite is codec_gpu_rewrite.py in hf-to-litertlm (audio8_tts_work/).

Accuracy

The reference is the vendor's own code at revision 1e857568 in float32 on the CPU (PyTorch 2.12.1, transformers 4.57.6), with the sampler of generation_config.json and seeded draws. The test set has 30 sentences in six of the 23 languages: 6 English and 6 Japanese with a reference voice of the same language; 3 each in Arabic, Portuguese, Russian and Turkish without a reference, and 1 each of those four with the English reference voice; one English and one Japanese without a reference. Set B repeats set A with every sampling seed raised by 100,000. Each output was transcribed by whisper large-v3-turbo and compared with its text (errors counted in words, in characters for Japanese), compared with the reference clip by TitaNet-L (speaker cosine), and scored by UTMOS22.

Run Errors en / ja / ar / pt / ru / tr Speaker cosine: en / ja / other languages with the English voice UTMOS22 Ended by end of speech
Reference, set A 1 / 0 / 6 / 4 / 0 / 1 0.708 / 0.756 / 0.530 3.905 30 of 30
Reference, set B 3 / 0 / 4 / 2 / 1 / 1 0.712 / 0.756 / 0.558 3.964 30 of 30
This repository, Mac CPU, set A 6 / 0 / 4 / 0 / 0 / 0 0.709 / 0.764 / 0.574 3.904 30 of 30
This repository, Mac CPU, set B 2 / 0 / 8 / 0 / 0 / 1 0.706 / 0.762 / 0.566 3.911 30 of 30
This repository, Pixel 11 Pro app, set A 1 / 0 / 4 / 1 / 0 / 1 0.714 / 0.755 / 0.524 3.927 30 of 30
This repository, Pixel 11 Pro app, set B 1 / 0 / 4 / 2 / 0 / 0 0.698 / 0.746 / 0.571 3.960 30 of 30

The errors are out of 94 English words, 162 Japanese characters, 33 Arabic, 41 Portuguese, 31 Russian and 28 Turkish words per set; N below is that count. Two pass rules:

  • First rule, written before any of these numbers, on set A alone: per language, at most the reference's errors plus max(2, โŒˆ0.03 ร— NโŒ‰), and the speaker, UTMOS22 and end-of-speech checks of the next rule, taken against reference set A. The Mac CPU run failed it on English (6 errors against a bar of 4) and passed its other checks; the phone's set A errors are within its bars.
  • Rule applied here, written after that result and before any set B run of these graphs: per language, the errors of sets A and B together at most the reference's A and B errors plus max(2, โŒˆ0.03 ร— 2NโŒ‰) (bars: en 10, ja 10, ar 12, pt 9, ru 3, tr 4); on set B, each speaker group's mean cosine at least the reference's minus 0.05, the UTMOS22 mean at least the reference's minus 0.10, at most 21 of the 30 sentences more than 0.02 below the reference's UTMOS22 on the same sentence, and every sentence ended by end of speech. The Mac CPU run passes it (Arabic errors 12 against a bar of 12), and so does the phone (Arabic errors 8 against a bar of 12).

The Mac run used ai-edge-litert 2.2.0 (Interpreter, 4 threads) on an Apple M4 Max, the slow graph at a KV cache of 2,048 positions and the Preview's codec decoders. With a KV cache of 1,024 positions, the slow graph gives bit-identical logits and hidden states on the 38 prompts tested (the 30 above and 8 more), and the rewritten decoders give byte-identical CPU output. The phone run is the app with this repository's files, the codec on the GPU and the slow AR's KV cache in the app's ping-pong mode (two buffer sets, each call reading one and writing the other); updating that cache in place gives the same codes on both phones (the two speed-test sentences, every run).

Not shipped, measured on the same test: a blockwise int4 slow AR fails it on the Mac CPU (Turkish 8 errors against a bar of 4, Arabic 14 against 12, UTMOS22 3.834 against 3.864), and the Preview repository's int8 codec decoder lowers UTMOS22 from 3.904 to 3.690 on the same codes, on every one of the 30 sentences.

Performance

Measured on 2026-11-02 with LiteRT 2.2.0 on a Galaxy S26 (SM-S942Q, SM8850, Android 16) and a Pixel 11 Pro (Tensor G6, Android 17).

In the Android app

The files of this repository: both AR graphs on the CPU (4 threads), the slow AR's KV cache updated in place, the codec decoder on the GPU. Each sentence was spoken 6 times, 3 in each of two app processes.

Phone Sentence Speech Real-time factor, median (range) Text to samples Prompt prefill Slow AR per frame Fast AR per frame (10 calls) Codec decode
Galaxy S26 English 6.36 s, 137 frames 0.725 (0.697 to 1.021) 4.61 s 175 ms 8.66 ms 11.85 ms 1.45 s, one 192-frame call
Galaxy S26 Japanese 5.29 s, 114 frames 0.655 (0.646 to 0.752) 3.47 s 164 ms 8.62 ms 11.64 ms 0.95 s, one 128-frame call
Pixel 11 Pro English 5.48 s, 118 frames 0.884 (0.869 to 1.151) 4.85 s 327 ms 12.57 ms 16.01 ms 1.08 s, one 128-frame call
Pixel 11 Pro Japanese 5.11 s, 110 frames 0.895 (0.883 to 1.233) 4.57 s 329 ms 12.14 ms 15.91 ms 1.06 s, one 128-frame call
  • Sentences: "Our train departs early in the morning, so we should reach the station on time." (18 tokens, the English voice, seed 1004) and "ใ“ใฎ่ฃฝๅ“ใฏใ€ใ‚นใƒžใƒผใƒˆใƒ•ใ‚ฉใƒณใฎไธŠใง้Ÿณๅฃฐใ‚’ๅˆๆˆใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚" (17 tokens, the Japanese voice, seed 1001). Each value except the range is the median of the 6 runs.
  • Text to samples covers building the prompt, the prefill, the frame loop and the codec decode; playback starts after it.
  • With the same files and seed, the English sentence came out as 137 frames on the Galaxy S26 and 118 on the Pixel 11 Pro: the two phones' CPUs give slightly different logits for the int8 graphs, and sampling follows them. Each phone gave the same codes in all 6 runs.
  • On the Galaxy S26 the English sentence is longer than 128 frames, so it uses the 192-frame decoder. The app creates that decoder during the first such sentence of a process: the codec decode took 3.46 s and 2.27 s in those two runs, against 1.44 to 1.46 s in the others.
  • Load (creating the AR graphs and the 128-frame GPU decoder, and checking that decoder against the CPU): 10.7 and 11.9 s on the Galaxy S26, 19.3 and 26.5 s on the Pixel 11 Pro. Peak resident memory of the app process (VmHWM): 3.52 to 3.79 GB on the Galaxy S26 (3,438,428 to 3,698,872 kB), 3.27 to 3.31 GB on the Pixel 11 Pro (3,189,264 to 3,237,244 kB).
  • Both phones started each process at thermal status 0. The Galaxy S26 ended both processes at status 2 with CPU frequency caps; the Pixel 11 Pro ended its second process at status 1 with a cap, and that process's last English and Japanese runs are the two slowest values (1.151, 1.233).

One call of each graph

Our benchmark runner on the same phones, LiteRT 2.2.0 CompiledModel API. A value is the median time per call (writing the inputs, running, reading the first output back; the AR graphs' KV state stays on the device), with the number of timed calls in parentheses. CPU: XNNPACK, 4 threads. GPU: the LiteRT GPU accelerator (OpenCL) at its default precision (float16). NPU: the Galaxy S26's NPU, through graphs compiled ahead of time for SM8850 with QAIRT 2.47.

Graph and call Backend Galaxy S26 Pixel 11 Pro File shipped here
slow_ar_int8.tflite, decode CPU 8.83 ms (10), 9.05 ms (10) 17.09 ms (10), 17.02 ms (10) yes
The same slow AR with a KV cache of 2,048 positions, decode CPU 11.87 ms (10), 11.80 ms (10) 21.46 ms (10), 21.19 ms (10) no
The same, prefill_256 CPU 387.7 ms (3) 881.6 ms (3) no
fast_ar_int8.tflite, step CPU 0.963 ms (20) 1.962 ms (20) yes
Slow AR rewritten for the GPU (float16, KV 2,048), decode GPU 21.0 ms (10) 53.2 ms (10) no
The same, prefill_256 GPU 106.8 ms (5) 242.1 ms (5) no
Fast AR rewritten for the GPU (float16), step GPU 3.683 ms (20) 19.935 ms (20) no
The GPU slow AR compiled for the NPU, decode NPU 21.54 ms (10) not run no
The same, prefill_256 NPU 160.2 ms (5) not run no
The GPU fast AR compiled for the NPU, step NPU 2.306 ms (30) not run no
codec_decoder_fp16_T128.tflite GPU 981.3 ms (8) 1,214.2 ms (8) yes
codec_decoder_fp16_T192.tflite GPU 1,457.4 ms (8) 1,677.9 ms (8) yes
The Preview's float16 T128 decoder (the same output on the CPU) CPU 11,132.7 ms (5) 9,717.7 ms (5) no (the app's CPU fallback runs this repository's decoder, which gives the same output on the CPU; its CPU time is not in this table)
The Preview's int8 T128 decoder CPU 3,113.0 ms (5) 5,385.3 ms (8) no
The rewritten T128 decoder compiled for the NPU NPU 1,742.6 ms (8) not run no
codec_encoder_fp16_10s.tflite CPU 3,099.2 ms (5) 5,240.9 ms (5) yes

A frame takes one slow decode call and ten fast step calls. At a KV cache of 2,048 positions that is 11.87 + 10 ร— 0.963 ms on the Galaxy S26's CPU against 21.0 + 10 ร— 3.683 ms for the GPU-rewritten AR graphs (not shipped), and 21.46 + 10 ร— 1.962 ms on the Pixel 11 Pro's CPU against 53.2 + 10 ร— 19.935 ms. In a separate session on the Galaxy S26, the per-call medians of a frame added up to 44.7 ms for those graphs compiled for the NPU and 24.4 ms for the CPU graphs. So the AR graphs here run on the CPU, at a KV cache of 1,024 positions. The GPU prefill is faster than the CPU's (106.8 against 387.7 ms on the Galaxy S26); a GPU prefill with a CPU decode was not tried for this release. The NPU-compiled codec decoder is slower than the GPU and lowered UTMOS22 on all 14 of its test sentences.

Limitations

  • The prompt (reference transcript, reference codes and text) plus the generated frames must fit the slow graph's KV cache of 1,024 positions. The host loop refuses a longer prompt and stops when the cache is full; the app refuses a sentence over 49 tokens, and its longest prompt (49 tokens and a 10 s voice) is 308 positions, which leaves room for the 512-frame cap.
  • At most 512 frames (23.8 s of speech) per call by default; the host loop stops there without a message (an 80-token English text did, in 2 of 2 runs on the Mac, and lost its last sentence).
  • The codec decoder is causal, but its transformer works on 128-frame windows, so decoding in windows is not sample-exact against one offline decode of the whole utterance. The host loop and the app make one 128-frame call up to 5.9 s of speech, one 192-frame call up to 8.9 s, and beyond that 192-frame windows with 128 frames of left context.
  • Voice registration takes up to 10 s of reference audio (the encoder has one fixed length), and the transcript must match the audio.
  • The accuracy test covers 6 of the 23 languages (English, Japanese, Arabic, Portuguese, Russian, Turkish). The other 17 were not tested on these files.
  • Speed was measured on one Galaxy S26 and one Pixel 11 Pro with our runner and app; other devices were not measured. The Mac numbers are agreement checks, not speed.
  • From the source model card: quality varies by language; noisy reference audio or a mismatched transcript can reduce stability and speaker similarity; speech may contain pronunciation errors, repetitions, omissions or early stopping, so listen to it before using it. Obtain permission to clone a voice, and disclose synthetic audio where appropriate.

Reproduce

Source: Edge0/Audio8-TTS-Realistic-0.6b at revision 1e857568bfd4f02931aca3988ee773a44d2d26d3; the later commit on its main branch, 925bbd4c (2026-11-01), changes README.md only. The export, quantization and decoder rewrite commands are in the Audio8-TTS-Realistic-0.6b section of REPRODUCE.md in hf-to-litertlm, with the scripts under audio8_tts_work/. Run again on 2026-11-02, they rebuilt slow_ar_int8.tflite, fast_ar_int8.tflite and both codec decoders with the SHA-256 of the files here.

License

Apache-2.0, inherited from the source model by Edge0 (LICENSE, a copy of the source repository's file). Attribution is in NOTICE. The Android app under android/ is under the MIT license (android/LICENSE).

Changes from the original work. The slow and fast AR transformers were exported from the checkpoint's weights to LiteRT graphs with the KV cache as graph inputs and outputs, and their weights quantized to dynamic int8. The codec graphs come from the Preview conversion; the decoders' graphs were rewritten as described above. The tokenizer is unchanged. The host loop and the app port the vendor's prompt format and sampler.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for litert-community/Audio8-TTS-Realistic-0.6b

Quantized
(10)
this model