whisper

September 8, 2026 · View on GitHub

Run a local ASR server with automatic backend selection based on your platform:

  • macOS Apple Siliconmlx-whisper (Metal acceleration)
  • Linux/CUDAfaster-whisper (CTranslate2)
  • HuggingFacetransformers (supports safetensors models, Qwen3-ASR, and known remote-code ASR models such as Cohere Transcribe)
  • NVIDIA ParakeetNeMo (e.g., parakeet-tdt-0.6b-v3)

Note

Quick Start - Get transcription working in 30 seconds:

pip install "agent-cli[faster-whisper]"
agent-cli server whisper

Server is now running at http://localhost:10301. Verify with curl http://localhost:10301/health.

Apple Silicon MLX-only setup:

pip install "agent-cli[mlx-whisper]"
agent-cli server whisper --backend mlx

Cohere Transcribe via HuggingFace transformers:

pip install "agent-cli[whisper-transformers]" librosa soundfile sentencepiece protobuf
agent-cli server whisper \
  --backend transformers \
  --model CohereLabs/cohere-transcribe-03-2026 \
  --default-language en

Qwen3-ASR via native HuggingFace transformers support:

pip install "agent-cli[whisper-transformers]"
agent-cli server whisper \
  --backend transformers \
  --model Qwen/Qwen3-ASR-1.7B-hf

NVIDIA Parakeet via NeMo:

agent-cli install-extras nemo-whisper wyoming
agent-cli server whisper --backend nemo

Use it with any OpenAI-compatible client, or configure agent-cli to use it - see Configuration.

Features

  • OpenAI-compatible API at /v1/audio/transcriptions - drop-in replacement for OpenAI's Whisper API
  • Wyoming protocol for Home Assistant voice integration (Wyoming is the standard protocol for local voice services)
  • TTL-based memory management - models unload after idle period, freeing RAM/VRAM
  • CUDA cache cleanup - the transformers backend releases unused GPU cache after each transcription while keeping model weights loaded
  • Multiple models - run different model sizes with independent TTLs
  • Background preloading - downloads start at startup without blocking; use --preload to wait
  • Multi-platform support - automatically uses the optimal backend for your hardware (auto switches to nemo for Parakeet models)

Important

Some backend/model combinations support fewer features than Whisper. For example, Cohere Transcribe currently requires an explicit language and does not provide translation or timestamped subtitle output.

Usage

agent-cli server whisper [OPTIONS]

Examples

# Run with default large-v3 model (5-minute TTL)
agent-cli server whisper

# Use smaller model with 10-minute TTL
agent-cli server whisper --model small --ttl 600

# Run multiple models (requests can specify which to use)
agent-cli server whisper --model large-v3 --model small --default-model large-v3

# Force CPU mode
agent-cli server whisper --device cpu

# Download model without starting server (requires faster-whisper)
agent-cli server whisper --model large-v3 --download-only

# Run NVIDIA Parakeet via NeMo
agent-cli server whisper --backend nemo

# Keep Parakeet loaded after first request (avoids repeated load cost)
agent-cli server whisper --backend nemo --ttl 0

# Run a specific Parakeet model instead of the NeMo default
agent-cli server whisper --backend nemo --model parakeet-tdt-0.6b-v3

# Preload model at startup and wait until ready
agent-cli server whisper --preload

# Run Cohere Transcribe through the transformers backend
agent-cli server whisper \
  --backend transformers \
  --model CohereLabs/cohere-transcribe-03-2026 \
  --default-language en

# Run Qwen3-ASR through its native transformers integration
agent-cli server whisper \
  --backend transformers \
  --model Qwen/Qwen3-ASR-1.7B-hf

Options

Options

OptionDefaultDescription
--model, -m-Whisper model(s) to load. Common models: tiny, base, small, medium, large-v3, distil-large-v3, parakeet-tdt-0.6b-v3, parakeet-unified-en-0.6b (NeMo backend). Can specify multiple for different accuracy/speed tradeoffs. Default: large-v3 (parakeet-unified-en-0.6b with --backend nemo)
--default-model-Model to use when client doesn't specify one. Must be in the --model list
--device, -dautoCompute device: auto (detect GPU), cuda, cuda:0, mps, cpu. MLX backend always uses Apple Silicon
--compute-typeautoPrecision for faster-whisper: auto, float16, int8, int8_float16. Lower precision = faster + less VRAM
--cache-dir-Custom directory for downloaded models (default: HuggingFace cache)
--default-language-Fallback language code for requests that omit language. Required for models that do not support language auto-detection (for example Cohere Transcribe).
--trust-remote-codefalseAllow Hugging Face model repositories to execute custom Python code. Known supported remote-code ASR models are trusted automatically.
--max-new-tokens4096Maximum output tokens for autoregressive transformers ASR models. Increase for unusually long audio
--ttl300Seconds of inactivity before unloading model from memory. Set to 0 to keep loaded indefinitely
--preloadfalseLoad model(s) immediately at startup instead of on first request. Useful for reducing first-request latency
--host0.0.0.0Network interface to bind. Use 0.0.0.0 for all interfaces
--port, --asr-openai-port, -p10301Port for OpenAI-compatible HTTP API (/v1/audio/transcriptions)
--wyoming-port, --asr-wyoming-port10300Port for Wyoming protocol (Home Assistant integration)
--no-wyomingfalseDisable Wyoming protocol server (only run HTTP API)
--download-onlyfalseDownload model(s) to cache and exit. Useful for Docker builds
--backend, -bautoInference backend: auto (faster-whisper on CUDA/CPU, MLX on Apple Silicon), faster-whisper, mlx, transformers (HuggingFace, supports safetensors and known remote-code ASR models), nemo (NVIDIA NeMo, supports Parakeet models)

