EN

Running Whisper on a Mac: Subtitles Without the Cloud

How we run Whisper on Mac with WhisperKit and Core ML: why on-device, which model we picked, the 3-minute first load, disk space and language detection.

Nicolas Ricardi7 min read

In short

  • JustRec makes subtitles with Whisper running on the Mac through WhisperKit, so your voice never leaves your computer.
  • We use a compressed Core ML build of Whisper large-v3 turbo of about 626 MB, downloaded once.
  • The first load took around three minutes and a lot of temporary disk space, because Core ML specializes the model for your chip; after that it loads in seconds.
  • Transcription starts from the microphone track as soon as you stop, in parallel with the video export.

You can run Whisper on a Mac entirely on device: the model weights are open source, and WhisperKit runs them through Core ML on Apple Silicon. That’s how JustRec makes subtitles for every recording without sending a second of audio to anyone. Below: how we set it up, which model we picked, and what surprised us (a 626 MB download, a first load of about three minutes and, once, a full disk).

Why subtitles had to run on the Mac

The promise on our home page is simple: your voice is never sent to an external AI. Our users record client work: a design review with names on screen, a quote explained line by line, a bug in a client’s admin panel. Sending that audio to a transcription API would mean one more company processing their clients’ data, one more line in a privacy notice, and one more thing to explain to a careful client. Keeping the voice on the Mac fits the rest of the product, which is built local-first and keeps shared copies in the EU.

There were practical reasons too:

  • No cost per minute. A cloud API charges for every minute of audio. On the Mac, the cost is the user’s electricity.
  • Works offline. After the model is downloaded, subtitles work on a train.
  • Subtitles before the upload. Transcription can start the moment you press stop, while the video is still exporting.

We wrote a longer, non-technical comparison in on-device vs cloud transcription. This article is the engineering side.

WhisperKit and Core ML

Whisper is OpenAI’s speech recognition model, released with its code and weights under the MIT license. It handles multilingual speech recognition and language identification, which is what we need for subtitles in the language you speak.

To run it well on a Mac you need it in Core ML format, so it can use the Neural Engine and GPU. We use WhisperKit, part of Argmax’s open-source Swift SDK (MIT license). It downloads Core ML builds of Whisper from Hugging Face, caches them locally, and gives you a Swift API for transcription with word timestamps and voice activity detection. It requires macOS 14, below our own macOS 15 minimum.

We looked at Apple’s own SpeechAnalyzer too. It’s promising, but it needs macOS 26, and JustRec supports macOS 15. WhisperKit runs everywhere our app runs.

Choosing the model

Whisper comes in several sizes, and the trade-off is the usual one: bigger models are more accurate and slower. OpenAI’s own table:

Whisper model sizes, as OpenAI publishes them
Size Parameters Memory needed Relative speed
tiny 39 M about 1 GB about 10x
base 74 M about 1 GB about 7x
small 244 M about 2 GB about 4x
medium 769 M about 5 GB about 2x
large 1,550 M about 10 GB 1x
turbo 809 M about 6 GB about 8x

From the openai/whisper README, checked November 2026. Relative speed compares models with each other, not with a Mac.

Turbo is the interesting row: close to the large model, at about half the parameters and many times the speed. On a Mac you don’t download these PyTorch checkpoints, though. You download a Core ML conversion, and Argmax publishes many variants. A few from their repository, with the size of each download:

Some of Argmax's Core ML builds of Whisper
Variant Download size Notes
small about 216 MB Fast and light; less accurate
distil-large-v3 about 594 MB Distilled large model
large-v3-v20240930 (turbo) about 547 MB or 626 MB Two compressed builds of large-v3 turbo
large-v3 about 947 MB The full large model

Sizes from the argmaxinc/whisperkit-coreml repository on Hugging Face, checked November 2026.

We use large-v3-v20240930_626MB. The v20240930 name is the release where OpenAI added large-v3 turbo, which OpenAI describes as an optimized version of large-v3 with faster transcription and minimal accuracy loss. Its config confirms the trick: the full 32-layer encoder, but only 4 decoder layers.

Why this one? We needed Italian to come out right, not just English, and with this model Italian was correct in our tests. On our development Mac it transcribed about 15 seconds of audio in 3 seconds. It’s also the model Argmax uses in its own README examples.

The cost is size: 626 MB is a lot to ask for an app that is otherwise small. We download it once, into the app’s Application Support folder, and tell the user what’s happening.

The first load: three minutes and a full disk

The download wasn’t the slow part. The first time we loaded the model, it took around three minutes before transcribing anything, and it used a lot of temporary disk space. Once, it filled the disk.

  1. First load

    About three minutes before the first word

    Plus a lot of temporary disk space. Once, it filled the disk.

  2. The cause

    Core ML specialization

    The model is compiled for your chip on first load and cached outside the app.

  3. The change

    Load it during setup

    The model is downloaded and loaded once during onboarding, so the wait comes before the first recording.

