Skip to content

feat(server): honour ignore_eos and min_tokens (#881) - #907

Merged
tawei-amd merged 1 commit into
mainfrom
feat/ignore-eos-min-tokens
Nov 1, 2026
Merged

tawei-amd merged 1 commit into
mainfrom
feat/ignore-eos-min-tokens

Conversation

@tawei-amd

Copy link
Copy Markdown
Collaborator

Fixes #881.

ignore_eos and min_tokens were accepted by /v1/chat/completions (and /generate, Ollama chat) but never read, so generation always stopped at the model's EOS.

Change

  • rest_handler.cpp: read ignore_eos (bool) and min_tokens (int) into chat_meta_info_t in all four handlers.
  • AutoModel::_sample(): while ignore_eos is set or generated_tokens < min_tokens, clear the EOS ids from the allowed-token mask (combined with any grammar mask; a grammar that allows only EOS keeps it).
  • modeling_qwen3_8mtp.cpp: the MTP draft head samples inside the engine, past that mask, so speculate() is skipped while EOS is suppressed (one token at a time, much slower on 27B; speculation resumes after min_tokens).
  • DFlash needs no change: it samples every verify row through _sample().
  • Docs: two rows + a note in request_parameters.md.

Tested (local build on XDNA 2, host-only change, no libs)

Model Request Result
Qwen3.5-2B baseline / min_tokens=64 2 / 66 tokens
Qwen3.5-2B ignore_eos max 150; ignore_eos+min_tokens=256 max 300 150 / 300, length
Qwen3.8-27B (MTP) min_tokens=64 max 96; ignore_eos max 32 96 / 32, length
nemotron3.5-bolt-dflash:e4b baseline / min_tokens=64 2 / 76 tokens
nemotron3.5-bolt-dflash:e4b ignore_eos max 150; ignore_eos+min_tokens=256 max 300; streaming max 60 150 / 300 / 60, speculation stayed on (AL 2.3-3.0)

min_tokens guarantees at least that many tokens; the reply can run 1-2 over (engines count the first sampled token differently), more with DFlash batches. The Qwen3.5-2B and 27B runs were on the earlier branch before the port onto this main; the code is identical.

🤖 Generated with Claude Code

…ma endpoints

Mask the end-of-sequence ids in AutoModel::_sample() while ignore_eos is set
or fewer than min_tokens tokens were generated (fixes #881). DFlash verifies
through _sample() so it is covered; the MTP loop skips speculate() while the
mask is needed, since its draft head samples inside the engine.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@tawei-amd
tawei-amd requested a review from zaneni6 November 1, 2026 00:41
@tawei-amd
tawei-amd marked this pull request as ready for review November 1, 2026 12:47
@tawei-amd
tawei-amd merged commit e0e1645 into main Nov 1, 2026
38 checks passed
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.

[Bug]: ignore_eos and min_tokens are not honored by /v1/chat/completions

1 participant