Intermediate 10 minQwen

Qwen3-TTS locally: text-to-speech and voice cloned

Qwen3-TTS is a family of speech synthesis models released as open weights by Alibaba's Qwen team under the Apache 2.0 license. It fits in a few gigabytes, speaks French among roughly ten languages, and can do three distinct things: read text with a predefined voice, invent a voice from a description, or reproduce a timbre from a short audio clip. This guide shows how to run Qwen3-TTS locally with the official Python package, which variant to choose, and under what conditions voice cloning remains acceptable. No quality or speed measurements are provided here: we did not conduct any, and you should consult the official sources for current versions.

By Thomas P.·Update 2026-10-15·Tested on Windows, macOS, and Linux

#Why Qwen3-TTS instead of a cloud voice

Online speech synthesis services sound good, but every sentence you send them leaves your machine, is billed by the character, and depends on an account that could be shut down. For an internal document reader, a home automation assistant, or an application prototype, a voice that runs entirely locally removes all three dependencies at once.

Until now, two families had coexisted in the open ecosystem. On one side were lightweight models such as Piper and Kokoro: fast on the CPU, with fixed voices and no cloning. On the other were larger, more expressive models, often focused on English and Chinese. Qwen3-TTS sits between the two: compact weights, but an LLM-style architecture that accepts natural-language style instructions, with explicit French support from launch.

The family's distinctive feature is that it is split into three behaviors rather than being a single do-everything model. You download only the variant that matches your needs, which matters on an 8 or 12 GB GPU shared with a text LLM.

i
What this guide does not do
It does not compare voice quality between Qwen3-TTS, Kokoro, or Voxtral, and it provides no throughput figures. We did not run a reproducible test; such a comparison would require a protocol, documented hardware, and published audio files. The guide relies on the QwenLM/Qwen3-TTS GitHub repository and the organization's Hugging Face model cards Qwen, which you should review when you install: model names and Python API parameters change over time.

#Available models: Base, CustomVoice, VoiceDesign

Local Social Media Kit

Create social videos, carousels and a LinkedIn PDF locally with Qwen3-TTS, animated captions, scripts and checklists.

  • Lifetime online access
  • PDF + files
  • Refunded within 30 days

At launch, the family includes two model sizes, 0.6 and 1.7 billion parameters, offered in three functional variants, plus a shared audio tokenizer. Hugging Face identifiers follow the pattern Qwen/Qwen3-TTS-12Hz-<size>-<variant>. “12Hz” refers to the audio codec frequency: the model produces twelve acoustic-token frames per second of speech, which explains its computational frugality compared with denser codecs.

CustomVoice
Predefined voices, each with its own timbre and native language, controllable with a style instruction (“speak slowly, reassuring tone”). Choose this variant to read text without having to think about the voice. Available in 0.6B and 1.7B.
VoiceDesign
You describe the desired voice in natural language (age, perceived gender, energy, accent, emotion), and the model invents it. No reference recording means no real person is imitated. Available in 1.7B.
Base
Cloning from an audio clip a few seconds long and its transcription. This is the most powerful variant and the only one that raises a consent issue, discussed below. Available in 0.6B and 1.7B.
Tokenizer-12Hz
The audio codec that encodes and decodes speech. The variants above download it automatically; you only need to handle it for advanced use cases.

The advertised languages are Chinese, English, Japanese, Korean, German, French, Russian, Portuguese, Spanish, and Italian, plus several Chinese dialects. The language parameter accepts either an explicit name such as “French” or “Auto” to let the model detect the text’s language. For French, forcing the value prevents pronunciation hesitation with proper names and anglicisms.

→
Which size to choose
bfloat16 weights use approximately two bytes per parameter: about 1.2 GB for the 0.6B version and 3.4 GB for the 1.7B version, excluding the codec and working memory. This is a calculation, not a measurement. If your GPU already hosts a text model, the 0.6B version leaves more room; if speech synthesis is the primary use case, the 1.7B version is the one the Qwen team highlights in its examples and the only one that offers VoiceDesign.

#Hardware and software requirements