WhisperKit’s own documentation explains why. Core ML models are downloaded in a device-agnostic format and have to be “specialized” to your chip before they run. Core ML does this the first time the model loads, and caches the specialized files on disk, outside the app. Apple maintains that cache, and it’s evicted after every OS update or if the model isn’t used for a long time. When the cache is hit, loading takes seconds: about 3 seconds for us.

What we changed after learning this:

  1. Prepare the model during first-run setup. While you grant permissions and pick a shortcut, JustRec downloads the model and loads it once, then unloads it. The three minutes happen before your first recording, not after it.
  2. Show progress. The download reports its progress, so a large first download doesn’t look like a frozen app.
  3. Expect it again after macOS updates. Because the cache can be cleared, the first transcription after an update can be slow again. That’s normal.
  4. Leave room on disk. If your Mac is nearly full, the specialization step is where you’ll feel it.

From recording to subtitle file

The pipeline is short, and most of the work is in the details.

Audio from the right track. We record the microphone and system audio as separate files (the ScreenCaptureKit article explains why). For subtitles we use the microphone alone, or system audio if there’s no microphone. That means no notification sounds or video soundtracks confusing the model, and transcription can start right away instead of waiting for the exported MP4.

16 kHz mono. Whisper expects 16 kHz mono audio. We read the track with an AVAssetReaderAudioMixOutput that converts as it reads. If a recording has several microphone pieces (you switched microphones halfway), they’re placed at their real start times and any gap is filled with silence, so timestamps stay aligned with the video.

let options = DecodingOptions(
    language: code,               // nil means "detect"
    detectLanguage: code == nil,
    skipSpecialTokens: true,
    wordTimestamps: true,
    chunkingStrategy: .vad        // split on voice activity
)
let results = try await pipe.transcribe(audioArray: samples, decodeOptions: options)

Word timestamps into readable cues. Whisper’s segments are often too long for a subtitle. We ask for word timestamps and rebuild the cues ourselves: at most 84 characters and 6 seconds per cue, a break after a full stop or a question mark once a line has some length, and two lines balanced by length. Overlapping cues are trimmed so two never show at once.

Two files next to the video. The result is saved as SRT and VTT beside the MP4 in your library. When you share, the VTT goes up with the video; if subtitles finish after the upload, they’re added to the link when ready. The first words also become the suggested title for the video.

If you want to do the same for your own recordings with any tool, our guide on adding subtitles to a screen recording on Mac walks through the options.

Language detection

In Settings, subtitles can be set to automatic, Italian or English. On automatic, Whisper identifies the language before transcribing, and we log what it detected. It works for the languages JustRec supports, including English, Italian, Spanish, French, German and Portuguese, which matters for agencies that work across borders.

Automatic detection has the usual weak spots: very short recordings, recordings that start with silence, or someone switching languages halfway. If you always speak the same language, set it by hand and the guess disappears.

What we’d tell another developer

Shipping Whisper in a Mac app

  • Pick the model on your users’ languages, not on English benchmarks.
  • Budget for the first load: download, then Core ML specialization, then the real work.
  • Do that first load during onboarding, with visible progress.
  • Transcribe the cleanest audio track you have, not the final mix.
  • Build your own cues from word timestamps; raw segments read badly.
  • Test with low disk space and after a macOS update.

What’s next

Translated subtitles are planned: the transcription stays on the Mac, and the translation would too. We’re also watching Apple’s SpeechAnalyzer for the day our minimum macOS allows it.

For why subtitles matter to the people watching, see why subtitles get your videos watched on mute. For everything else the app does, the features list has it in one place.

Sources

Frequently asked questions

Can you run Whisper on a Mac without the cloud?

Yes. Whisper's weights are open source under the MIT license, and libraries such as WhisperKit convert them to Core ML so they run locally on Apple Silicon. After the model is downloaded once, transcription needs no internet connection.

How big is the Whisper model?

It depends on the variant. Among Argmax's Core ML builds, small is about 216 MB and the full large-v3 about 947 MB. JustRec uses a compressed large-v3 turbo build of about 626 MB.

Why is the first Whisper load so slow on a Mac?

Core ML specializes the model for your specific chip the first time it's loaded and caches the result on disk. With our model that took around three minutes. Later loads hit the cache and take a few seconds, until a macOS update clears it.

Does Whisper detect the language automatically?

Yes, Whisper can identify the spoken language before transcribing. If you always speak one language, setting it by hand avoids the occasional wrong guess on short or mixed-language recordings.

Does JustRec send my voice to an AI service?

No. Subtitles are generated on your Mac by a speech-to-text model that runs locally. Only the subtitle file is uploaded with the video when you share it.

Written by

Nicolas Ricardi

Maker of JustRec, at Nube

Nicolas makes JustRec at Nube, a web studio in Italy. He built it for the videos Nube sends to its own clients: design reviews, handovers and quotes explained in a few minutes instead of a meeting.

www.wearenube.dev
Build in public