uttrflow / uttrflow/uttrflow-swift
The first dictation after a reboot waits 154 s while the speech model loads
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
The first dictation after a reboot waits about two and a half minutes for the speech model
to load. The app is honest about it now — the menu bar says it is loading rather than
"Ready" — but the wait itself is untouched, and it is the worst first impression the product
makes.
## Where it is
`Docs/startup.md:28-31`, measured on the shipped bundle:
| | |
|---|---|
| first load after boot, cold page cache | **154 s** |
| every load after that, warm | 2.1 s |
`applicationDidFinishLaunching` starts the load at
`Sources/Uttrflow/AppDelegate.swift:174` → `loadSpeechModel()` →
`AppDelegate.swift:193` (`await self?.pipeline?.prepare()`), so the clock usually starts
before anyone tries to dictate — but after a reboot, a login-item launch and a quick first
dictation still land inside those 154 seconds.
`Docs/startup.md:63-67` names the cause and declines to fix it there: the time is CoreML
compiling and paging in a 632 MB model, "and the lever is the model, not this code".
`Docs/performance.md:291-303` records the other side of the same call: preparing at launch
holds 219 MB of footprint / 409 MB resident for the whole session, including for people who
only ever use the clipboard.
## What to change
This one is open, and the first useful contribution is a measurement rather than a patch.
Worth knowing, roughly in this order:
1. Where the 154 seconds actually go — CoreML compilation of the model, first page-in of the
weights, or both. `Instruments` or a timestamped log around `SpeechModelStore` and the
engine's `prepare()` would settle it.
2. Whether a compiled model artefact can be produced once at install time instead of on
first load, and what that costs on disk.
3. Whether a smaller model as a first-run default, upgraded in the background, is a better
trade than either.
Say what you measured and on what hardware; a number from one Mac is still a number, and
there is none in the repository today apart from the two above.
## Notes
- Do not report a figure taken on a warm cache. `Docs/startup.md:25-31` describes how the
cold reading was taken; a reboot is the only honest way to get one.
- `BackedSpeechEngine.transcribe` loads on demand if nobody prepared it, so removing the
launch-time call is possible — it moves the wait onto the first dictation rather than
removing it, which is why it is not obviously right.
Contributor guide
Research direction
Start with Docs/startup.md:25-31 and the launch path at Sources/Uttrflow/AppDelegate.swift:174 and AppDelegate.swift:193. Measure a cold post-reboot load with Instruments or timestamped logs around SpeechModelStore and prepare(), using the hardware and cache conditions described. Done means reporting where the 154 seconds go and comparing the possible model or launch-time trade-offs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, swift
- Domain
- desktop, machine-learning, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100