Skip to content

Fix decode loop aborting on EOT sampled during prompt prefill#502

Open
hakanensari wants to merge 1 commit into
argmaxinc:mainfrom
hakanensari:fix-prefill-eot-abort-main
Open

Fix decode loop aborting on EOT sampled during prompt prefill#502
hakanensari wants to merge 1 commit into
argmaxinc:mainfrom
hakanensari:fix-prefill-eot-abort-main

Conversation

@hakanensari

@hakanensari hakanensari commented Jul 8, 2026

Copy link
Copy Markdown

Fixes #501.

When DecodingOptions.promptTokens is set, the decode loop force-feeds the prompt one token per step, and the token sampled at each of those steps is discarded on the next iteration. The completion check still honored a sampled <|endoftext|> during that forced prefill. With large-v3 turbo the model reliably samples EOT while the SOT sequence is being forced, so the loop broke before decoding any content token, and every transcription with a prompt came back as an empty segment with no error.

This change gates sampleResult.completed on !isPrefill, so a throwaway EOT cannot complete the segment. A real EOT sampled at or after the last prefill token still ends decoding exactly as before.

Verified on openai_whisper-large-v3-v20240930_turbo (macOS 15, Apple Silicon): with this change, transcription with promptTokens produces correct text and the prompt biases spelling as intended. Without it, the same runs return an empty string. Full analysis and a decoder trace are in #501.

When DecodingOptions.promptTokens is set, the main decode loop force-feeds
the prompt (<|startofprev|> + prompt + SOT sequence) one token per step,
and the token sampled at each of those steps is discarded on the next
iteration. The completion check, however, still honored a sampled EOT
mid-prefill: with large-v3 turbo the model reliably predicts <|endoftext|>
while the SOT sequence is being forced, so the loop broke before decoding
a single content token and every transcription with a prompt came back
empty.

Gate sampleResult.completed on !isPrefill so a throwaway EOT cannot
complete the segment; a real EOT at or after the last prefill token still
ends decoding as before.
Copilot AI review requested due to automatic review settings July 8, 2026 20:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a decoding bug in TextDecoder.decodeText where an <|endoftext|> token sampled during forced prompt prefill could prematurely terminate decoding, producing an empty transcription whenever DecodingOptions.promptTokens is set (Issue #501).

Changes:

  • Prevent segment completion on sampled EOT while the decode loop is still consuming forced prefill tokens.
  • Add an inline comment explaining why EOT during prefill must be ignored.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 673 to 676
let isSegmentCompleted =
sampleResult.completed ||
(sampleResult.completed && !isPrefill) ||
currentTokens.count >= Constants.maxTokenContext - 1 ||
isFirstTokenLogProbTooLow

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A meaningful regression test here is less mechanical than it looks. The deterministic repro is on large-v3 turbo, while this suite's decoder tests run against the tiny model, and I have not confirmed that tiny samples EOT mid-prefill at all. A transcribe-with-promptTokens assertion on tiny could therefore pass even without the fix. The stub route (a TokenSampling returning completed=true during prefill plus canned predictLogits output) needs mock scaffolding the suite does not currently have. If the maintainers want either shape, I am happy to add it. Until then, the failure mode and decoder trace are documented in #501.

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.

Setting promptTokens yields empty transcription: decode loop aborts on EOT sampled during forced prefill

3 participants