ggml: text-to-speech, speech-to-text, alignment,
diarization, separation, and more, across 80+ model families. GoModel has a
dedicated audiocpp provider type for it.
It is an audio-only provider. /v1/audio/speech and
/v1/audio/transcriptions route to it; chat, /responses, and /v1/embeddings
return invalid_request_error, because audiocpp_server has no such endpoints.
Start the server first, with a config naming the models it serves:
Configure
The base URL is required and registers the provider —audiocpp_server’s
default port (8080) collides with GoModel’s own, so there is no default:
AUDIOCPP_API_KEY is optional and usually unset: audio.cpp has no
authentication of its own. Set it only when a reverse proxy in front of the
server expects a bearer token.
These examples assume GoModel runs in Docker and audio.cpp is on the host —
hence
host.docker.internal. If GoModel runs on the host directly, use
http://localhost:8099. A trailing /v1 is accepted and trimmed, so both
spellings address the same server. Running several instances? Register each
under a suffixed name: AUDIOCPP_GPU_BASE_URL=... creates provider
audiocpp-gpu.Verify
Voices are audio.cpp names, not OpenAI names
voice names an audio.cpp voice preset, a cached voice id, or a wav in the
configured voice library — audio.cpp has no fixed voice set, so OpenAI’s
alloy/nova/… mean nothing to it. List what a model offers with
GET /p/audiocpp/audio/voices?model=<id>.
voice is required on /v1/audio/speech, as it is in the OpenAI API. To let
audio.cpp apply a model’s configured default_voice_preset instead, call the
route through passthrough: POST /p/audiocpp/audio/speech.
Cloning parameters (voice_ref, reference_text, seed, max_tokens,
options, …) are forwarded verbatim, so audio.cpp’s own request fields work
through the standard endpoint — with one exception, a voice_ref naming a
server-side path (see below):
Audio formats
Synthesis returns WAV whateverresponse_format asked for, unless the server
was built with the MP3 frontend module. The response is labelled with the type
audio.cpp actually returned (audio/wav), not the one that was requested.
Transcription uploads must be WAV; the server rejects other containers unless
it was built with the audio_decode frontend module, which adds MP3 and FLAC.
Transcribing without an upload
audio.cpp can also read audio from the machine it runs on, and its live route carries raw PCM with no file at all. Neither shape is offered on/v1/audio/transcriptions: both let the caller choose what the audio.cpp host
reads or how long it holds a model, and being authorized for a model is not
authorization for either. They stay on the native surface below, which an
operator enables deliberately and points only at trusted callers.
For the same reason, a voice_ref on /v1/audio/speech must carry inline
base64 audio; {"type": "path"} and a bare path string are rejected and
available only through passthrough.
Streaming
For a model configured with"mode": "streaming", stream=true returns
audio.cpp’s OpenAI-shaped transcript events (transcript.text.delta,
transcript.text.done, [DONE]). GoModel relays the event stream as it is,
but reads it to completion first, so this shortens nothing end to end — it is
the live route below that emits text while the speaker is still talking.
Native endpoints
audio.cpp’s routes with no OpenAI equivalent are reachable through passthrough at/p/audiocpp/..., once an operator
opts in:
/models/load, /tasks/unload_models) and
server-local file paths there. Enable it for trusted callers only.
The /v1 prefix is optional (/p/audiocpp/audio/voices and
/p/audiocpp/v1/audio/voices are the same route); /health is served from the
server root.
The live route is the one that transcribes speech as it is captured — there is
no file, and the audio never has to exist on disk:
-T - is what keeps it live: --data-binary @- drains stdin before opening
the connection, which turns the capture back into a file upload. Whether
partial text appears during capture is a property of the model, not the
route.
Model metadata
GET /v1/models reports what audio.cpp says about each configured model:
- Family — the audio.cpp model family (
pocket_tts,moonshine_asr, …). - Mode —
audio_speechfor attsmodel andaudio_transcriptionfor anasrone. Models registered for other tasks (align, diarization, separation, …) stay listed without a mode: GoModel has no endpoint to route them to, and they are reached through passthrough instead. - Capabilities —
streamingfor a model configured with"mode": "streaming".