General Options

OptionDefaultDescription
--log-levelinfoSet logging level.

API Endpoints

Once running, the server exposes:

EndpointMethodDescription
/v1/audio/transcriptionsPOSTOpenAI-compatible transcription
/v1/audio/translationsPOSTOpenAI-compatible translation (to English)
/v1/audio/transcriptions/streamWebSocketReal-time streaming transcription
/v1/model/unloadPOSTManually unload a model from memory
/healthGETHealth check with model status
/docsGETInteractive API documentation

Note

/v1/audio/translations, srt, and vtt output depend on the selected backend/model. Whisper models with timestamp-capable backends support them; Cohere Transcribe and the generic transformers backend do not provide timestamped subtitle output.

Using the API

curl Example

# Transcribe an audio file
curl -X POST http://localhost:10301/v1/audio/transcriptions \
  -F "file=@recording.wav" \
  -F "model=whisper-1"

# With language hint and verbose output
curl -X POST http://localhost:10301/v1/audio/transcriptions \
  -F "file=@recording.wav" \
  -F "model=whisper-1" \
  -F "language=en" \
  -F "response_format=verbose_json"

# Get SRT subtitles
curl -X POST http://localhost:10301/v1/audio/transcriptions \
  -F "file=@recording.wav" \
  -F "model=whisper-1" \
  -F "response_format=srt"

Python Example (OpenAI SDK)

from openai import OpenAI

client = OpenAI(base_url="http://localhost:10301/v1", api_key="not-needed")

# Transcribe audio
with open("recording.wav", "rb") as f:
    transcript = client.audio.transcriptions.create(
        model="whisper-1",
        file=f,
    )
print(transcript.text)

WebSocket Streaming Protocol

The /v1/audio/transcriptions/stream endpoint provides real-time streaming transcription.

Protocol

  1. Connect to ws://localhost:10301/v1/audio/transcriptions/stream?model=whisper-1
  2. Send binary audio chunks (16kHz, 16-bit, mono PCM)
  3. Send EOS (3 bytes: 0x45 0x4F 0x53) to signal end of audio
  4. Receive JSON response with transcription

Message Format

Server response:

{
  "type": "final",
  "text": "transcribed text here",
  "is_final": true,
  "language": "en",
  "duration": 3.5,
  "segments": [...]
}

Error response:

{"type": "error", "message": "error description"}

Model Selection Guide

ModelDiskVRAMSpeedAccuracyUse Case
large-v3~3GB~4GBSlowBestHighest accuracy, batch processing
medium~1.5GB~2GBMediumGoodBalanced accuracy/speed
small~500MB~1GBFastFairReal-time, lower VRAM
tiny~75MB~300MBFastestBasicVery limited VRAM, quick transcription

Tip

Use --model small --model large-v3 to run both models. Clients can request either via the model parameter.

Troubleshooting

IssueSolution
CUDA out of memoryUse --device cpu or smaller model (e.g., --model small)
Port already in useUse --port XXXX to specify different port
Model download failsCheck network connection, or use --download-only first
Slow first requestModel is still downloading/loading. Use --preload to wait at startup
Wyoming not workingEnsure port 10300 is not blocked; check with nc -zv localhost 10300

Using with agent-cli Commands

The Whisper server is designed to work seamlessly with other agent-cli commands. See Configuration: Local Whisper Server for setup instructions.

Installation

Requires server deps and a backend:

# faster-whisper backend (default on CUDA/CPU)
pip install "agent-cli[faster-whisper]"
# or
uv sync --extra faster-whisper

macOS Apple Silicon

For optimal performance on M1/M2/M3/M4 Macs, install mlx-whisper:

pip install "agent-cli[mlx-whisper]"

The server will automatically detect and use the MLX backend when available.

For NeMo/Parakeet models on Apple Silicon, --device auto uses PyTorch MPS when available. You can also request it explicitly:

agent-cli server whisper --backend nemo --model parakeet-unified-en-0.6b --device mps

HuggingFace Transformers

For loading models in safetensors format (instead of CTranslate2 .bin files):

pip install "agent-cli[whisper-transformers]"
agent-cli server whisper --backend transformers

