Skip to main content

Vayu - The Fastest Whisper on Apple Silicon

Vayu - The Fastest Whisper on Apple Silicon

PyPI Downloads Python 3.10+ License: MIT Platform: macOS Apple Silicon MLX Stars

Vayu (وایو) is the fastest Whisper speech-to-text implementation optimized for Apple Silicon Macs. It combines MLX Whisper with Lightning Whisper MLX batched decoding to deliver 3-5x faster transcription than standard Whisper on M1/M2/M3/M4 chips.

Named after the ancient Persian god of wind - the swiftest force in nature.

Why Vayu?

  • 3-5x faster than standard Whisper via batched decoding on Apple Silicon
  • One-line install - pip install vayu-whisper and you're transcribing
  • All Whisper models - tiny through large-v3, plus turbo and distil variants
  • Multiple output formats - txt, vtt, srt, tsv, json
  • Word-level timestamps - precise word timings for subtitles and alignment
  • Low memory options - 4-bit and 8-bit quantization for constrained environments
  • Simple Python API + CLI - use from code or the command line

Installation

pip install vayu-whisper

Or install from source:

git clone https://github.com/CodeWithBehnam/vayu.git
cd vayu
pip install -e .

Requirements

  • macOS with Apple Silicon (M1/M2/M3/M4)
  • Python 3.10+
  • MLX 0.11+

Quick Start

Python API

from whisper_mlx import LightningWhisperMLX

# Initialize with batched decoding for maximum speed
whisper = LightningWhisperMLX(model="distil-large-v3", batch_size=12)

# Transcribe audio
result = whisper.transcribe("audio.mp3")
print(result["text"])

# With word-level timestamps
result = whisper.transcribe("audio.mp3", language="en", word_timestamps=True)

Full API

from whisper_mlx import transcribe

result = transcribe(
    "audio.mp3",
    path_or_hf_repo="mlx-community/whisper-turbo",
    batch_size=6,
    language="en",
    word_timestamps=True,
)

print(result["text"])
for segment in result["segments"]:
    print(f"[{segment['start']:.2f} -> {segment['end']:.2f}] {segment['text']}")

CLI

# Basic transcription
vayu audio.mp3

# Batched decoding (3-5x faster)
vayu audio.mp3 --batch-size 12

# Specify model and output format
vayu audio.mp3 --model mlx-community/distil-whisper-large-v3 --output-format srt

# Multiple files
vayu audio1.mp3 audio2.mp3 --output-dir ./transcripts

# Word-level timestamps
vayu audio.mp3 --word-timestamps True

# Translate to English
vayu audio.mp3 --task translate

Available Models

Model HuggingFace Repo Size Speed
tiny mlx-community/whisper-tiny-mlx 39M Fastest
base mlx-community/whisper-base-mlx 74M Fast
small mlx-community/whisper-small-mlx 244M Medium
medium mlx-community/whisper-medium-mlx 769M Slow
large-v3 mlx-community/whisper-large-v3-mlx 1.5B Slowest
turbo mlx-community/whisper-turbo 809M Fast
distil-large-v3 mlx-community/distil-whisper-large-v3 756M Fast

Quantized Models

For reduced memory usage, use quantized models:

whisper = LightningWhisperMLX(model="distil-large-v3", quant="4bit")

quant accepts "4bit" or "8bit" and is available for tiny, small, medium, large-v3 and distil-large-v3. Other models raise a ValueError rather than silently loading full precision.

Batch Size Recommendations

Model Recommended batch_size Memory Usage
tiny/base 24-32 Low
small 16-24 Medium
medium 8-12 High
large/turbo 4-8 High
distil-large-v3 12-16 Medium

Higher batch sizes improve throughput but require more memory. Start with the recommended values and adjust based on your hardware.

Measuring the speed-up

The speed-up from batching depends on the model, batch size, chip and audio. To measure it on your Mac, time sequential against batched decoding on one of your own files:

python scripts/benchmark.py audio.mp3 --model distil-large-v3 --batch-size 12

The script loads the model and warms it up first, then reports the best of --runs timings for batch_size=1 and for the batch size you chose.

Batched vs Sequential Decoding