System
Linux x86_64 is the platform documented by the repository. macOS and Windows are possible, with the caveats detailed in the dedicated section.
GPU
A NVIDIA card with CUDA is the intended path. A RTX 3060 12 GB is more than enough for the 1.7B model alone; CPU execution works for testing a sentence but is not suitable for interactive use.
Python
The repository recommends Python 3.12 in a dedicated virtual environment. Avoid installing into the system environment or another audio project's environment: the PyTorch and transformers versions required by the package may conflict.
Disk space
Allow a few gigabytes for each downloaded variant, in the Hugging Face cache (~/.cache/huggingface by default).
Network
Only on the first launch, to download the weights. After that, everything works offline.

One final prerequisite is not technical: if you plan to use the Base variant, have a recording whose voice you have the right to use. Your own voice is the simplest and safest case for learning.

#Step 1: install the qwen-tts package

The official Python package is called qwen-tts on PyPI and is imported as qwen_tts. It pulls in PyTorch and transformers as dependencies. The installation below uses a standard virtual environment; conda works just as well if that's what you normally use.

Terminal
# Environnement isolé
python3.12 -m venv ~/qwen3-tts
source ~/qwen3-tts/bin/activate
pip install --upgrade pip

# Paquet officiel
pip install -U qwen-tts

# Lecture et écriture de fichiers audio pour les exemples
pip install soundfile

The repository optionally supports FlashAttention 2 to speed up inference on recent GPUs. Compiling it takes a long time and fails with some CUDA/PyTorch combinations. It is not required: without it, the model uses PyTorch's standard attention. Install it only after everything else works.

Terminal (optional)
pip install -U flash-attn --no-build-isolation

Make sure that the import passe is installed and that PyTorch can see your GPU before going any further.

Terminal
python -c "import torch, qwen_tts; print(torch.__version__, torch.cuda.is_available())"
!
Audio system dependencies
Python audio libraries sometimes rely on system tools (libsndfile for soundfile, sox or ffmpeg depending on the package version). If an import fails because a library is missing, install it with your package manager (apt, dnf, pacman) and try again. The error message always names the expected library.

#Step 2: generate a first sentence in French with Qwen3-TTS

The CustomVoice variant is the most straightforward for a first try: no reference recording and no description to write. Load the model, choose a voice from the repository's list, and provide the text and language. The first call downloads the weights from Hugging Face.

premiere_voix.py
import torch
import soundfile as sf
from qwen_tts import Qwen3TTSModel

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice",
    device_map="cuda:0",
    dtype=torch.bfloat16,
)

wavs, sr = model.generate_custom_voice(
    text="Bonjour, ceci est un test de synthèse vocale locale avec Qwen3-TTS.",
    language="French",
    speaker="Ryan",
    instruct="Ton calme et posé, débit modéré.",
)

sf.write("sortie_custom_voice.wav", wavs[0], sr)
print("Fichier écrit à", sr, "Hz")

Three parameters deserve an explanation. The speaker field selects one of the predefined voices; the exact list, including the native language and description of each timbre, appears in the README and on the Hugging Face page for the CustomVoice model. All these voices can speak French, but each retains an accent consistent with its native language, which is an aesthetic choice, not a defect. The instruct field is a natural-language style instruction: emotion, rhythm, and intent. It is optional. Finally, the function returns a list of waveforms and the sampling rate, allowing you to process multiple texts in a batch.

Batch generation
textes = [
    "Première phrase à lire.",
    "Deuxième phrase, avec une intonation différente.",
]
wavs, sr = model.generate_custom_voice(
    text=textes,
    language=["French", "French"],
    speaker=["Ryan", "Serena"],
    instruct=["Neutre.", "Enjouée, un peu plus rapide."],
)
for i, w in enumerate(wavs):
    sf.write(f"lot_{i}.wav", w, sr)
→
On a shared GPU with Ollama
Ollama keeps its models loaded in memory for the duration set by OLLAMA_KEEP_ALIVE. If speech synthesis fails with a CUDA out-of-memory error even though the card should be sufficient, unload the text model during the test, or load Qwen3-TTS in 0.6B. A 7B model in Q4_K_M already occupies about 5 GB.

