Qwen3-TTS-12Hz-0.6B-Base: voice-cloning TTS in 10 languages.
Two files make one model, as with llama.cpp's multimodal projectors: the model file is the text-to-speech LM backbone, run by llama.cpp; the codec file holds the audio side (decoder / vocoder, speaker encoders and the adaptor between the two), run by codec.cpp. The runtimes below wire the two graphs together, on CPU or GPU (CUDA, Vulkan, Metal), fully offline.
Every run needs one model file + one codec file from this repo.
--backbone |
--model (codec) |
Total | |
|---|---|---|---|
| Recommended | qwen3-tts-0.6b-q8_0.gguf |
codec-q8_0.gguf |
1.9 GB |
| Smallest | qwen3-tts-0.6b-q4_k_m.gguf |
codec-q4_k_m.gguf |
1.7 GB |
| Best quality | qwen3-tts-0.6b-f16.gguf |
codec-f16.gguf |
2.6 GB |
| Phones (smallest download and RAM) | qwen3-tts-0.6b-q4_0.gguf |
codec-q8_0-lm-q4_k_m.gguf |
1.06 GB |
| File | Size |
|---|---|
codec-f32.gguf |
1.7 GB |
codec-q5_k_m.gguf |
1.3 GB |
qwen3-tts-0.6b-bf16.gguf |
1.2 GB |
qwen3-tts-0.6b-f32.gguf |
2.4 GB |
qwen3-tts-0.6b-q2_k.gguf |
296 MB |
qwen3-tts-0.6b-q3_k_l.gguf |
368 MB |
qwen3-tts-0.6b-q3_k_m.gguf |
347 MB |
qwen3-tts-0.6b-q3_k_s.gguf |
323 MB |
qwen3-tts-0.6b-q4_0.gguf |
382 MB |
qwen3-tts-0.6b-q4_1.gguf |
409 MB |
qwen3-tts-0.6b-q4_k_s.gguf |
383 MB |
qwen3-tts-0.6b-q5_0.gguf |
437 MB |
qwen3-tts-0.6b-q5_1.gguf |
464 MB |
qwen3-tts-0.6b-q5_k_m.gguf |
444 MB |
qwen3-tts-0.6b-q5_k_s.gguf |
437 MB |
qwen3-tts-0.6b-q6_k.gguf |
495 MB |
codec-q8_0-lm-q4_k_m.gguf: the codec file with a quantized LM adaptorIn the other codec-*.gguf files the quantization in the name applies to the audio codec only; the LM adaptor
(lm.* tensors: talker codec embeddings, the 151936 x 2048 text embedding, text projection and depth decoder) is
F16, about 960 MB of the 1.29 GB. This file stores the adaptor's weight matrices as Q4_K_M (norms and biases BF16)
and the codec as Q8_0: 682 MB (682,225,248 bytes, sha256
c5e8e7f5160b7d1df0b78facf6b0d726e14e089f79dc5f1ce38e272c6c0a75a0). It was made for a phone app (Live
Translate's voice-cloned playback) and tested there on a Pixel 7 Pro (Tensor G2) with qwen3-tts-0.6b-q4_0.gguf:
synthesis took 4.2x the speech duration (5.4-5.7x with codec-q4_k_m.gguf, measured in a separate run), ~600 MB
less RAM; Whisper large-v3-turbo read back a 30-character Chinese test sentence with 4 characters wrong (a cloned
English voice speaking Chinese). No side-by-side listening comparison with the F16-adaptor files was done.
Converted with codec.cpp 3de7df1 from
Qwen/Qwen3-TTS-12Hz-0.6B-Base @ 5d839924:
python scripts/convert-to-gguf.py --checkpoint-path Qwen3-TTS-12Hz-0.6B-Base/speech_tokenizer \
--lm-source Qwen3-TTS-12Hz-0.6B-Base --outtype F16 --quantization Q8_0 \
--lm-outtype F16 --lm-quantization Q4_K_M -o codec-q8_0-lm-q4_k_m.gguf
Use it like any other codec file: --model codec-q8_0-lm-q4_k_m.gguf with any of the backbone files.
With codec.cpp's tts-cli (build it; it bundles llama.cpp), then:
hf download BricksDisplay/Qwen3-TTS-12Hz-0.6B-GGUF qwen3-tts-0.6b-q8_0.gguf codec-q8_0.gguf --local-dir Qwen3-TTS-12Hz-0.6B
./build/tts-cli synthesize --backbone Qwen3-TTS-12Hz-0.6B/qwen3-tts-0.6b-q8_0.gguf --model Qwen3-TTS-12Hz-0.6B/codec-q8_0.gguf \
--ref-audio my_voice.wav --text "Hello, nice to meet you." --output out.wav
All tts-cli options (voices, voice cloning, sampling, GPU) are described in the codec.cpp README.
The codec_cpp package runs the same pipeline (it builds codec.cpp with its
bundled llama.cpp, so it needs CMake and a C++ compiler):
pip install "codec-cpp @ git+https://github.com/mybigday/codec.cpp" huggingface_hub soundfile
import codec_cpp, soundfile
from huggingface_hub import hf_hub_download
tts = codec_cpp.TTS(hf_hub_download("BricksDisplay/Qwen3-TTS-12Hz-0.6B-GGUF", "qwen3-tts-0.6b-q8_0.gguf"),
hf_hub_download("BricksDisplay/Qwen3-TTS-12Hz-0.6B-GGUF", "codec-q8_0.gguf"))
audio, sr = tts.synthesize("Hello, nice to meet you.", ref_audio="my_voice.wav")
soundfile.write("out.wav", audio, sr)
tts.voices() lists the builtin voices; ref_audio= clones a voice where the
model supports it; tts.stream(text) yields audio as it is generated. More in
the Python docs.
llama.rn loads the same two files on iOS and Android:
const ctx = await initLlama({ model: 'qwen3-tts-0.6b-q8_0.gguf', embedding: true })
await ctx.initVocoder({ path: 'codec-q8_0.gguf' })
const { prompt, grammar, embedding, flow } = await ctx.getFormattedAudioCompletion({
prompt: 'Hello world',
speaker: await ctx.createSpeaker({ refAudio, refAudioSampleRate }), // required: no builtin voice
})
const result = await ctx.completion({ prompt, grammar, embedding })
const pcm = flow === 'continuous_embd'
? await ctx.decodeAudioEmbeddings(result.embeddings, result.embedding_dim)
: await ctx.decodeAudioTokens(result.audio_tokens)
Voice cloning, saved voices and per-model notes: llama.rn TTS docs.
The model files carry the recommended sampling as llama.cpp's
general.sampling.* metadata, the settings of the original model's generation_config.json;
tts-cli, tts-server, llama.rn and any llama.cpp host apply them unless
you set your own.
| Setting | Value | tts-cli flag |
|---|---|---|
| temperature | 0.9 | --temp 0.9 |
| top-k | 50 | --top-k 50 |
| top-p | 1.0 (off) | --top-p 1.0 |
| min-p | 0 (off) | --min-p 0.0 |
| repetition penalty | 1.05 | --repeat-penalty 1.05 |
| repetition window | 4096 (every generated token) | --repeat-last-n 4096 |
| sampler order | penalties → temperature → top-k → top-p | --samplers "penalties;temperature;top_k;top_p" |
Every codebook of a frame is sampled with these settings; the repetition penalty applies to the first codebook only, as in the original model. Keep it: without it a cloned voice with a reference transcript can loop on the smaller quantizations instead of ending.
This is the Base model: it has no builtin voice, so every run needs
--ref-audio with a short, clean clip of the voice to use (any sample rate).
Save it with --save-speaker to reuse it without the clip.
apache-2.0, the same as the original model.