Last updated: October 28, 2026
Ask an LLM to “fix the errors” in a transcript and you’ll get one of two things back: a transcript with the misrecognitions and the ums still in it, or a cleaner, better-written version of what the speaker almost said. The second one is worse. It reads well, it passes a glance, and it’s no longer a record of the conversation.
Transcript correction is the narrow task of cleaning up what speech-to-text produced for readability without changing what was said. This post defines it the way Voice Standard Bench measures it on every model on LLM Gateway, shows the live picks at four transcript lengths, and gives you the bench’s own correction prompt to run on your own transcripts. The numbers below are from the live bench as of October 28, 2026; the live page stays the source of truth.
What transcript correction is (and isn't)
Correction is a constrained-rewrite task. Given a raw call transcript with filler words, false starts, stutters, missing punctuation and casing, and the occasional misrecognized word, produce the transcript a careful human editor would: fillers and stutters removed, sentence boundaries and casing fixed, obvious mis-transcriptions fixed where context makes the intended word clear. Keep every fact, name, number, and claim, expressed the way the speaker expressed it. Keep the speaker’s hedges, disagreements, and informal phrasing. Change the meaning of nothing.
It is not:
- Dictation cleanup, which turns spoken formatting commands (“comma,” “new paragraph”) into finished written text for a message or note. That’s a different task with a different target; see the Dictation API for that job.
- Summarization or rewriting, which changes length or style on purpose.
- Grammar correction, which fixes what the speaker said rather than what the recognizer produced. If someone said “we was gonna ship it,” a correct transcript says that.
A short example makes the boundary clear:
ASR output:
so the patient is on met foreman five hundred twice a day and we
um we want to add a lisinopril ten starting next monday the fourteenth
Corrected:
So the patient is on metformin five hundred twice a day, and we want to add
a lisinopril ten starting next Monday, the fourteenth.
Over-edited:
The patient is on metformin 500 mg twice daily. We will add
lisinopril 10 mg starting Monday the 14th.The corrected version fixed “met foreman,” dropped the “um” and the stuttered “we,” and added punctuation and casing. It left the numbers the way the speaker said them. The over-edited version is a nicer sentence and a worse transcript: it added units the speaker never said, dropped “next,” and turned “we want to add” into “we will add,” which is a different claim.
The two failure modes: under-correction vs rewriting what was said
Under-correction is the obvious one. The model is too conservative, leaves “met foreman” and the stutters in place, and the pass adds latency and cost without improving the transcript. This tends to happen with small models given a vague prompt, or when the error is a plausible real word.
Over-correction is the dangerous one, because it looks like success. The model fixes the misrecognitions and keeps going: it swaps a correct product name for a more common one, “improves” a number it decided was unlikely, drops a clause it considered redundant, or standardizes a term the speaker used deliberately. The output is fluent and wrong. Proper nouns, domain terms, and numbers are where this bites hardest, because the model’s prior about what’s likely overrides what’s in the text.
A good correction model has to be confident enough to change “met foreman” and cut the ums, and restrained enough to leave “we was” alone. That’s why the bench scores correction on two criteria that pull in opposite directions.
How Voice Standard Bench scores text correction
Voice Standard Bench runs every Gateway model on four voice tasks: summarization, information extraction, text correction, and dictation cleanup. For text correction, the design is specific:
- Simulated errors added to real transcripts. The bench starts from real call transcripts and simulates a corrupted version of each one. The model receives that degraded text (the repo calls it missed_text) and is asked to correct it. The repo frames the corruption in ASR terms: filler words, false starts, stutters, and missing punctuation and casing, with numbers in spoken, spelled-out form. The task prompt also asks the model to fix obvious mis-transcriptions where the intended word is clear from context. The script that generates the corruption isn’t in the public repo, so there’s no published breakdown by error type.
- A fixed task prompt. Every model gets the same instructions: remove filler words, false starts, and stutters; fix obvious mis-transcriptions; fix punctuation, capitalization, and sentence boundaries; don’t paraphrase, summarize, shorten, or add anything; keep hedges and informal phrasing that carry meaning; leave clean passages unchanged; output only the corrected transcript.
- The original is not the answer key. Output is judged, not string-matched against the pre-corruption transcript. That matters because a real transcript has imperfections of its own, and a model shouldn’t be penalized for a correct fix the original lacked or rewarded for reproducing the original’s quirks.
- Two criteria, two judges. Claude Opus 5.5 and GPT-5.6 Sol each score faithfulness (does the output keep every fact, name, number, and claim, with the same meaning?) and improvement (is it actually more readable, with fillers and false starts removed and punctuation and casing fixed, without over-correcting into something that no longer reads like a real conversation?). Removing fillers is the job, not a faithfulness violation. Scores are tracked separately and combined.
- Four lengths. 30 seconds, 2 minutes, 15 minutes, and 60 minutes, 10 transcripts per bucket within 15% of the target length.
Every model also gets a median response time and a cost per hour of audio at provider list price. The methodology post has the rubric and the judge calibration details, including the note that scores within 2 to 3 points differ only marginally.
Quality, latency, and cost per hour: how to weight them for correction
Correction is usually a batch step, which changes the weighting compared to interactive tasks like dictation.
Quality first, and know what the score blends. The combined score averages faithfulness and improvement. A model with high improvement and middling faithfulness is an over-editor; a model with the reverse is timid. For a legal, medical, or compliance transcript, weight faithfulness. For a searchable archive where a wrong product name breaks retrieval, weight improvement. The live page shows the combined score; a private run of the bench gives you the two dimensions per sample.
Latency matters less, unless it doesn’t. If correction runs after the call, a few seconds per transcript is invisible. If you’re correcting short segments in near-real-time to feed a voice agent or live captions, start from the Fastest card, but read its score first: at 30 seconds the fastest model scores 62 against a top score of 98, and the next-fastest, Qwen3 32B (qwen3-32B), scores 81 with a 0.51-second median.
Cost compounds per hour. Correction sends the whole transcript in and gets nearly the whole transcript back, so output tokens are high relative to other tasks. At 60 minutes, that makes the cost-per-hour spread between models wide. Multiply the bench’s cost figure by your monthly audio hours before choosing the top performer by default.
The choose a model docs show how to filter the Gateway catalog by task and length to pull a shortlist with these three figures side by side.
Top models for transcript correction by length
On the live results page, open the Text correction tab and set the length. Each view shows Highest Performance (the top score, with ties going to the lower cost), Lowest cost (per hour of audio), and Fastest (the lowest median response time across all tasks at that length). Lowest cost and Fastest are raw picks with no quality floor; check the score before you ship one. Here are the cards as of October 28, 2026:
| Length | Highest Performance | Fastest | Lowest cost |
|---|---|---|---|
| 30 seconds | GPT-5.6 Sol (gpt-5.6-sol): score 98, $0.19/hr, 1.94 s | Qwen3.5 4B Fast (qwen3.5-4b-32k-fast): score 62, 0.28 s median | Nemotron 3 Nano 30B A3B (nemotron-3-nano-30b-a3b): score 57, $0.0019/hr |
| 2 minutes | GPT-6.1 Sol (gpt-6.1-sol): score 94, $0.11/hr, 6.76 s | Qwen3.5 4B Fast (qwen3.5-4b-32k-fast): score 60, 0.60 s median | Nemotron 3 Nano 30B A3B (nemotron-3-nano-30b-a3b): score 51, $0.0023/hr |
| 15 minutes | Opus 5 (claude-opus-5): score 91, $0.41/hr, 14.86 s | Qwen3.5 4B Fast (qwen3.5-4b-32k-fast): score 49, 1.49 s median | Nemotron Nano 9B v2 (nemotron-nano-9b-v2): score 11, $0.0025/hr |
| 60 minutes | GLM-5.3 (glm-5.3): score 88, $0.031/hr, 14.73 s | Gemini 3.5 Flash Lite (gemini-3.5-flash-lite): score 70, 2.86 s median | Nemotron Nano 9B v2 (nemotron-nano-9b-v2): score 6, $0.0019/hr |
Source: Voice Standard Bench, Text correction tab, as of October 28, 2026. Scores are 0–100; cost is per hour of audio; Fastest is the model’s median response time across all tasks at that length.
What the length effect looks like on this task: short transcripts have little to fix and little context, so cheaper models get close to the top. At 30 seconds, GPT-6 Luna (gpt-6-luna) scores 96, two points behind the top card, at about $0.006 per hour of audio. As transcripts get longer, two things happen. Models that over-edit do more damage because there’s more to rewrite, and models with weaker long-context handling start missing errors late in the transcript. The top score drifts down from 98 at 30 seconds to 88 at 60 minutes, and the raw Lowest cost pick falls apart: it scores 11 at 15 minutes and 6 at 60 minutes.
So at long lengths the Lowest cost card is a warning, not a recommendation. The better cost story at 60 minutes is the top card itself: GLM-5.3 (glm-5.3) scores 88 for about $0.03 per hour of audio, a fraction of what the frontier models next to it cost. Read the score before you read the price.
Highest Performance, Fastest, and Lowest cost per hour of audio for every Gateway model on text correction, at four transcript lengths.
Reduce errors before the LLM
The best correction pass is the one that has less to correct. Three upstream levers in AssemblyAI Speech-to-Text cut the error count before any LLM sees the transcript:
- Keyterm prompting. Pass product names, people, drug names, and jargon as key terms and the recognizer gets them right the first time. This is the single biggest lever for proper-noun errors, which are also the errors LLMs are most likely to “fix” incorrectly. See the keyterms prompting docs.
- Text formatting. With format_text on, which is the default, numbers, dates, and similar entities come back formatted for readability, so the correction model isn’t guessing whether “four eight two one” is an order number or a time. Set it to false when you need the words exactly as spoken. See the formatting docs.
- The right speech_models choice. Set speech_models to the model that fits your audio and language (universal-3-5-pro for pre-recorded audio, universal-3-6-pro for streaming); a stronger recognizer on the audio you have beats any downstream pass.
With those in place, a correction LLM is an optional layer, not a requirement. For an explainer on how transcript errors are measured, see our word error rate post.
Run a correction pass through LLM Gateway
LLM Gateway is OpenAI-compatible: same API key as Speech-to-Text, provider list price with 0% markup, switch models by changing one string. The sample below sends a transcript to three candidate model IDs with the bench’s own correction prompt as the system prompt, plus an optional glossary, then prints a word-level diff so you can see exactly what each model changed. The IDs are the three card picks for 2-minute transcripts; swap them for whatever the Text correction tab shows at your length.
import os, time, difflib, requests
API_KEY = os.environ["ASSEMBLYAI_API_KEY"]
URL = "https://llm-gateway.assemblyai.com/v1/chat/completions"
# Highest Performance, Fastest, and Lowest cost on the live Text correction tab (2 minutes)
CANDIDATES = ["gpt-6.1-sol", "qwen3.5-4b-32k-fast", "nemotron-3-nano-30b-a3b"]
# The task prompt Voice Standard Bench sends on every text correction record
# (src/prompts/correction.go)
SYSTEM = """You are cleaning up a raw call transcript for readability.
You will be given the raw transcript of a phone or video call. Produce a corrected version.
Rules:
- Remove filler words (um, uh, like), false starts, and stutters ("I- I think" becomes "I think").
- Fix obvious mis-transcriptions where the intended word is clear from context.
- Fix punctuation, capitalization, and sentence boundaries.
- Do NOT paraphrase, reword, summarize, shorten, or add anything. Every fact, name, number, and claim in the original must still be present, expressed the way the speaker expressed it.
- Do NOT remove disagreements, hedges, or informal phrasing that reflects what was actually meant — only remove noise that carries no meaning.
- If a passage is already clean, leave it unchanged.
- Output ONLY the corrected transcript. No preamble, no explanation of what you changed."""
# Optional: the bench sends no glossary, but your own domain terms help with names and jargon
GLOSSARY = "metformin, lisinopril, Dr. Okafor, Acme Fulfillment, SKU-4821"
transcript = open("transcript.txt").read()
def word_diff(a, b):
sm = difflib.SequenceMatcher(None, a.split(), b.split())
out = {"replace": [], "delete": [], "insert": []}
for tag, i1, i2, j1, j2 in sm.get_opcodes():
if tag == "replace":
out[tag].append(f"[{' '.join(a.split()[i1:i2])} -> {' '.join(b.split()[j1:j2])}]")
elif tag == "delete":
out[tag].append(f"[-{' '.join(a.split()[i1:i2])}]")
elif tag == "insert":
out[tag].append(f"[+{' '.join(b.split()[j1:j2])}]")
return out
for model in CANDIDATES:
t0 = time.time()
resp = requests.post(
URL,
headers={"authorization": API_KEY, "content-type": "application/json"},
json={
"model": model,
"messages": [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": f"Glossary: {GLOSSARY}\n\nTranscript:\n{transcript}"},
],
"max_tokens": 4096,
},
timeout=300,
)
resp.raise_for_status()
elapsed = time.time() - t0
corrected = resp.json()["choices"][0]["message"]["content"]
edits = word_diff(transcript, corrected)
counts = ", ".join(f"{len(v)} {k}" for k, v in edits.items())
print(f"--- {model} ({elapsed:.2f}s: {counts}) ---")
for e in edits["replace"] + edits["insert"]:
print(" ", e)Read the diff by type. Because the prompt removes fillers and stutters, every model will make plenty of deletions, and that’s the job. Replacements are where over-correction shows up. If one model makes 40 replacements where the others make 8 on the same transcript, open the diff before trusting it; that’s the pattern the bench’s faithfulness criterion is designed to catch. For 60-minute transcripts, chunk by speaker turn or by a few minutes of audio, correct each chunk with the same prompt, and rejoin; it keeps the model’s attention on local context and makes diffs easier to review.
If you’re starting from audio, transcribe first with keyterm prompting enabled, then pass transcript.text into the loop. The apply LLMs to audio files guide covers that handoff, and the Gemini 4 Argon on LLM Gateway post has a second worked Gateway example. For the broader decision framework, see how to choose an LLM for voice.
Pass your domain vocabulary to Speech-to-Text and get names and terms right before any correction pass runs.
Evaluate on your own transcripts
The bench shows which models to try first, not which to ship. A small gold set is enough to pick between two or three candidates on your own data:
- Pull 20 to 30 real transcripts across the lengths you care about.
- Have someone who knows the domain correct them by hand, following the same rules you’ll give the model. That’s your reference.
- Run each candidate with the prompt above.
- Score two things: edits that matched the reference (improvement) and edits the reference didn’t make (over-correction). Count the second category by hand for the first few transcripts; you’ll quickly see which model you trust.
For a judged run that mirrors the bench, the voice-standard-bench CLI accepts your own JSONL at normalized/text_correction/aai_transcripts.jsonl. Each text correction record carries the degraded input in a top-level missed_text field. Set ASSEMBLY_AI_TOKEN and run go run . -tasks text_correction -models model-a,model-b from src/ to get faithfulness and improvement scores from the bench’s judge prompt; -judge-model picks the judge.
Speech-to-Text and 50+ LLMs behind the same key, at provider rates with 0% markup. The free tier needs no credit card.
Frequently Asked Questions (FAQs)
What is LLM transcript correction?
It’s a post-processing step that uses an LLM to clean up a speech-to-text transcript for readability: removing fillers, false starts, and stutters, fixing punctuation, casing, and sentence boundaries, and fixing obvious misrecognitions, while keeping every fact, name, number, and claim the way the speaker said it. It differs from dictation cleanup, which executes spoken formatting commands, and from summarization, which changes length on purpose.
Can an LLM make a transcript worse?
Yes. Over-correction replaces correct but unusual words with more common ones, adds information the speaker never said, or drops hedges and informal phrasing that carried meaning. The result reads better and is less accurate. Voice Standard Bench scores faithfulness separately from improvement to catch this, and a constrained prompt plus a diff review catches it on your own data.
Which LLM is best for correcting speech-to-text output?
It depends on length. On the live Voice Standard Bench as of October 28, 2026, the Highest Performance card goes to GPT-5.6 Sol at 30 seconds (98), GPT-6.1 Sol at 2 minutes (94), Opus 5 at 15 minutes (91), and GLM-5.3 at 60 minutes (88). Check the score next to the Fastest and Lowest cost cards before using them, since neither has a quality floor, then test your shortlist on a small gold set.
How does Voice Standard Bench test correction?
It simulates a corrupted version of each real call transcript, asks each model to clean up the degraded text with a fixed prompt, and has two LLM judges score the output for faithfulness and improvement. The original transcript isn’t used as an answer key. It runs at four lengths, with median response time and cost per hour of audio tracked alongside quality.
Do I still need a correction pass with a modern speech-to-text model?
Often not. Keyterm prompting, text formatting, and choosing the right speech_models remove most proper-noun and number errors upstream. A correction LLM is an optional layer for domains where remaining errors are costly, or where you want fillers and false starts removed for readability.
How much does transcript correction cost per hour of audio?
It varies by model and transcript length, and it’s higher than tasks like summarization because the output is nearly as long as the input. The live results page shows the cost per hour for every model on the Text correction tab; at 60 minutes the top-scoring GLM-5.3 runs about $0.03 per hour of audio. Multiply by your monthly audio hours to compare candidates.