With batch_size=1, Vayu decodes like OpenAI's Whisper. Each 30-second window starts where the previous segment ended and is conditioned on the text so far.

With batch_size > 1, fixed 30-second windows are decoded together. This is much faster, with some trade-offs:

  • Every window in a batch is conditioned on the text from before the batch, so condition_on_previous_text applies between batches, not between windows.
  • Windows don't move to follow the speech. Text cut off at a window boundary is kept as a segment that ends at the boundary, so a word spanning two windows can be split.
  • hallucination_silence_threshold needs window-by-window seeking and is ignored (with a warning).
  • best_of is not used. Temperature fallback re-decodes only the windows that fail the quality checks.

Word-level timestamps work in both modes.

Loading Local Models

load_model and --model accept a local directory with MLX weights (config.json plus weights.safetensors, model.safetensors or weights.npz). For safety, local directories are only loaded from:

  • the HuggingFace cache (~/.cache/huggingface/hub)
  • /usr/local/share/whisper-mlx
  • directories listed in WHISPER_MLX_MODEL_DIRS (separated by :)
export WHISPER_MLX_MODEL_DIRS=~/models:/Volumes/External/whisper
vayu audio.mp3 --model ~/models/whisper-large-v3-mlx

Anything else fails with Model path '...' is not within allowed directories. HuggingFace repo names (mlx-community/whisper-turbo) are downloaded to the cache and are not affected.

API Reference

transcribe()

def transcribe(
    audio: Union[str, np.ndarray, mx.array],
    *,
    path_or_hf_repo: str = "mlx-community/whisper-turbo",
    batch_size: int = 1,
    verbose: Optional[bool] = None,
    temperature: Union[float, Tuple[float, ...]] = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0),
    compression_ratio_threshold: Optional[float] = 2.4,
    logprob_threshold: Optional[float] = -1.0,
    no_speech_threshold: Optional[float] = 0.6,
    condition_on_previous_text: bool = True,
    initial_prompt: Optional[str] = None,
    word_timestamps: bool = False,
    **decode_options,
) -> dict

LightningWhisperMLX

class LightningWhisperMLX:
    def __init__(
        self,
        model: str = "distil-large-v3",
        batch_size: int = 12,
        quant: str = None,
    )

    def transcribe(
        self,
        audio_path: str,
        language: str = None,
        task: str = "transcribe",
        verbose: bool = False,
        word_timestamps: bool = False,
        **kwargs,
    ) -> dict

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

# Development setup
git clone https://github.com/CodeWithBehnam/vayu.git
cd vayu
pip install -e ".[dev]"

License

MIT License - see LICENSE for details.

Acknowledgments

This project builds on the excellent work of:

Project Author(s) Contribution
mlx-examples/whisper Apple Inc. MLX framework, Whisper port, CLI, output writers
lightning-whisper-mlx Mustafa Aljadery, Siddharth Sharma Batched decoding for 3-5x speedup
Whisper OpenAI Original model architecture and weights

Star History

Star History Chart

Author

Behnam Ebrahimi - Unified implementation, security improvements, and maintenance

Metadata

Release files for vayu-whisper 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vayu-whisper 1.1.0
File Size Uploaded
vayu_whisper-1.1.0.tar.gz 804.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for vayu-whisper 1.1.0
File Interpreter ABI Platform
vayu_whisper-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / vayu_whisper-1.1.0.tar.gz

Download URL vayu_whisper-1.1.0.tar.gz
Size 804.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0091d55be7e2832e1e771619193a10020c373d7d6754763ca21237741f143ba3
BLAKE2b-256 checksum
How to use checksums
5b4a6fe00bbdb217bd772ba9d17a7aa85988f291aeaa5d895c9ddfefda5b177c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / vayu_whisper-1.1.0-py3-none-any.whl

Download URL vayu_whisper-1.1.0-py3-none-any.whl
Size 799.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9766ab5b7f1f9f4bc721c076e6018a88ad061e15e09940e312cfeca97cc87cab
BLAKE2b-256 checksum
How to use checksums
9f2a96d0cbb341b9e2eb5a8ca86fb9e90682062da85e971abc5cd59904be48b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page