CLI Reference

The speech binary is the main entry point for all speech processing tasks. Build with make build, then run from .build/release/speech.

transcribe

Transcribe audio files to text.

speech transcribe <file> [options]
OptionDefaultDescription
<file>Audio file to transcribe (WAV, M4A, MP3, CAF)
--engineqwen3ASR engine: qwen3, qwen3-coreml, parakeet, nemotron, or omnilingual
--model, -m0.6BModel variant: 0.6B, 1.7B, or full HuggingFace model ID (qwen3 only)
--languageLanguage hint (optional, ignored by omnilingual)
--window10[omnilingual] CoreML window size in seconds: 5 or 10
--backendcoreml[omnilingual] Backend: coreml (Neural Engine) or mlx (Metal GPU)
--variant300M[omnilingual mlx] Size: 300M, 1B, 3B, or 7B
--bits4[omnilingual mlx] Quantisation bits: 4 or 8
--streamEnable streaming transcription with VAD
--max-segment10Maximum segment duration in seconds (streaming)
--partialEmit partial results during speech (streaming)

Examples:

# Basic transcription
speech transcribe recording.wav

# Use larger model
speech transcribe recording.wav --model 1.7B

# CoreML encoder (Neural Engine + MLX decoder)
speech transcribe recording.wav --engine qwen3-coreml

# Use Parakeet (CoreML) engine
speech transcribe recording.wav --engine parakeet

# Use Nemotron Streaming (CoreML, English with native punctuation)
speech transcribe recording.wav --engine nemotron                                 # batch
speech transcribe recording.wav --engine nemotron --stream --partial              # streaming

# Omnilingual (CoreML, 1,672 languages)
speech transcribe recording.wav --engine omnilingual                              # 10 s window
speech transcribe recording.wav --engine omnilingual --window 5                     # 5 s window

# Omnilingual (MLX, any length up to 40 s)
speech transcribe recording.wav --engine omnilingual --backend mlx                              # 300M @ 4-bit
speech transcribe recording.wav --engine omnilingual --backend mlx --variant 1B                  # 1B @ 4-bit
speech transcribe recording.wav --engine omnilingual --backend mlx --variant 3B --bits 8         # 3B @ 8-bit
speech transcribe recording.wav --engine omnilingual --backend mlx --variant 7B                  # 7B @ 4-bit

# Streaming with VAD
speech transcribe recording.wav --stream --partial

align

Word-level forced alignment — get precise timestamps for every word.

speech align <file> [options]
OptionDefaultDescription
<file>Audio file
--text, -tText to align (if omitted, transcribes first)
--model, -m0.6BASR model for transcription: 0.6B, 1.7B, or full ID
--aligner-modelForced aligner model ID
--languageLanguage hint

Examples:

# Auto-transcribe then align
speech align recording.wav

# Align with known text
speech align recording.wav --text "Can you guarantee that the replacement part will be shipped tomorrow?"

speak

Text-to-speech synthesis.

speech speak "<text>" [options]
OptionDefaultDescription
<text>Text to synthesize (optional if using --batch-file)
--engineqwen3TTS engine: qwen3, cosyvoice, voxcpm2, or magpie
--output, -ooutput.wavOutput WAV file path
--languageenglishLanguage. Omit to use speaker's native dialect when --speaker is set.
--streamEnable streaming synthesis
--voice-sampleReference audio for voice cloning (works with both qwen3 and cosyvoice engines)
--verboseShow detailed timing info

Qwen3-TTS Options

OptionDefaultDescription
--modelbaseModel variant: base, customVoice, or full HF model ID
--speakerSpeaker voice (requires --model customVoice)
--instructStyle instruction (CustomVoice model)
--list-speakersList available speakers and exit
--temperature0.3Sampling temperature
--top-k50Top-k sampling
--max-tokens500Maximum tokens (500 = ~40s audio)
--batch-fileFile with one text per line for batch synthesis
--batch-size4Max batch size for parallel generation
--first-chunk-frames3Codec frames in first streamed chunk
--chunk-frames25Codec frames per streamed chunk

CosyVoice3 Options

OptionDefaultDescription
--speakersSpeaker mapping for multi-speaker dialogue: s1=alice.wav,s2=bob.wav
--cosy-instructStyle instruction (overrides default). Controls voice style for CosyVoice3.
--turn-gap0.2Silence gap between dialogue turns in seconds
--crossfade0.0Crossfade overlap between turns in seconds
--model-idHuggingFace model ID

VoxCPM2 Options