This uses HuggingFace's transformers library, which supports loading .safetensors models directly from the Hub. Qwen3-ASR requires transformers>=5.13.0 and supports automatic language detection and transcription prompts.

Qwen3-ASR

pip install "agent-cli[whisper-transformers]"
agent-cli server whisper \
  --backend transformers \
  --model Qwen/Qwen3-ASR-1.7B-hf

Qwen3-ASR supports transcription, automatic language detection, and context or hotwords through the OpenAI-compatible prompt field. Translation and timestamped subtitle output are not currently supported.

The default output budget is 4096 tokens, which accommodates long recordings. For unusually long or dense speech, increase it with --max-new-tokens. If Qwen3-ASR exhausts the configured budget, the request fails with a clear error instead of returning a silently truncated transcript.

To install it as the standard whisper background daemon:

agent-cli daemon install whisper -- \
  --backend transformers \
  --model Qwen/Qwen3-ASR-1.7B-hf

For Cohere Transcribe specifically:

pip install "agent-cli[whisper-transformers]" librosa soundfile sentencepiece protobuf
agent-cli server whisper \
  --backend transformers \
  --model CohereLabs/cohere-transcribe-03-2026 \
  --default-language en

Notes for Cohere Transcribe:

  • The HuggingFace repo is gated; you must accept the model terms on Hugging Face first.
  • Set --default-language unless every client request will pass language.
  • translate, srt, and vtt are not available for this model because it does not return timestamped segments or translation output.
  • Use --trust-remote-code only for additional custom Hugging Face models that require repository Python code and are not recognized automatically.

NVIDIA NeMo (Parakeet)

The NeMo backend runs NVIDIA Parakeet models behind the same OpenAI-compatible HTTP API and Wyoming protocol as the other Whisper backends. With --backend nemo, the default model is parakeet-unified-en-0.6b.

Install the runtime dependencies:

agent-cli install-extras nemo-whisper wyoming

Start the server:

agent-cli server whisper --backend nemo

Use it from agent-cli through either protocol:

# OpenAI-compatible HTTP API
ag transcribe \
  --asr-provider openai \
  --asr-openai-base-url http://localhost:10301/v1

# Wyoming protocol
ag transcribe \
  --asr-provider wyoming \
  --asr-wyoming-ip localhost \
  --asr-wyoming-port 10300

Run it as a daemon with persistent arguments:

agent-cli daemon install whisper -y -- \
  --backend nemo \
  --model parakeet-unified-en-0.6b \
  --ttl 0

Notes for NeMo/Parakeet:

  • --backend nemo defaults to parakeet-unified-en-0.6b.
  • --backend auto switches to NeMo when any requested model name is a Parakeet model.
  • NeMo uses CUDA when available and CPU otherwise; it does not use MLX/MPS on Apple Silicon.
  • First request can be slow because the model loads lazily. Use --preload to load at startup, or --ttl 0 to keep it loaded after the first request.
  • REST uploads can be WAV, MP3, M4A, FLAC, OGG, AAC, or WebM when ffmpeg is available.
  • NeMo models are currently transcription-only in this server. Requests to /v1/audio/translations return 400.
  • Segment formats (verbose_json, srt, vtt) require timestamp output from the selected NeMo model.

Python 3.14 note:

On Python 3.14, the plain published extra path does not apply agent-cli's NeMo override. The agent-cli install-extras nemo-whisper path is uv-aware and can apply agent-cli's temporary pinned NeMo Git install plus override file. Prefer it over plain pip install "agent-cli[nemo-whisper]" on Python 3.14.

Docker

Pre-built images are available from GitHub Container Registry:

# Run with GPU support
docker run -p 10300:10300 -p 10301:10301 --gpus all ghcr.io/basnijholt/agent-cli-whisper:latest-cuda

# Run CPU-only
docker run -p 10300:10300 -p 10301:10301 ghcr.io/basnijholt/agent-cli-whisper:latest-cpu

Or build from source using the whisper.Dockerfile:

# Build and run with GPU support
docker build -f docker/whisper.Dockerfile --target cuda -t agent-cli-whisper:cuda .
docker run -p 10300:10300 -p 10301:10301 --gpus all agent-cli-whisper:cuda

# Build and run CPU-only
docker build -f docker/whisper.Dockerfile --target cpu -t agent-cli-whisper:cpu .
docker run -p 10300:10300 -p 10301:10301 agent-cli-whisper:cpu

Or use Docker Compose:

# With GPU
docker compose -f docker/docker-compose.whisper.yml --profile cuda up

# CPU only
docker compose -f docker/docker-compose.whisper.yml --profile cpu up

Configure via environment variables:

VariableDefaultDescription
WHISPER_MODELlarge-v3Model to load
WHISPER_TTL300Seconds before unloading idle model
WHISPER_DEVICEcuda/cpuDevice (set by target)
WHISPER_LOG_LEVELinfoLogging level
WHISPER_EXTRA_ARGS-Additional CLI arguments