joddabod/anotherstt-formatter
anotherstt formatter
A Qwen3 1.7B fine-tune that turns a raw speech transcript into the text you meant to type. It removes fillers and stutters, applies spoken corrections ("at 6, no wait, 6:30"), fixes punctuation and casing, writes numbers, times and emails the normal way, and adds bullets, numbered lists and paragraphs when you clearly dictated them. It's the formatter in another-stt, a free, fully offline dictation keyboard for Android and Linux, and it runs on a phone.
It never answers or acts on what you dictate. A prompt to an AI assistant comes out as the same prompt, cleaned up.
Files
formatter-q4_k_m.gguf: 4-bit (Q4KM), 1.1 GB, for llama.cpp.
Prompt
It was trained on this exact format (Qwen3 chat template, thinking off):
<|im_start|>system
Clean up this dictation.<|im_end|>
<|im_start|>user
{transcript}<|im_end|>
<|im_start|>assistant
<think>
</think>
Decode greedily. The output ends at <|im_end|>.
Run it with the word constraint
For dictation you can send without reading, run the model under a grammar built from each transcript. The grammar only lets it write the speaker's own words in order, punctuation, and numbers that were actually said. It can still drop fillers and retracted corrections, but it can't invent a word, swap one, reorder anything, or change a number. another-stt's constrain.py builds the grammar, and llama.cpp takes it through --grammar or the server's grammar field.
Two more things make it fast on a phone. Output mostly copies the transcript, so drafting the next tokens from the transcript and checking them in one batch (prompt lookup) gets about three tokens per model call instead of one. And the transcript can be fed in chunk by chunk while the user is still talking.
Training
Full fine-tune of Qwen3 1.7B, with the embedding and output layers frozen, on about 1,400 handwritten dictation pairs. Each input was also spoken by Kokoro TTS and transcribed by Parakeet TDT 0.6B v2, so the model sees real recognizer output: numbers as digits, stray capitals where audio chunks meet, and misheard words.
Limits
- English only.
- It can't fix words the recognizer misheard: the constraint keeps what was transcribed. The app handles known terms with a personal dictionary before the formatter runs.
- It sometimes drops a small word, and a correction whose fix needs words reordered ("go left at the light, no, right") can't be applied under the constraint.
