Post-Processor Models for Super STT
A few weeks ago @svieujot opened super-stt#388 suggesting that Super STT should let users configure a post-processor model. The prompt was SuperWhisper's new S1 family, and the idea is simple: after the speech-to-text model produces a raw transcript, run it through a small language model that cleans up filler words, fixes formatting, and generally makes the result look like something you actually meant to type.
Before I go further, a quick clarification. SuperWhisper is a commercial dictation app for macOS, Windows, and iOS. Super STT is my own open-source project for Linux, and the two are not affiliated in any way. The names are similar, but they are separate projects. I'm writing about SuperWhisper's S1 models here because they are a useful reference point for a feature Super STT now ships, not because there is any relationship between the two.
The feature landed fast. The issue was opened on August 29, and by September 9 it was closed with v0.2.4, which ships post-processor support along with two post-processor backends.
What SuperWhisper Shipped
SuperWhisper released three models under the S1 banner:
- S1-Voice: a cloud-hosted speech-to-text model.
- S1-Language: a cloud-hosted instruction-following model for heavier cleanup, summarization, and custom modes.
- S1-mini: a 484 MB, 0.6B parameter language model that runs locally with open weights on Hugging Face.
The interesting one for Super STT is S1-mini. It is small enough to run on a laptop or low-power device, requires no network requests, and is narrowly focused on cleaning up STT output: removing filler words and stutters, formatting lists and emails, rendering numbers and dates consistently, and applying a chosen tone from casual to formal. SuperWhisper reports 94.8% token accuracy and a 11.6% text-edit error rate on their held-out test set.
The model is also deliberately constrained. It will not add facts, soften language, correct profanity, or rewrite dialect. Its only job is to clean what the STT model already produced.
How It Fits Super STT
In my last Super STT post I described how the project is built around backends. Each backend adds support for a model family and runs inside a sandbox. Some are WASM binaries for CPU or online models, others are subprocesses for GPU-heavy work.
A post-processor fits that architecture cleanly, and the implementation leaned on it. A post-processor is an ordinary backend model, distinguished only by a new role field on [[models]]:
toml[[models]] name = "textclean" role = "post_processor"
That reuses the same discovery, install, files, devices, options, and secrets that a regular backend uses.
The flow is:
- The STT backend transcribes audio into raw text.
- The engine passes that raw text to the post-processor backend.
- The post-processor backend returns polished text.
- The engine types the polished text into the active field.
Note: The previews and realtime transcriptions are still raw text. Post-processing is only applied to the final transcription.
A Pipeline Instead of a Single Backend
The daemon now exposes a pipeline where stages are addressed by position:
| Verb | Path |
|---|---|
| Select / deselect a stage's backend | POST / DELETE /pipeline/{stage} |
| Run / stop a model in it | POST / DELETE /pipeline/{stage}/model |
| Abort a load, reload in place | POST /pipeline/{stage}/model/{cancel,reload} |
| Read every stage in order | GET /pipeline |
Stage 1 transcribes, stage 2 post-processes, while stage 3 remains open for future expansion. The pipeline is a list of stages, and each stage has a single backend and a single model.
Two Post-Processor Backends
Along with the support, two post-processor backends shipped.
S1-mini
super-stt-s1-mini runs S1-mini by SuperWhisper on your transcripts before they are typed. It is a subprocess backend, so it can use the GPU, and it runs entirely on your machine.
The model is steered with three settings, each a closed set it was trained on:
| Setting | Values | Default | What it does |
|---|---|---|---|
| Styling | casual, semi-casual, semi-formal, formal | semi-formal | The register. casual is all lowercase with apostrophes stripped; semi-casual keeps your phrasing but capitalizes I and its contractions; semi-formal is standard written English with contractions kept; formal also expands contractions. |
| Structure | prose, lists | prose | Whether an enumeration of three or more items may become a Markdown bullet list. |
| Context | general, email | general | email lays the text out as a greeting line, the body, and a sign-off block, separated by blank lines. |
The model is the s1-mini-q4_k_m build, the Q4_K_M quantization the model card recommends and measured its accuracy on. It is English only.
Tidy
super-stt-tidy is the opposite approach: a rule-based backend, not a model. It is a ~200 KB WASM component with no weights to download and no network egress at all.
The rules are the same family of normalization applied to text corpora before training: fold typographic Unicode to ASCII, strip invisibles, drop vocalized fillers, repair spacing, restore casing. Each rule is a separate setting, on by default:
| Rule | Setting | What it does |
|---|---|---|
| Normalize punctuation | normalize_unicode | Replaces smart quotes with straight ' and ", en and em dashes with -, and … with .... Non-breaking spaces become regular spaces, and zero-width characters and control bytes are dropped. |
| Remove filler sounds | remove_fillers | Drops um, uh, erm, hmm and similar. |
| Collapse stutters | dedupe_words | Collapses an immediately repeated word, so the the becomes the. |
| Repair punctuation spacing | fix_punctuation | No space before , . ! ?, one space after; doubled marks collapsed; brackets unpadded. |
| Collapse whitespace | collapse_whitespace | Collapses runs of whitespace into a single space, and trims leading and trailing whitespace. |
| Fix sentence casing | sentence_case | Capitalizes sentence starts and the standalone pronoun i. |
An LLM post-processor can do more: rephrasing, formatting to intent. Tidy does less, deliberately, and never adds words you did not say. It is fast, private, small, and predictable: the same input always produces the same output.
The two backends are complementary. Tidy is the instant, zero-cost cleanup for people who just want their dictation to read cleanly. S1-mini is the heavier option for people who want the full normalization pass, at the cost of a model download and a round trip.
What's Next
The post-processor idea opens up more than cleanup. In the issue thread I noted the potential for post-processors to change how transcriptions are written and formatted. Maybe even converting to full Markdown with headers, bold, and italics automatically. That is a different kind of post-processor than S1-mini, but it slots into the same stage.
There are also open follow-ups from the implementation: whether realtime sessions should be post-processed, and stage renumbering rules once stages become insertable. For now, the pipeline is two stages, and the feature is shipped.
Thanks to @svieujot for the suggestion that kicked this off.
Sources
- super-stt#388 - Add the possibility to setup a post processor model
- super-stt#391 - Add transcript post-processing and a pipeline-addressed model API
- Super STT v0.2.4 release notes
- super-stt-s1-mini backend
- super-stt-tidy backend
- SuperWhisper - Introducing the S1 family of models
- S1-mini on Hugging Face