|
| 1 | +# Qwen3-TTS C++ backend |
| 2 | + |
| 3 | +This backend runs Qwen3-TTS GGUF models through |
| 4 | +[qwentts.cpp](https://github.com/ServeurpersoCom/qwentts.cpp). It supports |
| 5 | +24 kHz speech generation, streaming, named speakers, voice design, and |
| 6 | +reference-audio cloning depending on the model variant. |
| 7 | + |
| 8 | +## Gallery models |
| 9 | + |
| 10 | +The following Base models accept LocalAI Voice Library profiles: |
| 11 | + |
| 12 | +- `qwen3-tts-cpp` |
| 13 | +- `qwen3-tts-cpp-0.6b-base-q4` |
| 14 | +- `qwen3-tts-cpp-1.7b-base` |
| 15 | +- `qwen3-tts-cpp-1.7b-base-q4` |
| 16 | + |
| 17 | +Gallery models containing `customvoice` or `voicedesign` implement those Qwen |
| 18 | +modes instead and are not advertised as raw reference-audio models. |
| 19 | + |
| 20 | +Install a Base model with: |
| 21 | + |
| 22 | +```bash |
| 23 | +local-ai models install qwen3-tts-cpp |
| 24 | +``` |
| 25 | + |
| 26 | +## Model configuration |
| 27 | + |
| 28 | +Base filenames are detected automatically. Set `tts.voice_cloning` only when a |
| 29 | +verified private conversion has a name that does not identify it as a Base or |
| 30 | +VoiceClone model: |
| 31 | + |
| 32 | +```yaml |
| 33 | +name: private-qwen-voice |
| 34 | +backend: qwen3-tts-cpp |
| 35 | +parameters: |
| 36 | + model: qwen-private/talker.gguf |
| 37 | +known_usecases: |
| 38 | + - tts |
| 39 | +tts: |
| 40 | + voice_cloning: true |
| 41 | + audio_path: voices/default-reference.wav # optional model-wide fallback |
| 42 | +``` |
| 43 | +
|
| 44 | +The tokenizer GGUF is auto-discovered when its filename contains `tokenizer` |
| 45 | +and it is stored beside the talker. Otherwise set |
| 46 | +`options: ["tokenizer:qwen-private/tokenizer.gguf"]`. |
| 47 | + |
| 48 | +`tts.voice_cloning: false` removes a model from Voice Library compatibility |
| 49 | +results and rejects saved `localai://voice-profiles/...` references. It does |
| 50 | +not disable Qwen's named-speaker or VoiceDesign modes. Setting it to `true` |
| 51 | +cannot add cloning to a backend that lacks LocalAI's reference-audio contract. |
| 52 | + |
| 53 | +Request precedence is: a request `voice`, then `tts.voice`, then |
| 54 | +`tts.audio_path`. A saved profile supplies its private WAV and exact transcript |
| 55 | +for that request without changing the model YAML. |
| 56 | + |
| 57 | +## API example |
| 58 | + |
| 59 | +Create or select a profile in **Operate → Voice Library**, then pass its stable |
| 60 | +URI to either speech endpoint: |
| 61 | + |
| 62 | +```bash |
| 63 | +curl http://localhost:8080/v1/audio/speech \ |
| 64 | + -H 'Content-Type: application/json' \ |
| 65 | + -d '{ |
| 66 | + "model": "qwen3-tts-cpp", |
| 67 | + "input": "This request uses a saved reference voice.", |
| 68 | + "voice": "localai://voice-profiles/PROFILE_ID" |
| 69 | + }' \ |
| 70 | + --output speech.wav |
| 71 | +``` |
| 72 | + |
| 73 | +## Native end-to-end test |
| 74 | + |
| 75 | +The labeled test loads real GGUFs, synthesizes speech, streams audio, and |
| 76 | +exercises cloning with a generated 24 kHz reference WAV: |
| 77 | + |
| 78 | +```bash |
| 79 | +make -C backend/go/qwen3-tts-cpp qwen3-tts-cpp |
| 80 | +
|
| 81 | +QWEN3TTS_MODEL=/path/to/qwen-talker-0.6b-base-Q8_0.gguf \ |
| 82 | +QWEN3TTS_CODEC=/path/to/qwen-tokenizer-12hz-Q8_0.gguf \ |
| 83 | +QWEN3TTS_LIBRARY=backend/go/qwen3-tts-cpp/libgoqwen3ttscpp-fallback.so \ |
| 84 | + go test ./backend/go/qwen3-tts-cpp -ginkgo.label-filter=e2e |
| 85 | +``` |
0 commit comments