File size: 3,517 Bytes
76b33c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
---
license: other
license_name: lfm-open
base_model: juanquivilla/sotto-cleanup-lfm25-350m-mlx-5bit
library_name: mlx
tags:
- mlx
- lfm2
- text-cleanup
- dictation
- course-correction
- lora
language:
- en
pipeline_tag: text-generation
---

# LC-lfm2.5-350m β€” dictation cleanup with course-correction

A small, fast **on-device voice-dictation cleanup** model: it turns messy spoken
transcripts into clean written text, and β€” unlike most cleanup models β€” it
**honors spoken self-corrections** ("book the 7pm flight *no wait* the 9pm one"
β†’ "Book the 9pm flight.").

Built for [MacWispr](https://github.com/vasanthsreeram/macwispr). This repo ships
the **fused** model (LoRA baked in) so you can pull and run it directly; the
standalone LoRA adapter is under [`lora-adapter/`](./lora-adapter).

- **Base:** `juanquivilla/sotto-cleanup-lfm25-350m-mlx-5bit` (LFM2.5-350M, MLX 5-bit)
- **Method:** LoRA (8 layers, 600 iters, LR 5e-6), fused into the base
- **Runtime:** MLX (Apple Silicon) β€” also loadable in Swift via `mlx-swift-lm` (LFM2)

## What it does

1. Removes fillers and stutters ("um", "uh", "that that" β†’ "that").
2. **Honors self-corrections** β€” drops the retracted item, keeps the replacement,
   and keeps the rest of the sentence.
3. Writes numbers as digits ("three seventy-five" β†’ "375").
4. Fixes light grammar/punctuation/capitalization without summarizing.

## Prompt format

Trained on a raw completion format (**not** a chat template):

```
### Input:
{raw dictation}

### Output:
```

## Usage (mlx-lm)

```python
from mlx_lm import load, generate
from mlx_lm.sample_utils import make_sampler

model, tok = load("vasanth009/LC-lfm2.5-350m")
raw = "set the oven to three fifty no wait three seventy five for the lasagna"
prompt = f"### Input:\n{raw}\n\n### Output:\n"
out = generate(model, tok, prompt=prompt, max_tokens=64, sampler=make_sampler(temp=0.0))
print(out.split("###")[0].strip())
# -> Set the oven to 375 for the lasagna.
```

To apply the LoRA to the base yourself instead of using the fused weights:

```bash
mlx_lm.generate --model juanquivilla/sotto-cleanup-lfm25-350m-mlx-5bit \
  --adapter-path lora-adapter --prompt "### Input:\n...\n\n### Output:\n"
```

## Honest evaluation (leak-free held-out)

Graded by an LLM judge on a **94-item held-out set generated on topics disjoint
from training** (0/94 overlap with the training data β€” verified). This is a real
generalization test, not memorized phrases.

| Model | Course-correction | Light cleanup | Preserve (anti over-edit) |
|-------|------------------:|--------------:|--------------------------:|
| Base (Sotto LFM2.5-350M) | 10/16 | 12/12 | 6/8 |
| **This model (+LoRA)** | **13/16** | 12/12 | **7/8** |

Course-correction is the headline improvement (10β†’13/16). Light cleanup was
already strong (tie). Latency ~50–100 ms/utterance on Apple Silicon.

### Limitations

- The base is **5-bit quantized**; rare token corruptions can occur
  ("simmer" β†’ "smear"). A higher-precision base would reduce this.
- 350M parameters β€” capable for cleanup, not a general assistant. It only cleans
  text; it does not answer questions in the transcript.
- Occasionally over-shortens a long correction (drops a trailing clause).

## Provenance

Training data (course-correction / light-cleanup / preserve pairs) was generated
and QC-filtered with an LLM on fresh topics, with a hard leakage gate against the
held-out eval. See the MacWispr repo's `bench/polish_finetune/` for the full,
reproducible pipeline.