Omi-Health/medical-STT-eval

Evaluation of STT-models on medical dialogues

50

stars

29

commits

Python

primary language

Apr 29, 2026

updated

README

Medical STT Benchmark

Evaluation framework for speech-to-text models on medical conversation data.

Full write-up & leaderboard: omi.health/research/stt-benchmark Built by Omi Health · All research · Omi Scribe

Leaderboard

Dataset: PriMock57 (55 files, ~80,500 words) | Models: 42 comparable single-stream models | Updated: 2026-04-29

Ranked by Canonical Medical WER (M-WER)

#ModelWERM-WERDrug M-WERAvg SpeedType
1Google Gemini 3 Pro Preview*8.35%1.37%1.1%64.5sAPI
2Google Gemini 2.5 Pro8.15%1.52%1.9%56.4sAPI
3VibeVoice-ASR 9B8.34%1.81%4.5%96.7sH100
4Google Gemini 3 Flash Preview11.33%2.03%3.0%51.5sAPI
5Soniox stt-async-v49.18%2.06%5.4%46.2sAPI
6ElevenLabs Scribe v29.72%2.54%2.8%43.5sAPI
7AssemblyAI Universal-3 Pro (medical-v1)9.55%2.83%4.9%37.3sAPI
8Qwen3 ASR 1.7B9.00%3.14%7.1%6.8sA10
9Deepgram Nova-3 Medical9.05%3.17%7.9%12.9sAPI
10Microsoft MAI-Transcribe-111.52%3.33%8.8%21.8sAPI
11ElevenLabs Scribe v110.87%3.59%6.0%36.3sAPI
12Google Gemini 2.5 Flash9.45%3.65%8.2%20.2sAPI
13OpenAI GPT-4o Mini (Dec 2025)11.18%3.68%8.8%40.4sAPI
14Parakeet TDT 1.1B9.03%3.68%13.7%12.3sT4
15Voxtral Mini Transcribe V111.85%4.03%9.7%22.4sAPI
16Voxtral Mini Transcribe V211.64%4.10%10.9%18.4sAPI
17Voxtral Mini 4B Realtime11.89%4.10%10.3%133.9sA10
18Groq Whisper Large v3 Turbo12.14%4.32%12.2%8.0sAPI
19Cohere Transcribe (Mar 2026)11.81%4.32%14.8%3.9sA10
20OpenAI Whisper-113.20%4.51%8.6%104.3sAPI
21NVIDIA Canary 1B Flash12.03%4.51%14.2%23.4sT4
22Groq Whisper Large v311.93%4.60%11.8%8.6sAPI
23Parakeet TDT 0.6B v210.75%4.60%15.7%5.4sApple Silicon
24MLX Whisper Large v3 Turbo11.65%4.70%12.2%12.9sApple Silicon
25WhisperKit Large v3 Turbo12.28%4.73%12.4%21.4sApple Silicon
26OpenAI GPT-4o Mini Transcribe13.60%4.86%9.7%23.2sAPI
27Qwen3 ASR 0.6B9.83%4.95%13.7%5.1sA10
28Kyutai STT 2.6B11.20%5.21%14.0%148.4sT4
29GLM-ASR-Nano-251210.84%5.75%16.1%87.7sT4
30Parakeet TDT 0.6B v39.35%5.90%20.6%6.3sApple Silicon
31Nemotron Speech Streaming 0.6B11.06%7.05%21.0%11.7sT4
32OpenAI GPT-4o Transcribe14.84%7.87%13.5%27.9sAPI
33Gemma 4 E4B-it^15.69%7.90%12.4%185.4sT4
34NVIDIA Canary-Qwen 2.5B12.94%8.25%21.0%105.4sT4
35NVIDIA Canary 1B v214.32%9.40%18.0%9.2sT4
36IBM Granite Speech 3.3-2B16.55%11.02%22.1%109.7sT4
37Apple SpeechAnalyzer12.36%11.97%25.3%6.0sApple Silicon
38Gemma 4 E2B-it^18.90%12.22%17.6%134.6sT4
39Azure Foundry Phi-431.13%14.19%16.1%212.8sAPI
40Kyutai STT 1B (Multilingual)27.28%19.90%27.9%79.5sT4
41Google MedASR52.54%26.16%35.6%3.9sApple Silicon
42Facebook MMS-1B-all38.70%52.92%71.0%28.6sT4

