Skip to content

parakeet-tdt-0.6b-v3-coreml: window-composition instability corrupts words (right-context sensitivity) in the fixed 15s non-causal export #760

Description

@holovchenko

Summary

On windowed/long-form transcription, parakeet-tdt-0.6b-v3-coreml intermittently drops or mangles a word when that word lands within roughly the first ~5.5s of the 15s encoder window covering it. The identical weights via NeMo (PyTorch) and parakeet-mlx transcribe the same audio correctly, so this is specific to the CoreML export + windowing path, not the model weights.

Reproduction (deterministic; Ukrainian; .cpuOnly; ASRConfig(melChunkContext: false))

118s clip. Speaker says "…вимкнути фоновий процес…" at 43.6–46.6s.

  • FluidAudio (whole clip, chunked): "…вимкнути там кнопкою фоновиц" — "процес" dropped, "фоновий"→"фоновиц".
  • NeMo nvidia/parakeet-tdt-0.6b-v3 (whole audio): "…фоновий процес" ✓
  • parakeet-mlx mlx-community/parakeet-tdt-0.6b-v3 (whole audio): "…фоновий процес" ✓

Isolated cause — a left-context cliff

Single-shot inference (no chunk merge), varying the left audio context before the phrase:

left context before phrase output
1s / 3s / 4s mangled / "фоновиц" (word dropped)
5.5s / 7s "фоновий процес" ✓

The CoreML Encoder is stateless and fixed-shape (mel [1,128,1501] = 15.01s, hasShapeFlexibility: 0, empty stateSchema); the 15s window is baked at trace time (mobius .../coreml/convert-parakeet.py, max_audio_seconds = 15.0). With melChunkContext: false, the only left context a window gets is the sliding overlap (default 2s), so a word near a window's start sits below the ~5.5s the encoder needs and is dropped/mangled.

Widening the sliding overlap does NOT fix it

Raising ChunkProcessor.overlapSeconds 2→6s (the covering window then has ~7.76s of left context) still drops the word: the merge/token-selection picks the adjacent short-context window's tokens in the overlap zone. It also costs ~8–24% compute on multi-window clips.

Suggested directions

  1. Export the encoder with a larger context window (e.g. 30s) or a stateful/streaming variant, so positions aren't starved of left context.
  2. Make merge/token-selection in overlap zones prefer the window where a token had more left context (i.e. is deeper into its window), rather than the window where it sits near the start.

Environment

FluidAudio 0.15.3+, parakeet-tdt-0.6b-v3-coreml, macOS 26 / iOS, .cpuOnly, melChunkContext: false.


Correction / refined mechanism (further ablation)

Additional isolation shows this is window-composition instability, not purely a left-context cliff. Holding the word fixed and truncating the surrounding audio:

  • word decodes correctly with adequate left context AND ≤~2s of trailing audio after it in the window;
  • word corrupts ("фоновиц", "процес" dropped) once there is ≥~4s of audio after the word inside the same 15s window.

So the non-causal (bidirectional-within-window) encoder's encoding of a word is unstable to what follows it in the fixed window, not just what precedes it. Widening the sliding overlap therefore can't help (the word sits in a single window with no competing decode), and simply enlarging the window may add more trailing context rather than less. Reference runtimes with full-file attention (NeMo, parakeet-mlx) don't exhibit this. This points to the fixed-window / non-causal CoreML export (possibly interacting with INT8 quantization) rather than the chunk-merge or the weights.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions