Expose word timestamps for Parakeet#93
Open
ArturWierzbicki wants to merge 1 commit into
Open
Conversation
Verify Parakeet TDT word timestamps against the NeMo reference: - dump reference word and token timings in the parakeet NeMo dumper (transcript.json gains word rows; token rows gain timing) - emit words/tokens in the CLI batch JSON, gated on the returned timestamp kind - compare word start/end against the reference in validate.py, within the new "timestamps" budget in tests/tolerances/<family>.json (80 ms = one encoder frame for parakeet) - mirror NeMo's punctuation convention in the decoder: punctuation-only tokens are zero-length at the previous token's end, guarded for non-UTF-8 vocab pieces, with the punctuation set cached at model load. The first validation run caught a 560 ms word-end divergence this fixes; the re-run passes with max 80 ms and mean 3.6 ms on the validation clip, and parakeet-tdt-0.6b-v3 matches the reference exactly - update validate, model-family-testing, and model-card docs
Contributor
|
Thanks for this PR. I will take a look at it soon and then try to pull it. And I think this is pretty reasonable |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
I have a tool that turns recorded meetings into markdown transcripts with named speakers and screenshots of what was shared on screen. Today it transcribes with Parakeet TDT via parakeet-mlx. I'd love to move to transcribe.cpp to simplify the setup.
To do so, I need word timestamps: I use them to match words to diarized speaker turns and to merge overlapping audio chunks by cutting at silences between words. transcribe.cpp already computes them, but the per-file JSON from
--batch-jsonldoes not expose them. This PR exposes them and verifies them: the batch JSON gainswordsandtokensarrays, the parakeet NeMo dumper records word timings in its reference output, and validate.py compares each word's start and end against the reference within a new 80 ms tolerance, the duration of one encoder frame. The comparison code is shared across model families; a family turns it on by dumping reference word timings and adding atimestampsentry to its tolerance file.The check caught a real bug on its first run. A comma is its own token, and the model predicts a duration for it as it does for every token, even though nothing is spoken there.
Before this PR the decode kept those predicted durations, and word ends inherited them, drifting up to 560 ms past the speech on the validation clip. NeMo gives punctuation zero duration instead: in JFK's "And so, my fellow Americans, ...", the token " so" ends at 800 ms and the "," sits exactly there, so the word "so," ends when the audio does. The offline decode in
src/arch/parakeet/model.cppnow applies the same rule; transcript text is unchanged.Scope
src/arch/parakeet: punctuation tokens get zero duration in offline decode; the set of punctuation tokens is built once at model load, and vocab entries that are not valid UTF-8 skip the rewriteexamples/cli:wordsappears in batch JSONL when a run returns word or token timestamps,tokensonly at token levelscripts: the parakeet reference dumper emits word and token timings;validate.pygains the word-timestamp comparison and unit teststests: atimestampstolerance entry for parakeet; real-model smoke assertions for zero-duration punctuationdocs: tools/validate, model-family-testing, and the v2 and v3 model cardsAI Assistance
Yes, heavy Fable usage: code/docs/investigation. I directed and reviewed the work and own the change, happy to iterate more. I'm not an ASR/C++ person, so I also iterated upon a human-digestible :), zero-context explainer of the whole change for me and anyone else who wants the background: https://gist.github.com/ArturWierzbicki/3a5e21740703103e0a89a51428a862a6
Validation
validate.py allfor parakeet-tdt-0.6b-v2: 18/18 tensors within tolerance, exact transcript, and word timestamps that deviate from the reference by 80 ms max and 3.6 ms mean.validate.py allfor parakeet-tdt-0.6b-v3: exact transcript, and word timestamps that match the reference exactly (0.000 ms max deviation).