Workflow leaderboard / Research / Transcription

Transcribe and diarize research interviews

研究访谈转写与说话人分离

Research / 科研 Transcription / 转写 flagship verified 2026-08-02

Turn recorded interviews into timestamped, speaker-labelled transcripts while preserving a reproducible path from audio to JSON and subtitles.

Variants

Free & local / 免费本地 ~35 min setup

Recommended: Linux or Windows with an NVIDIA GPU and at least 8 GB VRAM. CPU and Apple Silicon paths work but are slower. Keep at least 20 GB free for environments and model caches.

ComponentRolePriceLink
WhisperX 3.8.6 batched transcription, word alignment and speaker assignment Free / 免费BSD-2-Clause software; model download and local compute costs are separatechecked 2026-08-02 https://github.com/m-bain/whisperX/releases/tag/v3.8.6
pyannote.audio 4.0.7 with speaker-diarization-community-1 local speaker diarization Free / 免费MIT software; gated Hugging Face model requires accepting its user agreement and a free tokenchecked 2026-08-02 https://github.com/pyannote/pyannote-audio/releases/tag/4.0.7
FFmpeg 8.1.2 audio normalization to mono 16 kHz WAV Free / 免费open-source command-line dependencychecked 2026-08-02 https://ffmpeg.org/download.html

Create an isolated environment and run diarization

uv venv --python 3.12 .venv
. .venv/bin/activate
uv pip install 'whisperx==3.8.6'
ffmpeg -i interview.m4a -ac 1 -ar 16000 interview.wav
export HF_TOKEN='paste_your_read_token_here'
whisperx interview.wav --model large-v3 --device cuda --compute_type float16 --batch_size 8 --diarize --hf_token "$HF_TOKEN" --min_speakers 2 --max_speakers 6 --output_dir transcript --output_format all

Transcript quality-control prompt

You are checking a research-interview transcript against its source notes. Preserve every speaker label and timestamp. Return three sections: (1) probable transcription errors with timestamp, original phrase, proposed correction, and reason; (2) uncertain speaker changes; (3) domain terms that need human confirmation. Do not silently rewrite the transcript. If evidence is insufficient, write 'needs audio review'.

Known pitfalls

  • WhisperX 3.8.6 requires Python 3.10 through 3.13 and pins the PyTorch 2.8 family.
  • The pyannote community pipeline is gated. Accept the model agreement before the first run.
  • Speaker labels are anonymous clusters, not verified identities. Map SPEAKER_00 to a person only after listening.
  • Overlapping speech and very short turns can increase diarization error; always spot-check boundaries.
Low budget / 低预算 ~15 min setup

Any machine able to upload audio and run curl. Audio leaves the device and is processed by Deepgram.

ComponentRolePriceLink
Deepgram Nova-3 Monolingual Nova-3 pay-as-you-go pre-recorded speech recognition Usage-based / 按用量计费$0.0077 per minute for pre-recorded monolingual Nova-3 at the pay-as-you-go ratechecked 2026-08-02 https://deepgram.com/pricing
Deepgram Speaker Diarization API add-on current 2026-08-02 speaker labels in transcript results Usage-based / 按用量计费$0.0020 per minute pay-as-you-go add-onchecked 2026-08-02 https://deepgram.com/pricing

Submit local audio to Deepgram

export DEEPGRAM_API_KEY='paste_key_here'
curl --fail-with-body --request POST \
  --url 'https://api.deepgram.com/v1/listen?model=nova-3&smart_format=true&diarize=true&utterances=true' \
  --header "Authorization: Token $DEEPGRAM_API_KEY" \
  --header 'Content-Type: audio/wav' \
  --data-binary @interview.wav > deepgram.json
jq -r '.results.utterances[] | "[\(.start)-\(.end)] SPEAKER_\(.speaker): \(.transcript)"' deepgram.json > transcript.txt

Known pitfalls

  • The quoted rate is per audio minute, not a fixed monthly bill.
  • Diarization is an add-on charge in addition to transcription.
  • Do not upload interviews without consent and an approved data-processing basis.
  • Check the returned metadata for request errors before treating an empty transcript as valid.
Cloud premium / 云端高配 ~15 min setup

Any machine with HTTPS access. Audio is uploaded to AssemblyAI; confirm institutional privacy requirements first.

ComponentRolePriceLink
AssemblyAI Universal-3.5 Pro Universal-3.5 Pro async API high-accuracy multilingual transcription Usage-based / 按用量计费$0.21 per audio hour pay as you gochecked 2026-08-02 https://www.assemblyai.com/pricing
AssemblyAI Speaker Diarization speaker_labels API option utterance-level speaker separation Usage-based / 按用量计费$0.02 per audio hour add-on for pre-recorded transcriptionchecked 2026-08-02 https://www.assemblyai.com/pricing

Upload, submit and poll an AssemblyAI transcript

export ASSEMBLYAI_API_KEY='paste_key_here'
AUDIO_URL=$(curl --fail-with-body -sS -X POST 'https://api.assemblyai.com/v2/upload' -H "Authorization: $ASSEMBLYAI_API_KEY" --data-binary @interview.wav | jq -r '.upload_url')
TRANSCRIPT_ID=$(jq -n --arg audio_url "$AUDIO_URL" '{audio_url:$audio_url,speech_models:["universal-3-pro"],speaker_labels:true,format_text:true}' | curl --fail-with-body -sS -X POST 'https://api.assemblyai.com/v2/transcript' -H "Authorization: $ASSEMBLYAI_API_KEY" -H 'Content-Type: application/json' -d @- | jq -r '.id')
while true; do curl -sS -H "Authorization: $ASSEMBLYAI_API_KEY" "https://api.assemblyai.com/v2/transcript/$TRANSCRIPT_ID" > assemblyai.json; STATUS=$(jq -r '.status' assemblyai.json); [ "$STATUS" = completed ] && break; [ "$STATUS" = error ] && { jq -r '.error' assemblyai.json >&2; exit 1; }; sleep 5; done
jq -r '.utterances[] | "[\(.start/1000)-\(.end/1000)] SPEAKER_\(.speaker): \(.text)"' assemblyai.json > transcript.txt

Known pitfalls

  • API model identifiers can differ from marketing labels; confirm the current request schema before production automation.
  • The monthly cost is usage-dependent, so usd_month is intentionally null.
  • Named speaker identification is a separate problem from diarization.
  • Retain the raw JSON because flattened text loses word confidence and timing detail.

Evidence