Fritter-TTS v1

A single-speaker text-to-speech fine-tune of Qwen3-TTS-12Hz-1.7B-Base on one voice: Daniel Rosehill, Irish-accented English. It is the text-to-speech side of the Fritter line: technical and general English, with AI model names, Linux commands, acronyms and version numbers read the way he reads them. There are no Hebrew words in its training data.

Licence and access. CC-BY-NC-4.0: free for non-commercial use with attribution. Access is by request, because this is a clone of a real person's voice. A personal project by Daniel Rosehill; not affiliated with Alibaba Cloud or NVIDIA.

It has not been benchmarked: no listening score or metric is reported here.

Listen

Before and after, on the same text. Before: the untuned base model, Qwen3-TTS-12Hz-1.7B-Base, cloning the voice from one reference recording. After: Fritter-TTS v1. Nothing here was picked by ear. Training takes were at most 15 s, so the longer passages (more than three sentences) are generated sentence by sentence and joined.

Text Before After
Restart the Docker container and check the logs again.
I'll SSH into the NAS and see why the backup job failed overnight.
The new release needs Python 3.12 and at least 16 GB of RAM.
The VPN drops whenever the router renews its DHCP lease. I've pinned a static IP for now and opened an issue on GitHub.
The fine-tune ran on an L40S for about an hour. After that I quantized it to Q4_K_M with llama.cpp and pushed the GGUF to Hugging Face.
I tried Claude Sonnet 4.5, GPT-5 and Gemini 2.5 Pro on the same prompt. Sonnet gave the cleanest JSON, so that's the one going into the pipeline.
The home server runs Ubuntu 24.04 with everything in Docker Compose. Home Assistant, Jellyfin and a small Postgres database each get their own container. Backups go to a Synology NAS every night, and a copy is synced to object storage once a week. It's not glamorous, but it has run for two years with almost no attention.
The build failed on CI but worked on my laptop, which is always a bad sign. It turned out the runner was on Node 18 while I was on Node 22. I pinned the version in the workflow file, cleared the npm cache and reran the job. Twenty minutes of debugging for a one-line fix, which is about the usual ratio.
My dictation setup uses a fine-tuned Parakeet model running locally on the GPU. I press a key on the macro pad, speak, and the text lands wherever the cursor is. The fine-tune fixed most of the technical vocabulary, things like Kubernetes, PyTorch and OpenRouter. Numbers were the last thing to sort out, so now I record version numbers the way I actually say them.
Most of my day now involves working alongside AI agents in the terminal. I describe what I want, the agent reads the repository, proposes a change and runs the tests. The trick is giving it enough context without burying it in detail. A short CLAUDE.md file with the project's rules does more than a long prompt ever did. When something goes wrong, I ask it to write down what it learned, so the next session starts smarter. It's not perfect, but it has changed how much I can get done in an afternoon. And I dictate almost all of it, which is why the speech models matter so much to me.

More on the public samples page, Fritter-ASR/Fritter-TTS-Samples: every line from the release run next to Daniel's real recordings, and longer passages generated in one pass.

How it was made

  1. Screening. Daniel's own speech-to-text recording takes (read sentences, recorded on a desktop microphone and his phone), screened for quality: sound events tagged with PANNs, quality scored with DNSMOS, noisy rooms left out. Sentences with Hebrew words were left out. Takes with digits were kept, so the model learns his readings of numbers and versions.
  2. Enhancement. Every take went through NVIDIA NemotronLabs RE-USE (OpenMDW-1.1), run as the audio-cpp/RE-USE-GGUF build through audio.cpp, then a podcast voice chain (EQ, de-ess, 2:1 compression, -20 LUFS), resampled to 24 kHz.
  3. Training. A full fine-tune (SFT) from the base model, the first run of this line.

Training

Data 9,125 takes of at most 15 s, about 743 min (12.4 h) after trimming: 8,424 speech-to-text takes from danielrosehill/Read-Aloud-Voice-Sentences (tech about 450 min, general English about 320 min before the length cap) and 731 read TTS takes without Hebrew words
Method Full SFT, upstream finetuning/sft_12hz.py with fixes (label shift, sub-talker, text_projection applied in training), fp32 master weights with bf16 autocast
Schedule LR 7e-6, 3 epochs, batch 2 x grad. accumulation 4, final checkpoint
Hardware 1 x L40S (Modal)

Usage

The speaker name is daniel.

import torch, soundfile as sf
from qwen_tts import Qwen3TTSModel

tts = Qwen3TTSModel.from_pretrained("Fritter-ASR/Fritter-TTS", device_map="cuda:0", dtype=torch.bfloat16)
wavs, sr = tts.generate_custom_voice(text="Pull the latest image, then restart the container with Docker Compose.",
                                     speaker="daniel", language="English")
sf.write("out.wav", wavs[0], sr)

Requires qwen-tts (tested with 0.1.1). The repo is gated: log in with a token that has access.

On-device (GGUF). Q8_0 and Q4_K_M builds for qwentts.cpp (CPU, Android, Vulkan) are in Fritter-ASR/Fritter-TTS-GGUF, same speaker daniel.

Version history

Version Date Data Repo
Fritter-TTS v1 2026-11-09 9,125 takes, about 743 min, RE-USE-enhanced this repo

Base model and licence notices

This model is a fine-tune of Qwen/Qwen3-TTS-12Hz-1.7B-Base, Copyright 2026 Alibaba Cloud, licensed under Apache-2.0 (text in LICENSE-Qwen-Apache-2.0). It was modified by fine-tuning. The CC-BY-NC-4.0 licence above covers the fine-tune; the base model's licence keeps applying to the base model.

Downloads last month
-
Safetensors
Model size
2B params
Tensor type
BF16
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for Fritter-ASR/Fritter-TTS

Finetuned
(58)
this model
Quantizations
2 models

Dataset used to train Fritter-ASR/Fritter-TTS

Spaces using Fritter-ASR/Fritter-TTS 2

Collection including Fritter-ASR/Fritter-TTS