Capabilities
The network does more than chat completion. Transcribe audio with dollama transcribe, generate text embeddings with dollama embed — routed to nodes that advertise the capability, not to whichever model happens to be loaded.
The network does more than chat completion. Transcribe audio with dollama transcribe, generate text embeddings with dollama embed — routed to nodes that advertise the capability, not to whichever model happens to be loaded.
Most of dollama routes an LLM prompt to a node running a worker, planner, or helper model. Capabilities are a separate axis. A node can advertise that it can transcribe audio or produce embedding vectors, independently of which LLM role it was assigned — and the relay keeps a distinct pool for each, so a transcription request is matched against nodes that can actually transcribe.
Two capabilities are documented here: audio_stt (speech-to-text) and
embeddings. Both follow the same shape — your CLI sends the request, the relay picks
a node from that capability's pool, the node does the work and streams the result back. As
everywhere else on dollama, the relay stays content-free: your audio and your
text are pulled by the serving node over the content tunnel, never stored on the relay.
You can see what the live network currently offers — pool depth, benchmark medians, and each
capability's wire contract — under the capabilities key of
GET /v1/network/models.
Sends a local audio file to a node advertising audio_stt and prints the transcript
as JSON. Per-word timestamps are on by default. Progress streams back as the transcription runs,
so a long clip reports partial text rather than sitting silent.
dollama transcribe recording.wav
dollama transcribe --language en --verbatim voicemail.ogg
dollama transcribe clip.wav --output transcript.json
| Flag | Type | Default | Description |
|---|---|---|---|
| --language | string | auto-detect | ISO-639-1 hint (e.g. en). Omit to let the model detect the language. |
| --verbatim | bool | false | Retain fillers and disfluencies (“um”, “uh”). Routes to a filler-preserving model with more precise timestamps. |
| --no-word-timestamps | bool | false | Omit per-word start/end times. Word timestamps are on unless you turn them off. |
| --initial-prompt | string | "" | Vocabulary or glossary bias for domain terms — names, jargon, product words the model would otherwise mishear. |
| --model | string | (network default) | Explicit STT model. Omit unless you have a reason. |
| --public | bool | false | Allow routing to public volunteer nodes. Off by default — see Routing & privacy. |
| --output | string | stdout | Write the JSON result to this file instead of stdout. |
| --relay-url | string | (config) | Relay URL override. |
| --token | string | (config) | Auth token override. |
{"text", "language", "words", "duration_s"}. Each entry in words carries
word, start, and end in seconds — enough to build subtitles,
seek to a phrase, or align a transcript against the source audio.
{
"text": "the quick brown fox",
"language": "en",
"duration_s": 3.0,
"words": [
{ "word": "the", "start": 0.00, "end": 0.20 },
{ "word": "quick", "start": 0.20, "end": 0.55 }
]
}
Word-level probability is part of the schema but the backend does not populate it in
practice, so treat it as absent rather than as a confidence score.
Use --initial-prompt for domain vocabulary. It biases the decoder
toward words it would otherwise guess wrong — the single highest-leverage flag on this command:
dollama transcribe standup.wav \
--initial-prompt "dollama, Ollama, Qwen, relay, OET, Fly.io, Neon"
Pass --language when you know it. Auto-detection costs accuracy on
short or noisy clips. Use --verbatim only when hesitations matter —
for meeting notes or captions the default reads far better.
STT runs on Speaches,
an OpenAI-compatible faster-whisper server that dollama installs and manages alongside Ollama.
dollama setup offers to install it; you can also add it later:
dollama audio-install # install and start Speaches
dollama audio-probe # check whether this machine can host it
dollama benchmark --stt # measure RTF and WER, cache the result
dollama benchmark --stt --sweep # compare whisper model sizes on your hardware
The install is CPU-capable and gated only on disk space, not on VRAM — a machine too small to serve LLM inference can still contribute transcription, which is why setup recommends it more strongly on client-only hardware. You can also enable, benchmark, and compare models from the Settings → Speech-to-Text card in the local dashboard.
Your benchmark decides whether the node joins the audio_stt pool at all:
| Axis | Meaning | Gate |
|---|---|---|
| rtf | Real-time factor — processing time divided by audio duration. Lower is better; below 1.0 means faster than real time. | ≤ 1.0 |
| wer | Word error rate against reference transcripts, as a percentage. | ≤ 25% |
WER needs a real speech corpus with reference transcripts to measure. Set stt_corpus_dir
in your config to a folder of clip.wav / clip.txt pairs to calibrate it;
without one, the benchmark measures RTF against a synthetic probe and reports WER as uncalibrated.
Sends one or more texts to a node advertising embeddings and prints the vectors as
JSON. Built for scripts, RAG indexing pipelines, and one-off lookups — not an interactive session.
It lets you build retrieval on dollama without a local GPU budget for an embedding model.
dollama embed "what is the capital of France?"
# A batch in one round trip — measurably faster per item than looping.
dollama embed "first chunk" "second chunk" "third chunk"
dollama embed --file chunks.txt # one text per non-empty line
cat chunks.txt | dollama embed # same, from stdin
| Flag | Type | Default | Description |
|---|---|---|---|
| --file | string | "" | Read texts from this file, one per non-empty line, instead of args or stdin. |
| --no-truncate | bool | false | Error instead of truncating inputs that exceed the model's context. |
| --model | string | (network default) | Embedding model override. The network sanctions one model so every vector is comparable — see below. |
| --output | string | stdout | Write the JSON result to this file instead of stdout. |
| --relay-url | string | (config) | Relay URL override. |
| --token | string | (config) | Auth token override. |
{"model", "dims", "embeddings", "usage"}. embeddings is one float array
per input text, in the same order as the inputs, and dims is the
vector width.
{
"model": "qwen3-embedding:0.6b",
"dims": 1024,
"embeddings": [[0.0123, -0.0456, "…"]],
"usage": { "prompt_tokens": 8 }
}
Batch rather than loop. Sending N texts in one call is one network round trip and one backend call; sending them one at a time is N of each. A single request accepts up to 512 texts or 8 MiB of text, whichever comes first.
The network deliberately sanctions a single embedding model rather than a hot-swappable set. Vectors from different models are not comparable, so one model network-wide is what makes an index built today still searchable tomorrow — and it keeps a small embedding model resident alongside a node's LLM role instead of thrashing them against each other.
Embeddings need no extra host process — Ollama already serves embedding models
natively, so your node's existing Ollama is the backend. dollama setup offers to pull
the sanctioned model and benchmark it; the Settings → Embeddings card in the
dashboard does the same at any time.
dollama benchmark --embeddings # measure throughput and latency
dollama benchmark --embeddings --sweep # compare embedding models on your hardware
The model is small enough (0.6B-class) to stay loaded next to a worker or helper model on most GPUs, and is negligible on a CPU-only box — so this is a real way for modest hardware to contribute.
| Axis | Meaning | Gate |
|---|---|---|
| embed_tok_per_sec | Input tokens embedded per second on a single-item call. | ≥ 20 |
| p95_latency_ms_single | 95th-percentile latency for a single-item request. | ≤ 2000 ms |
| batch_speedup | Batch throughput divided by single-item throughput. | informational |
batch_speedup never gates membership — it exists so the fleet-wide benchmark surface
can show how much batching actually helps. A node below either real gate simply doesn't join the
pool; nothing else about it changes.
Recorded speech is treated as more sensitive than a chat prompt, so dollama transcribe
routes to your own nodes and your groups' nodes only, and
fails closed: if none is available the request errors rather than falling through
to a public volunteer. Pass --public to deliberately opt into the public pool.
This is enforced in two independent places — the relay's node picker and again in the claim itself — so a routing bug in one cannot leak a private clip through the other.
dollama embed uses the same privacy mode as the rest of your session
(dollama private / group / network). If you are indexing
sensitive material, run in private or group mode so the work stays on machines you or your group
control.
Audio clips travel as a content reference the serving node pulls over the reverse content tunnel; the relay routes and streams but holds nothing. Embedding inputs ride inline with the request for latency reasons, and are likewise never persisted relay-side. See Docs for the full data-flow picture.
Being straight about the edges, so you don't build against something that isn't there:
| Not available | What to do instead |
|---|---|
OpenAI-compatible /v1/audio/transcriptions or /v1/embeddings REST endpoints |
Use the CLI, or send a request to POST /v1/messages naming the capability. See the API Reference. |
| Microphone capture and voice-activity detection | Record with any tool you like and pass the file. dollama has no client-side capture pipeline. |
| Streaming audio in — live dictation from an open mic | Send whole clips. Transcription progress streams back out, but the input is a complete file; clips are capped at 5 minutes. |
| Text-to-speech / read-aloud | Not implemented. Designed, not built. |
| Speaker diarization (“who said what”) | Not implemented. |
| Vector storage or search | dollama embed returns vectors; storing and searching them is yours. Any vector store works. |
Both capabilities depend on nodes choosing to advertise them. If a request fails with no node
available, check the capabilities key of
GET /v1/network/models for the current pool depth — and consider serving it yourself.