Skip to content
← All Posts
Build notes

Parakeet learns medical vocabulary and one feature stays off

SolScribe's Parakeet engine now takes a custom vocabulary on each transcription. A speech detector for splitting long audio ships switched off.

SolScribe’s optional Parakeet engine now accepts a custom vocabulary on each transcription. On a public sample of 200 medical clips, missed medical terms fell from 64 to 55. The same week I tested a speech detector for choosing where to split long audio, and it ships switched off because the numbers did not earn it a place.

Where Parakeet fits

Parakeet is NVIDIA’s TDT 0.6b v3 model, served from Go through sherpa-onnx. In August’s benchmark on the Mac Studio it made roughly half the word errors of the WhisperX base model on medical speech, finished in about a third of the time and needed no Python at runtime.

It is opt-in for self-hosted installs. The engine is compiled in with a build tag and then enabled with an environment variable. A stock build behaves exactly as it did before.

Vocabulary, one request at a time

Hints now apply per transcription stream. Only requests that carry vocabulary switch to the beam-search decoder that uses them. Plain jobs get the output they always got: all 200 unbiased transcripts and their word timestamps matched the previous engine exactly.

Isolation took more work than the biasing. The pinned Go wrapper only offered a recognizer-wide hotword file, which would let one job’s terms bleed into another’s. SolScribe now calls the sherpa-onnx C API through a small adapter, so each stream carries its own phrases in memory. Two concurrent jobs with different term lists never see each other’s words.

Custom terms are never written to a model file or logged. Every character is checked against the tokenizer before it reaches the native encoder, whose error paths can otherwise print their input. Anything unsupported falls back to WhisperX with the original vocabulary intact.

The numbers

Same 200 clips, same model, same machine:

  • Medical-term misses: 64 to 55 of 267 occurrences
  • Word error rate: 13.42% to 13.37%
  • Speed: 17.8 to 16.1 seconds of audio per processing second

Overall accuracy moved by one word. Substitutions fell from 207 to 190, but deletions rose from 31 to 47 and nearly cancelled the gain. An earlier trial with a stronger bias produced 78 insertions against 27, which is why the shipped setting is the gentler one.

One caveat: the 54-term list was drawn from this corpus’s own reference transcripts. That shows the mechanism works but is not evidence of a general clinical accuracy gain, and real results will depend on real term lists.

The speech detector stays off

Parakeet splits long audio into 15-second chunks at the nearest quiet point. The obvious upgrade is a trained speech detector that finds genuine pauses, so I bundled Silero V5 and measured it against the existing planner on three inputs.

On the medical clips it changed almost nothing. On a 17-minute recording built from those clips it added seven errors, taking word error rate from 15.44% to 15.80%. On two ten-minute AMI meeting excerpts it was flat, 17.51% against 17.55%. It was slower on all three.

So PARAKEET_VAD_ENABLED defaults to false. Operators can turn it on.

Benchmark safeguards

Both comparisons are committed with the commands to rerun them. The benchmark runner now refuses empty references and duplicate IDs, and writes results only after every clip succeeds, so a partial run cannot pass for a complete one.

That caught a problem: the older AMI manifests had empty transcript text, which would have made any error rate against them meaningless. References are now rebuilt from the official AMI manual annotations, with the archive pinned by hash and the audio offset checked against the original recording.