A self-hosted web app that turns ebooks into narrated, chaptered audiobooks, lets you read along word by word on any device, and makes new narrator voices. It can be one Docker host, or an always-on server for your library plus a Windows PC with a GPU that does the heavy lifting.
- Ebooks in, audiobooks out: EPUB, PDF, Word and a dozen other formats in. M4B with chapters, tags and cover out, ready for Audiobookshelf.
- Read along: a player that highlights every word as it's spoken. Each listener keeps their own place across phone, tablet and browser. It also works for audiobooks you already have: Whisper writes down their text.
- Your own voices (optional): clone a narrator from a clip with Qwen3-TTS, or train a Piper voice that needs no GPU to read a book. You listen to samples and pick one by ear.
What's done, in progress and planned: ROADMAP.md.
Nothing in this repository is a book, a recording or a voice. Every voice model is downloaded at first use from the project that publishes it (see Voices and models).
- Features
- Quick start
- A server plus GPU PCs
- Making voices
- Cloned voices: the clone server
- HTTPS
- Configuration
- How it works
- Voices and models
- Development
- License
| Formats in | EPUB, PDF (with a text layer), TXT (Project Gutenberg aware), DOCX, ODT, RTF, HTML, Markdown, FB2, reStructuredText, Org, LaTeX and more through pandoc, DOC through antiword. MOBI, AZW3 and other Kindle formats through Calibre (no DRM). |
| Chapters | Found from the table of contents, PDF bookmarks or headings. Front and back matter (copyright, contents, "also by") is turned off by default. Every chapter can be renamed, turned on or off, and its text edited. |
| Book details | Title, author, series, number, year, cover and more are read from the file. Missing details can be looked up online: Open Library, Audible, and Google Books with a free API key. Each result is scored against the file, and you pick when it's unclear. |
| Voices | 11 Kokoro voices and 6 Piper voices (US and UK English), one with several moods, plus voices you make. Voice, mood and speed are set per book or for many at once. Compare voices plays the same saved 10-second passage in each. |
| Formats out | M4B (the default), M4A, MP3, Opus or FLAC, with chapter markers, tags (narrator, series, genre and more) and the cover. Files go into an Author/Series/1 - Title/Title.m4b layout that Audiobookshelf reads, or a flat one. |
| Speed | Chapters are cut into small units that every worker voices in parallel, longest first, and several books share the workers. Units are cached under a hash of voice, speed and text, so a restart, a cancel or a text edit only re-voices what changed. Runs on the CPU, or on an NVIDIA GPU. |
| Narration check | Whisper transcribes a sample of every chapter and compares it with the text. A misread chapter is flagged, and Redo voices only the flagged chapters again. |
| Versions | Each voice a book has been made in is kept. Switching back to one takes seconds, and Read along changes voice on the same word. |
| Free books | Find a free book searches Project Gutenberg's 70,000+ public-domain books and adds one with a click. It keeps to their terms of use: Forge downloads their catalog once a week and searches it itself, fetches a book only when you add it (at most 50 a day), and only if its record says public domain in the USA. The book keeps its Project Gutenberg license. GUTENBERG=false hides it. |
| Read before voicing | A book that isn't voiced yet opens in the reader as text, with Voice it now above it. |
| Exports | The small ⋯ under a book's buttons downloads its audio, its text as one plain-text file, and the voice it's read in, if you made that voice. In Compare voices, each voice you made has its own ⋯. |
- The player: every word is highlighted as it's spoken, and tapping the text jumps there. It has playback speed and chapter skipping, and works in any browser, with no app to install.
- Listeners: each person ("Who's listening?") keeps their own place and checkpoints in every book, and they follow them from device to device.
- While listening: a sleep timer (10 minutes to an hour, or the end of the chapter), checkpoints, and Change the voice, which offers the versions already made or a new voice.
- Audiobooks you already have: add an M4B, MP3 or other audiobook and choose Make Read along. Whisper writes down what's said, with the time of every word, a chapter at a time. Your file stays exactly as it was; it is what plays and downloads. A name Whisper misheard can be fixed in the text, and the timings follow without listening again.
Forge runs on one machine or spreads across several:
- One always-on server (a Proxmox container, a NAS, any Docker host) keeps the library and serves Read along to every device.
- Any number of PCs with GPUs voice books and send them to it. Each book remembers which PC made it, so a voice change asked for on the server goes back to that PC, with its progress shown on the server. If that PC is off, Voice it here instead does it on the server's CPU.
- Any number of GPU servers speak cloned voices for all of them (Settings → GPU servers). Every card in each one works at once, each benchmarked for how much it can take.
- Voices made on any PC are copied to the server, and each PC looks after only its own.
Setting this up: A server plus GPU PCs.
The voice creator, at /createvoice, makes narrator voices from recordings
of them, such as audiobooks they read.
- Upload the recordings. Large files upload in parts and carry on after an interruption. A second copy of the same audio is skipped.
- Name the voice, or let it find the name in the tags or in the "read by…" of the opening credits.
- It listens. Whisper cuts clean clips at pauses, and drops music, noise, other speakers and strong character voices. Speaker fingerprints keep only the narrator's own voice. A readiness report says how many usable minutes there are.
- It makes the voice, one of two ways:
- Cloned (Qwen3-TTS): a few clean clips are each tried as the reference, and each reads the same sample. You hear the narrator's clip beside the clone and pick one. It needs no training, but a clone server with a GPU reads the book.
- Trained (Piper): fine-tunes a Piper voice on the recordings, or on the cloned voice reading the narrator's sentences (cleaner audio, and as much as wanted). Every 1,500 steps it measures how much the voice sounds like the narrator and how distorted it is, and keeps a sample to listen to. It stops once neither improves. The finished voice is small and reads books on any CPU.
- You pick by ear. Nothing goes into Forge's voice list until you choose Use this one.
- Take it elsewhere if you like. ⋯ → Voice downloads a zip of its files, with a README on using them in another Forge or with Piper, Kokoro or Qwen3-TTS.
Use voices responsibly. Only clone or train a voice you have the right to use, and don't publish a voice made from someone's recordings without their permission. This repository ships no cloned or trained voices.
You need Docker with the Compose plugin. Allow 8 GB of RAM or more and a few GB of disk for the voice models.
git clone https://github.com/kmmarin/AudioBookForge.git
cd AudioBookForge
./install.shThen open http://<host>:8080. install.sh creates .env from
.env.example, picks the GPU build when it finds an NVIDIA GPU, builds and
starts the app, and downloads the voices and Whisper model.
By hand:
cp .env.example .env
docker compose up -d --build # CPU
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d --build # NVIDIA GPUTo make your audiobooks show up in Audiobookshelf, point OUTPUT_DIR in
.env at your library.
deploy/proxmox-deploy.sh root@your-proxmox-hostThis creates an unprivileged Debian 12 container with Docker, then builds,
starts and prefetches the app. Run it again to update; books, settings and
models are kept. --help lists the options (cores, memory, disk, storage,
static IP, VLAN, output folder).
In an admin PowerShell, in the project folder:
powershell -ExecutionPolicy Bypass -File deploy\windows-converter.ps1It installs WSL 2 and Ubuntu if they're missing, then Docker inside WSL (and
NVIDIA's container toolkit for the GPU), and starts Forge at
http://localhost:8080. If you don't have a server, leave the server
question blank: the PC then keeps its books itself.
A card with 16 GB, such as an RTX 4070 Ti Super, runs all of it:
- Forge on the GPU;
- the voice creator;
- the clone server, for cloned voices.
What you need:
- Windows 11, or Windows 10 22H2, with a recent NVIDIA driver.
- About 80 GB of free disk: the images and models.
- An admin PowerShell.
Installing:
-
Unzip the project (or
git cloneit), for example toC:\audiobook-forge. -
In that folder, run:
powershell -ExecutionPolicy Bypass -File deploy\windows-converter.ps1 -OpenPort
-
It asks for a server to send books to: leave it blank to keep everything on this machine.
-
Open
http://<this PC>:8080.
On Linux, just run ./install.sh.
What's included: everything is on by default.
- The voice creator runs wherever there's an NVIDIA GPU.
- The clone server runs beside Forge on a card of 12 GB or more (
CLONE_LOCAL=auto). - To leave either out, pass
-NoVoiceCreatoror-NoCloneServer, or setVOICELAB=falseorCLONE_LOCAL=falsein.env.
The first start downloads several GB. The models for cloned voices (about 7 GB for both sizes) download the first time each is used.
This is the setup the app was built around:
- The server runs all the time and is light: it keeps the library, serves Read along to every device, and remembers each listener's place.
- One or more PCs with NVIDIA GPUs (converters) voice books many times
faster and run the voice creator. Set each one up the same way; they all send
to the same server, with the same
SHARE_TOKEN.
1. The server. Install it with install.sh or proxmox-deploy.sh (above). In its .env:
SHARE_TOKEN=<a long random secret, the same on every machine>
# optional: open one PC's voice creator from the server too
VOICELAB_URL=http://<PC address>:8080
# optional: cloned voices (see below)
CLONE_URL=http://<clone server>:8100Then restart it: docker compose up -d.
2. Each PC. On each Windows PC, in an admin PowerShell, in the project folder:
powershell -ExecutionPolicy Bypass -File deploy\windows-converter.ps1 -OpenPortIt asks:
- The server's address, like
http://192.168.1.10:8080. - Its
SHARE_TOKEN. Leave it blank on the first PC and the script makes one, which you then copy to the server and give to the other PCs.
The voice creator and, on a card of 6 GB or more, a clone server come with it
(everything is on by default). -OpenPort adds a Windows port proxy and
firewall rule so the server can reach the PC. Give each PC a fixed address (a
DHCP reservation). Run the script again to update; your books, .env and
models are kept.
3. Using it.
- Books finished on a PC go to the server by themselves (
PUBLISH_AUTO), or when you choose Send to server. They arrive with chapters, cover, text and the Read along map. - On the server, changing a book's voice sends the work back to the PC that made it, and the book's row shows that PC's progress.
- Each PC's voices are copied to the server, so they can be picked there too. A PC only ever replaces or removes the voices it sent.
No Windows? A PC can be any Linux machine with an NVIDIA GPU. Set
PUBLISH_URL, PUBLIC_URL and SHARE_TOKEN in its .env by hand.
The voice creator is on wherever there's an NVIDIA GPU (each GPU PC):
windows-converter.ps1, wsl-deploy.sh and install.sh add it there, and
leave it out on machines without one. Forge's header then shows
Create a voice.
Forge and the voice creator take turns on the GPU (app/gpushare.py). Voicing
a book always goes first: training pauses, saves its place, and carries on
once Forge is done, so a shared consumer GPU never runs out of memory.
What each kind needs:
| Cloned (Qwen3-TTS) | Trained (Piper) | |
|---|---|---|
| Recordings | a few clean 8–14 s clips (it stops listening after 10 clean minutes) | 15 minutes at least, an hour or more is better |
| Making it | minutes: samples to pick from, no training | hours on the GPU (a GTX 1660 does one to two steps a second) |
| Reading a book | on the clone server's GPU | on any CPU |
| Sound | closest to the narrator | good, can have a slight buzz; learning from the cloned voice helps |
The voice creator's own README has the details: voicelab/README.md.
Cloned voices are spoken by a small server running
Qwen3-TTS. It can run on whichever
machine has the GPU for it. Forge (to read books) and the voice creator (to
make samples) reach it at CLONE_URL, with the same CLONE_TOKEN on both
sides. If CLONE_TOKEN is blank, SHARE_TOKEN is used.
| Model | Video memory (bfloat16 / float32) |
|---|---|
| Qwen3-TTS 1.7B, the best | about 7 GB / 10 GB |
| Qwen3-TTS 0.6B | about 3 GB / 5.5 GB |
Setting one up takes one line on the GPU machine. It downloads what it needs, starts the server, and ends by showing the address and token to paste into Forge's Settings → GPU servers. Running it again updates the server and keeps its token.
-
Windows, natively (NVIDIA, or AMD Radeon RX 5000–9000): no WSL or Docker, and it starts with Windows. In PowerShell as administrator:
irm https://raw.githubusercontent.com/kmmarin/AudioBookForge/main/deploy/gpu-server.ps1 | iex
-
Windows with WSL and Docker (NVIDIA): it installs WSL if it's missing, and opens the port to other machines. In PowerShell as administrator:
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/kmmarin/AudioBookForge/main/deploy/gpu-server.ps1))) -Mode wsl
-
Linux with Docker (NVIDIA): it installs Docker and NVIDIA's container toolkit if they're missing:
curl -fsSL https://raw.githubusercontent.com/kmmarin/AudioBookForge/main/deploy/gpu-server.sh | sudo bash -
The same machine as Forge: with an NVIDIA card of 12 GB or more, Forge's installer runs it alongside by itself (
CLONE_LOCAL=auto).
From a copy of the project, the same scripts are deploy\gpu-server.ps1 and
deploy/gpu-server.sh. On an RX 6800, the 1.7B voice model reads at about 3.8
times real time.
On Windows, use C:\forge-clone\server\stop.ps1 to stop it: forcing the
process to end while it's working can leave the GPU driver stuck until a
restart.
Several GPU servers: Settings. Forge's Settings lists every clone server, and whether each is answering and on which GPU. You can add, test, change, reorder and remove them there.
- Who does what: a job goes to the first server that's answering, so a second machine can stand in when the first is off.
- Where it's kept: the list is stored in
gpu-servers.jsonin the models volume, shared with the voice creator. - The
.envserver: one set there (CLONE_URL) is listed too. - Tokens: they can be entered but are never shown back.
More, including the API and every setting: clone/README.md.
cp https.env.example https.env # fill in DOMAIN, the DNS API key and SERVER
./https-setup.sh --env https.envIt gets a Let's Encrypt certificate through your DNS provider (Cloudflare,
DigitalOcean, Linode, DNSimple or Route 53). Nothing has to be open to the
internet. It then serves the app at https://<your name>, and the
certificate renews itself. With Cloudflare it also creates the DNS record.
Other commands:
./https-setup.sh --statusshows the certificate and when it expires../https-setup.sh --offgoes back to plain HTTP.
The API key is kept on the server in certs/; https.env is in
.gitignore.
Settings live in .env; .env.example explains every one.
The main ones:
| Setting | Default | What it does |
|---|---|---|
PORT |
8080 | The web port |
OUTPUT_DIR |
./output |
Finished books: point it at your Audiobookshelf library |
DEFAULT_FORMAT |
m4b | m4b, m4a, mp3, opus or flac |
OUTPUT_LAYOUT |
abs | abs (Author/Series/1 - Title/) or flat |
TTS_WORKERS, TORCH_THREADS |
auto | Voice processes and threads each; auto fits your cores and memory |
BOOK_CONCURRENCY |
2 | Books voiced at once |
QA_DEFAULT, QA_FLAG_WER |
true, 0.12 | The Whisper narration check, and when it flags a chapter |
TRANSCRIBE_MODEL |
small | Whisper model for Read along of audiobooks you add (base is about 3x faster) |
METADATA_LOOKUP |
true | Look books up online |
PUBLISH_URL, PUBLIC_URL, SHARE_TOKEN |
The server and converter link | |
VOICELAB, VOICELAB_URL |
true | The voice creator, wherever there's an NVIDIA GPU, or reached on another machine |
CLONE_URL, CLONE_TOKEN |
A clone server for cloned voices (more in Settings) | |
CLONE_LOCAL |
auto | The clone server beside Forge: auto = on an NVIDIA card of 12 GB or more |
NORMALIZE |
true | Every book at the same loudness (EBU R128) |
INSTALL_CALIBRE |
true | Kindle and other older ebook formats (false: an image about 700 MB smaller) |
DEV_FAKE_TTS |
false | Tones instead of speech: tests the whole pipeline in seconds |
The stock voice list is app/voices.yaml. Add any Kokoro or
Piper voice there, or mount your own copy and set VOICES_FILE.
phones, tablets, browsers
│
▼
always-on server (CPU) web + worker, SQLite: the library,
│ ▲ Read along, each listener's place
voice │ │ finished
changes │ │ books
▼ │
Windows PC with a GPU (WSL 2) Forge on CUDA, plus the voice creator
│ (they take turns on the GPU)
│ cloned voices
▼
clone server (any GPU machine) Qwen3-TTS: NVIDIA in Docker, or AMD on Windows
- web and worker are one image and two containers. They share state through SQLite and never call each other.
- Voicing: the worker cuts each chapter into units of about 1,800 characters, voices them in a shared pool of processes, joins them into chapters, and encodes chapters in parallel.
- Read along: each unit records the time of every word as it's voiced, so the read-along map is built when the book is assembled. For audiobooks you add, Whisper's word timings make the same map.
- The voice creator is a separate service (
voicelab/) that Forge passes/createvoiceto. Finished voices go into the shared models volume, and Forge lists them without a restart. - The clone server is a separate image (
clone/), because Qwen3-TTS needs an older transformers than Kokoro does.
| Folder | What's there |
|---|---|
app/ |
Forge: parsing, voicing, assembly, Read along, publishing, the web UI (app/static/) |
voicelab/ |
The voice creator: listening, readiness, cloning, Piper training, quality checks |
clone/ |
The clone server, and clone/windows/ for AMD on Windows |
deploy/ |
Installers: Proxmox LXC, WSL, the Windows converter, the WSL clone server |
docker/ |
The container entrypoint and the HTTPS proxy |
experiments/qwen3-tts/ |
The harness used to try Qwen3-TTS before the clone server existed |
docs/ |
Notes for developers |
Nothing below is in this repository. Each is downloaded from its publisher the first time it's needed, and is under its own license:
| What | From | License |
|---|---|---|
| Kokoro voices | hexgrad/Kokoro-82M | Apache-2.0 |
| Piper voices | rhasspy/piper-voices | per voice: see each voice's model card |
| Piper base checkpoints (training) | rhasspy/piper-checkpoints | per voice: see each voice's model card |
| Qwen3-TTS 1.7B and 0.6B Base | Qwen on Hugging Face | Apache-2.0 |
| Whisper (faster-whisper) | Systran | MIT |
| Speaker fingerprints (ECAPA-TDNN) | speechbrain/spkrec-ecapa-voxceleb | Apache-2.0 |
Voices you make stay on your machines (/models/custom-voices and
/models/cloned-voices in the Docker volume).
# Forge without any models: tones instead of speech
DEV_FAKE_TTS=true docker compose up -d --build
# the voice creator's tests, from the project root, in the voicelab image
python -m unittest discover -s voicelab/tests
# a running clone server, end to end
PYTHONPATH=. python clone/test_server.py http://host:8100 ref.wav ref.txt TOKEN out/Branches:
mainis the stable version: install from it.nextcollects changes as they're made, with an open pull request intomain. They reachmainwhen it's merged.
There's no frontend build step: the UI is plain HTML, CSS and JavaScript in
app/static/ and voicelab/lab/static/. Every setting is an environment
variable read in one config.py. docs/DEVELOPING.md
covers the architecture, the API and the conventions.
GPL-3.0. Forge voices books with, and the voice creator trains with, piper1-gpl, which is GPL-3.0.
It also builds on:
- Kokoro (Apache-2.0)
- qwen-tts (Apache-2.0)
- faster-whisper (MIT)
- SpeechBrain (Apache-2.0)
- PyTorch Lightning (Apache-2.0)
- FastAPI (MIT)
- ffmpeg (LGPL/GPL)
- pandoc (GPL-2.0+)
- espeak-ng (GPL-3.0)
- Calibre, optional (GPL-3.0)