# 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 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 conda, e.g. ```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-TTS server The converter 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 model(s) will automatically download. ### Custom voice ```bash conda activate qwen3-tts qwen-tts-demo Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice --ip 127.0.0.1 --port 7860 ``` ### Voice clone ```bash conda activate qwen3-tts qwen-tts-demo Qwen/Qwen3-TTS-12Hz-1.7B-Base --ip 127.0.0.1 --port 7861 ``` ## Converting books Put your book files (epub, etc.) in the `input/` folder. Then run the script. The output goes to `output/`. ### Custom voice ```bash python audiobook.py ``` Edit `converter/config.py` to change which built-in voice is used. ``` CUSTOM_VOICE_SPEAKER = "Vivian" # Serena, Vivian, Uncle_Fu, Aiden, Ono_Anna, Sohee, Eric, Dylan CUSTOM_VOICE_LANGUAGE = "English" CUSTOM_VOICE_INSTRUCT = "Speak naturally and clearly, as if reading a dramatic book to an adult audience." ``` ### Voice clone ```bash python audiobook.py --clone path/to/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 "..."` or skip transcription with `--no-transcription`. ## Options | Flag | Description | | ----------------------------- | ------------------------------------------------------------------------------------------ | | `--clone ` | Reference audio (WAV) for voice cloning. Passing this flag switches to voice clone mode. | | `--transcription "..."` | Override whisper auto-transcription with your own manual reference 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. | | `--format {mp3,m4b,ogg,flac}` | Output format (default `m4b`). `m4b` uses AAC audio and has built-in chapters. | | `--single-file` | Not m4b: Merge all chapters into a single file (default: one file per chapter). | | `--language ` | Output language for the synthesized speech. Can add an accent even if the text is English. | ## Running tests ```bash python -m unittest discover -s tests -t . ``` ## FlashAttention (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 `--transcription` is usually 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. 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. ## 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.