# Handling Model Caching and HF_HUB_OFFLINE for Air-Gapped Deployments in Speech-to-Speech

> Deploy speech-to-speech models offline in air-gapped environments. Learn to handle model caching and HF_HUB_OFFLINE for seamless operation without network access.

- Repository: [Hugging Face/speech-to-speech](https://github.com/huggingface/speech-to-speech)
- Tags: how-to-guide
- Published: 2026-08-09

---

**The huggingface/speech-to-speech repository supports fully offline operation by caching model assets on first use and respecting the `HF_HUB_OFFLINE=1` environment variable to block all network requests in air-gapped environments.**

The speech-to-speech inference pipeline is architected to run without internet connectivity once initial model downloads are complete. By combining automatic model caching with strict offline mode enforcement, you can deploy voice AI systems in secure, isolated networks while ensuring immediate failure if required assets are missing from local storage.

## How Model Caching Works in Speech-to-Speech

The pipeline implements a lazy-loading caching strategy across all backend handlers. When a component is first instantiated, it downloads necessary files from the Hugging Face Hub and stores them for subsequent reuse.

### Backend Handler Implementation

Each processing component manages its own cache through the Hugging Face Hub API. In [`speech_to_speech/TTS/qwen3_tts_handler.py`](https://github.com/huggingface/speech-to-speech/blob/main/speech_to_speech/TTS/qwen3_tts_handler.py), the Qwen3-TTS backend loads voice references and model weights using `hf_hub_download()`, which automatically stores files in the local cache. Similarly, [`speech_to_speech/STT/whisper_stt_handler.py`](https://github.com/huggingface/speech-to-speech/blob/main/speech_to_speech/STT/whisper_stt_handler.py) handles speech recognition model caching. The `huggingface_hub` library manages these downloads transparently, ensuring that subsequent runs retrieve assets from disk rather than the network.

### Default Cache Location

By default, all model files reside in `~/.cache/huggingface/hub`. This directory stores STT models (Whisper, Parakeet), LLM weights (GGUF or MLX formats), TTS checkpoints (Qwen3), Smart-Turn ONNX files, and VAD (Silero) resources. Once populated, this cache directory can be transferred to air-gapped systems or mounted as a read-only volume.

## Enforcing Offline Mode with HF_HUB_OFFLINE

The `HF_HUB_OFFLINE` environment variable provides the primary mechanism for air-gapped deployments, forcing the pipeline to operate exclusively from local cache without attempting network connections.

### Environment Variable Behavior

When `HF_HUB_OFFLINE=1` is set, the `huggingface_hub` library raises `OfflineModeIsEnabled` for any download request targeting uncached files. The pipeline entry point in [`src/speech_to_speech/s2s_pipeline.py`](https://github.com/huggingface/speech-to-speech/blob/main/src/speech_to_speech/s2s_pipeline.py) orchestrates this through the call chain: `parse_arguments()` → `prepare_all_args()` → backend constructors. Because handlers initialize after argument parsing, the offline check occurs before any audio processing begins, ensuring fast failure during startup rather than mid-inference hangs.

### Error Handling and Validation

If a required model is absent from the cache while offline mode is active, the pipeline raises a clear `ValueError` indicating which specific asset is missing. This prevents ambiguous timeout errors and allows operators to identify exactly which files need to be pre-cached before deploying to restricted environments.

## Step-by-Step Air-Gapped Deployment Workflow

Deploying speech-to-speech in offline environments requires a three-phase approach:

1. **Pre-cache on a connected system** – Execute your target configuration on a machine with internet access using the exact command arguments you plan to use in production. This populates the cache with STT, LLM, TTS, Smart-Turn, and auxiliary resources (NLTK data, Silero VAD).
2. **Cache verification** – Confirm all required files exist under `~/.cache/huggingface/hub` or your custom cache directory.
3. **Enable offline mode** – Set `HF_HUB_OFFLINE=1` before launching the service in the air-gapped environment.

## Configuration Examples for Offline Operation

### Pre-Cache All Assets

Run the pipeline once with network access to download all required components:

```bash

# Example: Full pipeline with MLX LLM and Qwen3 TTS

HF_HUB_OFFLINE=0 speech-to-speech serve \
    --stt parakeet-tdt \
    --llm_backend mlx-lm \
    --tts qwen3 \
    --model_name "ggml-org/gemma-4-E4B-it-GGUF"

```

This command caches the STT model, LLM weights, TTS voice references, and Smart-Turn checkpoint in `~/.cache/huggingface/hub`.

### Run Completely Offline

After caching, operate without network connectivity:

```bash

# All models must exist in local cache

HF_HUB_OFFLINE=1 speech-to-speech serve \
    --model_name "ggml-org/gemma-4-E4B-it-GGUF" \
    --responses_api_base_url "http://127.0.0.1:8080/v1"

```

If any model is missing, the process exits immediately with:

```

ValueError: Model not found locally and HF_HUB_OFFLINE=1 prevents downloading.

```

### Custom Cache Directory

For systems requiring non-standard cache locations, use `HF_HOME` or `TRANSFORMERS_CACHE`:

```bash
export HF_HOME=/opt/local_hf_cache
HF_HUB_OFFLINE=1 speech-to-speech serve \
    --stt whisper-mlx \
    --tts qwen3 \
    --model_name "mlx-community/Qwen3-4B-Instruct-2507-bf16"

```

All subsequent operations read from and write to `/opt/local_hf_cache` instead of the default user cache.

### Disabling Smart-Turn for Minimal Deployments

If the Smart-Turn ONNX checkpoint is unavailable or unnecessary, disable it to avoid cache misses:

```bash
HF_HUB_OFFLINE=1 speech-to-speech serve \
    --no_smart_turn \
    --stt parakeet-tdt \
    --tts qwen3

```

The `--no_smart_turn` flag prevents the handler from attempting to load the Smart-Turn model, eliminating a potential offline failure point.

## Summary

- **Automatic caching** occurs on first use for all backend handlers (STT, LLM, TTS, VAD), storing files in `~/.cache/huggingface/hub` by default.
- **`HF_HUB_OFFLINE=1`** forces strict offline operation, raising immediate errors if required models are missing rather than attempting network downloads.
- **Pre-caching workflow** requires running your exact configuration once online before transferring to air-gapped systems.
- **Custom directories** are supported via `HF_HOME` or `TRANSFORMERS_CACHE` environment variables.
- **Optional components** like Smart-Turn can be disabled with `--no_smart_turn` to reduce cache dependencies.

## Frequently Asked Questions

### What happens if a model is missing when HF_HUB_OFFLINE is enabled?

The pipeline raises a `ValueError` during startup indicating which specific model is not found locally. Under the hood, `hf_hub_download()` raises `OfflineModeIsEnabled`, which propagates up through the backend constructors in `src/speech_to_speech/arguments_classes/` before any audio processing begins.

### Can I use a custom cache directory for air-gapped deployments?

Yes. Set the `HF_HOME` environment variable to your preferred path before starting the server. Alternatively, `TRANSFORMERS_CACHE` is respected for backward compatibility. All handlers, including those defined in [`src/speech_to_speech/TTS/qwen3_tts_handler.py`](https://github.com/huggingface/speech-to-speech/blob/main/src/speech_to_speech/TTS/qwen3_tts_handler.py), will look for assets in the specified location when `HF_HUB_OFFLINE=1` is active.

### Which components need to be pre-cached for full offline operation?

You must cache the STT model (e.g., Whisper or Parakeet), the LLM weights (GGUF, MLX, or API-based), the TTS checkpoint (e.g., Qwen3), the Smart-Turn ONNX model (unless disabled with `--no_smart_turn`), and auxiliary data including Silero VAD and NLTK resources. The first online run automatically handles all these downloads.

### How do I verify that my deployment is truly offline?

Set `HF_HUB_OFFLINE=1` and disconnect from the network before starting the server. If the pipeline initializes successfully and processes audio without hanging or timeout errors, it is operating entirely from local cache. The [`src/speech_to_speech/s2s_pipeline.py`](https://github.com/huggingface/speech-to-speech/blob/main/src/speech_to_speech/s2s_pipeline.py) entry point validates cache availability during the `prepare_all_args()` phase, ensuring no hidden network dependencies exist.