What mattered
Two levers moved the result. The rest were a wash or worse.
One clean recording beat everything I scraped
I started by scraping audio out of videos I had already published, because it was free and it was there. My first clone came from 2 minutes 33 seconds of it and was good enough to be my keeper for weeks. Here it is:
Scraping more of it stopped helping quickly. I built a second corpus of 14 minutes 28 seconds from the same videos and it tied with the 2.5 minute version in a blind ranking.
Then I sat down and recorded 45 minutes in one session, one room, one microphone, one sitting. That corpus produced the CosyVoice and VibeVoice keepers, then trained the OmniVoice adapter that beat them.
Record properly instead of scraping. Clips pulled from videos shot across different rooms and days carry all those rooms into the model. Forty five minutes recorded on purpose is a couple of hours of your time and it is the single biggest quality jump I found.
The peak arrives early
With one model I extended a run from 3200 to 6400 steps because the curve looked like it was still climbing. The first 3200 were the whole gain. My CosyVoice keeper peaked even earlier, at epoch 4 of 31, so plan on auditioning early checkpoints rather than training longer.
Blind test 2
The ranking that picked the first keepers
This earlier five-file session contained both ElevenLabs voices, the CosyVoice and VibeVoice fine-tunes, and the real recording. It selected the two keepers I shipped before OmniVoice finished training. The newer sealed tests at the top of the article supersede its overall order.
| File | What it was | What I said, before the reveal |
|---|---|---|
| A | ElevenLabs, scavenged source | "bad" |
| B | ElevenLabs, cleaner source | "good" |
| C | VibeVoice, fine-tuned | "good, maybe slightly better. honestly best" |
| D | Me, the real recording | "so good that I think it's probably legit me" |
| E | CosyVoice, fine-tuned | "good, maybe slightly better than B" |
Read C and D together. I called the fine-tuned model "honestly best" and, separately, flagged the real recording as "probably legit me." I did identify the human. I also rated a synthetic clone at the top of the set while doing it. Both paid clones landed below both fine-tunes.
That established the first practical bar for narration, and it stood for weeks. Every model in this session has since been beaten by a fine-tune that did not exist when I ran it. The order at the top of the article is the current one.
Cost
What each option actually costs
| Option | Cost | Limit | You own it? |
|---|---|---|---|
| ElevenLabs Creator | $22/mo forever | 100k credits, ~100 min | no |
| ElevenLabs Pro | $99/mo forever | 500k credits | no |
| Fine-tune your own | under $1 per run ~$5 to a first clone plus GPU time to render | none | your adapter, subject to the base-model licence |
The whole project, including every failed experiment and dozens of training runs, came to about $17 of GPU time. That is less than one month of the cheapest tier that supports professional voice cloning.
I did not provision or run any of this infrastructure by hand. I described what I wanted to an AI coding agent, it stood up the environment, rented the GPU, ran the training, and shut the machine down when it was done. The plan above is the instruction set, and everything it needs to get right is already in it.
The cost is a few dollars of rented GPU and the time it takes you to record.
One honest asterisk on that comparison: the $22 a month buys inference too, and self-hosting does not. Training is a one-off, but every minute of narration afterwards needs a GPU. At my volume that is pennies of pod time per batch. If you are generating a hundred minutes a month you should price it against the tier that covers it, not against the training run.
Generalisation
The 124-word script exposed silent drops
OmniVoice checkpoint 500 read the 67-word verdict script with 100% coverage and zero dropped words. On 124 unseen words, the same checkpoint fell to 86% to 91% coverage. Every take silently dropped 11 to 21 words.
A caveat I owe you about that number. "Coverage" here means the share of scripted words that Whisper heard in the render. I used it to pick takes for weeks, and it is worse than useless as a quality score. It measures Whisper's transcription, not the model's speech, so a robotic render that Whisper parses cleanly outscores a natural one it stumbles on. It ranked a take I described as sounding like Steve Urkel at the top of a ladder. It told me 24 words were missing from a take where the full script was plainly there. It scored 100% on OmniVoice clips where I could hear words being dropped. I keep the numbers below because the direction is real and the drop is large, but I no longer choose anything by them.
| Model and script | Word coverage | Words dropped |
|---|---|---|
| OmniVoice ck500, 67 words | 100% | 0 |
| OmniVoice ck500, 124 words | 86-91% | 11-21 every take |
| CosyVoice keeper, 124 words | 95-97% | 3-6 |
| Dots.TTS fine-tuned, 124 words | no drops heard | judged by ear |
Length is its own test, and it reorders the table. OmniVoice wins on speaker similarity and then loses continuity as the script grows. CosyVoice held long-form better and was my keeper for exactly that reason, until fine-tuned Dots.TTS beat it on both. A 23-second demo and a ten-minute narration are different tests, and most published demos are the former.
Before you ship it
Licence, consent, and the things that decide this in practice
Check the licence before you pick a winner
"You own the weights" in the cost table is doing more work than it looks. You own the adapter you trained, on top of a base model whose terms you did not write. Checked on Hugging Face, 24 August 2026:
| Base model | Licence |
|---|---|
| FunAudioLLM/Fun-CosyVoice3-0.5B-2512 | Apache 2.0 |
| vibevoice/VibeVoice-1.5B | MIT |
| IndexTeam/IndexTTS-2 | custom: "bilibili Model Use License Agreement" |
| Qwen/Qwen3-TTS-12Hz-1.7B-Base | Apache 2.0 |
| ResembleAI/chatterbox | MIT |
| coqui/XTTS-v2 | Coqui Public Model License 1.0.0, non-commercial |
| Audio8/Audio8-TTS-Preview-0.6b | Apache 2.0 |
| Audio8/Audio8-TTS-Preview-0.1b | custom: Audio8 Community License v1.0 |
| OpenMOSS-Team/MOSS-TTS-v1.5 | Apache 2.0 |
| k2-fsa/OmniVoice | CC-BY-NC on the pretrained weights |
| dots-studio/dots.tts-soar | Apache 2.0 |
Four of the eleven systems understate their restriction on the surface. IndexTTS-2 uses the bilibili Model Use License. XTTS-v2 is non-commercial, including its outputs. Audio8's 0.1b model uses a revenue-limited community licence even though its larger 0.6b sibling is Apache 2.0. OmniVoice is the easiest trap: the GitHub code is Apache 2.0 and the Hugging Face card has no licence tag, but the README licenses the pretrained weights under CC-BY-NC because the training data includes Emilia.
That code-versus-weights split also applies to F5-TTS: MIT code, CC-BY-NC weights, again because of Emilia. It remains an interesting research fine-tune, but its public weights are not the commercial next step a licence badge can make them look like.
One provenance note: I trained on vibevoice/VibeVoice-1.5B, a community copy, and Microsoft's first-party microsoft/VibeVoice-1.5B is also live and also MIT. Prefer the first-party repo, and read the licence on the specific checkpoint you pull, since a mirror can carry different terms than its source and terms change between releases.
Clone your own voice, and say that it is synthetic
Everything here is my voice, my recording, my consent. Cloning someone else's without permission is a legal problem in a growing number of places: Tennessee's ELVIS Act covers voice explicitly, right-of-publicity law applies in many US states, and the EU AI Act carries transparency obligations for synthetic media. None of that is legal advice, and all of it is worth ten minutes before you point this at a voice that is not yours. Label synthetic narration as synthetic.
Where this test stops
Eleven systems is what I ran, and the field is bigger. F5-TTS, Fish Speech, Higgs Audio, and Sesame CSM went untried. F5-TTS can be fine-tuned, but its public weights are CC-BY-NC. Higgs Audio v3 ships without training code and is research-only/non-commercial. Sesame CSM also ships without training code, and its public repository has been stale since 27 May 2025.
The long-form question now has a measured answer. OmniVoice was perfect on 67 words and dropped 11 to 21 words from every 124-word take. Fine-tuned Dots.TTS, the keeper, reads the same 124 words without dropping anything I can hear, and CosyVoice held 95% to 97% before it. Ten-minute narration still needs a stitching pass and per-chunk take selection, and I have not run one end to end yet.
Versions
Text to speech moves monthly, so these results are pinned to what I ran in August 2026: dots-studio/dots.tts-soar, OpenMOSS-Team/MOSS-TTS-v1.5, FunAudioLLM/Fun-CosyVoice3-0.5B-2512, vibevoice/VibeVoice-1.5B, IndexTeam/IndexTTS-2, Qwen/Qwen3-TTS-12Hz-1.7B-Base, coqui/XTTS-v2, Audio8/Audio8-TTS-Preview-0.6b, Audio8/Audio8-TTS-Preview-0.1b, OpenMOSS-Team/MOSS-TTS-v1.5, k2-fsa/OmniVoice, dots-studio/dots.tts-soar, and chatterbox-tts from PyPI. Assume a model released after this article behaves differently, and re-run the test rather than trusting the table.
What I would tell someone starting today
Fine-tune Dots.TTS soar. It is Apache 2.0, it is 2.2B so it trains and renders cheaply, and it won my final rounds. If it disappoints you, fine-tuned MOSS-TTS v1.5 is close enough to swap in without changing anything else.
Budget for three to five takes per clip, not one. This is the part I underestimated for weeks. Every model here is stochastic, and the same checkpoint gives you a usable take and an unusable one on the same script. Screen them by duration against each other, then listen to what survives.
For zero-shot, start with Dots.TTS. It is Apache 2.0, it needs no training, and it beat OmniVoice zero-shot head to head. It is also the model that won once fine-tuned, so it is a reasonable starting point either way.
Record one clean session before you touch a model. Forty five minutes from a phone in a quiet room beat everything I scavenged.
Then rank blind, and rank more than one take per model. Every time I evaluated with the labels visible, I confirmed what I already believed. Every time I ranked a single take, I got a result that did not reproduce.
So I can narrate the research instead of filming it
I run NexusTrade, an AI-powered trading research platform, and I publish what it finds. The writing is the work; recording it was the tax. Now the articles narrate themselves and I spend the time on the analysis.
The platform is built the same way this test was: run the experiment, rank it blind, publish the number even when it says you were wrong.
Explore NexusTrade
No comments yet.