OptionDefaultDescription
--voxcpm2-variantbf16Quantisation variant: bf16, int8, or int4. Resolves to aufklarer/VoxCPM2-MLX-<variant>.
--voxcpm2-instructNatural-language voice description (voice design), e.g. "a young woman, warm and gentle".
--voxcpm2-ref-audioReference audio file for cloning (16 kHz mono, resampled internally).
--voxcpm2-prompt-audio / --voxcpm2-prompt-text"Ultimate cloning" pair — reference clip + its transcript for prosody-preserving cloning.
--voxcpm2-cfg-value2.0Classifier-free guidance scale for the diffusion sampler.
--voxcpm2-timesteps10Euler solver steps per generated audio patch.
--voxcpm2-max-tokens2000Max generated patches before forced stop.
--voxcpm2-min-tokens2Min patches before the stop head is allowed to fire.
--seedSeed MLX RNG before synthesis (deterministic across runs).

Magpie Options

NVIDIA Magpie-TTS Multilingual 357M, 9 languages with 5 baked speakers. Pick the backend with --engine magpie (MLX, default) or --engine magpie-coreml (CoreML for the big models with MLX driving the LocalTransformer + audio embeddings). See the Magpie guide for the full per-language G2P breakdown. Voice cloning is not supported: --voice-sample, --speaker, and --instruct are rejected with a helpful error pointing at --magpie-speaker instead.

OptionDefaultDescription
--magpie-variantint4MLX-only. Quantisation: int4 (247 MB) or int8 (411 MB). Resolves to aufklarer/Magpie-TTS-Multilingual-357M-MLX-<variant>. The CoreML engine uses the INT8 CoreML bundle and ignores this flag.
--magpie-speakersofiaBaked speaker: sofia, aria, jason, leo, or john. Identity is consistent across all 9 languages and both backends.
--magpie-temperature0.6Sampling temperature (0 = greedy). Use 0.6 for Japanese — greedy gets stuck on the first phrase.
--magpie-top-k80Top-k filter for sampling.
--magpie-max-frames500Hard cap on codec frames (~23 s).
--magpie-min-frames4Minimum frames before EOS allowed.
--magpie-prephonemizedTreat input as IPA / phoneme stream; skip per-language G2P.
--list-speakersPrint the 5 baked speakers and exit.