Ranked by Canonical M-WER v2. Avg Speed = wall-clock seconds per ~7.5 min file (lower is better; not normalized for hardware tier — H100 ≫ A10 ≫ T4). Type: API (cloud), T4/A10/H100 (NVIDIA GPU tier via NeMo/vLLM/transformers), Apple Silicon (MLX/Native on M-series). Additional metrics in results/metrics/{model}_medical_wer.json.

*Google Gemini 3 Pro Preview completed 54/55 comparable files.

^Gemma 4 models use 30s chunking (model max audio = 30s).

Chunking Strategy

Most cloud APIs and native long-form models are evaluated on full audio. Chunking is only used when a model has an audio-length, token, memory, or decoder-behavior constraint.

The shared helpers live in transcribe/chunking_utils.py:

  • Post-hoc overlap + LCS merge: Canary-Qwen, Canary Flash, Granite, and Azure Phi-4 use overlapping chunks and text-level LCS merging.
  • CTC/HF chunking: MMS uses HF pipeline chunking with character timestamps. MedASR defaults to a stronger KenLM-backed short-chunk mode (8s chunks, 1s overlap) while preserving the old HF 20s/2s baseline via --decode_mode hf_pipeline.
  • Simple concat: Gemma 4 keeps non-overlapping 30s chunks because overlap/context merging tested worse for that model.
  • No chunking: Qwen3-ASR, cloud batch APIs, and native long-form paths keep full-audio decoding when the model supports it.

MedASR chunk/overlap experiments can be run with:

python scripts/run_medasr_chunk_ablation.py --audio_dir data/raw_audio --include_hf_baseline --evaluate

Multi-speaker models (separate — different metric)

These models output per-speaker transcripts with diarization, evaluated with cpWER (concatenated permutation WER) instead of standard WER. Not directly comparable to the single-stream leaderboard above.

ModelcpWERDoctor WERPatient WERGood diar (<30%)Notes
Multitalker Parakeet 0.6B34.17%13-20%19-32%30/55 (55%)Joint ASR+diar, streaming, NeMo

The model outputs SegLST segments (speaker-tagged words with timestamps) via SpeakerTaggedASR. On well-diarized files (30/55), per-speaker WER is competitive with single-speaker Parakeet models. On 12/55 files diarization fails — the model assigns text to the wrong speaker or merges both into one stream. This is an early streaming model (v1) optimized for real-time display.

Per-speaker references: PriMock57 TextGrid files (doctor + patient separately with timestamps).

Metrics explained

MetricWhat
WERWord Error Rate — overall transcription accuracy (lower = better)
M-WERCanonical Medical WER v2 — errors on medical terms only: drugs, conditions, symptoms, anatomy, clinical (lower = better)
Drug M-WERCanonical M-WER for drug names specifically — highest clinical risk category (lower = better)
cpWERConcatenated permutation WER — for multi-speaker models with diarization

Additional metrics available per model in results/metrics/{model}_medical_wer.json: M-CER (character-level error on medical substitutions), Token Recall (occurrence-weighted), Entity Recall (binary), per-category M-WER breakdown (drugs, conditions, symptoms, anatomy, clinical).

Canonical M-WER v2

