Skip to main content
ModelState is an enum that represents the current lifecycle state of a WhisperKit or TTSKit model pipeline.

Overview

Model loading and management involves several distinct states. ModelState provides a single canonical type that can be referenced across UI components, callbacks, and utilities to track where a model is in its lifecycle.

Cases

unloading
ModelState
The model is currently being unloaded from memory.Description: “Unloading”
unloaded
ModelState
The model is not loaded in memory.Description: “Unloaded”
loading
ModelState
The model is currently being loaded into memory.Description: “Loading”
loaded
ModelState
The model is fully loaded and ready for use.Description: “Loaded”
prewarming
ModelState
The model is being specialized for the device (one-time compilation).Description: “Specializing”
prewarmed
ModelState
The model has been specialized and cached.Description: “Specialized”
downloading
ModelState
The model files are being downloaded.Description: “Downloading”
downloaded
ModelState
The model files have been downloaded.Description: “Downloaded”

Properties

description
String
A human-readable description of the current state.
let state = ModelState.loading
print(state.description) // "Loading"
isBusy
Bool
Returns true when a loading, unloading, downloading, or prewarming operation is in progress.
let state = ModelState.loading
if state.isBusy {
    // Show loading indicator
}
Returns true for: .loading, .prewarming, .downloading, .unloadingReturns false for: .unloaded, .loaded, .prewarmed, .downloaded

State Machine

The typical state transitions follow these patterns:
unloaded → downloading → downloaded → loading → loaded
unloaded → prewarming → prewarmed
loaded   → unloading  → unloaded

Download and Load Flow

When a model needs to be downloaded and loaded:
  1. unloaded - Initial state
  2. downloading - Downloading model files from remote
  3. downloaded - Files downloaded successfully
  4. loading - Loading model into memory
  5. loaded - Ready for inference

Prewarm Flow

When using the prewarm option (see WhisperKitConfig):
  1. unloaded - Initial state
  2. prewarming - Specializing model for device
  3. prewarmed - Specialization complete
  4. loading - Loading model into memory
  5. loaded - Ready for inference

Unload Flow

When unloading a model:
  1. loaded - Model in memory
  2. unloading - Freeing memory
  3. unloaded - Memory freed

Usage Examples

Observing State Changes

let whisperKit = try await WhisperKit(
    model: "openai_whisper-base",
    verbose: true
)

// Access current state
if whisperKit.modelState == .loaded {
    print("Model ready for transcription")
}

Using State Callbacks

func handleModelStateChange(oldState: ModelState?, newState: ModelState) {
    print("Model state: \(oldState?.description ?? "none")\(newState.description)")
    
    switch newState {
    case .downloading:
        showDownloadProgress()
    case .loading:
        showLoadingIndicator()
    case .loaded:
        hideLoadingIndicator()
        enableTranscription()
    case .unloaded:
        disableTranscription()
    default:
        break
    }
}

UI State Binding (SwiftUI)

struct TranscriptionView: View {
    @State private var modelState: ModelState = .unloaded
    
    var body: some View {
        VStack {
            if modelState.isBusy {
                ProgressView(modelState.description)
            } else if modelState == .loaded {
                Button("Start Transcription") {
                    // Start transcription
                }
            }
            
            Text("Status: \(modelState.description)")
                .font(.caption)
        }
    }
}

Checking Multiple States

func canTranscribe(state: ModelState) -> Bool {
    switch state {
    case .loaded:
        return true
    case .loading, .prewarming, .downloading:
        return false  // Or check state.isBusy
    default:
        return false
    }
}

Type Alias

ModelStateCallback
(_ oldState: ModelState?, _ newState: ModelState) -> Void
Callback type invoked when the pipeline’s model state changes.
let callback: ModelStateCallback = { oldState, newState in
    print("State changed from \(oldState?.description ?? "none") to \(newState.description)")
}

Notes

  • ModelState is shared between WhisperKit and TTSKit for consistent state management
  • The enum is marked @frozen, meaning no new cases will be added (guaranteed binary compatibility)
  • Use isBusy to determine if the model is in a transitional state
  • State transitions are managed internally by WhisperKit

Build docs developers (and LLMs) love