magpie-coreml caveats: the bundled NanoCodec is traced at a fixed 64-frame window, so --stream is rejected. --language ja auto-routes to the MLX backend with a stderr note (the CoreML bundle doesn't ship JA tokenizer assets yet). The CoreML engine lazy-loads the MLX bundle on first synthesis to drive the LocalTransformer and average audio embeddings; pure-CoreML deployment is tracked as a follow-up.

Examples:

# Basic TTS
speech speak "Hello, world!" --output hello.wav

# Voice cloning (Qwen3-TTS)
speech speak "Hello in your voice" --voice-sample reference.wav -o cloned.wav

# Voice cloning (CosyVoice)
speech speak "Hello in your voice" --engine cosyvoice --voice-sample reference.wav -o cloned.wav

# CosyVoice multilingual
speech speak "Hallo Welt" --engine cosyvoice --language german -o hallo.wav

# Multi-speaker dialogue
speech speak "[S1] Hello there! [S2] Hey, how are you?" \
    --engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o dialogue.wav

# Inline emotion/style tags
speech speak "(excited) Wow, amazing! (sad) But I have to go..." \
    --engine cosyvoice -o emotion.wav

# Combined: dialogue + emotions + voice cloning
speech speak "[S1] (happy) Great news! [S2] (surprised) Really?" \
    --engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o combined.wav

# Custom style instruction
speech speak "Hello world" --engine cosyvoice --cosy-instruct "Speak cheerfully" -o cheerful.wav

# Magpie multilingual TTS — same Aria voice across 9 languages
speech speak "Hello, world." --engine magpie --magpie-speaker aria \
    --magpie-temperature 0 -o en.wav
speech speak "Hola mundo." --engine magpie --language es --magpie-speaker aria \
    --magpie-temperature 0 -o es.wav
# Japanese needs stochastic sampling
speech speak "こんにちは世界、これは音声合成システムです。" \
    --engine magpie --language ja --magpie-temperature 0.6 \
    --magpie-top-k 80 --seed 42 -o ja.wav
speech speak --engine magpie --list-speakers

# Magpie CoreML backend (ANE-accelerated, 8 languages, no streaming)
speech speak "Hello world." --engine magpie-coreml --magpie-speaker aria -o en.wav
speech speak "Hola mundo." --engine magpie-coreml --language es \
    --magpie-speaker leo -o es.wav
# Japanese auto-routes to MLX (CoreML bundle has no JA tokenizer)
speech speak "こんにちは。" --engine magpie-coreml --language ja -o ja.wav

# Streaming synthesis
speech speak "Long text here..." --stream

# Batch synthesis from file
speech speak --batch-file texts.txt --batch-size 4

# VoxCPM2 — 48 kHz studio output
speech speak "Hello there." --engine voxcpm2 --voxcpm2-variant int8 -o hi.wav

# VoxCPM2 — voice design
speech speak "Welcome to the show." --engine voxcpm2 \
    --voxcpm2-instruct "A young woman, warm and gentle voice." -o design.wav

# VoxCPM2 — single-reference cloning
speech speak "This is a cloned voice." --engine voxcpm2 \
    --voice-sample speaker.wav -o clone.wav

kokoro

Lightweight text-to-speech using Kokoro-82M on Neural Engine (CoreML). Non-autoregressive — single forward pass, ~45ms latency.

speech kokoro "<text>" [options]
OptionDefaultDescription
<text>Text to synthesize
--voiceaf_heartVoice preset (50 available across 10 languages)
--languageenLanguage code: en, es, fr, hi, it, ja, pt, zh, ko, de
--output, -okokoro_output.wavOutput WAV file path
--list-voicesList all available voices and exit
--model, -mHuggingFace model ID

Examples:

# Basic Kokoro TTS
speech kokoro "Hello, world!" --voice af_heart -o hello.wav

# French voice
speech kokoro "Bonjour le monde" --voice ff_siwis --language fr -o bonjour.wav

# List all 50 voices
speech kokoro --list-voices

respond

Full-duplex speech-to-speech dialogue using PersonaPlex 7B.

speech respond [options]
OptionDefaultDescription
--input, -iInput audio WAV file (24kHz mono) (required)
--output, -oresponse.wavOutput response WAV file
--voiceNATM0Voice preset (e.g. NATM0, NATF1, VARF0)
--system-promptassistantPreset: assistant, focused, customer-service, teacher
--system-prompt-textCustom system prompt text (overrides preset)
--max-steps200Max generation steps at 12.5Hz (~16s)
--streamEmit audio chunks during generation
--compileEnable compiled transformer (warmup + kernel fusion)
--list-voicesList available voice presets
--list-promptsList available system prompt presets
--transcriptPrint the model's inner monologue text
--jsonOutput as JSON (transcript, latency, audio path)
--verboseShow detailed timing info

Sampling Overrides

OptionDefaultDescription
--audio-temp0.8Audio sampling temperature
--text-temp0.7Text sampling temperature
--audio-top-k250Audio top-k candidates
--repetition-penalty1.2Audio repetition penalty (1.0 = disabled)
--text-repetition-penalty1.2Text repetition penalty (1.0 = disabled)
--repetition-window30Repetition penalty window in frames
--silence-early-stop15Silence frames before early stop (0 = disabled)
--entropy-threshold0Text entropy threshold for early stop (0 = disabled)
--entropy-window10Consecutive low-entropy steps before early stop

Examples:

# Basic speech-to-speech
speech respond --input question.wav

# Use a female voice with compiled transformer
speech respond -i question.wav --voice NATF1 --compile

# Stream response and show transcript
speech respond -i question.wav --stream --transcript --verbose

audio-translate

Streaming speech-to-speech translation using Kyutai Hibiki Zero-3B. FR / ES / PT / DE → EN, single binary, no cloud. Full guide →

speech audio-translate <input.wav> [options]
OptionDefaultDescription
<input>Source audio WAV file (mono, resampled to 24 kHz internally) (required)
--output, -otranslated.wavOutput 24 kHz English WAV file
--source-langfrSource language hint (fr, es, pt, de). Auto-detected; metadata only. FR + ES are strict E2E canaries; PT + DE are best-effort.
--quantization4bitVariant: 4bit (~2.7 GB) or 8bit (~3.9 GB)
--model-idHuggingFace model id override (takes precedence over --quantization)
--compileRun the temporal transformer warm-up pass before translating
--verbosePrint per-phase timings (Mimi encode, generation, Mimi decode)
--transcriptPrint the model's inner-monologue raw SPM token IDs (SPM decode wiring is a follow-up)

Environment Variables

VariableEffect
HIBIKI_GREEDY=1Force argmax decoding for text + target audio. Reproducible — used by the strict CI canaries.
HIBIKI_MODEL_IDOverride the default aufklarer/Hibiki-Zero-3B-MLX-4bit repo at runtime.

Examples:

# Translate a French clip to English
speech audio-translate input_fr.wav -o out_en.wav --source-lang fr

# Spanish, 8-bit, verbose
speech audio-translate input_es.wav -o out.wav --source-lang es --quantization 8bit --verbose

# Deterministic mode (matches the CI regression canaries)
HIBIKI_GREEDY=1 speech audio-translate input_fr.wav -o out.wav --source-lang fr

vad

Offline voice activity detection using Pyannote segmentation.

speech vad <file> [options]
OptionDescription
<file>Audio file to analyze
--model, -mHuggingFace model ID
--onsetOnset threshold (speech start)
--offsetOffset threshold (speech end)
--min-speechMinimum speech duration in seconds
--min-silenceMinimum silence duration in seconds
--jsonOutput as JSON

vad-stream

Streaming voice activity detection using Silero VAD v5. Processes speech in 32ms chunks.

speech vad-stream <file> [options]
OptionDescription
<file>Audio file to analyze
--engineVAD engine: mlx (default) or coreml
--model, -mHuggingFace model ID (auto-selected by engine)
--onsetOnset threshold
--offsetOffset threshold
--min-speechMinimum speech duration in seconds
--min-silenceMinimum silence duration in seconds
--jsonOutput as JSON

wake

On-device wake-word / keyword spotting using the KWS Zipformer (3.49M params, CoreML INT8, 26× real-time, English only).

speech wake <file> [options]
OptionDescription
<file>Audio file to analyze
--keywordsOne or more keywords. Formats: "hey soniqo" (greedy BPE), "hey soniqo:0.15:0.5" (with threshold/boost), or "LIGHT UP|▁ L IGHT ▁UP:0.25:2.0" (sherpa-onnx-style explicit BPE pieces)
--keywords-fileKeyword file, one entry per line (same syntax as --keywords); # for comments
--model, -mHuggingFace model ID. Defaults to aufklarer/KWS-Zipformer-3M-CoreML-INT8
--jsonOutput as JSON
# Plain phrase, tuned defaults
speech wake recording.wav --keywords "hey soniqo"

# Explicit BPE pieces for phrases the greedy tokenizer gets wrong
speech wake recording.wav --keywords "LIGHT UP|▁ L IGHT ▁UP:0.25:2.0"

# Multiple phrases + JSON output
speech wake recording.wav \
  --keywords "lovely child|▁LOVE LY ▁CHI L D:0.25:2.0" \
             "for ever|▁FOR E VER:0.25:2.0" \
  --json

diarize

Speaker diarization — identify who spoke when.

speech diarize <file> [options]
OptionDefaultDescription
<file>Audio file to analyze
--enginepyannoteDiarization engine: pyannote (segmentation + speaker chaining) or sortformer (end-to-end CoreML)
--target-speakerEnrollment audio for target speaker extraction (pyannote only)
--embedding-enginemlxSpeaker embedding engine: mlx or coreml (pyannote only)
--vad-filterPre-filter with Silero VAD (pyannote only)
--rttmOutput in RTTM format
--jsonOutput as JSON
--score-againstReference RTTM file to compute DER

Examples:

# Basic diarization (pyannote, default)
speech diarize meeting.wav

# End-to-end Sortformer (CoreML, Neural Engine)
speech diarize meeting.wav --engine sortformer

# RTTM output for evaluation
speech diarize meeting.wav --rttm

# Target speaker extraction (pyannote only)
speech diarize meeting.wav --target-speaker enrollment.wav

# Score against reference
speech diarize meeting.wav --score-against reference.rttm

embed-speaker

Extract a speaker embedding vector from audio.

speech embed-speaker <file> [options]
OptionDescription
<file>Audio file containing speaker voice
--engineInference engine: mlx (default), coreml (WeSpeaker 256-dim), or camplusplus (CAM++ CoreML 192-dim)
--jsonOutput as JSON

denoise

Remove background noise using DeepFilterNet3 on Neural Engine.

speech denoise <file> [options]
OptionDefaultDescription
<file>Input audio file
--output, -oinput_clean.wavOutput file path
--model, -mHuggingFace model ID

Example:

speech denoise noisy-recording.wav -o clean.wav

compose

Generate 30 s of music from a text prompt using MAGNeT on MLX.

speech compose <prompt> [options]
OptionDefaultDescription
<prompt>Text prompt describing the music to generate (e.g. "happy rock")
--output, -omagnet.wavOutput WAV path (32 kHz mono)
--variantsmall-int4Model variant: small-int4, small-int8, medium-int4, or medium-int8. Resolves to aufklarer/MAGNeT-{Small,Medium}-30secs-MLX-{4,8}bit.
--temperature3.0Sampling temperature, annealed linearly per stage.
--top-p0.9Nucleus sampling threshold.
--cfg-max10.0Max classifier-free guidance coefficient.
--cfg-min1.0Min CFG coefficient (annealed alongside the mask schedule).
--steps20,10,10,10Comma-separated decoding iterations per codebook (4 values).
--seedRandom seed for reproducible output.

Examples:

# Default: small-int4, ~10 s wall on M-series for a 30 s clip
speech compose "happy rock" -o happy_rock.wav

# Larger model — better prompt following, slower
speech compose "lo-fi hip hop with mellow piano" --variant medium-int4 -o lofi.wav

# Reproducible
speech compose "energetic EDM with synth lead" --seed 42 -o edm.wav