#Step 3: design a voice from a description

VoiceDesign addresses a common need: you want a voice that is not in the list, without imitating anyone. Describe the result in one or two sentences, and the model produces a timbre consistent with the instruction. This is also the variant to prefer for a product, since no real voice is reproduced.

voice_design.py
import torch
import soundfile as sf
from qwen_tts import Qwen3TTSModel

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-1.7B-VoiceDesign",
    device_map="cuda:0",
    dtype=torch.bfloat16,
)

wavs, sr = model.generate_voice_design(
    text="Votre rendez-vous est confirmé pour demain à quatorze heures.",
    language="French",
    instruct="Voix féminine d'une quarantaine d'années, grave et chaleureuse, "
             "articulation nette, rythme lent, sans emphase.",
)

sf.write("sortie_voice_design.wav", wavs[0], sr)

Descriptions work better when they specify acoustic characteristics (pitch, speed, energy, clarity) than when they use metaphors. “Late-night radio host voice” produces less stable results than “deep, slow, hushed male voice.” A voice designed this way is not fixed from one call to the next: if you need the same voice across hundreds of sentences, generate an initial clip you like, then use it as a reference with the Base variant. You are then cloning a synthetic voice, which raises no consent issues.

#Step 4: clone a voice with its owner's consent

The Base variant reproduces a timbre from a short audio clip and its transcription. A few seconds of clean speech are enough to produce a recognizable voice. This is the most impressive function in the family, and the one that requires the most rigor before you even write a line of code.

!
Consent: the rule, not the option
A person's voice is an attribute of their personality, protected in France under privacy law (article 9 of the Civil Code), and a voice recording is personal data under the GDPR. Cloning someone else's voice without their explicit, documented consent exposes you to civil liability, and to criminal liability if the use is deceptive. The European AI Act also requires, since August 2026, that you disclose when audio content is artificially generated or manipulated. Clone your own voice, the voice of someone who has given written consent for a specific use, or a synthetic voice created with VoiceDesign. Nothing else.

To prepare the reference, record a five- to ten-second sentence in a quiet place, with no background music or reverberation, speaking naturally. Transcribe it word for word, including punctuation: this is the text the model aligns with the audio to learn the timbre. A mono WAV file is the safest format.

clonage.py
import torch
import soundfile as sf
from qwen_tts import Qwen3TTSModel

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-1.7B-Base",
    device_map="cuda:0",
    dtype=torch.bfloat16,
)

wavs, sr = model.generate_voice_clone(
    text="Voici une phrase que je n'ai jamais prononcée, lue avec ma propre voix.",
    language="French",
    ref_audio="ma_reference.wav",
    ref_text="Bonjour, je m'appelle Thomas et j'enregistre cette phrase pour tester le clonage.",
)

sf.write("sortie_clone.wav", wavs[0], sr)

The repository documents two advanced uses that are useful in production. First, you can precompute a “voiceprint” of the reference voice once and reuse it for every sentence without reloading the audio: that is what you need for a document reader or an assistant that speaks continuously. Second, there is a mode that uses only the speaker’s voiceprint, without the transcript—faster but less faithful. The exact names of these parameters are listed in the README; they changed between the package’s early versions, which is why it is important to read the installed documentation rather than a dated tutorial.

What improves the result
A clean reference, an exact transcript, a forced language instead of “Auto,” and punctuated target text (the model breathes at commas and periods).
What degrades it
Background noise, a reference that is too short or too long, whispering, an approximate transcription, and numbers written as numerals instead of words in ambiguous cases.
What to document
Who gave consent, for what use, on what date, and where the recording is stored. A simple text file next to the reference is enough for a personal project; a proper processing record is needed for professional use.

#Step 5: web interface and server

The package installs a Gradio demo from the command line, which is convenient for trying voices and prompts without writing a script. It loads a model at startup and exposes a local web page.

Terminal
qwen-tts-demo Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice --ip 127.0.0.1 --port 8000

Keep the listening address on 127.0.0.1 until the machine is protected: Gradio does not authenticate anyone by default, and exposing a voice-cloning interface on a network is not harmless. If you need to access it from another machine, use an SSH tunnel or an authenticated reverse proxy, as you would for any local service.