Medical scoring uses the same base text normalization as standard WER, then applies a narrow clinical canonicalization pass before medical-term alignment:

  • Corrects known reference-side PriMock57 spelling issues: paracetemolparacetamol, thyrocsinthyroxine, flemphlegm.
  • Collapses accepted word-boundary variants such as water works/waterworks, hay fever/hayfever, and straight away/straightaway.
  • Normalizes low-risk morphology and symptom wording variants such as tests/test, headaches/headache, itchy/itching, and tummy/stomach.
  • Keeps clinically meaningful or unsafe substitutions penalized, including hyperthyroidism/hypothyroidism, modulite/modulate, clenil misspellings, ventolin/ventilin, and implanon/implant.

This canonicalization is used only for medical metrics. Overall WER remains the standard normalized WER.

Quick Start

# Install Git LFS (required for audio files)
git lfs install

# Clone and install
git clone https://github.com/Omi-Health/medical-STT-eval.git
cd medical-STT-eval
pip install -r requirements.txt

# Add API keys
cp .env.example .env

# Run transcription (outputs to results/transcripts/)
python transcribe/groq_whisper_transcribe.py --audio_dir data/raw_audio

# Generate metrics
python evaluate/metrics_generator.py --model_name groq-whisper-large-v3
python evaluate/medical_wer.py --model groq-whisper-large-v3 --output results/metrics/groq-whisper-large-v3_medical_wer.json

# Update leaderboard
python evaluate/comparison_generator.py

Note: Existing per-model transcripts are tracked in results/transcripts/ for reproducibility. To re-evaluate or add a new model, run the relevant transcription script then metrics_generator.py and medical_wer.py.

Project Structure

medical-stt-benchmark/
├── data/
│   ├── raw_audio/              # 57 WAV files (Git LFS)
│   └── cleaned_transcripts/    # 57 reference transcripts
├── transcribe/                 # Model-specific transcription scripts + base class
│   └── base_transcriber.py     # Shared base (loads .env)
├── evaluate/                   # Evaluation scripts
│   ├── text_normalizer.py     # Custom WER normalizer (see Metrics below)
│   ├── clinical_canonicalizer.py # Canonical M-WER v2 mappings
│   ├── wer_calculator.py
│   ├── metrics_generator.py
│   ├── medical_wer.py
│   └── comparison_generator.py
└── results/
    ├── metrics/                # WER, medical WER, and speed JSON
    ├── comparisons/            # leaderboard.json, per_file_results.json
    └── transcripts/            # tracked model transcripts for reproducibility

Public vs Private Contents

The public repository contains reproducible benchmark code, reference transcripts, tracked model transcripts, metrics, and leaderboard outputs.

A local private_analysis/ directory may exist in development checkouts. It is intentionally git-ignored and is not part of the public benchmark. Public documentation and reproducible workflows should not depend on it.

Supported Platforms

TypeModelsSetup
APIOpenAI, Groq, ElevenLabs, Google, Mistral, Deepgram, AssemblyAI, Soniox, Microsoft (MAI-Transcribe via Azure Speech)Add keys to .env
MLXWhisper, Parakeet, WhisperKitApple Silicon required
GPUNVIDIA Canary, Kyutai STT, VibeVoice, Nemotron, Voxtral RealtimeCUDA + NeMo/vLLM/transformers
NativeApple SpeechAnalyzermacOS 26+

Adding a New Model

  1. Create transcribe/your_model_transcribe.py inheriting from BaseTranscriber
  2. Implement transcribe_file() returning transcript text
  3. Run on dataset: python transcribe/your_model_transcribe.py --audio_dir data/raw_audio
  4. Generate metrics: python evaluate/metrics_generator.py --model_name your-model
  5. Generate medical metrics: python evaluate/medical_wer.py --model your-model --output results/metrics/your-model_medical_wer.json
  6. Update comparisons: python evaluate/comparison_generator.py

Dataset

PriMock57: 57 doctor-patient consultations, 81,236 words of British English medical dialogue. 55 files used for evaluation (2 excluded due to processing issues).

Audio files are tracked with Git LFS. Reference transcripts derived from PriMock57 under CC BY 4.0.

Citation:

