fix chunk overlap timestamp merge - #54
Conversation
|
Hello! First of all, thank you for the pull request. But it raises a few questions I'd want to ask before merging it. First, regarding to a = [
AlignedToken(id=1, text="t1", start=5.00, duration=0.30),
AlignedToken(id=2, text="t2", start=7.00, duration=0.30),
]
b = [
AlignedToken(id=1, text="t1", start=4.50, duration=0.30),
AlignedToken(id=3, text="t3", start=4.95, duration=0.30), # real token (first pass missed it)
AlignedToken(id=2, text="t2", start=7.00, duration=0.30),
]where first forward failed to predict the a = [
AlignedToken(id=99, text="t99", start=4.50, duration=0.30),
AlignedToken(id=1, text="t1", start=5.00, duration=0.30), # model stretch it to the end
]
b = [
AlignedToken(id=99, text="t99", start=4.50, duration=0.30),
AlignedToken(id=1, text="t1", start=4.60, duration=0.30),
AlignedToken(id=2, text="t2", start=4.95, duration=0.30), # new stuff from here
AlignedToken(id=3, text="t3", start=6.00, duration=0.30),
]It would drop and abs(overlap_a[k].start - overlap_b[l].start)
< overlap_duration / 2or introducing the better heuristic would be a better fix for this issue. Second, in this line +return result if _is_time_ordered(result) else _merge_at_cutoff(a, b)
Third, it's relatively minor nitpicking but it introduces too much helper functions at once. Like |
Background
This PR fixes an issue in chunked transcription where merging overlapping chunks can produce a token sequence whose text order does not match its timestamp order.
In some overlap cases, tokens from the previous chunk and the current chunk are aligned using either a contiguous match or the LCS fallback. The previous implementation rebuilt the merged token sequence from those matches, but it did not guarantee that the final token
starttimestamps remained monotonically increasing.That can break the following invariant in the JSON output:
The reason is that
sentence.textis built from the merged token order, whileAlignedSentence.__post_init__()sortssentence.tokensbytoken.start.One observed example was that the sentence text was correct:
but joining the exported tokens produced:
Test Files
I used three files to reproduce and isolate the issue:
demo.webmis the full reproduction case. Withchunk_duration=120andoverlap_duration=15, it is split like this:segment1.webmandsegment2.webmare the two individual chunks from that split:They are included to show that the problem comes from merging the two overlapping chunk hypotheses, not from a single chunk transcription.
In the overlap region, the first chunk ends with:
while the second chunk continues with:
The old merge logic could combine these into a sequence whose text order looked correct, but whose token timestamps caused the exported tokens to be sorted as:
Changes
This PR keeps the existing overlap matching logic and only changes how the matched tokens are merged afterward:
_merge_from_pairs()helper used by both contiguous matching and the LCS fallbackThis keeps the merged token sequence consistent in both text order and timestamp order.
Validation
I reproduced the issue with
demo.webmusing the default chunk overlap settings:I also used
segment1.webmandsegment2.webmwith chunking disabled to inspect the two chunk hypotheses independently:After generating the JSON output from the fixed code, I checked the following invariants with a separate validation script:
sentence.text == "".join(token.text for token in sentence.tokens)starttimestamps do not move backward within each sentencestarttimestamps do not move backward globallyThe sentence that previously reproduced the issue is now consistent:
Joining the exported tokens no longer produces
local. Olama.