← The System

The System

The 73-Second Hallucination: Building Automated QA for Generative TTS

DEV.to · October 28, 2026 · 8:10 AM EDT · 5 min read

Automating QA by comparing generated audio against the original script.

In my previous article, I wrote about solving ear fatigue in long-form TTS: repeated cadence, unnatural pacing, and the tendency for generated narration to fall into predictable patterns.

One of the conclusions I came away with was that higher temperature gave the model more room to vary its performance without changing the words.

Then I listened to the final master of Chapter 9.

At 03:48, the script called for a short exchange:

Sarah: “You made dinner?”
Daniel: “I tried.”

Instead, the model kept going.

It invented new dialogue. Then more dialogue. Then blocking, reactions, and tension that weren’t anywhere in the manuscript.

For roughly 73 seconds, it wrote and performed its own version of the story.

Then, at about 05:01, it found the script again and continued as though nothing had happened.

That created a much bigger problem than one bad section of audio.

If Chapter 9 could invent 73 seconds of dialogue, what had the other 12 chapters done?

Had the model dropped sentences? Substituted words? Added smaller pieces of dialogue that weren’t obvious enough for me to notice?

I had already listened to the audiobook. But listening for whether a performance sounds good is different from verifying that every generated word matches the manuscript.

I needed QA.

The Problem With Manual Verification

The audiobook was roughly 80 minutes long.

I could listen to the entire thing again while following the manuscript line by line, but that would turn 80 minutes of audio into several hours of concentrated verification.

More importantly, that doesn’t scale.

I already had three things:

  1. The ground-truth manuscript.
  2. The generated audio.
  3. A multimodal model capable of processing audio and text together.

So instead of manually comparing them, I used the model to perform a first-pass comparison.

The job was simple:

Listen to the generated audio, compare it against the source script, and flag meaningful discrepancies.

That became the Multimodal Script Verification Pipeline.

Treat the Script as Ground Truth

The verifier wasn’t judging whether the narration sounded good. It wasn’t evaluating pacing, emotion, or performance.

It had a narrower job: compare what was spoken with what was written.

For each chapter, it received the generated audio and corresponding script and looked for:

  • inserted content,
  • omitted content,
  • substitutions,
  • repeated passages,
  • and other meaningful mismatches.

The manuscript remained the source of truth.

The verification request looked roughly like this:

# scripts/media/audit_all_chapters.py
import json
import time
from pathlib import Path
from google import genai

client = genai.Client()

AUDIT_PROMPT = """You are a strict professional audio QA auditor for an audiobook production company.
Ground Truth Narration Script:
\"\"\"
{script_text}
\"\"\"

Carefully listen to the entire audio file and compare it word-for-word against the ground truth script.
Look for ANY:
1. Hallucinations / Added words (words spoken in audio that are NOT in the script)
2. Omissions / Skipped words or lines (words in the script that were NOT spoken in the audio)
3. Substitutions or major stutters

Return a structured JSON report inside ```

json ...

 ``` code blocks:
{{
  "status": "PERFECT_MATCH" | "DISCREPANCIES_FOUND",
  "discrepancies": [
    {{
      "timestamp": "MM:SS",
      "type": "HALLUCINATION" | "OMISSION" | "SUBSTITUTION",
      "expected": "text in script",
      "actual": "spoken text in audio",
      "notes": "brief explanation"
    }}
  ]
}}
"""
Enter fullscreen mode Exit fullscreen mode

The architecture was essentially:

Ground-truth script ─┐
                     ├──> Multimodal verifier ──> Structured discrepancies
Generated audio ─────┘
Enter fullscreen mode Exit fullscreen mode

That gave me an automated QA pass I could run across the entire audiobook instead of manually comparing every spoken line against the manuscript.

Auditing the Book

I ran the verifier across all 13 tracks.

Most came back without a reported discrepancy. Others were flagged for review.

The original audit output included:

Track # Chapter Title Status Type Timestamp Detail
00–02 Credits & Ch 1–2 ✅ Clean — — 100% Verbatim
03 Ch 3: The Friday Dinner ⚠️ Flagged SUBSTITUTION 06:32 Spoke "We doing this" instead of "We're doing this"
04–06 Chapters 4–6 ✅ Clean — — 100% Verbatim
07 Ch 7: The Other Side of the Table ⚠️ Flagged OMISSION 00:00 Omitted chapter title heading entirely
08 Ch 8: The Chipped Mug ⚠️ Flagged SUBSTITUTION 02:23 Said "chip's lip" instead of "chipped lip"
09 Ch 9: The Table for Eight ❌ Flagged HALLUCINATION 03:48 73-second unprompted argument inserted
10–12 Ch 10–11 & Credits ✅ Clean — — 100% Verbatim

The verifier is another model. Its output shouldn’t be treated as unquestionable proof that every unflagged track is perfect.

Its job is to make QA tractable: compare generated audio against known ground truth and surface discrepancies worth investigating.

The Chapter 9 hallucination was dramatic enough that I noticed it while listening.

A missing heading or substituted word is much easier to miss.

The most obvious TTS failures may not be the most dangerous ones.

The dangerous ones can be the ones that still sound plausible.

Listening and Verification Are Different Jobs

I still need to listen to the audiobook.

Script verification doesn’t tell me whether a performance is emotionally convincing, whether the pacing feels right, or whether a voice choice becomes exhausting over a full chapter.

Those are performance-review problems.

But listening for performance and verifying fidelity aren’t the same task.

Before Chapter 9, my process was effectively:


Generate
   ↓
Listen
   ↓
Ship
Enter fullscreen mode Exit fullscreen mode

The hallucination exposed the missing step.

Now the pipeline looks more like:


Generate
   ↓
Performance review
   ↓
Verify against ground truth
   ↓
Review flagged discrepancies
   ↓
Repair
   ↓
Ship
Enter fullscreen mode Exit fullscreen mode

The model that generated the audio doesn’t get to define whether its output is correct.

The manuscript does.

The 73-second hallucination was the error I heard.

The auditor was how I checked for the errors I didn’t.