# How `whisper.load_model()` Downloads and Verifies Model Checkpoints in OpenAI Whisper

> **`whisper.load_model()` automatically downloads model checkpoints to `~/.cache/whisper`, verifies their integrity using SHA-256 hashes embedded in the download URL, and returns a ready-to-use `Whisper` instance on the specifie...

- Repository: [OpenAI/whisper](https://github.com/openai/whisper)
- Tags: 
- Published: 2026-02-27

---

**`whisper.load_model()` automatically downloads model checkpoints to `~/.cache/whisper`, verifies their integrity using SHA-256 hashes embedded in the download URL, and returns a ready-to-use `Whisper` instance on the specified device.**

The `openai/whisper` repository provides a robust model loading pipeline that handles everything from device selection to cryptographic verification. When you call `whisper.load_model()`, the function orchestrates a multi-stage process defined in [`whisper/__init__.py`](https://github.com/openai/whisper/blob/main/whisper/__init__.py) that ensures you receive an authentic, uncorrupted model checkpoint every time.

## Device Selection and Cache Directory Setup

Before any network requests occur, `whisper.load_model()` prepares the runtime environment by detecting available hardware and establishing a local cache location.

### Automatic Device Detection

If you do not specify a `device` parameter, the function automatically selects CUDA when available, falling back to CPU otherwise:

```python
if device is None:
    device = "cuda" if torch.cuda.is_available() else "cpu"

```

This logic ensures optimal performance without requiring manual configuration across different hardware setups.

### Cache Directory Resolution

The function determines where to store downloaded checkpoints using the XDG Base Directory specification. It checks for the `XDG_CACHE_HOME` environment variable first, defaulting to `~/.cache/whisper`:

```python
default = os.path.join(os.path.expanduser("~"), ".cache")
download_root = os.path.join(os.getenv("XDG_CACHE_HOME", default), "whisper")

```

This approach respects user preferences while providing a predictable default location for model weights.

## Model Name Resolution: Built-in vs. Local Checkpoints

The `name` parameter accepts either a built-in model identifier or a filesystem path. The resolution logic in [`whisper/__init__.py`](https://github.com/openai/whisper/blob/main/whisper/__init__.py) handles both cases:

```python
if name in _MODELS:
    # Download from OpenAI's CDN using the URL mapping in _MODELS

    checkpoint_file = _download(_MODELS[name], download_root, in_memory)
elif os.path.isfile(name):
    # Load user-provided local checkpoint

    checkpoint_file = open(name, "rb")
else:
    raise RuntimeError(f"Model {name} not found")

```

Built-in models include `tiny`, `base`, `small`, `medium`, `large`, and their multilingual or English-specific variants. The `_MODELS` dictionary maps these names to HTTPS URLs containing embedded SHA-256 hashes.

## The Download and Verification Pipeline

When a built-in model is requested, `whisper.load_model()` delegates to the private `_download` function, which implements a defense-in-depth strategy for ensuring file integrity.

### Extracting SHA-256 Hashes from URLs

OpenAI embeds the expected SHA-256 hash directly into the download URL as the second-to-last path segment. The `_download` function extracts this value before any network activity:

```python
expected_sha256 = url.split("/")[-2]

```

For example, a URL ending in `/d3dd57d32accea0b295c96e26670aa495de38d6b/whisper-small.pt` yields `d3dd57d32accea0b295c96e26670aa495de38d6b` as the expected hash.

### Cache Hit Validation

Before downloading, the function checks for an existing file in the cache directory. If found, it validates the file's integrity:

```python

# Check if file already exists and matches hash

if os.path.isfile(download_target):
    with open(download_target, "rb") as f:
        if hashlib.sha256(f.read()).hexdigest() == expected_sha256:
            return torch.load(download_target, map_location="cpu") if in_memory else download_target
        else:
            warnings.warn(f"File {download_target} has incorrect hash, re-downloading")

```

This prevents redundant downloads while ensuring corrupted cache entries are automatically replaced.

### Streaming Download with Integrity Checks

For fresh downloads, the function streams the file in 8 KB chunks to minimize memory usage, displaying a progress bar via `tqdm`:

```python
with urllib.request.urlopen(url) as source, open(download_target, "wb") as output:
    with tqdm(total=int(source.info().get("Content-Length")), ncols=80, unit="iB", unit_scale=True) as pbar:
        while True:
            buffer = source.read(8192)
            if not buffer:
                break
            output.write(buffer)
            pbar.update(len(buffer))

```

This approach handles large model files (several GB for the `large` variants) efficiently without loading the entire file into RAM during the download phase.

### Post-Download Verification

After the download completes, the function performs a mandatory verification step. It recomputes the SHA-256 hash of the downloaded file and compares it against the expected value extracted from the URL:

```python
model_bytes = open(download_target, "rb").read()
if hashlib.sha256(model_bytes).hexdigest() != expected_sha256:
    raise RuntimeError("Model has been downloaded but the SHA256 checksum does not match. Please retry loading the model.")

```

If the hashes do not match, the function raises a `RuntimeError`, preventing the loading of potentially corrupted or tampered model weights.

## Loading and Instantiating the Model

Once the checkpoint file is verified and available (either from cache or fresh download), `whisper.load_model()` proceeds to deserialize the weights and construct the model architecture.

### Checkpoint Deserialization

The function uses `torch.load` to read the checkpoint, mapping tensors to the appropriate device immediately:

```python
checkpoint = torch.load(checkpoint_file, map_location=device, **kwargs)

```

If `in_memory=True` was passed to `_download`, the checkpoint is already a bytes object or loaded tensor dictionary; otherwise, it is loaded from the cached file path.

### Model Architecture Reconstruction

The function extracts model dimensions from the checkpoint metadata and instantiates the `Whisper` class defined in [`whisper/model.py`](https://github.com/openai/whisper/blob/main/whisper/model.py):

```python
dims = ModelDimensions(**checkpoint["dims"])
model = Whisper(dims)
model.load_state_dict(checkpoint["model_state_dict"])

```

This two-step process ensures the model architecture matches the saved weights exactly before loading the parameters.

### Alignment Head Configuration

For models that support precise word-level timing, the function applies pre-computed alignment head metadata if present in the checkpoint:

```python
if alignment_heads is not None:
    model.set_alignment_heads(alignment_heads)

```

This step configures cross-attention heads used for timestamp alignment, enabling features like `word_timestamps=True` during transcription.

Finally, the function moves the model to the target device and returns it:

```python
return model.to(device)

```

## Practical Usage Examples

Here are common patterns for using `whisper.load_model()` in production and research contexts:

```python
import whisper

# Automatic device selection with default cache

model = whisper.load_model("base")

# Force CPU usage and load weights into RAM immediately

model = whisper.load_model("large-v2", device="cpu", in_memory=True)

# Use a custom checkpoint downloaded from Hugging Face

model = whisper.load_model("/home/user/models/whisper-medium-custom.pt")

# Transcribe with the loaded model

result = model.transcribe("interview.mp3", language="en")
print(result["text"])

```

The function handles all caching and verification transparently, so subsequent calls with the same model name return instantly from the local cache after the initial download.

## Summary

- **`whisper.load_model()`** serves as the primary entry point for obtaining Whisper models in the `openai/whisper` repository.
- The function automatically selects CUDA when available, falling back to CPU, and stores downloads in `~/.cache/whisper` (or `$XDG_CACHE_HOME/whisper`).
- SHA-256 hashes embedded in download URLs enable cryptographic verification both before cache reuse and after fresh downloads.
- The implementation streams large files in 8 KB chunks with progress bars, then validates integrity before instantiating the `Whisper` class from [`whisper/model.py`](https://github.com/openai/whisper/blob/main/whisper/model.py).
- Alignment head metadata is automatically applied when present, enabling precise word-level timestamp features.

## Frequently Asked Questions

### How does Whisper verify that downloaded models haven't been tampered with?

Whisper extracts the expected SHA-256 hash from the second-to-last segment of the download URL (e.g., `d3dd57d...` in `https://.../d3dd57d.../model.pt`). After downloading, it computes the file's SHA-256 hash using `hashlib.sha256()` and raises a `RuntimeError` if the values don't match. This verification happens both when reusing cached files and immediately after fresh downloads in [`whisper/__init__.py`](https://github.com/openai/whisper/blob/main/whisper/__init__.py).

### Can I use a custom cache directory instead of ~/.cache/whisper?

While `whisper.load_model()` doesn't expose a direct `cache_dir` parameter, you can override the cache location by setting the `XDG_CACHE_HOME` environment variable before importing Whisper. The function checks `os.getenv("XDG_CACHE_HOME")` and appends `/whisper` to construct the final download root. Alternatively, you can pass an absolute file path as the `name` argument to load models from arbitrary locations without caching.

### What happens if the SHA-256 checksum fails during model loading?

If the computed SHA-256 hash of a cached file doesn't match the expected value embedded in the URL, Whisper emits a warning via `warnings.warn()` indicating the file has an incorrect hash, then proceeds to re-download the model. However, if a freshly downloaded file fails the checksum verification, the function raises a `RuntimeError` with the message "Model has been downloaded but the SHA256 checksum does not match. Please retry loading the model." This prevents corrupted or malicious files from being loaded into memory.

### Does whisper.load_model() support loading models directly into GPU memory?

Yes, the `device` parameter controls where the model tensors reside. When `device="cuda"` (or `None` with CUDA available), the function passes `map_location=device` to `torch.load()`, ensuring weights are placed directly on the GPU during deserialization. Additionally, setting `in_memory=True` causes the `_download` function to return the checkpoint as a loaded object rather than a file path, though the final `model.to(device)` call in `load_model()` ensures the model resides on the specified device regardless of how the checkpoint was loaded.