Skip to main content
Efficient memory management is critical when deploying large Whisper models on Apple devices. This guide covers prewarming, model caching, resource allocation, and strategies for minimizing memory footprint.

Understanding Memory Usage

WhisperKit’s memory footprint consists of:

Model Weights

75 MB (tiny) to 3 GB (large-v3)

KV Cache

Dynamic during decoding

Audio Buffers

Mel spectrograms and features

Model Size Reference

Loaded memory includes model weights, CoreML runtime overhead, and active computation buffers.

Model Prewarming

What is Prewarming?

CoreML models are downloaded as device-agnostic .mlmodelc files and must be “specialized” (compiled) for your specific device chip before use. Apple caches these specialized models, but the cache is evicted:
  • After OS updates
  • When not used for extended periods
  • When system storage is low
Prewarming triggers specialization sequentially to minimize peak memory.

Configuration

Prewarming Workflow

1

Load Model 1

Load audio encoder → specialization if needed
2

Unload Model 1

Immediately release audio encoder memory
3

Load Model 2

Load text decoder → specialization if needed
4

Unload Model 2

Release text decoder memory
5

Final Load

Load all models together (now cached)

Trade-offs

Pros:
  • Lower peak memory (1 model at a time)
  • Safer for background/low-memory apps
  • Prevents crashes on older devices
Cons:
  • 2x longer load time when cache is hit
  • Unnecessary overhead if cache is fresh

When to Use Prewarming

  • Deploying on older iOS devices (iPhone 11 and earlier)
  • Using large models (medium, large-v3) on mobile
  • App runs in background or as extension
  • Memory pressure warnings occur
  • First launch after OS update
  • Deploying on M1/M2/M3 Macs with ample RAM
  • Using small models (tiny, base)
  • Load time is critical (real-time apps)
  • Models are loaded once and cached

CoreML Model Cache

Cache Location

Apple maintains CoreML specialized model cache outside your app bundle:
This cache is:
  • Managed by the OS (you cannot directly control it)
  • Device-specific (different for each chip)
  • Persistent across app launches
  • Evicted unpredictably by the system

Checking Cache Status

No official API exists, but you can measure load time:

Prefilling KV Cache

Accelerate decoding with prefilled key-value cache:
KV cache prefill reduces first-token latency by 2-3x by preloading common decoder states.

Resource Allocation

Compute Units and Memory

Different compute units have different memory characteristics:
.cpuOnly
  • Memory: Uses system RAM
  • Usage: 200-400 MB additional overhead
  • Best for: Extreme memory constraints
.cpuAndGPU
  • Memory: Uses unified memory (shared with CPU)
  • Usage: 300-600 MB additional overhead
  • Best for: Balanced performance
.cpuAndNeuralEngine
  • Memory: Uses dedicated ANE memory + system RAM
  • Usage: 400-800 MB additional overhead
  • Best for: Maximum speed on supported devices

Optimizing Compute Units for Memory

Memory Monitoring

Runtime Memory Tracking

Xcode Instruments

1

Open Instruments

Product → Profile (⌘I) in Xcode
2

Select Allocations

Choose “Allocations” template
3

Record Session

Run your app and transcribe audio
4

Analyze

Look for:
  • Peak memory usage
  • Memory growth over time
  • Allocation backtrace

Strategies for Large Models

Model Splitting

Load encoder and decoder separately:

Lazy Loading

Defer model loading until needed:

Unloading Models

Free memory after transcription:

Concurrent Processing

Worker Count and Memory

More workers = more memory:
Each concurrent worker may hold its own audio buffer and KV cache state. Start with defaults and adjust based on memory pressure.

Sequential Processing

Audio Buffer Management

Chunking Strategy

VAD chunking reduces memory by processing smaller segments:

Clip Timestamps

Manually segment long audio:

Platform-Specific Guidance

iOS Memory Limits

iOS has stricter memory limits than macOS:

macOS Memory Guidelines

M1/M2 Base
  • Recommended: small or distil*medium
  • Max: medium with prewarming
  • Avoid: large-v3 (may cause swapping)
M1 Pro/M2 Pro
  • Recommended: medium or distil*large-v3
  • Max: large-v3 comfortably
  • Concurrent workers: 8-16
M1 Max/M2 Max/M3 Max
  • Use any model including large-v3
  • Multiple instances possible
  • Concurrent workers: 16+

Background Execution

App Extensions

Background Tasks

Troubleshooting Memory Issues

Solutions:
  • Enable prewarming: prewarm: true
  • Use smaller model: tiny or base
  • Switch to CPU-only: computeOptions with .cpuOnly
  • Close other apps to free memory
Solutions:
  • Reduce concurrent workers: concurrentWorkerCount = 1
  • Enable VAD chunking: chunkingStrategy = .vad
  • Process files sequentially instead of in parallel
  • Use clip timestamps to segment long audio
May be memory pressure causing throttling:
  • Monitor with Xcode Instruments
  • Explicitly release unused references
  • Consider smaller model or reduced worker count
Cache being evicted:
  • Check available disk space (cache requires ~2x model size)
  • Verify OS version (cache behavior varies)
  • Consider bundling pre-compiled models (advanced)

Best Practices Summary

1

Profile first

Use Xcode Instruments to establish baseline memory usage
2

Choose appropriate model

Match model size to device capabilities and requirements
3

Enable prewarming on mobile

Always use prewarm: true on iOS devices
4

Optimize compute units

Balance performance and memory with appropriate compute units
5

Limit concurrency

Don’t exceed recommended worker counts for platform
6

Use chunking

Enable VAD for long audio files
7

Monitor in production

Log memory metrics and watch for pressure warnings
8

Test on oldest devices

Ensure app works on minimum supported hardware

Next Steps

Performance Optimization

Optimize speed and quality

Custom Models

Deploy optimized custom models