Speaker Diarization
OpenASR can label transcript segments with per-speaker identities. Diarization is a model-agnostic stage that wraps around any ASR executor — it composes with every native model family additively, using neural VAD plus speaker segmentation, embedding, and clustering.
All processing is local. No network calls are made beyond a one-time, consented capability-pack install. Only L2-normalized embeddings are stored — raw enrollment audio is never written to the voiceprint store. Voice matching is a diarization convenience, not authentication.
Enabling diarization
Section titled “Enabling diarization”Pass --diarize to transcribe or live:
openasr transcribe --diarize recording.wavopenasr live --diarizeSegments are labeled with anonymous speakers in zero-padded format:
SPEAKER_00, SPEAKER_01, and so on.
If the required WeSpeaker speaker-embedder capability pack is not already
installed, passing --diarize triggers an automatic install — the flag itself
is the consent. The install reuses the same progress UI as openasr pull. If
--diarize is passed on a backend or pack that does not support diarization,
the CLI fails closed with an error rather than silently skipping it.
Forcing a speaker count
Section titled “Forcing a speaker count”For offline transcription you can force an exact cluster count:
openasr transcribe --diarize --speakers 3 recording.wav--speakers accepts a positive integer and requires --diarize. It is
available on transcribe only — live does not support a forced speaker
count.
Voice-match enrollment
Section titled “Voice-match enrollment”Enroll a voice-match profile so diarized output uses a display name instead of an anonymous label:
openasr speaker enroll enroll.wav --name "Alice" --match-similarity 0.6| Option | Description | Default |
|---|---|---|
<input> | 16 kHz mono PCM16 WAV with at least five seconds of speech. | (required) |
--name | Display name used when this voice matches. | SPEAKER_ME |
--match-similarity | Cosine similarity threshold (0–1) required for a match. | 0.5 |
If your audio is not in the right format, convert it with ffmpeg:
ffmpeg -i input.mp3 -ac 1 -ar 16000 -c:a pcm_s16le enroll.wavOn success the CLI prints the profile name, ID, input path, and storage location. The profile takes effect on the next diarized session.
Clearing profiles
Section titled “Clearing profiles”Remove all local voice-match profiles:
openasr speaker clearThis deletes the on-disk voiceprint store entirely.
Storage location
Section titled “Storage location”Profiles are stored at OPENASR_HOME/diarize/voiceprints.json by default.
Override the path with the OPENASR_SPEAKER_PROFILES environment variable.
Server API
Section titled “Server API”The server exposes a REST surface for managing voice-match profiles. All
/v1/speakers routes are operator-only — they require the pairing admin
token when pairing auth is enabled.
List profiles
Section titled “List profiles”curl -s http://127.0.0.1:8080/v1/speakersEach profile in the response includes:
| Field | Type | Description |
|---|---|---|
id | string | Profile identifier. |
name | string | Display name. |
created_at | string | Creation timestamp. |
sample_seconds | number | Duration of the enrollment audio. |
compatible | bool | Whether the stored embedding matches the currently active speaker-embedder. |
Enroll a profile
Section titled “Enroll a profile”curl -s http://127.0.0.1:8080/v1/speakers \ -F name=Alice \Rename a profile
Section titled “Rename a profile”curl -s -X PATCH http://127.0.0.1:8080/v1/speakers/{id} \ -H "Content-Type: application/json" \ -d '{"name": "Bob"}'Re-enroll a profile
Section titled “Re-enroll a profile”Replace a profile’s stored embedding from a new recording without changing its ID:
curl -s -X POST http://127.0.0.1:8080/v1/speakers/{id}/reenroll \ -F wav=@new_sample.wavDelete a profile
Section titled “Delete a profile”curl -s -X DELETE http://127.0.0.1:8080/v1/speakers/{id}Returns { "id": "...", "deleted": true }.
Privacy model
Section titled “Privacy model”- Embeddings only — raw enrollment audio is never persisted. The voiceprint store contains L2-normalized embeddings and the active speaker-embedder identity.
- Local processing — diarization runs entirely on-device. The only
network activity is the one-time capability-pack download, which only
happens when you pass
--diarizeand the pack is missing. - Not authentication — voice matching assigns display names during diarization. It is not an identity-verification mechanism.
- No telemetry.
See the CLI reference for the full flag list and Server API for the complete endpoint table.