@inproceedings{korfiatis2022primock57,
  title={PriMock57: A Dataset Of Primary Care Mock Consultations},
  author={Papadopoulos Korfiatis, Alex and Moramarco, Francesco and Sarac, Radmila and Savkov, Aleksandar},
  booktitle={Proceedings of the 60th Annual Meeting of the ACL},
  year={2022}
}

Metrics

  • WER: Word Error Rate (lower is better)
  • M-WER: Canonical Medical WER v2 on medical terms only (lower is better)
  • Drug M-WER: Canonical M-WER v2 on drug terms only (lower is better)
  • Accuracy: 1 - WER
  • Speed: Average seconds per ~7.5 min file

Text Normalization

WER is calculated using a custom normalizer (evaluate/text_normalizer.py) based on Whisper's EnglishTextNormalizer with two fixes:

  1. "oh" bug fix: Whisper treats "oh" as the digit zero (self.zeros = {"o", "oh", "zero"}). In medical conversations "oh" is always an interjection. Our normalizer removes "oh" from this set.
  2. Word equivalence mappings: ok/okay/k, yeah/yep/yes, mum/mom, alright/all right, kinda/kind of — variant spellings that Whisper does not normalize to the same form.

This reduced WER by ~2-3% across all models compared to stock Whisper normalization. No runtime dependency on the openai-whisper package.

Citation

If you use this benchmark, please cite:

APA — Omi Health. (2025). Benchmarking Speech-to-Text Models for Long-Form Medical Dialogue. https://omi.health/research/stt-benchmark

BibTeX

