Skip to content

fix(asr): preserve merge token order at chunk seams (#825) - #830

Merged
Alex-Wengg merged 2 commits into
mainfrom
fix/chunk-seam-token-order
Aug 1, 2026
Merged

Alex-Wengg merged 2 commits into
mainfrom
fix/chunk-seam-token-order

Conversation

@Alex-Wengg

Copy link
Copy Markdown
Member

Fixes #825.

Root cause

The AsrManager batch long-form path merges overlapping windows with order-aware, word-boundary-aware splicing (mergeChunks), which yields tokens in correct linear (text) order. It then globally re-sorted that stream by frame timestamp before building the transcript:

mergedTokens.sort { $0.timestamp < $1.timestamp }   // ChunkProcessor.swift

convertTokensToText joins tokens in array order, so that sort determines the transcript. But frame timestamps are a bad sort key here:

  • TDT emits several tokens per 80 ms frame, so many timestamps are equal.
  • The two overlapping windows' frame indices don't co-register across a seam (different global offsets + mel-context/warmup frame adjustments), so a token that linearly follows another can carry a numerically smaller timestamp.

Re-sorting by that coarse, locally non-monotonic key reorders same-frame subwords and interleaves subwords from the two windows — exactly the reporter's German seam:

expected produced
im Frühjahr imüh Frjahr (subwords interleaved)
Für die Regale die Für Regale (word order inverted)
Punkt Pktun (same-frame subwords shuffled)

This is the token-order-inversion class #761 flagged as needing "a fix in the merger itself."

Fix

The pairwise merges already produce correct order, so the global sort is not just unnecessary — it's the corruption. Replace it with enforceMonotonicTimestamps, which clamps each backward-stepping timestamp up to the running maximum without reordering. Text order (the merger's output) is preserved; word timing and the opt-in seam-gap repair pass still see a non-decreasing timestamp sequence. collapseSeamWordDuplicates and repairSeamGaps are unaffected — both depend on token order + monotonic time, which the clamp keeps (and both previously ran on the scrambled stream).

Scope

