ASR + diarization service built around Parakeet transcription and Sortformer diarization. The API exposes an OpenAI-style /v1/audio/transcriptions endpoint with optional diarization. Runtime-selectable ASR adapters include Parakeet, Whisper, faster-whisper, Cohere Transcribe, and IBM Granite Speech.
docker compose build api
docker compose up api
API guide: docs/api.md
One-off command-line transcription:
export LD_LIBRARY_PATH="$PWD/.venv/lib/python3.12/site-packages/nvidia/cu13/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
python transcribe_parakeet.py Examples/output_10s.mp3 \
--backend transformers-asr \
--model granite-speech-4.1-2b-nar \
--timestamps none
The historical transcribe_parakeet.py AUDIO command remains valid. Use
--backend and --model to select another adapter.
ASR API (main service, api.py):
POST /v1/audio/transcriptions (multipart/form-data)GET /healthGET /v1/modelsGET /v1/models/currentPOST /v1/models/currentStandalone diarization service (optional, diarize_api.py):
POST /v1/diarize (multipart/form-data)GET /healthPOST /v1/audio/transcriptionsRequired form fields:
file (WAV/FLAC/MP3)response_format=verbose_json (only supported value)Optional form fields:
diarization=true|false (default false)timestamps=word|segment|none (default word)language=en (default en)chunk_mode=memory|file (default memory)chunk_only=true|false (default false)trace_audio=true|false (default false)force_vad=off|on (default off)vad_sample_rate, vad_threshold, vad_min_speech_ms, vad_min_silence_msvad_merge_gap_ms, vad_target_min_s, vad_target_max_s, vad_hard_max_svad_overlap_s, vad_speech_pad_msvad_energy_gate, vad_energy_db, vad_energy_frame_ms, vad_energy_min_active_msvad_energy_merge_gap_ms, vad_energy_active_skipvad_uniform_chunk_s, vad_uniform_overlap_sValidation behavior:
response_format must be verbose_jsontimestamps must be word, segment, or nonechunk_mode must be memory or filediarization=true requires timestamps=wordforce_vad must be off or onResponse (top-level):
{
"text": "Hello world.",
"language": "en",
"duration": 12.34,
"words": [...],
"segments": [...],
"speakers": ["SPEAKER_00", "SPEAKER_01"]
}
If timestamps=word, words[] is populated and segments[] is derived from words.
If timestamps=segment, segments[] is populated and words[] is empty.
If timestamps=none, both arrays are empty and text is a plain string transcript.
Chunk-only response (chunk_only=true) returns VAD metadata only and skips ASR:
{
"ok": true,
"chunk_only": true,
"chunk_mode": "memory",
"duration": 123.45,
"sample_rate": 16000,
"vad_sample_rate": 16000,
"vad_params": { "...": "..." },
"chunks": [ { "...": "..." } ]
}
POST /v1/diarize (optional standalone service)Required form fields:
file (WAV/FLAC/MP3)Response is a list of speaker turns:
[
{ "start": 0.0, "end": 1.23, "speaker": "SPEAKER_00" }
]
Full request/response examples and schemas live in docs/api.md.
Use .env.example as the template. Common settings:
ASR_BACKENDASR_MODELASR_TRUST_REMOTE_CODEASR_RETURN_TIMESTAMPSASR_ATTENTION_IMPLEMENTATION (sdpa, eager, or optional flash_attention_2)HF_TOKEN (required for diarization downloads)DIARIZE_URL (external diarize service URL if used)DIARIZE_EMPTY_CACHE (1 to gc.collect() + reset CUDA stats after diarize)DIARIZE_TF32 (1 to enable TF32 in CUDA matmul/cudnn)VAD_DEVICE (cpu or cuda)VAD_SAMPLE_RATEVAD_THRESHOLDVAD_MIN_SPEECH_MSVAD_MIN_SILENCE_MSVAD_MERGE_GAP_MSVAD_TARGET_MIN_SVAD_TARGET_MAX_SVAD_HARD_MAX_SVAD_OVERLAP_SVAD_SPEECH_PAD_MSVAD_ENERGY_GATEVAD_ENERGY_DBVAD_ENERGY_FRAME_MSVAD_ENERGY_MIN_ACTIVE_MSVAD_ENERGY_MERGE_GAP_MSVAD_ENERGY_ACTIVE_SKIPVAD_UNIFORM_CHUNK_SVAD_UNIFORM_OVERLAP_SDISABLE_CUDA_GRAPHS (1 to disable NeMo RNNT CUDA graph decoding)See docs/api.md for detailed VAD/energy-gate behavior and defaults.
docs/api.md - endpoint, parameters, examples, response schemadocs/granite.md - IBM Granite Speech setup, CLI/API usage, and limitationsdocs/parakeet.md - Parakeet notes and container guidancedocs/pyannote.md - legacy pyannote notesdocs/sortformer.md - Sortformer diarization notesdocs/trace_audio.md - chunk tracing and diagnosticsdocs/tests.md - test plan + existing testsdocs/Parakeet_Progress.md - progress logdocs/sortformer_progress.md - diarization progress logdocs/VAD_energy_gate_issue.md - VAD energy gate investigationdocs/brief.md - project briefUnit/behavior tests live in test/. See docs/tests.md for what each test does and the planned test matrix.
api.py - ASR API servicediarize_api.py - diarization API wiringdiarize_align.py / merge_diarized.py - word/segment alignment helpersvad_chunk.py - VAD chunking logicchunk_transcribe.py / asr_merge.py - ASR chunking and merge utilitiesDockerfile, compose.yaml - container setupIgnored runtime artifacts (expected): .venv/, Output/, __pycache__/.
23 commits
Python
99.5%
ASR + diarization service built around Parakeet transcription and Sortformer diarization. The API exposes an OpenAI-style /v1/audio/transcriptions endpoint with optional diarization. Runtime-selectable ASR adapters include Parakeet, Whisper, faster-whisper, Cohere Transcribe, and IBM Granite Speech.
docker compose build api
docker compose up api
API guide: docs/api.md
One-off command-line transcription:
export LD_LIBRARY_PATH="$PWD/.venv/lib/python3.12/site-packages/nvidia/cu13/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
python transcribe_parakeet.py Examples/output_10s.mp3 \
--backend transformers-asr \
--model granite-speech-4.1-2b-nar \
--timestamps none
The historical transcribe_parakeet.py AUDIO command remains valid. Use
--backend and --model to select another adapter.
ASR API (main service, api.py):
POST /v1/audio/transcriptions (multipart/form-data)GET /healthGET /v1/modelsGET /v1/models/currentPOST /v1/models/currentStandalone diarization service (optional, diarize_api.py):
POST /v1/diarize (multipart/form-data)GET /healthPOST /v1/audio/transcriptionsRequired form fields:
file (WAV/FLAC/MP3)response_format=verbose_json (only supported value)Optional form fields:
diarization=true|false (default false)timestamps=word|segment|none (default word)language=en (default en)chunk_mode=memory|file (default memory)chunk_only=true|false (default false)trace_audio=true|false (default false)force_vad=off|on (default off)vad_sample_rate, vad_threshold, vad_min_speech_ms, vad_min_silence_msvad_merge_gap_ms, vad_target_min_s, vad_target_max_s, vad_hard_max_svad_overlap_s, vad_speech_pad_msvad_energy_gate, vad_energy_db, vad_energy_frame_ms, vad_energy_min_active_msvad_energy_merge_gap_ms, vad_energy_active_skipvad_uniform_chunk_s, vad_uniform_overlap_sValidation behavior:
response_format must be verbose_jsontimestamps must be word, segment, or nonechunk_mode must be memory or filediarization=true requires timestamps=wordforce_vad must be off or onResponse (top-level):
{
"text": "Hello world.",
"language": "en",
"duration": 12.34,
"words": [...],
"segments": [...],
"speakers": ["SPEAKER_00", "SPEAKER_01"]
}
If timestamps=word, words[] is populated and segments[] is derived from words.
If timestamps=segment, segments[] is populated and words[] is empty.
If timestamps=none, both arrays are empty and text is a plain string transcript.
Chunk-only response (chunk_only=true) returns VAD metadata only and skips ASR:
{
"ok": true,
"chunk_only": true,
"chunk_mode": "memory",
"duration": 123.45,
"sample_rate": 16000,
"vad_sample_rate": 16000,
"vad_params": { "...": "..." },
"chunks": [ { "...": "..." } ]
}
POST /v1/diarize (optional standalone service)Required form fields:
file (WAV/FLAC/MP3)Response is a list of speaker turns:
[
{ "start": 0.0, "end": 1.23, "speaker": "SPEAKER_00" }
]
Full request/response examples and schemas live in docs/api.md.
Use .env.example as the template. Common settings:
ASR_BACKENDASR_MODELASR_TRUST_REMOTE_CODEASR_RETURN_TIMESTAMPSASR_ATTENTION_IMPLEMENTATION (sdpa, eager, or optional flash_attention_2)HF_TOKEN (required for diarization downloads)DIARIZE_URL (external diarize service URL if used)DIARIZE_EMPTY_CACHE (1 to gc.collect() + reset CUDA stats after diarize)DIARIZE_TF32 (1 to enable TF32 in CUDA matmul/cudnn)VAD_DEVICE (cpu or cuda)VAD_SAMPLE_RATEVAD_THRESHOLDVAD_MIN_SPEECH_MSVAD_MIN_SILENCE_MSVAD_MERGE_GAP_MSVAD_TARGET_MIN_SVAD_TARGET_MAX_SVAD_HARD_MAX_SVAD_OVERLAP_SVAD_SPEECH_PAD_MSVAD_ENERGY_GATEVAD_ENERGY_DBVAD_ENERGY_FRAME_MSVAD_ENERGY_MIN_ACTIVE_MSVAD_ENERGY_MERGE_GAP_MSVAD_ENERGY_ACTIVE_SKIPVAD_UNIFORM_CHUNK_SVAD_UNIFORM_OVERLAP_SDISABLE_CUDA_GRAPHS (1 to disable NeMo RNNT CUDA graph decoding)See docs/api.md for detailed VAD/energy-gate behavior and defaults.
docs/api.md - endpoint, parameters, examples, response schemadocs/granite.md - IBM Granite Speech setup, CLI/API usage, and limitationsdocs/parakeet.md - Parakeet notes and container guidancedocs/pyannote.md - legacy pyannote notesdocs/sortformer.md - Sortformer diarization notesdocs/trace_audio.md - chunk tracing and diagnosticsdocs/tests.md - test plan + existing testsdocs/Parakeet_Progress.md - progress logdocs/sortformer_progress.md - diarization progress logdocs/VAD_energy_gate_issue.md - VAD energy gate investigationdocs/brief.md - project briefUnit/behavior tests live in test/. See docs/tests.md for what each test does and the planned test matrix.
api.py - ASR API servicediarize_api.py - diarization API wiringdiarize_align.py / merge_diarized.py - word/segment alignment helpersvad_chunk.py - VAD chunking logicchunk_transcribe.py / asr_merge.py - ASR chunking and merge utilitiesDockerfile, compose.yaml - container setupIgnored runtime artifacts (expected): .venv/, Output/, __pycache__/.
23 commits
Python
99.5%