> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/cactus-compute/cactus/llms.txt
> Use this file to discover all available pages before exploring further.

# Speech-to-Text Transcription

> Real-time audio transcription with Whisper, Moonshine, and Parakeet models

## Overview

Cactus supports high-quality speech-to-text transcription with multiple model families:

* **Whisper** (tiny, base, small, medium) - OpenAI's multilingual models
* **Moonshine** - Lightweight, fast transcription
* **Parakeet** (CTC 0.6B, 1.1B) - NVIDIA's efficient models with NPU support

All transcription models support both file-based and real-time streaming transcription.

## File Transcription

### Basic Usage

```python theme={null}
from cactus import cactus_init, cactus_transcribe, cactus_destroy
import json

model = cactus_init("weights/parakeet-ctc-1.1b", None, False)

result = json.loads(
    cactus_transcribe(
        model,
        "audio.wav",  # audio file path
        None,         # prompt (optional)
        None,         # options
        None,         # callback
        None          # pcm_data
    )
)

print(result["text"])
print(f"Duration: {result['audio_duration_sec']:.2f}s")
print(f"Latency: {result['total_time_ms']:.2f}ms")

cactus_destroy(model)
```

### C API

```c theme={null}
#include <cactus.h>

cactus_model_t model = cactus_init("weights/whisper-base", NULL, false);

char response[8192];
int result = cactus_transcribe(
    model,
    "audio.wav",
    NULL,  // prompt
    response,
    sizeof(response),
    NULL,  // options
    NULL,  // callback
    NULL,  // user_data
    NULL,  // pcm_buffer
    0      // pcm_buffer_size
);

if (result == 0) {
    printf("%s\n", response);
}

cactus_destroy(model);
```

## Audio Format Requirements

<Note>
  All models expect 16 kHz mono PCM audio. If your audio is in a different format, resample it before passing to Cactus.
</Note>

For raw PCM data:

```python theme={null}
import numpy as np

# Load audio at 16 kHz
audio = np.array([...], dtype=np.float32)  # mono, 16 kHz

# Convert to 16-bit PCM
pcm_data = (audio * 32767).astype(np.int16).tobytes()

result = json.loads(
    cactus_transcribe(
        model,
        None,      # audio_path
        None,      # prompt
        None,      # options
        None,      # callback
        pcm_data   # PCM data
    )
)
```

## Response Format

```json theme={null}
{
    "success": true,
    "text": "This is the transcribed text.",
    "language": "en",
    "audio_duration_sec": 5.2,
    "time_to_first_token_ms": 120.5,
    "total_time_ms": 450.3,
    "decode_tps": 95000,
    "tokens": 12
}
```

## Streaming Transcription

Get real-time transcription results as audio is captured:

```python theme={null}
from cactus import (
    cactus_init,
    cactus_stream_transcribe_start,
    cactus_stream_transcribe_process,
    cactus_stream_transcribe_stop,
    cactus_destroy
)
import json

model = cactus_init("weights/moonshine-base", None, False)

# Start streaming session
options = json.dumps({"language": "en"})
stream = cactus_stream_transcribe_start(model, options)

# Process audio chunks (e.g., from microphone)
for audio_chunk in audio_stream:
    partial = json.loads(cactus_stream_transcribe_process(stream, audio_chunk))
    print(f"Partial: {partial['text']}", end="\r")

# Get final result
final = json.loads(cactus_stream_transcribe_stop(stream))
print(f"\nFinal: {final['text']}")

cactus_destroy(model)
```

## Prompting

Guide transcription with a text prompt:

```python theme={null}
# Improve accuracy for specific terminology
prompt = "Transcribe this audio about machine learning and neural networks."

result = json.loads(
    cactus_transcribe(model, "audio.wav", prompt, None, None, None)
)
```

## Options

```json theme={null}
{
    "language": "en",
    "task": "transcribe",
    "temperature": 0.0,
    "best_of": 5
}
```

<ParamField path="language" type="string">
  Language code (e.g., "en", "es", "fr"). Auto-detected if omitted
</ParamField>

<ParamField path="task" type="string" default="transcribe">
  Either "transcribe" or "translate" (translate to English)
</ParamField>

<ParamField path="temperature" type="number" default="0.0">
  Sampling temperature for generation
</ParamField>

<ParamField path="best_of" type="integer" default="5">
  Number of candidates to generate when temperature > 0
</ParamField>

## Streaming with Callbacks

```python theme={null}
def on_token(text, token_id):
    print(text, end="", flush=True)

result = json.loads(
    cactus_transcribe(
        model,
        "audio.wav",
        None,
        None,
        on_token,
        None
    )
)
```

## Model Comparison

| Model             | Size  | Speed | Quality | NPU |
| ----------------- | ----- | ----- | ------- | --- |
| moonshine-base    | 80MB  | ★★★★★ | ★★★     | ❌   |
| whisper-tiny      | 75MB  | ★★★★  | ★★★     | ✅   |
| whisper-base      | 145MB | ★★★   | ★★★★    | ✅   |
| whisper-small     | 488MB | ★★    | ★★★★★   | ✅   |
| parakeet-ctc-0.6b | 600MB | ★★★★  | ★★★★    | ✅   |
| parakeet-ctc-1.1b | 1.1GB | ★★★   | ★★★★★   | ✅   |

## Language Detection

Detect audio language before transcription:

```python theme={null}
result = json.loads(cactus_detect_language(model, "audio.wav", None, None))
print(f"Detected language: {result['language']}")
print(f"Confidence: {result['confidence']:.2f}")
```

## CLI Usage

```bash theme={null}
# Live microphone transcription
cactus transcribe

# Transcribe audio file
cactus transcribe --file audio.wav

# Use specific model
cactus transcribe --file audio.wav parakeet-ctc-1.1b
```

## Performance Benchmarks

Real-world latency on mobile devices (30s audio):

| Device           | Moonshine | Whisper-Base | Parakeet 1.1B |
| ---------------- | --------- | ------------ | ------------- |
| iPhone 17 Pro    | 0.2s      | 0.3s         | 0.3s          |
| Mac M4 Pro       | 0.1s      | 0.2s         | 0.1s          |
| Galaxy S25 Ultra | N/A       | N/A          | N/A           |

<Note>
  Android NPU support for Whisper and Parakeet is coming in March 2026.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Audio Embeddings" icon="fingerprint" href="/guides/embeddings">
    Generate embeddings from audio for similarity search
  </Card>

  <Card title="Voice Activity Detection" icon="waveform" href="/api/vad">
    Detect speech segments in audio
  </Card>

  <Card title="Supported Models" icon="list" href="/concepts/models">
    Browse all transcription models
  </Card>

  <Card title="API Reference" icon="code" href="/api/transcription">
    Complete transcription API docs
  </Card>
</CardGroup>