@misc{omi_stt_benchmark_2025,
  title   = {Benchmarking Speech-to-Text Models for Long-Form Medical Dialogue},
  author  = {{Omi Health}},
  year    = {2025},
  url     = {https://omi.health/research/stt-benchmark},
  note    = {Medical Word Error Rate (M-WER) leaderboard, 42 models}
}

License

MIT License. Dataset under CC BY 4.0.


Built by Omi Health — the private AI stack for healthcare.

Contributors

farhang87

29 commits

Omi-Health/medical-STT-eval

Evaluation of STT-models on medical dialogues

50

stars

29

commits

Python

primary language

Apr 29, 2026

updated

README

Medical STT Benchmark

Evaluation framework for speech-to-text models on medical conversation data.

Full write-up & leaderboard: omi.health/research/stt-benchmark Built by Omi Health · All research · Omi Scribe

Leaderboard

Dataset: PriMock57 (55 files, ~80,500 words) | Models: 42 comparable single-stream models | Updated: 2026-04-29

Ranked by Canonical Medical WER (M-WER)

#ModelWERM-WERDrug M-WERAvg SpeedType
1Google Gemini 3 Pro Preview*8.35%1.37%1.1%64.5sAPI
2Google Gemini 2.5 Pro8.15%1.52%1.9%56.4sAPI
3VibeVoice-ASR 9B8.34%1.81%4.5%96.7sH100
4Google Gemini 3 Flash Preview11.33%2.03%3.0%51.5sAPI
5Soniox stt-async-v49.18%2.06%5.4%46.2sAPI
6ElevenLabs Scribe v29.72%2.54%2.8%43.5sAPI
7AssemblyAI Universal-3 Pro (medical-v1)9.55%2.83%4.9%37.3sAPI
8Qwen3 ASR 1.7B9.00%3.14%7.1%6.8sA10
9Deepgram Nova-3 Medical9.05%3.17%7.9%12.9sAPI
10Microsoft MAI-Transcribe-111.52%3.33%8.8%21.8sAPI
11ElevenLabs Scribe v110.87%3.59%6.0%36.3sAPI
12Google Gemini 2.5 Flash9.45%3.65%8.2%20.2sAPI
13OpenAI GPT-4o Mini (Dec 2025)11.18%3.68%8.8%40.4sAPI
14Parakeet TDT 1.1B9.03%3.68%13.7%12.3sT4
15Voxtral Mini Transcribe V111.85%4.03%9.7%22.4sAPI
16Voxtral Mini Transcribe V211.64%4.10%10.9%18.4sAPI
17Voxtral Mini 4B Realtime11.89%4.10%10.3%133.9sA10
18Groq Whisper Large v3 Turbo12.14%4.32%12.2%8.0sAPI
19Cohere Transcribe (Mar 2026)11.81%4.32%14.8%3.9sA10
20OpenAI Whisper-113.20%4.51%8.6%104.3sAPI
21NVIDIA Canary 1B Flash12.03%4.51%14.2%23.4sT4
22Groq Whisper Large v311.93%4.60%11.8%8.6sAPI
23Parakeet TDT 0.6B v210.75%4.60%15.7%5.4sApple Silicon
24MLX Whisper Large v3 Turbo11.65%4.70%12.2%12.9sApple Silicon
25WhisperKit Large v3 Turbo12.28%4.73%12.4%21.4sApple Silicon
26OpenAI GPT-4o Mini Transcribe13.60%4.86%9.7%23.2sAPI
27Qwen3 ASR 0.6B9.83%4.95%13.7%5.1sA10
28Kyutai STT 2.6B11.20%5.21%14.0%148.4sT4
29GLM-ASR-Nano-251210.84%5.75%16.1%87.7sT4
30Parakeet TDT 0.6B v39.35%5.90%20.6%6.3sApple Silicon
31Nemotron Speech Streaming 0.6B11.06%7.05%21.0%11.7sT4
32OpenAI GPT-4o Transcribe14.84%7.87%13.5%27.9sAPI
33Gemma 4 E4B-it^15.69%7.90%12.4%185.4sT4
34NVIDIA Canary-Qwen 2.5B12.94%8.25%21.0%105.4sT4
35NVIDIA Canary 1B v214.32%9.40%18.0%9.2sT4
36IBM Granite Speech 3.3-2B16.55%11.02%22.1%109.7sT4
37Apple SpeechAnalyzer12.36%11.97%25.3%6.0sApple Silicon
38Gemma 4 E2B-it^18.90%12.22%17.6%134.6sT4
39Azure Foundry Phi-431.13%14.19%16.1%212.8sAPI
40Kyutai STT 1B (Multilingual)27.28%19.90%27.9%79.5sT4
41Google MedASR52.54%26.16%35.6%3.9sApple Silicon
42Facebook MMS-1B-all38.70%52.92%71.0%28.6sT4

Ranked by Canonical M-WER v2. Avg Speed = wall-clock seconds per ~7.5 min file (lower is better; not normalized for hardware tier — H100 ≫ A10 ≫ T4). Type: API (cloud), T4/A10/H100 (NVIDIA GPU tier via NeMo/vLLM/transformers), Apple Silicon (MLX/Native on M-series). Additional metrics in results/metrics/{model}_medical_wer.json.

*Google Gemini 3 Pro Preview completed 54/55 comparable files.

^Gemma 4 models use 30s chunking (model max audio = 30s).

Chunking Strategy

Most cloud APIs and native long-form models are evaluated on full audio. Chunking is only used when a model has an audio-length, token, memory, or decoder-behavior constraint.

The shared helpers live in transcribe/chunking_utils.py:

  • Post-hoc overlap + LCS merge: Canary-Qwen, Canary Flash, Granite, and Azure Phi-4 use overlapping chunks and text-level LCS merging.
  • CTC/HF chunking: MMS uses HF pipeline chunking with character timestamps. MedASR defaults to a stronger KenLM-backed short-chunk mode (8s chunks, 1s overlap) while preserving the old HF 20s/2s baseline via --decode_mode hf_pipeline.
  • Simple concat: Gemma 4 keeps non-overlapping 30s chunks because overlap/context merging tested worse for that model.
  • No chunking: Qwen3-ASR, cloud batch APIs, and native long-form paths keep full-audio decoding when the model supports it.

MedASR chunk/overlap experiments can be run with:

python scripts/run_medasr_chunk_ablation.py --audio_dir data/raw_audio --include_hf_baseline --evaluate

Multi-speaker models (separate — different metric)

These models output per-speaker transcripts with diarization, evaluated with cpWER (concatenated permutation WER) instead of standard WER. Not directly comparable to the single-stream leaderboard above.

ModelcpWERDoctor WERPatient WERGood diar (<30%)Notes
Multitalker Parakeet 0.6B34.17%13-20%19-32%30/55 (55%)Joint ASR+diar, streaming, NeMo

The model outputs SegLST segments (speaker-tagged words with timestamps) via SpeakerTaggedASR. On well-diarized files (30/55), per-speaker WER is competitive with single-speaker Parakeet models. On 12/55 files diarization fails — the model assigns text to the wrong speaker or merges both into one stream. This is an early streaming model (v1) optimized for real-time display.

Per-speaker references: PriMock57 TextGrid files (doctor + patient separately with timestamps).

Metrics explained

MetricWhat
WERWord Error Rate — overall transcription accuracy (lower = better)
M-WERCanonical Medical WER v2 — errors on medical terms only: drugs, conditions, symptoms, anatomy, clinical (lower = better)
Drug M-WERCanonical M-WER for drug names specifically — highest clinical risk category (lower = better)
cpWERConcatenated permutation WER — for multi-speaker models with diarization

Additional metrics available per model in results/metrics/{model}_medical_wer.json: M-CER (character-level error on medical substitutions), Token Recall (occurrence-weighted), Entity Recall (binary), per-category M-WER breakdown (drugs, conditions, symptoms, anatomy, clinical).

Canonical M-WER v2

Medical scoring uses the same base text normalization as standard WER, then applies a narrow clinical canonicalization pass before medical-term alignment:

  • Corrects known reference-side PriMock57 spelling issues: paracetemolparacetamol, thyrocsinthyroxine, flemphlegm.
  • Collapses accepted word-boundary variants such as water works/waterworks, hay fever/hayfever, and straight away/straightaway.
  • Normalizes low-risk morphology and symptom wording variants such as tests/test, headaches/headache, itchy/itching, and tummy/stomach.
  • Keeps clinically meaningful or unsafe substitutions penalized, including hyperthyroidism/hypothyroidism, modulite/modulate, clenil misspellings, ventolin/ventilin, and implanon/implant.

This canonicalization is used only for medical metrics. Overall WER remains the standard normalized WER.

Quick Start

# Install Git LFS (required for audio files)
git lfs install

# Clone and install
git clone https://github.com/Omi-Health/medical-STT-eval.git
cd medical-STT-eval
pip install -r requirements.txt

# Add API keys
cp .env.example .env

# Run transcription (outputs to results/transcripts/)
python transcribe/groq_whisper_transcribe.py --audio_dir data/raw_audio

# Generate metrics
python evaluate/metrics_generator.py --model_name groq-whisper-large-v3
python evaluate/medical_wer.py --model groq-whisper-large-v3 --output results/metrics/groq-whisper-large-v3_medical_wer.json

# Update leaderboard
python evaluate/comparison_generator.py

Note: Existing per-model transcripts are tracked in results/transcripts/ for reproducibility. To re-evaluate or add a new model, run the relevant transcription script then metrics_generator.py and medical_wer.py.

Project Structure

medical-stt-benchmark/
├── data/
│   ├── raw_audio/              # 57 WAV files (Git LFS)
│   └── cleaned_transcripts/    # 57 reference transcripts
├── transcribe/                 # Model-specific transcription scripts + base class
│   └── base_transcriber.py     # Shared base (loads .env)
├── evaluate/                   # Evaluation scripts
│   ├── text_normalizer.py     # Custom WER normalizer (see Metrics below)
│   ├── clinical_canonicalizer.py # Canonical M-WER v2 mappings
│   ├── wer_calculator.py
│   ├── metrics_generator.py
│   ├── medical_wer.py
│   └── comparison_generator.py
└── results/
    ├── metrics/                # WER, medical WER, and speed JSON
    ├── comparisons/            # leaderboard.json, per_file_results.json
    └── transcripts/            # tracked model transcripts for reproducibility

Public vs Private Contents

The public repository contains reproducible benchmark code, reference transcripts, tracked model transcripts, metrics, and leaderboard outputs.

A local private_analysis/ directory may exist in development checkouts. It is intentionally git-ignored and is not part of the public benchmark. Public documentation and reproducible workflows should not depend on it.

Supported Platforms

TypeModelsSetup
APIOpenAI, Groq, ElevenLabs, Google, Mistral, Deepgram, AssemblyAI, Soniox, Microsoft (MAI-Transcribe via Azure Speech)Add keys to .env
MLXWhisper, Parakeet, WhisperKitApple Silicon required
GPUNVIDIA Canary, Kyutai STT, VibeVoice, Nemotron, Voxtral RealtimeCUDA + NeMo/vLLM/transformers
NativeApple SpeechAnalyzermacOS 26+

Adding a New Model

  1. Create transcribe/your_model_transcribe.py inheriting from BaseTranscriber
  2. Implement transcribe_file() returning transcript text
  3. Run on dataset: python transcribe/your_model_transcribe.py --audio_dir data/raw_audio
  4. Generate metrics: python evaluate/metrics_generator.py --model_name your-model
  5. Generate medical metrics: python evaluate/medical_wer.py --model your-model --output results/metrics/your-model_medical_wer.json
  6. Update comparisons: python evaluate/comparison_generator.py

Dataset

PriMock57: 57 doctor-patient consultations, 81,236 words of British English medical dialogue. 55 files used for evaluation (2 excluded due to processing issues).

Audio files are tracked with Git LFS. Reference transcripts derived from PriMock57 under CC BY 4.0.

Citation:

@inproceedings{korfiatis2022primock57,
  title={PriMock57: A Dataset Of Primary Care Mock Consultations},
  author={Papadopoulos Korfiatis, Alex and Moramarco, Francesco and Sarac, Radmila and Savkov, Aleksandar},
  booktitle={Proceedings of the 60th Annual Meeting of the ACL},
  year={2022}
}

Metrics

  • WER: Word Error Rate (lower is better)
  • M-WER: Canonical Medical WER v2 on medical terms only (lower is better)
  • Drug M-WER: Canonical M-WER v2 on drug terms only (lower is better)
  • Accuracy: 1 - WER
  • Speed: Average seconds per ~7.5 min file

Text Normalization

WER is calculated using a custom normalizer (evaluate/text_normalizer.py) based on Whisper's EnglishTextNormalizer with two fixes:

  1. "oh" bug fix: Whisper treats "oh" as the digit zero (self.zeros = {"o", "oh", "zero"}). In medical conversations "oh" is always an interjection. Our normalizer removes "oh" from this set.
  2. Word equivalence mappings: ok/okay/k, yeah/yep/yes, mum/mom, alright/all right, kinda/kind of — variant spellings that Whisper does not normalize to the same form.

This reduced WER by ~2-3% across all models compared to stock Whisper normalization. No runtime dependency on the openai-whisper package.

Citation

If you use this benchmark, please cite:

APA — Omi Health. (2025). Benchmarking Speech-to-Text Models for Long-Form Medical Dialogue. https://omi.health/research/stt-benchmark

BibTeX

@misc{omi_stt_benchmark_2025,
  title   = {Benchmarking Speech-to-Text Models for Long-Form Medical Dialogue},
  author  = {{Omi Health}},
  year    = {2025},
  url     = {https://omi.health/research/stt-benchmark},
  note    = {Medical Word Error Rate (M-WER) leaderboard, 42 models}
}

License

MIT License. Dataset under CC BY 4.0.


Built by Omi Health — the private AI stack for healthcare.

Contributors

farhang87

29 commits

Languages

Python

100.0%