Preserve model-declared EOS tokens in serve mode#584
Conversation
|
This is the right fix for the default, and it composes cleanly with the The distinction is exactly the one #401 wanted and never drew. Three populations, not two:
The old serve branch collapsed the middle group into "discard," which is precisely the Relationship to #572 (already on dev): they're complementary, not competing.
So the layering ends up: correct by default (#584), with a "stop on everything" lever for non-conforming containers (#572). No conflict β #584 just means the lever is rarely needed. One thing worth a line in the code comment: #584 trusts +1. Cleaner root-cause fix than the opt-in flag. |
What changed
config.jsonorgeneration_config.jsonwhen the engine runs inSERVEmode.behavior introduced for [Bug]: Tool Calling Fail in serve APIΒ #401.
SERVEpath.Root cause
GLM-5.2 declares three EOS IDs:
154820β<|endoftext|>154827β<|user|>154829β<|observation|>stops_arm_tok()initially loaded all three, but itsSERVEbranch subsequentlydiscarded every stop except the tokenizer's primary EOS. The Python CLI and
OpenAI-compatible server forward native output and do not own a streaming-safe role
boundary stop, so
<|user|>was emitted as assistant content and generation continueduntil
NGEN.User impact
Before:
After:
This affects private
coli chatand the shared native path used by/v1/chat/completions, including streaming.Validation
tests/test_stops.exepasses.SERVEretains all three model-declared EOS tokens whilefiltering tokenizer-only
<|assistant|>and<sop>./v1/chat/completions:GLM-5.2 is running.max_tokens: 32finish_reason: stopThe model files were unchanged; the test used the existing validated 144-shard
checkpoint.