We train our polish model in the open

MacWispr's dictation polish — the model that turns raw speech-to-text into clean, structured writing — is a 0.8B model post-trained by us, on a Mac Studio. The full pipeline, eval suite, reward code, and results (including the failures) are open source.

Fully open source Training in progress Runs on-device ~200 ms
What the polish model does

You say “camping list — tent, headlamp, snacks, as bullets” and it writes an actual bulleted list. It cleans fillers, applies self-corrections (“no wait, almond milk”), structures lists and emails — and never answers your questions, only transcribes them. All locally, in about 200 ms.

The recipe

  1. SFT — supervised fine-tuning of Qwen3.5-0.8B on dictation-polish pairs (2,400 iterations, MLX on Apple Silicon).
  2. DPO — preference training against flattened outputs. Honest result: it made the model worse (see below), so our pipeline now gates it out automatically.
  3. GRPO — reinforcement learning where the reward is our open polish_verifier — the same rule-based scorer used in evals, so the model trains on exactly what we measure.
  4. 4-bit quantization — shrinks the best checkpoint to ~450 MB so it ships inside the app and runs offline.

Honest numbers

Our out-of-distribution suite: 40 unseen dictations covering lists, mixed formats, emails, and “don't touch this” prose, scored by the shared verifier. Same prompts, same scorer, against Claude Sonnet via API:

SystemPassBulletsChecklistNumberedMulti-listLatency
MacWispr local 0.8B (4-bit, on-device) 23/40 (57.5%) 3/4 2/4 2/4 2/8 191 ms
Claude Sonnet (cloud API) 25/40 (62.5%) 3/4 0/4 4/4 6/8 4,407 ms

Two cases behind a frontier cloud model, at 23× lower latency, with zero audio or text leaving your Mac. We're currently running a GRPO pass targeting the remaining gaps (multi-list and numbered lists) — results land in the repo when it finishes.

What we got wrong (and kept public)

Our DPO stage regressed the model from 55% to 48% because the preference pairs only taught “don't flatten lists” — and collapsed checklist and mixed-format skills as collateral. Our first GRPO attempt crashed on a dataset-format bug and the pipeline silently shipped the worse checkpoint. Both are documented in the run log, with the fixes: a verifier-driven reward and a gate that only promotes a checkpoint if it actually beats the previous best.

Everything is in the repo. Training pipeline: bench/polish_posttrain/ — the SFT/DPO/GRPO scripts, the polish_verifier reward, the 40-case eval suite, the Claude comparison harness, and raw results. Run logs and findings: docs/context/post-training/. Trained on a Mac Studio M3 Ultra with MLX.
See the training code Download MacWispr Back home