sabofa/AudioBook-Pipeline

this repository consists of a partially automated pipeline in which you can train models, gather model data and fully export audiobooks via a unique hashing system. ABP is fully customizable and made for user

0

stars

110

commits

Python

primary language

Aug 12, 2026

updated

README

abp — Audiobook Pipeline

Content-addressed, resumable pipeline that converts novel-length text into a verified, mastered audiobook using local or rented-GPU neural TTS. Feed it a .txt/.epub/.html source; it extracts, dedupes, figures out who's speaking, casts voices, synthesizes, verifies against ASR, and masters a final .m4b — with every expensive step cached by content hash so nothing gets redone unless its actual inputs changed.

Full spec: docs/audiobook-pipeline.md. Everything you can customize, in plain language: docs/customization-guide.md. Build order: docs/TODO.md. AI-agent conventions: CLAUDE.md + docs/dev-log.md.

Status

Every milestone in the original build order (M0 through M12) has shipped, as of 2026-08-01. Two items remain not-started: M9 Phase B (IndexTTS2/ VibeVoice eval pilot arms — blocked on validating those engines against a real install) and the Dashboard Rebuild Phase 1 (React/TS/Vite SPA replacing the current single-page abp ui). See docs/TODO.md for the authoritative per-item build status before assuming a feature exists.

MilestoneState
M0 Spine (manifest, config, hashing, CLI skeleton, gates)done
M1 First audio (txt → chatterbox → verify → m4b)done
M2 Real intake (epub/html, dedup, ordering, lexicon)done
M3 Intelligence (attribution, registry, casting, duet)done
M4 Full cast + rental workflow (kokoro preview engine, plan/work/gc)done
M4.5 Dashboard (abp ui)done
M4.75 Realism layer (pause jitter, crossfades, room tone, breaths)done
M5 Voice trainingdone
M6 Mood + musicdone
M7 Book adapter / customization layer (book_adapter.yaml)done
M8 Register assignmentdone
M8.1 Register assignment amendmentsdone
M9 Evaluation harness — Phase A (Chatterbox pilot)done
M9 Evaluation harness — Phase B (IndexTTS2/VibeVoice pilot arms)not started
M10 Multi-engine synthesis (IndexTTS2 real, VibeVoice stubbed)done
M12 Cross-chapter consistency (fingerprint, loudness, voice freeze, timbre)done
Dashboard Rebuild Phase 1 (React/TS/Vite SPA)not started

