Skip to main content

🔥 SemanticWER

Evaluation framework for speech-to-LLM systems.

PyPI version Python 3.9+ License: MIT


Classic Word Error Rate (WER) measures token accuracy. But modern pipelines look like this:

Speech → ASR → LLM → Task (QA, summarization, agents, RAG)

A 20% WER transcript can preserve meaning — or completely break downstream reasoning. WER cannot tell the difference.

SemanticWER fixes this with a four-component composite score:

SemanticWER = w₁·L + w₂·E + w₃·S + w₄·T
Component What it measures
L — Lexical Standard WER + CER (NIST-compatible)
E — Entity Named entity preservation (PERSON, ORG, DATE, …)
S — Semantic Embedding cosine similarity (SBERT)
T — Task Downstream task success delta

Lower score = better transcript quality.


Installation

# Minimal (WER/CER + regex NER + Jaccard semantic fallback)
pip install semanticwer

# Recommended (full features)
pip install "semanticwer[full]"
python -m spacy download en_core_web_sm

Quick Start

from semanticwer import SemanticWER

metric = SemanticWER()  # defaults: weights=(0.3, 0.2, 0.3, 0.2)

result = metric(
    reference="The patient was prescribed 50mg of metformin twice daily",
    hypothesis="The patient was prescribed 15mg of metformin twice daily",
)

print(result.summary())
# ====================================================
#   SemanticWER Result
# ====================================================
#   Composite Score  : 0.3241  (lower = better)
# ----------------------------------------------------
#   [L] Lexical      : WER=0.1429  CER=0.0541  (w=0.30)
#   [E] Entity       : F1=0.8000  Recall=0.6667  (w=0.20)
#   [S] Semantic     : Sim=0.8923  (w=0.30)
#   [T] Task         : N/A  (w=0.20)
# ====================================================

print(result.wer)           # 0.1429
print(result.semantic_sim)  # 0.8923
print(result.entity_f1)     # 0.8000
print(result.score)         # 0.3241

torchmetrics-Style API

metric = SemanticWER(weights=(0.3, 0.2, 0.3, 0.2))

# Accumulate samples
for ref, hyp in dataset:
    metric.update(ref, hyp)

# Compute over full corpus
result = metric.aggregate()
print(f"Corpus SemanticWER: {result.score:.4f}")

HuggingFace evaluate-Style API

result = metric.compute(
    predictions=hypotheses,
    references=references,
)

Task Utility: The Game-Changer

Connect SemanticWER to your actual downstream task:

Built-in: ROUGE

from semanticwer import SemanticWER
from semanticwer.modules.task import TaskModule

metric = SemanticWER(
    weights=(0.25, 0.25, 0.25, 0.25),
    task_fn=TaskModule.rouge_adapter("rougeL"),
)
result = metric(ref, hyp)
print(result.task_score)  # 0.0–1.0

Built-in: Token F1 (SQuAD-style QA)

metric = SemanticWER(
    task_fn=TaskModule.f1_token_adapter(),
    weights=(0.25, 0.25, 0.25, 0.25),
)

Custom: Any callable

def my_qa_eval(reference: str, hypothesis: str) -> float:
    """Return 1.0 if hypothesis preserves the answer to our question."""
    ref_answer = qa_model(question="Who was mentioned?", context=reference)
    hyp_answer = qa_model(question="Who was mentioned?", context=hypothesis)
    return 1.0 if ref_answer == hyp_answer else 0.0

metric = SemanticWER(
    task_fn=my_qa_eval,
    weights=(0.2, 0.2, 0.3, 0.3),
)

Custom: LLM-as-judge

import anthropic

client = anthropic.Anthropic()

def llm_judge(reference: str, hypothesis: str) -> float:
    response = client.messages.create(
        model="claude-3-5-haiku-20241022",
        max_tokens=10,
        messages=[{
            "role": "user",
            "content": (
                f"Score semantic equivalence 0.0–1.0 (1.0 = identical meaning).\n"
                f"REF: {reference}\nHYP: {hypothesis}\n"
                f"Respond with only a float."
            ),
        }],
    )
    return float(response.content[0].text.strip())

metric = SemanticWER(
    task_fn=TaskModule.llm_judge_adapter(llm_judge),
    weights=(0.2, 0.2, 0.3, 0.3),
)

NER Backend Selection

# spaCy (default, best accuracy for English)
metric = SemanticWER(ner_backend="spacy")

# HuggingFace transformers pipeline
metric = SemanticWER(ner_backend="hf")

# Lightweight regex (no extra deps)
metric = SemanticWER(ner_backend="regex")

# Disable entity scoring
metric = SemanticWER(ner_backend="none")

CLI

# Single pair
semanticwer --ref "John Smith called at 3pm" --hyp "Tom Jones called at 9am"

# Files (one sentence per line)
semanticwer --ref ref.txt --hyp hyp.txt

# With ROUGE task scoring
semanticwer --ref ref.txt --hyp hyp.txt --task rouge

# JSON output (for pipelines)
semanticwer --ref ref.txt --hyp hyp.txt --output json

# Custom weights
semanticwer --ref ref.txt --hyp hyp.txt --weights 0.4 0.2 0.3 0.1

# CSV output
semanticwer --ref ref.txt --hyp hyp.txt --output csv

Result Object

result = metric(ref, hyp)

result.score            # Composite SemanticWER [0, 1]
result.wer              # Classic WER
result.cer              # Character Error Rate
result.entity_f1        # Entity F1 score
result.entity_recall    # Entity recall
result.semantic_sim     # Cosine similarity [0, 1]
result.task_score       # Task utility score (or None)

result.to_dict()        # Full breakdown as dict
result.to_json()        # Full breakdown as JSON string
result.summary()        # Human-readable table

Reproducibility / Custom Weights

Weights must sum to 1.0. Recommended presets:

Use case Weights (L, E, S, T)
General ASR evaluation (0.3, 0.2, 0.3, 0.2)
Medical / legal (entity-critical) (0.2, 0.4, 0.2, 0.2)
LLM pipeline (task-first) (0.15, 0.15, 0.3, 0.4)
Backward-compatible WER (1.0, 0.0, 0.0, 0.0)

Citation

If you use SemanticWER in research, please cite:

@software{semanticwer2024,
  title     = {SemanticWER: Meaning-Aware ASR Evaluation Toolkit},
  year      = {2024},
  url       = {https://github.com/semanticwer/semanticwer},
}

License

MIT

Metadata

Release files for semanticwer 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 semanticwer 0.1.0
File Size Uploaded Provenance Actions
semanticwer-0.1.0.tar.gz 20.2 kB Without provenance Details for semanticwer-0.1.0.tar.gz

Built distribution (wheel)

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

Total release size: 37.7 kB

Release files / semanticwer-0.1.0.tar.gz

Download URL semanticwer-0.1.0.tar.gz
Size 20.2 kB
Tags Source
SHA-256 checksum
How to use checksums
73d51f35e4d6ad71f0e32d761b8d4bc1a4c45142484d16cf209e2a0dabe67bdc
BLAKE2b-256 checksum
How to use checksums
cfec7c2848809628b5003fcd9462ddd9c9a3590fd18da88cdb1bfee8b1e4cce4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

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

Download URL semanticwer-0.1.0-py3-none-any.whl
Size 17.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
34f1ac5d814d7af52065689aadf5013ed69074eba9568b732b2c13cb5f08a5d6
BLAKE2b-256 checksum
How to use checksums
fbe4a2735c73ab862e9939baa136a9d004e28637af2cfb89675ec13fb7f07e1b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Security for semanticwer 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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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 No 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