Open-source voice-cloning and voice-design studio
Clone a voice from a single reference WAV. Design accents from scratch. Assemble clips in a timeline editor. Serve it all over an OpenAI-compatible API. One process, no training required — run it in the container or natively.
OmniVoice accent audition — generate candidates per segment, across accents, in real time:
Voice Design → Stitch Studio — compose a voice from trait chips, then assemble it into a reference clip:
| Feature | Description | |
|---|---|---|
| 🎙️ | Voice cloning | Clone a voice from one reference WAV. No fine-tuning, no training data. |
| 🎨 | Voice Design | Compose a voice from trait chips — gender, register, texture, persona — or a free-form description. Preview, then save. |
| 🌏 | Accent design | OmniVoice generates candidates per segment across accents. Audition them, cherry-pick the best takes, stitch the winners into a reference voice. |
| ✂️ | Stitch Studio | Drag segments onto a timeline. Per-clip trim, fade, gain, and DSP, with live preview. |
| 📚 | Voice Library | Prosody fingerprints (LUFS, speech rate, pause ratio, peak dBFS) for every saved voice. Fork, edit, compare variants. |
| 🎵 | Prosody Adjustment | Precise control over pause placement — choose style presets (Calm, Energetic, etc.), see word-level pause markers, and preview before saving. |
| 🔌 | OpenAI-compatible API | POST /v1/audio/speech — a drop-in TTS endpoint for any OpenAI SDK client. |
| ⚡ | CPU-first | The default pocket-tts backend runs on any CPU. Qwen3-TTS (PyTorch or OpenVINO) is opt-in. |
| 🎛️ | Live runtime config | Change backend, idle-unload timer, and DSP knobs from the UI. No restart. |
|
Speak — generate from any saved voice |
Voice Design — compose from trait chips |
|
Prosody Adjustment — control pause placement with word-level precision |
Stitch Studio — assemble clips into a new reference voice |
Prerequisites: Docker and Docker Compose. Images are published to GHCR on every release — this pulls a prebuilt image rather than building from source.
git clone https://github.com/nmorgowicz-org/persona-forge.git
cd persona-forge
cp .env.example .env # optional: set HF_TOKEN, REF_AUDIO_PATH
echo 'PERSONA_FORGE_IMAGE=ghcr.io/nmorgowicz-org/persona-forge:latest' >> .env
docker compose up -d persona-forge
open http://localhost:8318The service is ready when GET /health reports "model_loaded": true — roughly 30–60 seconds on
first boot with the default pocket-tts backend.
Leave PERSONA_FORGE_IMAGE unset only if you're changing the Dockerfile/source and want
docker compose up --build to build a local image instead. See Container image
below for pinned version/digest tags.
No Compose, or don't want to clone the repo? Run the published image directly:
docker run -d --name persona-forge -p 8318:8318 \ -v "$(pwd)/data/model:/root/.cache/huggingface/hub" \ -v "$(pwd)/data/voices:/voices" \ ghcr.io/nmorgowicz-org/persona-forge:latestCovers the pocket-tts default with a persistent model cache and voice library. See compose.yml for the full set of optional volumes/env (reference audio, OpenVINO IR cache, segment library).
Want the Qwen engine with OpenVINO acceleration? Run the export step first and set
TTS_BACKEND=openvino. See HOW_TO_RUN.md.
Don't want Docker? The recommended native path is the platform launcher archive from a GitHub Release. It includes the Persona Forge wheel, a pinned
uv, and hash-locked dependency requirements, so users do not need to preinstall Python,uv, or Node.js. The first run downloads Python and the runtime dependencies; the first server start downloads model assets into the user's application-data directory. Persona Forge can also be installed from a source checkout withuv; the release wheel is a GitHub Release asset (we do not currently publish it to PyPI). See RUN_LOCAL.md; to move an existing Docker deployment's data over, see MIGRATION.md.
On macOS, verify the release checksum first. If Gatekeeper blocks the extracted launcher, run
xattr -dr com.apple.quarantine .from that archive's directory. See native setup for the safety note.
The recommended native install is the launcher archive on the latest release. Choose the archive for your platform:
| Platform | Archive |
|---|---|
| Linux x86-64 | persona-forge-bootstrap-linux-x86_64.tar.gz |
| Apple Silicon macOS | persona-forge-bootstrap-macos-aarch64.tar.gz |
| Windows x86-64 | persona-forge-bootstrap-windows-x86_64.zip |
Download checksums.json and your archive from the same release, verify the archive's SHA-256
against that file, then extract it. On Linux/macOS:
tar -xzf persona-forge-bootstrap-<platform>.tar.gz
chmod +x persona-forge-launcher
./persona-forge-launcher doctor --json
./persona-forge-launcher setup
./persona-forge-launcher serveOn Apple Silicon macOS, if Gatekeeper blocks the extracted launcher, run the following from the
verified archive directory before doctor:
xattr -dr com.apple.quarantine .On Windows PowerShell:
Expand-Archive .\persona-forge-bootstrap-windows-x86_64.zip -DestinationPath .\persona-forge
Set-Location .\persona-forge
.\persona-forge-launcher.exe doctor --json
.\persona-forge-launcher.exe setup
.\persona-forge-launcher.exe serveOpen http://127.0.0.1:8318. The archive includes the app wheel, pinned uv, and locked
requirements, so Python, uv, and Node.js do not need to be installed first. The first launcher
command downloads Python and runtime dependencies; the first server start downloads model assets.
For exact checksum commands, upgrades, source checkout, and release-wheel installation, see
the full native guide.
Everything is served on port 8318. There is no authentication by default.
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health, model status, backend and mount info |
POST |
/v1/audio/speech |
OpenAI-compatible TTS |
POST |
/generate |
Native TTS — adds language, seed, prosody_repair |
GET |
/voices |
Saved voices with prosody metrics |
POST |
/voice_design |
Generate a voice from a description |
POST |
/omnivoice/audition |
Accent audition (streaming, multi-segment) |
GET/POST |
/runtime/config |
Live runtime configuration |
curl -s http://localhost:8318/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{"input": "Hello world", "voice_id": "vd_000000000001", "response_format": "mp3"}' \
--output speech.mp3from openai import OpenAI
client = OpenAI(base_url="http://localhost:8318/v1", api_key="unused")
client.audio.speech.create(
model="tts-1", voice="vd_000000000001", input="Hello world"
).stream_to_file("speech.mp3")Full reference: docs/api/HTTP_API_REFERENCE.md
docker pull ghcr.io/nmorgowicz-org/persona-forge:latestPin a version — or a digest — for anything you depend on:
docker pull ghcr.io/nmorgowicz-org/persona-forge:v1.4.9 # x-release-please-versionTags: latest, v<major>.<minor>.<patch>, <git-sha>. Use any of these as
PERSONA_FORGE_IMAGE (see Getting started) instead of latest for a
reproducible deploy.
Container vs. native — why both exist. The runtime depends on pinned torch/torchaudio
wheels, source-level patches applied to installed third-party packages (qwen_tts, transformers),
a per-accelerator-family install step, and a Node/npm frontend build (frontend/) that has to
run and get bundled in ahead of time. The container packages all of that into one pinned,
reproducible artifact — backend and frontend — so none of it is visible to the operator, and it
stays the most-tested, canonical deployment path. Persona Forge also installs and runs natively
(source checkout via uv, an installable wheel/sdist, or a self-contained launcher archive) —
the same pins and patches are applied by the native setup/serve commands instead of a
container build. See RUN_LOCAL.md for the native paths and their current
hardware-validation status, and MIGRATION.md for moving between the two.
Quick links: Docker setup · Native setup · Migration · Environment · HTTP API · Architecture · Contributing
No authentication and no TLS out of the box. Persona Forge is built to run on a trusted LAN or behind an authenticated reverse proxy. Do not expose port 8318 to the internet without putting auth in front of it.
Reporting: SECURITY.md
MIT — with the exception of OmniVoice model weights, which are CC-BY-NC (non-commercial). See OMNIVOICE_REFERENCE.md.