Requirements

  • Python 3.11+
  • ffmpeg on PATH (mastering, resampling)
  • An NVIDIA GPU is strongly recommended for real synthesis (chatterbox/ kokoro/IndexTTS2 all run on CPU, but slowly) — not required for intake/ clean/segment/attribution/casting, which are all CPU-class stages
  • API keys only if you use an LLM-backed stage (attribution's window pass, registry auto-build, mood tagging, abp analyze) — see Environment variables below. Every LLM-touching stage sits behind an explicit review gate; nothing paid runs without you opting in (spec §2, "gates before money")

Install (dev)

git clone <this-repo-url>
cd abp
python -m venv .venv
.venv/Scripts/activate        # .venv/bin/activate on macOS/Linux
pip install -e ".[dev,chatterbox,asr]"
abp --help

pyproject.toml defines the installable extras — mix and match what you actually need:

ExtraAddsNeeded for
chatterboxchatterbox-ttsthe default/main TTS engine (M1)
kokorokokorothe fast preview/draft engine (M4)
asrfaster-whisperabp verify (ASR-vs-text comparison)
evaltransformers, librosa, torchaudioabp voice eval (M9 — identity/drift/naturalness metrics; also needs chatterbox+asr)
devpytest, pytest-cov, ruff, mypyrunning the test suite / linting

IndexTTS2 (M10) isn't a pyproject.toml extra — it's installed and pointed at via ABP_INDEXTTS2_MODEL_DIR (see below); read src/abp/engines/indextts2.py's module docstring before using it for real. VibeVoice is a deliberate stub (src/abp/engines/vibevoice.py) — no maintained upstream inference code exists to build against yet.

Two more tools live in this repo but are fully standalone (their own venv, their own CLI, zero imports from abp core) — see Companion tools below.

Quick start

mkdir myproject && cd myproject
abp init                         # scaffolds project.yaml + folder layout
cp /path/to/book.txt dump/       # or .epub / .html
abp intake                       # extract, dedupe, order-reconstruct -> book.json
abp clean                        # normalize + source profile + optional LLM clean pass
abp segment                      # sentence split, dialogue/narration spans, chunk pack
abp detect                       # propose quote convention (review before casting)
abp annotate --pass attribution  # who-speaks-what
abp sheet                        # ranked casting sheet -> casting.review gate
abp cast                         # resolve voice_id per span
abp annotate --pass register     # delivery register assignment (spec §7 S8b)
abp annotate --pass mood         # scene mood/intensity/music tagging
abp synth                        # drain pending chunks (chatterbox default, kokoro preview)
abp verify                       # ASR compare, retry loop
abp mix --chapter <id>           # mood-driven music bed (if mix.enabled)
abp master                       # concat, loudnorm, encode -> m4b (--book for cross-chapter)
# → out/*.m4b

Every stage picks up exactly where it left off — re-running abp synth after adding a new chapter only synthesizes the new chunks; editing a lexicon.yaml entry only re-renders the chunks containing that word. See docs/customization-guide.md for every way to steer a specific book's output (pronunciation fixes, inline directives, source profiles, and the full book_adapter.yaml rule vocabulary) without ever touching pipeline code.

Longer-running or paid-resource work is queued and reviewed rather than run inline:

abp plan                # pending work, GPU-hour/cost estimate, gate check
abp work --class gpu     # class-scoped queue drainer (rental-friendly)
abp voice add / audition / train / freeze / unlock / timbre-check / eval
abp gc --dry-run         # orphaned chunk cleanup
abp ui                   # single-page dashboard: status, verify review, casting review
abp adapter diff         # dry-run book_adapter.yaml rules against current state
abp analyze              # quirk report with drafted glossary/profile/adapter fixes
abp stress parser        # dev-only harness: hammer S1-S8b against curated fixtures/real books
abp gate list|close|waive
abp register sheet|freeze
abp lexicon add|suggest

Every subcommand in abp --help reflects the full CLI surface — see src/abp/cli.py.

Environment variables

VariablePurpose
ABP_INDEXTTS2_MODEL_DIRPath to a local IndexTTS2 checkpoint directory (default checkpoints/indextts2). Used by both inference (abp synth) and voice_train's install-checkpoint.
ABP_TEST_REAL_TTSOpt into real chatterbox synthesis in the test suite (downloads weights, slow).
ABP_TEST_REAL_TRAININGOpt into real chatterbox training in the test suite.
ABP_TEST_REAL_KOKOROOpt into real kokoro synthesis in the test suite.
ABP_TEST_REAL_INDEXTTS2Opt into real IndexTTS2 synthesis in the test suite (needs the indextts package + downloaded checkpoints).
ABP_TEST_REAL_LLM / ABP_TEST_REAL_PROJECTOpt into a real-LLM-backed milestone test against an already-intake/clean/segment'd project (real API cost).
ABP_TEST_REAL_EVAL_MODELSOpt into real WavLM-TDNN / SQUIM model downloads for voice_eval tests.
ABP_TEST_REAL_TIMBREOpt into a real WavLM embedder load for the webapi voices test.

Every ABP_TEST_REAL_* flag is off by default — the full test suite runs without any of them, real models, or network access.

Companion tools

Two packages ship in this repo but are fully standalone — their own virtualenv, their own CLI entry point, no imports from abp's core pipeline. Neither is required to use abp itself; both exist to build a custom cloned/trained voice to feed into abp's voice bank.

ToolTurnsIntoDocs
voice_dataset_prepraw episode video/audio + subtitlesa clean, per-character voice dataset (manifest.jsonl)full setup, command reference, review-UI workflow
voice_trainvoice_dataset_prep's manifest.jsonla trained IndexTTS2 GPT checkpoint, installable via ABP_INDEXTTS2_MODEL_DIRfull setup, vendored-repo pinning, rental-box handoff

The chain end to end: voice_dataset_prepmanifest.jsonlvoice_train → a checkpoint → abp's existing IndexTTS2 adapter. Each README documents its own venv because both packages pull in heavy, version-sensitive ML dependencies (torch, pyannote.audio, audio-separator) that don't need to collide with the core pipeline's own environment.

Testing

pytest -q

Runs the full suite (tests/ + voice_train/tests/, per pyproject.toml's testpaths) with every ABP_TEST_REAL_* flag off by default — no real model downloads, no network calls, no GPU required. voice_dataset_prep/tests/ runs the same way from inside its own venv (voice_dataset_prep/README.md has the setup). Config/hashing/manifest-DDL changes need a test that fails before the change and passes after — see CLAUDE.md's non-negotiable invariants before touching any of those.

Architecture principles

Every design decision follows the spec's binding principles (see §2):

  1. Content-addressed, resumable. Work already done is never redone. A crash costs zero completed chunks.
  2. Facts vs. policy. GPU work produces facts about the text (who speaks, what mood). Config expresses policy (which voice, whether music). Policy changes never redo facts.
  3. Book-agnostic core. The pipeline knows blocks, spans, speakers, voices. It never knows about a specific book or character.
  4. User sovereignty. Every creative decision is user-configurable with sane defaults.
  5. Fail visible, degrade invisible. Unsure → narrator (invisible). Failed → gate blocks mastering.
  6. Gates before money. Paid resources are blocked behind explicit review gates.
  7. Class-tagged execution. Every stage is cpu, api, or gpu; the pipeline runs unchanged on any host.

Because the core is book-agnostic by design, no book-specific content (character names, source text, lexicon entries, profiles tuned to one book) ever belongs in this repo — see CLAUDE.md. Real projects, profiles/<source>.yaml, and book_adapter.yaml files live outside this repo (or gitignored inside it), never committed here.

Layout

src/abp/
├── config.py          # project.yaml loader
├── manifest.py        # SQLite state (§5.2)
├── model.py           # canonical book.json dataclasses (§5.1)
├── gates.py           # review-gate machinery
├── hashing.py         # chunk identity (§5.3), voice_hash (§9.4)
├── cli.py             # click-based CLI (§11.5)
├── engines/           # TTS adapter plugins (§10.1) — chatterbox (default/main), kokoro (preview), indextts2, vibevoice (stub)
├── llm/               # provider adapters (§10.2) — deepseek, gemini, anthropic, openai_compatible
├── stages/            # S1–S11 stage implementations
├── voice/             # voice bank, training, breaths, freeze (§9)
├── voice_eval/        # evaluation harness (§16) — identity/drift/boundary/intelligibility/level/naturalness metrics
├── stress/            # dev-only parser stress harness — curated fixtures + real-book runs against S1-S8b
├── adapter*.py         # book_adapter.yaml matching engine, loader, diff, analyze (§15)
├── register*.py        # delivery register assignment cascade (§7 S8b)
├── fingerprint.py       # render-fingerprint drift detection (§8.6 Layer 1)
├── voice_freeze.py      # per-voice content-addressed freeze/unlock (§8.6 Layer 3)
└── timbre_tracking.py    # per-voice book-wide timbre drift (§8.6 Layer 4)
voice_dataset_prep/    # standalone: episode audio/subtitles -> per-character voice dataset
voice_train/           # standalone: voice dataset -> trained IndexTTS2 checkpoint
tests/                 # unit tests — one file per module, hash stability, config parsing, gate transitions
docs/                  # spec + build TODO + dev log + index + customization guide

Runtime project layout lives outside this repo (spec §4). See docs/INDEX.md for a full map from "where does X live" to file/symbol.

Docs map

DocWhat's in it
docs/audiobook-pipeline.mdthe authoritative spec — every stage, schema, and invariant
docs/customization-guide.mdplain-language guide to every way to steer a specific book's output
docs/TODO.mdmilestone build order and per-item status (source of truth over this README's table)
docs/INDEX.md"where does X live" — file/symbol lookup
docs/dev-log.mdrolling log of what changed and why, newest first
docs/realism-notes.mdmastering-chain realism layer companion (pause jitter, crossfades, room tone, breaths)
docs/ab-testing.mdA/B listening protocol for realism-layer changes
docs/indextts2-voice-training-research.mdresearch behind voice_train — which fork, VRAM, what fine-tuning changes
CLAUDE.mdnon-negotiable invariants and workflow conventions for AI-assisted development

License

MIT — see pyproject.toml.

Contributors

benifits

109 commits

sabofa

1 commits

sabofa/AudioBook-Pipeline

this repository consists of a partially automated pipeline in which you can train models, gather model data and fully export audiobooks via a unique hashing system. ABP is fully customizable and made for user

0

stars

110

commits

Python

primary language

Aug 12, 2026

updated

README

abp — Audiobook Pipeline

Content-addressed, resumable pipeline that converts novel-length text into a verified, mastered audiobook using local or rented-GPU neural TTS. Feed it a .txt/.epub/.html source; it extracts, dedupes, figures out who's speaking, casts voices, synthesizes, verifies against ASR, and masters a final .m4b — with every expensive step cached by content hash so nothing gets redone unless its actual inputs changed.

Full spec: docs/audiobook-pipeline.md. Everything you can customize, in plain language: docs/customization-guide.md. Build order: docs/TODO.md. AI-agent conventions: CLAUDE.md + docs/dev-log.md.

Status

Every milestone in the original build order (M0 through M12) has shipped, as of 2026-08-01. Two items remain not-started: M9 Phase B (IndexTTS2/ VibeVoice eval pilot arms — blocked on validating those engines against a real install) and the Dashboard Rebuild Phase 1 (React/TS/Vite SPA replacing the current single-page abp ui). See docs/TODO.md for the authoritative per-item build status before assuming a feature exists.

MilestoneState
M0 Spine (manifest, config, hashing, CLI skeleton, gates)done
M1 First audio (txt → chatterbox → verify → m4b)done
M2 Real intake (epub/html, dedup, ordering, lexicon)done
M3 Intelligence (attribution, registry, casting, duet)done
M4 Full cast + rental workflow (kokoro preview engine, plan/work/gc)done
M4.5 Dashboard (abp ui)done
M4.75 Realism layer (pause jitter, crossfades, room tone, breaths)done
M5 Voice trainingdone
M6 Mood + musicdone
M7 Book adapter / customization layer (book_adapter.yaml)done
M8 Register assignmentdone
M8.1 Register assignment amendmentsdone
M9 Evaluation harness — Phase A (Chatterbox pilot)done
M9 Evaluation harness — Phase B (IndexTTS2/VibeVoice pilot arms)not started
M10 Multi-engine synthesis (IndexTTS2 real, VibeVoice stubbed)done
M12 Cross-chapter consistency (fingerprint, loudness, voice freeze, timbre)done
Dashboard Rebuild Phase 1 (React/TS/Vite SPA)not started

Requirements

  • Python 3.11+
  • ffmpeg on PATH (mastering, resampling)
  • An NVIDIA GPU is strongly recommended for real synthesis (chatterbox/ kokoro/IndexTTS2 all run on CPU, but slowly) — not required for intake/ clean/segment/attribution/casting, which are all CPU-class stages
  • API keys only if you use an LLM-backed stage (attribution's window pass, registry auto-build, mood tagging, abp analyze) — see Environment variables below. Every LLM-touching stage sits behind an explicit review gate; nothing paid runs without you opting in (spec §2, "gates before money")

Install (dev)

git clone <this-repo-url>
cd abp
python -m venv .venv
.venv/Scripts/activate        # .venv/bin/activate on macOS/Linux
pip install -e ".[dev,chatterbox,asr]"
abp --help

pyproject.toml defines the installable extras — mix and match what you actually need:

ExtraAddsNeeded for
chatterboxchatterbox-ttsthe default/main TTS engine (M1)
kokorokokorothe fast preview/draft engine (M4)
asrfaster-whisperabp verify (ASR-vs-text comparison)
evaltransformers, librosa, torchaudioabp voice eval (M9 — identity/drift/naturalness metrics; also needs chatterbox+asr)
devpytest, pytest-cov, ruff, mypyrunning the test suite / linting

IndexTTS2 (M10) isn't a pyproject.toml extra — it's installed and pointed at via ABP_INDEXTTS2_MODEL_DIR (see below); read src/abp/engines/indextts2.py's module docstring before using it for real. VibeVoice is a deliberate stub (src/abp/engines/vibevoice.py) — no maintained upstream inference code exists to build against yet.

Two more tools live in this repo but are fully standalone (their own venv, their own CLI, zero imports from abp core) — see Companion tools below.

Quick start

mkdir myproject && cd myproject
abp init                         # scaffolds project.yaml + folder layout
cp /path/to/book.txt dump/       # or .epub / .html
abp intake                       # extract, dedupe, order-reconstruct -> book.json
abp clean                        # normalize + source profile + optional LLM clean pass
abp segment                      # sentence split, dialogue/narration spans, chunk pack
abp detect                       # propose quote convention (review before casting)
abp annotate --pass attribution  # who-speaks-what
abp sheet                        # ranked casting sheet -> casting.review gate
abp cast                         # resolve voice_id per span
abp annotate --pass register     # delivery register assignment (spec §7 S8b)
abp annotate --pass mood         # scene mood/intensity/music tagging
abp synth                        # drain pending chunks (chatterbox default, kokoro preview)
abp verify                       # ASR compare, retry loop
abp mix --chapter <id>           # mood-driven music bed (if mix.enabled)
abp master                       # concat, loudnorm, encode -> m4b (--book for cross-chapter)
# → out/*.m4b

Every stage picks up exactly where it left off — re-running abp synth after adding a new chapter only synthesizes the new chunks; editing a lexicon.yaml entry only re-renders the chunks containing that word. See docs/customization-guide.md for every way to steer a specific book's output (pronunciation fixes, inline directives, source profiles, and the full book_adapter.yaml rule vocabulary) without ever touching pipeline code.

Longer-running or paid-resource work is queued and reviewed rather than run inline:

abp plan                # pending work, GPU-hour/cost estimate, gate check
abp work --class gpu     # class-scoped queue drainer (rental-friendly)
abp voice add / audition / train / freeze / unlock / timbre-check / eval
abp gc --dry-run         # orphaned chunk cleanup
abp ui                   # single-page dashboard: status, verify review, casting review
abp adapter diff         # dry-run book_adapter.yaml rules against current state
abp analyze              # quirk report with drafted glossary/profile/adapter fixes
abp stress parser        # dev-only harness: hammer S1-S8b against curated fixtures/real books
abp gate list|close|waive
abp register sheet|freeze
abp lexicon add|suggest

Every subcommand in abp --help reflects the full CLI surface — see src/abp/cli.py.

Environment variables

VariablePurpose
ABP_INDEXTTS2_MODEL_DIRPath to a local IndexTTS2 checkpoint directory (default checkpoints/indextts2). Used by both inference (abp synth) and voice_train's install-checkpoint.
ABP_TEST_REAL_TTSOpt into real chatterbox synthesis in the test suite (downloads weights, slow).
ABP_TEST_REAL_TRAININGOpt into real chatterbox training in the test suite.
ABP_TEST_REAL_KOKOROOpt into real kokoro synthesis in the test suite.
ABP_TEST_REAL_INDEXTTS2Opt into real IndexTTS2 synthesis in the test suite (needs the indextts package + downloaded checkpoints).
ABP_TEST_REAL_LLM / ABP_TEST_REAL_PROJECTOpt into a real-LLM-backed milestone test against an already-intake/clean/segment'd project (real API cost).
ABP_TEST_REAL_EVAL_MODELSOpt into real WavLM-TDNN / SQUIM model downloads for voice_eval tests.
ABP_TEST_REAL_TIMBREOpt into a real WavLM embedder load for the webapi voices test.

Every ABP_TEST_REAL_* flag is off by default — the full test suite runs without any of them, real models, or network access.

Companion tools

Two packages ship in this repo but are fully standalone — their own virtualenv, their own CLI entry point, no imports from abp's core pipeline. Neither is required to use abp itself; both exist to build a custom cloned/trained voice to feed into abp's voice bank.

ToolTurnsIntoDocs
voice_dataset_prepraw episode video/audio + subtitlesa clean, per-character voice dataset (manifest.jsonl)full setup, command reference, review-UI workflow
voice_trainvoice_dataset_prep's manifest.jsonla trained IndexTTS2 GPT checkpoint, installable via ABP_INDEXTTS2_MODEL_DIRfull setup, vendored-repo pinning, rental-box handoff

The chain end to end: voice_dataset_prepmanifest.jsonlvoice_train → a checkpoint → abp's existing IndexTTS2 adapter. Each README documents its own venv because both packages pull in heavy, version-sensitive ML dependencies (torch, pyannote.audio, audio-separator) that don't need to collide with the core pipeline's own environment.

Testing

pytest -q

Runs the full suite (tests/ + voice_train/tests/, per pyproject.toml's testpaths) with every ABP_TEST_REAL_* flag off by default — no real model downloads, no network calls, no GPU required. voice_dataset_prep/tests/ runs the same way from inside its own venv (voice_dataset_prep/README.md has the setup). Config/hashing/manifest-DDL changes need a test that fails before the change and passes after — see CLAUDE.md's non-negotiable invariants before touching any of those.

Architecture principles

Every design decision follows the spec's binding principles (see §2):

  1. Content-addressed, resumable. Work already done is never redone. A crash costs zero completed chunks.
  2. Facts vs. policy. GPU work produces facts about the text (who speaks, what mood). Config expresses policy (which voice, whether music). Policy changes never redo facts.
  3. Book-agnostic core. The pipeline knows blocks, spans, speakers, voices. It never knows about a specific book or character.
  4. User sovereignty. Every creative decision is user-configurable with sane defaults.
  5. Fail visible, degrade invisible. Unsure → narrator (invisible). Failed → gate blocks mastering.
  6. Gates before money. Paid resources are blocked behind explicit review gates.
  7. Class-tagged execution. Every stage is cpu, api, or gpu; the pipeline runs unchanged on any host.

Because the core is book-agnostic by design, no book-specific content (character names, source text, lexicon entries, profiles tuned to one book) ever belongs in this repo — see CLAUDE.md. Real projects, profiles/<source>.yaml, and book_adapter.yaml files live outside this repo (or gitignored inside it), never committed here.

Layout

src/abp/
├── config.py          # project.yaml loader
├── manifest.py        # SQLite state (§5.2)
├── model.py           # canonical book.json dataclasses (§5.1)
├── gates.py           # review-gate machinery
├── hashing.py         # chunk identity (§5.3), voice_hash (§9.4)
├── cli.py             # click-based CLI (§11.5)
├── engines/           # TTS adapter plugins (§10.1) — chatterbox (default/main), kokoro (preview), indextts2, vibevoice (stub)
├── llm/               # provider adapters (§10.2) — deepseek, gemini, anthropic, openai_compatible
├── stages/            # S1–S11 stage implementations
├── voice/             # voice bank, training, breaths, freeze (§9)
├── voice_eval/        # evaluation harness (§16) — identity/drift/boundary/intelligibility/level/naturalness metrics
├── stress/            # dev-only parser stress harness — curated fixtures + real-book runs against S1-S8b
├── adapter*.py         # book_adapter.yaml matching engine, loader, diff, analyze (§15)
├── register*.py        # delivery register assignment cascade (§7 S8b)
├── fingerprint.py       # render-fingerprint drift detection (§8.6 Layer 1)
├── voice_freeze.py      # per-voice content-addressed freeze/unlock (§8.6 Layer 3)
└── timbre_tracking.py    # per-voice book-wide timbre drift (§8.6 Layer 4)
voice_dataset_prep/    # standalone: episode audio/subtitles -> per-character voice dataset
voice_train/           # standalone: voice dataset -> trained IndexTTS2 checkpoint
tests/                 # unit tests — one file per module, hash stability, config parsing, gate transitions
docs/                  # spec + build TODO + dev log + index + customization guide

Runtime project layout lives outside this repo (spec §4). See docs/INDEX.md for a full map from "where does X live" to file/symbol.

Docs map

DocWhat's in it
docs/audiobook-pipeline.mdthe authoritative spec — every stage, schema, and invariant
docs/customization-guide.mdplain-language guide to every way to steer a specific book's output
docs/TODO.mdmilestone build order and per-item status (source of truth over this README's table)
docs/INDEX.md"where does X live" — file/symbol lookup
docs/dev-log.mdrolling log of what changed and why, newest first
docs/realism-notes.mdmastering-chain realism layer companion (pause jitter, crossfades, room tone, breaths)
docs/ab-testing.mdA/B listening protocol for realism-layer changes
docs/indextts2-voice-training-research.mdresearch behind voice_train — which fork, VRAM, what fine-tuning changes
CLAUDE.mdnon-negotiable invariants and workflow conventions for AI-assisted development

License

MIT — see pyproject.toml.

Contributors

benifits

109 commits

sabofa

1 commits

Languages

Python

100.0%