For application integration, the Qwen team recommends vLLM-Omni, vLLM's multimodal extension, which can serve the model through an HTTP API with streaming output (audio starts playing before generation finishes). This is the approach to investigate for a voice assistant where latency matters; for batch generation of audio files, the direct Python script is sufficient and avoids an extra layer.

#Apple Silicon and Windows: community approaches, identified as such

The official repository documents Linux with CUDA. On other platforms, the following comes from the community ecosystem: we have not verified these paths ourselves, and their status changes from month to month.

Mac Apple Silicon
The official package is built on PyTorch; you can try device_map="mps" with dtype float16 or float32 (bfloat16 is not always supported by MPS), while expecting some unsupported operations. The most natural path on Mac is an MLX port: the community project mlx-audio has announced support for Qwen3-TTS. Check its repository to see which variants are covered and how mature the support is before committing to it.
Native Windows
PyTorch with CUDA normally installs without issue, but FlashAttention is difficult to compile on Windows: leave it out and use the default attention implementation. Some audio dependencies require system binaries (ffmpeg in the PATH, for example). Third-party “one-click” installers are available; they often bundle a pinned package version, so read what they install.
Windows through WSL2
This is the approach closest to the official documentation: an Ubuntu distribution under WSL2 with the recent NVIDIA Windows driver can see the GPU and follow this guide's commands exactly. The tradeoff is an extra layer and slightly slower access to Windows files.
i
Quantized formats
Unlike text models, there is no official Ollama or GGUF path for Qwen3-TTS: speech synthesis uses an audio codec that llama.cpp does not support as-is. Community conversions may appear; treat them as experiments until the QwenLM repository references them.

#Troubleshooting

CUDA out of memory while loading
Another process is using the GPU (Ollama, a browser with hardware acceleration, or a Stable Diffusion session). Check with nvidia-smi, free up memory, or switch to the 0.6B variant.
Download interrupted or repository not found
Check the model's exact identifier on the Hugging Face page for the organization Qwen; variant names may have changed since this was written. A partial download resumes when you rerun the script.
import liée error in transformers or torch
Version conflict with another project installed in the same environment. Re-create a clean virtual environment and install only qwen-tts and soundfile.
Strange French pronunciation
Force language="French" instead of “Auto,” spell out numbers when pronunciation is ambiguous, and use punctuation. Acronyms are easier to read when separated by periods or spaces.
The clone does not sound like the reference
Re-record the reference in a quiet environment, check the transcript word for word, and try the 1.7B model if you were using 0.6B. A clip that is too long does not help: a few seconds of clear speech are better than a noisy minute.
Silence or empty file
Make sure you write wavs[0], not the entire list, and that the sampling rate returned by the model is the one passed to soundfile.
Extremely slow performance
The model is probably running on the CPU. The torch.cuda.is_available() test in step 1 must return True; otherwise, reinstall PyTorch with the CUDA version corresponding to your driver.

#Go further

Qwen3-TTS covers the “speaking” part of a local voice pipeline. For the other half—the understanding side—and to compare it with lighter synthesis models, the site already covers several related topics. The package and model versions cited in this guide are those in the QwenLM/Qwen3-TTS repository at the time of writing; in case of discrepancies, the repository and Hugging Face model cards are authoritative.

Kokoro TTS: a convincing, lightweight local voice
The 82-million-parameter model that speaks faster than real time on a CPU, without cloning. The right choice when frugality matters more than expressiveness. https://quelllm.fr/guide/kokoro-tts-voix-locale
100% local voice assistant: Whisper + Ollama + Piper
The complete pipeline: listening, reasoning, spoken response. Qwen3-TTS can replace Piper for synthesis if your GPU can handle it. https://quelllm.fr/guide/assistant-vocal-local-whisper-piper
Voxtral 4B TTS model card
The other recent open speech synthesis model from Europe, included to place Qwen3-TTS in context without a numerical comparison. https://quelllm.fr/modele/voxtral-4b-tts
Did this guide help you?

Feedback, an error, or a clarification? Let us know—it improves the guide for everyone.