CLI Reference
The speech command is the entry point for local speech processing.
Install with Homebrew
On Apple Silicon with macOS 15 or newer, install the CLI using Homebrew:
brew install speech
speech --help
To update an existing installation, run brew upgrade speech.
Alternative: build from source
In a speech-swift checkout, run make build, then use .build/release/speech. See the Getting Started guide for prerequisites and source-build instructions.
transcribe
Transcribe audio files to text.
speech transcribe <file> [options]
| Option | Default | Description |
|---|---|---|
<file> | Audio file to transcribe (WAV, M4A, MP3, CAF) | |
--engine | qwen3 | ASR engine: qwen3, qwen3-coreml, parakeet, nemotron, omnilingual, cohere, voxtral, moss, whisper |
--model, -m | 0.6B | Model variant: 0.6B, 1.7B, or full HuggingFace model ID (qwen3 only) [whisper]: default, turbo, or full CoreML HuggingFace repo ID.[cohere/voxtral]: INT5 (default), INT8, FP16, a Hugging Face model ID, or a local directory. [moss coreml]: int8 (default) or fp16; [moss mlx]: int5 (default) or int8. MOSS also accepts a compatible Hugging Face repository ID or local directory. |
--max-tokens | CoreML: 512MLX: 5120 | [moss] Maximum generated transcript tokens. |
--kv-cache | fp16 | [moss mlx] Dynamic KV-cache precision: fp16 or int8. |
--language | Language hint (optional, ignored by omnilingual) | |
--window | 10 | [omnilingual] CoreML window size in seconds: 5 or 10 |
--backend | coreml | [omnilingual/moss] Backend: coreml (Neural Engine) or mlx (Metal GPU). MOSS MLX provides a dynamic 131,072-token context; MOSS CoreML uses a fixed 1,024-token state. |
--variant | 300M | [omnilingual mlx] Size: 300M, 1B, 3B, or 7B |
--bits | 4 | [omnilingual mlx] Quantisation bits: 4 or 8 |
--stream | Enable streaming transcription with VAD | |
--max-segment | 10 | Maximum segment duration in seconds (streaming) |
--partial | Emit 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
# Cohere Transcribe 2B (MLX, INT5 default)
speech transcribe recording.wav --engine cohere
speech transcribe recording.wav --engine cohere --model int8 --language de
# Voxtral Mini 3B (MLX, INT5 default)
speech transcribe recording.wav --engine voxtral
speech transcribe recording.wav --engine voxtral --model int8 --language fr
# MOSS Transcribe Diarize (CoreML short-form)
speech transcribe recording.wav --engine moss
speech transcribe recording.wav --engine moss --model fp16
# MOSS Transcribe Diarize (MLX 128K offline context; INT5 default)
speech transcribe meeting.wav --engine moss --backend mlx
speech transcribe meeting.wav --engine moss --backend mlx --model int8 --kv-cache int8
# Whisper Large-v3 Turbo (CoreML)
speech transcribe recording.wav --engine whisper
speech transcribe recording.wav --engine whisper --model turbo --language de
# Streaming with VAD
speech transcribe recording.wav --stream --partial
align
Word-level forced alignment — get precise timestamps for every word.
speech align <file> [options]
| Option | Default | Description |
|---|---|---|
<file> | Audio file | |
--text, -t | Text to align (if omitted, transcribes first) | |
--model, -m | 0.6B | ASR model for transcription: 0.6B, 1.7B, or full ID |
--aligner-model | Forced aligner model ID | |
--language | Language 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]
| Option | Default | Description |
|---|---|---|
<text> | Text to synthesize (optional if using --batch-file) | |
--engine | qwen3 | TTS engine: qwen3, cosyvoice, voxcpm2, indextts2, f5, higgs, indic-mio, magpie, or magpie-coreml |
--output, -o | output.wav | Output WAV file path |
--language | english | Language. Omit to use speaker's native dialect when --speaker is set. |
--stream | Enable streaming synthesis | |
--voice-sample | Reference audio for voice cloning (works with qwen3, cosyvoice, voxcpm2, f5, higgs, and indextts2) | |
--verbose | Show detailed timing info |
Qwen3-TTS Options
| Option | Default | Description |
|---|---|---|
--model | base | Model variant: base, customVoice, or full HF model ID |
--speaker | Speaker voice (requires --model customVoice) | |
--instruct | Style instruction (CustomVoice model) | |
--list-speakers | List available speakers and exit | |
--temperature | 0.3 | Sampling temperature |
--top-k | 50 | Top-k sampling |
--max-tokens | 500 | Maximum tokens (500 = ~40s audio) |
--batch-file | File with one text per line for batch synthesis | |
--batch-size | 4 | Max batch size for parallel generation |
--first-chunk-frames | 3 | Codec frames in first streamed chunk |
--chunk-frames | 25 | Codec frames per streamed chunk |
CosyVoice3 Options
| Option | Default | Description |
|---|---|---|
--speakers | Speaker mapping for multi-speaker dialogue: s1=alice.wav,s2=bob.wav | |
--cosy-instruct | Style instruction (overrides default). Controls voice style for CosyVoice3. | |
--turn-gap | 0.2 | Silence gap between dialogue turns in seconds |
--crossfade | 0.0 | Crossfade overlap between turns in seconds |
--model-id | HuggingFace model ID |
VoxCPM2 Options
| Option | Default | Description |
|---|---|---|
--voxcpm2-variant | bf16 | Quantisation variant: bf16, int8, or int4. Resolves to aufklarer/VoxCPM2-MLX-<variant>. |
--voxcpm2-instruct | Natural-language voice description (voice design), e.g. "a young woman, warm and gentle". | |
--voxcpm2-ref-audio | Reference 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-value | 2.0 | Classifier-free guidance scale for the diffusion sampler. |
--voxcpm2-timesteps | 10 | Euler solver steps per generated audio patch. |
--voxcpm2-max-tokens | 2000 | Max generated patches before forced stop. |
--voxcpm2-min-tokens | 2 | Min patches before the stop head is allowed to fire. |
--seed | Seed MLX RNG before synthesis (deterministic across runs). |
IndexTTS2 Options
IndexTTS2 is a zero-shot voice-cloning engine backed by an expanded MLX bundle. It requires --voice-sample and currently runs batch synthesis only.
| Option | Default | Description |
|---|---|---|
--indextts2-model-id | aufklarer/IndexTTS2-MLX-fp16 | HuggingFace model ID. Defaults to aufklarer/IndexTTS2-MLX-fp16. |
--indextts2-bundle-dir | Load a local expanded bundle instead of downloading from Hugging Face. | |
--indextts2-emotion-audio | Optional emotion/style reference audio. Defaults to the speaker reference. | |
--indextts2-emotion | Optional preset or 8-value emotion vector. Presets include eager, happy, excited, and calm. | |
--indextts2-emotion-weight | 1.0 | Scales --indextts2-emotion; keep modest when speaker identity matters. |
--indextts2-speaking-rate | 1.0 | Speaking-rate multiplier from 0.5 to 1.5; values above 1.0 are faster. |
--indextts2-max-pause | Optional cap for long internal low-energy pauses, in seconds. | |
--indextts2-s2mel-steps | 15 | S2Mel flow steps (default 15, ear-validated; 25 matches upstream exactly) |
F5-TTS Options
| Option | Default | Description |
|---|---|---|
--f5-reference-text | Reference transcript: the text content of --voice-sample (required) | |
--f5-steps | 16 | Flow-matching steps (default 16; 32 for maximum fidelity) |
--f5-cfg-strength | 2.0 | Classifier-free guidance strength |
--f5-sway | -1.0 | Sway sampling coefficient |
--f5-speed | 1.0 | Speaking-rate multiplier |
--f5-seed | 0 | Seed for deterministic output |
--f5-target-rms | 0.1 | Reference RMS normalization target |
--f5-model-id | Hugging Face model ID | |
--f5-bundle-dir | Load a bundle from this local directory |
Higgs TTS 3 Options
| Option | Default | Description |
|---|---|---|
--higgs-ref-text | Reference transcript: the text content of --voice-sample (improves cloning) | |
--higgs-temperature | 0.8 | Sampling temperature (default 0.8) |
--higgs-top-p | Nucleus sampling threshold (off by default) | |
--higgs-top-k | Top-k sampling cutoff (off by default) | |
--higgs-max-new-tokens | 2048 | Maximum generated audio frames (25 per second) |
--higgs-seed | 0 | Seed for deterministic output |
--higgs-model-id | Hugging Face model ID | |
--higgs-bundle-dir | Load a bundle from this local directory |
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.
| Option | Default | Description |
|---|---|---|
--magpie-variant | int4 | MLX-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-speaker | sofia | Baked speaker: sofia, aria, jason, leo, or john. Identity is consistent across all 9 languages and both backends. |
--magpie-temperature | 0.6 | Sampling temperature (0 = greedy). Use 0.6 for Japanese — greedy gets stuck on the first phrase. |
--magpie-top-k | 80 | Top-k filter for sampling. |
--magpie-max-frames | 500 | Hard cap on codec frames (~23 s). |
--magpie-min-frames | 4 | Minimum frames before EOS allowed. |
--magpie-prephonemized | Treat input as IPA / phoneme stream; skip per-language G2P. | |
--list-speakers | Print 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
# Voice cloning (IndexTTS2)
speech speak "Hello in your voice" --engine indextts2 \
--voice-sample reference.wav --indextts2-speaking-rate 1.35 \
--indextts2-max-pause 0.05 -o indextts2.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]
| Option | Default | Description |
|---|---|---|
<text> | Text to synthesize | |
--voice | af_heart | Voice preset (50 available across 10 languages) |
--language | en | Language code: en, es, fr, hi, it, ja, pt, zh, ko, de |
--output, -o | kokoro_output.wav | Output WAV file path |
--list-voices | List all available voices and exit | |
--model, -m | HuggingFace 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]
| Option | Default | Description |
|---|---|---|
--input, -i | Input audio WAV file (24kHz mono) (required) | |
--output, -o | response.wav | Output response WAV file |
--voice | NATM0 | Voice preset (e.g. NATM0, NATF1, VARF0) |
--system-prompt | assistant | Preset: assistant, focused, customer-service, teacher |
--system-prompt-text | Custom system prompt text (overrides preset) | |
--max-steps | 200 | Max generation steps at 12.5Hz (~16s) |
--stream | Emit audio chunks during generation | |
--compile | Enable compiled transformer (warmup + kernel fusion) | |
--list-voices | List available voice presets | |
--list-prompts | List available system prompt presets | |
--transcript | Print the model's inner monologue text | |
--json | Output as JSON (transcript, latency, audio path) | |
--verbose | Show detailed timing info |
Sampling Overrides
| Option | Default | Description |
|---|---|---|
--audio-temp | 0.8 | Audio sampling temperature |
--text-temp | 0.7 | Text sampling temperature |
--audio-top-k | 250 | Audio top-k candidates |
--repetition-penalty | 1.2 | Audio repetition penalty (1.0 = disabled) |
--text-repetition-penalty | 1.2 | Text repetition penalty (1.0 = disabled) |
--repetition-window | 30 | Repetition penalty window in frames |
--silence-early-stop | 15 | Silence frames before early stop (0 = disabled) |
--entropy-threshold | 0 | Text entropy threshold for early stop (0 = disabled) |
--entropy-window | 10 | Consecutive 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
voice-chat
Live full-duplex conversation with Soniqo, powered by NVIDIA Nemotron VoiceChat 11B. Microphone mode enables Apple AEC, streaming RNN-T captions, human-facing realtime metrics, adaptive 8→2→1-step voice refinement, and bounded input resynchronization instead of a long silent catch-up.
speech voice-chat [options]
| Option | Default | Description |
|---|---|---|
--model, -m | aufklarer/VoiceChat-11B-Perception-MLX-int5 | Hugging Face model ID or complete local bundle. |
--revision | main | Hub revision. |
--system-prompt | Override the system prompt. | |
--mcp-config | Provider-neutral JSON configuration for MCP tool servers. | |
--mcp-server | all configured | Select one configured server; repeat to select more. |
--mcp-write-policy | allow | Write policy: immediate allow, model-mediated confirm, or deny. |
--mcp-timeout-seconds | 15 | MCP tool-call timeout; server startup allows at least 60 seconds. |
--greet | Ask the model to greet first. | |
--no-aec | Disable Apple acoustic echo cancellation. | |
--no-transcript | Disable live RNN-T user captions. | |
--no-rnnt-turn-taking | Disable NVIDIA RNN-T turn-taking safety fallbacks. | |
--prebuffer-frames | 3 | 80 ms output frames buffered before playback. |
--max-buffered-frames | 8 | Maximum queued 80 ms microphone frames before stale audio is dropped. |
--max-seconds | Stop live capture after this many seconds. | |
--input | Read an audio file instead of the microphone. | |
--output, -o | Write the full-context 22.05 kHz WAV. | |
--tail-seconds | 6 | Silence appended after file input. |
--force-turn-at-end | Force BOS at file EOF; regression tests only. | |
--plain | Use append-only output instead of the fixed redraw dashboard. | |
--debug-timeline | Show relative phrase and generated-pronunciation-end timestamps plus decoded tool-call lifecycle events. | |
--terminal-width | 120 | Terminal display width. |
--temperature | 0 | Text temperature; 0 is greedy. |
--text-top-p | 1 | Text top-p. |
--guidance | 0.2 | EAR-TTS guidance strength. |
--speech-top-p | 0.95 | EAR-TTS top-p. |
--speech-noise | 0.001 | EAR-TTS sampling noise. |
--speech-iterations | 8 | EAR-TTS MaskGIT iterations per frame. |
--realtime-speech-iterations | 2 | Intermediate voice-refinement budget used to protect realtime speed; severe overload uses one step. |
--live-speech-context-seconds | 20 | Recent EAR-TTS history retained in live mode; 0 keeps full history. |
Examples:
speech voice-chat
speech voice-chat --model /path/to/complete-bundle --prebuffer-frames 3
speech voice-chat --input question.wav --output response.wav
speech voice-chat --mcp-config Examples/VoiceChatMCP/apple-reminders.json
With MCP enabled, model-native call JSON and returned tool-response tokens use NVIDIA's two-phase asynchronous function path on a cached silence embedding. There is no transcript router, regular-expression matcher, reminder draft state, argument repair, or scripted assistant reply: the checkpoint alone chooses a tool and its arguments. The coordinator only validates the native JSON, applies read/write policy, executes the selected MCP operation, and returns structured results through the trained function channel. Writes execute immediately under the default allow policy, removing the second confirmation turn from the reminders demo; an identical completed write is still suppressed until fresh user speech. Use confirm only when model-mediated confirmation is explicitly wanted, or deny to refuse writes. MCP commands run locally with the current user's filesystem and application permissions, so use only trusted configuration files and server packages.
Microphone perception and RNN-T captions continue between model steps, while external MCP I/O runs in a separate task. Speech-bearing microphone regions captured while the shared function cache is busy are retained as evaluated embeddings and replayed causally after the result, so a captioned follow-up is no longer discarded. Replay is limited to one old semantic frame per live callback; the corresponding new frame remains queued, replay text is forced to PAD, and already-elapsed audio is never queued to the speaker. Matching idle EAR-TTS cache positions synchronize later in bounded eight-frame chunks. The dashboard separates native call decoding, the MCP round trip, and tool-result cache synchronization. Decode and result lines show model/cache compute plus live interleave, the residual used by actor yields, bookkeeping, and system contention; foreground audio RTF measures none of that background work. Once a call is open, the forced-PAD text channel skips its unused full-vocabulary projection. After EOTC, the two-phase path freezes the shared language and EAR-TTS timeline while the external result is pending; microphone frames remain live for perception and RNN-T but do not become synthetic PAD positions before the result. Known results replay in bounded 16-token causal-prefill chunks. The live loop reads one coherent function snapshot and one MCP snapshot every 160 ms instead of making several actor calls after every microphone frame. Ordinary conversation retains the 40-frame RNN-T safety fallback, while an already-proposed native tool candidate may commit after eight blank frames. The text and function channels still share one Nemotron-H cache, so coherent result-conditioned speech starts only after the function response closes; arbitrary assistant speech cannot safely run as a second causal future in parallel.
A clean M5 Pro 48 GB release profile measured 3.56–4.00 seconds from end of speech to the first model-authored post-tool speech for three reminder-list phrasings with a fixed 200 ms provider. Native JSON decoding used 27–31 steps in 1.15–1.28 seconds, and a 67-token result synchronized in 0.58–0.72 seconds. With a deliberately slow two-second provider, microphone work during the wait remained 19.6 ms p95 and 19.8 ms maximum. A final clean run measured 118 ms microphone-service p95 and 139 ms p95 lateness beyond the 80 ms capture deadlines. The provider therefore adds reply latency without freezing capture; the remaining compute limit is native call decoding plus shared-cache result replay.
The bundled demo exposes only list_reminders, create_reminder, and update_reminder; list discovery remains adapter-private. One flattened reminder read covers every EventKit list and replaces long provider UUIDs with stable, session-scoped references such as r1. Updates return one of those model-visible references, and the adapter resolves it exactly before execution; it never matches spoken names or transcript text. No-op updates and fractional priorities are rejected rather than reported as successful changes. A controlled update regression fell from 67 native steps / 5.25 seconds with a realistic UUID to 37 steps / about 2.29 seconds with r1. Create requires only a name while optional provider defaults remain optional. The streaming RNN-T frontend uses NeMo-compatible reflection padding at rolling window edges instead of zero padding.
File mode is the hardware-free reproducible path. --force-turn-at-end is only for controlled regression tests and must not be reported as natural turn-taking latency.
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]
| Option | Default | Description |
|---|---|---|
<input> | Source audio WAV file (mono, resampled to 24 kHz internally) (required) | |
--output, -o | translated.wav | Output 24 kHz English WAV file |
--source-lang | fr | Source language hint (fr, es, pt, de). Auto-detected; metadata only. FR + ES are strict E2E canaries; PT + DE are best-effort. |
--quantization | 4bit | Variant: 4bit (~2.7 GB) or 8bit (~3.9 GB) |
--model-id | HuggingFace model id override (takes precedence over --quantization) | |
--compile | Run the temporal transformer warm-up pass before translating | |
--verbose | Print per-phase timings (Mimi encode, generation, Mimi decode) | |
--transcript | Print the model's inner-monologue raw SPM token IDs (SPM decode wiring is a follow-up) |
Environment Variables
| Variable | Effect |
|---|---|
HIBIKI_GREEDY=1 | Force argmax decoding for text + target audio. Reproducible — used by the strict CI canaries. |
HIBIKI_MODEL_ID | Override 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]
| Option | Description |
|---|---|
<file> | Audio file to analyze |
--model, -m | HuggingFace model ID |
--onset | Onset threshold (speech start) |
--offset | Offset threshold (speech end) |
--min-speech | Minimum speech duration in seconds |
--min-silence | Minimum silence duration in seconds |
--json | Output as JSON |
vad-stream
Streaming voice activity detection using Silero VAD v5. Processes speech in 32ms chunks.
speech vad-stream <file> [options]
| Option | Description |
|---|---|
<file> | Audio file to analyze |
--engine | VAD engine: mlx (default) or coreml |
--model, -m | HuggingFace model ID (auto-selected by engine) |
--onset | Onset threshold |
--offset | Offset threshold |
--min-speech | Minimum speech duration in seconds |
--min-silence | Minimum silence duration in seconds |
--json | Output as JSON |
--smart-turn | Confirm each pause with Smart Turn before ending a segment; mid-sentence pauses merge into one segment |
--turn-threshold | Smart Turn completion threshold (default 0.5) |
--turn-max-silence | Seconds of silence after a vetoed pause that end the segment anyway (default 2.0) |
turn
End-of-turn detection with Smart Turn v3.2 (8M params, CoreML, 23 languages). Scores the last 8 s of a recorded utterance and prints the probability that the speaker has finished, the complete / incomplete verdict, and the inference time.
speech turn <file> [options]
| Option | Description |
|---|---|
<file> | Audio file with one user turn (any sample rate); the last 8 s are used |
--threshold | Probability at or above which the turn counts as complete (default 0.5) |
--model, -m | HuggingFace model ID. Defaults to aufklarer/Smart-Turn-v3.2-CoreML |
--model-dir | Local directory holding smart_turn.mlmodelc and config.json; skips the download |
--json | Output as JSON |
# Probability, verdict and inference time for one utterance
speech turn utterance.wav
# Custom threshold, JSON output
speech turn utterance.wav --threshold 0.7 --json
# Streaming VAD with Smart Turn confirming each pause
speech vad-stream call.wav --smart-turn --turn-threshold 0.6 --turn-max-silence 1.5
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]
| Option | Description |
|---|---|
<file> | Audio file to analyze |
--keywords | One 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-file | Keyword file, one entry per line (same syntax as --keywords); # for comments |
--model, -m | HuggingFace model ID. Defaults to aufklarer/KWS-Zipformer-3M-CoreML-INT8 |
--json | Output 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]
| Option | Default | Description |
|---|---|---|
<file> | Audio file to analyze | |
--engine | pyannote | Diarization engine: pyannote, community1 (CoreML + native PLDA/VBx), or sortformer |
--community1-compute-units | ane | Community-1 CoreML compute units: ane, cpu, gpu, or all |
--num-speakers | Known exact speaker count for Community-1 | |
--min-speakers | 1 | Minimum speaker count for Community-1 |
--max-speakers | Maximum speaker count for Community-1 | |
--target-speaker | Enrollment audio for target speaker extraction (pyannote only) | |
--embedding-engine | mlx | Speaker embedding engine: mlx or coreml (pyannote only) |
--vad-filter | Pre-filter with Silero VAD (pyannote only) | |
--rttm | Output in RTTM format | |
--json | Output as JSON | |
--score-against | Reference RTTM file to compute DER |
Examples:
# Basic diarization (pyannote, default)
speech diarize meeting.wav
# Community-1 (CoreML + native PLDA/VBx)
speech diarize meeting.wav --engine community1 --min-speakers 2 --max-speakers 6
# 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]
| Option | Description |
|---|---|
<file> | Audio file containing speaker voice |
--engine | mlx (default) or coreml for WeSpeaker 256-dim; redimnet2 for persistent identity CoreML 192-dim; camplusplus for CAM++ CoreML 192-dim |
--json | Output as JSON |
language-id
Identify the spoken language in an audio file.
speech language-id <file> [options]
| Option | Description |
|---|---|
<file> | Audio file to classify |
--engine | Inference engine: mlx or coreml |
--model | Override the Hugging Face model ID |
--top | Number of ranked language candidates |
--json | Output the result as JSON |
speech language-id recording.wav --top 5
speech language-id recording.wav --engine coreml --json
denoise
Remove background noise using DeepFilterNet3 on Neural Engine.
speech denoise <file> [options]
| Option | Default | Description |
|---|---|---|
<file> | Input audio file | |
--output, -o | input_clean.wav | Output file path |
--model, -m | HuggingFace 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]
| Option | Default | Description |
|---|---|---|
<prompt> | Text prompt describing the music to generate (e.g. "happy rock") | |
--output, -o | magnet.wav | Output WAV path (32 kHz mono) |
--variant | small-int4 | Model variant: small-int4, small-int8, medium-int4, or medium-int8. Resolves to aufklarer/MAGNeT-{Small,Medium}-30secs-MLX-{4,8}bit. |
--temperature | 3.0 | Sampling temperature, annealed linearly per stage. |
--top-p | 0.9 | Nucleus sampling threshold. |
--cfg-max | 10.0 | Max classifier-free guidance coefficient. |
--cfg-min | 1.0 | Min CFG coefficient (annealed alongside the mask schedule). |
--steps | 20,10,10,10 | Comma-separated decoding iterations per codebook (4 values). |
--seed | Random 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
transcribe-batch
Transcribe a directory of audio files; the model is loaded once.
speech transcribe-batch <input-dir> [options]
| Option | Default | Description |
|---|---|---|
<input-dir> | Directory of audio files to transcribe (WAV, FLAC, etc.) | |
--output-dir | Output directory for the transcripts | |
--engine | qwen3 | ASR engine (same values as transcribe) |
--jsonl | Output results as JSON lines, one per file |
restore
Restore speech (denoise + dereverb) with Sidon — CoreML, 48 kHz output.
speech restore <audio-file> [options]
| Option | Default | Description |
|---|---|---|
--output, -o | input_restored.wav | Output WAV file path (48 kHz) |
--variant | fp16 | Precision / bundle variant |
--compute-units | Core ML placement for both stages: ane, gpu, cpu, all (default: vocoder gpu, predictor auto) |
separate
Separate a music track into stems (vocals, drums, bass, other).
speech separate <input> [options]
| Option | Default | Description |
|---|---|---|
--stems | vocals,drums,bass,other | Stems to extract: vocals, drums, bass, other |
--engine | umx | Engine: umx (default) or htdemucs (higher quality) |
--output-dir | Output directory for the transcripts |
upsample
Audio super-resolution with FlashSR — one-step distilled AudioSR, 48 kHz output.
speech upsample <audio-file> [options]
| Option | Default | Description |
|---|---|---|
--output, -o | hr.wav | Output WAV file path (48 kHz) |
--variant | int4 | Precision / bundle variant |
--seed | Seed for deterministic output |
qwen3-tts-coreml
Text-to-speech with Qwen3-TTS on CoreML (Neural Engine).
speech qwen3-tts-coreml "<text>" [options]
| Option | Default | Description |
|---|---|---|
--output, -o | output.wav | Output WAV file path |
--language | english | Output language |
--model | Hugging Face model ID |
vibevoice
Text-to-speech with Microsoft VibeVoice (MLX).
speech vibevoice "<text>" --voice-cache <cache> [options]
| Option | Default | Description |
|---|---|---|
--voice-cache, -v | Voice cache from vibevoice-encode-voice (required) | |
--steps | DPM-Solver inference steps (higher = better quality) | |
--cfg | 1.3 | Classifier-free guidance strength |
--long-form | Chunked long-form synthesis for long texts |
vibevoice-encode-voice
Mint a VibeVoice voice cache from a reference recording plus transcript.
speech vibevoice-encode-voice <input> "<transcript>" [options]
| Option | Default | Description |
|---|---|---|
<input> | Reference audio file | |
<transcript> | Transcript of the reference audio (English only) | |
--output, -o | Output voice cache (.safetensors) |
translate
Translate text into a target language with MADLAD-400 (MLX).
speech translate "<text>" --to <lang> [options]
| Option | Default | Description |
|---|---|---|
--to, -t | Target language code (ISO 639-1, e.g. es, zh, ja) | |
--stream | Stream tokens as they decode | |
--model | Hugging Face model ID |
avatar-motion
Generate NVIDIA Audio2Face-3D avatar-motion coefficient frames from speech audio.
speech avatar-motion <input> [options]
| Option | Default | Description |
|---|---|---|
--output, -o | avatar-motion.jsonl | Output JSONL file path |
--model | …James-MLX | Avatar identity bundle (James default; Claire and Mark available) |
--verbose | Print timing and frame counts |