Targets the merge-seam reordering (the issue's title class). The first-chunk mel-context degradation the report also notes (all-lowercase, spoken-punctuation not converted) is the separate #594 family and is out of scope here.

Tests

Adds ChunkSeamTokenOrderTests — token-level regression covering the cross-window subword interleave, the word-order inversion, same-frame ties, and the already-monotonic no-op, each asserting order is preserved while timestamps become non-decreasing. (Local XCTest is unavailable in my env; validated the clamp logic + golden values with a standalone harness, and the FluidAudio library target builds clean.)

The batch long-form path merged overlapping windows with order-aware
splicing, then globally re-sorted the merged stream by frame timestamp
before building the transcript. That sort is destructive:

- TDT emits several tokens per 80 ms frame, so many timestamps are equal.
- The two overlapping windows' frame indices don't co-register across a
  seam, so a token that linearly follows another can carry a numerically
  smaller timestamp.

convertTokensToText joins tokens in array order, so re-sorting by that
coarse, non-monotonic key reorders same-frame subwords and interleaves
subwords from the two windows — the reporter's German seam showed
'im Frühjahr' -> 'imüh Frjahr', 'Für die' -> 'die Für', 'Punkt' ->
'Pktun'. This is the token-order-inversion class #761 flagged as needing
a fix in the merger itself.

The pairwise merges already produce correct linear (text) order, so
replace the global sort with enforceMonotonicTimestamps: clamp each
backward-stepping timestamp up to the running max WITHOUT reordering.
Text order is preserved; word timing and the seam-gap repair pass still
see a non-decreasing sequence. collapseSeamWordDuplicates and the
repair pass are unaffected (both rely on order + monotonic time, which
the clamp keeps).

Scope: fixes the merge-seam reordering. The first-chunk mel-context
degradation (#594 family) the report also notes is separate.

Adds token-level regression tests for the interleave/inversion cases.
@github-actions

github-actions Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Parakeet EOU Benchmark Results ✅

Status: Benchmark passed
Chunk Size: 320ms
Files Tested: 100/100

Performance Metrics

Metric Value Description
WER (Avg) 7.03% Average Word Error Rate
WER (Med) 4.17% Median Word Error Rate
RTFx 11.12x Real-time factor (higher = faster)
Total Audio 470.6s Total audio duration processed
Total Time 43.9s Total processing time

Streaming Metrics

Metric Value Description
Avg Chunk Time 0.044s Average chunk processing time
Max Chunk Time 0.088s Maximum chunk processing time
EOU Detections 0 Total End-of-Utterance detections

Test runtime: 0m50s • 07/31/2026, 10:57 PM EST

RTFx = Real-Time Factor (higher is better) • Processing includes: Model inference, audio preprocessing, state management, and file I/O

@github-actions

github-actions Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

PocketTTS Smoke Test ✅

Check Result
Build ✅
Model download ✅
Model load ✅
Synthesis pipeline ✅
Output WAV ✅ (150.0 KB)

Runtime: 0m5s

Note: PocketTTS uses CoreML MLState (macOS 15) KV cache + Mimi streaming state. CI VM lacks physical GPU — audio quality and performance may differ from Apple Silicon.

@github-actions

github-actions Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Supertonic3 Smoke Test ✅

Check Result
Build ✅
Model download (incl. VectorEstimatorVariants/ int4 buckets) ✅
Model load ✅
Synthesis pipeline (--ve-variant int4) ✅
Output WAV ✅ (364.7 KB)

Runtime: 0m27s

Note: CI VMs lack a physical Neural Engine; the ANE-bucketed VectorEstimator falls back to CPU here. This validates download + variant resolution + synthesis, not ANE residency/perf.

@github-actions

github-actions Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

VAD Benchmark Results

Performance Comparison

Dataset Accuracy Precision Recall F1-Score RTFx Files
MUSAN 94.0% 89.3% 100.0% 94.3% 732.5x faster 50
VOiCES 94.0% 89.3% 100.0% 94.3% 743.0x faster 50

Dataset Details

  • MUSAN: Music, Speech, and Noise dataset - standard VAD evaluation
  • VOiCES: Voices Obscured in Complex Environmental Settings - tests robustness in real-world conditions

✅: Average F1-Score above 70%

Add the token-order-inversion failure mode, a "Token Order Is
Authoritative" merge subsection explaining why timestamps are clamped
monotonic instead of sorted, qualify the seam-garble known-limitation
bullet (order-inversion subclass now fixed), and a changelog row.
@github-actions

github-actions Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Sortformer High-Latency Benchmark Results

ES2004a Performance (30.4s latency config)

Metric Value Target Status
DER 30.3% <35% ✅
Miss Rate 28.2% - -
False Alarm 0.9% - -
Speaker Error 1.2% - -
RTFx 19.0x >1.0x ✅
Speakers 4/4 - -

Sortformer High-Latency • ES2004a • Runtime: 2m 47s • 2026-08-01T03:05:04.408Z

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

Speaker Diarization Benchmark Results

Speaker Diarization Performance

Evaluating "who spoke when" detection accuracy

Metric Value Target Status Description
DER 15.1% <30% ✅ Diarization Error Rate (lower is better)
JER 24.9% <25% ✅ Jaccard Error Rate
RTFx 25.60x >1.0x ✅ Real-Time Factor (higher is faster)

Diarization Pipeline Timing Breakdown

Time spent in each stage of speaker diarization

Stage Time (s) % Description
Model Download 12.889 31.4 Fetching diarization models
Model Compile 5.524 13.5 CoreML compilation
Audio Load 0.057 0.1 Loading audio file
Segmentation 12.290 30.0 Detecting speech regions
Embedding 20.484 50.0 Extracting speaker voices
Clustering 8.193 20.0 Grouping same speakers
Total 40.995 100 Full pipeline

Speaker Diarization Research Comparison

Research baselines typically achieve 18-30% DER on standard datasets

Method DER Notes
FluidAudio 15.1% On-device CoreML
Research baseline 18-30% Standard dataset performance

Note: RTFx shown above is from GitHub Actions runner. On Apple Silicon with ANE:

  • M2 MacBook Air (2022): Runs at 150 RTFx real-time
  • Performance scales with Apple Neural Engine capabilities

🎯 Speaker Diarization Test • AMI Corpus ES2004a • 1049.0s meeting audio • 41.0s diarization time • Test runtime: 2m 57s • 07/31/2026, 10:59 PM EST

@github-actions

github-actions Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

ASR Benchmark Results ✅

Status: All benchmarks passed

Parakeet v3 (multilingual)

Dataset WER Avg WER Med RTFx Status
test-clean 0.57% 0.00% 5.39x ✅
test-other 1.19% 0.00% 3.50x ✅

Parakeet v2 (English-optimized)

Dataset WER Avg WER Med RTFx Status
test-clean 0.80% 0.00% 4.81x ✅
test-other 1.40% 0.00% 2.83x ✅

Streaming (v3)

Metric Value Description
WER 0.00% Word Error Rate in streaming mode
RTFx 0.64x Streaming real-time factor
Avg Chunk Time 1.400s Average time to process each chunk
Max Chunk Time 1.473s Maximum chunk processing time
First Token 1.665s Latency to first transcription token
Total Chunks 31 Number of chunks processed

Streaming (v2)

Metric Value Description
WER 0.00% Word Error Rate in streaming mode
RTFx 0.52x Streaming real-time factor
Avg Chunk Time 1.753s Average time to process each chunk
Max Chunk Time 2.125s Maximum chunk processing time
First Token 1.698s Latency to first transcription token
Total Chunks 31 Number of chunks processed

Streaming tests use 5 files with 0.5s chunks to simulate real-time audio streaming

25 files per dataset • Test runtime: 9m38s • 07/31/2026, 11:10 PM EST

RTFx = Real-Time Factor (higher is better) • Calculated as: Total audio duration ÷ Total processing time
Processing time includes: Model inference on Apple Neural Engine, audio preprocessing, state resets between files, token-to-text conversion, and file I/O
Example: RTFx of 2.0x means 10 seconds of audio processed in 5 seconds (2x faster than real-time)

Expected RTFx Performance on Physical M1 Hardware:

• M1 Mac: ~28x (clean), ~25x (other)
• CI shows ~0.5-3x due to virtualization limitations

Testing methodology follows HuggingFace Open ASR Leaderboard

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

Offline VBx Pipeline Results

Speaker Diarization Performance (VBx Batch Mode)

Optimal clustering with Hungarian algorithm for maximum accuracy

Metric Value Target Status Description
DER 10.4% <20% ✅ Diarization Error Rate (lower is better)
RTFx 13.30x >1.0x ✅ Real-Time Factor (higher is faster)

Offline VBx Pipeline Timing Breakdown

Time spent in each stage of batch diarization

Stage Time (s) % Description
Model Download 20.886 26.5 Fetching diarization models
Model Compile 8.951 11.3 CoreML compilation
Audio Load 0.051 0.1 Loading audio file
Segmentation 21.546 27.3 VAD + speech detection
Embedding 78.663 99.7 Speaker embedding extraction
Clustering (VBx) 0.105 0.1 Hungarian algorithm + VBx clustering
Total 78.889 100 Full VBx pipeline

Speaker Diarization Research Comparison

Offline VBx achieves competitive accuracy with batch processing

Method DER Mode Description
FluidAudio (Offline) 10.4% VBx Batch On-device CoreML with optimal clustering
FluidAudio (Streaming) 17.7% Chunk-based First-occurrence speaker mapping
Research baseline 18-30% Various Standard dataset performance

Pipeline Details:

  • Mode: Offline VBx with Hungarian algorithm for optimal speaker-to-cluster assignment
  • Segmentation: VAD-based voice activity detection
  • Embeddings: WeSpeaker-compatible speaker embeddings
  • Clustering: PowerSet with VBx refinement
  • Accuracy: Higher than streaming due to optimal post-hoc mapping

🎯 Offline VBx Test • AMI Corpus ES2004a • 1049.0s meeting audio • 100.3s processing • Test runtime: 1m 53s • 07/31/2026, 11:10 PM EST

@Alex-Wengg
Alex-Wengg merged commit c802b43 into main Aug 1, 2026
11 checks passed
@Alex-Wengg
Alex-Wengg deleted the fix/chunk-seam-token-order branch August 1, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chunk-seam merge interleaves subword tokens on non-English long-form batch audio (token-order inversion, not just intra-word garbles)

1 participant