# Qwen3 Audiobook Converter Convert TXT, PDF, and EPUB files into audiobooks using the Qwen3-TTS voice model. This builds upon [WhiskeyCoder/Qwen3-Audiobook-Converter](https://github.com/WhiskeyCoder/Qwen3-Audiobook-Converter) adding more output files, metadata, generated cover art, transcription/speed/language options, better text cleanup, and clearer instructions. It also expects the qwen-tts server to be on different ports per model, so two server processes can run at once. ## Overview The converter sends text extracted from your books to a locally running Qwen3-TTS server and assembles the returned audio into a single audiobook file. - Input: `.txt`, `.pdf`, or `.epub` - Output: `.m4b`, `.mp3`, `.ogg`, or `.flac` - Output a single file or one per chapter - Automatic metadata (title/artist/album tags, chapter track numbers) and a generated cover - Two voice modes: - Custom voice: pre-built speakers - Voice clone: clone a voice from a `.wav` reference audio file ## Prerequisites - Python 3.12 - ffmpeg - Enough VRAM to run the 1.7B model (~6GB) ## Installation Install ffmpeg and your python environment of choice, e.g. conda. ```bash sudo pacman -S conda ffmpeg #Arch Linux sudo apt-get install ffmpeg #Debian, conda must be installed separately ``` ### Install Qwen3-TTS (Server) ```bash conda create -n qwen3-tts python=3.12 -y conda activate qwen3-tts pip install -U qwen-tts ``` ### Install the conversion script ```bash git clone https://git.historia.vg/git/qwen3-audiobook-converter cd qwen3-audiobook-converter pip install -r requirements.txt ``` ## Running the Qwen server and audiobook script The audiobook script talks to a Qwen3-TTS Gradio server that is run using `qwen-tts-demo`. Add `--no-flash-attn` if FlashAttention isn't installed (see below). The script expects the custom voice model and base model to be on different ports depending on which you're using. The Qwen model(s) will automatically download. Put your book files (epub, etc.) in the `input/` folder. Then run the script. The output goes to `output/`. ### Voice clone ```bash conda activate qwen3-tts qwen-tts-demo Qwen/Qwen3-TTS-12Hz-1.7B-Base --ip 127.0.0.1 --port 7861 ``` Then in another terminal: ```bash python audiobook.py --clone reference.wav ``` The reference `.wav` should be ~10-15 seconds (3 second minimum, 60 second maximum; ~15 seconds is ideal). Longer is **not** better. Whisper (`faster_whisper` or `whisper`) is used automatically to transcribe the reference audio. Without a Whisper backend it falls back to x-vector-only cloning. Override with `--transcription "What the .wav says"` or skip transcription with `--no-transcription`. ### Custom voice (i.e. built-in voice) ```bash conda activate qwen3-tts qwen-tts-demo Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice --ip 127.0.0.1 --port 7860 ``` ```bash python audiobook.py ``` Edit `converter/config.py` to change which built-in voice is used. ## Options | Flag | Description | | ----------------------------- | ------------------------------------------------------------------------------------------------ | | `--format {mp3,m4b,ogg,flac}` | Output format (default `m4b`). `m4b` uses AAC audio and has built-in chapters. | | `--clone ` | Reference audio (`wav`) for voice cloning. | | `--transcription "..."` | Override whisper auto-transcription with manual audio transcript. | | `--no-transcription` | Skip auto-transcription of the reference audio. | | `--speed ` | Playback speed, pitch-preserving (`1.0` = normal). A normal-speed copy is also output. | | `--single-file` | Merge all chapters into a single file (default: one file per chapter). `m4b` is always one file. | | `--language ` | Output language for the synthesized speech. Can add an accent even if the text is English. | ## FlashAttention for qwen-tts-demo server (optional) The server tries to use FlashAttention 2 by default, but `--no-flash-attn` works without it. On supported GPUs FlashAttention can give a modest speedup. 1. Build from source (takes absolutely forever). If you run out of memory, lower MAX_JOBS until you don't. ```bash conda activate qwen3-tts pip install ninja packaging psutil MAX_JOBS=4 pip install --no-build-isolation flash-attn ``` 2. Or pip install a prebuilt wheel matching your torch / CUDA / Python / CXX11-ABI combination: ```bash python -c "import torch; print(torch.__version__, torch.version.cuda, torch._C._GLIBCXX_USE_CXX11_ABI)" ``` Official wheels: https://github.com/Dao-AILab/flash-attention/releases (pick `cp312` + matching `cuX` + `torchX.Y` + `cxx11abiTRUE/FALSE`). Third-party wheels: https://mjunya.com/flash-attention-prebuild-wheels/ (hosted at https://github.com/mjun0812/flash-attention-prebuild-wheels). ## Tips Transcription affects the output a lot. Whisper is okay, but does not give perfect transcription. A manual transcription passed via `--transcription` is better. Manual transcription, imperfect whisper transcription, and `--no-transcription` each provide different results. Usually the most accurate transcription is the best, but sometimes `--no-transcription` can produce a flat tone that might be preferable for certain voices. Even tiny amounts of pause between phrases in the sample audio can have a big impact. Try increasing or decreasing them. Setting `--language` to the "wrong" language for English text can produce an accent. It is not as strong as cloning a voice with the desired accent. The built-in "custom" voices are mediocre. I get *much* better results cloning anything. ## License MIT ## Credits - [Qwen3-Audiobook-Converter](https://github.com/WhiskeyCoder/Qwen3-Audiobook-Converter) by WhiskeyCoder. - [Qwen3-TTS](https://github.com/QwenLM/Qwen3-TTS) voice model.