Skip to main content

context-asr

Speech-to-text that notices what you're talking about and biases Whisper toward the right names.

The problem

Whisper is great at ordinary speech and bad at rare names. Say "Daenerys Targaryen" and you get "to Ennery's Targaryen"; say "Petyr Baelish" and you get "Potir Balish". Whisper can be steered with an initial_prompt, but you have to know the vocabulary before you transcribe.

context-asr works that vocabulary out as it goes. When the speaker mentions an entity like "Game of Thrones", it looks up related names (Westeros, Tyrion Lannister, Iron Throne, ...) and puts them in the prompt for the audio that follows. It also re-decodes the current chunk, since the topic and the hard name often come up in the same sentence:

first pass   Last night I finally finished watching Game of Thrones. Honestly, to Ennery's Targaryen and her dragon...
             └─ "Game of Thrones" → Wikipedia → Daenerys Targaryen, Westeros, Tyrion Lannister, ...
refined      Last night I finally finished watching Game of Thrones. Honestly, Daenerys Targaryen and her dragon...

When a name is misheard after its topic is live ("Brand Stark" while the glossary has "Bran Stark"), it's matched phonetically against the glossary. It never goes to Wikipedia, and the output is rewritten to the glossary spelling.

How it works

 audio ──► VAD chunks (≤15 s, cut at pauses)
               │
               ▼
        ┌─────────────┐   prompt: "Glossary: Westeros, Tyrion Lannister, ... <last 25 words>"
        │   Whisper   │◄──────────────────────────────────────────────┐
        └──────┬──────┘                                               │
               │ text                                                 │
               ▼                                                      │
      extract_entities()  ──►  sounds like a glossary term? ──► mention it, fix the spelling
               │                  else new entity?  ──►  Wikipedia / terms.json
               │                                        │             │
               │                                        ▼             │
               │                           ContextMemory (topics      │
               │                           +1 on mention, ×0.7 per ───┘
               │                           chunk, round-robin glossary)
               ▼
   learned something new? → re-decode this chunk once with the new prompt
Module What it does
entities.py extract_entities(text): runs of capitalized words (with of/the/and inside titles), or spaCy NER with use_spacy=True
context.py WikipediaSource, FileSource, ChainSource. All implement related_terms(entity) -> list[str]
fuzzy.py closest() / correct_text(): near-miss names via Metaphone + edit distance
memory.py ContextMemory: topic scores, decay, and the prompt builder (about 200 tokens max)
pipeline.py ContextualTranscriber: chunking, the transcribe/learn/refine loop
evaluate.py wer() and term_recall()
cli.py the context-asr command

Install

pip install context-asr            # or: pip install "context-asr[spacy]"

Requires Python 3.10+. The first run downloads the Whisper model from Hugging Face.

If context-asr isn't found after install (common with pip install --user on Windows), run python -m context_asr.cli instead.

Usage

# Transcribe (Wikipedia lookups on by default)
context-asr transcribe talk.mp3 --model small

# Offline, using your own vocabulary
context-asr transcribe talk.mp3 --no-wikipedia --terms-file examples/terms.json

# Always-on hints, plus a JSON report with every chunk's prompt
context-asr transcribe talk.mp3 --hint "Verstappen,Leclerc" --json report.json -v

# What would an entity add to the prompt?
context-asr lookup "Game of Thrones"

Other flags: --device cpu|cuda|auto, --language en, --spacy, --no-correct. --spacy also needs python -m spacy download en_core_web_sm. If you see cublas64_12.dll is not found, pass --device cpu or install the CUDA 12 libraries.

From Python:

from context_asr import ContextualTranscriber, ChainSource, FileSource, WikipediaSource

t = ContextualTranscriber("small", source=ChainSource(FileSource("terms.json"), WikipediaSource()))
result = t.transcribe("talk.mp3")
print(result.text)
for chunk in result.chunks:
    print(chunk["prompt"], "->", chunk["text"])

terms.json maps an entity to terms, with case-insensitive keys:

{"Formula 1": ["Max Verstappen", "Charles Leclerc", "DRS", "Monza"]}

Results: Earnings-21

Results are being finalized; the latest table is in the GitHub README. benchmarks/earnings21.py compares baseline, contextual and oracle prompting on the 11-call eval10 subset, scoring the dataset's own entity annotations.

Benchmark with your own clip

  1. Record or find a clip where the rare names matter and write the exact transcript to ref.txt.
  2. List the names you care about.
  3. Run:
context-asr transcribe clip.mp3 --compare --reference ref.txt     --key-terms "Daenerys Targaryen,Petyr Baelish,Westeros" --json report.json

This prints WER and term recall for both runs. The baseline uses the same chunks, but its prompt is only the transcript tail, so the difference comes from the lookup alone. Term recall is the main number: fixing five names barely moves WER, but those names are what people notice. Use --json and -v to see each chunk's prompt, the topics it added and the corrections it made. A short clip with a dozen names can only show the pipeline working; a difference of one name is noise.

Known limitations

  • Whisper's prompt is short. It holds about 224 tokens, and we cap ours at about 200 (estimated at 4 chars per token). A long topic list gets cut off, and two topics share the space round-robin.
  • The heuristic finds false entities. Any capitalized word at the start of a sentence that isn't in STOPWORDS counts as an entity ("Somehow we..."). "And" can join two names into one ("Westeros and Essos"). Use --spacy for real NER.
  • Wikipedia is noisy and slow. Each new entity costs one HTTP round trip, often 200–800 ms, cached afterwards in ~/.cache/context-asr/wikipedia-v2.json. A misheard name whose topic isn't live yet can still fuzzy-match an unrelated article.
  • Phonetic correction can be wrong. It only rewrites toward the leading words of glossary terms, but two real names that sound alike can still be confused. Turn it off with --no-correct.
  • Re-decoding costs time. A chunk that teaches us something is transcribed twice.
  • Network errors never break transcription. The lookup just returns nothing.

Roadmap

  • Streaming microphone input (the loop is already chunk-by-chunk)
  • An LLM post-correction pass that fixes names using the glossary (beyond the phonetic one)
  • Deepgram / AssemblyAI keyword boosting as alternative backends to the Whisper prompt

Development

git clone https://github.com/Om-anand-0/context-asr && cd context-asr
pip install -e ".[dev]"
pytest

The tests need no model and no network. Wikipedia responses are mocked. benchmarks/earnings21.py reproduces the results table (needs a GPU for reasonable run time).

License

MIT

Metadata

Release files for context-asr 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for context-asr 0.1.0
File Size Uploaded Provenance
context_asr-0.1.0.tar.gz 22.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for context-asr 0.1.0
File Interpreter ABI Platform
context_asr-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.2 kB

Release files / context_asr-0.1.0.tar.gz

Download URL context_asr-0.1.0.tar.gz
Size 22.5 kB
Tags Source
SHA-256 checksum
How to use checksums
afd3d556103d62fb6cc8bfb9436abaed678b72827e3ad4804496c774d55caf10
BLAKE2b-256 checksum
How to use checksums
e82dbf8b9bc43cd0654644fa01295858987a980ee9ced097c8486cb18900b400
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / context_asr-0.1.0-py3-none-any.whl

Download URL context_asr-0.1.0-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
67e58bd0776be951f823416c893659cf447349b4786e6bab9a161cf61d9358e9
BLAKE2b-256 checksum
How to use checksums
0f95ef7b35682389b8e613b7041edda7916925928c2c9e87388ca12afc54270e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for context-asr 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for context_asr-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page